Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 :
10 : #include "FluidPropertiesInterrogator.h"
11 : #include "FluidProperties.h"
12 : #include "SinglePhaseFluidProperties.h"
13 : #include "VaporMixtureFluidProperties.h"
14 : #include "TwoPhaseFluidProperties.h"
15 : #include "TwoPhaseNCGFluidProperties.h"
16 : #include "TwoPhaseNCGPartialPressureFluidProperties.h"
17 :
18 : registerMooseObject("FluidPropertiesApp", FluidPropertiesInterrogator);
19 :
20 : InputParameters
21 314 : FluidPropertiesInterrogator::validParams()
22 : {
23 314 : InputParameters params = GeneralUserObject::validParams();
24 628 : params.addRequiredParam<UserObjectName>("fp",
25 : "The name of the fluid properties object to query.");
26 628 : params.addParam<bool>("json", false, "Output in JSON format");
27 628 : params.addParam<Real>("rho", "Density");
28 628 : params.addParam<Real>("rhou", "Momentum density; rho * u");
29 628 : params.addParam<Real>("rhoE", "Total energy density; rho * E");
30 628 : params.addParam<Real>("e", "Specific internal energy");
31 628 : params.addParam<Real>("p", "Pressure");
32 628 : params.addParam<Real>("T", "Temperature");
33 628 : params.addParam<Real>("vel", "Velocity");
34 628 : params.addParam<std::vector<Real>>("x_ncg", "Mass fractions of NCGs");
35 628 : params.addRequiredParam<unsigned int>("precision", "Precision for printing values");
36 :
37 314 : params.addClassDescription(
38 : "User object for querying a single-phase or two-phase fluid properties object");
39 :
40 314 : return params;
41 0 : }
42 :
43 158 : FluidPropertiesInterrogator::FluidPropertiesInterrogator(const InputParameters & parameters)
44 : : GeneralUserObject(parameters),
45 158 : _json(getParam<bool>("json")),
46 158 : _fp(&getUserObject<FluidProperties>("fp")),
47 158 : _fp_1phase(dynamic_cast<const SinglePhaseFluidProperties * const>(_fp)),
48 158 : _fp_2phase(dynamic_cast<const TwoPhaseFluidProperties * const>(_fp)),
49 158 : _fp_2phase_ncg(dynamic_cast<const TwoPhaseNCGFluidProperties * const>(_fp)),
50 158 : _fp_2phase_ncg_partial_pressure(
51 158 : dynamic_cast<const TwoPhaseNCGPartialPressureFluidProperties * const>(_fp)),
52 158 : _has_1phase(_fp_1phase),
53 158 : _has_vapor_mixture(dynamic_cast<const VaporMixtureFluidProperties * const>(_fp)),
54 158 : _has_2phase(_fp_2phase),
55 158 : _has_2phase_ncg(_fp_2phase_ncg),
56 158 : _has_2phase_ncg_partial_pressure(_fp_2phase_ncg_partial_pressure),
57 158 : _fp_liquid(_has_2phase
58 158 : ? &getUserObjectByName<SinglePhaseFluidProperties>(_fp_2phase->getLiquidName())
59 : : nullptr),
60 316 : _fp_vapor(_has_2phase
61 158 : ? &getUserObjectByName<SinglePhaseFluidProperties>(_fp_2phase->getVaporName())
62 : : nullptr),
63 316 : _fp_vapor_mixture(_has_vapor_mixture
64 158 : ? dynamic_cast<const VaporMixtureFluidProperties * const>(_fp)
65 142 : : (_has_2phase_ncg ? &getUserObjectByName<VaporMixtureFluidProperties>(
66 24 : _fp_2phase_ncg->getVaporMixtureName())
67 : : nullptr)),
68 158 : _nan_encountered(false),
69 474 : _precision(getParam<unsigned int>("precision"))
70 : {
71 158 : if (!(_has_1phase || _has_2phase || _has_vapor_mixture))
72 2 : mooseError(
73 : "The type of the parameter 'fp' must be derived from type 'SinglePhaseFluidProperties', "
74 : "'VaporMixtureFluidProperties', or 'TwoPhaseFluidProperties'.");
75 156 : }
76 :
77 : void
78 156 : FluidPropertiesInterrogator::initialize()
79 : {
80 156 : }
81 :
82 : void
83 156 : FluidPropertiesInterrogator::execute()
84 : {
85 156 : if (_has_2phase_ncg)
86 : {
87 24 : InputParameters pars_2phase = compute2Phase();
88 24 : InputParameters pars_liquid = compute1Phase(_fp_liquid, false);
89 24 : InputParameters pars_mixture = computeVaporMixture(false);
90 :
91 24 : if (_json)
92 : {
93 : nlohmann::json json;
94 :
95 8 : auto & json_2phase = json["2-phase"];
96 8 : buildJSON2Phase(json_2phase, pars_2phase);
97 8 : auto & json_liquid = json["liquid"];
98 8 : buildJSON1Phase(json_liquid, pars_liquid);
99 8 : auto & json_mixture = json["vapor-mixture"];
100 8 : buildJSONVaporMixture(json_mixture, pars_mixture);
101 :
102 : Moose::out << "**START JSON DATA**\n";
103 : Moose::out << json << "\n";
104 : Moose::out << "**END JSON DATA**" << std::endl;
105 : }
106 : else
107 : {
108 16 : outputASCII2Phase(pars_2phase);
109 16 : outputASCII1Phase("LIQUID phase", pars_liquid);
110 16 : outputASCIIVaporMixture(pars_mixture);
111 : }
112 24 : }
113 132 : else if (_has_2phase)
114 : {
115 48 : InputParameters pars_2phase = compute2Phase();
116 48 : InputParameters pars_liquid = compute1Phase(_fp_liquid, false);
117 48 : InputParameters pars_vapor = compute1Phase(_fp_vapor, false);
118 :
119 48 : if (_json)
120 : {
121 : nlohmann::json json;
122 :
123 24 : auto & json_2phase = json["2-phase"];
124 24 : buildJSON2Phase(json_2phase, pars_2phase);
125 24 : if (pars_liquid.have_parameter<bool>("specified"))
126 : {
127 8 : auto & json_liquid = json["liquid"];
128 8 : buildJSON1Phase(json_liquid, pars_liquid);
129 : }
130 24 : if (pars_vapor.have_parameter<bool>("specified"))
131 : {
132 8 : auto & json_vapor = json["vapor"];
133 8 : buildJSON1Phase(json_vapor, pars_vapor);
134 : }
135 :
136 : Moose::out << "**START JSON DATA**\n";
137 : Moose::out << json << "\n";
138 : Moose::out << "**END JSON DATA**" << std::endl;
139 : }
140 : else
141 : {
142 24 : outputASCII2Phase(pars_2phase);
143 24 : if (pars_liquid.have_parameter<bool>("specified"))
144 16 : outputASCII1Phase("LIQUID phase", pars_liquid);
145 24 : if (pars_vapor.have_parameter<bool>("specified"))
146 16 : outputASCII1Phase("VAPOR phase", pars_vapor);
147 : }
148 48 : }
149 84 : else if (_has_vapor_mixture)
150 : {
151 16 : InputParameters pars_mixture = computeVaporMixture(true);
152 16 : if (_json)
153 : {
154 : nlohmann::json json;
155 8 : buildJSONVaporMixture(json, pars_mixture);
156 :
157 : Moose::out << "**START JSON DATA**\n";
158 : Moose::out << json << "\n";
159 : Moose::out << "**END JSON DATA**" << std::endl;
160 : }
161 : else
162 8 : outputASCIIVaporMixture(pars_mixture);
163 16 : }
164 : else
165 : {
166 68 : InputParameters pars_1phase = compute1Phase(_fp_1phase, true);
167 :
168 64 : if (_json)
169 : {
170 : nlohmann::json json;
171 :
172 32 : buildJSON1Phase(json, pars_1phase);
173 :
174 : Moose::out << "**START JSON DATA**\n";
175 : Moose::out << json << "\n";
176 : Moose::out << "**END JSON DATA**" << std::endl;
177 : }
178 : else
179 64 : outputASCII1Phase("Single-phase", pars_1phase);
180 64 : }
181 152 : }
182 :
183 : void
184 152 : FluidPropertiesInterrogator::finalize()
185 : {
186 152 : }
187 :
188 : InputParameters
189 188 : FluidPropertiesInterrogator::compute1Phase(const SinglePhaseFluidProperties * const fp_1phase,
190 : bool throw_error_if_no_match)
191 : {
192 188 : InputParameters params = emptyInputParameters();
193 :
194 : // reset NaN flag
195 188 : _nan_encountered = false;
196 :
197 : // determine how state is specified
198 752 : std::vector<std::vector<std::string>> parameter_sets = {{"p", "T"}, {"rho", "e"}, {"rho", "p"}};
199 188 : if (_has_1phase)
200 136 : parameter_sets.push_back({"rho", "rhou", "rhoE"});
201 188 : auto specified = getSpecifiedSetMap(parameter_sets, "one-phase", throw_error_if_no_match);
202 :
203 : // compute/determine rho, e, p, T, vel
204 :
205 : Real rho, e, p, T, vel = 0;
206 : bool specified_a_set = false;
207 184 : if (specified["rho,e"])
208 : {
209 32 : rho = getParam<Real>("rho");
210 32 : e = getParam<Real>("e");
211 16 : const Real v = 1.0 / rho;
212 16 : p = fp_1phase->p_from_v_e(v, e);
213 16 : T = fp_1phase->T_from_v_e(v, e);
214 32 : if (isParamValid("vel"))
215 0 : vel = getParam<Real>("vel");
216 :
217 : specified_a_set = true;
218 : }
219 168 : else if (specified["rho,p"])
220 : {
221 32 : rho = getParam<Real>("rho");
222 32 : p = getParam<Real>("p");
223 16 : const Real v = 1.0 / rho;
224 16 : e = fp_1phase->e_from_p_rho(p, rho);
225 16 : T = fp_1phase->T_from_v_e(v, e);
226 32 : if (isParamValid("vel"))
227 0 : vel = getParam<Real>("vel");
228 :
229 : specified_a_set = true;
230 : }
231 152 : else if (specified["p,T"])
232 : {
233 144 : p = getParam<Real>("p");
234 144 : T = getParam<Real>("T");
235 72 : rho = fp_1phase->rho_from_p_T(p, T);
236 72 : e = fp_1phase->e_from_p_rho(p, rho);
237 144 : if (isParamValid("vel"))
238 0 : vel = getParam<Real>("vel");
239 :
240 : specified_a_set = true;
241 : }
242 80 : else if (specified["rho,rhou,rhoE"])
243 : {
244 32 : rho = getParam<Real>("rho");
245 32 : const Real rhou = getParam<Real>("rhou");
246 32 : const Real rhoE = getParam<Real>("rhoE");
247 :
248 16 : vel = rhou / rho;
249 16 : const Real E = rhoE / rho;
250 16 : e = E - 0.5 * vel * vel;
251 :
252 16 : const Real v = 1.0 / rho;
253 16 : p = fp_1phase->p_from_v_e(v, e);
254 16 : T = fp_1phase->T_from_v_e(v, e);
255 :
256 : specified_a_set = true;
257 : }
258 :
259 184 : if (specified_a_set)
260 : {
261 120 : params.set<bool>("specified") = true;
262 :
263 120 : const Real v = 1.0 / rho;
264 :
265 120 : params.set<Real>("rho") = rho;
266 120 : params.set<Real>("e") = e;
267 120 : params.set<Real>("p") = p;
268 120 : params.set<Real>("T") = T;
269 120 : params.set<Real>("v") = v;
270 120 : params.set<Real>("h") = fp_1phase->h_from_p_T(p, T);
271 120 : params.set<Real>("s") = fp_1phase->s_from_v_e(v, e);
272 120 : params.set<Real>("c") = fp_1phase->c_from_v_e(v, e);
273 120 : params.set<Real>("mu") = fp_1phase->mu_from_v_e(v, e);
274 120 : params.set<Real>("cp") = fp_1phase->cp_from_v_e(v, e);
275 120 : params.set<Real>("cv") = fp_1phase->cv_from_v_e(v, e);
276 120 : params.set<Real>("k") = fp_1phase->k_from_v_e(v, e);
277 120 : params.set<Real>("beta") = fp_1phase->beta_from_p_T(p, T);
278 :
279 360 : if (isParamValid("vel") || specified["rho,rhou,rhoE"])
280 : {
281 16 : const Real s = fp_1phase->s_from_v_e(v, e);
282 : const Real s0 = s;
283 16 : const Real h = fp_1phase->h_from_p_T(p, T);
284 16 : const Real h0 = h + 0.5 * vel * vel;
285 16 : const Real p0 = fp_1phase->p_from_h_s(h0, s0);
286 16 : const Real rho0 = fp_1phase->rho_from_p_s(p0, s0);
287 16 : const Real e0 = fp_1phase->e_from_p_rho(p0, rho0);
288 16 : const Real v0 = 1.0 / rho0;
289 16 : const Real T0 = fp_1phase->T_from_v_e(v0, e0);
290 16 : const Real c0 = fp_1phase->c_from_v_e(v0, e0);
291 16 : const Real mu0 = fp_1phase->mu_from_v_e(v0, e0);
292 16 : const Real cp0 = fp_1phase->cp_from_v_e(v0, e0);
293 16 : const Real cv0 = fp_1phase->cv_from_v_e(v0, e0);
294 16 : const Real k0 = fp_1phase->k_from_v_e(v0, e0);
295 16 : const Real beta0 = fp_1phase->beta_from_p_T(p0, T0);
296 :
297 16 : params.set<Real>("vel") = vel;
298 16 : params.set<Real>("rho0") = rho0;
299 16 : params.set<Real>("s0") = s0;
300 16 : params.set<Real>("v0") = v0;
301 16 : params.set<Real>("e0") = e0;
302 16 : params.set<Real>("h0") = h0;
303 16 : params.set<Real>("p0") = p0;
304 16 : params.set<Real>("T0") = T0;
305 16 : params.set<Real>("c0") = c0;
306 16 : params.set<Real>("mu0") = mu0;
307 16 : params.set<Real>("cp0") = cp0;
308 16 : params.set<Real>("cv0") = cv0;
309 16 : params.set<Real>("k0") = k0;
310 16 : params.set<Real>("beta0") = beta0;
311 : }
312 :
313 : // warn if NaN encountered
314 120 : if (_nan_encountered)
315 0 : mooseWarning(
316 : "At least one NaN was encountered. This implies one of the following:\n",
317 : " 1. The specified thermodynamic state is inconsistent with the equation of state\n",
318 : " (for example, the state corresponds to a different phase of the fluid).\n",
319 : " 2. There is a problem with the equation of state package at this state\n",
320 : " (for example, the supplied state is outside of the valid state space\n",
321 : " that was programmed in the package).");
322 : }
323 :
324 184 : return params;
325 560 : }
326 :
327 : InputParameters
328 72 : FluidPropertiesInterrogator::compute2Phase()
329 : {
330 72 : InputParameters params = emptyInputParameters();
331 :
332 : // reset NaN flag
333 72 : _nan_encountered = false;
334 :
335 : // determine how state is specified
336 288 : std::vector<std::vector<std::string>> parameter_sets = {{"p", "T"}, {"p"}, {"T"}};
337 72 : auto specified = getSpecifiedSetMap(parameter_sets, "two-phase", true);
338 :
339 72 : const Real p_critical = _fp_2phase->p_critical();
340 72 : params.set<Real>("p_critical") = p_critical;
341 72 : if (specified["p"])
342 : {
343 32 : const Real p = getParam<Real>("p");
344 16 : const Real T_sat = _fp_2phase->T_sat(p);
345 16 : const Real h_lat = _fp_2phase->h_lat(p, T_sat);
346 :
347 16 : params.set<Real>("p") = p;
348 16 : params.set<Real>("T_sat") = T_sat;
349 16 : params.set<Real>("h_lat") = h_lat;
350 : }
351 56 : else if (specified["T"])
352 : {
353 32 : const Real T = getParam<Real>("T");
354 16 : const Real p_sat = _fp_2phase->p_sat(T);
355 16 : const Real h_lat = _fp_2phase->h_lat(p_sat, T);
356 16 : const Real sigma = _fp_2phase->sigma_from_T(T);
357 :
358 16 : params.set<Real>("T") = T;
359 16 : params.set<Real>("p_sat") = p_sat;
360 16 : params.set<Real>("h_lat") = h_lat;
361 16 : params.set<Real>("sigma") = sigma;
362 : }
363 40 : else if (specified["p,T"])
364 : {
365 80 : const Real p = getParam<Real>("p");
366 80 : const Real T = getParam<Real>("T");
367 40 : const Real h_lat = _fp_2phase->h_lat(p, T);
368 :
369 40 : params.set<Real>("p") = p;
370 40 : params.set<Real>("T") = T;
371 40 : params.set<Real>("h_lat") = h_lat;
372 : }
373 :
374 : // warn if NaN encountered
375 72 : if (_nan_encountered)
376 0 : mooseWarning("At least one NaN was encountered.");
377 :
378 72 : return params;
379 216 : }
380 :
381 : InputParameters
382 40 : FluidPropertiesInterrogator::computeVaporMixture(bool throw_error_if_no_match)
383 : {
384 40 : InputParameters params = emptyInputParameters();
385 :
386 : // reset NaN flag
387 40 : _nan_encountered = false;
388 :
389 : // determine how state is specified
390 : std::vector<std::vector<std::string>> parameter_sets = {
391 160 : {"p", "T", "x_ncg"}, {"rho", "e", "x_ncg"}, {"rho", "rhou", "rhoE", "x_ncg"}};
392 40 : if (_has_2phase_ncg_partial_pressure)
393 16 : parameter_sets.push_back({"p", "T"});
394 80 : auto specified = getSpecifiedSetMap(parameter_sets, "vapor mixture", throw_error_if_no_match);
395 :
396 : // compute/determine rho, e, p, T, vel
397 :
398 : Real rho, e, p, T, vel = 0;
399 : std::vector<Real> x_ncg;
400 : bool specified_a_set = false;
401 40 : if (specified["rho,e,x_ncg"])
402 : {
403 32 : rho = getParam<Real>("rho");
404 32 : e = getParam<Real>("e");
405 32 : x_ncg = getParam<std::vector<Real>>("x_ncg");
406 16 : const Real v = 1.0 / rho;
407 16 : p = _fp_vapor_mixture->p_from_v_e(v, e, x_ncg);
408 16 : T = _fp_vapor_mixture->T_from_v_e(v, e, x_ncg);
409 32 : if (isParamValid("vel"))
410 0 : vel = getParam<Real>("vel");
411 :
412 : specified_a_set = true;
413 : }
414 24 : else if (specified["p,T,x_ncg"])
415 : {
416 32 : p = getParam<Real>("p");
417 32 : T = getParam<Real>("T");
418 32 : x_ncg = getParam<std::vector<Real>>("x_ncg");
419 16 : const Real v = _fp_vapor_mixture->v_from_p_T(p, T, x_ncg);
420 16 : rho = 1.0 / v;
421 16 : e = _fp_vapor_mixture->e_from_p_T(p, T, x_ncg);
422 32 : if (isParamValid("vel"))
423 0 : vel = getParam<Real>("vel");
424 :
425 : specified_a_set = true;
426 : }
427 16 : else if (_has_2phase_ncg_partial_pressure && specified["p,T"])
428 : {
429 16 : p = getParam<Real>("p");
430 16 : T = getParam<Real>("T");
431 8 : x_ncg = {_fp_2phase_ncg_partial_pressure->x_sat_ncg_from_p_T(p, T)};
432 8 : const Real v = _fp_vapor_mixture->v_from_p_T(p, T, x_ncg);
433 8 : rho = 1.0 / v;
434 8 : e = _fp_vapor_mixture->e_from_p_T(p, T, x_ncg);
435 16 : if (isParamValid("vel"))
436 0 : vel = getParam<Real>("vel");
437 :
438 : specified_a_set = true;
439 : }
440 0 : else if (specified["rho,rhou,rhoE,x_ncg"])
441 : {
442 0 : rho = getParam<Real>("rho");
443 0 : const Real rhou = getParam<Real>("rhou");
444 0 : const Real rhoE = getParam<Real>("rhoE");
445 0 : x_ncg = getParam<std::vector<Real>>("x_ncg");
446 :
447 0 : vel = rhou / rho;
448 0 : const Real E = rhoE / rho;
449 0 : e = E - 0.5 * vel * vel;
450 :
451 0 : const Real v = 1.0 / rho;
452 0 : p = _fp_vapor_mixture->p_from_v_e(v, e, x_ncg);
453 0 : T = _fp_vapor_mixture->T_from_v_e(v, e, x_ncg);
454 :
455 : specified_a_set = true;
456 : }
457 :
458 40 : if (specified_a_set)
459 : {
460 40 : params.set<bool>("specified") = true;
461 :
462 40 : const Real v = 1.0 / rho;
463 40 : const Real h = e + p / rho;
464 40 : const Real s = _fp_vapor_mixture->s_from_p_T(p, T, x_ncg);
465 40 : const Real c = _fp_vapor_mixture->c_from_p_T(p, T, x_ncg);
466 40 : const Real mu = _fp_vapor_mixture->mu_from_p_T(p, T, x_ncg);
467 40 : const Real cp = _fp_vapor_mixture->cp_from_p_T(p, T, x_ncg);
468 40 : const Real cv = _fp_vapor_mixture->cv_from_p_T(p, T, x_ncg);
469 40 : const Real k = _fp_vapor_mixture->k_from_p_T(p, T, x_ncg);
470 :
471 40 : params.set<std::vector<Real>>("x_ncg") = x_ncg;
472 40 : params.set<Real>("p") = p;
473 40 : params.set<Real>("T") = T;
474 40 : params.set<Real>("rho") = rho;
475 40 : params.set<Real>("e") = e;
476 40 : params.set<Real>("v") = v;
477 40 : params.set<Real>("h") = h;
478 40 : params.set<Real>("s") = s;
479 40 : params.set<Real>("c") = c;
480 40 : params.set<Real>("mu") = mu;
481 40 : params.set<Real>("cp") = cp;
482 40 : params.set<Real>("cv") = cv;
483 40 : params.set<Real>("k") = k;
484 :
485 120 : if (isParamValid("vel") || specified["rho,rhou,rhoE,x_ncg"])
486 : {
487 : const Real h = e + p / rho;
488 0 : const Real h0 = h + 0.5 * vel * vel;
489 :
490 0 : params.set<Real>("h0") = h0;
491 : }
492 :
493 : // warn if NaN encountered
494 40 : if (_nan_encountered)
495 0 : mooseWarning(
496 : "At least one NaN was encountered. This implies one of the following:\n",
497 : " 1. The specified thermodynamic state is inconsistent with the equation of state\n",
498 : " (for example, the state corresponds to a different phase of the fluid).\n",
499 : " 2. There is a problem with the equation of state package at this state\n",
500 : " (for example, the supplied state is outside of the valid state space\n",
501 : " that was programmed in the package).");
502 : }
503 :
504 40 : return params;
505 160 : }
506 :
507 : void
508 56 : FluidPropertiesInterrogator::buildJSON1Phase(nlohmann::json & json, const InputParameters & params)
509 : {
510 784 : for (auto p : {"rho", "e", "p", "T", "v", "h", "s", "c", "mu", "cp", "cv", "k", "beta"})
511 2184 : json["static"][p] = params.get<Real>(p);
512 :
513 56 : if (params.have_parameter<Real>("vel"))
514 112 : for (auto p : {"vel",
515 : "rho0",
516 : "s0",
517 : "v0",
518 : "e0",
519 : "h0",
520 : "p0",
521 : "T0",
522 : "c0",
523 : "mu0",
524 : "cp0",
525 : "cv0",
526 : "k0",
527 120 : "beta0"})
528 336 : json["stagnation"][p] = params.get<Real>(p);
529 56 : }
530 :
531 : void
532 32 : FluidPropertiesInterrogator::buildJSON2Phase(nlohmann::json & json, const InputParameters & params)
533 : {
534 64 : json["p_critical"] = params.get<Real>("p_critical");
535 160 : for (auto p : {"T_sat", "p_sat", "h_lat", "sigma"})
536 128 : if (params.have_parameter<Real>(p))
537 168 : json[p] = params.get<Real>(p);
538 32 : }
539 :
540 : void
541 16 : FluidPropertiesInterrogator::buildJSONVaporMixture(nlohmann::json & json,
542 : const InputParameters & params)
543 : {
544 208 : for (auto p : {"p", "T", "rho", "e", "v", "h", "s", "c", "mu", "cp", "cv", "k"})
545 192 : if (params.have_parameter<Real>(p))
546 576 : json["static"][p] = params.get<Real>(p);
547 :
548 16 : if (params.have_parameter<Real>("vel"))
549 0 : json["stagnation"]["h0"] = params.get<Real>("h0");
550 16 : }
551 :
552 : void
553 64 : FluidPropertiesInterrogator::outputASCII1Phase(const std::string & description,
554 : const InputParameters & params)
555 : {
556 : // output static property values
557 64 : outputHeader(description + " STATIC properties");
558 64 : outputStaticProperties(params);
559 :
560 : // output stagnation property values
561 64 : if (params.have_parameter<Real>("vel"))
562 : {
563 8 : outputHeader(description + " STAGNATION properties");
564 8 : outputStagnationProperties(params);
565 : }
566 64 : }
567 :
568 : void
569 40 : FluidPropertiesInterrogator::outputASCII2Phase(const InputParameters & params)
570 : {
571 40 : outputHeader("TWO-PHASE properties");
572 80 : outputProperty("Critical pressure", params.get<Real>("p_critical"), "Pa");
573 40 : if (params.have_parameter<Real>("T_sat"))
574 16 : outputProperty("Saturation temperature", params.get<Real>("T_sat"), "K");
575 40 : if (params.have_parameter<Real>("p_sat"))
576 16 : outputProperty("Saturation pressure", params.get<Real>("p_sat"), "Pa");
577 40 : if (params.have_parameter<Real>("h_lat"))
578 80 : outputProperty("Latent heat of vaporization", params.get<Real>("h_lat"), "J/kg");
579 40 : if (params.have_parameter<Real>("sigma"))
580 16 : outputProperty("Surface tension", params.get<Real>("sigma"), "N/m");
581 40 : _console << std::endl;
582 40 : }
583 :
584 : void
585 24 : FluidPropertiesInterrogator::outputASCIIVaporMixture(const InputParameters & params)
586 : {
587 : // output static property values
588 24 : outputHeader("Vapor mixture STATIC properties");
589 24 : outputVaporMixtureStaticProperties(params);
590 :
591 : // output stagnation property values
592 24 : if (params.have_parameter<Real>("vel"))
593 : {
594 0 : outputHeader("Vapor mixture STAGNATION properties");
595 0 : outputVaporMixtureStagnationProperties(params);
596 : }
597 24 : }
598 :
599 : std::map<std::string, bool>
600 300 : FluidPropertiesInterrogator::getSpecifiedSetMap(
601 : const std::vector<std::vector<std::string>> & parameter_sets,
602 : const std::string & fp_type,
603 : bool throw_error_if_no_match) const
604 : {
605 : // get union of parameters from all sets
606 : std::vector<std::string> parameter_union;
607 1276 : for (auto & parameter_set : parameter_sets)
608 976 : parameter_union.insert(parameter_union.end(), parameter_set.begin(), parameter_set.end());
609 300 : std::sort(parameter_union.begin(), parameter_union.end());
610 300 : parameter_union.erase(std::unique(parameter_union.begin(), parameter_union.end()),
611 : parameter_union.end());
612 :
613 : std::vector<std::string> parameter_set_names;
614 : std::map<std::string, bool> specified;
615 : bool specified_a_set = false;
616 1270 : for (const auto & parameter_set : parameter_sets)
617 : {
618 : // create unique string to identify parameter set
619 972 : std::stringstream ss;
620 2998 : for (unsigned int i = 0; i < parameter_set.size(); i++)
621 2026 : if (i == 0)
622 : ss << parameter_set[i];
623 : else
624 1054 : ss << "," << parameter_set[i];
625 : const std::string parameter_set_name = ss.str();
626 972 : parameter_set_names.push_back(parameter_set_name);
627 :
628 : // check if the set parameters were provided
629 : bool all_parameters_provided = true;
630 2998 : for (const auto & parameter : parameter_set)
631 2026 : if (!isParamValid(parameter))
632 : all_parameters_provided = false;
633 :
634 972 : if (all_parameters_provided)
635 : {
636 : // exclude set if a superset (assumed to be ordered before this set) was specified
637 314 : if (!specified_a_set)
638 : {
639 234 : specified[parameter_set_name] = true;
640 :
641 : // check that there are no extraneous parameters
642 234 : std::vector<std::string> parameter_set_sorted(parameter_set);
643 234 : std::sort(parameter_set_sorted.begin(), parameter_set_sorted.end());
644 : std::vector<std::string> extraneous_parameters;
645 234 : std::set_difference(parameter_union.begin(),
646 : parameter_union.end(),
647 : parameter_set_sorted.begin(),
648 : parameter_set_sorted.end(),
649 : std::inserter(extraneous_parameters, extraneous_parameters.end()));
650 786 : for (const auto & parameter : extraneous_parameters)
651 554 : if (isParamValid(parameter))
652 2 : mooseError("(",
653 : parameter_set_name,
654 : ") has been specified; ",
655 : parameter,
656 : " cannot be specified.");
657 232 : }
658 :
659 : specified_a_set = true;
660 : }
661 : else
662 658 : specified[parameter_set_name] = false;
663 970 : }
664 :
665 298 : if (!specified_a_set && throw_error_if_no_match)
666 : {
667 2 : std::stringstream ss;
668 : ss << "For " << fp_type
669 : << " fluid properties, you must provide one of the following\n"
670 4 : "combinations of thermodynamic properties:\n";
671 10 : for (const auto & parameter_set_name : parameter_set_names)
672 16 : ss << " * (" << parameter_set_name << ")\n";
673 2 : mooseError(ss.str());
674 0 : }
675 :
676 296 : return specified;
677 296 : }
678 :
679 : void
680 136 : FluidPropertiesInterrogator::outputHeader(const std::string & header) const
681 : {
682 136 : _console << std::endl
683 136 : << std::endl
684 136 : << header << ":" << std::endl
685 136 : << std::setfill('-') << std::setw(80) << "-" << std::setfill(' ') << std::endl;
686 136 : }
687 :
688 : void
689 1352 : FluidPropertiesInterrogator::outputProperty(const std::string & name,
690 : const Real & value,
691 : const std::string & units)
692 : {
693 1352 : const bool use_scientific_notation = ((value < 0.001) || (value >= 10000.0));
694 :
695 : // check for NaN value
696 : const bool is_nan = value != value;
697 1352 : if (is_nan)
698 0 : _nan_encountered = true;
699 :
700 1352 : const std::string units_printed = is_nan ? "" : units;
701 :
702 : // The console output is not used directly because there is no way to reset
703 : // format flags. For example, if scientific format is used, there is no way
704 : // to restore the general format (not fixed format); for cout, there are
705 : // methods to save and restore format flags, but Console does not provide these.
706 1352 : std::stringstream ss;
707 :
708 1352 : if (use_scientific_notation)
709 1248 : ss << std::setw(35) << std::left << name + ":" << std::setw(_precision + 10) << std::right
710 416 : << std::setprecision(_precision) << std::scientific << value << " " << units_printed
711 : << std::endl;
712 : else
713 2808 : ss << std::setw(35) << std::left << name + ":" << std::setw(_precision + 10) << std::right
714 936 : << std::setprecision(_precision) << value << " " << units_printed << std::endl;
715 :
716 1352 : _console << ss.str();
717 2704 : }
718 :
719 : void
720 64 : FluidPropertiesInterrogator::outputStaticProperties(const InputParameters & params)
721 : {
722 128 : outputProperty("Pressure", params.get<Real>("p"), "Pa");
723 128 : outputProperty("Temperature", params.get<Real>("T"), "K");
724 128 : outputProperty("Density", params.get<Real>("rho"), "kg/m^3");
725 128 : outputProperty("Specific volume", params.get<Real>("v"), "m^3/kg");
726 128 : outputProperty("Specific internal energy", params.get<Real>("e"), "J/kg");
727 128 : outputProperty("Specific enthalpy", params.get<Real>("h"), "J/kg");
728 128 : outputProperty("Specific entropy", params.get<Real>("s"), "J/(kg-K)");
729 64 : _console << std::endl;
730 128 : outputProperty("Sound speed", params.get<Real>("c"), "m/s");
731 128 : outputProperty("Dynamic viscosity", params.get<Real>("mu"), "Pa-s");
732 128 : outputProperty("Specific heat at constant pressure", params.get<Real>("cp"), "J/(kg-K)");
733 128 : outputProperty("Specific heat at constant volume", params.get<Real>("cv"), "J/(kg-K)");
734 128 : outputProperty("Thermal conductivity", params.get<Real>("k"), "W/(m-K)");
735 128 : outputProperty("Volumetric expansion coefficient", params.get<Real>("beta"), "1/K");
736 64 : _console << std::endl;
737 64 : }
738 :
739 : void
740 8 : FluidPropertiesInterrogator::outputStagnationProperties(const InputParameters & params)
741 : {
742 16 : outputProperty("Pressure", params.get<Real>("p0"), "Pa");
743 16 : outputProperty("Temperature", params.get<Real>("T0"), "K");
744 16 : outputProperty("Density", params.get<Real>("rho0"), "kg/m^3");
745 16 : outputProperty("Specific volume", params.get<Real>("v0"), "m^3/kg");
746 16 : outputProperty("Specific internal energy", params.get<Real>("e0"), "J/kg");
747 16 : outputProperty("Specific enthalpy", params.get<Real>("h0"), "J/kg");
748 16 : outputProperty("Specific entropy", params.get<Real>("s0"), "J/(kg-K)");
749 8 : _console << std::endl;
750 16 : outputProperty("Sound speed", params.get<Real>("c0"), "m/s");
751 16 : outputProperty("Dynamic viscosity", params.get<Real>("mu0"), "Pa-s");
752 16 : outputProperty("Specific heat at constant pressure", params.get<Real>("cp0"), "J/(kg-K)");
753 16 : outputProperty("Specific heat at constant volume", params.get<Real>("cv0"), "J/(kg-K)");
754 16 : outputProperty("Thermal conductivity", params.get<Real>("k0"), "W/(m-K)");
755 16 : outputProperty("Volumetric expansion coefficient", params.get<Real>("beta0"), "1/K");
756 8 : _console << std::endl;
757 8 : }
758 :
759 : void
760 24 : FluidPropertiesInterrogator::outputVaporMixtureStaticProperties(const InputParameters & params)
761 : {
762 24 : const auto x_ncg = params.get<std::vector<Real>>("x_ncg");
763 48 : for (unsigned int i = 0; i < x_ncg.size(); i++)
764 48 : outputProperty("Mass fraction " + std::to_string(i), x_ncg[i], "-");
765 48 : outputProperty("Pressure", params.get<Real>("p"), "Pa");
766 48 : outputProperty("Temperature", params.get<Real>("T"), "K");
767 48 : outputProperty("Density", params.get<Real>("rho"), "kg/m^3");
768 48 : outputProperty("Specific volume", params.get<Real>("v"), "m^3/kg");
769 48 : outputProperty("Specific internal energy", params.get<Real>("e"), "J/kg");
770 48 : outputProperty("Specific enthalpy", params.get<Real>("h"), "J/kg");
771 48 : outputProperty("Specific entropy", params.get<Real>("s"), "J/kg");
772 24 : _console << std::endl;
773 48 : outputProperty("Sound speed", params.get<Real>("c"), "m/s");
774 48 : outputProperty("Dynamic viscosity", params.get<Real>("mu"), "Pa-s");
775 48 : outputProperty("Specific heat at constant pressure", params.get<Real>("cp"), "J/(kg-K)");
776 48 : outputProperty("Specific heat at constant volume", params.get<Real>("cv"), "J/(kg-K)");
777 48 : outputProperty("Thermal conductivity", params.get<Real>("k"), "W/(m-K)");
778 24 : _console << std::endl;
779 24 : }
780 :
781 : void
782 0 : FluidPropertiesInterrogator::outputVaporMixtureStagnationProperties(const InputParameters & params)
783 : {
784 0 : outputProperty("Specific enthalpy", params.get<Real>("h0"), "J/kg");
785 0 : _console << std::endl;
786 0 : }
|