https://mooseframework.inl.gov
SinglePhaseFluidProperties.h
Go to the documentation of this file.
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 
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 
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 
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 
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 
115 {
116 public:
117  static InputParameters validParams();
118 
120  virtual ~SinglePhaseFluidProperties();
121 
122 #pragma GCC diagnostic push
123 #pragma GCC diagnostic ignored "-Woverloaded-virtual"
124  // clang-format off
125 
180  propfunc(p, v, e)
182  propfunc(T, v, e)
183  propfunc(c, v, e)
184  propfunc(cp, v, e)
185  propfunc(cv, v, e)
186  propfunc(mu, v, e)
187  propfunc(k, v, e)
189  propfunc(s, h, p)
191  propfunc(e, v, h)
193  propfunc(pp_sat, p, T)
195  propfunc(k, rho, T)
201  propfunc(rho, p, T)
203  propfunc(e, T, v)
205  propfunc(h, T, v)
206  propfunc(s, T, v)
207  propfunc(cv, T, v)
209  propfuncWithDefault(h, v, e)
210  propfunc(g, v, e)
211  propfuncWithDefault(p, h, s)
212  propfunc(T, h, p) // temporary, until uniformization
217  propfuncWithDefault(gamma, v, e)
220 
221  // clang-format on
222 
223 #undef propfunc
224 #undef propfuncWithDefault
225 #undef propfuncAD
226 
231  virtual std::string fluidName() const;
232 
237  virtual Real molarMass() const;
238 
243  virtual Real criticalPressure() const;
244 
249  virtual Real criticalTemperature() const;
250 
255  virtual Real criticalDensity() const;
256 
261  virtual Real criticalInternalEnergy() const;
262 
267  virtual Real triplePointPressure() const;
268 
273  virtual Real triplePointTemperature() const;
274 
281  virtual Real e_spndl_from_v(Real v) const;
282 
289  virtual void v_e_spndl_from_T(Real T, Real & v, Real & e) const;
290 
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 
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 
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 
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 
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 
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;
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:
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 
436  template <typename T>
437  static std::pair<T, T> makeZeroAndOne(const T &);
438 
442  const Real _tolerance;
449  const unsigned int _max_newton_its;
451  const bool _verbose_newton;
452 
453 private:
454  void unimplementedDerivativeMethod(const std::string & property_function_name) const
455  {
456  const std::string message =
457  "The fluid properties class '" + type() +
458  "' has not implemented the method below, which computes derivatives of fluid properties "
459  "with regards to the flow variables. If your application requires this "
460  "method, you must either implement it or use a different fluid properties "
461  " class.\n\n" +
462  property_function_name;
463 
465  mooseDoOnce(mooseWarning(message + "\nThe unimplemented derivatives for this fluid property "
466  "are currently neglected, set to 0."));
467  else
468  mooseError(message + "\n\nYou can avoid this error by neglecting the "
469  "unimplemented derivatives of fluid properties by setting the "
470  "'allow_imperfect_jacobians' parameter");
471  }
472 };
473 
474 #pragma GCC diagnostic pop
475 
476 template <typename T>
477 std::pair<T, T>
479 {
480  return {T{0, 0}, T{1, 0}};
481 }
482 
483 template <>
484 inline std::pair<Real, Real>
486 {
487  return {Real{0}, Real{1}};
488 }
489 
490 template <typename T, typename Functor>
491 void
493  const T x, const T & y, T & z, T & dz_dx, T & dz_dy, const Functor & z_from_x_y)
494 {
496  const auto [zero, one] = makeZeroAndOne(x);
497 
498  CompoundType x_c(x, zero);
499  auto & x_cd = x_c.derivatives();
500  x_cd[0] = one;
501  CompoundType y_c(y, zero);
502  auto & y_cd = y_c.derivatives();
503  y_cd[1] = one;
504 
505  const auto z_c = z_from_x_y(x_c, y_c);
506  z = z_c.value();
507  dz_dx = z_c.derivatives()[0];
508  dz_dy = z_c.derivatives()[1];
509 }
510 
511 template <typename CppType>
512 void
513 SinglePhaseFluidProperties::p_T_from_v_e(const CppType & v, // v value
514  const CppType & e, // e value
515  const Real p0, // initial guess
516  const Real T0, // initial guess
517  CppType & p, // returned pressure
518  CppType & T, // returned temperature
519  bool & conversion_succeeded) const
520 {
521  auto v_lambda = [&](const CppType & pressure,
522  const CppType & temperature,
523  CppType & new_v,
524  CppType & dv_dp,
525  CppType & dv_dT) { v_from_p_T(pressure, temperature, new_v, dv_dp, dv_dT); };
526  auto e_lambda = [&](const CppType & pressure,
527  const CppType & temperature,
528  CppType & new_e,
529  CppType & de_dp,
530  CppType & de_dT) { e_from_p_T(pressure, temperature, new_e, de_dp, de_dT); };
531  try
532  {
534  e,
535  p0,
536  T0,
537  p,
538  T,
539  _tolerance,
540  _tolerance,
541  v_lambda,
542  e_lambda,
543  "p_T_from_v_e",
546  conversion_succeeded = true;
547  }
548  catch (MooseException &)
549  {
550  conversion_succeeded = false;
551  }
552 
553  if (!conversion_succeeded)
554  mooseDoOnce(mooseWarning("Conversion from (v, e)=(", v, ", ", e, ") to (p, T) failed"));
555 }
556 
557 template <typename T>
558 void
560  const T & h, // e value
561  const Real p0, // initial guess
562  const Real T0, // initial guess
563  T & pressure, // returned pressure
564  T & temperature, // returned temperature
565  bool & conversion_succeeded) const
566 {
567  auto v_lambda = [&](const T & pressure, const T & temperature, T & new_v, T & dv_dp, T & dv_dT)
568  { v_from_p_T(pressure, temperature, new_v, dv_dp, dv_dT); };
569  auto h_lambda = [&](const T & pressure, const T & temperature, T & new_h, T & dh_dp, T & dh_dT)
570  { h_from_p_T(pressure, temperature, new_h, dh_dp, dh_dT); };
571  try
572  {
574  h,
575  p0,
576  T0,
577  pressure,
578  temperature,
579  _tolerance,
580  _tolerance,
581  v_lambda,
582  h_lambda,
583  "p_T_from_v_h",
586  conversion_succeeded = true;
587  }
588  catch (MooseException &)
589  {
590  conversion_succeeded = false;
591  }
592 
593  if (!conversion_succeeded)
594  mooseDoOnce(mooseWarning("Conversion from (v, h)=(", v, ", ", h, ") to (p, T) failed"));
595 }
596 
597 template <typename T>
598 void
600  const T & s, // s value
601  const Real p0, // initial guess
602  const Real T0, // initial guess
603  T & pressure, // returned pressure
604  T & temperature, // returned temperature
605  bool & conversion_succeeded) const
606 {
607  auto h_lambda = [&](const T & pressure, const T & temperature, T & new_h, T & dh_dp, T & dh_dT)
608  { h_from_p_T(pressure, temperature, new_h, dh_dp, dh_dT); };
609  auto s_lambda = [&](const T & pressure, const T & temperature, T & new_s, T & ds_dp, T & ds_dT)
610  { s_from_p_T(pressure, temperature, new_s, ds_dp, ds_dT); };
611  try
612  {
614  s,
615  p0,
616  T0,
617  pressure,
618  temperature,
619  _tolerance,
620  _tolerance,
621  h_lambda,
622  s_lambda,
623  "p_T_from_h_s",
626  conversion_succeeded = true;
627  }
628  catch (MooseException &)
629  {
630  conversion_succeeded = false;
631  }
632 
633  if (!conversion_succeeded)
634  mooseDoOnce(mooseWarning("Conversion from (h, s)=(", h, ", ", s, ") to (p, T) failed"));
635 }
636 
637 template <typename CppType>
638 void
640  const CppType & T,
641  CppType & v,
642  CppType & e) const
643 {
644  const CppType rho = rho_from_p_T(p, T);
645  v = 1.0 / rho;
646  try
647  {
648  // more likely to not involve a Newton search
649  e = e_from_p_T(p, T);
650  }
651  catch (...)
652  {
653  e = e_from_p_rho(p, rho);
654  }
655 }
656 
657 template <typename CppType>
658 void
660  const CppType & T,
661  CppType & v,
662  CppType & dv_dp,
663  CppType & dv_dT,
664  CppType & e,
665  CppType & de_dp,
666  CppType & de_dT) const
667 {
668  CppType rho, drho_dp, drho_dT;
669  rho_from_p_T(p, T, rho, drho_dp, drho_dT);
670 
671  v = 1.0 / rho;
672  const CppType dv_drho = -1.0 / (rho * rho);
673  dv_dp = dv_drho * drho_dp;
674  dv_dT = dv_drho * drho_dT;
675 
676  CppType de_dp_partial, de_drho;
677  e_from_p_rho(p, rho, e, de_dp_partial, de_drho);
678  de_dp = de_dp_partial + de_drho * drho_dp;
679  de_dT = de_drho * drho_dT;
680 }
propfunc(p, v, e) propfunc(T
Compute a fluid property given for the state defined by two given properties.
static const std::string cv
Definition: NS.h:126
e e e e s T T T propfuncWithDefault(cp, p, T) propfuncWithDefault(cv
const bool _allow_imperfect_jacobians
Flag to set unimplemented Jacobian entries to zero.
virtual Real triplePointTemperature() const
Triple point temperature.
void p_T_from_v_h(const T &v, const T &h, Real p0, Real T0, T &pressure, T &temperature, bool &conversion_succeeded) const
Determines (p,T) from (v,h) using Newton Solve in 2D Useful for conversion between different sets of ...
const double T
static InputParameters validParams()
const InputParameters & parameters() const
static std::pair< T, T > makeZeroAndOne(const T &)
Given a type example, this method returns zero and unity representations of that type (first and seco...
virtual Real molarMass() const
Molar mass [kg/mol].
void NewtonSolve2D(const T &f, const T &g, const Real x0, const Real y0, T &x_final, T &y_final, const Real f_tol, const Real g_tol, const Functor1 &f_from_x_y, const Functor2 &g_from_x_y, const std::string &caller_name="", const unsigned int max_its=100, bool debug=false)
NewtonSolve2D does a 2D Newton Solve to solve for the x and y such that: f = f_from_x_y(x, y) and g = g_from_x_y(x, y).
const double v
virtual std::vector< Real > henryCoefficients() const
Henry&#39;s law coefficients for dissolution in water.
SinglePhaseFluidProperties(const InputParameters &parameters)
const std::vector< double > y
static const std::string temperature
Definition: NS.h:60
const Number zero
void v_e_from_p_T(const CppType &p, const CppType &T, CppType &v, CppType &e) const
DualNumber< Real, DNDerivativeType, false > ADReal
void p_T_from_v_e(const CppType &v, const CppType &e, Real p0, Real T0, CppType &p, CppType &T, bool &conversion_succeeded) const
Determines (p,T) from (v,e) using Newton Solve in 2D Useful for conversion between different sets of ...
virtual Real criticalInternalEnergy() const
Critical specific internal energy.
static void xyDerivatives(const T x, const T &y, T &z, T &dz_dx, T &dz_dy, const Functor &z_from_x_y)
Computes the dependent variable z and its derivatives with respect to the independent variables x and...
static const std::string cp
Definition: NS.h:125
const Real _tolerance
Newton&#39;s method may be used to convert between variable sets.
const bool _verbose_newton
Whether to output information about newton solves to console.
e e e e s T T T T T rho v v T e h
virtual Real vaporTemperature(Real p) const
Vapor temperature.
FunctorEnvelope< T > Functor
virtual Real criticalTemperature() const
Critical temperature.
const std::vector< double > x
const std::string & type() const
Common class for single phase fluid properties.
virtual void v_e_spndl_from_T(Real T, Real &v, Real &e) const
Specific internal energy from temperature and specific volume.
virtual void rho_e_from_p_T(Real p, Real T, Real &rho, Real &drho_dp, Real &drho_dT, Real &e, Real &de_dp, Real &de_dT) const
virtual Real triplePointPressure() const
Triple point pressure.
virtual Real e_spndl_from_v(Real v) const
Specific internal energy from temperature and specific volume.
void p_T_from_h_s(const T &h, const T &s, Real p0, Real T0, T &pressure, T &temperature, bool &conversion_succeeded) const
Determines (p,T) from (h,s) using Newton Solve in 2D Useful for conversion between different sets of ...
virtual void rho_mu_from_p_T(Real p, Real T, Real &rho, Real &mu) const
Combined methods.
virtual Real criticalDensity() const
Critical density.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string message
const Real p
const unsigned int _max_newton_its
Maximum number of iterations for the variable conversion newton solves.
static const std::string pressure
Definition: NS.h:57
const Real _p_initial_guess
Initial guess for pressure (or pressure used to compute the initial guess)
void mooseWarning(Args &&... args) const
void mooseError(Args &&... args) const
virtual Real criticalPressure() const
Critical pressure.
e e e e s T T T T T rho v v T e p T T virtual T std::string fluidName() const
Fluid name.
virtual Real vaporPressure(Real T) const
Vapor pressure.
const double mu
const Real _T_initial_guess
Initial guess for temperature (or temperature used to compute the initial guess)
void unimplementedDerivativeMethod(const std::string &property_function_name) const
static const std::string k
Definition: NS.h:134