28 "Single phase fluid properties computed using bi-dimensional interpolation of tabulated "
32 params.
addParam<
bool>(
"create_pT_interpolations",
34 "Whether to load (from file) or create (from a fluid property object) "
35 "properties interpolations from pressure and temperature");
37 "create_ve_interpolations",
39 "Whether to load (from file) or create (from a fluid property object) "
40 "properties interpolations from specific volume and specific internal energy");
43 params.
addParam<UserObjectName>(
"fp",
"The name of the FluidProperties UserObject");
46 params.
addParam<FileName>(
"fluid_property_file",
47 "Name of the csv file containing the tabulated fluid property data.");
49 "fluid_property_ve_file",
50 "Name of the csv file containing the tabulated (v,e) fluid property data.");
51 params.
addParam<FileName>(
"fluid_property_output_file",
52 "Name of the CSV file which can be output with the tabulation. This "
53 "file can then be read as a 'fluid_property_file'");
55 "fluid_property_ve_output_file",
56 "Name of the CSV file which can be output with the (v,e) tabulation. This "
57 "file can then be read as a 'fluid_property_ve_file'");
60 "Whether to save the csv fluid properties file",
61 "This parameter is no longer required. Whether to save a CSV tabulation file is controlled "
62 "by specifying the 'fluid_property_output_file' parameter");
63 params.
addParam<
bool>(
"skip_header_tabulation",
65 "Whether to skip the header in the tabulation output, useful for testing");
69 "density enthalpy internal_energy viscosity k c cv cp entropy pressure temperature",
70 "density enthalpy internal_energy viscosity");
73 "Properties to interpolate. If unspecified and a data file is "
74 "provided, the properties from the data file will be used. If "
75 "specified, some properties from the data file can be ignored.");
79 "temperature_min", 300,
"temperature_min > 0",
"Minimum temperature for tabulated data.");
80 params.
addParam<Real>(
"temperature_max", 500,
"Maximum temperature for tabulated data.");
82 "pressure_min", 1e5,
"pressure_min > 0",
"Minimum pressure for tabulated data.");
83 params.
addParam<Real>(
"pressure_max", 50.0e6,
"Maximum pressure for tabulated data.");
85 "num_T", 100,
"num_T > 0",
"Number of points to divide temperature range.");
87 "num_p", 100,
"num_p > 0",
"Number of points to divide pressure range.");
90 params.
addParam<Real>(
"e_min",
"Minimum specific internal energy for tabulated data.");
91 params.
addParam<Real>(
"e_max",
"Maximum specific internal energy for tabulated data.");
93 "v_min",
"v_min > 0",
"Minimum specific volume for tabulated data.");
95 "v_max",
"v_max > 0",
"Maximum specific volume for tabulated data.");
96 params.
addParam<
bool>(
"construct_pT_from_ve",
98 "If the lookup table (p, T) as functions of (v, e) should be constructed.");
99 params.
addParam<
bool>(
"construct_pT_from_vh",
101 "If the lookup table (p, T) as functions of (v, h) should be constructed.");
106 "Number of points to divide specific volume range for (v,e) lookups.");
110 "Number of points to divide specific internal energy "
111 "range for (v,e) lookups.");
115 "Option to use a base-10 logarithmically-spaced grid for specific volume instead of a "
116 "linearly-spaced grid.");
120 "Option to use a base-10 logarithmically-spaced grid for specific internal energy instead "
121 "of a linearly-spaced grid.");
125 "Option to use a base-10 logarithmically-spaced grid for specific enthalpy instead "
126 "of a linearly-spaced grid.");
130 "error_on_out_of_bounds",
131 "Whether pressure or temperature from tabulation exceeding user-specified bounds leads to "
133 "This parameter has been replaced by the 'out_of_bounds_behavior' parameter which offers "
134 "more flexibility. The option to error is called 'throw' in that parameter.");
136 MooseEnum OOBBehavior(
"ignore throw declare_invalid warn_invalid set_to_closest_bound",
"throw");
139 "Property evaluation behavior when evaluated outside the "
140 "user-specified or tabulation-specified bounds");
146 "allow_fp_and_tabulation",
false,
"Whether to allow the two sources of data concurrently");
149 "fluid_property_output_file fluid_property_ve_output_file",
150 "Tabulation file read/write");
152 "Variable set conversion");
154 "e_max v_min v_max error_on_out_of_bounds out_of_bounds_behavior",
155 "Tabulation and interpolation bounds");
157 "num_T num_p num_v num_e use_log_grid_v use_log_grid_e use_log_grid_h",
158 "Tabulation and interpolation discretization");
165 _file_name_in(isParamValid(
"fluid_property_file") ? getParam<FileName>(
"fluid_property_file")
168 isParamValid(
"fluid_property_ve_file") ? getParam<FileName>(
"fluid_property_ve_file") :
""),
169 _file_name_out(isParamValid(
"fluid_property_output_file")
170 ? getParam<FileName>(
"fluid_property_output_file")
172 _file_name_ve_out(isParamValid(
"fluid_property_ve_output_file")
173 ? getParam<FileName>(
"fluid_property_ve_output_file")
175 _save_file(isParamValid(
"save_file") ? getParam<bool>(
"save_file")
176 : (isParamValid(
"fluid_property_output_file") ||
177 isParamValid(
"fluid_property_ve_output_file"))),
178 _create_direct_pT_interpolations(getParam<bool>(
"create_pT_interpolations")),
179 _create_direct_ve_interpolations(getParam<bool>(
"create_ve_interpolations")),
180 _temperature_min(getParam<Real>(
"temperature_min")),
181 _temperature_max(getParam<Real>(
"temperature_max")),
182 _pressure_min(getParam<Real>(
"pressure_min")),
183 _pressure_max(getParam<Real>(
"pressure_max")),
184 _num_T(getParam<unsigned
int>(
"num_T")),
185 _num_p(getParam<unsigned
int>(
"num_p")),
187 _fp(isParamValid(
"input_fp") ? ((getParam<UserObjectName>(
"input_fp") !=
name())
191 _allow_fp_and_tabulation(getParam<bool>(
"allow_fp_and_tabulation")),
192 _interpolated_properties_enum(getParam<
MultiMooseEnum>(
"interpolated_properties")),
193 _interpolated_properties(),
194 _interpolate_density(false),
195 _interpolate_enthalpy(false),
196 _interpolate_internal_energy(false),
197 _interpolate_viscosity(false),
198 _interpolate_k(false),
199 _interpolate_c(false),
200 _interpolate_cp(false),
201 _interpolate_cv(false),
202 _interpolate_entropy(false),
203 _interpolate_pressure(false),
204 _interpolate_temperature(false),
205 _density_idx(
libMesh::invalid_uint),
206 _enthalpy_idx(
libMesh::invalid_uint),
207 _internal_energy_idx(
libMesh::invalid_uint),
208 _viscosity_idx(
libMesh::invalid_uint),
211 _cp_idx(
libMesh::invalid_uint),
212 _cv_idx(
libMesh::invalid_uint),
213 _entropy_idx(
libMesh::invalid_uint),
216 _csv_reader(_file_name_in, &_communicator),
217 _construct_pT_from_ve(getParam<bool>(
"construct_pT_from_ve")),
218 _construct_pT_from_vh(getParam<bool>(
"construct_pT_from_vh")),
219 _initial_setup_done(false),
220 _num_v(getParam<unsigned
int>(
"num_v")),
221 _num_e(getParam<unsigned
int>(
"num_e")),
222 _log_space_v(getParam<bool>(
"use_log_grid_v")),
223 _log_space_e(getParam<bool>(
"use_log_grid_e")),
224 _log_space_h(getParam<bool>(
"use_log_grid_h")),
225 _OOBBehavior(getParam<
MooseEnum>(
"out_of_bounds_behavior")),
235 mooseError(
"temperature_max must be greater than temperature_min");
237 mooseError(
"pressure_max must be greater than pressure_min");
242 _e_min = getParam<Real>(
"e_min");
243 _e_max = getParam<Real>(
"e_max");
248 "Either both or none of the min and max values of the specific internal energy "
249 "should be specified");
254 _v_min = getParam<Real>(
"v_min");
255 _v_max = getParam<Real>(
"v_max");
260 "Either both or none of the min and max values of the specific volume "
261 "should be specified");
266 if (
isParamValid(
"error_on_out_of_bounds") && getParam<bool>(
"error_on_out_of_bounds") &&
268 paramError(
"out_of_bounds_behavior",
"Inconsistent selection of out of bounds behavior.");
269 else if (
isParamValid(
"error_on_out_of_bounds") && !getParam<bool>(
"error_on_out_of_bounds"))
278 "fluid_property_file",
279 "Cannot supply both a fluid properties object with 'input_fp' and a source tabulation "
280 "file with 'fluid_property_file', unless 'allow_fp_and_tabulation' is set to true");
283 "fluid_property_file",
284 "Either a fluid properties object with the parameter 'input_fp' and a source tabulation "
285 "file with the parameter 'fluid_property_file' or 'fluid_property_ve_file' should "
288 paramError(
"create_pT_interpolations",
"Must create either (p,T) or (v,e) interpolations");
294 mooseWarning(
"User-specified bounds in pressure and temperature are ignored when reading a "
295 "'fluid_property_file'. The tabulation bounds are selected "
296 "from the bounds of the input tabulation.");
298 mooseWarning(
"User-specified grid sizes in pressure and temperature are ignored when reading a "
299 "'fluid_property_file'. The tabulation bounds are selected "
300 "from the bounds of the input tabulation.");
305 "User-specified bounds in specific volume and internal energy are ignored when reading a "
306 "'fluid_property_ve_file'. The tabulation bounds are selected "
307 "from the bounds of the input tabulation.");
309 mooseWarning(
"User-specified grid sizes in specific volume and internal energy are ignored "
310 "when reading a 'fluid_property_ve_file'. The tabulation widths are read "
311 "from the input tabulation.");
314 "User specfied logarithmic grids in specific volume and energy are ignored when reading a "
315 "'fluid_properties_ve_file'. The tabulation grid is read from the input tabulation");
334 "No FluidProperties (specified with 'input_fp' parameter) exists. Either "
335 "specify a 'input_fp' or "
336 "specify a (p, T) tabulation file with the 'fluid_property_file' parameter");
337 _console <<
name() +
": Generating (p, T) tabulated data\n";
353 "No FluidProperties (specified with 'input_fp' parameter) exists. Either "
354 "specify a 'input_fp' or "
355 "specify a (v, e) tabulation file with the 'fluid_property_ve_file' parameter");
356 _console <<
name() +
": Generating (v, e) tabulated data\n";
384 return "TabulationFromFile";
408 auto p_from_v_e = [&](Real
v, Real e, Real & new_p, Real & dp_dv, Real & dp_de)
409 { this->
p_from_v_e(v, e, new_p, dp_dv, dp_de); };
410 auto T_from_v_e = [&](Real
v, Real e, Real & new_T, Real & dT_dv, Real & dT_de)
411 { this->
T_from_v_e(v, e, new_T, dT_dv, dT_de); };
422 name() +
"::v_from_p_T",
430 return 1.0 /
_fp->rho_from_p_T(pressure, temperature);
441 ADReal pressure_nc = pressure, temperature_nc = temperature;
447 ADReal pressure_nc = pressure, temperature_nc = temperature;
451 { this->
p_from_v_e(v, e, new_p, dp_dv, dp_de); };
453 { this->
T_from_v_e(v, e, new_T, dT_dv, dT_de); };
464 name() +
"::v_from_p_T",
472 return 1.0 /
_fp->rho_from_p_T(pressure, temperature);
480 Real pressure, Real temperature, Real &
v, Real & dv_dp, Real & dv_dT)
const
482 Real
rho = 0, drho_dp = 0, drho_dT = 0;
487 pressure, temperature,
rho, drho_dp, drho_dT);
492 _fp->rho_from_p_T(pressure, temperature,
rho, drho_dp, drho_dT);
498 dv_dp = -drho_dp / (
rho *
rho);
499 dv_dT = -drho_dT / (
rho *
rho);
511 return 1. /
v_from_p_T(pressure, temperature);
515 return _fp->rho_from_p_T(pressure, temperature);
526 ADReal pressure_nc = pressure, temperature_nc = temperature;
531 return 1. /
v_from_p_T(pressure, temperature);
535 return _fp->rho_from_p_T(pressure, temperature);
543 Real pressure, Real temperature, Real &
rho, Real & drho_dp, Real & drho_dT)
const
549 pressure, temperature,
rho, drho_dp, drho_dT);
563 _fp->rho_from_p_T(pressure, temperature,
rho, drho_dp, drho_dT);
571 const ADReal & temperature,
578 ADReal p = pressure,
T = temperature;
585 _fp->rho_from_p_T(pressure, temperature,
rho, drho_dp, drho_dT);
600 Real
p, Real s, Real &
rho, Real & drho_dp, Real & drho_ds)
const
602 Real
T, dT_dp, dT_ds;
604 Real drho_dp_T, drho_dT;
606 drho_dp = drho_dT * dT_dp + drho_dp_T;
607 drho_ds = drho_dT * dT_ds;
625 auto lambda = [&](Real
v, Real current_e, Real & new_T, Real & dT_dv, Real & dT_de)
626 {
T_from_v_e(
v, current_e, new_T, dT_dv, dT_de); };
632 name() +
"::e_from_p_T",
640 return _fp->e_from_p_T(pressure, temperature);
651 ADReal pressure_nc = pressure, temperature_nc = temperature;
660 ADReal pressure_nc = pressure, temperature_nc = temperature;
664 {
T_from_v_e(
v, current_e, new_T, dT_dv, dT_de); };
670 name() +
"::e_from_p_T",
678 return _fp->e_from_p_T(pressure, temperature);
686 Real pressure, Real temperature, Real & e, Real & de_dp, Real & de_dT)
const
693 pressure, temperature, e, de_dp, de_dT);
703 de_dp = (
e_from_p_T(pressure * (1 +
eps), temperature) - e) / (
eps * pressure);
704 de_dT = (
e_from_p_T(pressure, temperature * (1 +
eps)) - e) / (
eps * temperature);
709 _fp->e_from_p_T(pressure, temperature, e, de_dp, de_dT);
723 {
p_from_v_e(
v, current_e, new_p, dp_dv, dp_de); };
729 name() +
"::e_from_p_rho",
752 auto lambda = [&](Real
v, Real current_e, Real & new_p, Real & dp_dv, Real & dp_de)
753 {
p_from_v_e(
v, current_e, new_p, dp_dv, dp_de); };
759 name() +
"::e_from_p_rho",
775 Real pressure, Real
rho, Real & e, Real & de_dp, Real & de_drho)
const
778 Real
T, dT_dp, dT_drho;
782 Real de_dp_at_const_T, de_dT;
783 e_from_p_T(pressure,
T, e, de_dp_at_const_T, de_dT);
786 Real rho_pT, drho_dp, drho_dT;
790 de_drho = de_dT * dT_drho;
791 de_dp = de_dp_at_const_T - (de_drho * drho_dp);
801 auto lambda = [&](Real
p, Real current_T, Real & new_rho, Real & drho_dp, Real & drho_dT)
808 name() +
"::T_from_p_rho",
821 ") and density (rho = ",
823 ") to temperature failed to converge.");
840 name() +
"::T_from_p_rho",
845 if (std::isnan(
T.value()))
848 ") and density (rho = ",
850 ") to temperature failed to converge.");
861 Real pressure, Real
rho, Real &
T, Real & dT_dp, Real & dT_drho)
const
872 auto lambda = [&](Real
p, Real current_T, Real & new_s, Real & ds_dp, Real & ds_dT)
873 {
s_from_p_T(
p, current_T, new_s, ds_dp, ds_dT); };
879 name() +
"::T_from_p_s",
887 ") and entropy (s = ",
889 ") to temperature failed to converge.");
895 Real pressure, Real s, Real &
T, Real & dT_dp, Real & dT_ds)
const
923 return _fp->h_from_p_T(pressure, temperature);
934 ADReal pressure_nc = pressure, temperature_nc = temperature;
948 return _fp->h_from_p_T(pressure, temperature);
955 Real pressure, Real temperature, Real & h, Real & dh_dp, Real & dh_dT)
const
962 pressure, temperature,
h, dh_dp, dh_dT);
965 Real
v, e, dv_dp, dv_dT, de_dp, de_dT;
967 pressure, temperature,
v, dv_dp, dv_dT, e, de_dp, de_dT);
970 dh_dp = dh_dv * dv_dp + dh_de * de_dp;
971 dh_dT = dh_dv * dv_dT + dh_de * de_dT;
979 _fp->h_from_p_T(pressure, temperature,
h, dh_dp, dh_dT);
996 return _fp->mu_from_p_T(pressure, temperature);
1004 Real pressure, Real temperature, Real &
mu, Real & dmu_dp, Real & dmu_dT)
const
1010 pressure, temperature,
mu, dmu_dp, dmu_dT);
1015 _fp->mu_from_p_T(pressure, temperature,
mu, dmu_dp, dmu_dT);
1032 return _fp->c_from_p_T(pressure, temperature);
1040 Real pressure, Real temperature, Real &
c, Real & dc_dp, Real & dc_dT)
const
1050 _fp->c_from_p_T(pressure, temperature,
c, dc_dp, dc_dT);
1067 return _fp->cp_from_p_T(pressure, temperature);
1075 Real pressure, Real temperature, Real & cp, Real & dcp_dp, Real & dcp_dT)
const
1085 _fp->cp_from_p_T(pressure, temperature, cp, dcp_dp, dcp_dT);
1102 return _fp->cv_from_p_T(pressure, temperature);
1110 Real pressure, Real temperature, Real & cv, Real & dcv_dp, Real & dcv_dT)
const
1120 _fp->cv_from_p_T(pressure, temperature, cv, dcv_dp, dcv_dT);
1137 return _fp->k_from_p_T(pressure, temperature);
1145 Real pressure, Real temperature, Real & k, Real & dk_dp, Real & dk_dT)
const
1151 pressure, temperature, k, dk_dp, dk_dT);
1156 return _fp->k_from_p_T(pressure, temperature, k, dk_dp, dk_dT);
1173 return _fp->s_from_p_T(pressure, temperature);
1189 Real
v, e, dv_dp, dv_dT, de_dp, de_dT;
1193 ds_dp = ds_dv * dv_dp + ds_de * de_dp;
1194 ds_dT = ds_dv * dv_dT + ds_de * de_dT;
1202 _fp->s_from_p_T(
p,
T, s, ds_dp, ds_dT);
1220 auto lambda = [&](Real
v, Real current_e, Real & new_h, Real & dh_dv, Real & dh_de)
1221 { h_from_v_e(
v, current_e, new_h, dh_dv, dh_de); };
1227 name() +
"::e_from_v_h",
1234 return _fp->e_from_v_h(
v,
h);
1244 Real
p = 0, dp_dv = 0, dp_dh = 0;
1246 Real
T = 0, dT_dv = 0, dT_dh = 0;
1250 de_dv = de_dp * dp_dv + de_dT * dT_dv;
1251 de_dh = de_dp * dp_dh + de_dT * dT_dh;
1256 auto lambda = [&](Real
v, Real current_e, Real & new_h, Real & dh_dv, Real & dh_de)
1257 { h_from_v_e(
v, current_e, new_h, dh_dv, dh_de); };
1264 name() +
"::e_from_v_h",
1270 de_dv = (e2 - e) / (TOLERANCE *
v);
1271 de_dh = 1. / e_data.second;
1274 _fp->e_from_v_h(
v,
h, e, de_dv, de_dh);
1386 return _fp->p_from_v_e(
v, e);
1403 _fp->p_from_v_e(
v, e,
p, dp_dv, dp_de);
1422 _fp->p_from_v_e(vc, ec,
p, dp_dv, dp_de);
1439 return _fp->T_from_v_e(
v, e);
1456 _fp->T_from_v_e(
v, e,
T, dT_dv, dT_de);
1475 _fp->T_from_v_e(vc, ec,
T, dT_dv, dT_de);
1496 return _fp->c_from_v_e(
v, e);
1512 Real
p, dp_dv, dp_de;
1514 Real
T, dT_dv, dT_de;
1518 dc_dv = dc_dp * dp_dv + dc_dT * dT_dv;
1519 dc_de = dc_dp * dp_de + dc_dT * dT_de;
1522 _fp->c_from_v_e(
v, e,
c, dc_dv, dc_de);
1543 return _fp->cp_from_v_e(
v, e);
1559 Real
p, dp_dv, dp_de;
1561 Real
T, dT_dv, dT_de;
1563 Real dcp_dp, dcp_dT;
1565 dcp_dv = dcp_dp * dp_dv + dcp_dT * dT_dv;
1566 dcp_de = dcp_dp * dp_de + dcp_dT * dT_de;
1569 _fp->cp_from_v_e(
v, e, cp, dcp_dv, dcp_de);
1590 return _fp->cv_from_v_e(
v, e);
1606 Real
p, dp_dv, dp_de;
1608 Real
T, dT_dv, dT_de;
1610 Real dcv_dp, dcv_dT;
1612 dcv_dv = dcv_dp * dp_dv + dcv_dT * dT_dv;
1613 dcv_de = dcv_dp * dp_de + dcv_dT * dT_de;
1616 _fp->cv_from_v_e(
v, e, cv, dcv_dv, dcv_de);
1637 return _fp->mu_from_v_e(
v, e);
1653 Real
p, dp_dv, dp_de;
1655 Real
T, dT_dv, dT_de;
1657 Real dmu_dp, dmu_dT;
1659 dmu_dv = dmu_dp * dp_dv + dmu_dT * dT_dv;
1660 dmu_de = dmu_dp * dp_de + dmu_dT * dT_de;
1663 _fp->mu_from_v_e(
v, e,
mu, dmu_dv, dmu_de);
1684 return _fp->k_from_v_e(
v, e);
1700 Real
p, dp_dv, dp_de;
1702 Real
T, dT_dv, dT_de;
1706 dk_dv = dk_dp * dp_dv + dk_dT * dT_dv;
1707 dk_de = dk_dp * dp_de + dk_dT * dT_de;
1710 _fp->k_from_v_e(
v, e, k, dk_dv, dk_de);
1731 return _fp->s_from_v_e(
v, e);
1747 Real
p,
T, dT_dv, dT_de, dp_dv, dp_de;
1752 ds_dv = ds_dp * dp_dv + ds_dT * dT_dv;
1753 ds_dv = ds_dp * dp_de + ds_dT * dT_de;
1756 _fp->s_from_v_e(
v, e, s, ds_dv, ds_de);
1782 bool conversion_succeeded;
1789 "\nNo tabulation or fluid property 'input_fp' object to compute value");
1799 bool conversion_succeeded;
1809 auto lambda = [&](Real pressure, Real current_T, Real & new_h, Real & dh_dp, Real & dh_dT)
1810 {
h_from_p_T(pressure, current_T, new_h, dh_dp, dh_dT); };
1816 name() +
"::T_from_p_h",
1824 ") and pressure (p = ",
1826 ") to temperature failed to converge.");
1830 return _fp->T_from_p_h(pressure, enthalpy);
1844 h_from_p_T(pressure.value(), current_T.value(), new_h.value(), dh_dp.value(), dh_dT.value());
1846 new_h.derivatives() =
1847 dh_dp.value() * pressure.derivatives() + dh_dT.value() * current_T.derivatives();
1854 name() +
"::T_from_p_h",
1862 ") and pressure (p = ",
1864 ") to temperature failed to converge.");
1868 return _fp->T_from_p_h(pressure, enthalpy);
1882 Real h, Real pressure, Real & s, Real & ds_dh, Real & ds_dp)
const
1885 _fp->s_from_h_p(
h, pressure, s, ds_dh, ds_dp);
1893 mooseError(
"TabulatedFluidProperties can only call the function '" + desired_routine +
1894 "' when the 'input_fp' parameter is provided. It is currently not implemented using "
1895 "tabulations, and this property is simply forwarded to the FluidProperties specified "
1896 "in the 'input_fp' parameter");
1901 const std::string & needed_property)
const
1904 "TabulatedFluidProperties can only call the function '" + desired_routine +
1905 "' when either:\n- the property '" + needed_property +
1906 "' is tabulated and listed in the 'interpolated_properties' parameter.\n- the 'input_fp' "
1907 "parameter is provided.");
1914 "' is marked as interpolated but neither of the following methods are active:\n- "
1915 "(p,T) interpolation created from fluid properties ('create_pT_interpolations' "
1916 "parameter)\n- a (p,T) tabulation file ('fluid_property_file')\n- (v,e) interpolation "
1917 "created from fluid properties or a (p,T) tabulation ('create_ve_interpolations' "
1918 "parameter)\n- a (v,e) tabulation file ('fluid_property_ve_file' parameter)");
1929 file_name = file_name.empty() ?
"fluid_properties_" +
name() +
"_out.csv" : file_name;
1932 std::ofstream file_out(file_name.c_str());
1934 if (!getParam<bool>(
"skip_header_tabulation"))
1937 time_t now = std::time(&now);
1939 <<
" properties (p,T) tabulation created by TabulatedFluidProperties on "
1940 << ctime(&now) <<
"\n";
1944 file_out <<
"pressure, temperature";
1952 for (
unsigned int p = 0;
p <
_num_p; ++
p)
1953 for (
unsigned int t = 0; t <
_num_T; ++t)
1956 for (std::size_t i = 0; i <
_properties.size(); ++i)
1961 file_out << std::flush;
1969 ? std::regex_replace(file_name, std::regex(
"\\.csv"),
"_ve.csv")
1972 std::ofstream file_out(file_name_ve.c_str());
1975 if (!getParam<bool>(
"skip_header_tabulation"))
1977 time_t now = std::time(&now);
1979 <<
" properties (v,e) tabulation created by TabulatedFluidProperties on "
1980 << ctime(&now) <<
"\n";
1984 file_out <<
"specific_volume, internal_energy, pressure, temperature";
1994 for (
const auto v : make_range(
_num_v))
1995 for (
const auto e : make_range(
_num_e))
2000 Real pressure, temperature;
2011 file_out << v_val <<
", " << e_val <<
", " << pressure <<
", " << temperature
2015 bool add_comma =
true;
2017 file_out << 1. / v_val;
2019 file_out << h_from_v_e(v_val, e_val);
2044 file_out << std::flush;
2053 mooseAssert(
_fp,
"We should not try to generate (p,T) tabulated data without a _fp user object");
2070 for (
unsigned int j = 0; j <
_num_T; ++j)
2076 for (
unsigned int i = 0; i <
_num_p; ++i)
2083 for (
unsigned int p = 0;
p <
_num_p; ++
p)
2084 for (
unsigned int t = 0; t <
_num_T; ++t)
2088 for (
unsigned int p = 0;
p <
_num_p; ++
p)
2089 for (
unsigned int t = 0; t <
_num_T; ++t)
2093 for (
unsigned int p = 0;
p <
_num_p; ++
p)
2094 for (
unsigned int t = 0; t <
_num_T; ++t)
2098 for (
unsigned int p = 0;
p <
_num_p; ++
p)
2099 for (
unsigned int t = 0; t <
_num_T; ++t)
2103 for (
unsigned int p = 0;
p <
_num_p; ++
p)
2104 for (
unsigned int t = 0; t <
_num_T; ++t)
2108 for (
unsigned int p = 0;
p <
_num_p; ++
p)
2109 for (
unsigned int t = 0; t <
_num_T; ++t)
2113 for (
unsigned int p = 0;
p <
_num_p; ++
p)
2114 for (
unsigned int t = 0; t <
_num_T; ++t)
2118 for (
unsigned int p = 0;
p <
_num_p; ++
p)
2119 for (
unsigned int t = 0; t <
_num_T; ++t)
2123 for (
unsigned int p = 0;
p <
_num_p; ++
p)
2124 for (
unsigned int t = 0; t <
_num_T; ++t)
2132 mooseAssert(
_fp,
"We should not try to generate (v,e) tabulated data without a _fp user object");
2155 for (
unsigned int v = 0;
v <
_num_v; ++
v)
2156 for (
unsigned int e = 0; e <
_num_e; ++e)
2160 for (
unsigned int v = 0;
v <
_num_v; ++
v)
2161 for (
unsigned int e = 0; e <
_num_e; ++e)
2166 for (
unsigned int v = 0;
v <
_num_v; ++
v)
2167 for (
unsigned int e = 0; e <
_num_e; ++e)
2171 for (
unsigned int v = 0;
v <
_num_v; ++
v)
2172 for (
unsigned int e = 0; e <
_num_e; ++e)
2177 for (
unsigned int v = 0;
v <
_num_v; ++
v)
2178 for (
unsigned int e = 0; e <
_num_e; ++e)
2183 for (
unsigned int v = 0;
v <
_num_v; ++
v)
2184 for (
unsigned int e = 0; e <
_num_e; ++e)
2189 for (
unsigned int v = 0;
v <
_num_v; ++
v)
2190 for (
unsigned int e = 0; e <
_num_e; ++e)
2195 for (
unsigned int v = 0;
v <
_num_v; ++
v)
2196 for (
unsigned int e = 0; e <
_num_e; ++e)
2201 for (
unsigned int v = 0;
v <
_num_v; ++
v)
2202 for (
unsigned int e = 0; e <
_num_e; ++e)
2207 for (
unsigned int v = 0;
v <
_num_v; ++
v)
2208 for (
unsigned int e = 0; e <
_num_e; ++e)
2213 for (
unsigned int v = 0;
v <
_num_v; ++
v)
2214 for (
unsigned int e = 0; e <
_num_e; ++e)
2220template <
typename T>
2224 using std::max, std::min;
2233 " is outside the range of tabulated pressure (" +
2241 flagInvalidSolution(
"Pressure out of bounds");
2243 flagSolutionWarning(
"Pressure out of bounds");
2252 " is outside the range of tabulated temperature (" +
2259 flagInvalidSolution(
"Temperature out of bounds");
2261 flagSolutionWarning(
"Temperature out of bounds");
2266template <
typename T>
2270 using std::max, std::min;
2274 else if (e < _e_min || e >
_e_max)
2278 " is outside the range of tabulated specific internal energies (" +
2284 flagInvalidSolution(
"Specific internal energy out of bounds");
2286 flagSolutionWarning(
"Specific internal energy out of bounds");
2290 if (v < _v_min || v >
_v_max)
2294 " is outside the range of tabulated specific volumes (" +
2300 flagInvalidSolution(
"Specific volume out of bounds");
2302 flagSolutionWarning(
"Specific volume out of bounds");
2317 if (_p_initial_guess < _pressure_min || _p_initial_guess >
_pressure_max)
2318 mooseWarning(
"Pressure initial guess for (p,T), (v,e) conversions " +
2320 " is outside the range of tabulated "
2324 if (_T_initial_guess < _temperature_min || _T_initial_guess >
_temperature_max)
2325 mooseWarning(
"Temperature initial guess for (p,T), (v,e) conversions " +
2327 " is outside the range of tabulated "
2337 std::string file_name;
2355 std::vector<std::string> required_columns;
2357 required_columns = {
"pressure",
"temperature"};
2359 required_columns = {
"specific_volume",
"internal_energy"};
2362 for (std::size_t i = 0; i < required_columns.size(); ++i)
2364 if (std::find(column_names.begin(), column_names.end(), required_columns[i]) ==
2367 required_columns[i],
2370 ". A column named ",
2371 required_columns[i],
2372 " must be present");
2376 std::vector<std::string> property_columns = {
2377 "density",
"enthalpy",
"viscosity",
"k",
"c",
"cv",
"cp",
"entropy"};
2379 property_columns.push_back(
"internal_energy");
2382 property_columns.push_back(
"pressure");
2383 property_columns.push_back(
"temperature");
2388 for (std::size_t i = 0; i < column_names.size(); ++i)
2391 if (std::find(required_columns.begin(), required_columns.end(), column_names[i]) ==
2392 required_columns.end())
2394 if (std::find(property_columns.begin(), property_columns.end(), column_names[i]) ==
2395 property_columns.end())
2399 " tabulation file is not one of the properties that TabulatedFluidProperties "
2400 "understands. It will be ignored.");
2413 std::map<std::string, unsigned int> data_index;
2414 for (std::size_t i = 0; i < column_names.size(); ++i)
2416 auto it = std::find(column_names.begin(), column_names.end(), column_names[i]);
2417 data_index[column_names[i]] = std::distance(column_names.begin(), it);
2425 _pressure = column_data[data_index.find(
"pressure")->second];
2426 _temperature = column_data[data_index.find(
"temperature")->second];
2430 _specific_volume = column_data[data_index.find(
"specific_volume")->second];
2431 _internal_energy = column_data[data_index.find(
"internal_energy")->second];
2441 "specific internal energy");
2475 "Reading a (v,e) tabulation and generating (p,T) to (v,e) interpolation tables is "
2476 "not supported at this time.");
2488 const auto & p_col = column_data[data_index.find(
"pressure")->second];
2489 _pressure_min = *std::min_element(p_col.begin(), p_col.end());
2490 _pressure_max = *std::max_element(p_col.begin(), p_col.end());
2491 const auto & T_col = column_data[data_index.find(
"temperature")->second];
2500 std::vector<Real> & v2,
2501 const std::string & file_name,
2502 const std::string & v1_name,
2503 const std::string & v2_name)
2508 if (!std::is_sorted(v1.begin(), v1.end()))
2509 mooseError(
"The column data for ", v1_name,
" is not monotonically increasing in ", file_name);
2513 auto num_v2 = std::count(v1.begin(), v1.end(), v1.front());
2516 auto last_unique = std::unique(v1.begin(), v1.end());
2517 v1.erase(last_unique, v1.end());
2521 if (v2.size() != v1.size() * libMesh::cast_int<unsigned int>(num_v2))
2524 " is not equal to the number of unique ",
2528 " multiplied by the number of unique ",
2534 std::vector<Real> base_v2(v2.begin(), v2.begin() + num_v2);
2535 if (!std::is_sorted(base_v2.begin(), base_v2.end()))
2536 mooseError(
"The column data for ", v2_name,
" is not monotonically increasing in ", file_name);
2539 auto it_v2 = v2.begin() + num_v2;
2540 for (
const auto i : make_range(v1.size() - 1))
2542 std::vector<Real> repeated_v2(it_v2, it_v2 + num_v2);
2543 if (repeated_v2 != base_v2)
2549 " are not identical to values for ",
2552 std::advance(it_v2, num_v2);
2557 v2.erase(v2.begin() + num_v2, v2.end());
2625 "' is present in the tabulation but is not currently leveraged by the code in the "
2626 "TabulatedFluidProperties. If it is spelled correctly, then please contact a "
2627 "MOOSE or fluid properties module developer.");
2634 mooseAssert(
_file_name_ve_in.empty(),
"We should be reading the specific volume grid from file");
2654 _v_min = std::min({v1, v2, v3, v4});
2655 _v_max = std::max({v1, v2, v3, v4});
2658 mooseWarning(
"Unable to compute grid bounds in specific volume. Please specify the v_min/max "
2672 Real log_v_min = std::log10(
_v_min);
2673 for (
unsigned int j = 0; j <
_num_v; ++j)
2679 for (
unsigned int j = 0; j <
_num_v; ++j)
2705 _e_min = std::min({e1, e2, e3, e4});
2706 _e_max = std::max({e1, e2, e3, e4});
2709 mooseWarning(
"Unable to compute grid bounds in internal energy. Please specify the e_min/max "
2720 mooseError(
"Logarithmic grid in specific energy can only be used with a positive specific "
2721 "energy. Current minimum: " +
2724 Real log_e_min = std::log10(
_e_min);
2725 for (
const auto j : make_range(
_num_e))
2731 for (
const auto j : make_range(
_num_e))
2748 _h_min = std::min({h1, h2, h3, h4});
2749 _h_max = std::max({h1, h2, h3, h4});
2763 mooseError(
"Need a source to compute the enthalpy grid bounds: either a FP object, or a (p,T) "
2764 "tabulation file or a (v,e) tabulation file");
2774 mooseError(
"Logarithmic grid in specific energy can only be used with a positive enthalpy. "
2775 "Current minimum: " +
2778 Real log_h_min = std::log10(
_h_min);
2779 for (
const auto j : make_range(
_num_e))
2780 _enthalpy[j] = std::pow(10, log_h_min + j * dh);
2785 for (
const auto j : make_range(
_num_e))
2794 ": to call this function you must:\n-add this property to the list to the list of "
2795 "'interpolated_properties'\n and then either:\n-construct (p, T) from (v, e) "
2796 "tabulations using the 'construct_pT_from_ve' parameter\n-load (v,e) interpolation "
2797 "tables using the 'fluid_property_ve_file' parameter");
2801 Real & temperature)
const;
2803 ADReal & temperature)
const;
DualNumber< Real, DNDerivativeType, true > ADReal
void ErrorVector unsigned int
const ConsoleStream _console
const std::string & name() const
void paramError(const std::string ¶m, Args... args) const
bool isParamSetByUser(const std::string &name) const
void mooseError(Args &&... args) const
void mooseWarning(Args &&... args) const
bool isParamValid(const std::string &name) const
const std::vector< std::string > & getNames() const
const std::vector< std::vector< T > > & getData() const
void setComment(const std::string &value)
void setFileName(const std::string &new_file)
bool contains(const std::string &value) const
unsigned int size() const
Common class for single phase fluid properties.
virtual std::vector< Real > henryCoefficients() const
Henry's law coefficients for dissolution in water.
const Real _T_initial_guess
Initial guess for temperature (or temperature used to compute the initial guess)
void p_T_from_h_s(const T &h, const T &s, Real p0, Real T0, T &pressure, T &temperature, bool &conversion_succeeded) const
Determines (p,T) from (h,s) using Newton Solve in 2D Useful for conversion between different sets of ...
const bool _verbose_newton
Whether to output information about newton solves to console.
void p_T_from_v_e(const CppType &v, const CppType &e, Real p0, Real T0, CppType &p, CppType &T, bool &conversion_succeeded) const
Determines (p,T) from (v,e) using Newton Solve in 2D Useful for conversion between different sets of ...
const Real _p_initial_guess
Initial guess for pressure (or pressure used to compute the initial guess)
virtual Real vaporPressure(Real T) const
Vapor pressure.
static InputParameters validParams()
e e e e s T T T T T rho T
const Real _tolerance
Newton's method may be used to convert between variable sets.
virtual Real triplePointPressure() const
Triple point pressure.
virtual Real criticalDensity() const
Critical density.
virtual Real criticalPressure() const
Critical pressure.
const unsigned int _max_newton_its
Maximum number of iterations for the variable conversion newton solves.
virtual Real molarMass() const
Molar mass [kg/mol].
void v_e_from_p_T(const CppType &p, const CppType &T, CppType &v, CppType &e) const
e e e e s T T T T T rho v v T e h
virtual Real criticalTemperature() const
Critical temperature.
virtual Real triplePointTemperature() const
Triple point temperature.
virtual Real vaporTemperature(Real p) const
Vapor temperature.
e e e e s T T T T T rho v v T e p T T virtual T std::string fluidName() const
Fluid name.
FileName _file_name_out
File name of output tabulated data file.
std::unique_ptr< BidimensionalInterpolation > _T_from_v_e_ipol
Bi-dimensional interpolation of temperature from (v,e)
virtual Real v_from_p_T(Real pressure, Real temperature) const override
unsigned int _num_T
Number of temperature points in the tabulated data.
const bool _save_file
Whether to save a generated fluid properties file to disk.
bool _initial_setup_done
keeps track of whether initialSetup has been performed
const SinglePhaseFluidProperties *const _fp
SinglePhaseFluidPropertiesPT UserObject.
FileName _file_name_ve_out
File name of output (v,e) tabulated data file.
std::vector< std::string > _interpolated_properties
List of properties to be interpolated.
void checkInputVariables(T &pressure, T &temperature) const
Checks that the inputs are within the range of the tabulated data, and throws an error if they are no...
std::vector< Real > _internal_energy
Specific internal energy vector.
void readFileTabulationData(bool use_pT)
Read tabulation data from file.
unsigned int _enthalpy_idx
Real _v_min
Minimum specific volume in tabulated data (can be user-specified)
virtual Real s_from_v_e(Real v, Real e) const override
unsigned int _viscosity_idx
virtual Real triplePointTemperature() const override
Triple point temperature.
std::vector< std::vector< Real > > _properties_ve
Tabulated fluid properties in (v,e) (read from file OR computed from _fp)
void computePropertyIndicesInInterpolationVectors()
Retrieves the index for each property in the vector of interpolations.
virtual Real e_from_v_h(Real v, Real h) const override
TabulatedFluidProperties(const InputParameters ¶meters)
unsigned int _num_v
Number of specific volume points in the tabulated data.
Real _v_max
Maximum specific volume in tabulated data (can be user-specified)
Real _h_min
Minimum specific enthalpy in tabulated data.
FileName _file_name_ve_in
File name of input (v,e) tabulated data file.
virtual Real T_from_p_h(Real pressure, Real enthalpy) const override
void missingVEInterpolationError(const std::string &function_name) const
Standardized error message for missing interpolation.
virtual void constructInterpolation()=0
virtual Real rho_from_p_s(Real p, Real s) const override
std::vector< Real > _temperature
Temperature vector.
const bool _create_direct_ve_interpolations
Whether the object has direct (v,e) interpolations (whether created from file or from _fp)
virtual Real g_from_v_e(Real v, Real e) const override
bool _interpolate_entropy
void writeTabulatedData(std::string file_name)
Writes tabulated data to a file.
void NeedTabulationError(const std::string &needed_property) const
Utility to forward errors related to properties being requested for tabulation, but no tabulation is ...
virtual void generateTabulatedData()
Generates a table of fluid properties by looping over pressure and temperature and calculating proper...
virtual Real cp_from_p_T(Real pressure, Real temperature) const override
std::unique_ptr< BidimensionalInterpolation > _p_from_v_h_ipol
Bidimensional interpolation of pressure from (v,h)
virtual void generateVETabulatedData()
Generates a table of fluid properties by looping over specific volume and internal energy and calcula...
unsigned int _entropy_idx
Real _temperature_max
Maximum temperature in tabulated data.
static InputParameters validParams()
Real _e_min
Minimum internal energy in tabulated data (can be user-specified)
virtual Real T_from_p_rho(Real pressure, Real rho) const
const bool _create_direct_pT_interpolations
Whether the object has direct (p,T) interpolations (whether created from file or from _fp)
Real _e_max
Maximum internal energy in tabulated data (can be user-specified)
virtual Real triplePointPressure() const override
Triple point pressure.
void checkFileTabulationGrids(std::vector< Real > &v1, std::vector< Real > &v2, const std::string &file_name, const std::string &v1_name, const std::string &v2_name)
Check that the tabulation grids in the file are correct (no repeats etc)
bool _interpolate_temperature
std::vector< Real > _enthalpy
Specific enthalpy vector.
virtual Real cp_from_v_e(Real v, Real e) const override
void TabulationNotImplementedError(const std::string &desired_routine) const
Utility to forward errors related to fluid properties methods not implemented.
virtual Real cv_from_v_e(Real v, Real e) const override
void createVHGridVectors()
Create (or reset) the grid vectors for the specific volume and enthalpy interpolation The order of pr...
virtual Real T_from_h_s(Real h, Real s) const
bool _log_space_v
log-space the specific volume interpolation grid axis instead of linear
unsigned int _num_p
Number of pressure points in the tabulated data.
OOBBehavior
Enum specifying all the behavior on out of bounds data options.
MooseUtils::DelimitedFileReader _csv_reader
The MOOSE delimited file reader.
FileName _file_name_in
File name of input tabulated data file.
bool _v_bounds_specified
Whether the specific volume bounds were set by the user.
std::vector< std::unique_ptr< BidimensionalInterpolation > > _property_ve_ipol
Vector of bi-dimensional interpolation of fluid properties directly in (v,e)
bool _construct_pT_from_vh
if the lookup table p(v, h) and T(v, h) should be constructed
bool _interpolate_viscosity
virtual void checkInitialGuess(bool post_reading_tabulation) const
Checks initial guess for Newton Method.
MultiMooseEnum _interpolated_properties_enum
Properties to be interpolated entered in the input file.
std::unique_ptr< BidimensionalInterpolation > _p_from_v_e_ipol
Bi-dimensional interpolation of pressure from (v,e)
void createVGridVector()
Create (or reset) the grid vectors for the specific volume and internal energy interpolations The ord...
virtual Real criticalTemperature() const override
Critical temperature.
virtual Real h_from_p_T(Real p, Real T) const override
unsigned int _num_e
Number of internal energy points in tabulated data.
void NeedTabulationOrFPError(const std::string &desired_routine, const std::string &needed_property) const
Utility to forward errors related to fluid properties needing more data for their computation This sh...
bool _interpolate_internal_energy
std::vector< Real > _specific_volume
Specific volume vector.
virtual Real rho_from_p_T(Real pressure, Real temperature) const override
virtual void initialSetup() override
virtual Real e_from_p_rho(Real pressure, Real rho) const override
virtual Real cv_from_p_T(Real pressure, Real temperature) const override
MooseEnum _OOBBehavior
User-selected out-of-bounds behavior.
virtual Real p_from_v_e(Real v, Real e) const override
Derivatives like dc_dv & dc_de are computed using the chain rule dy/dx(p,T) = dy/dp * dp/dx + dy/dT *...
bool _log_space_e
log-space the internal energy interpolation grid axis instead of linear
void checkInputVariablesVE(T &v, T &e) const
Checks that the inputs are within the range of the tabulated data, and throws an error if they are no...
virtual Real mu_from_p_T(Real pressure, Real temperature) const override
virtual Real mu_from_v_e(Real v, Real e) const override
virtual Real k_from_p_T(Real pressure, Real temperature) const override
virtual std::vector< Real > henryCoefficients() const override
The following routines are simply forwarded to the 'fp' companion FluidProperties as they are not inc...
unsigned int _internal_energy_idx
bool _interpolate_pressure
virtual Real T_from_p_s(Real p, Real s) const
virtual Real s_from_h_p(Real h, Real pressure) const override
virtual Real vaporTemperature(Real pressure) const override
Vapor temperature.
Real _pressure_max
Maximum pressure in tabulated data.
virtual Real vaporPressure(Real temperature) const override
Vapor pressure.
Real _h_max
Maximum specific enthalpy in tabulated data.
std::vector< std::unique_ptr< BidimensionalInterpolation > > _property_ipol
Vector of bi-dimensional interpolation of fluid properties.
virtual Real criticalDensity() const override
Critical density.
virtual Real molarMass() const override
Molar mass [kg/mol].
virtual Real T_from_v_e(Real v, Real e) const override
void createVEGridVectors()
unsigned int _density_idx
Index of each property.
virtual Real k_from_v_e(Real v, Real e) const override
std::unique_ptr< BidimensionalInterpolation > _T_from_v_h_ipol
Bi-dimensional interpolation of temperature from (v,h)
virtual Real s_from_p_T(Real pressure, Real temperature) const override
Real _temperature_min
Minimum temperature in tabulated data.
virtual std::string fluidName() const override
Fluid name.
Real _pressure_min
Minimum pressure in tabulated data.
const bool _allow_fp_and_tabulation
Whether to allow a fp object when a tabulation is in use.
virtual Real c_from_v_e(Real v, Real e) const override
std::vector< std::vector< Real > > _properties
Tabulated fluid properties (read from file OR computed from _fp)
bool _construct_pT_from_ve
if the lookup table p(v, e) and T(v, e) should be constructed
std::vector< Real > _pressure
Pressure vector.
bool _log_space_h
log-space the enthalpy interpolation grid axis instead of linear
bool _e_bounds_specified
Whether the specific internal energy bounds were set by the user.
virtual Real e_from_p_T(Real pressure, Real temperature) const override
bool _interpolate_enthalpy
virtual Real c_from_p_T(Real pressure, Real temperature) const override
bool _interpolate_density
Set of flags to note whether a property is to be interpolated.
virtual Real criticalPressure() const override
Critical pressure.
processor_id_type processor_id() const
std::pair< T, T > NewtonSolve(const T &x, const T &y, const Real z_initial_guess, const Real tolerance, const Functor &y_from_x_z, const std::string &caller_name, const unsigned int max_its=100, const bool verbose=false)
NewtonSolve does a 1D Newton Solve to solve the equation y = f(x, z) for variable z.
void NewtonSolve2D(const T &f, const T &g, const Real x0, const Real y0, T &x_final, T &y_final, const Real f_tol, const Real g_tol, const Functor1 &f_from_x_y, const Functor2 &g_from_x_y, const std::string &caller_name="", const unsigned int max_its=100, bool debug=false)
NewtonSolve2D does a 2D Newton Solve to solve for the x and y such that: f = f_from_x_y(x,...
bool checkFileWriteable(const std::string &filename, bool throw_on_unwritable)
std::string stringify(const T &t)
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
const unsigned int invalid_uint
static constexpr Real TOLERANCE