https://mooseframework.inl.gov
Loading...
Searching...
No Matches
TabulatedPVTFluidProperties.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
12#include "Conversion.h"
13
15
18{
21 "density_sc",
22 "density_sc>0",
23 "Density of the fluid at standard (surface) conditions (kg/m^3)");
24 params.addRequiredParam<std::vector<Real>>(
25 "pressure", "Tabulated pressures (Pa). Must be strictly increasing");
26 params.addRequiredParam<std::vector<Real>>(
27 "formation_volume_factor",
28 "Formation volume factor B (reservoir volume / standard volume) at each tabulated pressure");
29 params.addRequiredParam<std::vector<Real>>("viscosity",
30 "Dynamic viscosity (Pa.s) at each tabulated pressure");
31 params.addRangeCheckedParam<Real>(
32 "cv", 2000.0, "cv>0", "Constant specific heat capacity at constant volume (J/kg/K)");
33 params.addRangeCheckedParam<Real>(
34 "molar_mass", "molar_mass>0", "Molar mass of the fluid (kg/mol). Only needed if requested");
35 // Same options and wording as TabulatedFluidProperties
36 MooseEnum OOBBehavior("ignore throw declare_invalid warn_invalid set_to_closest_bound", "throw");
37 params.addParam<MooseEnum>(
38 "out_of_bounds_behavior",
40 "Property evaluation behavior when evaluated outside the tabulated pressure range. "
41 "'ignore': 1/B and 1/(B mu) are extrapolated linearly from the end intervals of the table; "
42 "'throw': an exception is thrown, so the time step is cut; 'set_to_closest_bound': the "
43 "pressure is moved to the closest bound of the table; 'declare_invalid' and 'warn_invalid': "
44 "as 'set_to_closest_bound', but the solution is also marked as invalid or a warning is "
45 "recorded. Results computed outside the table should be used with care");
47 "Isothermal fluid properties from a table of pressure, formation volume factor and "
48 "viscosity (PVDO/PVDG style). 1/B and 1/(B mu) are interpolated linearly in pressure.");
49 return params;
50}
51
53 : SinglePhaseFluidProperties(parameters),
54 _density_sc(getParam<Real>("density_sc")),
55 _p(getParam<std::vector<Real>>("pressure")),
56 _cv(getParam<Real>("cv")),
57 _OOBBehavior(getParam<MooseEnum>("out_of_bounds_behavior").getEnum<OOBBehavior>())
58{
59 const auto & B = getParam<std::vector<Real>>("formation_volume_factor");
60 const auto & mu = getParam<std::vector<Real>>("viscosity");
61
62 if (_p.size() < 2)
63 paramError("pressure", "At least two tabulated pressures are required");
64 if (B.size() != _p.size())
65 paramError("formation_volume_factor", "Must have the same number of entries as 'pressure'");
66 if (mu.size() != _p.size())
67 paramError("viscosity", "Must have the same number of entries as 'pressure'");
68
69 for (std::size_t i = 1; i < _p.size(); ++i)
70 if (_p[i] <= _p[i - 1])
71 paramError("pressure", "Tabulated pressures must be strictly increasing");
72
73 std::vector<Real> inv_B(_p.size());
74 std::vector<Real> inv_B_mu(_p.size());
75 for (std::size_t i = 0; i < _p.size(); ++i)
76 {
77 if (B[i] <= 0.0)
78 paramError("formation_volume_factor", "All entries must be positive");
79 if (mu[i] <= 0.0)
80 paramError("viscosity", "All entries must be positive");
81 inv_B[i] = 1.0 / B[i];
82 inv_B_mu[i] = 1.0 / (B[i] * mu[i]);
83 }
84
85 // Extrapolate linearly beyond the table for 'ignore' (and for 'throw', so that the one-sided
86 // derivative is used exactly at the end points). Otherwise, the interpolation returns the end
87 // values with zero derivative outside the table
88 const bool extrapolate =
90 _inv_B_table = LinearInterpolation(_p, inv_B, extrapolate);
91 _inv_B_mu_table = LinearInterpolation(_p, inv_B_mu, extrapolate);
92}
93
94std::string
96{
97 return "tabulated_pvt";
98}
99
100Real
102{
103 if (!isParamValid("molar_mass"))
104 paramError("molar_mass",
105 "molar_mass must be provided because it is required by another object");
106 return getParam<Real>("molar_mass");
107}
108
109void
111 const LinearInterpolation & table,
112 Real & value,
113 Real & dvalue_dp) const
114{
115 if (p < _p.front() || p > _p.back())
116 switch (_OOBBehavior)
117 {
120 break;
121
123 throw MooseException(
124 "Pressure " + Moose::stringify(p) + " is outside the range of tabulated pressure (" +
125 Moose::stringify(_p.front()) + ", " + Moose::stringify(_p.back()) + ").");
126
127 // The messages must differ: the solution invalidity registry identifies an entry by its
128 // object type and message, and requires each entry to be either an error or a warning
130 flagInvalidSolution("Pressure outside the tabulated range: set to the closest bound");
131 break;
132
134 flagSolutionWarning("Pressure outside the tabulated range: set to the closest bound "
135 "(warning only)");
136 break;
137 }
138
139 value = table.sample(p);
140 dvalue_dp = table.sampleDerivative(p);
141}
142
143Real
145{
146 Real rho, drho_dp, drho_dT;
147 rho_from_p_T(p, T, rho, drho_dp, drho_dT);
148 return rho;
149}
150
151void
153 Real p, Real /*T*/, Real & rho, Real & drho_dp, Real & drho_dT) const
154{
155 Real inv_B, dinv_B_dp;
156 interpolate(p, _inv_B_table, inv_B, dinv_B_dp);
157
158 if (inv_B <= 0.0)
159 throw MooseException(name(),
160 ": the formation volume factor is non-positive at pressure ",
161 p,
162 ", which is outside the tabulated range. Extend the table.");
163
164 rho = _density_sc * inv_B;
165 drho_dp = _density_sc * dinv_B_dp;
166 drho_dT = 0.0;
167}
168
169Real
171{
172 Real mu, dmu_dp, dmu_dT;
173 mu_from_p_T(p, T, mu, dmu_dp, dmu_dT);
174 return mu;
175}
176
177void
179 Real p, Real /*T*/, Real & mu, Real & dmu_dp, Real & dmu_dT) const
180{
181 Real inv_B, dinv_B_dp, inv_B_mu, dinv_B_mu_dp;
182 interpolate(p, _inv_B_table, inv_B, dinv_B_dp);
183 interpolate(p, _inv_B_mu_table, inv_B_mu, dinv_B_mu_dp);
184
185 if (inv_B <= 0.0 || inv_B_mu <= 0.0)
186 throw MooseException(name(),
187 ": the viscosity is non-positive at pressure ",
188 p,
189 ", which is outside the tabulated range. Extend the table.");
190
191 // mu = (1/B) / (1/(B mu))
192 mu = inv_B / inv_B_mu;
193 dmu_dp = (dinv_B_dp * inv_B_mu - inv_B * dinv_B_mu_dp) / (inv_B_mu * inv_B_mu);
194 dmu_dT = 0.0;
195}
196
197Real
199{
200 return _cv * T;
201}
202
203void
204TabulatedPVTFluidProperties::e_from_p_T(Real p, Real T, Real & e, Real & de_dp, Real & de_dT) const
205{
206 e = e_from_p_T(p, T);
207 de_dp = 0.0;
208 de_dT = _cv;
209}
210
211Real
213{
214 Real h, dh_dp, dh_dT;
215 h_from_p_T(p, T, h, dh_dp, dh_dT);
216 return h;
217}
218
219void
220TabulatedPVTFluidProperties::h_from_p_T(Real p, Real T, Real & h, Real & dh_dp, Real & dh_dT) const
221{
222 Real rho, drho_dp, drho_dT;
223 rho_from_p_T(p, T, rho, drho_dp, drho_dT);
224
225 // h = e + p / rho
226 h = e_from_p_T(p, T) + p / rho;
227 dh_dp = 1.0 / rho - p * drho_dp / (rho * rho);
228 dh_dT = _cv;
229}
const double mu
const Real p
const double rho
const double T
registerMooseObject("PorousFlowApp", TabulatedPVTFluidProperties)
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
T sampleDerivative(const T &x) const
T sample(const T &x) const
const std::string & name() const
void paramError(const std::string &param, Args... args) const
bool isParamValid(const std::string &name) const
Common class for single phase fluid properties.
static InputParameters validParams()
e e e e s T T T T T rho v v T e h
Fluid properties from a table of pressure, formation volume factor and viscosity (PVDO/PVDG style)
OOBBehavior
Property evaluation behavior outside the tabulated pressure range (as in TabulatedFluidProperties).
virtual std::string fluidName() const override
Fluid name.
LinearInterpolation _inv_B_mu_table
Interpolation of the reciprocal of the product of formation volume factor and viscosity,...
TabulatedPVTFluidProperties(const InputParameters &parameters)
virtual Real e_from_p_T(Real p, Real T) const override
const Real _density_sc
Density at standard (surface) conditions (kg/m^3)
virtual Real rho_from_p_T(Real p, Real T) const override
virtual Real molarMass() const override
Molar mass [kg/mol].
LinearInterpolation _inv_B_table
Interpolation of the reciprocal of the formation volume factor, 1/B, in pressure.
const Real _cv
Constant specific heat capacity at constant volume (J/kg/K)
virtual Real h_from_p_T(Real p, Real T) const override
const std::vector< Real > _p
Tabulated pressures (Pa), strictly increasing.
void interpolate(Real p, const LinearInterpolation &table, Real &value, Real &dvalue_dp) const
Interpolate a tabulated quantity in pressure, applying the out-of-bounds behavior.
virtual Real mu_from_p_T(Real p, Real T) const override
std::string stringify(const T &t)