diff --git a/ssc/cmod_etes_ptes.cpp b/ssc/cmod_etes_ptes.cpp index 942bfb297..8a2394007 100644 --- a/ssc/cmod_etes_ptes.cpp +++ b/ssc/cmod_etes_ptes.cpp @@ -373,6 +373,10 @@ static var_info _cm_vtab_etes_ptes[] = { { SSC_OUTPUT, SSC_ARRAY, "disp_presolve_nvar", "Dispatch number of variables in problem", "", "", "", "sim_type=1", "", "" }, { SSC_OUTPUT, SSC_ARRAY, "disp_solve_time", "Dispatch solver time", "sec", "", "", "sim_type=1", "", "" }, + { SSC_OUTPUT, SSC_ARRAY, "operating_modes_a", "First 3 operating modes tried", "", "", "", "sim_type=1", "", "" }, + { SSC_OUTPUT, SSC_ARRAY, "operating_modes_b", "Next 3 operating modes tried", "", "", "", "sim_type=1", "", "" }, + { SSC_OUTPUT, SSC_ARRAY, "operating_modes_c", "Final 3 operating modes tried", "", "", "", "sim_type=1", "", "" }, + // Annual single-value outputs { SSC_OUTPUT, SSC_NUMBER, "annual_energy", "Annual total electric power to grid", "kWhe", "", "", "sim_type=1", "", "" }, @@ -918,6 +922,10 @@ class cm_etes_ptes : public compute_module csp_solver.mc_reported_outputs.assign(C_csp_solver::C_solver_outputs::DISPATCH_PRES_NVAR, allocate("disp_presolve_nvar", n_steps_fixed), n_steps_fixed); csp_solver.mc_reported_outputs.assign(C_csp_solver::C_solver_outputs::DISPATCH_SOLVE_TIME, allocate("disp_solve_time", n_steps_fixed), n_steps_fixed); + csp_solver.mc_reported_outputs.assign(C_csp_solver::C_solver_outputs::CTRL_OP_MODE_SEQ_A, allocate("operating_modes_a", n_steps_fixed), n_steps_fixed); + csp_solver.mc_reported_outputs.assign(C_csp_solver::C_solver_outputs::CTRL_OP_MODE_SEQ_B, allocate("operating_modes_b", n_steps_fixed), n_steps_fixed); + csp_solver.mc_reported_outputs.assign(C_csp_solver::C_solver_outputs::CTRL_OP_MODE_SEQ_C, allocate("operating_modes_c", n_steps_fixed), n_steps_fixed); + // ***************************************************** // ***************************************************** diff --git a/tcs/csp_solver_cr_heat_pump.cpp b/tcs/csp_solver_cr_heat_pump.cpp index fff085545..efd7e7a9e 100644 --- a/tcs/csp_solver_cr_heat_pump.cpp +++ b/tcs/csp_solver_cr_heat_pump.cpp @@ -169,14 +169,14 @@ void C_csp_cr_heat_pump::init(const C_csp_collector_receiver::S_csp_cr_init_inpu double eta_htf_pump = 0.85; //[-] used to back out pressure drop m_T_HT_HTF_avg_des = 0.5 * (m_T_HT_HTF_cold_des + m_T_HT_HTF_hot_des); //[C] - m_cp_HT_HTF_des = m_HT_htfProps->Cp(m_T_HT_HTF_avg_des + 273.15); //[kJ/kg-K] + m_cp_HT_HTF_des = m_HT_htfProps->Cp_ave(m_T_HT_HTF_cold_des + 273.15, m_T_HT_HTF_hot_des + 273.15); //[kJ/kg-K] double rho_HT_htf_des = m_HT_htfProps->dens(m_T_HT_HTF_avg_des + 273.15,1.0); //[kg/m3] m_m_dot_HT_des = m_q_dot_hot_out_des * 1.E3 / (m_cp_HT_HTF_des * (m_T_HT_HTF_hot_des - m_T_HT_HTF_cold_des)); //[kg/s] m_W_dot_HT_htf_pump_des = m_heat_pump_HT_htf_pump_coef*m_m_dot_HT_des*1.E-3; //[MWe] double HT_htf_deltaP = m_W_dot_HT_htf_pump_des*rho_HT_htf_des/m_m_dot_HT_des*eta_htf_pump; //[MPa] m_T_CT_HTF_avg_des = 0.5 * (m_T_CT_HTF_cold_des + m_T_CT_HTF_hot_des); //[C] - m_cp_CT_HTF_des = m_CT_htfProps->Cp(m_T_CT_HTF_avg_des + 273.15); //[kJ/kg-K] + m_cp_CT_HTF_des = m_CT_htfProps->Cp_ave(m_T_CT_HTF_cold_des + 273.15, m_T_CT_HTF_hot_des + 273.15); //[kJ/kg-K] double rho_CT_htf_des = m_CT_htfProps->dens(m_T_CT_HTF_avg_des + 273.15,1.0); //[kg/m3] m_m_dot_CT_des = m_q_dot_cold_in_des*1.E3/(m_cp_CT_HTF_des*(m_T_CT_HTF_hot_des-m_T_CT_HTF_cold_des)); //[kg/s] m_W_dot_CT_htf_pump_des = m_heat_pump_CT_htf_pump_coef*m_m_dot_CT_des*1.E-3; //[MWe] diff --git a/tcs/csp_solver_pc_ptes.cpp b/tcs/csp_solver_pc_ptes.cpp index cb5d088c8..28d1d19ab 100644 --- a/tcs/csp_solver_pc_ptes.cpp +++ b/tcs/csp_solver_pc_ptes.cpp @@ -149,14 +149,14 @@ void C_pc_ptes::init(C_csp_power_cycle::S_solved_params& solved_params) double eta_htf_pump = 0.85; //[-] used to back out pressure drop m_T_HT_HTF_avg_des = 0.5*(m_T_HT_HTF_cold_des + m_T_HT_HTF_hot_des); //[C] - m_cp_HT_HTF_des = m_HT_htfProps->Cp(m_T_HT_HTF_avg_des+273.15); //[kJ/kg-K] + m_cp_HT_HTF_des = m_HT_htfProps->Cp_ave(m_T_HT_HTF_cold_des + 273.15, m_T_HT_HTF_hot_des + 273.15); //[kJ/kg-K] m_m_dot_HT_des = m_q_dot_hot_in_des * 1.E3 / (m_cp_HT_HTF_des * (m_T_HT_HTF_hot_des - m_T_HT_HTF_cold_des)); //[kg/s] double rho_HT_htf_des = m_HT_htfProps->dens(m_T_HT_HTF_avg_des + 273.15, 1.0); //[kg/m3] m_W_dot_HT_htf_pump_des = m_HT_htf_pump_coef_des * m_m_dot_HT_des * 1.E-3; //[MWe] double HT_htf_deltaP = m_W_dot_HT_htf_pump_des * rho_HT_htf_des / m_m_dot_HT_des * eta_htf_pump; //[MPa] m_T_CT_HTF_avg_des = 0.5*(m_T_CT_HTF_cold_des + m_T_CT_HTF_hot_des); //[C] - m_cp_CT_HTF_des = m_CT_htfProps->Cp(m_T_CT_HTF_avg_des+273.15); //[kJ/kg-K] + m_cp_CT_HTF_des = m_CT_htfProps->Cp_ave(m_T_CT_HTF_cold_des + 273.15, m_T_CT_HTF_hot_des + 273.15); //[kJ/kg-K] m_m_dot_CT_des = m_q_dot_cold_to_CTES*1.E3/(m_cp_CT_HTF_des*(m_T_CT_HTF_hot_des-m_T_CT_HTF_cold_des)); //[kg/s] double rho_CT_htf_des = m_CT_htfProps->dens(m_T_CT_HTF_avg_des + 273.15, 1.0); //[kg/m3] m_W_dot_CT_htf_pump_des = m_CT_htf_pump_coef_des * m_m_dot_CT_des * 1.E-3; //[MWe] diff --git a/tcs/csp_solver_trough_collector_receiver.cpp b/tcs/csp_solver_trough_collector_receiver.cpp index 06d917be9..179c50374 100644 --- a/tcs/csp_solver_trough_collector_receiver.cpp +++ b/tcs/csp_solver_trough_collector_receiver.cpp @@ -590,7 +590,7 @@ bool C_csp_trough_collector_receiver::init_fieldgeom() m_nhdrsec = (int)ceil(float(m_nLoops) / float(m_nfsec * 2)); //We need to determine design information about the field for purposes of header sizing ONLY - m_c_htf_ave = m_htfProps.Cp((m_T_loop_out_des + m_T_loop_in_des) / 2.0)*1000.; //[J/kg-K] Specific heat + m_c_htf_ave = m_htfProps.Cp_ave(m_T_loop_in_des, m_T_loop_out_des) * 1000.; //[J/kg-K] Specific heat //Need to loop through to calculate the weighted average optical efficiency at design //Start by initializing sensitive variables @@ -873,7 +873,7 @@ double C_csp_trough_collector_receiver::get_pumping_parasitic_coef() double C_csp_trough_collector_receiver::get_min_power_delivery() { - double c_htf_ave = m_htfProps.Cp((m_T_startup + m_T_loop_in_des) / 2.0)*1000.; //[J/kg-K] Specific heat + double c_htf_ave = m_htfProps.Cp_ave(m_T_loop_in_des, m_T_startup) * 1000.; //[J/kg-K] Specific heat return m_m_dot_htfmin * m_nLoops * c_htf_ave * (m_T_startup - m_T_loop_in_des) * 1.e-6; // [MWt] } @@ -881,7 +881,7 @@ double C_csp_trough_collector_receiver::get_max_power_delivery(double T_cold_in { double T_in = T_cold_in + 273.15; // [K] double T_out = m_T_loop_out_des; // [K] - double c_htf_ave = m_htfProps.Cp((T_out + T_in) / 2.0) * 1000.; // [J/kg-K] + double c_htf_ave = m_htfProps.Cp_ave(T_in, T_out) * 1000.; // [J/kg-K] return m_m_dot_htfmax * m_nLoops * c_htf_ave * (T_out - T_in) * 1.e-6; // [MWt] } @@ -2644,7 +2644,7 @@ void C_csp_trough_collector_receiver::on(const C_csp_weatherreader::S_outputs &w // The controller also requires the receiver thermal output // 7.12.16 Now using the timestep-integrated-average temperature - double c_htf_ave = m_htfProps.Cp((m_T_sys_h_t_int + T_cold_in) / 2.0); //[kJ/kg-K] + double c_htf_ave = m_htfProps.Cp_ave(T_cold_in, m_T_sys_h_t_int); //[kJ/kg-K] cr_out_solver.m_q_thermal = (cr_out_solver.m_m_dot_salt_tot / 3600.0)*c_htf_ave*(m_T_sys_h_t_int - T_cold_in) / 1.E3; //[MWt] // Finally, the controller need the HTF outlet temperature from the field cr_out_solver.m_T_salt_hot = m_T_sys_h_t_int - 273.15; //[C] @@ -3419,7 +3419,7 @@ void C_csp_trough_collector_receiver::call(const C_csp_weatherreader::S_outputs { if (qq<3) { - m_c_htf_ave = m_htfProps.Cp((m_T_loop_out_des + m_TCS_T_htf_in[0]) / 2.0)*1000.; //Specific heat + m_c_htf_ave = m_htfProps.Cp_ave(m_TCS_T_htf_in[0], m_T_loop_out_des)*1000.; //Specific heat double qsum = 0.; for (int i = 0; i T_src_in_expected{ 250.00, 250.00, 250.00, 250.00, 250.00, 250.00, 250.00, 250.00, 296.51, 296.48, 296.44, 296.40, 296.34, 296.27, 296.18, 296.18, 380.00, 360.00, 293.00, 293.00, 293.00, 293.00, 293.00, 293.00 }; -// std::vector T_sink_in_expected{ 250.00, 250.00, 250.00, 250.00, 250.00, 250.00, 250.00, 250.00, 390.00, 390.00, 390.00, 390.00, -// 390.00, 390.00, 390.00, 390.00, 380.00, 360.00, 383.58, 383.54, 383.50, 383.46, 383.40, 383.31 }; std::vector T_sink_in_expected{ 250.00, 250.00, 250.00, 250.00, 250.00, 250.00, 250.00, 250.00, 390.00, 390.00, 390.00, 390.00, - 390.00, 390.00, 390.00, 390.00, 380.00, 360.00, 383.70, 383.66, 383.63, 383.58, 383.52, 383.43 }; + 390.00, 390.00, 390.00, 390.00, 380.00, 360.00, 383.70, 383.67, 383.63, 383.58, 383.52, 383.43 }; std::vector T_tank_cold_expected{ 292.97, 292.94, 292.91, 292.88, 292.85, 292.82, 292.79, 292.76, 292.73, 292.69, 292.65, 292.60, 292.54, 292.45, 292.33, 292.33, 292.17, 292.01, 294.38, 295.19, 295.61, 295.86, 296.02, 296.14 }; std::vector T_tank_hot_expected{ 390.91, 390.83, 390.75, 390.67, 390.59, 390.51, 390.43, 390.35, 389.48, 388.89, 388.46, 388.14, diff --git a/test/ssc_test/cmod_trough_physical_test.cpp b/test/ssc_test/cmod_trough_physical_test.cpp index 3c9cc095f..6303780c8 100644 --- a/test/ssc_test/cmod_trough_physical_test.cpp +++ b/test/ssc_test/cmod_trough_physical_test.cpp @@ -48,8 +48,8 @@ NAMESPACE_TEST(csp_trough, PowerTroughCmod, Default_NoFinancial) EXPECT_FALSE(errors); if (!errors) { EXPECT_NEAR_FRAC(power_trough.GetOutput("annual_energy"), 376824118, kErrorToleranceHi); - EXPECT_NEAR_FRAC(power_trough.GetOutput("annual_thermal_consumption"), 628313, kErrorToleranceHi); - EXPECT_NEAR_FRAC(power_trough.GetOutput("annual_tes_freeze_protection"), 590320, kErrorToleranceHi); + EXPECT_NEAR_FRAC(power_trough.GetOutput("annual_thermal_consumption"), 628322, kErrorToleranceHi); + EXPECT_NEAR_FRAC(power_trough.GetOutput("annual_tes_freeze_protection"), 590329, kErrorToleranceHi); EXPECT_NEAR_FRAC(power_trough.GetOutput("annual_field_freeze_protection"), 38042, kErrorToleranceHi); EXPECT_NEAR_FRAC(power_trough.GetOutput("capacity_factor"), 43.05, kErrorToleranceHi); EXPECT_NEAR_FRAC(power_trough.GetOutput("annual_W_cycle_gross"), 429613242, kErrorToleranceHi);