LCOV - code coverage report
Current view: top level - src/userobjects - FluidPropertiesInterrogator.C (source / functions) Hit Total Coverage
Test: idaholab/moose fluid_properties: #32971 (54bef8) with base c6cf66 Lines: 417 449 92.9 %
Date: 2026-05-29 20:36:28 Functions: 20 21 95.2 %
Legend: Lines: hit not hit

          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         238 : FluidPropertiesInterrogator::validParams()
      22             : {
      23         238 :   InputParameters params = GeneralUserObject::validParams();
      24         476 :   params.addRequiredParam<UserObjectName>("fp",
      25             :                                           "The name of the fluid properties object to query.");
      26         476 :   params.addParam<bool>("json", false, "Output in JSON format");
      27         476 :   params.addParam<Real>("rho", "Density");
      28         476 :   params.addParam<Real>("rhou", "Momentum density; rho * u");
      29         476 :   params.addParam<Real>("rhoE", "Total energy density; rho * E");
      30         476 :   params.addParam<Real>("e", "Specific internal energy");
      31         476 :   params.addParam<Real>("p", "Pressure");
      32         476 :   params.addParam<Real>("T", "Temperature");
      33         476 :   params.addParam<Real>("vel", "Velocity");
      34         476 :   params.addParam<std::vector<Real>>("x_ncg", "Mass fractions of NCGs");
      35         476 :   params.addRequiredParam<unsigned int>("precision", "Precision for printing values");
      36             : 
      37         238 :   params.addClassDescription(
      38             :       "User object for querying a single-phase or two-phase fluid properties object");
      39             : 
      40         238 :   return params;
      41           0 : }
      42             : 
      43         120 : FluidPropertiesInterrogator::FluidPropertiesInterrogator(const InputParameters & parameters)
      44             :   : GeneralUserObject(parameters),
      45         120 :     _json(getParam<bool>("json")),
      46         120 :     _fp(&getUserObject<FluidProperties>("fp")),
      47         120 :     _fp_1phase(dynamic_cast<const SinglePhaseFluidProperties * const>(_fp)),
      48         120 :     _fp_2phase(dynamic_cast<const TwoPhaseFluidProperties * const>(_fp)),
      49         120 :     _fp_2phase_ncg(dynamic_cast<const TwoPhaseNCGFluidProperties * const>(_fp)),
      50         120 :     _fp_2phase_ncg_partial_pressure(
      51         120 :         dynamic_cast<const TwoPhaseNCGPartialPressureFluidProperties * const>(_fp)),
      52         120 :     _has_1phase(_fp_1phase),
      53         120 :     _has_vapor_mixture(dynamic_cast<const VaporMixtureFluidProperties * const>(_fp)),
      54         120 :     _has_2phase(_fp_2phase),
      55         120 :     _has_2phase_ncg(_fp_2phase_ncg),
      56         120 :     _has_2phase_ncg_partial_pressure(_fp_2phase_ncg_partial_pressure),
      57         120 :     _fp_liquid(_has_2phase
      58         120 :                    ? &getUserObjectByName<SinglePhaseFluidProperties>(_fp_2phase->getLiquidName())
      59             :                    : nullptr),
      60         240 :     _fp_vapor(_has_2phase
      61         120 :                   ? &getUserObjectByName<SinglePhaseFluidProperties>(_fp_2phase->getVaporName())
      62             :                   : nullptr),
      63         240 :     _fp_vapor_mixture(_has_vapor_mixture
      64         120 :                           ? dynamic_cast<const VaporMixtureFluidProperties * const>(_fp)
      65         108 :                           : (_has_2phase_ncg ? &getUserObjectByName<VaporMixtureFluidProperties>(
      66          18 :                                                    _fp_2phase_ncg->getVaporMixtureName())
      67             :                                              : nullptr)),
      68         120 :     _nan_encountered(false),
      69         360 :     _precision(getParam<unsigned int>("precision"))
      70             : {
      71         120 :   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         118 : }
      76             : 
      77             : void
      78         118 : FluidPropertiesInterrogator::initialize()
      79             : {
      80         118 : }
      81             : 
      82             : void
      83         118 : FluidPropertiesInterrogator::execute()
      84             : {
      85         118 :   if (_has_2phase_ncg)
      86             :   {
      87          18 :     InputParameters pars_2phase = compute2Phase();
      88          18 :     InputParameters pars_liquid = compute1Phase(_fp_liquid, false);
      89          18 :     InputParameters pars_mixture = computeVaporMixture(false);
      90             : 
      91          18 :     if (_json)
      92             :     {
      93             :       nlohmann::json json;
      94             : 
      95           6 :       auto & json_2phase = json["2-phase"];
      96           6 :       buildJSON2Phase(json_2phase, pars_2phase);
      97           6 :       auto & json_liquid = json["liquid"];
      98           6 :       buildJSON1Phase(json_liquid, pars_liquid);
      99           6 :       auto & json_mixture = json["vapor-mixture"];
     100           6 :       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          12 :       outputASCII2Phase(pars_2phase);
     109          12 :       outputASCII1Phase("LIQUID phase", pars_liquid);
     110          12 :       outputASCIIVaporMixture(pars_mixture);
     111             :     }
     112          18 :   }
     113         100 :   else if (_has_2phase)
     114             :   {
     115          36 :     InputParameters pars_2phase = compute2Phase();
     116          36 :     InputParameters pars_liquid = compute1Phase(_fp_liquid, false);
     117          36 :     InputParameters pars_vapor = compute1Phase(_fp_vapor, false);
     118             : 
     119          36 :     if (_json)
     120             :     {
     121             :       nlohmann::json json;
     122             : 
     123          18 :       auto & json_2phase = json["2-phase"];
     124          18 :       buildJSON2Phase(json_2phase, pars_2phase);
     125          18 :       if (pars_liquid.have_parameter<bool>("specified"))
     126             :       {
     127           6 :         auto & json_liquid = json["liquid"];
     128           6 :         buildJSON1Phase(json_liquid, pars_liquid);
     129             :       }
     130          18 :       if (pars_vapor.have_parameter<bool>("specified"))
     131             :       {
     132           6 :         auto & json_vapor = json["vapor"];
     133           6 :         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          18 :       outputASCII2Phase(pars_2phase);
     143          18 :       if (pars_liquid.have_parameter<bool>("specified"))
     144          12 :         outputASCII1Phase("LIQUID phase", pars_liquid);
     145          18 :       if (pars_vapor.have_parameter<bool>("specified"))
     146          12 :         outputASCII1Phase("VAPOR phase", pars_vapor);
     147             :     }
     148          36 :   }
     149          64 :   else if (_has_vapor_mixture)
     150             :   {
     151          12 :     InputParameters pars_mixture = computeVaporMixture(true);
     152          12 :     if (_json)
     153             :     {
     154             :       nlohmann::json json;
     155           6 :       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           6 :       outputASCIIVaporMixture(pars_mixture);
     163          12 :   }
     164             :   else
     165             :   {
     166          52 :     InputParameters pars_1phase = compute1Phase(_fp_1phase, true);
     167             : 
     168          48 :     if (_json)
     169             :     {
     170             :       nlohmann::json json;
     171             : 
     172          24 :       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          48 :       outputASCII1Phase("Single-phase", pars_1phase);
     180          48 :   }
     181         114 : }
     182             : 
     183             : void
     184         114 : FluidPropertiesInterrogator::finalize()
     185             : {
     186         114 : }
     187             : 
     188             : InputParameters
     189         142 : FluidPropertiesInterrogator::compute1Phase(const SinglePhaseFluidProperties * const fp_1phase,
     190             :                                            bool throw_error_if_no_match)
     191             : {
     192         142 :   InputParameters params = emptyInputParameters();
     193             : 
     194             :   // reset NaN flag
     195         142 :   _nan_encountered = false;
     196             : 
     197             :   // determine how state is specified
     198         568 :   std::vector<std::vector<std::string>> parameter_sets = {{"p", "T"}, {"rho", "e"}, {"rho", "p"}};
     199         142 :   if (_has_1phase)
     200         104 :     parameter_sets.push_back({"rho", "rhou", "rhoE"});
     201         142 :   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         138 :   if (specified["rho,e"])
     208             :   {
     209          24 :     rho = getParam<Real>("rho");
     210          24 :     e = getParam<Real>("e");
     211          12 :     const Real v = 1.0 / rho;
     212          12 :     p = fp_1phase->p_from_v_e(v, e);
     213          12 :     T = fp_1phase->T_from_v_e(v, e);
     214          24 :     if (isParamValid("vel"))
     215           0 :       vel = getParam<Real>("vel");
     216             : 
     217             :     specified_a_set = true;
     218             :   }
     219         126 :   else if (specified["rho,p"])
     220             :   {
     221          24 :     rho = getParam<Real>("rho");
     222          24 :     p = getParam<Real>("p");
     223          12 :     const Real v = 1.0 / rho;
     224          12 :     e = fp_1phase->e_from_p_rho(p, rho);
     225          12 :     T = fp_1phase->T_from_v_e(v, e);
     226          24 :     if (isParamValid("vel"))
     227           0 :       vel = getParam<Real>("vel");
     228             : 
     229             :     specified_a_set = true;
     230             :   }
     231         114 :   else if (specified["p,T"])
     232             :   {
     233         108 :     p = getParam<Real>("p");
     234         108 :     T = getParam<Real>("T");
     235          54 :     rho = fp_1phase->rho_from_p_T(p, T);
     236          54 :     e = fp_1phase->e_from_p_rho(p, rho);
     237         108 :     if (isParamValid("vel"))
     238           0 :       vel = getParam<Real>("vel");
     239             : 
     240             :     specified_a_set = true;
     241             :   }
     242          60 :   else if (specified["rho,rhou,rhoE"])
     243             :   {
     244          24 :     rho = getParam<Real>("rho");
     245          24 :     const Real rhou = getParam<Real>("rhou");
     246          24 :     const Real rhoE = getParam<Real>("rhoE");
     247             : 
     248          12 :     vel = rhou / rho;
     249          12 :     const Real E = rhoE / rho;
     250          12 :     e = E - 0.5 * vel * vel;
     251             : 
     252          12 :     const Real v = 1.0 / rho;
     253          12 :     p = fp_1phase->p_from_v_e(v, e);
     254          12 :     T = fp_1phase->T_from_v_e(v, e);
     255             : 
     256             :     specified_a_set = true;
     257             :   }
     258             : 
     259         138 :   if (specified_a_set)
     260             :   {
     261          90 :     params.set<bool>("specified") = true;
     262             : 
     263          90 :     const Real v = 1.0 / rho;
     264             : 
     265          90 :     params.set<Real>("rho") = rho;
     266          90 :     params.set<Real>("e") = e;
     267          90 :     params.set<Real>("p") = p;
     268          90 :     params.set<Real>("T") = T;
     269          90 :     params.set<Real>("v") = v;
     270          90 :     params.set<Real>("h") = fp_1phase->h_from_p_T(p, T);
     271          90 :     params.set<Real>("s") = fp_1phase->s_from_v_e(v, e);
     272          90 :     params.set<Real>("c") = fp_1phase->c_from_v_e(v, e);
     273          90 :     params.set<Real>("mu") = fp_1phase->mu_from_v_e(v, e);
     274          90 :     params.set<Real>("cp") = fp_1phase->cp_from_v_e(v, e);
     275          90 :     params.set<Real>("cv") = fp_1phase->cv_from_v_e(v, e);
     276          90 :     params.set<Real>("k") = fp_1phase->k_from_v_e(v, e);
     277          90 :     params.set<Real>("beta") = fp_1phase->beta_from_p_T(p, T);
     278             : 
     279         270 :     if (isParamValid("vel") || specified["rho,rhou,rhoE"])
     280             :     {
     281          12 :       const Real s = fp_1phase->s_from_v_e(v, e);
     282             :       const Real s0 = s;
     283          12 :       const Real h = fp_1phase->h_from_p_T(p, T);
     284          12 :       const Real h0 = h + 0.5 * vel * vel;
     285          12 :       const Real p0 = fp_1phase->p_from_h_s(h0, s0);
     286          12 :       const Real rho0 = fp_1phase->rho_from_p_s(p0, s0);
     287          12 :       const Real e0 = fp_1phase->e_from_p_rho(p0, rho0);
     288          12 :       const Real v0 = 1.0 / rho0;
     289          12 :       const Real T0 = fp_1phase->T_from_v_e(v0, e0);
     290          12 :       const Real c0 = fp_1phase->c_from_v_e(v0, e0);
     291          12 :       const Real mu0 = fp_1phase->mu_from_v_e(v0, e0);
     292          12 :       const Real cp0 = fp_1phase->cp_from_v_e(v0, e0);
     293          12 :       const Real cv0 = fp_1phase->cv_from_v_e(v0, e0);
     294          12 :       const Real k0 = fp_1phase->k_from_v_e(v0, e0);
     295          12 :       const Real beta0 = fp_1phase->beta_from_p_T(p0, T0);
     296             : 
     297          12 :       params.set<Real>("vel") = vel;
     298          12 :       params.set<Real>("rho0") = rho0;
     299          12 :       params.set<Real>("s0") = s0;
     300          12 :       params.set<Real>("v0") = v0;
     301          12 :       params.set<Real>("e0") = e0;
     302          12 :       params.set<Real>("h0") = h0;
     303          12 :       params.set<Real>("p0") = p0;
     304          12 :       params.set<Real>("T0") = T0;
     305          12 :       params.set<Real>("c0") = c0;
     306          12 :       params.set<Real>("mu0") = mu0;
     307          12 :       params.set<Real>("cp0") = cp0;
     308          12 :       params.set<Real>("cv0") = cv0;
     309          12 :       params.set<Real>("k0") = k0;
     310          12 :       params.set<Real>("beta0") = beta0;
     311             :     }
     312             : 
     313             :     // warn if NaN encountered
     314          90 :     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         138 :   return params;
     325         422 : }
     326             : 
     327             : InputParameters
     328          54 : FluidPropertiesInterrogator::compute2Phase()
     329             : {
     330          54 :   InputParameters params = emptyInputParameters();
     331             : 
     332             :   // reset NaN flag
     333          54 :   _nan_encountered = false;
     334             : 
     335             :   // determine how state is specified
     336         216 :   std::vector<std::vector<std::string>> parameter_sets = {{"p", "T"}, {"p"}, {"T"}};
     337          54 :   auto specified = getSpecifiedSetMap(parameter_sets, "two-phase", true);
     338             : 
     339          54 :   const Real p_critical = _fp_2phase->p_critical();
     340          54 :   params.set<Real>("p_critical") = p_critical;
     341          54 :   if (specified["p"])
     342             :   {
     343          24 :     const Real p = getParam<Real>("p");
     344          12 :     const Real T_sat = _fp_2phase->T_sat(p);
     345          12 :     const Real h_lat = _fp_2phase->h_lat(p, T_sat);
     346             : 
     347          12 :     params.set<Real>("p") = p;
     348          12 :     params.set<Real>("T_sat") = T_sat;
     349          12 :     params.set<Real>("h_lat") = h_lat;
     350             :   }
     351          42 :   else if (specified["T"])
     352             :   {
     353          24 :     const Real T = getParam<Real>("T");
     354          12 :     const Real p_sat = _fp_2phase->p_sat(T);
     355          12 :     const Real h_lat = _fp_2phase->h_lat(p_sat, T);
     356          12 :     const Real sigma = _fp_2phase->sigma_from_T(T);
     357             : 
     358          12 :     params.set<Real>("T") = T;
     359          12 :     params.set<Real>("p_sat") = p_sat;
     360          12 :     params.set<Real>("h_lat") = h_lat;
     361          12 :     params.set<Real>("sigma") = sigma;
     362             :   }
     363          30 :   else if (specified["p,T"])
     364             :   {
     365          60 :     const Real p = getParam<Real>("p");
     366          60 :     const Real T = getParam<Real>("T");
     367          30 :     const Real h_lat = _fp_2phase->h_lat(p, T);
     368             : 
     369          30 :     params.set<Real>("p") = p;
     370          30 :     params.set<Real>("T") = T;
     371          30 :     params.set<Real>("h_lat") = h_lat;
     372             :   }
     373             : 
     374             :   // warn if NaN encountered
     375          54 :   if (_nan_encountered)
     376           0 :     mooseWarning("At least one NaN was encountered.");
     377             : 
     378          54 :   return params;
     379         162 : }
     380             : 
     381             : InputParameters
     382          30 : FluidPropertiesInterrogator::computeVaporMixture(bool throw_error_if_no_match)
     383             : {
     384          30 :   InputParameters params = emptyInputParameters();
     385             : 
     386             :   // reset NaN flag
     387          30 :   _nan_encountered = false;
     388             : 
     389             :   // determine how state is specified
     390             :   std::vector<std::vector<std::string>> parameter_sets = {
     391         120 :       {"p", "T", "x_ncg"}, {"rho", "e", "x_ncg"}, {"rho", "rhou", "rhoE", "x_ncg"}};
     392          30 :   if (_has_2phase_ncg_partial_pressure)
     393          12 :     parameter_sets.push_back({"p", "T"});
     394          60 :   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          30 :   if (specified["rho,e,x_ncg"])
     402             :   {
     403          24 :     rho = getParam<Real>("rho");
     404          24 :     e = getParam<Real>("e");
     405          24 :     x_ncg = getParam<std::vector<Real>>("x_ncg");
     406          12 :     const Real v = 1.0 / rho;
     407          12 :     p = _fp_vapor_mixture->p_from_v_e(v, e, x_ncg);
     408          12 :     T = _fp_vapor_mixture->T_from_v_e(v, e, x_ncg);
     409          24 :     if (isParamValid("vel"))
     410           0 :       vel = getParam<Real>("vel");
     411             : 
     412             :     specified_a_set = true;
     413             :   }
     414          18 :   else if (specified["p,T,x_ncg"])
     415             :   {
     416          24 :     p = getParam<Real>("p");
     417          24 :     T = getParam<Real>("T");
     418          24 :     x_ncg = getParam<std::vector<Real>>("x_ncg");
     419          12 :     const Real v = _fp_vapor_mixture->v_from_p_T(p, T, x_ncg);
     420          12 :     rho = 1.0 / v;
     421          12 :     e = _fp_vapor_mixture->e_from_p_T(p, T, x_ncg);
     422          24 :     if (isParamValid("vel"))
     423           0 :       vel = getParam<Real>("vel");
     424             : 
     425             :     specified_a_set = true;
     426             :   }
     427          12 :   else if (_has_2phase_ncg_partial_pressure && specified["p,T"])
     428             :   {
     429          12 :     p = getParam<Real>("p");
     430          12 :     T = getParam<Real>("T");
     431           6 :     x_ncg = {_fp_2phase_ncg_partial_pressure->x_sat_ncg_from_p_T(p, T)};
     432           6 :     const Real v = _fp_vapor_mixture->v_from_p_T(p, T, x_ncg);
     433           6 :     rho = 1.0 / v;
     434           6 :     e = _fp_vapor_mixture->e_from_p_T(p, T, x_ncg);
     435          12 :     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          30 :   if (specified_a_set)
     459             :   {
     460          30 :     params.set<bool>("specified") = true;
     461             : 
     462          30 :     const Real v = 1.0 / rho;
     463          30 :     const Real h = e + p / rho;
     464          30 :     const Real s = _fp_vapor_mixture->s_from_p_T(p, T, x_ncg);
     465          30 :     const Real c = _fp_vapor_mixture->c_from_p_T(p, T, x_ncg);
     466          30 :     const Real mu = _fp_vapor_mixture->mu_from_p_T(p, T, x_ncg);
     467          30 :     const Real cp = _fp_vapor_mixture->cp_from_p_T(p, T, x_ncg);
     468          30 :     const Real cv = _fp_vapor_mixture->cv_from_p_T(p, T, x_ncg);
     469          30 :     const Real k = _fp_vapor_mixture->k_from_p_T(p, T, x_ncg);
     470             : 
     471          30 :     params.set<std::vector<Real>>("x_ncg") = x_ncg;
     472          30 :     params.set<Real>("p") = p;
     473          30 :     params.set<Real>("T") = T;
     474          30 :     params.set<Real>("rho") = rho;
     475          30 :     params.set<Real>("e") = e;
     476          30 :     params.set<Real>("v") = v;
     477          30 :     params.set<Real>("h") = h;
     478          30 :     params.set<Real>("s") = s;
     479          30 :     params.set<Real>("c") = c;
     480          30 :     params.set<Real>("mu") = mu;
     481          30 :     params.set<Real>("cp") = cp;
     482          30 :     params.set<Real>("cv") = cv;
     483          30 :     params.set<Real>("k") = k;
     484             : 
     485          90 :     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          30 :     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          30 :   return params;
     505         120 : }
     506             : 
     507             : void
     508          42 : FluidPropertiesInterrogator::buildJSON1Phase(nlohmann::json & json, const InputParameters & params)
     509             : {
     510         588 :   for (auto p : {"rho", "e", "p", "T", "v", "h", "s", "c", "mu", "cp", "cv", "k", "beta"})
     511        1638 :     json["static"][p] = params.get<Real>(p);
     512             : 
     513          42 :   if (params.have_parameter<Real>("vel"))
     514          84 :     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          90 :                    "beta0"})
     528         252 :       json["stagnation"][p] = params.get<Real>(p);
     529          42 : }
     530             : 
     531             : void
     532          24 : FluidPropertiesInterrogator::buildJSON2Phase(nlohmann::json & json, const InputParameters & params)
     533             : {
     534          48 :   json["p_critical"] = params.get<Real>("p_critical");
     535         120 :   for (auto p : {"T_sat", "p_sat", "h_lat", "sigma"})
     536          96 :     if (params.have_parameter<Real>(p))
     537         126 :       json[p] = params.get<Real>(p);
     538          24 : }
     539             : 
     540             : void
     541          12 : FluidPropertiesInterrogator::buildJSONVaporMixture(nlohmann::json & json,
     542             :                                                    const InputParameters & params)
     543             : {
     544         156 :   for (auto p : {"p", "T", "rho", "e", "v", "h", "s", "c", "mu", "cp", "cv", "k"})
     545         144 :     if (params.have_parameter<Real>(p))
     546         432 :       json["static"][p] = params.get<Real>(p);
     547             : 
     548          12 :   if (params.have_parameter<Real>("vel"))
     549           0 :     json["stagnation"]["h0"] = params.get<Real>("h0");
     550          12 : }
     551             : 
     552             : void
     553          48 : FluidPropertiesInterrogator::outputASCII1Phase(const std::string & description,
     554             :                                                const InputParameters & params)
     555             : {
     556             :   // output static property values
     557          48 :   outputHeader(description + " STATIC properties");
     558          48 :   outputStaticProperties(params);
     559             : 
     560             :   // output stagnation property values
     561          48 :   if (params.have_parameter<Real>("vel"))
     562             :   {
     563           6 :     outputHeader(description + " STAGNATION properties");
     564           6 :     outputStagnationProperties(params);
     565             :   }
     566          48 : }
     567             : 
     568             : void
     569          30 : FluidPropertiesInterrogator::outputASCII2Phase(const InputParameters & params)
     570             : {
     571          30 :   outputHeader("TWO-PHASE properties");
     572          60 :   outputProperty("Critical pressure", params.get<Real>("p_critical"), "Pa");
     573          30 :   if (params.have_parameter<Real>("T_sat"))
     574          12 :     outputProperty("Saturation temperature", params.get<Real>("T_sat"), "K");
     575          30 :   if (params.have_parameter<Real>("p_sat"))
     576          12 :     outputProperty("Saturation pressure", params.get<Real>("p_sat"), "Pa");
     577          30 :   if (params.have_parameter<Real>("h_lat"))
     578          60 :     outputProperty("Latent heat of vaporization", params.get<Real>("h_lat"), "J/kg");
     579          30 :   if (params.have_parameter<Real>("sigma"))
     580          12 :     outputProperty("Surface tension", params.get<Real>("sigma"), "N/m");
     581          30 :   _console << std::endl;
     582          30 : }
     583             : 
     584             : void
     585          18 : FluidPropertiesInterrogator::outputASCIIVaporMixture(const InputParameters & params)
     586             : {
     587             :   // output static property values
     588          18 :   outputHeader("Vapor mixture STATIC properties");
     589          18 :   outputVaporMixtureStaticProperties(params);
     590             : 
     591             :   // output stagnation property values
     592          18 :   if (params.have_parameter<Real>("vel"))
     593             :   {
     594           0 :     outputHeader("Vapor mixture STAGNATION properties");
     595           0 :     outputVaporMixtureStagnationProperties(params);
     596             :   }
     597          18 : }
     598             : 
     599             : std::map<std::string, bool>
     600         226 : 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         962 :   for (auto & parameter_set : parameter_sets)
     608         736 :     parameter_union.insert(parameter_union.end(), parameter_set.begin(), parameter_set.end());
     609         226 :   std::sort(parameter_union.begin(), parameter_union.end());
     610         226 :   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         956 :   for (const auto & parameter_set : parameter_sets)
     617             :   {
     618             :     // create unique string to identify parameter set
     619         732 :     std::stringstream ss;
     620        2258 :     for (unsigned int i = 0; i < parameter_set.size(); i++)
     621        1526 :       if (i == 0)
     622             :         ss << parameter_set[i];
     623             :       else
     624         794 :         ss << "," << parameter_set[i];
     625             :     const std::string parameter_set_name = ss.str();
     626         732 :     parameter_set_names.push_back(parameter_set_name);
     627             : 
     628             :     // check if the set parameters were provided
     629             :     bool all_parameters_provided = true;
     630        2258 :     for (const auto & parameter : parameter_set)
     631        1526 :       if (!isParamValid(parameter))
     632             :         all_parameters_provided = false;
     633             : 
     634         732 :     if (all_parameters_provided)
     635             :     {
     636             :       // exclude set if a superset (assumed to be ordered before this set) was specified
     637         236 :       if (!specified_a_set)
     638             :       {
     639         176 :         specified[parameter_set_name] = true;
     640             : 
     641             :         // check that there are no extraneous parameters
     642         176 :         std::vector<std::string> parameter_set_sorted(parameter_set);
     643         176 :         std::sort(parameter_set_sorted.begin(), parameter_set_sorted.end());
     644             :         std::vector<std::string> extraneous_parameters;
     645         176 :         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         590 :         for (const auto & parameter : extraneous_parameters)
     651         416 :           if (isParamValid(parameter))
     652           2 :             mooseError("(",
     653             :                        parameter_set_name,
     654             :                        ") has been specified; ",
     655             :                        parameter,
     656             :                        " cannot be specified.");
     657         174 :       }
     658             : 
     659             :       specified_a_set = true;
     660             :     }
     661             :     else
     662         496 :       specified[parameter_set_name] = false;
     663         730 :   }
     664             : 
     665         224 :   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         222 :   return specified;
     677         222 : }
     678             : 
     679             : void
     680         102 : FluidPropertiesInterrogator::outputHeader(const std::string & header) const
     681             : {
     682         102 :   _console << std::endl
     683         102 :            << std::endl
     684         102 :            << header << ":" << std::endl
     685         102 :            << std::setfill('-') << std::setw(80) << "-" << std::setfill(' ') << std::endl;
     686         102 : }
     687             : 
     688             : void
     689        1014 : FluidPropertiesInterrogator::outputProperty(const std::string & name,
     690             :                                             const Real & value,
     691             :                                             const std::string & units)
     692             : {
     693        1014 :   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        1014 :   if (is_nan)
     698           0 :     _nan_encountered = true;
     699             : 
     700        1014 :   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        1014 :   std::stringstream ss;
     707             : 
     708        1014 :   if (use_scientific_notation)
     709         936 :     ss << std::setw(35) << std::left << name + ":" << std::setw(_precision + 10) << std::right
     710         312 :        << std::setprecision(_precision) << std::scientific << value << "  " << units_printed
     711             :        << std::endl;
     712             :   else
     713        2106 :     ss << std::setw(35) << std::left << name + ":" << std::setw(_precision + 10) << std::right
     714         702 :        << std::setprecision(_precision) << value << "  " << units_printed << std::endl;
     715             : 
     716        1014 :   _console << ss.str();
     717        2028 : }
     718             : 
     719             : void
     720          48 : FluidPropertiesInterrogator::outputStaticProperties(const InputParameters & params)
     721             : {
     722          96 :   outputProperty("Pressure", params.get<Real>("p"), "Pa");
     723          96 :   outputProperty("Temperature", params.get<Real>("T"), "K");
     724          96 :   outputProperty("Density", params.get<Real>("rho"), "kg/m^3");
     725          96 :   outputProperty("Specific volume", params.get<Real>("v"), "m^3/kg");
     726          96 :   outputProperty("Specific internal energy", params.get<Real>("e"), "J/kg");
     727          96 :   outputProperty("Specific enthalpy", params.get<Real>("h"), "J/kg");
     728          96 :   outputProperty("Specific entropy", params.get<Real>("s"), "J/(kg-K)");
     729          48 :   _console << std::endl;
     730          96 :   outputProperty("Sound speed", params.get<Real>("c"), "m/s");
     731          96 :   outputProperty("Dynamic viscosity", params.get<Real>("mu"), "Pa-s");
     732          96 :   outputProperty("Specific heat at constant pressure", params.get<Real>("cp"), "J/(kg-K)");
     733          96 :   outputProperty("Specific heat at constant volume", params.get<Real>("cv"), "J/(kg-K)");
     734          96 :   outputProperty("Thermal conductivity", params.get<Real>("k"), "W/(m-K)");
     735          96 :   outputProperty("Volumetric expansion coefficient", params.get<Real>("beta"), "1/K");
     736          48 :   _console << std::endl;
     737          48 : }
     738             : 
     739             : void
     740           6 : FluidPropertiesInterrogator::outputStagnationProperties(const InputParameters & params)
     741             : {
     742          12 :   outputProperty("Pressure", params.get<Real>("p0"), "Pa");
     743          12 :   outputProperty("Temperature", params.get<Real>("T0"), "K");
     744          12 :   outputProperty("Density", params.get<Real>("rho0"), "kg/m^3");
     745          12 :   outputProperty("Specific volume", params.get<Real>("v0"), "m^3/kg");
     746          12 :   outputProperty("Specific internal energy", params.get<Real>("e0"), "J/kg");
     747          12 :   outputProperty("Specific enthalpy", params.get<Real>("h0"), "J/kg");
     748          12 :   outputProperty("Specific entropy", params.get<Real>("s0"), "J/(kg-K)");
     749           6 :   _console << std::endl;
     750          12 :   outputProperty("Sound speed", params.get<Real>("c0"), "m/s");
     751          12 :   outputProperty("Dynamic viscosity", params.get<Real>("mu0"), "Pa-s");
     752          12 :   outputProperty("Specific heat at constant pressure", params.get<Real>("cp0"), "J/(kg-K)");
     753          12 :   outputProperty("Specific heat at constant volume", params.get<Real>("cv0"), "J/(kg-K)");
     754          12 :   outputProperty("Thermal conductivity", params.get<Real>("k0"), "W/(m-K)");
     755          12 :   outputProperty("Volumetric expansion coefficient", params.get<Real>("beta0"), "1/K");
     756           6 :   _console << std::endl;
     757           6 : }
     758             : 
     759             : void
     760          18 : FluidPropertiesInterrogator::outputVaporMixtureStaticProperties(const InputParameters & params)
     761             : {
     762          18 :   const auto x_ncg = params.get<std::vector<Real>>("x_ncg");
     763          36 :   for (unsigned int i = 0; i < x_ncg.size(); i++)
     764          36 :     outputProperty("Mass fraction " + std::to_string(i), x_ncg[i], "-");
     765          36 :   outputProperty("Pressure", params.get<Real>("p"), "Pa");
     766          36 :   outputProperty("Temperature", params.get<Real>("T"), "K");
     767          36 :   outputProperty("Density", params.get<Real>("rho"), "kg/m^3");
     768          36 :   outputProperty("Specific volume", params.get<Real>("v"), "m^3/kg");
     769          36 :   outputProperty("Specific internal energy", params.get<Real>("e"), "J/kg");
     770          36 :   outputProperty("Specific enthalpy", params.get<Real>("h"), "J/kg");
     771          36 :   outputProperty("Specific entropy", params.get<Real>("s"), "J/kg");
     772          18 :   _console << std::endl;
     773          36 :   outputProperty("Sound speed", params.get<Real>("c"), "m/s");
     774          36 :   outputProperty("Dynamic viscosity", params.get<Real>("mu"), "Pa-s");
     775          36 :   outputProperty("Specific heat at constant pressure", params.get<Real>("cp"), "J/(kg-K)");
     776          36 :   outputProperty("Specific heat at constant volume", params.get<Real>("cv"), "J/(kg-K)");
     777          36 :   outputProperty("Thermal conductivity", params.get<Real>("k"), "W/(m-K)");
     778          18 :   _console << std::endl;
     779          18 : }
     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 : }

Generated by: LCOV version 1.14