https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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{
116public:
118
121
122#pragma GCC diagnostic push
123#pragma GCC diagnostic ignored "-Woverloaded-virtual"
124 // clang-format off
125
184 propfunc(cp, v, e)
185 propfunc(cv, v, e)
187 propfunc(k, v, e)
193 propfunc(pp_sat, p, T)
210 propfunc(g, v, e)
212 propfunc(T, h, p) // temporary, until uniformization
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
422protected:
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
443 const Real _tolerance;
449 const unsigned int _max_newton_its;
451 const bool _verbose_newton;
452
453private:
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
476template <typename T>
477std::pair<T, T>
479{
480 return {T{0, 0}, T{1, 0}};
481}
482
483template <>
484inline std::pair<Real, Real>
486{
487 return {Real{0}, Real{1}};
488}
489
490template <typename T, typename Functor>
491void
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
511template <typename CppType>
512void
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,
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
557template <typename T>
558void
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,
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
597template <typename T>
598void
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,
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
637template <typename CppType>
638void
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
657template <typename CppType>
658void
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}
DualNumber< Real, DNDerivativeType, true > ADReal
const std::vector< double > y
const std::vector< double > x
const double mu
const Real p
const double T
const double v
const bool _allow_imperfect_jacobians
Flag to set unimplemented Jacobian entries to zero.
const InputParameters & parameters() const
const std::string & type() const
void mooseError(Args &&... args) const
void mooseWarning(Args &&... args) const
Common class for single phase fluid properties.
virtual std::vector< Real > henryCoefficients() const
Henry's law coefficients for dissolution in water.
const Real _T_initial_guess
Initial guess for temperature (or temperature used to compute the initial guess)
void p_T_from_h_s(const T &h, const T &s, Real p0, Real T0, T &pressure, T &temperature, bool &conversion_succeeded) const
Determines (p,T) from (h,s) using Newton Solve in 2D Useful for conversion between different sets of ...
propfunc(p, v, e) propfunc(T
Compute a fluid property given for the state defined by two given properties.
virtual Real criticalInternalEnergy() const
Critical specific internal energy.
const bool _verbose_newton
Whether to output information about newton solves to console.
void p_T_from_v_e(const CppType &v, const CppType &e, Real p0, Real T0, CppType &p, CppType &T, bool &conversion_succeeded) const
Determines (p,T) from (v,e) using Newton Solve in 2D Useful for conversion between different sets of ...
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...
const Real _p_initial_guess
Initial guess for pressure (or pressure used to compute the initial guess)
virtual void v_e_spndl_from_T(Real T, Real &v, Real &e) const
Specific internal energy from temperature and specific volume.
virtual Real vaporPressure(Real T) const
Vapor pressure.
static InputParameters validParams()
const Real _tolerance
Newton's method may be used to convert between variable sets.
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.
virtual Real criticalDensity() const
Critical density.
virtual Real criticalPressure() const
Critical pressure.
const unsigned int _max_newton_its
Maximum number of iterations for the variable conversion newton solves.
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 ...
virtual Real molarMass() const
Molar mass [kg/mol].
void unimplementedDerivativeMethod(const std::string &property_function_name) const
void v_e_from_p_T(const CppType &p, const CppType &T, CppType &v, CppType &e) const
e e e e s T T T propfuncWithDefault(cp, p, T) propfuncWithDefault(cv
e e e e s T T T T T rho v v T e h
virtual Real criticalTemperature() const
Critical temperature.
virtual Real triplePointTemperature() const
Triple point temperature.
virtual Real vaporTemperature(Real p) const
Vapor temperature.
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...
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 void rho_mu_from_p_T(Real p, Real T, Real &rho, Real &mu) const
Combined methods.
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,...