Skip to content

Commit 0276c6c

Browse files
Merge pull request #1353 from NREL/sco2_tsf
Add two new sco2 configurations
2 parents 2afff4f + 1e7fc7d commit 0276c6c

21 files changed

+5691
-234
lines changed

ssc/cmod_csp_heatsink.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class cm_csp_heatsink : public compute_module
6060

6161
NS_HX_counterflow_eqs::E_UA_target_type ua_type = NS_HX_counterflow_eqs::E_UA_target_type::E_constant_UA;
6262

63-
mc_phx.initialize(hot_fl, 10, ua_type);
63+
mc_phx.initialize(hot_fl, 10, ua_type, 2024.0);
6464

6565
double q_dot = 1000.0; //[kWt]
6666
double T_co2_hot = 700.0; //[C]

ssc/cmod_sco2_csp_system.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3838
#include <ctime>
3939

4040
#include "sco2_pc_csp_int.h"
41+
#include "sco2_htrbypass_cycle.h"
4142

4243
static var_info _cm_vtab_sco2_csp_system[] = {
4344

@@ -363,7 +364,7 @@ class cm_sco2_csp_system : public compute_module
363364
bool is_od_set_control = is_assigned("od_set_control");
364365
bool is_od_generate_udpc_assigned = is_assigned("od_generate_udpc");
365366
if (is_od_cases_assigned && is_P_mc_in_od_sweep_assigned)
366-
{
367+
{
367368
log("Both off design cases and main compressor inlet pressure sweep assigned. Only modeling off design cases");
368369
is_P_mc_in_od_sweep_assigned = false;
369370
}
@@ -452,11 +453,18 @@ class cm_sco2_csp_system : public compute_module
452453
P_LP_comp_in_des = c_sco2_cycle.get_design_solved()->ms_rc_cycle_solved.m_pres[C_sco2_cycle_core::MC_IN] / 1000.0; //[MPa] convert from kPa
453454
delta_P = 10.0;
454455
}
455-
else
456+
else if (cycle_config == 2)
456457
{
457458
P_LP_comp_in_des = c_sco2_cycle.get_design_solved()->ms_rc_cycle_solved.m_pres[C_sco2_cycle_core::PC_IN] / 1000.0; //[MPa] convert from kPa
458459
delta_P = 6.0;
459460
}
461+
else
462+
{
463+
log("Cycle configuration not supported for off-design");
464+
std::string err_msg = util::format("Cycle configuration not supported for off-design");
465+
throw exec_error("sco2_csp_system", err_msg);
466+
return;
467+
}
460468

461469
// Get turbine inlet mode
462470
int T_t_in_mode = as_integer("od_T_t_in_mode");
@@ -1741,3 +1749,7 @@ class cm_sco2_comp_curves : public compute_module
17411749
};
17421750

17431751
DEFINE_MODULE_ENTRY(sco2_comp_curves, "Calls sCO2 auto-design cycle function", 1)
1752+
1753+
1754+
1755+

ssc/csp_common.cpp

Lines changed: 279 additions & 46 deletions
Large diffs are not rendered by default.

ssc/csp_common.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ extern var_info vtab_sco2_design[];
8383

8484
int sco2_design_cmod_common(compute_module *cm, C_sco2_phx_air_cooler & c_sco2_cycle);
8585

86+
#endif
8687

8788

88-
89-
90-
#endif

