https://mooseframework.inl.gov
Loading...
Searching...
No Matches
TabulatedPVTFluidPropertiesTest.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
12#include "MooseException.h"
13#include "MooseUnitUtils.h"
14
18TEST_F(TabulatedPVTFluidPropertiesTest, fluidName) { EXPECT_EQ(_fp->fluidName(), "tabulated_pvt"); }
19
21{
22 ABS_TEST(_fp->molarMass(), _molar_mass, REL_TOL_SAVED_VALUE);
23}
24
29{
30 const Real T = 350.0;
31 for (std::size_t i = 0; i < _p.size(); ++i)
32 {
33 REL_TEST(_fp->rho_from_p_T(_p[i], T), _rho_sc / _B[i], REL_TOL_CONSISTENCY);
34 REL_TEST(_fp->mu_from_p_T(_p[i], T), _mu[i], REL_TOL_CONSISTENCY);
35 REL_TEST(_fp_bounds->rho_from_p_T(_p[i], T), _rho_sc / _B[i], REL_TOL_CONSISTENCY);
36 REL_TEST(_fp_bounds->mu_from_p_T(_p[i], T), _mu[i], REL_TOL_CONSISTENCY);
37 REL_TEST(_fp_throw->rho_from_p_T(_p[i], T), _rho_sc / _B[i], REL_TOL_CONSISTENCY);
38 REL_TEST(_fp_throw->mu_from_p_T(_p[i], T), _mu[i], REL_TOL_CONSISTENCY);
39 }
40}
41
46{
47 const Real T = 350.0;
48 const Real p = 1.5e7; // midpoint of the second interval
49
50 const Real inv_B = 0.5 * (1.0 / _B[1] + 1.0 / _B[2]);
51 const Real inv_B_mu = 0.5 * (1.0 / (_B[1] * _mu[1]) + 1.0 / (_B[2] * _mu[2]));
52 const Real rho = _rho_sc * inv_B;
53 const Real mu = inv_B / inv_B_mu;
54
55 REL_TEST(_fp->rho_from_p_T(p, T), rho, REL_TOL_CONSISTENCY);
56 REL_TEST(_fp->mu_from_p_T(p, T), mu, REL_TOL_CONSISTENCY);
57 REL_TEST(_fp->e_from_p_T(p, T), _cv * T, REL_TOL_CONSISTENCY);
58 REL_TEST(_fp->h_from_p_T(p, T), _cv * T + p / rho, REL_TOL_CONSISTENCY);
59
60 // Saved values, also used in the regression test fluids/tabulated_pvt.i
61 REL_TEST(_fp->rho_from_p_T(p, T), 814.20313790256, REL_TOL_SAVED_VALUE);
62 REL_TEST(_fp->mu_from_p_T(p, T), 1.1341216986149e-3, REL_TOL_SAVED_VALUE);
63
64 // rho_mu_from_p_T (used by PorousFlow) must be consistent with the individual methods
65 Real rho2, mu2;
66 _fp->rho_mu_from_p_T(p, T, rho2, mu2);
67 REL_TEST(rho2, rho, REL_TOL_CONSISTENCY);
68 REL_TEST(mu2, mu, REL_TOL_CONSISTENCY);
69}
70
76{
77 const Real T = 350.0;
78
79 // Above the table: half an interval beyond the last tabulated pressure
80 {
81 const Real p = 3.5e7;
82 const Real inv_B = 1.0 / _B[3] + 0.5 * (1.0 / _B[3] - 1.0 / _B[2]);
83 const Real inv_B_mu =
84 1.0 / (_B[3] * _mu[3]) + 0.5 * (1.0 / (_B[3] * _mu[3]) - 1.0 / (_B[2] * _mu[2]));
85 REL_TEST(_fp->rho_from_p_T(p, T), _rho_sc * inv_B, REL_TOL_CONSISTENCY);
86 REL_TEST(_fp->mu_from_p_T(p, T), inv_B / inv_B_mu, REL_TOL_CONSISTENCY);
87 }
88
89 // Below the table: an eighth of the first interval below the first tabulated pressure
90 {
91 const Real p = 1.0e6;
92 const Real inv_B = 1.0 / _B[0] - 0.125 * (1.0 / _B[1] - 1.0 / _B[0]);
93 const Real inv_B_mu =
94 1.0 / (_B[0] * _mu[0]) - 0.125 * (1.0 / (_B[1] * _mu[1]) - 1.0 / (_B[0] * _mu[0]));
95 REL_TEST(_fp->rho_from_p_T(p, T), _rho_sc * inv_B, REL_TOL_CONSISTENCY);
96 REL_TEST(_fp->mu_from_p_T(p, T), inv_B / inv_B_mu, REL_TOL_CONSISTENCY);
97 }
98}
99
104{
105 const Real T = 350.0;
106 Real rho, drho_dp, drho_dT, mu, dmu_dp, dmu_dT;
107
108 _fp_bounds->rho_from_p_T(3.5e7, T, rho, drho_dp, drho_dT);
109 _fp_bounds->mu_from_p_T(3.5e7, T, mu, dmu_dp, dmu_dT);
110 REL_TEST(rho, _rho_sc / _B[3], REL_TOL_CONSISTENCY);
111 REL_TEST(mu, _mu[3], REL_TOL_CONSISTENCY);
112 ABS_TEST(drho_dp, 0.0, REL_TOL_CONSISTENCY);
113 ABS_TEST(dmu_dp, 0.0, REL_TOL_CONSISTENCY);
114
115 _fp_bounds->rho_from_p_T(1.0e6, T, rho, drho_dp, drho_dT);
116 _fp_bounds->mu_from_p_T(1.0e6, T, mu, dmu_dp, dmu_dT);
117 REL_TEST(rho, _rho_sc / _B[0], REL_TOL_CONSISTENCY);
118 REL_TEST(mu, _mu[0], REL_TOL_CONSISTENCY);
119 ABS_TEST(drho_dp, 0.0, REL_TOL_CONSISTENCY);
120 ABS_TEST(dmu_dp, 0.0, REL_TOL_CONSISTENCY);
121}
122
129{
130 const Real T = 350.0;
131 const Real tol = REL_TOL_DERIVATIVE;
132
133 for (const Real p : {1.0e6, 5.0e6, 1.5e7, 2.5e7, 3.5e7})
134 {
135 DERIV_TEST(_fp->rho_from_p_T, p, T, tol);
136 DERIV_TEST(_fp->mu_from_p_T, p, T, tol);
137 DERIV_TEST(_fp->e_from_p_T, p, T, tol);
138 DERIV_TEST(_fp->h_from_p_T, p, T, tol);
139
140 DERIV_TEST(_fp_bounds->rho_from_p_T, p, T, tol);
141 DERIV_TEST(_fp_bounds->mu_from_p_T, p, T, tol);
142 DERIV_TEST(_fp_bounds->h_from_p_T, p, T, tol);
143 }
144
145 // Inside the table, the default (throw) object behaves like the others
146 for (const Real p : {5.0e6, 1.5e7, 2.5e7})
147 {
148 DERIV_TEST(_fp_throw->rho_from_p_T, p, T, tol);
149 DERIV_TEST(_fp_throw->mu_from_p_T, p, T, tol);
150 DERIV_TEST(_fp_throw->h_from_p_T, p, T, tol);
151 }
152}
153
158{
159 const Real p = 1.5e7;
160 const Real T = 350.0;
161
162 ADReal ad_p = p;
163 Moose::derivInsert(ad_p.derivatives(), 0, 1.0);
164 ADReal ad_T = T;
165 Moose::derivInsert(ad_T.derivatives(), 1, 1.0);
166
167 Real rho, drho_dp, drho_dT, mu, dmu_dp, dmu_dT;
168 _fp->rho_from_p_T(p, T, rho, drho_dp, drho_dT);
169 _fp->mu_from_p_T(p, T, mu, dmu_dp, dmu_dT);
170
171 const ADReal ad_rho = _fp->rho_from_p_T(ad_p, ad_T);
172 const ADReal ad_mu = _fp->mu_from_p_T(ad_p, ad_T);
173
174 REL_TEST(ad_rho.value(), rho, REL_TOL_CONSISTENCY);
175 REL_TEST(ad_rho.derivatives()[0], drho_dp, REL_TOL_CONSISTENCY);
176 ABS_TEST(ad_rho.derivatives()[1], drho_dT, REL_TOL_CONSISTENCY);
177 REL_TEST(ad_mu.value(), mu, REL_TOL_CONSISTENCY);
178 REL_TEST(ad_mu.derivatives()[0], dmu_dp, REL_TOL_CONSISTENCY);
179 ABS_TEST(ad_mu.derivatives()[1], dmu_dT, REL_TOL_CONSISTENCY);
180}
181
187{
188 const Real T = 350.0;
189
190 EXPECT_THROW(_fp_throw->rho_from_p_T(3.5e7, T), MooseException);
191 EXPECT_THROW(_fp_throw->mu_from_p_T(3.5e7, T), MooseException);
192 EXPECT_THROW(_fp_throw->h_from_p_T(3.5e7, T), MooseException);
193 EXPECT_THROW(_fp_throw->rho_from_p_T(1.0e6, T), MooseException);
194 EXPECT_THROW(_fp_throw->mu_from_p_T(1.0e6, T), MooseException);
195
196 EXPECT_NO_THROW(_fp_throw->rho_from_p_T(_p.front(), T));
197 EXPECT_NO_THROW(_fp_throw->rho_from_p_T(_p.back(), T));
198
199 try
200 {
201 _fp_throw->rho_from_p_T(3.5e7, T);
202 FAIL() << "missing expected exception";
203 }
204 catch (const MooseException & err)
205 {
206 EXPECT_NE(std::string(err.what()).find("is outside the range of tabulated pressure"),
207 std::string::npos)
208 << err.what();
209 }
210}
211
217{
218 const Real T = 350.0;
219
220 for (const auto * fp : {_fp_declare_invalid, _fp_warn_invalid})
221 {
222 Real rho, drho_dp, drho_dT, mu, dmu_dp, dmu_dT;
223
224 fp->rho_from_p_T(3.5e7, T, rho, drho_dp, drho_dT);
225 fp->mu_from_p_T(3.5e7, T, mu, dmu_dp, dmu_dT);
226 REL_TEST(rho, _rho_sc / _B[3], REL_TOL_CONSISTENCY);
227 REL_TEST(mu, _mu[3], REL_TOL_CONSISTENCY);
228 ABS_TEST(drho_dp, 0.0, REL_TOL_CONSISTENCY);
229 ABS_TEST(dmu_dp, 0.0, REL_TOL_CONSISTENCY);
230
231 fp->rho_from_p_T(1.0e6, T, rho, drho_dp, drho_dT);
232 fp->mu_from_p_T(1.0e6, T, mu, dmu_dp, dmu_dT);
233 REL_TEST(rho, _rho_sc / _B[0], REL_TOL_CONSISTENCY);
234 REL_TEST(mu, _mu[0], REL_TOL_CONSISTENCY);
235 }
236}
237
243{
244 // 1/B reaches zero at about -7E8 Pa for this table
245 EXPECT_THROW(_fp->rho_from_p_T(-1.0e9, 350.0), MooseException);
246 EXPECT_THROW(_fp->mu_from_p_T(-1.0e9, 350.0), MooseException);
247}
248
256{
257 InputParameters params = validFPParams();
258 params.set<std::vector<Real>>("pressure") = {2.0e6, 1.0e7, 1.0e7, 3.0e7};
259 EXPECT_MOOSEERROR_MSG_CONTAINS(
260 _fe_problem->addUserObject("TabulatedPVTFluidProperties", "invalid_fp", params),
261 "Tabulated pressures must be strictly increasing");
262}
263
265{
266 InputParameters params = validFPParams();
267 params.set<std::vector<Real>>("pressure") = {2.0e6};
268 params.set<std::vector<Real>>("formation_volume_factor") = {1.062};
269 params.set<std::vector<Real>>("viscosity") = {1.04e-3};
270 EXPECT_MOOSEERROR_MSG_CONTAINS(
271 _fe_problem->addUserObject("TabulatedPVTFluidProperties", "invalid_fp", params),
272 "At least two tabulated pressures are required");
273}
274
275TEST_F(TabulatedPVTFluidPropertiesTest, wrongSizeFormationVolumeFactor)
276{
277 InputParameters params = validFPParams();
278 params.set<std::vector<Real>>("formation_volume_factor") = {1.062, 1.050, 1.038};
279 EXPECT_MOOSEERROR_MSG_CONTAINS(
280 _fe_problem->addUserObject("TabulatedPVTFluidProperties", "invalid_fp", params),
281 "Must have the same number of entries as 'pressure'");
282}
283
285{
286 InputParameters params = validFPParams();
287 params.set<std::vector<Real>>("viscosity") = {1.04e-3, 1.10e-3};
288 EXPECT_MOOSEERROR_MSG_CONTAINS(
289 _fe_problem->addUserObject("TabulatedPVTFluidProperties", "invalid_fp", params),
290 "Must have the same number of entries as 'pressure'");
291}
292
293TEST_F(TabulatedPVTFluidPropertiesTest, nonPositiveFormationVolumeFactor)
294{
295 InputParameters params = validFPParams();
296 params.set<std::vector<Real>>("formation_volume_factor") = {1.062, 0.0, 1.038, 1.028};
297 EXPECT_MOOSEERROR_MSG_CONTAINS(
298 _fe_problem->addUserObject("TabulatedPVTFluidProperties", "invalid_fp", params),
299 "All entries must be positive");
300}
301
303{
304 InputParameters params = validFPParams();
305 params.set<std::vector<Real>>("viscosity") = {1.04e-3, -1.10e-3, 1.17e-3, 1.24e-3};
306 EXPECT_MOOSEERROR_MSG_CONTAINS(
307 _fe_problem->addUserObject("TabulatedPVTFluidProperties", "invalid_fp", params),
308 "All entries must be positive");
309}
DualNumber< Real, DNDerivativeType, true > ADReal
const double tol
const double mu
const Real p
const double rho
const double T
TEST_F(TabulatedPVTFluidPropertiesTest, fluidName)
Test that the fluid name and molar mass are correctly returned.
T & set(const std::string &name, bool quiet_mode=false)
void derivInsert(SemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< N > > &derivs, libMesh::dof_id_type index, Real value)