www.mooseframework.org
RichardsDensityVDW.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "RichardsDensityVDW.h"
11 #include "libmesh/utility.h"
12 
14 
17 {
20  "a",
21  "a > 0",
22  "Parameter 'a' in the van der Waals expression (P + n^2 a/V^2)(V - nb) = nRT. "
23  "Example for methane 0.2303 Pa m^6 mol^-2");
25  "b",
26  "b > 0",
27  "Parameter 'b' in the van der Waals expression (P + n^2 a/V^2)(V - nb) = nRT. "
28  "Example for methane 4.31E-5 m^3/mol");
30  "temperature", "temperature > 0", "Temperature in Kelvin");
32  "molar_mass",
33  "molar_mass > 0",
34  "Molar mass of the gas. Example for methane 16.04246E-3 kg/mol");
35  params.addRangeCheckedParam<Real>("infinity_ratio",
36  10,
37  "infinity_ratio > 0",
38  "For P<0 the density is not physically defined, "
39  "but numerically it is advantageous to define "
40  "it: density(P=-infinity) = "
41  "-infinity_ratio*molar_mass, and density tends "
42  "exponentially towards this value as P -> "
43  "-infinity. (Units are mol/m^3).");
44  params.addClassDescription("Density of van der Waals gas.");
45  return params;
46 }
47 
49  : RichardsDensity(parameters),
50  _a(getParam<Real>("a")),
51  _b(getParam<Real>("b")),
52  _rt(getParam<Real>("temperature") * 8.314472), // multiply by gas constant
53  _molar_mass(getParam<Real>("molar_mass")),
54  _infinity_ratio(getParam<Real>("infinity_ratio")),
55  _rhs(_rt * _b / _a),
56  _b2oa(_b * _b / _a)
57 {
58  _vdw0 = densityVDW(0);
60 }
61 
62 Real
64 {
65  // transform (P + a/V^2)(V-b) = RT to
66  // (y + x^2)(1/x - 1) = rhs
67  // with: y = b^2*P/a, x = b/V, rhs = RT*b/a
68  // Then solve for x, using mathematica
69  // Then density = molar_mass/V = molar_mass*x/b
70  Real y = _b2oa * p;
71  Real sq = std::sqrt(4.0 * Utility::pow<3>(-1.0 + 3.0 * y + 3.0 * _rhs) +
72  Utility::pow<2>(-2.0 - 18.0 * y + 9.0 * _rhs));
73  Real cr = std::cbrt(-2.0 + 9.0 * _rhs - 18.0 * y + sq);
74  Real x = 1.0 / 3.0;
75  x += std::cbrt(2.0) * (-1.0 + 3.0 * _rhs + 3.0 * y) / (3.0 * cr);
76  x -= cr / (3.0 * std::cbrt(2.0));
77  return _molar_mass * x / _b;
78 }
79 
80 Real
82 {
83  if (p >= 0)
84  return densityVDW(p) - _vdw0;
85  else
86  return _infinity_ratio * _molar_mass * (std::exp(_slope0 * p) - 1.0);
87 }
88 
89 Real
91 {
92  if (p >= 0)
93  {
94  Real y = _b2oa * p;
95  Real dy = _b2oa;
96  Real sq = std::sqrt(4.0 * Utility::pow<3>(-1.0 + 3.0 * y + 3.0 * _rhs) +
97  Utility::pow<2>(-2.0 - 18.0 * y + 9.0 * _rhs));
98  Real dsq = 0.5 / sq *
99  (4.0 * 3.0 * Utility::pow<2>(-1.0 + 3.0 * y + 3.0 * _rhs) * 3.0 * dy +
100  2.0 * (-2.0 - 18.0 * y + 9.0 * _rhs) * (-18.0 * dy));
101  Real cr = std::cbrt(-2.0 + 9.0 * _rhs - 18.0 * y + sq);
102  Real dcr =
103  1.0 / 3.0 * std::pow(-2.0 + 9.0 * _rhs - 18.0 * y + sq, -2.0 / 3.0) * (-18.0 * dy + dsq);
104  Real dx = std::cbrt(2.0) *
105  ((3.0 * dy) / (3.0 * cr) + (-1.0 + 3.0 * _rhs + 3.0 * y) / 3.0 * (-dcr / (cr * cr)));
106  dx -= dcr / (3.0 * std::cbrt(2.0));
107  return _molar_mass * dx / _b;
108  }
109  else
110  return _infinity_ratio * _molar_mass * _slope0 * std::exp(_slope0 * p);
111 }
112 
113 Real
115 {
116  if (p >= 0)
117  {
118  Real y = _b2oa * p;
119  Real dy = _b2oa;
120  Real sq = std::sqrt(4.0 * Utility::pow<3>(-1.0 + 3.0 * y + 3.0 * _rhs) +
121  Utility::pow<2>(-2.0 - 18.0 * y + 9.0 * _rhs));
122  Real dsq = 0.5 / sq *
123  (4.0 * 3.0 * Utility::pow<2>(-1.0 + 3.0 * y + 3.0 * _rhs) * 3.0 * dy +
124  2.0 * (-2.0 - 18.0 * y + 9.0 * _rhs) * (-18.0 * dy));
125  Real d2sq = -dsq * dsq / sq;
126  d2sq += 0.5 / sq *
127  (4.0 * 3.0 * 2.0 * (-1.0 + 3.0 * y + 3.0 * _rhs) * 3.0 * dy * 3.0 * dy +
128  2.0 * (-18.0 * dy) * (-18.0 * dy));
129  Real cr = std::cbrt(-2.0 + 9.0 * _rhs - 18.0 * y + sq);
130  Real dcr =
131  1.0 / 3.0 * std::pow(-2.0 + 9.0 * _rhs - 18.0 * y + sq, -2.0 / 3.0) * (-18.0 * dy + dsq);
132  Real d2cr = 1.0 / 3.0 * (-2.0 / 3.0) * std::pow(-2 + 9 * _rhs - 18 * y + sq, -5. / 3.) *
133  Utility::pow<2>(-18 * dy + dsq);
134  d2cr += 1.0 / 3.0 * std::pow(-2 + 9 * _rhs - 18 * y + sq, -2. / 3.) * d2sq;
135  // Real dx = std::pow(2, 1.0/3.0)*( (3*dy)/3/cr + (-1 + 3*_rhs + 3*y)/3*(-dcr/cr/cr));
136  // dx -= dcr/3/std::pow(2, 1.0/3.0);
137  Real d2x = std::cbrt(2.0) *
138  (-(3.0 * dy) * dcr / (3.0 * cr * cr) + 3.0 * dy / 3.0 * (-dcr / (cr * cr)) +
139  (-1.0 + 3.0 * _rhs + 3.0 * y) / 3.0 *
140  (-d2cr / (cr * cr) + 2.0 * dcr * dcr / Utility::pow<3>(cr)));
141  d2x -= d2cr / (3.0 * std::cbrt(2.0));
142  return _molar_mass * d2x / _b;
143  }
144  else
145  return _infinity_ratio * _molar_mass * Utility::pow<2>(_slope0) * std::exp(_slope0 * p);
146 }
Real density(Real p) const
fluid density as a function of porepressure
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
RichardsDensityVDW(const InputParameters &parameters)
Real densityVDW(Real p) const
Density according to the van der Waals expression This is modified to yield density(p) as noted above...
Real _infinity_ratio
density at P=-infinity is _infinity_ratio*_molar_mass
static InputParameters validParams()
Real _b
van der Waals b
const std::vector< double > y
ADRealEigenVector< T, D, asd > sqrt(const ADRealEigenVector< T, D, asd > &)
static InputParameters validParams()
const std::vector< double > x
registerMooseObject("RichardsApp", RichardsDensityVDW)
Real _slope0
(1/_molar_mass)*d(density)/dP at P=0
Real _vdw0
density at P=0 according to the van der Waals expression
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Density of a gas according to the van der Waals expression (P + n^2 a/V^2)(V - nb) = nRT How density ...
Real d2density(Real p) const
second derivative of fluid density wrt porepressure
void addClassDescription(const std::string &doc_string)
Base class for fluid density as a function of porepressure The functions density, ddensity and d2dens...
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
Real _molar_mass
molar mass of gas
MooseUnits pow(const MooseUnits &, int)
Real ddensity(Real p) const
derivative of fluid density wrt porepressure