tcs/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,12 @@ set(TCS_SRC
5252
numeric_solvers.cpp
5353
ptes_solver_design_point.cpp
5454
sco2_cycle_components.cpp
55+
sco2_htrbypass_cycle.cpp
5556
sco2_partialcooling_cycle.cpp
5657
sco2_pc_csp_int.cpp
5758
sco2_power_cycle.cpp
5859
sco2_recompression_cycle.cpp
60+
sco2_turbinesplitflow_cycle.cpp
5961
tcskernel.cpp
6062
trnsys_weatherreader.cpp
6163
typelib.cpp
@@ -131,10 +133,12 @@ set(TCS_SRC
131133
sam_csp_util.h
132134
sco2_cycle_components.h
133135
sco2_cycle_templates.h
136+
sco2_htrbypass_cycle.h
134137
sco2_partialcooling_cycle.h
135138
sco2_pc_csp_int.h
136139
sco2_power_cycle.h
137140
sco2_recompression_cycle.h
141+
sco2_turbinesplitflow_cycle.h
138142
storage_hx.h
139143
tcskernel.h
140144
tcstype.h

tcs/heat_exchangers.cpp

Lines changed: 63 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3535
#include "sam_csp_util.h"
3636
#include <algorithm>
3737
#include "numeric_solvers.h"
38+
#include "sco2_cycle_components.h"
3839

3940
double NS_HX_counterflow_eqs::calc_max_q_dot_enth(int hot_fl_code /*-*/, HTFProperties & hot_htf_class,
4041
int cold_fl_code /*-*/, HTFProperties & cold_htf_class,
@@ -1523,11 +1524,13 @@ void NS_HX_counterflow_eqs::solve_q_dot_for_fixed_UA_enth(int hot_fl_code /*-*/,
15231524
throw(C_csp_exception("Off-design heat exchanger method failed"));
15241525
}
15251526

1526-
//if (!(od_hx_code == C_monotonic_eq_solver::CONVERGED || od_hx_code == C_monotonic_eq_solver::SLOPE_POS_NO_POS_ERR || od_hx_code == C_monotonic_eq_solver::SLOPE_POS_BOTH_ERRS))
1527-
//{
1528-
// throw(C_csp_exception("Off-design heat exchanger method failed"));
1529-
//}
1527+
/*if (!(od_hx_code == C_monotonic_eq_solver::CONVERGED || od_hx_code == C_monotonic_eq_solver::SLOPE_POS_NO_POS_ERR || od_hx_code == C_monotonic_eq_solver::SLOPE_POS_BOTH_ERRS))
1528+
{
1529+
throw(C_csp_exception("Off-design heat exchanger method failed"));
1530+
}*/
1531+
15301532
}
1533+
15311534
else if (test_code == 0 && diff_UA_max_eff <= 0.0) // UA_max_eff <= UA_target)
15321535
{
15331536
// At maximum allowable heat transfer, the calculated UA is less than target
@@ -1785,16 +1788,37 @@ double C_HX_counterflow_CRM::calc_max_q_dot_enth(double h_h_in /*kJ/kg*/, double
17851788

17861789
double /*M$*/ C_HX_counterflow_CRM::calculate_equipment_cost(double UA /*kWt/K*/,
17871790
double T_hot_in /*K*/, double P_hot_in /*kPa*/, double m_dot_hot /*kg/s*/,
1788-
double T_cold_in /*K*/, double P_cold_in /*kPa*/, double m_dot_cold /*kg/s*/)
1791+
double T_cold_in /*K*/, double P_cold_in /*kPa*/, double m_dot_cold /*kg/s*/,
1792+
double yr_inflation /*yr*/)
17891793
{
17901794
switch (m_cost_model)
17911795
{
17921796
case C_HX_counterflow_CRM::E_CARLSON_17_RECUP:
1793-
return 1.25*1.E-3*UA; //[M$] needs UA in kWt/K
1797+
{
1798+
double yr_base_inflation = 2017;
1799+
double f_inflation = calculate_inflation_factor(yr_base_inflation, yr_inflation);
1800+
return 1.25 * 1.E-3 * UA * f_inflation; //[M$] needs UA in kWt/K
1801+
}
17941802
case C_HX_counterflow_CRM::E_WEILAND_19_RECUP:
1795-
return 49.45*std::pow(UA*1.E3, 0.7544)*1.E-6; //[M$] needs UA in Wt/K
1803+
{
1804+
double C_recup = 49.45 * std::pow(UA * 1.E3, 0.7544) * 1.E-6; //[M$] needs UA in Wt/K
1805+
double T_factor = 1;
1806+
double T_max_C = std::max(T_hot_in, T_cold_in) - 273.15;
1807+
if (T_max_C >= 550)
1808+
{
1809+
T_factor = 1.0 + 0.02141 * (T_max_C - 550);
1810+
}
1811+
double yr_base_inflation = 2017;
1812+
double f_inflation = calculate_inflation_factor(yr_base_inflation, yr_inflation);
1813+
return C_recup * T_factor * f_inflation; //[M$]
1814+
break;
1815+
}
17961816
case C_HX_counterflow_CRM::E_CARLSON_17_PHX:
1797-
return 3.5*1.E-3*UA; //[M$] needs UA in kWt/K
1817+
{
1818+
double yr_base_inflation = 2017;
1819+
double f_inflation = calculate_inflation_factor(yr_base_inflation, yr_inflation);
1820+
return 3.5 * 1.E-3 * UA * f_inflation; //[M$] needs UA in kWt/K
1821+
}
17981822
default:
17991823
return std::numeric_limits<double>::quiet_NaN();
18001824
}
@@ -1860,7 +1884,8 @@ void C_HX_counterflow_CRM::design_calc_UA(C_HX_counterflow_CRM::S_des_calc_UA_pa
18601884

18611885
ms_des_solved.m_cost_equipment = calculate_equipment_cost(ms_des_solved.m_UA_design,
18621886
ms_des_calc_UA_par.m_T_h_in, ms_des_calc_UA_par.m_P_h_in, ms_des_calc_UA_par.m_m_dot_hot_des,
1863-
ms_des_calc_UA_par.m_T_c_in, ms_des_calc_UA_par.m_P_c_in, ms_des_calc_UA_par.m_m_dot_cold_des);
1887+
ms_des_calc_UA_par.m_T_c_in, ms_des_calc_UA_par.m_P_c_in, ms_des_calc_UA_par.m_m_dot_cold_des,
1888+
m_yr_inflation);
18641889

18651890
ms_des_solved.m_cost_bare_erected = calculate_bare_erected_cost(ms_des_solved.m_cost_equipment);
18661891

@@ -1981,7 +2006,7 @@ void C_HX_counterflow_CRM::design_calc_UA_TP_to_PH(C_HX_counterflow_CRM::S_des_c
19812006

19822007
ms_des_solved.m_cost_equipment = calculate_equipment_cost(ms_des_solved.m_UA_design,
19832008
ms_des_calc_UA_par.m_T_h_in, ms_des_calc_UA_par.m_P_h_in, ms_des_calc_UA_par.m_m_dot_hot_des,
1984-
ms_des_calc_UA_par.m_T_c_in, ms_des_calc_UA_par.m_P_c_in, ms_des_calc_UA_par.m_m_dot_cold_des);
2009+
ms_des_calc_UA_par.m_T_c_in, ms_des_calc_UA_par.m_P_c_in, ms_des_calc_UA_par.m_m_dot_cold_des, m_yr_inflation);
19852010

19862011
ms_des_solved.m_cost_bare_erected = calculate_bare_erected_cost(ms_des_solved.m_cost_equipment);
19872012

@@ -2059,7 +2084,8 @@ void C_HX_counterflow_CRM::design_for_target__calc_outlet(int hx_target_code /*-
20592084

20602085
ms_des_solved.m_cost_equipment = calculate_equipment_cost(ms_des_solved.m_UA_design,
20612086
T_h_in, P_h_in, m_dot_h,
2062-
T_c_in, P_c_in, m_dot_c);
2087+
T_c_in, P_c_in, m_dot_c,
2088+
m_yr_inflation);
20632089

20642090
ms_des_solved.m_cost_bare_erected = calculate_bare_erected_cost(ms_des_solved.m_cost_equipment);
20652091
}
@@ -3370,7 +3396,8 @@ double NS_HX_counterflow_eqs::UA_scale_vs_m_dot(double m_dot_cold_over_des /*-*/
33703396
return pow(m_dot_ratio, 0.8);
33713397
}
33723398

3373-
void C_HX_co2_to_co2_CRM::initialize(int N_sub_hx, NS_HX_counterflow_eqs::E_UA_target_type od_UA_target_type)
3399+
void C_HX_co2_to_co2_CRM::initialize(int N_sub_hx, NS_HX_counterflow_eqs::E_UA_target_type od_UA_target_type,
3400+
double yr_inflation)
33743401
{
33753402
// Set design parameters member structure
33763403
ms_init_par.m_N_sub_hx = N_sub_hx;
@@ -3379,9 +3406,11 @@ void C_HX_co2_to_co2_CRM::initialize(int N_sub_hx, NS_HX_counterflow_eqs::E_UA_t
33793406
m_is_HX_initialized = true;
33803407

33813408
m_od_UA_target_type = od_UA_target_type;
3409+
m_yr_inflation = yr_inflation;
33823410
}
33833411

3384-
void C_HX_co2_to_htf::initialize(int hot_fl, util::matrix_t<double> hot_fl_props, int N_sub_hx, NS_HX_counterflow_eqs::E_UA_target_type od_UA_target_type)
3412+
void C_HX_co2_to_htf::initialize(int hot_fl, util::matrix_t<double> hot_fl_props, int N_sub_hx, NS_HX_counterflow_eqs::E_UA_target_type od_UA_target_type,
3413+
double yr_inflation)
33853414
{
33863415
// Hard-code some of the design parameters
33873416
ms_init_par.m_N_sub_hx = N_sub_hx; //[-]
@@ -3427,13 +3456,16 @@ void C_HX_co2_to_htf::initialize(int hot_fl, util::matrix_t<double> hot_fl_props
34273456
// Class is initialized
34283457
m_is_HX_initialized = true;
34293458

3459+
m_yr_inflation = yr_inflation;
3460+
34303461
}
34313462

3432-
void C_HX_co2_to_htf::initialize(int hot_fl, int N_sub_hx, NS_HX_counterflow_eqs::E_UA_target_type od_UA_target_type)
3463+
void C_HX_co2_to_htf::initialize(int hot_fl, int N_sub_hx, NS_HX_counterflow_eqs::E_UA_target_type od_UA_target_type,
3464+
double yr_inflation)
34333465
{
34343466
util::matrix_t<double> null_fluid_props;
34353467

3436-
initialize(hot_fl, null_fluid_props, N_sub_hx, od_UA_target_type);
3468+
initialize(hot_fl, null_fluid_props, N_sub_hx, od_UA_target_type, yr_inflation);
34373469
}
34383470

34393471
void C_HX_co2_to_htf::design_and_calc_m_dot_htf(C_HX_counterflow_CRM::S_des_calc_UA_par& des_par,
@@ -3691,7 +3723,8 @@ bool C_CO2_to_air_cooler::design_hx(S_des_par_ind des_par_ind, S_des_par_cycle_d
36913723
solver_code = -1;
36923724
i_W_par = -1;
36933725

3694-
while (solver_code != 0 || std::abs(T_hot_in_calc_2 - T_hot_in_calc) / T_hot_in_calc < 0.01)
3726+
while (solver_code != 0 || std::abs(T_hot_in_calc_2 - T_hot_in_calc) / T_hot_in_calc < 0.01
3727+
|| ms_des_par_cycle_dep.m_T_hot_in_des - T_hot_in_calc_2 > 100.0)
36953728
{
36963729
i_W_par++;
36973730

@@ -3774,7 +3807,7 @@ bool C_CO2_to_air_cooler::design_hx(S_des_par_ind des_par_ind, S_des_par_cycle_d
37743807
ms_hx_des_sol.m_W_dot_fan = ms_des_par_cycle_dep.m_W_dot_fan_des; //[MWe]
37753808

37763809
ms_hx_des_sol.m_cost_equipment = calculate_equipment_cost(ms_hx_des_sol.m_UA_total*1.E-3, ms_hx_des_sol.m_V_total,
3777-
ms_hx_des_sol.m_T_in_co2, ms_hx_des_sol.m_P_in_co2, ms_hx_des_sol.m_m_dot_co2); //[M$]
3810+
ms_hx_des_sol.m_T_in_co2, ms_hx_des_sol.m_P_in_co2, ms_hx_des_sol.m_m_dot_co2, des_par_ind.m_yr_inflation); //[M$]
37783811

37793812
ms_hx_des_sol.m_cost_bare_erected = calculate_bare_erected_cost(ms_hx_des_sol.m_cost_equipment);
37803813

@@ -4361,14 +4394,24 @@ int C_CO2_to_air_cooler::C_MEQ_target_T_hot__width_parallel::operator()(double W
43614394
}
43624395

43634396
double /*M$*/ C_CO2_to_air_cooler::calculate_equipment_cost(double UA /*kWt/K*/, double V_material /*m^3*/,
4364-
double T_hot_in /*K*/, double P_hot_in /*kPa*/, double m_dot_hot /*kg/s*/)
4397+
double T_hot_in /*K*/, double P_hot_in /*kPa*/, double m_dot_hot /*kg/s*/, double yr_inflation/**/)
43654398
{
43664399
switch (m_cost_model)
43674400
{
43684401
case C_CO2_to_air_cooler::E_CARLSON_17:
4369-
return 2.3*1.E-3*UA; //[M$] needs UA in kWt/K
4402+
{
4403+
double yr_base_inflation = 2017;
4404+
double f_inflation = calculate_inflation_factor(yr_base_inflation, yr_inflation);
4405+
return 2.3 * 1.E-3 * UA * f_inflation; //[M$] needs UA in kWt/K
4406+
}
4407+
43704408
case C_CO2_to_air_cooler::E_WEILAND_19:
4371-
return 32.88*std::pow(UA*1.E3, 0.75)*1.E-6; //[M$] needs UA in Wt/K
4409+
{
4410+
double yr_base_inflation = 2017;
4411+
double f_inflation = calculate_inflation_factor(yr_base_inflation, yr_inflation);
4412+
return 32.88 * std::pow(UA * 1.E3, 0.75) * 1.E-6 * f_inflation; //[M$] needs UA in Wt/K
4413+
}
4414+
43724415
default:
43734416
return std::numeric_limits<double>::quiet_NaN();
43744417
}

tcs/heat_exchangers.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ class C_HX_counterflow_CRM
478478

479479
int m_cost_model; //[-]
480480
int m_od_solution_type; //[-]
481+
double m_yr_inflation = 0; //[yr]
481482

482483
bool m_is_single_node_des_set;
483484
NS_HX_counterflow_eqs::S_hx_node_info ms_node_info_des;
@@ -678,7 +679,8 @@ class C_HX_counterflow_CRM
678679

679680
double calculate_equipment_cost(double UA /*kWt/K*/,
680681
double T_hot_in /*K*/, double P_hot_in /*kPa*/, double m_dot_hot /*kg/s*/,
681-
double T_cold_in /*K*/, double P_cold_in /*kPa*/, double m_dot_cold /*kg/s*/);
682+
double T_cold_in /*K*/, double P_cold_in /*kPa*/, double m_dot_cold /*kg/s*/,
683+
double yr_inflation /*yr*/);
682684

683685
double calculate_bare_erected_cost(double cost_equipment /*M$*/);
684686

@@ -838,9 +840,10 @@ class C_HX_co2_to_htf : public C_HX_counterflow_CRM
838840
void design_and_calc_m_dot_htf(C_HX_counterflow_CRM::S_des_calc_UA_par &des_par,
839841
double q_dot_design /*kWt*/, double dt_cold_approach /*C/K*/, C_HX_counterflow_CRM::S_des_solved &des_solved);
840842

841-
virtual void initialize(int hot_fl, util::matrix_t<double> hot_fl_props, int N_sub_hx, NS_HX_counterflow_eqs::E_UA_target_type od_UA_target_type);
843+
virtual void initialize(int hot_fl, util::matrix_t<double> hot_fl_props, int N_sub_hx, NS_HX_counterflow_eqs::E_UA_target_type od_UA_target_type,
844+
double yr_inflation);
842845

843-
virtual void initialize(int hot_fl, int N_sub_hx, NS_HX_counterflow_eqs::E_UA_target_type od_UA_target_type);
846+
virtual void initialize(int hot_fl, int N_sub_hx, NS_HX_counterflow_eqs::E_UA_target_type od_UA_target_type, double yr_inflation);
844847

845848
};
846849

@@ -861,7 +864,8 @@ class C_HX_co2_to_co2_CRM : public C_HX_counterflow_CRM
861864

862865
}
863866

864-
virtual void initialize(int N_sub_hx, NS_HX_counterflow_eqs::E_UA_target_type od_UA_target_type);
867+
virtual void initialize(int N_sub_hx, NS_HX_counterflow_eqs::E_UA_target_type od_UA_target_type,
868+
double yr_inflation);
865869
};
866870

867871
namespace N_compact_hx
@@ -907,10 +911,12 @@ class C_CO2_to_air_cooler
907911

908912
double m_eta_fan; //[-] Fan isentropic efficiency
909913
int m_N_nodes_pass; //[-] Number of nodes per pass
914+
double m_yr_inflation; //[yr] Inflation year target
910915

911916
S_des_par_ind()
912917
{
913-
m_T_amb_des = m_elev = std::numeric_limits<double>::quiet_NaN();
918+
m_T_amb_des = m_elev = m_yr_inflation =
919+
std::numeric_limits<double>::quiet_NaN();
914920

915921
// Set realistic default values so model can solve without inputs for these values
916922
m_eta_fan = 0.5;
@@ -1414,7 +1420,8 @@ class C_CO2_to_air_cooler
14141420
double & k_air /*W/m-K*/, double & Pr_air);
14151421

14161422
double /*M$*/ calculate_equipment_cost(double UA /*kWt/K*/, double V_material /*m^3*/,
1417-
double T_hot_in /*K*/, double P_hot_in /*kPa*/, double m_dot_hot /*kg/s*/);
1423+
double T_hot_in /*K*/, double P_hot_in /*kPa*/, double m_dot_hot /*kg/s*/,
1424+
double yr_inflation /*yr*/);
14181425

14191426
double /*M$*/ calculate_bare_erected_cost(double cost_equipment /*M$*/);
14201427
};

0 commit comments

Comments
 (0)