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