New cmod_csp_tower_particle_IPH.cpp - #1414
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.
Adds a new SSC compute module (csp_tower_particle_iph) for falling-particle tower systems delivering industrial process heat (IPH), combining particle-tower receiver/field modeling with a heat-sink workflow and exposing field-average cosine efficiency from SolarPILOT.
Changes:
- Registers the new
csp_tower_particle_iphmodule with SSC and build system. - Extends SolarPILOT invocation utilities to expose field-average cosine efficiency.
- Implements a new compute module
cmod_csp_tower_particle_IPH.cppwith multi-receiver support and heat-sink outputs.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| ssc/sscapi.cpp | Registers the new compute module entry so SSC can discover it. |
| ssc/csp_common.h / ssc/csp_common.cpp | Adds getFieldAverageCosine() to pull cosine efficiency directly from SolarPILOT. |
| solarpilot/AutoPilot_API.h | Exposes SolarField* from AutoPilot to enable cosine averaging. |
| ssc/CMakeLists.txt | Adds the new module file to the SSC build. |
| ssc/cmod_csp_tower_particle_IPH.cpp | New IPH compute module combining particle tower + heat-sink workflow and outputs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| cmod_csp_tower_particle.cpp | ||
| cmod_csp_heatsink.cpp | ||
| cmod_csp_subcomponent.cpp | ||
| cmod_csp_tower_particle.cpp | ||
| cmod_csp_tower_particle_IPH.cpp |
| // If electricity pricing data is not available, then dispatch to a uniform schedule | ||
| elec_pricing_schedule = C_timeseries_schedule_inputs(1.0, std::numeric |
| } | ||
| else { // if no dispatch optimization, don't need an input pricing schedule | ||
| // If electricity pricing data is not available, then dispatch to a uniform schedule | ||
| elec_pricing_schedule = C_timeseries_schedule_inputs(1.0, std::numeric |
There was a problem hiding this comment.
p_gen is hardcoded to 0 for all timesteps since this module has no electric output
| } | ||
| else { // if no dispatch optimization, don't need an input pricing schedule | ||
| // If electricity pricing data is not available, then dispatch to a uniform schedule | ||
| elec_pricing_schedule = C_timeseries_schedule_inputs(1.0, std::numeric |
There was a problem hiding this comment.
p_gen is hardcoded to 0 for all timesteps since this module has no electric output
| } | ||
| else { // if no dispatch optimization, don't need an input pricing schedule | ||
| // If electricity pricing data is not available, then dispatch to a uniform schedule | ||
| elec_pricing_schedule = C_timeseries_schedule_inputs(1.0, std::numeric |
There was a problem hiding this comment.
p_gen is hardcoded to 0 for all timesteps since this module has no electric output
| for (size_t i = 0; i < num_recs; i++) { // loop through receivers | ||
| input_idx = duplicate_recs ? 0 : i; // Use the first element if duplicate receivers |
There was a problem hiding this comment.
This block is unchanged from cmod_csp_tower_particle.cpp
| q_dot_des_per_rec.at(i) = q_dot_rec_des * (power_fraction[input_idx] / power_fraction_sum); // Receiver design point power | ||
| rec_orientation = rec_azimuth[i]; |
There was a problem hiding this comment.
This block is unchanged from cmod_csp_tower_particle.cpp
| { SSC_INPUT, SSC_NUMBER, "transport_deltaT_cold", "Temperature loss for cold particle transport", "K", "", "Tower and Receiver", "*", "", ""}, | ||
|
|
||
| // Falling particle receiver inputs for SolarPILOT that should *not* be reset during call to this cmod | ||
| { SSC_INPUT, SSC_MATRIX, "rec_tower_offset", "Distance from tower optical height to receiver aperture center, format [[x1,y1],[x2,y2],...] or [[x1,y1,z1],[x2,y2,z2],...]", "m", "", "Tower and Receiver", "?", "", ""}, |
There was a problem hiding this comment.
Identical to cmod_csp_tower_particle.cpp
| } | ||
| else { // if no dispatch optimization, don't need an input pricing schedule | ||
| // If electricity pricing data is not available, then dispatch to a uniform schedule | ||
| elec_pricing_schedule = C_timeseries_schedule_inputs(1.0, std::numeric |
There was a problem hiding this comment.
Identical to cmod_csp_tower_particle.cpp
| { SSC_INPUT, SSC_NUMBER, "is_parallel_htr", "Does plant include a HTF heater parallel to solar field?", "", "", "System Control", "?=0", "", ""}, | ||
| { SSC_INPUT, SSC_NUMBER, "T_htf_cold_des", "Cold HTF inlet temperature at design conditions", "C", "", "System Design", "*", "", ""}, | ||
| { SSC_INPUT, SSC_NUMBER, "T_htf_hot_des", "Hot HTF outlet temperature at design conditions", "C", "", "System Design", "*", "", ""}, | ||
| { SSC_INPUT, SSC_NUMBER, "q_pb_design", "Design heat input to power block", "MWt", "", "System Design", "*", "", ""}, |
There was a problem hiding this comment.
Labeled identical to the molten-salt IPH
capacity_factor_highest_1000_ppas / _2000_ppas summed p_gen, which is always 0 in this heat-only module, so the outputs were structurally zero. Removed the two SSC outputs and their calculation block. Addresses PR NatLabRockies#1414 review comment.
Adds rec_fixed_cost input (default 0) charged once per receiver in the receiver cost loop, alongside the existing area-scaled power law. Defaults reproduce prior behavior exactly.
Adds a new compute module, csp_tower_particle_iph, for falling-particle tower systems delivering industrial process heat (IPH). It combines the heat/heat-sink workflow from cmod_mspt_iph (thermal design point driven by q_pb_design, no power block) with the particle-receiver field and receiver physics from cmod_csp_tower_particle, supporting multi-receiver layouts. Also exposes eta_cosine_field, the field-average cosine efficiency, read directly from SolarPILOT.