https://mooseframework.inl.gov
Loading...
Searching...
No Matches
TabulatedBicubicFluidPropertiesTest.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
14
15#include <fstream>
16
17// Test data for unordered data
19{
20 try
21 {
22 // Must cast away const to call initialSetup(), where the file is
23 // checked for consistency
24 const_cast<TabulatedBicubicFluidProperties *>(_unordered_fp)->initialSetup();
25 FAIL();
26 }
27 catch (const std::exception & err)
28 {
29 std::size_t pos = std::string(err.what())
30 .find("The column data for temperature is not monotonically increasing");
31 ASSERT_TRUE(pos != std::string::npos);
32 }
33}
34
35// Test data for different temperatures ranges in pressure data
37{
38 try
39 {
40 const_cast<TabulatedBicubicFluidProperties *>(_unequal_fp)->initialSetup();
41 FAIL();
42 }
43 catch (const std::exception & err)
44 {
45 std::size_t pos = std::string(err.what())
46 .find("temperature values for pressure 2e+06 are not "
47 "identical to values for 1e+06");
48 ASSERT_TRUE(pos != std::string::npos);
49 }
50}
51
52// Test data for missing column
54{
55 try
56 {
57 const auto tow = Moose::_throw_on_warning;
59 const_cast<TabulatedBicubicFluidProperties *>(_missing_col_fp)->initialSetup();
61 FAIL();
62 }
63 catch (const std::exception & err)
64 {
65 std::size_t pos = std::string(err.what())
66 .find("data/csv/missing_col_fluid_props.csv. A "
67 "column named temperature must be present");
68 ASSERT_TRUE(pos != std::string::npos);
69 }
70}
71
72// Test data for unknown property column
74{
75 try
76 {
77 const_cast<TabulatedBicubicFluidProperties *>(_unknown_col_fp)->initialSetup();
78 FAIL();
79 }
80 catch (const std::exception & err)
81 {
82 std::size_t pos = std::string(err.what())
83 .find("data/csv/unknown_fluid_props.csv tabulation file is not one of "
84 "the properties that TabulatedFluidProperties understands");
85 ASSERT_TRUE(pos != std::string::npos);
86 }
87}
88
89// Test data for missing data
91{
92 try
93 {
94 const_cast<TabulatedBicubicFluidProperties *>(_missing_data_fp)->initialSetup();
95 FAIL();
96 }
97 catch (const std::exception & err)
98 {
99 std::size_t pos = std::string(err.what())
100 .find("data/csv/missing_data_fluid_props.csv "
101 "is not equal to the number of unique pressure values 3 multiplied "
102 "by the number of unique temperature values 3");
103 ASSERT_TRUE(pos != std::string::npos);
104 }
105}
106
107// Test tabulated fluid properties read from file including comments
109{
110 Real p = 1.5e6;
111 Real T = 450.0;
112
113 // Read the data file
114 const_cast<TabulatedBicubicFluidProperties *>(_tab_pT_from_fp)->initialSetup();
115
116 // Fluid properties
117 REL_TEST(_tab_pT_from_fp->rho_from_p_T(p, T), _co2_fp->rho_from_p_T(p, T), 1.0e-4);
118 REL_TEST(_tab_pT_from_fp->h_from_p_T(p, T), _co2_fp->h_from_p_T(p, T), 1.0e-4);
119 REL_TEST(_tab_pT_from_fp->e_from_p_T(p, T), _co2_fp->e_from_p_T(p, T), 1.0e-4);
120 REL_TEST(_tab_pT_from_fp->mu_from_p_T(p, T), _co2_fp->mu_from_p_T(p, T), 1.0e-4);
121 REL_TEST(_tab_pT_from_fp->k_from_p_T(p, T), _co2_fp->k_from_p_T(p, T), 1.0e-4);
122 REL_TEST(_tab_pT_from_fp->cp_from_p_T(p, T), _co2_fp->cp_from_p_T(p, T), 1.0e-4);
123 REL_TEST(_tab_pT_from_fp->cv_from_p_T(p, T), _co2_fp->cv_from_p_T(p, T), 1.0e-4);
124 REL_TEST(_tab_pT_from_fp->s_from_p_T(p, T), _co2_fp->s_from_p_T(p, T), 1.0e-4);
125
126 // Fluid properties and derivatives
127 Real rho, drho_dp, drho_dT, rhoc, drhoc_dp, drhoc_dT;
128 _tab_pT_from_fp->rho_from_p_T(p, T, rho, drho_dp, drho_dT);
129 _co2_fp->rho_from_p_T(p, T, rhoc, drhoc_dp, drhoc_dT);
130 REL_TEST(rho, rhoc, 1.0e-4);
131 REL_TEST(drho_dp, drhoc_dp, 1.0e-3);
132 REL_TEST(drho_dT, drhoc_dT, 1.0e-3);
133
134 Real h, dh_dp, dh_dT, hc, dhc_dp, dhc_dT;
135 _tab_pT_from_fp->h_from_p_T(p, T, h, dh_dp, dh_dT);
136 _co2_fp->h_from_p_T(p, T, hc, dhc_dp, dhc_dT);
137 REL_TEST(h, hc, 1.0e-4);
138 REL_TEST(dh_dp, dhc_dp, 1.0e-3);
139 REL_TEST(dh_dT, dhc_dT, 1.0e-3);
140
141 Real mu, dmu_dp, dmu_dT, muc, dmuc_dp, dmuc_dT;
142 _tab_pT_from_fp->mu_from_p_T(p, T, mu, dmu_dp, dmu_dT);
143 _co2_fp->mu_from_p_T(p, T, muc, dmuc_dp, dmuc_dT);
144 REL_TEST(mu, muc, 1.0e-4);
145 REL_TEST(dmu_dp, dmuc_dp, 1.0e-3);
146 REL_TEST(dmu_dT, dmuc_dT, 1.0e-3);
147
148 Real k, dk_dp, dk_dT, kc, dkc_dp, dkc_dT;
149 _tab_pT_from_fp->k_from_p_T(p, T, k, dk_dp, dk_dT);
150 _co2_fp->k_from_p_T(p, T, kc, dkc_dp, dkc_dT);
151 REL_TEST(k, kc, 1.0e-4);
152 REL_TEST(dk_dp, dkc_dp, 1.0e-3);
153 REL_TEST(dk_dT, dkc_dT, 1.0e-3);
154
155 Real e, de_dp, de_dT, ec, dec_dp, dec_dT;
156 _tab_pT_from_fp->e_from_p_T(p, T, e, de_dp, de_dT);
157 _co2_fp->e_from_p_T(p, T, ec, dec_dp, dec_dT);
158 REL_TEST(e, ec, 1.0e-4);
159 REL_TEST(de_dp, dec_dp, 1.0e-3);
160 REL_TEST(de_dT, dec_dT, 1.0e-3);
161
162 Real s, ds_dp, ds_dT, sc, dsc_dp, dsc_dT;
163 _tab_pT_from_fp->s_from_p_T(p, T, s, ds_dp, ds_dT);
164 _co2_fp->s_from_p_T(p, T, sc, dsc_dp, dsc_dT);
165 REL_TEST(s, sc, 1.0e-4);
166 REL_TEST(ds_dp, dsc_dp, 1.0e-3);
167 REL_TEST(ds_dT, dsc_dT, 1.0e-3);
168}
169
170// Test tabulated fluid properties read from file including comments
172{
173 Real p = 1.5e6;
174 Real T = 450.0;
175 Real pert = 1.0e-7;
176
177 // Read the data file
179 const_cast<TabulatedBicubicFluidProperties *>(_tab_ve_from_pT)->initialSetup();
181
182 // round trip p,T -> v,e -> p,T
183 {
184 Real e = _tab_ve_from_pT->e_from_p_T(p, T);
185 Real v = _tab_ve_from_pT->v_from_p_T(p, T);
186 Real pp = _tab_ve_from_pT->p_from_v_e(v, e);
187 Real TT = _tab_ve_from_pT->T_from_v_e(v, e);
188 ABS_TEST(T, TT, 1.0);
189 REL_TEST(p, pp, 0.001);
190 }
191
192 // check computation of fluid props from p, T & v, e
193 {
194 Real e = _tab_ve_from_pT->e_from_p_T(p, T);
195 Real v = _tab_ve_from_pT->v_from_p_T(p, T);
196
197 // heat capacity at constant pressure
198 Real cp1 = _tab_ve_from_pT->cp_from_p_T(p, T);
199 Real cp2 = _tab_ve_from_pT->cp_from_v_e(v, e);
200 REL_TEST(cp1, cp2, 0.001);
201
202 // heat capacity at constant volume
203 Real cv1 = _tab_ve_from_pT->cv_from_p_T(p, T);
204 Real cv2 = _tab_ve_from_pT->cv_from_v_e(v, e);
205 REL_TEST(cv1, cv2, 0.001);
206
207 // viscosity
208 Real mu1 = _tab_ve_from_pT->mu_from_p_T(p, T);
209 Real mu2 = _tab_ve_from_pT->mu_from_v_e(v, e);
210 REL_TEST(mu1, mu2, 0.001);
211
212 // thermal conductivity
213 Real k1 = _tab_ve_from_pT->k_from_p_T(p, T);
214 Real k2 = _tab_ve_from_pT->k_from_v_e(v, e);
215 REL_TEST(k1, k2, 0.001);
216
217 // enthalpy
218 Real h1 = _tab_ve_from_pT->h_from_p_T(p, T);
219 Real h2 = _tab_ve_from_pT->h_from_v_e(v, e);
220 REL_TEST(h1, h2, 0.001);
221
222 // entropy
223 Real s1 = _tab_ve_from_pT->s_from_p_T(p, T);
224 Real s2 = _tab_ve_from_pT->s_from_v_e(v, e);
225 REL_TEST(s1, s2, 0.001);
226
227 // Gibbs free energy from the (p, T) from (v, e) interpolations
228 REL_TEST(_tab_ve_from_pT->g_from_v_e(v, e), h1 - T * s1, 0.001);
229
230 // entropy derivatives from the (p, T) from (v, e) interpolations: de = T ds - p dv
231 Real s3, ds_dv, ds_de;
232 _tab_ve_from_pT->s_from_v_e(v, e, s3, ds_dv, ds_de);
233 REL_TEST(s3, s2, REL_TOL_CONSISTENCY);
234 REL_TEST(ds_de, 1.0 / T, 0.01);
235 REL_TEST(ds_dv, p / T, 0.01);
236 }
237
238 // check computation of fluid props from p, s
239 {
240 Real s = _tab_ve_from_pT->s_from_p_T(p, T);
241
242 // density
243 Real rho1 = _tab_ve_from_pT->rho_from_p_T(p, T);
244 Real rho2 = _tab_ve_from_pT->rho_from_p_s(p, s);
245 REL_TEST(rho1, rho2, 0.001);
246
247 // temperature
248 Real Ts = _tab_ve_from_pT->T_from_p_s(p, s);
249 REL_TEST(T, Ts, 0.001);
250 }
251
252 // check computation of fluid props from p, rho
253 {
254 Real rho = _tab_ve_from_pT->rho_from_p_T(p, T);
255
256 // specific internal energy
257 Real e1 = _tab_ve_from_pT->e_from_p_T(p, T);
258 Real e2 = _tab_ve_from_pT->e_from_p_rho(p, rho);
259 REL_TEST(e1, e2, REL_TOL_CONSISTENCY);
260 }
261
262 // check computation of fluids props from p, h
263 {
264 Real T = 450;
265 Real p = 1.5e6;
266 Real h = _tab_ve_from_pT->h_from_p_T(p, T);
267 Real Ts = _tab_ve_from_pT->T_from_p_h(p, h);
268 REL_TEST(T, Ts, 1e-4);
269
270 // to keep coverage on the default definition in SinglePhaseFP
271 Ts = dynamic_cast<const SinglePhaseFluidProperties *>(_tab_ve_from_pT)->T_from_p_h(p, h);
272 REL_TEST(T, Ts, 1e-4);
273 }
274
275 // are the two version of functions equivalent
276 {
277 Real e = _tab_ve_from_pT->e_from_p_T(p, T);
278 Real v = _tab_ve_from_pT->v_from_p_T(p, T);
279
280 Real d1, d2;
281
282 // speed of sound errors bc co2 props don't
283 // implement enough
284
285 // heat capacity at constant pressure
286 Real cp1;
287 _tab_ve_from_pT->cp_from_v_e(v, e, cp1, d1, d2);
288 Real cp2 = _tab_ve_from_pT->cp_from_v_e(v, e);
289 REL_TEST(cp1, cp2, 0.001);
290
291 // heat capacity at constant volume
292 Real cv1;
293 _tab_ve_from_pT->cv_from_v_e(v, e, cv1, d1, d2);
294 Real cv2 = _tab_ve_from_pT->cv_from_v_e(v, e);
295 REL_TEST(cv1, cv2, 0.001);
296
297 // viscosity
298 Real mu1;
299 _tab_ve_from_pT->mu_from_v_e(v, e, mu1, d1, d2);
300 Real mu2 = _tab_ve_from_pT->mu_from_v_e(v, e);
301 REL_TEST(mu1, mu2, 0.001);
302
303 // thermal conductivity
304 Real k1;
305 _tab_ve_from_pT->k_from_v_e(v, e, k1, d1, d2);
306 Real k2 = _tab_ve_from_pT->k_from_v_e(v, e);
307 REL_TEST(k1, k2, 0.001);
308 }
309
310 // check derivatives
311 {
312 Real e = _tab_ve_from_pT->e_from_p_T(p, T);
313 Real v = _tab_ve_from_pT->v_from_p_T(p, T);
314
315 Real deriv1, deriv2;
316
317 // pressure
318 Real p1;
319 _tab_ve_from_pT->p_from_v_e(v, e, p1, deriv1, deriv2);
320 Real p2 = _tab_ve_from_pT->p_from_v_e(v, e);
321 REL_TEST(p1, p2, 0.001);
322
323 // temperature
324 Real T1;
325 _tab_ve_from_pT->T_from_v_e(v, e, T1, deriv1, deriv2);
326 Real T2 = _tab_ve_from_pT->T_from_v_e(v, e);
327 REL_TEST(T1, T2, 0.001);
328
329 // speed of sound errors bc co2 props don't
330 // implement enough
331
332 // heat capacity at constant pressure
333 Real cp1;
334 _tab_ve_from_pT->cp_from_v_e(v, e, cp1, deriv1, deriv2);
335 Real cp_0 = _tab_ve_from_pT->cp_from_v_e(v, e);
336 Real cp_1 = _tab_ve_from_pT->cp_from_v_e(v * (1 + pert), e);
337 Real cp_2 = _tab_ve_from_pT->cp_from_v_e(v, e * (1 + pert));
338 REL_TEST(deriv1, (cp_1 - cp_0) / (v * pert), 0.001);
339 REL_TEST(deriv2, (cp_2 - cp_0) / (e * pert), 0.001);
340
341 // heat capacity at constant volume
342 Real cv1;
343 _tab_ve_from_pT->cv_from_v_e(v, e, cv1, deriv1, deriv2);
344 Real cv_0 = _tab_ve_from_pT->cv_from_v_e(v, e);
345 Real cv_1 = _tab_ve_from_pT->cv_from_v_e(v * (1 + pert), e);
346 Real cv_2 = _tab_ve_from_pT->cv_from_v_e(v, e * (1 + pert));
347 REL_TEST(deriv1, (cv_1 - cv_0) / (v * pert), 0.001);
348 REL_TEST(deriv2, (cv_2 - cv_0) / (e * pert), 0.001);
349
350 // viscosity
351 Real mu1;
352 _tab_ve_from_pT->mu_from_v_e(v, e, mu1, deriv1, deriv2);
353 Real mu_0 = _tab_ve_from_pT->mu_from_v_e(v, e);
354 Real mu_1 = _tab_ve_from_pT->mu_from_v_e(v * (1 + pert), e);
355 Real mu_2 = _tab_ve_from_pT->mu_from_v_e(v, e * (1 + pert));
356 REL_TEST(deriv1, (mu_1 - mu_0) / (v * pert), 0.001);
357 REL_TEST(deriv2, (mu_2 - mu_0) / (e * pert), 0.001);
358
359 // thermal conductivity
360 Real k1;
361 _tab_ve_from_pT->k_from_v_e(v, e, k1, deriv1, deriv2);
362 Real k_0 = _tab_ve_from_pT->k_from_v_e(v, e);
363 Real k_1 = _tab_ve_from_pT->k_from_v_e(v * (1 + pert), e);
364 Real k_2 = _tab_ve_from_pT->k_from_v_e(v, e * (1 + pert));
365 REL_TEST(deriv1, (k_1 - k_0) / (v * pert), 0.001);
366 REL_TEST(deriv2, (k_2 - k_0) / (e * pert), 0.001);
367 }
368
369 // test enthalpy relationships
370 {
371 Real h = _tab_ve_from_pT->h_from_p_T(p, T);
372 Real v = _tab_ve_from_pT->v_from_p_T(p, T);
373 Real e_gold = _tab_ve_from_pT->e_from_p_T(p, T);
374 Real e = _tab_ve_from_pT->e_from_v_h(v, h);
375 REL_TEST(e_gold, e, 0.001);
376
377 Real e2, de_dv, de_dh;
378 _tab_ve_from_pT->e_from_v_h(v, h, e2, de_dv, de_dh);
379 REL_TEST(e_gold, e2, 0.001);
380 Real e_0 = _tab_ve_from_pT->e_from_v_h(v, h);
381 Real e_1 = _tab_ve_from_pT->e_from_v_h(v * (1 + pert), h);
382 Real e_2 = _tab_ve_from_pT->e_from_v_h(v, h * (1 + pert));
383 REL_TEST(de_dv, (e_1 - e_0) / (v * pert), 0.001);
384 REL_TEST(de_dh, (e_2 - e_0) / (h * pert), 0.001);
385 }
386
387 // AD p_from_v_e
388 {
389 Real e = _tab_ve_from_pT->e_from_p_T(p, T);
390 Real v = _tab_ve_from_pT->v_from_p_T(p, T);
391 DNDerivativeType dvdx;
392 DNDerivativeType dedx;
393 // set it up so these are the derivatives
394 // w.r.t. to themselves
395 Moose::derivInsert(dvdx, 0, 1);
396 Moose::derivInsert(dvdx, 1, 0);
397 Moose::derivInsert(dedx, 0, 0);
398 Moose::derivInsert(dedx, 1, 1);
399
400 ADReal v_ad(v, dvdx);
401 ADReal e_ad(e, dedx);
402 ADReal p_ad = _tab_ve_from_pT->p_from_v_e(v_ad, e_ad);
403
404 Real pp, dp_dv, dp_de;
405 _tab_ve_from_pT->p_from_v_e(v, e, pp, dp_dv, dp_de);
406 REL_TEST(p_ad.derivatives()[0], dp_dv, 0.0001);
407 REL_TEST(p_ad.derivatives()[1], dp_de, 0.0001);
408
409 ADReal ad_pp, ad_dp_dv, ad_dp_de;
410 _tab_ve_from_pT->p_from_v_e(v_ad, e_ad, ad_pp, ad_dp_dv, ad_dp_de);
411 REL_TEST(p_ad.derivatives()[0], ad_dp_dv.value(), 0.0001);
412 REL_TEST(p_ad.derivatives()[1], ad_dp_de.value(), 0.0001);
413 }
414
415 // AD T_from_v_e
416 {
417 Real e = _tab_ve_from_pT->e_from_p_T(p, T);
418 Real v = _tab_ve_from_pT->v_from_p_T(p, T);
419 DNDerivativeType dvdx;
420 DNDerivativeType dedx;
421 // set it up so these are the derivatives
422 // w.r.t. to themselves
423 Moose::derivInsert(dvdx, 0, 1);
424 Moose::derivInsert(dvdx, 1, 0);
425 Moose::derivInsert(dedx, 0, 0);
426 Moose::derivInsert(dedx, 1, 1);
427
428 ADReal v_ad(v, dvdx);
429 ADReal e_ad(e, dedx);
430 ADReal T_ad = _tab_ve_from_pT->T_from_v_e(v_ad, e_ad);
431
432 Real TT, dT_dv, dT_de;
433 _tab_ve_from_pT->T_from_v_e(v, e, TT, dT_dv, dT_de);
434 REL_TEST(T_ad.derivatives()[0], dT_dv, 0.0001);
435 REL_TEST(T_ad.derivatives()[1], dT_de, 0.0001);
436
437 ADReal ad_TT, ad_dT_dv, ad_dT_de;
438 _tab_ve_from_pT->T_from_v_e(v_ad, e_ad, ad_TT, ad_dT_dv, ad_dT_de);
439 REL_TEST(T_ad.derivatives()[0], ad_dT_dv.value(), 0.0001);
440 REL_TEST(T_ad.derivatives()[1], ad_dT_de.value(), 0.0001);
441 }
442
443 // cannot test AD c_from_v_e because co2 props do not
444 // implement enough
445
446 // AD T_from_p_h
447 {
448 Real h = _tab_ve_from_pT->h_from_p_T(p, T);
449 DNDerivativeType dpdx;
450 DNDerivativeType dhdx;
451 // set it up so these are the derivatives
452 // w.r.t. to themselves
453 Moose::derivInsert(dpdx, 0, 1);
454 Moose::derivInsert(dpdx, 1, 0);
455 Moose::derivInsert(dhdx, 0, 0);
456 Moose::derivInsert(dhdx, 1, 1);
457
458 ADReal p_ad(p, dpdx);
459 ADReal h_ad(h, dhdx);
460 ADReal T_ad = _tab_ve_from_pT->T_from_p_h(p_ad, h_ad);
461
462 Real TT_1 = _tab_ve_from_pT->T_from_p_h(p * (1 + pert), h);
463 Real TT_2 = _tab_ve_from_pT->T_from_p_h(p, h * (1 + pert));
464 Real dT_dp = (TT_1 - T) / p / pert;
465 Real dT_dh = (TT_2 - T) / h / pert;
466 REL_TEST(T_ad.derivatives()[0], dT_dp, 0.0001);
467 REL_TEST(T_ad.derivatives()[1], dT_dh, 0.0001);
468 }
469
470 // AD rho_from_p_T
471 {
472 DNDerivativeType dpdx;
473 DNDerivativeType dTdx;
474 // set it up so these are the derivatives
475 // w.r.t. to themselves
476 Moose::derivInsert(dpdx, 0, 1);
477 Moose::derivInsert(dpdx, 1, 0);
478 Moose::derivInsert(dTdx, 0, 0);
479 Moose::derivInsert(dTdx, 1, 1);
480
481 ADReal p_ad(p, dpdx);
482 ADReal T_ad(T, dTdx);
483 ADReal rho_ad = _tab_ve_from_pT->rho_from_p_T(p_ad, T_ad);
484
485 Real rho, drho_dp, drho_dT;
486 _tab_ve_from_pT->rho_from_p_T(p, T, rho, drho_dp, drho_dT);
487 REL_TEST(rho_ad.derivatives()[0], drho_dp, 0.0001);
488 REL_TEST(rho_ad.derivatives()[1], drho_dT, 0.0001);
489
490 ADReal ad_rho, ad_drho_dp, ad_drho_dT;
491 _tab_ve_from_pT->rho_from_p_T(p_ad, T_ad, ad_rho, ad_drho_dp, ad_drho_dT);
492 REL_TEST(rho_ad.derivatives()[0], ad_drho_dp.value(), 0.0001);
493 REL_TEST(rho_ad.derivatives()[1], ad_drho_dT.value(), 0.0001);
494 }
495
496 // AD e_from_p_T
497 {
498 DNDerivativeType dpdx;
499 DNDerivativeType dTdx;
500 // set it up so these are the derivatives
501 // w.r.t. to themselves
502 Moose::derivInsert(dpdx, 0, 1);
503 Moose::derivInsert(dpdx, 1, 0);
504 Moose::derivInsert(dTdx, 0, 0);
505 Moose::derivInsert(dTdx, 1, 1);
506
507 ADReal p_ad(p, dpdx);
508 ADReal T_ad(T, dTdx);
509 ADReal e_ad = _tab_ve_from_pT->e_from_p_T(p_ad, T_ad);
510
511 Real e, de_dp, de_dT;
512 _tab_ve_from_pT->e_from_p_T(p, T, e, de_dp, de_dT);
513 REL_TEST(e_ad.derivatives()[0], de_dp, 0.0001);
514 REL_TEST(e_ad.derivatives()[1], de_dT, 0.0001);
515 }
516
517 // AD v_from_p_T
518 {
519 DNDerivativeType dpdx;
520 DNDerivativeType dTdx;
521 // set it up so these are the derivatives
522 // w.r.t. to themselves
523 Moose::derivInsert(dpdx, 0, 1);
524 Moose::derivInsert(dpdx, 1, 0);
525 Moose::derivInsert(dTdx, 0, 0);
526 Moose::derivInsert(dTdx, 1, 1);
527
528 ADReal p_ad(p, dpdx);
529 ADReal T_ad(T, dTdx);
530 ADReal v_ad = _tab_ve_from_pT->v_from_p_T(p_ad, T_ad);
531
532 Real v, dv_dp, dv_dT;
533 _tab_ve_from_pT->v_from_p_T(p, T, v, dv_dp, dv_dT);
534 REL_TEST(v_ad.derivatives()[0], dv_dp, 0.0001);
535 REL_TEST(v_ad.derivatives()[1], dv_dT, 0.0001);
536 }
537}
538
539// Test tabulated fluid properties read from file including comments
541{
542 // These values must be within the bounds specified in the header
543 Real p = 1.223e6;
544 Real T = 420.1;
545 Real pert = 1.0e-7;
546
547 // Generate the (v, e) tabulation from the FP user object
548 const_cast<TabulatedBicubicFluidProperties *>(_tab_ve_from_fp)->initialSetup();
549
550 // Use as a reference
551 Real e = _idg_fp->e_from_p_T(p, T);
552 Real v = _idg_fp->v_from_p_T(p, T);
553
554 // check computation of fluid props from v, e
555 {
556 // heat capacity at constant pressure
557 Real cp1 = _idg_fp->cp_from_v_e(v, e);
558 Real cp2 = _tab_ve_from_fp->cp_from_v_e(v, e);
559 REL_TEST(cp1, cp2, 0.001);
560
561 // heat capacity at constant volume
562 Real cv1 = _idg_fp->cv_from_v_e(v, e);
563 Real cv2 = _tab_ve_from_fp->cv_from_v_e(v, e);
564 REL_TEST(cv1, cv2, 0.001);
565
566 // speed of sound
567 Real c1 = _idg_fp->c_from_v_e(v, e);
568 Real c2 = _tab_ve_from_fp->c_from_v_e(v, e);
569 REL_TEST(c1, c2, 0.001);
570
571 // viscosity
572 Real mu1 = _idg_fp->mu_from_v_e(v, e);
573 Real mu2 = _tab_ve_from_fp->mu_from_v_e(v, e);
574 REL_TEST(mu1, mu2, 0.001);
575
576 // thermal conductivity
577 Real k1 = _idg_fp->k_from_v_e(v, e);
578 Real k2 = _tab_ve_from_fp->k_from_v_e(v, e);
579 REL_TEST(k1, k2, 0.001);
580 }
581
582 // are the two version of functions equivalent
583 {
584 Real d1, d2;
585
586 // pressure
587 Real p1;
588 _tab_ve_from_fp->p_from_v_e(v, e, p1, d1, d2);
589 Real p2 = _tab_ve_from_fp->p_from_v_e(v, e);
590 REL_TEST(p1, p2, 0.001);
591
592 // temperature
593 Real T1;
594 _tab_ve_from_fp->T_from_v_e(v, e, T1, d1, d2);
595 Real T2 = _tab_ve_from_fp->T_from_v_e(v, e);
596 REL_TEST(T1, T2, 0.001);
597
598 // heat capacity at constant pressure
599 Real cp1;
600 _tab_ve_from_fp->cp_from_v_e(v, e, cp1, d1, d2);
601 Real cp2 = _tab_ve_from_fp->cp_from_v_e(v, e);
602 REL_TEST(cp1, cp2, 0.001);
603
604 // heat capacity at constant volume
605 Real cv1;
606 _tab_ve_from_fp->cv_from_v_e(v, e, cv1, d1, d2);
607 Real cv2 = _tab_ve_from_fp->cv_from_v_e(v, e);
608 REL_TEST(cv1, cv2, 0.001);
609
610 // speed of sound
611 Real c1;
612 _tab_ve_from_fp->c_from_v_e(v, e, c1, d1, d2);
613 Real c2 = _tab_ve_from_fp->c_from_v_e(v, e);
614 REL_TEST(c1, c2, 0.001);
615
616 // viscosity
617 Real mu1;
618 _tab_ve_from_fp->mu_from_v_e(v, e, mu1, d1, d2);
619 Real mu2 = _tab_ve_from_fp->mu_from_v_e(v, e);
620 REL_TEST(mu1, mu2, 0.001);
621
622 // thermal conductivity
623 Real k1;
624 _tab_ve_from_fp->k_from_v_e(v, e, k1, d1, d2);
625 Real k2 = _tab_ve_from_fp->k_from_v_e(v, e);
626 REL_TEST(k1, k2, 0.001);
627 }
628
629 // check derivatives
630 {
631 Real deriv1, deriv2;
632
633 // speed of sound errors bc co2 props don't
634 // implement enough
635
636 // heat capacity at constant pressure
637 Real cp1;
638 _tab_ve_from_fp->cp_from_v_e(v, e, cp1, deriv1, deriv2);
639 Real cp_0 = _tab_ve_from_fp->cp_from_v_e(v, e);
640 Real cp_1 = _tab_ve_from_fp->cp_from_v_e(v * (1 + pert), e);
641 Real cp_2 = _tab_ve_from_fp->cp_from_v_e(v, e * (1 + pert));
642 REL_TEST(cp1, cp_0, 0.001);
643 REL_TEST(deriv1, (cp_1 - cp_0) / (v * pert), 0.001);
644 REL_TEST(deriv2, (cp_2 - cp_0) / (e * pert), 0.001);
645
646 // heat capacity at constant volume
647 Real cv1;
648 _tab_ve_from_fp->cv_from_v_e(v, e, cv1, deriv1, deriv2);
649 Real cv_0 = _tab_ve_from_fp->cv_from_v_e(v, e);
650 Real cv_1 = _tab_ve_from_fp->cv_from_v_e(v * (1 + pert), e);
651 Real cv_2 = _tab_ve_from_fp->cv_from_v_e(v, e * (1 + pert));
652 REL_TEST(cv1, cv_0, 0.001);
653 REL_TEST(deriv1, (cv_1 - cv_0) / (v * pert), 0.001);
654 REL_TEST(deriv2, (cv_2 - cv_0) / (e * pert), 0.001);
655
656 // viscosity
657 Real mu1;
658 _tab_ve_from_fp->mu_from_v_e(v, e, mu1, deriv1, deriv2);
659 Real mu_0 = _tab_ve_from_fp->mu_from_v_e(v, e);
660 Real mu_1 = _tab_ve_from_fp->mu_from_v_e(v * (1 + pert), e);
661 Real mu_2 = _tab_ve_from_fp->mu_from_v_e(v, e * (1 + pert));
662 REL_TEST(mu1, mu_0, 0.001);
663 REL_TEST(deriv1, (mu_1 - mu_0) / (v * pert), 0.001);
664 REL_TEST(deriv2, (mu_2 - mu_0) / (e * pert), 0.001);
665
666 // thermal conductivity
667 Real k1;
668 _tab_ve_from_fp->k_from_v_e(v, e, k1, deriv1, deriv2);
669 Real k_0 = _tab_ve_from_fp->k_from_v_e(v, e);
670 Real k_1 = _tab_ve_from_fp->k_from_v_e(v * (1 + pert), e);
671 Real k_2 = _tab_ve_from_fp->k_from_v_e(v, e * (1 + pert));
672 REL_TEST(k1, k_0, 0.001);
673 REL_TEST(deriv1, (k_1 - k_0) / (v * pert), 0.001);
674 REL_TEST(deriv2, (k_2 - k_0) / (e * pert), 0.001);
675
676 // entropy
677 Real s1;
678 _tab_ve_from_fp->s_from_v_e(v, e, s1, deriv1, deriv2);
679 Real s_0 = _tab_ve_from_fp->s_from_v_e(v, e);
680 Real s_1 = _tab_ve_from_fp->s_from_v_e(v * (1 + pert), e);
681 Real s_2 = _tab_ve_from_fp->s_from_v_e(v, e * (1 + pert));
682 REL_TEST(s1, s_0, 0.001);
683 REL_TEST(deriv1, (s_1 - s_0) / (v * pert), 0.001);
684 REL_TEST(deriv2, (s_2 - s_0) / (e * pert), 0.001);
685 }
686
687 // test enthalpy relationships (v,h)
688 {
690 Real h = _idg_fp->h_from_p_T(p, T);
691 Real v = _idg_fp->v_from_p_T(p, T);
692 Real e_gold = _idg_fp->e_from_p_T(p, T);
693 Real e0 = _tab_ve_from_fp->e_from_v_h(v, h);
694 REL_TEST(e_gold, e0, 0.001);
695
696 Real e2, de_dv, de_dh;
697 _tab_ve_from_fp->e_from_v_h(v, h, e2, de_dv, de_dh);
698 REL_TEST(e_gold, e2, 0.001);
699 Real e_0 = _tab_ve_from_fp->e_from_v_h(v, h);
700 Real e_1 = _tab_ve_from_fp->e_from_v_h(v * (1 + pert), h);
701 Real e_2 = _tab_ve_from_fp->e_from_v_h(v, h * (1 + pert));
702 REL_TEST(de_dv, (e_1 - e_0) / (v * pert), 0.001);
703 REL_TEST(de_dh, (e_2 - e_0) / (h * pert), 0.001);
705 }
706
707 // check computations from p, T
708 {
709 // density
710 Real p = _tab_ve_from_fp->p_from_v_e(v, e);
711 Real T = _tab_ve_from_fp->T_from_v_e(v, e);
712 REL_TEST(1. / v, _tab_ve_from_fp->rho_from_p_T(p, T), 1e-6);
713
714 // internal energy
715 REL_TEST(e, _tab_ve_from_fp->e_from_p_T(p, T), 1e-6);
716
717 // enthalpy
718 Real h = _tab_ve_from_fp->h_from_v_e(v, e);
719 REL_TEST(h, _tab_ve_from_fp->h_from_p_T(p, T), 1e-6);
720
721 // entropy
722 Real s = _tab_ve_from_fp->s_from_v_e(v, e);
723 REL_TEST(s, _tab_ve_from_fp->s_from_p_T(p, T), 1e-6);
724 }
725
726 // check computations from p, rho
727 {
728 // temperature
729 Real p = _tab_ve_from_fp->p_from_v_e(v, e);
730 Real T = _tab_ve_from_fp->T_from_v_e(v, e);
731 REL_TEST(T, _tab_ve_from_fp->T_from_p_rho(p, 1. / v), 1e-6);
732
733 // specific internal energy
734 REL_TEST(e, _tab_ve_from_fp->e_from_p_rho(p, 1. / v), 1e-6);
735 }
736
737 // check computations from p, h
738 {
739 // temperature
740 Real p = _tab_ve_from_fp->p_from_v_e(v, e);
741 Real T = _tab_ve_from_fp->T_from_v_e(v, e);
742 Real h = _tab_ve_from_fp->h_from_v_e(v, e);
743 REL_TEST(T, _tab_ve_from_fp->T_from_p_h(p, h), 1e-6);
744
745 // entropy
746 Real s = _tab_ve_from_fp->s_from_v_e(v, e);
747 REL_TEST(s, _tab_ve_from_fp->s_from_h_p(h, p), 1e-6);
748 }
749
750 // check computations from p, s
751 {
752 // temperature
753 Real p = _tab_ve_from_fp->p_from_v_e(v, e);
754 Real T = _tab_ve_from_fp->T_from_v_e(v, e);
755 Real s = _tab_ve_from_fp->s_from_v_e(v, e);
757 REL_TEST(T, _tab_ve_from_fp->T_from_p_s(p, s), 1e-6);
759 }
760
761 // AD p_from_v_e
762 {
763 DNDerivativeType dvdx;
764 DNDerivativeType dedx;
765 // set it up so these are the derivatives
766 // w.r.t. to themselves
767 Moose::derivInsert(dvdx, 0, 1);
768 Moose::derivInsert(dvdx, 1, 0);
769 Moose::derivInsert(dedx, 0, 0);
770 Moose::derivInsert(dedx, 1, 1);
771
772 ADReal v_ad(v, dvdx);
773 ADReal e_ad(e, dedx);
774 ADReal p_ad = _tab_ve_from_fp->p_from_v_e(v_ad, e_ad);
775
776 Real pp, dp_dv, dp_de;
777 _tab_ve_from_fp->p_from_v_e(v, e, pp, dp_dv, dp_de);
778 REL_TEST(p_ad.derivatives()[0], dp_dv, 0.0001);
779 REL_TEST(p_ad.derivatives()[1], dp_de, 0.0001);
780 }
781
782 // AD T_from_v_e
783 {
784 DNDerivativeType dvdx;
785 DNDerivativeType dedx;
786 // set it up so these are the derivatives
787 // w.r.t. to themselves
788 Moose::derivInsert(dvdx, 0, 1);
789 Moose::derivInsert(dvdx, 1, 0);
790 Moose::derivInsert(dedx, 0, 0);
791 Moose::derivInsert(dedx, 1, 1);
792
793 ADReal v_ad(v, dvdx);
794 ADReal e_ad(e, dedx);
795 ADReal T_ad = _tab_ve_from_fp->T_from_v_e(v_ad, e_ad);
796
797 Real TT, dT_dv, dT_de;
798 _tab_ve_from_fp->T_from_v_e(v, e, TT, dT_dv, dT_de);
799 REL_TEST(T_ad.derivatives()[0], dT_dv, 0.0001);
800 REL_TEST(T_ad.derivatives()[1], dT_de, 0.0001);
801 }
802
803 // AD e_from_p_rho
804 {
805 DNDerivativeType dpdx;
806 DNDerivativeType drhodx;
807 // set it up so these are the derivatives
808 // w.r.t. to themselves
809 Moose::derivInsert(dpdx, 0, 1);
810 Moose::derivInsert(dpdx, 1, 0);
811 Moose::derivInsert(drhodx, 0, 0);
812 Moose::derivInsert(drhodx, 1, 1);
813
814 Real rho = 1. / v;
815 ADReal p_ad(p, dpdx);
816 ADReal rho_ad(rho, drhodx);
817 ADReal e_ad = _tab_ve_from_fp->e_from_p_rho(p_ad, rho_ad);
818
819 Real e, de_dp, de_drho;
820 _tab_ve_from_fp->e_from_p_rho(p, rho, e, de_dp, de_drho);
821 REL_TEST(e_ad.derivatives()[0], de_dp, 0.0001);
822 REL_TEST(e_ad.derivatives()[1], de_drho, 0.0001);
823 }
824
825 // AD T_from_p_rho
826 {
827 DNDerivativeType dpdx;
828 DNDerivativeType drhodx;
829 // set it up so these are the derivatives
830 // w.r.t. to themselves
831 Moose::derivInsert(dpdx, 0, 1);
832 Moose::derivInsert(dpdx, 1, 0);
833 Moose::derivInsert(drhodx, 0, 0);
834 Moose::derivInsert(drhodx, 1, 1);
835
836 Real rho = 1. / v;
837 ADReal p_ad(p, dpdx);
838 ADReal rho_ad(rho, drhodx);
839 ADReal T_ad = _tab_ve_from_fp->T_from_p_rho(p_ad, rho_ad);
840
841 Real T, dT_dp, dT_drho;
842 _tab_ve_from_fp->T_from_p_rho(p, rho, T, dT_dp, dT_drho);
843 REL_TEST(T_ad.derivatives()[0], dT_dp, 0.0001);
844 REL_TEST(T_ad.derivatives()[1], dT_drho, 0.0001);
845 // The AD and non-AD overloads must use the same (v, e) tabulation
846 REL_TEST(T_ad.value(), _tab_ve_from_fp->T_from_p_rho(p, rho), REL_TOL_CONSISTENCY);
847 }
848
849 // AD e_from_p_T
850 {
851 DNDerivativeType dpdx;
852 DNDerivativeType dTdx;
853 // set it up so these are the derivatives
854 // w.r.t. to themselves
855 Moose::derivInsert(dpdx, 0, 1);
856 Moose::derivInsert(dpdx, 1, 0);
857 Moose::derivInsert(dTdx, 0, 0);
858 Moose::derivInsert(dTdx, 1, 1);
859
860 ADReal p_ad(p, dpdx);
861 ADReal T_ad(T, dTdx);
862 ADReal e_ad = _tab_ve_from_fp->e_from_p_T(p_ad, T_ad);
863
864 Real e, de_dp, de_dT;
865 _tab_ve_from_fp->e_from_p_T(p, T, e, de_dp, de_dT);
866 REL_TEST(e_ad.derivatives()[0], de_dp, 0.0001);
867 REL_TEST(e_ad.derivatives()[1], de_dT, 0.0001);
868 }
869
870 // AD rho_from_p_T
871 {
872 DNDerivativeType dpdx;
873 DNDerivativeType dTdx;
874 // set it up so these are the derivatives
875 // w.r.t. to themselves
876 Moose::derivInsert(dpdx, 0, 1);
877 Moose::derivInsert(dpdx, 1, 0);
878 Moose::derivInsert(dTdx, 0, 0);
879 Moose::derivInsert(dTdx, 1, 1);
880
881 Real p = _tab_ve_from_fp->p_from_v_e(v, e);
882 Real T = _tab_ve_from_fp->p_from_v_e(v, e);
883 ADReal p_ad(p, dpdx);
884 ADReal T_ad(T, dTdx);
885 ADReal rho_ad = _tab_ve_from_fp->rho_from_p_T(p_ad, T_ad);
886
887 Real rho, drho_dp, drho_dT;
888 _tab_ve_from_fp->rho_from_p_T(p, T, rho, drho_dp, drho_dT);
889 REL_TEST(rho_ad.derivatives()[0], drho_dp, 0.0001);
890 REL_TEST(rho_ad.derivatives()[1], drho_dT, 0.0001);
891 }
892
893 // cannot test AD c_from_v_e because co2 props do not
894 // implement enough
895}
896
902{
903
904 const Real p = 1.5e6;
905 const Real T = 452.0;
906
907 {
908 // Read the data file and generate (v,e) to (p,T) interpolations
910 const_cast<TabulatedBicubicFluidProperties *>(_tab_ve_from_pT)->initialSetup();
912 const Real tol = REL_TOL_DERIVATIVE;
913
914 const Real rho = _tab_ve_from_pT->rho_from_p_T(p, T);
915 const Real v = 1. / rho;
916 const Real e = _tab_ve_from_pT->e_from_p_T(p, T);
917 const Real s = _tab_ve_from_pT->s_from_p_T(p, T);
918
919 DERIV_TEST(_tab_ve_from_pT->rho_from_p_T, p, T, tol);
920 DERIV_TEST(_tab_ve_from_pT->e_from_p_T, p, T, tol);
921 DERIV_TEST(_tab_ve_from_pT->v_from_p_T, p, T, tol);
922 DERIV_TEST(_tab_ve_from_pT->h_from_p_T, p, T, tol);
923 DERIV_TEST(_tab_ve_from_pT->k_from_p_T, p, T, tol);
924 DERIV_TEST(_tab_ve_from_pT->cp_from_p_T, p, T, tol);
925 DERIV_TEST(_tab_ve_from_pT->cv_from_p_T, p, T, tol);
926 DERIV_TEST(_tab_ve_from_pT->mu_from_p_T, p, T, tol);
927
928 DERIV_TEST(_tab_ve_from_pT->p_from_v_e, v, e, tol);
929 DERIV_TEST(_tab_ve_from_pT->mu_from_v_e, v, e, tol);
930 DERIV_TEST(_tab_ve_from_pT->k_from_v_e, v, e, tol);
931 DERIV_TEST(_tab_ve_from_pT->T_from_v_e, v, e, tol);
932 DERIV_TEST(_tab_ve_from_pT->cp_from_v_e, v, e, tol);
933 DERIV_TEST(_tab_ve_from_pT->cv_from_v_e, v, e, tol);
934
935 DERIV_TEST(_tab_ve_from_pT->T_from_p_rho, p, rho, tol);
936 DERIV_TEST(_tab_ve_from_pT->e_from_p_rho, p, rho, tol);
937
938 DERIV_TEST(_tab_ve_from_pT->T_from_p_s, p, s, tol);
939 DERIV_TEST(_tab_ve_from_pT->rho_from_p_s, p, s, tol);
940
941 // The temperature derivatives must not rely on relative perturbations of the arguments,
942 // which vanish at zero entropy: (dT/ds)_p = T / cp. The CO2 entropy reference puts s = 0
943 // within the range of the tabulation generated from CO2FluidProperties.
944 {
945 const Real s0 = 0.0;
946 Real T0, dT_dp, dT_ds;
947 _tab_pT_from_fp->T_from_p_s(p, s0, T0, dT_dp, dT_ds);
948 REL_TEST(dT_ds, T0 / _tab_pT_from_fp->cp_from_p_T(p, T0), 1e-3);
949 }
950 }
951
952 {
953 // Read the data file with direct to (v,e) interpolations
955 const_cast<TabulatedBicubicFluidProperties *>(_tab_ve_from_fp)->initialSetup();
957 const Real tol = REL_TOL_DERIVATIVE;
958
959 const Real rho = _tab_ve_from_fp->rho_from_p_T(p, T);
960 const Real v = 1. / rho;
961 const Real e = _tab_ve_from_fp->e_from_p_T(p, T);
962 const Real h = e + p * v;
963
964 DERIV_TEST(_tab_ve_from_fp->p_from_v_e, v, e, tol);
965 DERIV_TEST(_tab_ve_from_fp->mu_from_v_e, v, e, tol);
966 DERIV_TEST(_tab_ve_from_fp->k_from_v_e, v, e, tol);
967 DERIV_TEST(_tab_ve_from_fp->T_from_v_e, v, e, tol);
968 DERIV_TEST(_tab_ve_from_fp->cp_from_v_e, v, e, tol);
969 DERIV_TEST(_tab_ve_from_fp->cv_from_v_e, v, e, tol);
970
971 // Jacobian warning and finite differencing in use
973 DERIV_TEST(_tab_ve_from_fp->e_from_v_h, v, h, 100 * tol);
975 }
976}
977
978// Test generation of tabulated fluid properties
980{
981 Real p = 1.5e6;
982 Real T = 450.0;
983
984 // Generate the tabulated data from the CO2 fluid properties
985 const_cast<TabulatedBicubicFluidProperties *>(_tab_pT_from_fp_gen)->initialSetup();
986
987 REL_TEST(_tab_pT_from_fp_gen->rho_from_p_T(p, T), _co2_fp->rho_from_p_T(p, T), 1.0e-4);
988 REL_TEST(_tab_pT_from_fp_gen->h_from_p_T(p, T), _co2_fp->h_from_p_T(p, T), 1.0e-4);
989 REL_TEST(_tab_pT_from_fp_gen->e_from_p_T(p, T), _co2_fp->e_from_p_T(p, T), 1.0e-4);
990 REL_TEST(_tab_pT_from_fp_gen->mu_from_p_T(p, T), _co2_fp->mu_from_p_T(p, T), 1.0e-4);
991 REL_TEST(_tab_pT_from_fp_gen->k_from_p_T(p, T), _co2_fp->k_from_p_T(p, T), 1.0e-4);
992 REL_TEST(_tab_pT_from_fp_gen->cp_from_p_T(p, T), _co2_fp->cp_from_p_T(p, T), 1.0e-4);
993 REL_TEST(_tab_pT_from_fp_gen->cv_from_p_T(p, T), _co2_fp->cv_from_p_T(p, T), 1.0e-4);
994 REL_TEST(_tab_pT_from_fp_gen->s_from_p_T(p, T), _co2_fp->s_from_p_T(p, T), 1.0e-4);
995}
996
997// Test that all fluid properties are properly passed back to the given user object
998// if they are not tabulated
1000{
1001 Real p = 1.5e6;
1002 Real T = 450.0;
1003 const Real tol = REL_TOL_SAVED_VALUE;
1004
1005 // As the flags for interpolation in TabulatedBicubicFluidProperties default to false,
1006 // properties will be passed through to the given fluid properties object
1007 ABS_TEST(_tab_pT_from_fp->v_from_p_T(p, T), 1. / _co2_fp->rho_from_p_T(p, T), tol);
1008 ABS_TEST(_tab_pT_from_fp->rho_from_p_T(p, T), _co2_fp->rho_from_p_T(p, T), tol);
1009 ABS_TEST(_tab_pT_from_fp->h_from_p_T(p, T), _co2_fp->h_from_p_T(p, T), tol);
1010 ABS_TEST(_tab_pT_from_fp->e_from_p_T(p, T), _co2_fp->e_from_p_T(p, T), tol);
1011 ABS_TEST(_tab_pT_from_fp->mu_from_p_T(p, T), _co2_fp->mu_from_p_T(p, T), tol);
1012 ABS_TEST(_tab_pT_from_fp->k_from_p_T(p, T), _co2_fp->k_from_p_T(p, T), tol);
1013 ABS_TEST(_tab_pT_from_fp->cp_from_p_T(p, T), _co2_fp->cp_from_p_T(p, T), tol);
1014 ABS_TEST(_tab_pT_from_fp->cv_from_p_T(p, T), _co2_fp->cv_from_p_T(p, T), tol);
1015 ABS_TEST(_tab_pT_from_fp->s_from_p_T(p, T), _co2_fp->s_from_p_T(p, T), tol);
1016
1017 // These calls are always forwarded to the 'fp' parameter fluid properties because the
1018 // tabulations are not implemented
1019 ABS_TEST(_tab_pT_from_fp->henryCoefficients()[0], _co2_fp->henryCoefficients()[0], tol);
1020 ABS_TEST(_tab_pT_from_fp->henryCoefficients()[1], _co2_fp->henryCoefficients()[1], tol);
1021 ABS_TEST(_tab_pT_from_fp->henryCoefficients()[2], _co2_fp->henryCoefficients()[2], tol);
1022 ABS_TEST(_tab_pT_from_fp->triplePointPressure(), _co2_fp->triplePointPressure(), tol);
1023 ABS_TEST(_tab_pT_from_fp->triplePointTemperature(), _co2_fp->triplePointTemperature(), tol);
1024 ABS_TEST(_tab_pT_from_fp->criticalPressure(), _co2_fp->criticalPressure(), tol);
1025 ABS_TEST(_tab_pT_from_fp->criticalTemperature(), _co2_fp->criticalTemperature(), tol);
1026 ABS_TEST(_tab_pT_from_fp->criticalDensity(), _co2_fp->criticalDensity(), tol);
1027
1028 // Use a temperature less than the critical point
1029 T = 300.0;
1030 ABS_TEST(_tab_pT_from_fp->vaporPressure(T), _co2_fp->vaporPressure(T), tol);
1031
1032 // TODO: these properties are not implemented in CO2 fp so we cannot test the pass through
1033 // T_from_p_h
1034 // vaporPressure with saturation pressure
1035 // vaporTemperature
1036
1037 // AD passthrough
1038 // Switching to IdealGas FP to have more definitions
1039 const_cast<TabulatedBicubicFluidProperties *>(_tab_pT_from_fp_idg)->initialSetup();
1040 DNDerivativeType dpdx;
1041 DNDerivativeType dTdx;
1042 Moose::derivInsert(dpdx, 0, 1);
1043 Moose::derivInsert(dpdx, 1, 0);
1044 Moose::derivInsert(dTdx, 0, 0);
1045 Moose::derivInsert(dTdx, 1, 1);
1046 ADReal p_ad(1.5e6, dpdx);
1047 ADReal T_ad(450.0, dTdx);
1048 // value
1049 ABS_TEST(_tab_pT_from_fp_idg->v_from_p_T(p_ad, T_ad).value(),
1050 _idg_fp->v_from_p_T(p_ad, T_ad).value(),
1051 tol);
1052 ABS_TEST(_tab_pT_from_fp_idg->rho_from_p_T(p_ad, T_ad).value(),
1053 _idg_fp->rho_from_p_T(p_ad, T_ad).value(),
1054 tol);
1055 ABS_TEST(_tab_pT_from_fp_idg->e_from_p_T(p_ad, T_ad).value(),
1056 _idg_fp->e_from_p_T(p_ad, T_ad).value(),
1057 tol);
1058 ABS_TEST(_tab_pT_from_fp_idg->cp_from_p_T(p_ad, T_ad).value(),
1059 _idg_fp->cp_from_p_T(p_ad, T_ad).value(),
1060 tol);
1061 // derivatives
1062 ABS_TEST(_tab_pT_from_fp_idg->v_from_p_T(p_ad, T_ad).derivatives()[0],
1063 _idg_fp->v_from_p_T(p_ad, T_ad).derivatives()[0],
1064 tol);
1065 ABS_TEST(_tab_pT_from_fp_idg->rho_from_p_T(p_ad, T_ad).derivatives()[0],
1066 _idg_fp->rho_from_p_T(p_ad, T_ad).derivatives()[0],
1067 tol);
1068 ABS_TEST(_tab_pT_from_fp_idg->e_from_p_T(p_ad, T_ad).derivatives()[0],
1069 _idg_fp->e_from_p_T(p_ad, T_ad).derivatives()[0],
1070 tol);
1071 ABS_TEST(_tab_pT_from_fp_idg->cp_from_p_T(p_ad, T_ad).derivatives()[0],
1072 _idg_fp->cp_from_p_T(p_ad, T_ad).derivatives()[0],
1073 tol);
1074 ABS_TEST(_tab_pT_from_fp_idg->v_from_p_T(p_ad, T_ad).derivatives()[1],
1075 _idg_fp->v_from_p_T(p_ad, T_ad).derivatives()[1],
1076 tol);
1077 ABS_TEST(_tab_pT_from_fp_idg->rho_from_p_T(p_ad, T_ad).derivatives()[1],
1078 _idg_fp->rho_from_p_T(p_ad, T_ad).derivatives()[1],
1079 tol);
1080 ABS_TEST(_tab_pT_from_fp_idg->e_from_p_T(p_ad, T_ad).derivatives()[1],
1081 _idg_fp->e_from_p_T(p_ad, T_ad).derivatives()[1],
1082 tol);
1083 ABS_TEST(_tab_pT_from_fp_idg->cp_from_p_T(p_ad, T_ad).derivatives()[1],
1084 _idg_fp->cp_from_p_T(p_ad, T_ad).derivatives()[1],
1085 tol);
1086}
1087
1088// Test that all fluid properties are properly passed back to the given user object
1089// if they are not tabulated
1091{
1092 Real p = 1.5e6;
1093 Real T = 450.0;
1094 Real v = 1. / _idg_fp->rho_from_p_T(p, T);
1095 Real e = _idg_fp->e_from_p_T(p, T);
1096 const Real tol = REL_TOL_CONSISTENCY;
1097
1098 // need to generate (v,e) bounds
1099 const_cast<TabulatedBicubicFluidProperties *>(_tab_ve_from_fp)->initialSetup();
1100 // we use this tabulation based on idg as too many (v,e) routines are missing for CO2
1101
1102 // As the flags for interpolation in TabulatedBicubicFluidProperties default to false,
1103 // properties will be passed through to the given fluid properties object
1104 ABS_TEST(_tab_ve_from_fp->T_from_v_e(v, e), _idg_fp->T_from_v_e(v, e), tol);
1105 ABS_TEST(_tab_ve_from_fp->p_from_v_e(v, e), _idg_fp->p_from_v_e(v, e), 3 * tol);
1106 ABS_TEST(_tab_ve_from_fp->h_from_v_e(v, e), _idg_fp->h_from_v_e(v, e), tol);
1107 ABS_TEST(_tab_ve_from_fp->mu_from_v_e(v, e), _idg_fp->mu_from_v_e(v, e), tol);
1108 ABS_TEST(_tab_ve_from_fp->k_from_v_e(v, e), _idg_fp->k_from_v_e(v, e), tol);
1109 ABS_TEST(_tab_ve_from_fp->cp_from_v_e(v, e), _idg_fp->cp_from_v_e(v, e), tol);
1110 ABS_TEST(_tab_ve_from_fp->cv_from_v_e(v, e), _idg_fp->cv_from_v_e(v, e), tol);
1111 ABS_TEST(_tab_ve_from_fp->s_from_v_e(v, e), _idg_fp->s_from_v_e(v, e), 30 * tol);
1112
1113 // passthrough with derivatives
1114 {
1115 Real pert = 1e-7;
1116 Real deriv1, deriv2;
1117 // temperature
1118 Real T1;
1119 _tab_ve_from_fp->T_from_v_e(v, e, T1, deriv1, deriv2);
1120 Real T_0 = _tab_ve_from_fp->T_from_v_e(v, e);
1121 Real T_1 = _tab_ve_from_fp->T_from_v_e(v * (1 + pert), e);
1122 Real T_2 = _tab_ve_from_fp->T_from_v_e(v, e * (1 + pert));
1123 REL_TEST(deriv1, (T_1 - T_0) / (v * pert), 0.001);
1124 REL_TEST(deriv2, (T_2 - T_0) / (e * pert), 0.001);
1125
1126 // pressure
1127 Real p1;
1128 _tab_ve_from_fp->p_from_v_e(v, e, p1, deriv1, deriv2);
1129 Real p_0 = _tab_ve_from_fp->p_from_v_e(v, e);
1130 Real p_1 = _tab_ve_from_fp->p_from_v_e(v * (1 + pert), e);
1131 Real p_2 = _tab_ve_from_fp->p_from_v_e(v, e * (1 + pert));
1132 REL_TEST(deriv1, (p_1 - p_0) / (v * pert), 0.001);
1133 REL_TEST(deriv2, (p_2 - p_0) / (e * pert), 0.001);
1134 }
1135}
1136
1141{
1142 EXPECT_EQ(_tab_pT_from_fp->fluidName(), "co2");
1143}
1144
1149{
1150 ABS_TEST(_tab_pT_from_fp->molarMass(), 44.0098e-3, REL_TOL_SAVED_VALUE);
1151}
1152
1158{
1159 const Real p = 1.0e6;
1160 const Real T = 300.0;
1161 const Real tol = REL_TOL_CONSISTENCY;
1162
1163 // Single property methods
1164 Real rho, drho_dp, drho_dT;
1165 _tab_pT_from_fp->rho_from_p_T(p, T, rho, drho_dp, drho_dT);
1166 Real mu, dmu_dp, dmu_dT;
1167 _tab_pT_from_fp->mu_from_p_T(p, T, mu, dmu_dp, dmu_dT);
1168 Real e, de_dp, de_dT;
1169 _tab_pT_from_fp->e_from_p_T(p, T, e, de_dp, de_dT);
1170
1171 // Combined property methods
1172 Real rho2, drho2_dp, drho2_dT, mu2, dmu2_dp, dmu2_dT, e2, de2_dp, de2_dT;
1173 _tab_pT_from_fp->rho_mu_from_p_T(p, T, rho2, mu2);
1174
1175 ABS_TEST(rho, rho2, tol);
1176 ABS_TEST(mu, mu2, tol);
1177
1178 _tab_pT_from_fp->rho_mu_from_p_T(p, T, rho2, drho2_dp, drho2_dT, mu2, dmu2_dp, dmu2_dT);
1179 ABS_TEST(rho, rho2, tol);
1180 ABS_TEST(drho_dp, drho2_dp, tol);
1181 ABS_TEST(drho_dT, drho2_dT, tol);
1182 ABS_TEST(mu, mu2, tol);
1183 ABS_TEST(dmu_dp, dmu2_dp, tol);
1184 ABS_TEST(dmu_dT, dmu2_dT, tol);
1185
1186 _tab_pT_from_fp->rho_e_from_p_T(p, T, rho2, drho2_dp, drho2_dT, e2, de2_dp, de2_dT);
1187 ABS_TEST(rho, rho2, tol);
1188 ABS_TEST(drho_dp, drho2_dp, tol);
1189 ABS_TEST(drho_dT, drho2_dT, tol);
1190 ABS_TEST(e, e2, tol);
1191 ABS_TEST(de_dp, de2_dp, tol);
1192 ABS_TEST(de_dT, de2_dT, tol);
1193}
1194
1199TEST_F(TabulatedBicubicFluidPropertiesTest, gibbsWithoutTemperatureColumn)
1200{
1201 InputParameters params = _factory.getValidParams("TabulatedBicubicFluidProperties");
1202 params.set<UserObjectName>("input_fp") = "idg_fp";
1203 params.set<MooseEnum>("out_of_bounds_behavior") = "set_to_closest_bound";
1204 params.set<bool>("create_pT_interpolations") = false;
1205 params.set<bool>("create_ve_interpolations") = true;
1206 params.set<bool>("construct_pT_from_ve") = true;
1207 params.set<Real>("temperature_min") = 400;
1208 params.set<Real>("temperature_max") = 500;
1209 params.set<Real>("pressure_min") = 1e6;
1210 params.set<Real>("pressure_max") = 2e6;
1211 params.set<Real>("T_initial_guess") = 450;
1212 params.set<Real>("p_initial_guess") = 1.5e6;
1213 MultiMooseEnum properties("density enthalpy viscosity k c cv cp entropy pressure temperature",
1214 "density enthalpy entropy");
1215 params.set<MultiMooseEnum>("interpolated_properties") = properties;
1216 _fe_problem->addUserObject("TabulatedBicubicFluidProperties", "tab_ve_no_T", params);
1217 auto & fp = _fe_problem->getUserObject<TabulatedBicubicFluidProperties>("tab_ve_no_T");
1219 fp.initialSetup();
1221
1222 const Real p = 1.5e6;
1223 const Real T = 450.0;
1224 const Real v = _idg_fp->v_from_p_T(p, T);
1225 const Real e = _idg_fp->e_from_p_T(p, T);
1226 REL_TEST(fp.g_from_v_e(v, e), _idg_fp->g_from_v_e(v, e), 1e-3);
1227}
1228
1234{
1235 InputParameters params = _factory.getValidParams("CheckNaNsTabulatedFluidProperties");
1236 params.set<UserObjectName>("input_fp") = "idg_fp";
1237 _fe_problem->addUserObject("CheckNaNsTabulatedFluidProperties", "check_nans_fp", params);
1238 auto & fp = _fe_problem->getUserObject<CheckNaNsTabulatedFluidProperties>("check_nans_fp");
1239 fp.setSpecificVolumeGrid({1.0, 2.0, 3.0});
1240
1241 for (const auto i : make_range(3u))
1242 {
1243 Real p = std::numeric_limits<Real>::quiet_NaN();
1244 Real T = std::numeric_limits<Real>::quiet_NaN();
1245 unsigned int num_nans_p = 0, num_nans_T = 0;
1246 fp.checkNaNs(1e5, 1e6, 300, 500, i, p, T, num_nans_p, num_nans_T);
1247 EXPECT_FALSE(std::isnan(p));
1248 EXPECT_FALSE(std::isnan(T));
1249 EXPECT_EQ(num_nans_p, 1u);
1250 EXPECT_EQ(num_nans_T, 1u);
1251 }
1252}
DualNumber< Real, DNDerivativeType, true > ADReal
SemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< MOOSE_AD_MAX_DOFS_PER_ELEM > > DNDerivativeType
const double tol
const double mu
const Real p
const double rho
const double T
const double v
TEST_F(TabulatedBicubicFluidPropertiesTest, unorderedData)
Exposes TabulatedBicubicFluidProperties::checkNaNs and the specific volume grid for testing.
T & set(const std::string &name, bool quiet_mode=false)
Common class for single phase fluid properties.
Class for fluid properties read from a file.
bool _throw_on_warning
void derivInsert(SemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< N > > &derivs, libMesh::dof_id_type index, Real value)