LCOV - code coverage report
Current view: top level - include/fluidproperties - SinglePhaseFluidProperties.h (source / functions) Hit Total Coverage
Test: idaholab/moose fluid_properties: #31405 (292dce) with base fef103 Lines: 75 113 66.4 %
Date: 2025-09-04 07:53:14 Functions: 29 145 20.0 %
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             : #pragma once
      11             : 
      12             : #include "FluidProperties.h"
      13             : #include "NewtonInversion.h"
      14             : #include "metaphysicl/dualnumberarray.h"
      15             : 
      16             : /**
      17             :  * Adds AD versions of each fluid property. These functions use the Real versions of these methods
      18             :  * to compute the AD variables complete with derivatives. Typically, these do not need to be
      19             :  * overriden in derived classes.
      20             :  */
      21             : #define propfuncAD(want, prop1, prop2)                                                             \
      22             :   virtual ADReal want##_from_##prop1##_##prop2(const ADReal & p1, const ADReal & p2) const         \
      23             :   {                                                                                                \
      24             :     Real x = 0;                                                                                    \
      25             :     Real raw1 = p1.value();                                                                        \
      26             :     Real raw2 = p2.value();                                                                        \
      27             :     Real dxd1 = 0;                                                                                 \
      28             :     Real dxd2 = 0;                                                                                 \
      29             :     want##_from_##prop1##_##prop2(raw1, raw2, x, dxd1, dxd2);                                      \
      30             :                                                                                                    \
      31             :     ADReal result = x;                                                                             \
      32             :     result.derivatives() = p1.derivatives() * dxd1 + p2.derivatives() * dxd2;                      \
      33             :     return result;                                                                                 \
      34             :   }                                                                                                \
      35             :                                                                                                    \
      36             :   virtual void want##_from_##prop1##_##prop2(const ADReal & prop1,                                 \
      37             :                                              const ADReal & prop2,                                 \
      38             :                                              ADReal & val,                                         \
      39             :                                              ADReal & d##want##d1,                                 \
      40             :                                              ADReal & d##want##d2) const                           \
      41             :   {                                                                                                \
      42             :     unimplementedDerivativeMethod(__PRETTY_FUNCTION__);                                            \
      43             :     Real dummy, tmp1, tmp2;                                                                        \
      44             :     val = want##_from_##prop1##_##prop2(prop1, prop2);                                             \
      45             :     want##_from_##prop1##_##prop2(prop1.value(), prop2.value(), dummy, tmp1, tmp2);                \
      46             :     d##want##d1 = tmp1;                                                                            \
      47             :     d##want##d2 = tmp2;                                                                            \
      48             :   }
      49             : 
      50             : /**
      51             :  * Adds function definitions with not implemented error. These functions should be overriden in
      52             :  * derived classes where required. AD versions are constructed automatically using propfuncAD.
      53             :  */
      54             : #define propfunc(want, prop1, prop2)                                                               \
      55             :   virtual Real want##_from_##prop1##_##prop2(Real, Real) const                                     \
      56             :   {                                                                                                \
      57             :     mooseError(                                                                                    \
      58             :         "The fluid properties class '",                                                            \
      59             :         type(),                                                                                    \
      60             :         "' has not implemented the method below. If your application requires this method, you "   \
      61             :         "must either implement it or use a different fluid properties class.\n\n",                 \
      62             :         __PRETTY_FUNCTION__);                                                                      \
      63             :   }                                                                                                \
      64             :                                                                                                    \
      65             :   virtual void want##_from_##prop1##_##prop2(                                                      \
      66             :       Real prop1, Real prop2, Real & val, Real & d##want##d1, Real & d##want##d2) const            \
      67             :   {                                                                                                \
      68             :     unimplementedDerivativeMethod(__PRETTY_FUNCTION__);                                            \
      69             :     d##want##d1 = 0;                                                                               \
      70             :     d##want##d2 = 0;                                                                               \
      71             :     val = want##_from_##prop1##_##prop2(prop1, prop2);                                             \
      72             :   }                                                                                                \
      73             :                                                                                                    \
      74             :   propfuncAD(want, prop1, prop2)
      75             : 
      76             : /**
      77             :  * Adds Real declarations of functions that have a default implementation.
      78             :  * Important: properties declared using this macro must be defined in SinglePhaseFluidProperties.C.
      79             :  * AD versions are constructed automatically using propfuncAD.
      80             :  */
      81             : #define propfuncWithDefault(want, prop1, prop2)                                                    \
      82             :   virtual Real want##_from_##prop1##_##prop2(Real, Real) const;                                    \
      83             :   virtual void want##_from_##prop1##_##prop2(                                                      \
      84             :       Real prop1, Real prop2, Real & val, Real & d##want##d1, Real & d##want##d2) const;           \
      85             :                                                                                                    \
      86             :   propfuncAD(want, prop1, prop2)
      87             : 
      88             : /**
      89             :  * Adds Real and ADReal declarations of functions that have an implementation.
      90             :  */
      91             : #define propfuncWithDefinitionOverride(want, prop1, prop2)                                         \
      92             :   Real want##_from_##prop1##_##prop2(Real, Real) const override;                                   \
      93             :   void want##_from_##prop1##_##prop2(                                                              \
      94             :       Real prop1, Real prop2, Real & val, Real & d##want##d1, Real & d##want##d2) const override;  \
      95             :   ADReal want##_from_##prop1##_##prop2(const ADReal &, const ADReal &) const override;             \
      96             :   void want##_from_##prop1##_##prop2(const ADReal & prop1,                                         \
      97             :                                      const ADReal & prop2,                                         \
      98             :                                      ADReal & val,                                                 \
      99             :                                      ADReal & d##want##d1,                                         \
     100             :                                      ADReal & d##want##d2) const override;                         \
     101             :   template <typename CppType>                                                                      \
     102             :   CppType want##_from_##prop1##_##prop2##_template(const CppType & prop1, const CppType & prop2)   \
     103             :       const;                                                                                       \
     104             :   template <typename CppType>                                                                      \
     105             :   void want##_from_##prop1##_##prop2##_template(const CppType & prop1,                             \
     106             :                                                 const CppType & prop2,                             \
     107             :                                                 CppType & val,                                     \
     108             :                                                 CppType & d##want##d1,                             \
     109             :                                                 CppType & d##want##d2) const
     110             : 
     111             : /**
     112             :  * Common class for single phase fluid properties
     113             :  */
     114             : class SinglePhaseFluidProperties : public FluidProperties
     115             : {
     116             : public:
     117             :   static InputParameters validParams();
     118             : 
     119             :   SinglePhaseFluidProperties(const InputParameters & parameters);
     120             :   virtual ~SinglePhaseFluidProperties();
     121             : 
     122             : #pragma GCC diagnostic push
     123             : #pragma GCC diagnostic ignored "-Woverloaded-virtual"
     124             :   // clang-format off
     125             : 
     126             :   /**
     127             :    * @brief Compute a fluid property given for the state defined by two given properties.
     128             :    *
     129             :    * For all functions, the first two arguments are the given properties that define the fluid
     130             :    * state.  For the two-argument variants, the desired property is the return value.
     131             :    * The five-argument variants also provide partial derivatives dx/da and dx/db where x is the
     132             :    * desired property being computed, a is the first given property, and b is the second given
     133             :    * property.  The desired property, dx/da, and dx/db are stored into the 3rd, 4th, and 5th
     134             :    * arguments respectively.
     135             :    *
     136             :    * Properties/parameters used in these function are listed below with their units:
     137             :    *
     138             :    * @begincode
     139             :    * p      pressure [Pa]
     140             :    * T      temperature [K]
     141             :    * e      specific internal energy [J/kg]
     142             :    * v      specific volume [m^3/kg]
     143             :    * rho    density [kg/m^3]
     144             :    * h      specific enthalpy [J/kg]
     145             :    * s      specific entropy [J/(kg*K)]
     146             :    * mu     viscosity [Pa*s]
     147             :    * k      thermal conductivity [W/(m*K)]
     148             :    * c      speed of sound [m/s]
     149             :    * cp     constant-pressure specific heat [J/K]
     150             :    * cv     constant-volume specific heat [J/K]
     151             :    * beta   volumetric thermal expansion coefficient [1/K]
     152             :    * g      Gibbs free energy [J]
     153             :    * pp_sat partial pressure at saturation [Pa]
     154             :    * gamma  Adiabatic ratio (cp/cv) [-]
     155             :    * @endcode
     156             :    *
     157             :    * As an example:
     158             :    *
     159             :    * @begincode
     160             :    * // calculate pressure given specific vol and energy:
     161             :    * auto pressure = your_fluid_properties_object.p_from_v_e(specific_vol, specific_energy);
     162             :    *
     163             :    * // or use the derivative variant:
     164             :    * Real dp_dv = 0; // derivative will be stored into here
     165             :    * Real dp_de = 0; // derivative will be stored into here
     166             :    * your_fluid_properties_object.p_from_v_e(specific_vol, specific_energy, pressure, dp_dv, dp_de);
     167             :    * @endcode
     168             :    *
     169             :    * Automatic differentiation (AD) support is provided through x_from_a_b(ADReal a, ADReal b) and
     170             :    * x_from_a_b(ADReal a, ADReal b, ADReal x, ADReal dx_da, ADReal dx_db) versions of the
     171             :    * functions where a and b must be ADReal/DualNumber's calculated using all AD-supporting values:
     172             :    *
     173             :    * @begincode
     174             :    * auto v = 1/rho; // rho must be an AD non-linear variable.
     175             :    * auto e = rhoE/rho - vel_energy; // rhoE and vel_energy must be AD variables/numbers also.
     176             :    * auto pressure = your_fluid_properties_object.p_from_v_e(v, e);
     177             :    * // pressure now contains partial derivatives w.r.t. all degrees of freedom
     178             :    * @endcode
     179             :    */
     180             :   ///@{
     181           2 :   propfunc(p, v, e)
     182           2 :   propfunc(T, v, e)
     183           0 :   propfunc(c, v, e)
     184           0 :   propfunc(cp, v, e)
     185           0 :   propfunc(cv, v, e)
     186           0 :   propfunc(mu, v, e)
     187           0 :   propfunc(k, v, e)
     188           0 :   propfuncWithDefault(s, v, e)
     189           0 :   propfunc(s, h, p)
     190           0 :   propfunc(rho, p, s)
     191           0 :   propfunc(e, v, h)
     192           0 :   propfuncWithDefault(s, p, T)
     193           0 :   propfunc(pp_sat, p, T)
     194           0 :   propfunc(mu, rho, T)
     195           0 :   propfunc(k, rho, T)
     196           0 :   propfuncWithDefault(c, p, T)
     197           0 :   propfuncWithDefault(cp, p, T)
     198           0 :   propfuncWithDefault(cv, p, T)
     199           0 :   propfuncWithDefault(mu, p, T)
     200           0 :   propfuncWithDefault(k, p, T)
     201          20 :   propfunc(rho, p, T)
     202           0 :   propfunc(e, p, rho)
     203           0 :   propfunc(e, T, v)
     204           0 :   propfunc(p, T, v)
     205           0 :   propfunc(h, T, v)
     206           0 :   propfunc(s, T, v)
     207           0 :   propfunc(cv, T, v)
     208           2 :   propfunc(h, p, T)
     209           0 :   propfuncWithDefault(h, v, e)
     210           7 :   propfunc(g, v, e)
     211           0 :   propfuncWithDefault(p, h, s)
     212           0 :   propfunc(T, h, p)  // temporary, until uniformization
     213           0 :   propfuncWithDefault(T, p, h)
     214           0 :   propfuncWithDefault(beta, p, T)
     215           0 :   propfuncWithDefault(v, p, T)
     216           0 :   propfuncWithDefault(e, p, T)
     217           0 :   propfuncWithDefault(gamma, v, e)
     218           0 :   propfuncWithDefault(gamma, p, T)
     219             :   ///@}
     220             : 
     221             :   // clang-format on
     222             : 
     223             : #undef propfunc
     224             : #undef propfuncWithDefault
     225             : #undef propfuncAD
     226             : 
     227             :       /**
     228             :        * Fluid name
     229             :        * @return string representing fluid name
     230             :        */
     231             :       virtual std::string fluidName() const;
     232             : 
     233             :   /**
     234             :    * Molar mass [kg/mol]
     235             :    * @return molar mass
     236             :    */
     237             :   virtual Real molarMass() const;
     238             : 
     239             :   /**
     240             :    * Critical pressure
     241             :    * @return critical pressure (Pa)
     242             :    */
     243             :   virtual Real criticalPressure() const;
     244             : 
     245             :   /**
     246             :    * Critical temperature
     247             :    * @return critical temperature (K)
     248             :    */
     249             :   virtual Real criticalTemperature() const;
     250             : 
     251             :   /**
     252             :    * Critical density
     253             :    * @return critical density (kg/m^3)
     254             :    */
     255             :   virtual Real criticalDensity() const;
     256             : 
     257             :   /**
     258             :    * Critical specific internal energy
     259             :    * @return specific internal energy (J/kg)
     260             :    */
     261             :   virtual Real criticalInternalEnergy() const;
     262             : 
     263             :   /**
     264             :    * Triple point pressure
     265             :    * @return triple point pressure (Pa)
     266             :    */
     267             :   virtual Real triplePointPressure() const;
     268             : 
     269             :   /**
     270             :    * Triple point temperature
     271             :    * @return triple point temperature (K)
     272             :    */
     273             :   virtual Real triplePointTemperature() const;
     274             : 
     275             :   /**
     276             :    * Specific internal energy from temperature and specific volume
     277             :    *
     278             :    * @param[in] T     temperature
     279             :    * @param[in] v     specific volume
     280             :    */
     281             :   virtual Real e_spndl_from_v(Real v) const;
     282             : 
     283             :   /**
     284             :    * Specific internal energy from temperature and specific volume
     285             :    *
     286             :    * @param[in] T     temperature
     287             :    * @param[in] v     specific volume
     288             :    */
     289             :   virtual void v_e_spndl_from_T(Real T, Real & v, Real & e) const;
     290             : 
     291             :   /**
     292             :    * Vapor pressure. Used to delineate liquid and gas phases.
     293             :    * Valid for temperatures between the triple point temperature
     294             :    * and the critical temperature
     295             :    *
     296             :    * @param T fluid temperature (K)
     297             :    * @param[out] saturation pressure (Pa)
     298             :    * @param[out] derivative of saturation pressure wrt temperature (Pa/K)
     299             :    */
     300             :   virtual Real vaporPressure(Real T) const;
     301             :   virtual void vaporPressure(Real T, Real & psat, Real & dpsat_dT) const;
     302             :   virtual ADReal vaporPressure(const ADReal & T) const;
     303             : 
     304             :   /**
     305             :    * Vapor temperature. Used to delineate liquid and gas phases.
     306             :    * Valid for pressures between the triple point pressure
     307             :    * and the critical pressure
     308             :    *
     309             :    * @param p fluid pressure (Pa)
     310             :    * @param[out] saturation temperature (K)
     311             :    * @param[out] derivative of saturation temperature wrt pressure
     312             :    */
     313             :   virtual Real vaporTemperature(Real p) const;
     314             :   virtual void vaporTemperature(Real p, Real & Tsat, Real & dTsat_dp) const;
     315             :   virtual ADReal vaporTemperature(const ADReal & p) const;
     316             : 
     317             :   /**
     318             :    * Henry's law coefficients for dissolution in water
     319             :    * @return Henry's constant coefficients
     320             :    */
     321             :   virtual std::vector<Real> henryCoefficients() const;
     322             : 
     323             :   template <typename CppType>
     324             :   void v_e_from_p_T(const CppType & p, const CppType & T, CppType & v, CppType & e) const;
     325             :   template <typename CppType>
     326             :   void v_e_from_p_T(const CppType & p,
     327             :                     const CppType & T,
     328             :                     CppType & v,
     329             :                     CppType & dv_dp,
     330             :                     CppType & dv_dT,
     331             :                     CppType & e,
     332             :                     CppType & de_dp,
     333             :                     CppType & de_dT) const;
     334             : 
     335             :   /**
     336             :    * Combined methods. These methods are particularly useful for the PorousFlow
     337             :    * module, where density and viscosity are typically both computed everywhere.
     338             :    * The combined methods allow the most efficient means of calculating both
     339             :    * properties, especially where rho(p, T) and mu(rho, T). In this case, an
     340             :    * extra density calculation would be required to calculate mu(p, T). All
     341             :    * property names are described above.
     342             :    */
     343             :   virtual void rho_mu_from_p_T(Real p, Real T, Real & rho, Real & mu) const;
     344             :   virtual void rho_mu_from_p_T(Real p,
     345             :                                Real T,
     346             :                                Real & rho,
     347             :                                Real & drho_dp,
     348             :                                Real & drho_dT,
     349             :                                Real & mu,
     350             :                                Real & dmu_dp,
     351             :                                Real & dmu_dT) const;
     352             :   virtual void rho_mu_from_p_T(const ADReal & p, const ADReal & T, ADReal & rho, ADReal & mu) const;
     353             : 
     354             :   virtual void rho_e_from_p_T(Real p,
     355             :                               Real T,
     356             :                               Real & rho,
     357             :                               Real & drho_dp,
     358             :                               Real & drho_dT,
     359             :                               Real & e,
     360             :                               Real & de_dp,
     361             :                               Real & de_dT) const;
     362             : 
     363             :   /**
     364             :    * Determines (p,T) from (v,e) using Newton Solve in 2D
     365             :    * Useful for conversion between different sets of state variables
     366             :    *
     367             :    * @param[in] v specific volume (m^3 / kg)
     368             :    * @param[in] e specific internal energy (J / kg)
     369             :    * @param[in] p0 initial guess for pressure (Pa / kg)
     370             :    * @param[in] T0 initial guess for temperature (K)
     371             :    * @param[out] fluid pressure (Pa / kg)
     372             :    * @param[out] Temperature (K)
     373             :    */
     374             :   template <typename CppType>
     375             :   void p_T_from_v_e(const CppType & v,
     376             :                     const CppType & e,
     377             :                     Real p0,
     378             :                     Real T0,
     379             :                     CppType & p,
     380             :                     CppType & T,
     381             :                     bool & conversion_succeeded) const;
     382             : 
     383             :   /**
     384             :    * Determines (p,T) from (v,h) using Newton Solve in 2D
     385             :    * Useful for conversion between different sets of state variables
     386             :    *
     387             :    * @param[in] v specific volume (m^3 / kg)
     388             :    * @param[in] h specific enthalpy (J / kg)
     389             :    * @param[in] p0 initial guess for pressure (Pa / kg)
     390             :    * @param[in] T0 initial guess for temperature (K)
     391             :    * @param[out] fluid pressure (Pa / kg)
     392             :    * @param[out] Temperature (K)
     393             :    */
     394             :   template <typename T>
     395             :   void p_T_from_v_h(const T & v,
     396             :                     const T & h,
     397             :                     Real p0,
     398             :                     Real T0,
     399             :                     T & pressure,
     400             :                     T & temperature,
     401             :                     bool & conversion_succeeded) const;
     402             :   /**
     403             :    * Determines (p,T) from (h,s) using Newton Solve in 2D
     404             :    * Useful for conversion between different sets of state variables
     405             :    *
     406             :    * @param[in] h specific enthalpy (J / kg)
     407             :    * @param[in] s specific entropy (J/K*kg)
     408             :    * @param[in] p0 initial guess for pressure (Pa / kg)
     409             :    * @param[in] T0 initial guess for temperature (K)
     410             :    * @param[out] fluid pressure (Pa / kg)
     411             :    * @param[out] Temperature (K)
     412             :    */
     413             :   template <typename T>
     414             :   void p_T_from_h_s(const T & h,
     415             :                     const T & s,
     416             :                     Real p0,
     417             :                     Real T0,
     418             :                     T & pressure,
     419             :                     T & temperature,
     420             :                     bool & conversion_succeeded) const;
     421             : 
     422             : protected:
     423             :   /**
     424             :    * Computes the dependent variable z and its derivatives with respect to the independent
     425             :    * variables x and y using the simple two parameter \p z_from_x_y functor. The derivatives are
     426             :    * computed using a compound automatic differentiation type
     427             :    */
     428             :   template <typename T, typename Functor>
     429             :   static void
     430             :   xyDerivatives(const T x, const T & y, T & z, T & dz_dx, T & dz_dy, const Functor & z_from_x_y);
     431             : 
     432             :   /**
     433             :    * Given a type example, this method returns zero and unity representations of that type (first
     434             :    * and second members of returned pair respectively)
     435             :    */
     436             :   template <typename T>
     437             :   static std::pair<T, T> makeZeroAndOne(const T &);
     438             : 
     439             :   /**
     440             :    * Newton's method may be used to convert between variable sets
     441             :    */
     442             :   /// Relative tolerance of the solves
     443             :   const Real _tolerance;
     444             :   /// Initial guess for temperature (or temperature used to compute the initial guess)
     445             :   const Real _T_initial_guess;
     446             :   /// Initial guess for pressure (or pressure used to compute the initial guess)
     447             :   const Real _p_initial_guess;
     448             :   /// Maximum number of iterations for the variable conversion newton solves
     449             :   const unsigned int _max_newton_its;
     450             : 
     451             : private:
     452           3 :   void unimplementedDerivativeMethod(const std::string & property_function_name) const
     453             :   {
     454             :     const std::string message =
     455           3 :         "The fluid properties class '" + type() +
     456             :         "' has not implemented the method below, which computes derivatives of fluid properties "
     457             :         "with regards to the flow variables. If your application requires this "
     458             :         "method, you must either implement it or use a different fluid properties "
     459             :         " class.\n\n" +
     460           3 :         property_function_name;
     461             : 
     462           3 :     if (_allow_imperfect_jacobians)
     463           2 :       mooseDoOnce(mooseWarning(message + "\nThe unimplemented derivatives for this fluid property "
     464             :                                          "are currently neglected, set to 0."));
     465             :     else
     466           3 :       mooseError(message + "\n\nYou can avoid this error by neglecting the "
     467             :                            "unimplemented derivatives of fluid properties by setting the "
     468             :                            "'allow_imperfect_jacobians' parameter");
     469           1 :   }
     470             : };
     471             : 
     472             : #pragma GCC diagnostic pop
     473             : 
     474             : template <typename T>
     475             : std::pair<T, T>
     476         317 : SinglePhaseFluidProperties::makeZeroAndOne(const T & /*ex*/)
     477             : {
     478         317 :   return {T{0, 0}, T{1, 0}};
     479             : }
     480             : 
     481             : template <>
     482             : inline std::pair<Real, Real>
     483             : SinglePhaseFluidProperties::makeZeroAndOne(const Real & /*ex*/)
     484             : {
     485             :   return {Real{0}, Real{1}};
     486             : }
     487             : 
     488             : template <typename T, typename Functor>
     489             : void
     490         418 : SinglePhaseFluidProperties::xyDerivatives(
     491             :     const T x, const T & y, T & z, T & dz_dx, T & dz_dy, const Functor & z_from_x_y)
     492             : {
     493             :   typedef MetaPhysicL::DualNumber<T, MetaPhysicL::NumberArray<2, T>> CompoundType;
     494         317 :   const auto [zero, one] = makeZeroAndOne(x);
     495             : 
     496         317 :   CompoundType x_c(x, zero);
     497             :   auto & x_cd = x_c.derivatives();
     498         358 :   x_cd[0] = one;
     499         317 :   CompoundType y_c(y, zero);
     500             :   auto & y_cd = y_c.derivatives();
     501         358 :   y_cd[1] = one;
     502             : 
     503             :   const auto z_c = z_from_x_y(x_c, y_c);
     504         358 :   z = z_c.value();
     505         358 :   dz_dx = z_c.derivatives()[0];
     506         358 :   dz_dy = z_c.derivatives()[1];
     507         418 : }
     508             : 
     509             : template <typename CppType>
     510             : void
     511      381268 : SinglePhaseFluidProperties::p_T_from_v_e(const CppType & v, // v value
     512             :                                          const CppType & e, // e value
     513             :                                          const Real p0,     // initial guess
     514             :                                          const Real T0,     // initial guess
     515             :                                          CppType & p,       // returned pressure
     516             :                                          CppType & T,       // returned temperature
     517             :                                          bool & conversion_succeeded) const
     518             : {
     519      381268 :   auto v_lambda = [&](const CppType & pressure,
     520             :                       const CppType & temperature,
     521             :                       CppType & new_v,
     522             :                       CppType & dv_dp,
     523     9835748 :                       CppType & dv_dT) { v_from_p_T(pressure, temperature, new_v, dv_dp, dv_dT); };
     524      381268 :   auto e_lambda = [&](const CppType & pressure,
     525             :                       const CppType & temperature,
     526             :                       CppType & new_e,
     527             :                       CppType & de_dp,
     528     9835748 :                       CppType & de_dT) { e_from_p_T(pressure, temperature, new_e, de_dp, de_dT); };
     529             :   try
     530             :   {
     531      381268 :     FluidPropertiesUtils::NewtonSolve2D(
     532      381268 :         v, e, p0, T0, p, T, _tolerance, _tolerance, v_lambda, e_lambda);
     533      295086 :     conversion_succeeded = true;
     534             :   }
     535       86182 :   catch (MooseException &)
     536             :   {
     537       86182 :     conversion_succeeded = false;
     538             :   }
     539             : 
     540      381268 :   if (!conversion_succeeded)
     541       86182 :     mooseDoOnce(mooseWarning("Conversion from (v, e)=(", v, ", ", e, ") to (p, T) failed"));
     542      381268 : }
     543             : 
     544             : template <typename T>
     545             : void
     546      381204 : SinglePhaseFluidProperties::p_T_from_v_h(const T & v,     // v value
     547             :                                          const T & h,     // e value
     548             :                                          const Real p0,   // initial guess
     549             :                                          const Real T0,   // initial guess
     550             :                                          T & pressure,    // returned pressure
     551             :                                          T & temperature, // returned temperature
     552             :                                          bool & conversion_succeeded) const
     553             : {
     554      381204 :   auto v_lambda = [&](const T & pressure, const T & temperature, T & new_v, T & dv_dp, T & dv_dT)
     555    10045180 :   { v_from_p_T(pressure, temperature, new_v, dv_dp, dv_dT); };
     556      381204 :   auto h_lambda = [&](const T & pressure, const T & temperature, T & new_h, T & dh_dp, T & dh_dT)
     557    10045180 :   { h_from_p_T(pressure, temperature, new_h, dh_dp, dh_dT); };
     558             :   try
     559             :   {
     560      381204 :     FluidPropertiesUtils::NewtonSolve2D(
     561      381204 :         v, h, p0, T0, pressure, temperature, _tolerance, _tolerance, v_lambda, h_lambda);
     562      292864 :     conversion_succeeded = true;
     563             :   }
     564       88340 :   catch (MooseException &)
     565             :   {
     566       88340 :     conversion_succeeded = false;
     567             :   }
     568             : 
     569      381204 :   if (!conversion_succeeded)
     570       88340 :     mooseDoOnce(mooseWarning("Conversion from (v, h)=(", v, ", ", h, ") to (p, T) failed"));
     571      381204 : }
     572             : 
     573             : template <typename T>
     574             : void
     575           2 : SinglePhaseFluidProperties::p_T_from_h_s(const T & h,     // h value
     576             :                                          const T & s,     // s value
     577             :                                          const Real p0,   // initial guess
     578             :                                          const Real T0,   // initial guess
     579             :                                          T & pressure,    // returned pressure
     580             :                                          T & temperature, // returned temperature
     581             :                                          bool & conversion_succeeded) const
     582             : {
     583           2 :   auto h_lambda = [&](const T & pressure, const T & temperature, T & new_h, T & dh_dp, T & dh_dT)
     584           6 :   { h_from_p_T(pressure, temperature, new_h, dh_dp, dh_dT); };
     585           2 :   auto s_lambda = [&](const T & pressure, const T & temperature, T & new_s, T & ds_dp, T & ds_dT)
     586           6 :   { s_from_p_T(pressure, temperature, new_s, ds_dp, ds_dT); };
     587             :   try
     588             :   {
     589           2 :     FluidPropertiesUtils::NewtonSolve2D(
     590           2 :         h, s, p0, T0, pressure, temperature, _tolerance, _tolerance, h_lambda, s_lambda);
     591           2 :     conversion_succeeded = true;
     592             :   }
     593           0 :   catch (MooseException &)
     594             :   {
     595           0 :     conversion_succeeded = false;
     596             :   }
     597             : 
     598           2 :   if (!conversion_succeeded)
     599           0 :     mooseDoOnce(mooseWarning("Conversion from (h, s)=(", h, ", ", s, ") to (p, T) failed"));
     600           2 : }
     601             : 
     602             : template <typename CppType>
     603             : void
     604         792 : SinglePhaseFluidProperties::v_e_from_p_T(const CppType & p,
     605             :                                          const CppType & T,
     606             :                                          CppType & v,
     607             :                                          CppType & e) const
     608             : {
     609         792 :   const CppType rho = rho_from_p_T(p, T);
     610         792 :   v = 1.0 / rho;
     611             :   try
     612             :   {
     613             :     // more likely to not involve a Newton search
     614         792 :     e = e_from_p_T(p, T);
     615             :   }
     616           0 :   catch (...)
     617             :   {
     618           0 :     e = e_from_p_rho(p, rho);
     619             :   }
     620         792 : }
     621             : 
     622             : template <typename CppType>
     623             : void
     624           7 : SinglePhaseFluidProperties::v_e_from_p_T(const CppType & p,
     625             :                                          const CppType & T,
     626             :                                          CppType & v,
     627             :                                          CppType & dv_dp,
     628             :                                          CppType & dv_dT,
     629             :                                          CppType & e,
     630             :                                          CppType & de_dp,
     631             :                                          CppType & de_dT) const
     632             : {
     633             :   CppType rho, drho_dp, drho_dT;
     634           7 :   rho_from_p_T(p, T, rho, drho_dp, drho_dT);
     635             : 
     636           7 :   v = 1.0 / rho;
     637           7 :   const CppType dv_drho = -1.0 / (rho * rho);
     638           7 :   dv_dp = dv_drho * drho_dp;
     639           7 :   dv_dT = dv_drho * drho_dT;
     640             : 
     641             :   CppType de_dp_partial, de_drho;
     642           7 :   e_from_p_rho(p, rho, e, de_dp_partial, de_drho);
     643           7 :   de_dp = de_dp_partial + de_drho * drho_dp;
     644           7 :   de_dT = de_drho * drho_dT;
     645           7 : }

Generated by: LCOV version 1.14