From 9db25bdb1ac6727455d730d7ec8cdb9a76f2e4ac Mon Sep 17 00:00:00 2001 From: Taylor Brown <60201147+taylorbrown75@users.noreply.github.com> Date: Fri, 6 Dec 2024 12:03:01 -0700 Subject: [PATCH] Pass optimizer results even if it fails. Update heat_sink test problem. --- ssc/cmod_csp_heatsink.cpp | 107 +++++++++++------------ tcs/csp_solver_pc_heat_sink_physical.cpp | 39 ++++++++- tcs/heat_exchangers.cpp | 14 +-- tcs/heat_exchangers.h | 3 +- 4 files changed, 96 insertions(+), 67 deletions(-) diff --git a/ssc/cmod_csp_heatsink.cpp b/ssc/cmod_csp_heatsink.cpp index 7f84a48e1..a9bbe3f09 100644 --- a/ssc/cmod_csp_heatsink.cpp +++ b/ssc/cmod_csp_heatsink.cpp @@ -53,95 +53,90 @@ class cm_csp_heatsink : public compute_module void exec() { - double dT_subcool = 30; //[dC] Steam temp diff below outlet + // Define Steam Inlet Conditions + double T_ext_cold = 120; //[C] Steam inlet temp + double P_ext_cold = 4.762 * 100.0; //[kPa] Inlet steam pressure - // Define Outlet Steam Conditions + // Get inlet steam properties water_state ms_water_props; - double Q_ext_hot = 0.75; // Outlet Steam Quality - double T_ext_hot = 150; // [C] Outlet Steam Temp - - int prop_error_code = water_TQ(T_ext_hot + 273.15, Q_ext_hot, &ms_water_props); - - double P_ext_hot = ms_water_props.pres; // [kPa] Outlet Steam Pressure - double h_ext_hot = ms_water_props.enth; // [kJ/kg] Outlet Steam Enthalpy - double dens_ext_hot = ms_water_props.dens; //[kg/m3] Outlet steam density - double k_ext_hot = water_cond(dens_ext_hot, T_ext_hot + 273.15); // [W/m-K] - double mu_ext_hot = water_visc(dens_ext_hot, T_ext_hot + 273.15); // [uPa-s] - - // Define Inlet Steam Conditions - double T_ext_cold = T_ext_hot - dT_subcool; // [C] Inlet water temp - double P_ext_cold = P_ext_hot; // [kPa] Inlet Steam Pressure - - prop_error_code = water_TP(T_ext_cold + 273.15, P_ext_cold, &ms_water_props); - + int prop_error_code = water_TP(T_ext_cold + 273.15, P_ext_cold, &ms_water_props); double h_ext_cold = ms_water_props.enth; // [kJ/kg] Inlet water enthalpy double Q_ext_cold = ms_water_props.qual; // [] Inlet water quality (should be 0, n/a) double dens_ext_cold = ms_water_props.dens; // [kg/m3] Inlet water density - double k_ext_cold = water_cond(dens_ext_cold, T_ext_cold + 273.15); // [W/m-K] - double mu_ext_cold = water_visc(dens_ext_cold, T_ext_cold + 273.15); // [uPa-s] + + // Define Outlet Steam Conditions + double Q_ext_hot = 0.75; // Outlet Steam Quality + double P_ext_hot = P_ext_cold; //[kPa] Outlet Steam Pressure + + // Outlet steam properties + prop_error_code = water_PQ(P_ext_hot, Q_ext_hot, &ms_water_props); + double h_ext_hot = ms_water_props.enth; // [kJ/kg] Outlet Steam Enthalpy + double dens_ext_hot = ms_water_props.dens; //[kg/m3] Outlet steam density + double T_ext_hot = ms_water_props.temp - 273.15; // [C] Outlet Steam Temp // Initialize C_HX_htf_to_steam m_hx; int hot_fl = 21; // HTF fl id - int N_sub_hx = 5000; + int N_sub_hx = 500; NS_HX_counterflow_eqs::E_UA_target_type od_target_type = NS_HX_counterflow_eqs::E_UA_target_type::E_constant_UA; m_hx.initialize(hot_fl, N_sub_hx, od_target_type); // Design - double T_htf_hot = 250; //[C] + double T_htf_hot = 300; //[C] double T_htf_cold = 200; //[C] - double q_design = 5.19; //[MW] + double q_design = 5; //[MW] C_HX_counterflow_CRM::S_des_solved des_solved; m_hx.design_w_TP_PH(T_htf_hot + 273.15, 1.0, T_htf_cold + 273.15, 1.0, P_ext_cold, h_ext_cold, P_ext_hot, h_ext_hot, q_design * 1e3, des_solved); // Off Design - double T_htf_hot_od = T_htf_hot; - double T_htf_cold_od = T_htf_cold; - double od_tol = 1e-3; - double mdot_htf_od = 0.5 * m_hx.ms_des_calc_UA_par.m_m_dot_hot_des; + double T_htf_hot_od = 295.9725; //[C] + double od_tol = 1e-5; + double mdot_htf_od = 22.90448; //[kg/s] double h_htf_hot_od = m_hx.mc_hot_fl.enth(T_htf_hot_od + 273.15) * 1e-3; //[kJ/kg] - double h_htf_cold_od = m_hx.mc_hot_fl.enth(T_htf_cold_od + 273.15) * 1e-3; //[kJ/kg] double q_dot_calc, h_ext_out_calc, h_htf_out_calc; std::vector mdot_vec; std::vector h_vec; - //double mdot_min = 0.1; - //double mdot_max = 2 * m_hx.ms_des_calc_UA_par.m_m_dot_cold_des; - double mdot_min = 2.605; - double mdot_max = 2.8; - int total_runs = 20; - for (int i = 0; i < total_runs; i++) + double mdot_min = 0.75 * m_hx.ms_des_calc_UA_par.m_m_dot_cold_des; + double mdot_max = 1.5 * m_hx.ms_des_calc_UA_par.m_m_dot_cold_des; + + // Manually run range of steam mass flow rates + if (true) { - double frac = (double)i / (double)total_runs; - double mdot = mdot_min + (frac * (mdot_max - mdot_min)); - try - { - m_hx.off_design_solution_fixed_dP_enth(h_ext_cold, P_ext_cold, mdot, P_ext_hot, - h_htf_hot_od, 1.0, mdot_htf_od, 1.0, od_tol, - q_dot_calc, h_ext_out_calc, h_htf_out_calc); - } - catch (C_csp_exception exc) + int total_runs = 200; + for (int i = 0; i < total_runs; i++) { - h_ext_out_calc = 0; + double frac = (double)i / (double)total_runs; + double mdot = mdot_min + (frac * (mdot_max - mdot_min)); + try + { + m_hx.off_design_solution_fixed_dP_enth(h_ext_cold, P_ext_cold, mdot, P_ext_hot, + h_htf_hot_od, 1.0, mdot_htf_od, 1.0, od_tol, + q_dot_calc, h_ext_out_calc, h_htf_out_calc); + } + catch (C_csp_exception exc) + { + h_ext_out_calc = 0; + } + + h_vec.push_back(h_ext_out_calc); + mdot_vec.push_back(mdot); } - - h_vec.push_back(h_ext_out_calc); - mdot_vec.push_back(mdot); } - - - double mdot_ext_calc; - - m_hx.off_design_target_cold_PH_out(h_ext_hot, 0.1, 2* m_hx.ms_des_calc_UA_par.m_m_dot_cold_des, P_ext_cold, h_ext_cold, + // Optimize to find steam mdot + double mdot_ext_calc, tol_solved; + int solve_code = m_hx.off_design_target_cold_PH_out(h_ext_hot, mdot_min, mdot_max, P_ext_cold, h_ext_cold, P_ext_hot, 1.0, h_htf_hot_od, 1.0, mdot_htf_od, od_tol, - q_dot_calc, h_ext_out_calc, h_htf_out_calc, mdot_ext_calc); - - + q_dot_calc, h_ext_out_calc, h_htf_out_calc, mdot_ext_calc, tol_solved); + // Off design Outlet steam properties + prop_error_code = water_PH(P_ext_hot, h_ext_out_calc, &ms_water_props); + double Q_ext_hot_od = ms_water_props.qual; // [] Outlet Steam Quality + double T_ext_hot_od = ms_water_props.temp - 273.15; // [C] Outlet Steam Temp int x = 0; } diff --git a/tcs/csp_solver_pc_heat_sink_physical.cpp b/tcs/csp_solver_pc_heat_sink_physical.cpp index 7a0a69ba4..3631fd3db 100644 --- a/tcs/csp_solver_pc_heat_sink_physical.cpp +++ b/tcs/csp_solver_pc_heat_sink_physical.cpp @@ -293,7 +293,7 @@ void C_pc_heat_sink_physical::call(const C_csp_weatherreader::S_outputs &weather double m_dot_htf = inputs.m_m_dot / 3600.0; //[kg/s] int standby_control = inputs.m_standby_control; //[-] 1: On, 2: Standby, 3: Off - double q_dot, T_c_out, T_h_out_C, m_dot_c; + double q_dot, T_c_out, T_h_out_C, m_dot_c, tol_solved; // Handle no mass flow coming in if (inputs.m_m_dot < 1e-5 && standby_control == ON) @@ -351,14 +351,14 @@ void C_pc_heat_sink_physical::call(const C_csp_weatherreader::S_outputs &weather try { // Get HTF inlet enthalpy - double h_htf_cold = mc_pc_htfProps.enth(htf_state_in.m_temp + 273.15) * 1e-3; //[kJ/kg] + double h_htf_hot = mc_pc_htfProps.enth(htf_state_in.m_temp + 273.15) * 1e-3; //[kJ/kg] // Run Off design to find steam mdot to hit enthalpy target double h_ext_out_calc, h_htf_out_calc; int solve_code = m_hx.off_design_target_cold_PH_out(m_h_ext_hot_des, m_m_dot_ext_min, m_m_dot_ext_max, ms_params.m_P_ext_cold_des, m_h_ext_cold_des, ms_params.m_P_ext_hot_des, - 1.0, h_htf_cold, 1.0, m_dot_htf, ms_params.m_od_tol, - q_dot, h_ext_out_calc, h_htf_out_calc, m_dot_c); + 1.0, h_htf_hot, 1.0, m_dot_htf, ms_params.m_od_tol, + q_dot, h_ext_out_calc, h_htf_out_calc, m_dot_c, tol_solved); if (solve_code == C_monotonic_eq_solver::CONVERGED) { @@ -378,6 +378,37 @@ void C_pc_heat_sink_physical::call(const C_csp_weatherreader::S_outputs &weather } else { + // test why it failed + if (true) + { + std::vector mdot_vec; + std::vector h_vec; + int total_runs = 200; + for (int i = 0; i < total_runs; i++) + { + double frac = (double)i / (double)total_runs; + double mdot = m_m_dot_ext_min + (frac * (m_m_dot_ext_max - m_m_dot_ext_min)); + try + { + m_hx.off_design_solution_fixed_dP_enth(m_h_ext_cold_des, ms_params.m_P_ext_cold_des, mdot, ms_params.m_P_ext_hot_des, + h_htf_hot, 1.0, m_dot_htf, 1.0, ms_params.m_od_tol, + q_dot, h_ext_out_calc, h_htf_out_calc); + } + catch (C_csp_exception exc) + { + h_ext_out_calc = 0; + } + + h_vec.push_back(h_ext_out_calc); + mdot_vec.push_back(mdot); + } + + + int x = 0; + } + + + // Could not solve q_dot = 0; T_h_out_C = htf_state_in.m_temp; diff --git a/tcs/heat_exchangers.cpp b/tcs/heat_exchangers.cpp index c76112906..694ce6499 100644 --- a/tcs/heat_exchangers.cpp +++ b/tcs/heat_exchangers.cpp @@ -3181,7 +3181,8 @@ int C_HX_htf_to_steam::off_design_target_cold_PH_out(double h_c_out_target /*kJ/ double P_c_in /*kPa*/, double h_c_in /*kJ/kg*/, double P_c_out /*kPa*/, double P_h_in /*kPa*/, double h_h_in /*kJ/kg*/, double P_h_out /*kPa*/, double m_dot_h /*kg/s*/, double od_tol /*-*/, - double& q_dot /*kWt*/, double& h_c_out /*kJ/kg*/, double& h_h_out /*kJ/kg*/, double& m_dot_c /*kg/s*/) + double& q_dot /*kWt*/, double& h_c_out /*kJ/kg*/, double& h_h_out /*kJ/kg*/, double& m_dot_c /*kg/s*/, + double& tol_solved) { // ADD inputs double max_iter = 1000; @@ -3197,7 +3198,7 @@ int C_HX_htf_to_steam::off_design_target_cold_PH_out(double h_c_out_target /*kJ/ C_monotonic_eq_solver h_out_solver(h_out_eq); h_out_solver.settings(od_tol, max_iter, m_dot_c_min, m_dot_c_max, false); - double m_dot_c_solved, tol_solved; + double m_dot_c_solved; int iter_solved = -1; if (false) @@ -3234,14 +3235,15 @@ int C_HX_htf_to_steam::off_design_target_cold_PH_out(double h_c_out_target /*kJ/ h_c_out = h_out_eq.m_h_c_out; //[kJ/kg] h_h_out = h_out_eq.m_h_h_out; //[kJ/kg] m_dot_c = h_out_eq.m_m_dot_c; //[kg/s] + } else { // Could not converge - q_dot = 0.0; //[kJ] - h_c_out = h_c_in; //[kJ/kg] - h_h_out = h_h_in; //[kJ/kg] - m_dot_c = 0.0; //[kg/s] + q_dot = h_out_eq.m_q_dot; //[kJ] + h_c_out = h_out_eq.m_h_c_out; //[kJ/kg] + h_h_out = h_out_eq.m_h_h_out; //[kJ/kg] + m_dot_c = h_out_eq.m_m_dot_c; //[kg/s] } return m_dot_code; diff --git a/tcs/heat_exchangers.h b/tcs/heat_exchangers.h index 11bed2574..957b501d1 100644 --- a/tcs/heat_exchangers.h +++ b/tcs/heat_exchangers.h @@ -764,7 +764,8 @@ class C_HX_htf_to_steam : public C_HX_counterflow_CRM double P_c_in /*kPa*/, double h_c_in /*kJ/kg*/, double P_c_out /*kPa*/, double P_h_in /*kPa*/, double h_h_in /*kJ/kg*/, double P_h_out /*kPa*/, double m_dot_h /*kg/s*/, double od_tol /*-*/, - double& q_dot /*kWt*/, double& h_c_out /*kJ/kg*/, double& h_h_out /*kJ/kg*/, double& m_dot_c /*kg/s*/); + double& q_dot /*kWt*/, double& h_c_out /*kJ/kg*/, double& h_h_out /*kJ/kg*/, double& m_dot_c /*kg/s*/, + double& tol_solved); class C_MEQ__target_cold_PH_out : public C_monotonic_equation {