https://mooseframework.inl.gov
TemperaturePressureFunctionFluidProperties.C
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 
11 #include "NewtonInversion.h"
12 
14 
17 {
19  params.addRequiredParam<FunctionName>(
20  "k", "Thermal conductivity function of temperature and pressure [W/(m-K)]");
21  params.addRequiredParam<FunctionName>("rho",
22  "Density function of temperature and pressure [kg/m^3]");
23  params.addRequiredParam<FunctionName>(
24  "mu", "Dynamic viscosity function of temperature and pressure [Pa-s]");
25 
26  params.addParam<FunctionName>(
27  "cp", "Isobaric specific heat function of temperature and pressure [J/(kg-K)]");
28  params.addRangeCheckedParam<Real>(
29  "cv", 0, "cv >= 0", "Constant isochoric specific heat [J/(kg-K)]");
30  params.addParam<Real>("e_ref", 0, "Specific internal energy at the reference temperature");
31  params.addParam<Real>("T_ref", 0, "Reference temperature for the specific internal energy");
32  params.addParam<Real>("dT_integration_intervals",
33  10,
34  "Size of intervals for integrating cv(T) to compute e(T) from e(T_ref)");
35 
36  params.addClassDescription(
37  "Single-phase fluid properties that allows to provide thermal "
38  "conductivity, density, and viscosity as functions of temperature and pressure.");
39  return params;
40 }
41 
43  const InputParameters & parameters)
44  : SinglePhaseFluidProperties(parameters),
45  _initialized(false),
46  _cv(getParam<Real>("cv")),
47  _cv_is_constant(_cv != 0),
48  _e_ref(getParam<Real>("e_ref")),
49  _T_ref(getParam<Real>("T_ref")),
50  _integration_dT(getParam<Real>("dT_integration_intervals"))
51 {
52  if (isParamValid("cp") && _cv_is_constant)
53  paramError("cp", "The parameter 'cp' may only be specified if 'cv' is unspecified or is zero.");
54 }
55 
56 void
58 {
59  _k_function = &getFunction("k");
60  _rho_function = &getFunction("rho");
61  _mu_function = &getFunction("mu");
62  _cp_function = isParamValid("cp") ? &getFunction("cp") : nullptr;
63  _initialized = true;
64 }
65 
66 std::string
68 {
69  return "TemperaturePressureFunctionFluidProperties";
70 }
71 
72 Real
74 {
75  if (_cv_is_constant)
76  return _T_ref + (e - _e_ref) / _cv;
77  else
78  {
79  const Real p0 = _p_initial_guess;
80  const Real T0 = _T_initial_guess;
81  Real p, T;
82  bool conversion_succeeded = true;
83  p_T_from_v_e(v, e, p0, T0, p, T, conversion_succeeded);
84  if (conversion_succeeded)
85  return T;
86  else
87  mooseError("T_from_v_e calculation failed.");
88  }
89 }
90 
91 Real
93 {
94  auto lambda = [&](Real p, Real current_T, Real & new_h, Real & dh_dp, Real & dh_dT)
95  { h_from_p_T(p, current_T, new_h, dh_dp, dh_dT); };
97  p, h, _T_initial_guess, _tolerance, lambda, name() + "::T_from_p_h", _max_newton_its)
98  .first;
99  // check for nans
100  if (std::isnan(T))
101  mooseError("Conversion from pressure (p = ",
102  p,
103  ") and enthalpy (h = ",
104  h,
105  ") to temperature failed to converge.");
106  return T;
107 }
108 
109 Real
111 {
112  auto lambda = [&](Real p, Real current_T, Real & new_rho, Real & drho_dp, Real & drho_dT)
113  { rho_from_p_T(p, current_T, new_rho, drho_dp, drho_dT); };
115  p, rho, _T_initial_guess, _tolerance, lambda, name() + "::T_from_p_rho")
116  .first;
117  // check for nans
118  if (std::isnan(T))
119  mooseError("Conversion from pressure (p = ",
120  p,
121  ") and density (rho = ",
122  rho,
123  ") to temperature failed to converge.");
124  return T;
125 }
126 
127 Real
129 {
130  if (_cv_is_constant)
131  {
132  Real p = p_from_v_e(v, e);
133  Real T = T_from_v_e(v, e);
134  return cp_from_p_T(p, T);
135  }
136  else
137  {
138  const Real p0 = _p_initial_guess;
139  const Real T0 = _T_initial_guess;
140  Real p, T;
141  bool conversion_succeeded = true;
142  p_T_from_v_e(v, e, p0, T0, p, T, conversion_succeeded);
143  if (conversion_succeeded)
144  return cp_from_p_T(p, T);
145  else
146  mooseError("cp_from_v_e calculation failed. p= ", p, " T = ", T);
147  }
148 }
149 
150 void
152  Real v, Real e, Real & cp, Real & dcp_dv, Real & dcp_de) const
153 {
154  cp = cp_from_v_e(v, e);
155  // Using finite difference to get around difficulty of implementation
156  Real eps = 1e-10;
157  Real cp_pert = cp_from_v_e(v * (1 + eps), e);
158  dcp_dv = (cp_pert - cp) / eps / v;
159  cp_pert = cp_from_v_e(v, e * (1 + eps));
160  dcp_de = (cp_pert - cp) / eps / e;
161 }
162 
163 Real
165 {
166  if (_cv_is_constant)
167  return _cv;
168  else
169  {
170  const Real p0 = _p_initial_guess;
171  const Real T0 = _T_initial_guess;
172  Real p, T;
173  bool conversion_succeeded = true;
174  p_T_from_v_e(v, e, p0, T0, p, T, conversion_succeeded);
175  if (conversion_succeeded)
176  return cv_from_p_T(p, T);
177  else
178  mooseError("cp_from_v_e calculation failed.");
179  }
180 }
181 
182 void
184  Real v, Real e, Real & cv, Real & dcv_dv, Real & dcv_de) const
185 {
186  if (_cv_is_constant)
187  {
188  cv = cv_from_v_e(v, e);
189  dcv_dv = 0.0;
190  dcv_de = 0.0;
191  }
192  else
193  {
194  const Real p0 = _p_initial_guess;
195  const Real T0 = _T_initial_guess;
196  Real p, T;
197  bool conversion_succeeded = true;
198  p_T_from_v_e(v, e, p0, T0, p, T, conversion_succeeded);
199  Real dcv_dp, dcv_dT;
200  cv_from_p_T(p, T, cv, dcv_dp, dcv_dT);
201  if (!conversion_succeeded)
202  mooseError("cp_from_v_e and derivatives calculation failed.");
203 
204  Real p1, T1;
205  p_T_from_v_e(v * (1 + 1e-6), e, p0, T0, p1, T1, conversion_succeeded);
206  Real dp_dv = (p1 - p) / (v * 1e-6);
207  Real dT_dv = (T1 - T) / (v * 1e-6);
208  if (!conversion_succeeded)
209  mooseError("cp_from_v_e and derivatives calculation failed.");
210 
211  Real p2, T2;
212  p_T_from_v_e(v, e * (1 + 1e-6), p0, T0, p2, T2, conversion_succeeded);
213  Real dp_de = (p2 - p) / (e * 1e-6);
214  Real dT_de = (T2 - T) / (e * 1e-6);
215  if (!conversion_succeeded)
216  mooseError("cp_from_v_e and derivatives calculation failed.");
217 
218  dcv_dv = dcv_dp * dp_dv + dcv_dT * dT_dv;
219  dcv_de = dcv_dp * dp_de + dcv_dT * dT_de;
220  }
221 }
222 
223 Real
225 {
226  const Real T = T_from_v_e(v, e);
227  // note that p and T inversion in the definition of lambda
228  auto lambda = [&](Real T, Real current_p, Real & new_rho, Real & drho_dT, Real & drho_dp)
229  { rho_from_p_T(current_p, T, new_rho, drho_dp, drho_dT); };
231  T, 1. / v, _p_initial_guess, _tolerance, lambda, name() + "::p_from_v_e")
232  .first;
233  // check for nans
234  if (std::isnan(p))
235  mooseError("Conversion from specific volume (v = ",
236  v,
237  ") and specific energy (e = ",
238  e,
239  ") to pressure failed to converge.");
240  return p;
241 }
242 
243 Real
245 {
246  if (_cv_is_constant)
247  {
249  Real pressure = p_from_v_e(v, e);
251  }
252  else
253  {
254  const Real p0 = _p_initial_guess;
255  const Real T0 = _T_initial_guess;
256  Real p, T;
257  bool conversion_succeeded = true;
258  p_T_from_v_e(v, e, p0, T0, p, T, conversion_succeeded);
259  if (conversion_succeeded)
260  return mu_from_p_T(p, T);
261  else
262  mooseError("mu_from_v_e calculation failed.");
263  }
264 }
265 
266 Real
268 {
269  if (_cv_is_constant)
270  {
272  Real pressure = p_from_v_e(v, e);
274  }
275  else
276  {
277  const Real p0 = _p_initial_guess;
278  const Real T0 = _T_initial_guess;
279  Real p, T;
280  bool conversion_succeeded = true;
281  p_T_from_v_e(v, e, p0, T0, p, T, conversion_succeeded);
282  if (conversion_succeeded)
283  return k_from_p_T(p, T);
284  else
285  mooseError("k_from_v_e calculation failed.");
286  }
287 }
288 
289 Real
291 {
292  if (!_initialized)
294  return _rho_function->value(0, Point(temperature, pressure, 0));
295 }
296 
297 void
299  Real pressure, Real temperature, Real & rho, Real & drho_dp, Real & drho_dT) const
300 {
302  const RealVectorValue grad_function = _rho_function->gradient(0, Point(temperature, pressure, 0));
303  drho_dT = grad_function(0);
304  drho_dp = grad_function(1);
305 }
306 
307 void
309  const ADReal & temperature,
310  ADReal & rho,
311  ADReal & drho_dp,
312  ADReal & drho_dT) const
313 {
315  const ADRealVectorValue grad_function =
316  _rho_function->gradient(0, Point(temperature.value(), pressure.value(), 0));
317  drho_dT = grad_function(0);
318  drho_dp = grad_function(1);
319 }
320 
321 Real
323 {
324  return 1.0 / rho_from_p_T(pressure, temperature);
325 }
326 
327 void
329  Real pressure, Real temperature, Real & v, Real & dv_dp, Real & dv_dT) const
330 {
332 
333  Real rho, drho_dp, drho_dT;
334  rho_from_p_T(pressure, temperature, rho, drho_dp, drho_dT);
335 
336  dv_dp = -v * v * drho_dp;
337  dv_dT = -v * v * drho_dT;
338 }
339 
340 Real
342 {
345  return e + pressure / rho;
346 }
347 
348 void
350  Real pressure, Real temperature, Real & h, Real & dh_dp, Real & dh_dT) const
351 {
352  Real e, de_dp, de_dT;
353  e_from_p_T(pressure, temperature, e, de_dp, de_dT);
354  Real rho, drho_dp, drho_dT;
355  rho_from_p_T(pressure, temperature, rho, drho_dp, drho_dT);
356  h = e + pressure / rho;
357  dh_dp = de_dp + 1. / rho - pressure / rho / rho * drho_dp;
358  dh_dT = de_dT - pressure * drho_dT / rho / rho;
359 }
360 
361 Real
363 {
364  if (_cv_is_constant)
365  return _e_ref + _cv * (temperature - _T_ref);
366  else
367  {
368  const int n_intervals = std::ceil(std::abs(temperature - _T_ref) / _integration_dT);
369  const auto h = (temperature - _T_ref) / n_intervals;
370  Real integral = 0;
371  // Centered step integration is second-order
372  for (const auto i : make_range(n_intervals))
373  integral += cv_from_p_T(pressure, _T_ref + (i + 0.5) * h);
374  integral *= h;
375  // we are still missing the dV or dP term to go from V/P_ref (e_ref = e(T_ref, V/P_ref))
376  // to current V. The dT term is the largest one though
377  return _e_ref + integral;
378  }
379 }
380 
381 void
383  Real pressure, Real temperature, Real & e, Real & de_dp, Real & de_dT) const
384 {
385  if (_cv_is_constant)
386  {
388  de_dp = 0.0;
389  de_dT = _cv;
390  }
391  else
392  {
394  Real ep = e_from_p_T(pressure * (1 + 1e-8), temperature);
395  de_dp = (ep - e) / (pressure * 1e-8);
396  de_dT = cv_from_p_T(pressure, temperature);
397  }
398 }
399 
400 Real
402 {
403  if (_cv_is_constant)
404  {
406  return _e_ref + _cv * (temperature - _T_ref);
407  }
408  else
409  {
411  return e_from_p_T(p, temperature);
412  }
413 }
414 
415 Real
417 {
418  Real rho, drho_dp, drho_dT;
419  rho_from_p_T(pressure, temperature, rho, drho_dp, drho_dT);
420  return -drho_dT / rho;
421 }
422 
423 Real
425 {
426  if (_cv_is_constant)
427  {
428  Real rho, drho_dp, drho_dT;
429  rho_from_p_T(p, T, rho, drho_dp, drho_dT);
430  // Wikipedia notation for thermal expansion / compressibility coefficients
431  Real alpha = -drho_dT / rho;
432  Real beta = -drho_dp / rho;
433  return _cv + MathUtils::pow(alpha, 2) * T / rho / beta;
434  }
435  else
436  {
437  if (!_initialized)
439  return _cp_function->value(0, Point(T, p, 0));
440  }
441 }
442 
443 void
445  Real pressure, Real temperature, Real & cp, Real & dcp_dp, Real & dcp_dT) const
446 {
447  if (_cv_is_constant)
448  {
450  Real eps = 1e-8;
451  Real cp_1p = cp_from_p_T(pressure * (1 + eps), temperature);
452  Real cp_1T = cp_from_p_T(pressure, temperature * (1 + eps));
453  dcp_dp = (cp_1p - cp) / (pressure * eps);
454  dcp_dT = (cp_1T - cp) / (temperature * eps);
455  }
456  else
457  {
459  const RealVectorValue grad_function =
460  _cp_function->gradient(0, Point(temperature, pressure, 0));
461  dcp_dT = grad_function(0);
462  dcp_dp = grad_function(1);
463  }
464 }
465 
466 Real
468 {
469  if (_cv_is_constant)
470  return _cv;
471  else
472  {
473  Real rho, drho_dp, drho_dT;
474  rho_from_p_T(pressure, temperature, rho, drho_dp, drho_dT);
475  // Wikipedia notation for thermal expansion / compressibility coefficients
476  Real alpha = -drho_dT / rho;
477  Real beta = -drho_dp / rho;
479  }
480 }
481 
482 void
484  Real pressure, Real temperature, Real & cv, Real & dcv_dp, Real & dcv_dT) const
485 {
486  if (_cv_is_constant)
487  {
489  dcv_dp = 0.0;
490  dcv_dT = 0.0;
491  }
492  else
493  {
495  Real eps = 1e-10;
496  Real cv_1p = cv_from_p_T(pressure * (1 + eps), temperature);
497  Real cv_1T = cv_from_p_T(pressure, temperature * (1 + eps));
498  dcv_dp = (cv_1p - cv) / (pressure * eps);
499  dcv_dT = (cv_1T - cv) / (temperature * eps);
500  }
501 }
502 
503 Real
505 {
506  if (!_initialized)
508  return _mu_function->value(0, Point(temperature, pressure, 0));
509 }
510 
511 void
513  Real pressure, Real temperature, Real & mu, Real & dmu_dp, Real & dmu_dT) const
514 {
516  const RealVectorValue grad_function = _mu_function->gradient(0, Point(temperature, pressure, 0));
517  dmu_dT = grad_function(0);
518  dmu_dp = grad_function(1);
519 }
520 
521 Real
523 {
524  if (!_initialized)
526  return _k_function->value(0, Point(temperature, pressure, 0));
527 }
528 
529 void
531  Real pressure, Real temperature, Real & k, Real & dk_dp, Real & dk_dT) const
532 {
534  const RealVectorValue grad_function = _k_function->gradient(0, Point(temperature, pressure, 0));
535  dk_dT = grad_function(0);
536  dk_dp = grad_function(1);
537 }
virtual Real beta_from_p_T(Real p, Real T) const override
Thermal expansion coefficient from pressure and temperature.
static const std::string cv
Definition: NS.h:122
const Function * _k_function
function defining thermal conductivity as a function of temperature and pressure
virtual Real mu_from_v_e(Real v, Real e) const override
Dynamic viscosity from specific volume and specific internal energy.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const Function * _cp_function
function defining specific heat as a function of temperature and pressure
const Real eps
static InputParameters validParams()
const Function & getFunction(const std::string &name) const
virtual Real mu_from_p_T(Real p, Real T) const override
Dynamic viscosity from pressure and temperature.
Fluid properties provided as multiple-variable functions of temperature and pressure.
static const std::string temperature
Definition: NS.h:59
bool _initialized
whether the object is initialized, eg, the functions have been retrieved from the problem ...
DualNumber< Real, DNDerivativeType, true > ADReal
virtual Real e_from_p_rho(Real p, Real rho) const override
Specific internal energy from pressure and density.
virtual const std::string & name() const
virtual Real T_from_p_rho(Real p, Real rho) const
Temperature from pressure and density.
void addRequiredParam(const std::string &name, const std::string &doc_string)
std::pair< T, T > NewtonSolve(const T &x, const T &y, const Real z_initial_guess, const Real tolerance, const Functor &func, const std::string &caller_name, const unsigned int max_its=100)
NewtonSolve does a 1D Newton Solve to solve the equation y = f(x, z) for variable z...
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 k_from_p_T(Real p, Real T) const override
Thermal conductivity from pressure and temperature.
bool isParamValid(const std::string &name) const
virtual std::string fluidName() const override
Fluid name.
static const std::string cp
Definition: NS.h:121
const Real _tolerance
Newton&#39;s method may be used to convert between variable sets.
e e e e s T T T T T rho v v T e h
virtual Real T_from_v_e(Real v, Real e) const override
Temperature from specific volume and specific internal energy.
virtual Real cv_from_p_T(Real p, Real T) const override
Isochoric specific heat capacity from pressure and temperature.
void initialSetup() override
Functions are constructed after fluid properties, so we delay the getting of the Function.
static const std::string mu
Definition: NS.h:123
Common class for single phase fluid properties.
void paramError(const std::string &param, Args... args) const
TemperaturePressureFunctionFluidProperties(const InputParameters &parameters)
virtual Real rho_from_p_T(Real p, Real T) const override
Density from pressure and temperature.
const Real _T_ref
Reference temperature for the reference specific energy.
registerMooseObject("FluidPropertiesApp", TemperaturePressureFunctionFluidProperties)
virtual Real T_from_p_h(Real p, Real h) const override
Temperature from pressure and specific enthalpy.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string v
Definition: NS.h:84
const Real _integration_dT
Size of temperature intervals when integrating the specific heat to compute the specific energy...
static const std::string alpha
Definition: NS.h:134
virtual Real k_from_v_e(Real v, Real e) const override
Thermal conductivity from specific volume and specific internal energy.
const unsigned int _max_newton_its
Maximum number of iterations for the variable conversion newton solves.
static const std::string pressure
Definition: NS.h:56
virtual Real h_from_p_T(Real p, Real T) const override
Specific enthalpy from pressure and temperature.
const Function * _rho_function
function defining density as a function of temperature and pressure
const Real _p_initial_guess
Initial guess for pressure (or pressure used to compute the initial guess)
IntRange< T > make_range(T beg, T end)
virtual RealGradient gradient(Real t, const Point &p) const
void mooseError(Args &&... args) const
virtual Real cp_from_p_T(Real p, Real T) const override
Isobaric specific heat capacity from pressure and temperature.
void addClassDescription(const std::string &doc_string)
virtual Real p_from_v_e(Real v, Real e) const override
Pressure from specific volume and specific internal energy.
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
virtual Real e_from_p_T(Real p, Real T) const override
Specific internal energy from pressure and temperature.
virtual Real value(Real t, const Point &p) const
virtual Real v_from_p_T(Real p, Real T) const override
Specific volume from pressure and temperature.
T pow(T x, int e)
const bool _cv_is_constant
whether a constant isochoric specific heat is used
const Function * _mu_function
function defining dynamic viscosity as a function of temperature and pressure
const Real _T_initial_guess
Initial guess for temperature (or temperature used to compute the initial guess)
virtual Real cp_from_v_e(Real v, Real e) const override
Isobaric specific heat from specific volume and specific internal energy.
static const std::string k
Definition: NS.h:130
virtual Real cv_from_v_e(Real v, Real e) const override
Isochoric specific heat from specific volume and specific internal energy.