From 8e67452b9fc5e52af5a8ca1b3951a79da3823af6 Mon Sep 17 00:00:00 2001 From: Taylor Brown <60201147+taylorbrown75@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:53:14 -0700 Subject: [PATCH 1/4] Add physical heat sink variables to IPH trough cmod. --- ssc/cmod_trough_physical_iph.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/ssc/cmod_trough_physical_iph.cpp b/ssc/cmod_trough_physical_iph.cpp index e44fb6502..3dedba31f 100644 --- a/ssc/cmod_trough_physical_iph.cpp +++ b/ssc/cmod_trough_physical_iph.cpp @@ -169,7 +169,16 @@ static var_info _cm_vtab_trough_physical_iph[] = { { SSC_INPUT, SSC_NUMBER, "p_start", "Collector startup energy, per SCA", "kWhe", "", "solar_field", "*", "", "" }, // Heat Sink - { SSC_INPUT, SSC_NUMBER, "pb_pump_coef", "Pumping power to move 1kg of HTF through PB loop", "kW/kg", "", "Heat Sink", "*", "", "" }, + { SSC_INPUT, SSC_NUMBER, "pb_pump_coef", "Pumping power to move 1kg of HTF through PB loop", "kW/kg", "", "Heat Sink", "*", "", "" }, + + { SSC_INPUT, SSC_NUMBER, "hs_type", "0: ideal model, 1: physical steam model", "", "", "Heat Sink", "?=0", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_N_sub", "Number physical heat sink HX nodes", "", "", "Heat Sink", "hs_type=1", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_tol", "Physical heat sink solve tolerance", "", "", "Heat Sink", "hs_type=1", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_f_mdot_steam_min", "Min steam mdot fraction for physical heat sink", "", "", "Heat Sink", "hs_type=1", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_f_mdot_steam_max", "Max steam mdot fraction for physical heat sink", "", "", "Heat Sink", "hs_type=1", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_T_steam_cold_des", "Steam inlet temperature for physical heat sink", "C", "", "Heat Sink", "hs_type=1", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_P_steam_hot_des", "Steam outlet (and inlet) pressure for physical heat sink", "bar", "", "Heat Sink", "hs_type=1", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_Q_steam_hot_des", "Steam outlet quality for physical heat sink", "", "", "Heat Sink", "hs_type=1", "", "" }, // Parallel heater parameters { SSC_INPUT, SSC_NUMBER, "heater_mult", "Heater multiple relative to design cycle thermal power", "-", "", "Parallel Heater", "is_parallel_htr=1", "", "" }, @@ -1492,7 +1501,12 @@ class cm_trough_physical_iph : public compute_module } // Heat Sink + int hs_type = as_integer("hs_type"); + C_csp_power_cycle* c_heat_sink_pointer; C_pc_heat_sink c_heat_sink; + + // Ideal heat sink + if(hs_type == 0) { //size_t n_f_turbine1 = 0; //ssc_number_t* p_f_turbine1 = as_array("f_turb_tou_periods", &n_f_turbine1); // heat sink, not turbine @@ -1522,6 +1536,12 @@ class cm_trough_physical_iph : public compute_module c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_M_DOT_HTF, allocate("m_dot_htf_heat_sink", n_steps_fixed), n_steps_fixed); c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_T_HTF_IN, allocate("T_heat_sink_in", n_steps_fixed), n_steps_fixed); c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_T_HTF_OUT, allocate("T_heat_sink_out", n_steps_fixed), n_steps_fixed); + + c_heat_sink_pointer = &c_heat_sink; + } + else + { + throw exec_error("trough_physical_iph", "hs_type != 0; other heat sink models are not currently supported"); } // Electricity pricing schedule @@ -1665,7 +1685,7 @@ class cm_trough_physical_iph : public compute_module // Instantiate Solver C_csp_solver csp_solver(weather_reader, c_trough, - c_heat_sink, + *c_heat_sink_pointer, *storage_pointer, tou, dispatch, From 366ae1a7f547c22451584f16c626b9a24ce234bc Mon Sep 17 00:00:00 2001 From: Taylor Brown <60201147+taylorbrown75@users.noreply.github.com> Date: Fri, 22 Nov 2024 14:26:47 -0700 Subject: [PATCH 2/4] Add physical heat sink variables to IPH tower cmod. --- ssc/cmod_mspt_iph.cpp | 56 ++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/ssc/cmod_mspt_iph.cpp b/ssc/cmod_mspt_iph.cpp index 992361564..1bd84c8d3 100644 --- a/ssc/cmod_mspt_iph.cpp +++ b/ssc/cmod_mspt_iph.cpp @@ -224,6 +224,16 @@ static var_info _cm_vtab_mspt_iph[] = { // Heat Sink { SSC_INPUT, SSC_NUMBER, "pb_pump_coef", "Pumping power to move 1kg of HTF through PB loop", "kW/kg", "", "Heat Sink", "*", "", "" }, +{ SSC_INPUT, SSC_NUMBER, "hs_type", "0: ideal model, 1: physical steam model", "", "", "Heat Sink", "?=0", "", "" }, +{ SSC_INPUT, SSC_NUMBER, "hs_phys_N_sub", "Number physical heat sink HX nodes", "", "", "Heat Sink", "hs_type=1", "", "" }, +{ SSC_INPUT, SSC_NUMBER, "hs_phys_tol", "Physical heat sink solve tolerance", "", "", "Heat Sink", "hs_type=1", "", "" }, +{ SSC_INPUT, SSC_NUMBER, "hs_phys_f_mdot_steam_min", "Min steam mdot fraction for physical heat sink", "", "", "Heat Sink", "hs_type=1", "", "" }, +{ SSC_INPUT, SSC_NUMBER, "hs_phys_f_mdot_steam_max", "Max steam mdot fraction for physical heat sink", "", "", "Heat Sink", "hs_type=1", "", "" }, +{ SSC_INPUT, SSC_NUMBER, "hs_phys_T_steam_cold_des", "Steam inlet temperature for physical heat sink", "C", "", "Heat Sink", "hs_type=1", "", "" }, +{ SSC_INPUT, SSC_NUMBER, "hs_phys_P_steam_hot_des", "Steam outlet (and inlet) pressure for physical heat sink", "bar", "", "Heat Sink", "hs_type=1", "", "" }, +{ SSC_INPUT, SSC_NUMBER, "hs_phys_Q_steam_hot_des", "Steam outlet quality for physical heat sink", "", "", "Heat Sink", "hs_type=1", "", "" }, + + // Aux and Balance of Plant { SSC_INPUT, SSC_NUMBER, "pb_fixed_par", "Fixed parasitic load - runs at all times", "MWe/MWcap", "", "System Control", "*", "", "" }, { SSC_INPUT, SSC_NUMBER, "aux_par", "Aux heater, boiler parasitic", "MWe/MWcap", "", "System Control", "*", "", "" }, @@ -1208,6 +1218,10 @@ class cm_mspt_iph : public compute_module // *********************************************** // *********************************************** + int hs_type = as_integer("hs_type"); + C_csp_power_cycle* c_heat_sink_pointer; + C_pc_heat_sink c_heat_sink; + size_t n_f_turbine1 = 0; ssc_number_t* p_f_turbine1 = as_array("f_turb_tou_periods", &n_f_turbine1); // heat sink, not turbine double f_turbine_max1 = 1.0; @@ -1215,24 +1229,34 @@ class cm_mspt_iph : public compute_module f_turbine_max1 = max(f_turbine_max1, p_f_turbine1[i]); } - C_pc_heat_sink c_heat_sink; - c_heat_sink.ms_params.m_T_htf_hot_des = T_htf_hot_des; //[C] FIELD design outlet temperature - c_heat_sink.ms_params.m_T_htf_cold_des = T_htf_cold_des; //[C] FIELD design inlet temperature - c_heat_sink.ms_params.m_q_dot_des = q_dot_pc_des; //[MWt] HEAT SINK design thermal power (could have field solar multiple...) - // 9.18.2016 twn: assume for now there's no pressure drop though heat sink - c_heat_sink.ms_params.m_htf_pump_coef = as_double("pb_pump_coef"); //[kWe/kg/s] - c_heat_sink.ms_params.m_max_frac = f_turbine_max1; + // Ideal heat sink + if (hs_type == 0) + { + c_heat_sink.ms_params.m_T_htf_hot_des = T_htf_hot_des; //[C] FIELD design outlet temperature + c_heat_sink.ms_params.m_T_htf_cold_des = T_htf_cold_des; //[C] FIELD design inlet temperature + c_heat_sink.ms_params.m_q_dot_des = q_dot_pc_des; //[MWt] HEAT SINK design thermal power (could have field solar multiple...) + // 9.18.2016 twn: assume for now there's no pressure drop though heat sink + c_heat_sink.ms_params.m_htf_pump_coef = as_double("pb_pump_coef"); //[kWe/kg/s] + c_heat_sink.ms_params.m_max_frac = f_turbine_max1; - c_heat_sink.ms_params.m_pc_fl = as_integer("rec_htf"); - c_heat_sink.ms_params.m_pc_fl_props = as_matrix("field_fl_props"); + c_heat_sink.ms_params.m_pc_fl = as_integer("rec_htf"); + c_heat_sink.ms_params.m_pc_fl_props = as_matrix("field_fl_props"); - // Allocate heat sink outputs - c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_Q_DOT_HEAT_SINK, allocate("q_dot_to_heat_sink", n_steps_fixed), n_steps_fixed); - c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_W_DOT_PUMPING, allocate("W_dot_pc_pump", n_steps_fixed), n_steps_fixed); - c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_M_DOT_HTF, allocate("m_dot_htf_heat_sink", n_steps_fixed), n_steps_fixed); - c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_T_HTF_IN, allocate("T_heat_sink_in", n_steps_fixed), n_steps_fixed); - c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_T_HTF_OUT, allocate("T_heat_sink_out", n_steps_fixed), n_steps_fixed); + // Allocate heat sink outputs + c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_Q_DOT_HEAT_SINK, allocate("q_dot_to_heat_sink", n_steps_fixed), n_steps_fixed); + c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_W_DOT_PUMPING, allocate("W_dot_pc_pump", n_steps_fixed), n_steps_fixed); + c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_M_DOT_HTF, allocate("m_dot_htf_heat_sink", n_steps_fixed), n_steps_fixed); + c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_T_HTF_IN, allocate("T_heat_sink_in", n_steps_fixed), n_steps_fixed); + c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_T_HTF_OUT, allocate("T_heat_sink_out", n_steps_fixed), n_steps_fixed); + + c_heat_sink_pointer = &c_heat_sink; + } + else + { + throw exec_error("mspt_iph", "hs_type != 0; other heat sink models are not currently supported"); + } + //// ********************************************************* //// ********************************************************* @@ -1741,7 +1765,7 @@ class cm_mspt_iph : public compute_module // Instantiate Solver C_csp_solver csp_solver(weather_reader, collector_receiver, - c_heat_sink, + *c_heat_sink_pointer, storage, tou, dispatch, From 71a0b4b3b668463c78c6cd443c138bedacb36685 Mon Sep 17 00:00:00 2001 From: Taylor Brown <60201147+taylorbrown75@users.noreply.github.com> Date: Fri, 22 Nov 2024 16:06:31 -0700 Subject: [PATCH 3/4] Add physical heat sink variables to IPH MSLF cmod. --- ssc/cmod_fresnel_physical_iph.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/ssc/cmod_fresnel_physical_iph.cpp b/ssc/cmod_fresnel_physical_iph.cpp index 07d721520..1e3364f12 100644 --- a/ssc/cmod_fresnel_physical_iph.cpp +++ b/ssc/cmod_fresnel_physical_iph.cpp @@ -153,7 +153,17 @@ static var_info _cm_vtab_fresnel_physical_iph[] = { // Heat Sink - {SSC_INPUT, SSC_NUMBER, "pb_pump_coef", "Pumping power to move 1kg of HTF through PB loop", "kW/kg", "", "Heat Sink", "*", "", ""}, + { SSC_INPUT, SSC_NUMBER, "pb_pump_coef", "Pumping power to move 1kg of HTF through PB loop", "kW/kg", "", "Heat Sink", "*", "", "" }, + + { SSC_INPUT, SSC_NUMBER, "hs_type", "0: ideal model, 1: physical steam model", "", "", "Heat Sink", "?=0", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_N_sub", "Number physical heat sink HX nodes", "", "", "Heat Sink", "hs_type=1", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_tol", "Physical heat sink solve tolerance", "", "", "Heat Sink", "hs_type=1", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_f_mdot_steam_min", "Min steam mdot fraction for physical heat sink", "", "", "Heat Sink", "hs_type=1", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_f_mdot_steam_max", "Max steam mdot fraction for physical heat sink", "", "", "Heat Sink", "hs_type=1", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_T_steam_cold_des", "Steam inlet temperature for physical heat sink", "C", "", "Heat Sink", "hs_type=1", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_P_steam_hot_des", "Steam outlet (and inlet) pressure for physical heat sink", "bar", "", "Heat Sink", "hs_type=1", "", "" }, + { SSC_INPUT, SSC_NUMBER, "hs_phys_Q_steam_hot_des", "Steam outlet quality for physical heat sink", "", "", "Heat Sink", "hs_type=1", "", "" }, + // TES @@ -911,7 +921,12 @@ class cm_fresnel_physical_iph : public compute_module } // Heat Sink + int hs_type = as_integer("hs_type"); + C_csp_power_cycle* c_heat_sink_pointer; C_pc_heat_sink c_heat_sink; + + // Ideal heat sink + if (hs_type == 0) { //size_t n_f_turbine1 = 0; //ssc_number_t* p_f_turbine1 = as_array("f_turb_tou_periods", &n_f_turbine1); // heat sink, not turbine @@ -940,6 +955,12 @@ class cm_fresnel_physical_iph : public compute_module c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_M_DOT_HTF, allocate("m_dot_htf_heat_sink", n_steps_fixed), n_steps_fixed); c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_T_HTF_IN, allocate("T_heat_sink_in", n_steps_fixed), n_steps_fixed); c_heat_sink.mc_reported_outputs.assign(C_pc_heat_sink::E_T_HTF_OUT, allocate("T_heat_sink_out", n_steps_fixed), n_steps_fixed); + + c_heat_sink_pointer = &c_heat_sink; + } + else + { + throw exec_error("fresnel_physical_iph", "hs_type != 0; other heat sink models are not currently supported"); } // Electricity pricing schedule @@ -1087,7 +1108,7 @@ class cm_fresnel_physical_iph : public compute_module // Instantiate Solver C_csp_solver csp_solver(weather_reader, c_fresnel, - c_heat_sink, + *c_heat_sink_pointer, storage, tou, dispatch, From 850d48936bb946817e914ceddf7b38d4df072f16 Mon Sep 17 00:00:00 2001 From: Taylor Brown <60201147+taylorbrown75@users.noreply.github.com> Date: Tue, 3 Dec 2024 13:30:20 -0700 Subject: [PATCH 4/4] Add nullptr check for heat sink --- ssc/cmod_fresnel_physical_iph.cpp | 7 ++++++- ssc/cmod_mspt_iph.cpp | 7 +++++-- ssc/cmod_trough_physical_iph.cpp | 7 ++++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ssc/cmod_fresnel_physical_iph.cpp b/ssc/cmod_fresnel_physical_iph.cpp index 1e3364f12..dacf31b90 100644 --- a/ssc/cmod_fresnel_physical_iph.cpp +++ b/ssc/cmod_fresnel_physical_iph.cpp @@ -922,7 +922,7 @@ class cm_fresnel_physical_iph : public compute_module // Heat Sink int hs_type = as_integer("hs_type"); - C_csp_power_cycle* c_heat_sink_pointer; + C_csp_power_cycle* c_heat_sink_pointer = nullptr; C_pc_heat_sink c_heat_sink; // Ideal heat sink @@ -963,6 +963,11 @@ class cm_fresnel_physical_iph : public compute_module throw exec_error("fresnel_physical_iph", "hs_type != 0; other heat sink models are not currently supported"); } + if (c_heat_sink_pointer == nullptr) + { + throw exec_error("fresnel_physical_iph", "Heat sink pointer not assigned"); + } + // Electricity pricing schedule int csp_financial_model = as_integer("csp_financial_model"); C_timeseries_schedule_inputs elec_pricing_schedule; diff --git a/ssc/cmod_mspt_iph.cpp b/ssc/cmod_mspt_iph.cpp index 1bd84c8d3..c6fef576f 100644 --- a/ssc/cmod_mspt_iph.cpp +++ b/ssc/cmod_mspt_iph.cpp @@ -1219,7 +1219,7 @@ class cm_mspt_iph : public compute_module // *********************************************** int hs_type = as_integer("hs_type"); - C_csp_power_cycle* c_heat_sink_pointer; + C_csp_power_cycle* c_heat_sink_pointer = nullptr; C_pc_heat_sink c_heat_sink; size_t n_f_turbine1 = 0; @@ -1256,7 +1256,10 @@ class cm_mspt_iph : public compute_module { throw exec_error("mspt_iph", "hs_type != 0; other heat sink models are not currently supported"); } - + if (c_heat_sink_pointer == nullptr) + { + throw exec_error("mspt_iph", "Heat sink pointer not assigned"); + } //// ********************************************************* //// ********************************************************* diff --git a/ssc/cmod_trough_physical_iph.cpp b/ssc/cmod_trough_physical_iph.cpp index 3dedba31f..63ec126ff 100644 --- a/ssc/cmod_trough_physical_iph.cpp +++ b/ssc/cmod_trough_physical_iph.cpp @@ -1502,7 +1502,7 @@ class cm_trough_physical_iph : public compute_module // Heat Sink int hs_type = as_integer("hs_type"); - C_csp_power_cycle* c_heat_sink_pointer; + C_csp_power_cycle* c_heat_sink_pointer = nullptr; C_pc_heat_sink c_heat_sink; // Ideal heat sink @@ -1544,6 +1544,11 @@ class cm_trough_physical_iph : public compute_module throw exec_error("trough_physical_iph", "hs_type != 0; other heat sink models are not currently supported"); } + if (c_heat_sink_pointer == nullptr) + { + throw exec_error("trough_physical_iph", "Heat sink pointer not assigned"); + } + // Electricity pricing schedule C_timeseries_schedule_inputs elec_pricing_schedule;