https://mooseframework.inl.gov
Loading...
Searching...
No Matches
CaloricallyImperfectGasTest.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
17{
19 std::vector<Real> T = {100, 200, 300, 400, 500};
20 std::vector<Real> e = {1825110, 5272540, 10342290, 17034360, 25348750};
21 std::vector<Real> T2 = {100, 500};
22 std::vector<Real> mu = {1, 6};
23 std::vector<Real> k = {11, 1};
24
25 InputParameters e_fn_params = _factory.getValidParams("PiecewiseLinear");
26 e_fn_params.set<std::vector<Real>>("x") = T;
27 e_fn_params.set<std::vector<Real>>("y") = e;
28 _fe_problem->addFunction("PiecewiseLinear", "e_fn", e_fn_params);
29
30 InputParameters mu_fn_params = _factory.getValidParams("PiecewiseLinear");
31 mu_fn_params.set<std::vector<Real>>("x") = T2;
32 mu_fn_params.set<std::vector<Real>>("y") = mu;
33 _fe_problem->addFunction("PiecewiseLinear", "mu_fn", mu_fn_params);
34
35 InputParameters k_fn_params = _factory.getValidParams("PiecewiseLinear");
36 k_fn_params.set<std::vector<Real>>("x") = T2;
37 k_fn_params.set<std::vector<Real>>("y") = k;
38 _fe_problem->addFunction("PiecewiseLinear", "k_fn", k_fn_params);
39
40 InputParameters uo_pars = _factory.getValidParams("CaloricallyImperfectGas");
41 uo_pars.set<Real>("molar_mass") = 0.002;
42 uo_pars.set<FunctionName>("e") = "e_fn";
43 uo_pars.set<FunctionName>("mu") = "mu_fn";
44 uo_pars.set<FunctionName>("k") = "k_fn";
45 uo_pars.set<Real>("min_temperature") = 100.0;
46 uo_pars.set<Real>("max_temperature") = 500.0;
47 uo_pars.set<Real>("temperature_resolution") = 0.01;
48 _fe_problem->addUserObject("CaloricallyImperfectGas", "fp", uo_pars);
49 fp = &_fe_problem->getUserObject<CaloricallyImperfectGas>("fp");
50
51 const_cast<CaloricallyImperfectGas *>(fp)->initialSetup();
52
53 Real min_T = 100.0;
54 Real max_T = 500.0;
55 unsigned int np = 200;
56 Real dT = (max_T - min_T) / ((Real)np - 1.0);
57 Real Ru = 8.31446261815324;
58 Real Rs = Ru / 0.002;
59
60 // Consistency checks
61 {
62 for (unsigned int j = 1; j < np - 1; ++j)
63 {
64 Real T = min_T + j * dT;
65 Real p = 1.0e6;
66 const Real rho = fp->rho_from_p_T(p, T);
67 const Real v = 1.0 / rho;
68 Real h = fp->h_from_p_T(p, T);
69 Real e = fp->e_from_p_T(p, T);
70 Real cp = fp->cp_from_p_T(p, T);
71 Real cv = fp->cv_from_p_T(p, T);
72 Real k = fp->k_from_p_T(p, T);
73 Real mu = fp->mu_from_p_T(p, T);
74 Real s = fp->s_from_p_T(p, T);
75
76 // test rho_from_p_s
77 REL_TEST(fp->rho_from_p_s(p, s), rho, 10.0 * REL_TOL_CONSISTENCY);
78
79 // test e_from_x_y functions
80 REL_TEST(fp->e_from_v_h(v, h), e, 10.0 * REL_TOL_CONSISTENCY);
81 REL_TEST(fp->e_from_p_rho(p, rho), e, 10.0 * REL_TOL_CONSISTENCY);
82 REL_TEST(fp->e_from_T_v(T, v), e, 10.0 * REL_TOL_CONSISTENCY);
83
84 // test cv_x_y functions
85 REL_TEST(fp->cv_from_T_v(T, v), cv, 10.0 * REL_TOL_CONSISTENCY);
86 REL_TEST(fp->cv_from_v_e(v, e), cv, 10.0 * REL_TOL_CONSISTENCY);
87
88 // test cp_x_y functions
89 REL_TEST(fp->cp_from_v_e(v, e), cp, 10.0 * REL_TOL_CONSISTENCY);
90
91 // test h_from_x_y functions
92 REL_TEST(fp->h_from_T_v(T, v), h, 10.0 * REL_TOL_CONSISTENCY);
93
94 // test p_from_x_y functions
95 REL_TEST(fp->p_from_v_e(v, e), p, 10.0 * REL_TOL_CONSISTENCY);
96 REL_TEST(fp->p_from_T_v(T, v), p, 10.0 * REL_TOL_CONSISTENCY);
97
98 // test T_from_x_y functions
99 REL_TEST(fp->T_from_p_h(p, h), T, 10.0 * REL_TOL_CONSISTENCY);
100 REL_TEST(fp->T_from_v_e(v, e), T, 10.0 * REL_TOL_CONSISTENCY);
101
102 // test k_from_x_y functions
103 REL_TEST(fp->k_from_v_e(v, e), k, 10.0 * REL_TOL_CONSISTENCY);
104
105 // test mu_from_x_y functions
106 REL_TEST(fp->mu_from_v_e(v, e), mu, 10.0 * REL_TOL_CONSISTENCY);
107 }
108 }
109
110 // AD consistency checks
111 {
112 for (unsigned int j = 1; j < np - 1; ++j)
113 {
114 Real T = min_T + j * dT;
115 Real p = 1.0e6;
116 const Real rho = fp->rho_from_p_T(p, T);
117 const Real v = 1.0 / rho;
118 Real e = fp->e_from_p_T(p, T);
119 Real cv = fp->cv_from_p_T(p, T);
120 Real c = fp->c_from_p_T(p, T);
121
122 ADReal ad_e = e;
123 ADReal ad_v = v;
124 ADReal ad_p = fp->p_from_v_e(ad_v, ad_e);
125 Real tol = 1e-11;
126 REL_TEST(MetaPhysicL::raw_value(ad_p), p, tol);
127
128 ADReal ad_T = fp->T_from_v_e(ad_v, ad_e);
129 REL_TEST(MetaPhysicL::raw_value(ad_T), T, tol);
130
131 REL_TEST(MetaPhysicL::raw_value(fp->cv_from_v_e(ad_v, ad_e)), cv, tol);
132
133 ADReal ad_rho = fp->rho_from_p_T(ad_p, ad_T);
134 REL_TEST(MetaPhysicL::raw_value(ad_rho), rho, tol);
135
136 REL_TEST(MetaPhysicL::raw_value(fp->e_from_p_rho(ad_p, ad_rho)), e, tol);
137 REL_TEST(MetaPhysicL::raw_value(fp->e_from_T_v(ad_T, ad_v)), e, tol);
138 REL_TEST(MetaPhysicL::raw_value(fp->e_from_p_T(ad_p, ad_T)), e, tol);
139 REL_TEST(
140 MetaPhysicL::raw_value(fp->gamma_from_v_e(ad_v, ad_e)), fp->gamma_from_v_e(v, e), tol);
141 REL_TEST(MetaPhysicL::raw_value(fp->gamma_from_p_T(ad_p, ad_T)),
142 fp->gamma_from_p_T(ad_p, ad_T),
143 tol);
144 REL_TEST(MetaPhysicL::raw_value(fp->c_from_v_e(ad_v, ad_e)), c, tol);
145 REL_TEST(MetaPhysicL::raw_value(fp->c_from_p_T(ad_p, ad_T)), c, tol);
146 }
147 }
148
149 // check e/h lookups for T = 325.0 & e_from_v_h
150 {
151 Real T = 325.0;
152 Real p = 1.0e6;
153 Real e = 10342290 * 0.75 + 17034360 * 0.25;
154 Real h = e + p / fp->rho_from_p_T(p, T);
155 Real v = fp->v_from_p_T(p, T);
156
157 REL_TEST(h, fp->h_from_p_T(p, T), 1e-5);
158 REL_TEST(e, fp->e_from_p_T(p, T), 1e-5);
159 REL_TEST(e, fp->e_from_v_h(v, h), 1e-5);
160 }
161
162 // check cv/cp lookups for T = 325.0
163 {
164 Real T = 325.0;
165 Real p = 1.0e6;
166 Real cv = (17034360.0 - 10342290.0) / 100.0;
167 Real cp = cv + 8.3144598 / 0.002;
168 REL_TEST(cp, fp->cp_from_p_T(p, T), 1e-5);
169 REL_TEST(cv, fp->cv_from_p_T(p, T), 1e-5);
170
171 Real v = fp->v_from_p_T(p, T);
172 Real e = fp->e_from_p_T(p, T);
173 REL_TEST(cp, fp->cp_from_v_e(v, e), 1e-5);
174 REL_TEST(cv, fp->cv_from_v_e(v, e), 1e-5);
175 }
176
177 // test mu(p, T), mu(v, e), k(p, T), k(v, e) & derivatives
178 {
179 Real T = 250.0;
180 Real p = 1.0e6;
181 REL_TEST(fp->mu_from_p_T(p, T), 2.875, 1e-5);
182 REL_TEST(fp->k_from_p_T(p, T), 7.25, 1e-5);
183
184 Real v = fp->v_from_p_T(p, T);
185 Real e = fp->e_from_p_T(p, T);
186 REL_TEST(fp->mu_from_v_e(v, e), 2.875, 0.001);
187 REL_TEST(fp->k_from_v_e(v, e), 7.25, 0.001);
188
189 Real mu, dmu_dp, dmu_dT;
190 fp->mu_from_p_T(p, T, mu, dmu_dp, dmu_dT);
191 REL_TEST(dmu_dT, 0.0125, 1e-5);
192
193 Real k, dk_dp, dk_dT;
194 fp->k_from_p_T(p, T, k, dk_dp, dk_dT);
195 REL_TEST(dk_dT, -0.025, 1e-5);
196
197 Real cv = fp->cv_from_p_T(p, T);
198 Real dmu_dv, dmu_de;
199 fp->mu_from_v_e(v, e, mu, dmu_dv, dmu_de);
200 REL_TEST(dmu_de, 0.0125 / cv, 0.001);
201
202 Real dk_dv, dk_de;
203 fp->k_from_v_e(v, e, k, dk_dv, dk_de);
204 REL_TEST(dk_de, -0.025 / cv, 0.001);
205 }
206
207 // 5 argument functions
208 {
209 Real T = 325.0;
210 Real p = 1.0e6;
211 Real e = 10342290 * 0.75 + 17034360 * 0.25;
212 Real h = e + p / fp->rho_from_p_T(p, T);
213 Real v = fp->v_from_p_T(p, T);
214 Real rho = 1.0 / v;
215 Real cp = fp->cp_from_p_T(p, T);
216 Real cv = fp->cv_from_p_T(p, T);
217 Real s = fp->s_from_p_T(p, T);
218 Real mu = fp->mu_from_v_e(v, e);
219 Real k = fp->k_from_v_e(v, e);
220 Real gamma = fp->gamma_from_p_T(p, T);
221 Real ssound = fp->c_from_p_T(p, T);
222 Real tol = 1e-12;
223
224 {
225 Real a, b, c;
226 fp->p_from_v_e(v, e, a, b, c);
227 REL_TEST(a, p, tol);
228 DERIV_TEST_CUSTOM_PERTURBATION(fp->p_from_v_e, v, e, 1e-4, 1e-4);
229 }
230
231 {
232 Real a, b, c;
233 fp->T_from_v_e(v, e, a, b, c);
234 REL_TEST(a, T, tol);
235 DERIV_TEST_CUSTOM_PERTURBATION(fp->T_from_v_e, v, e, 1e-4, 1e-4);
236 }
237
238 {
239 Real a, b, c;
240 fp->cp_from_v_e(v, e, a, b, c);
241 REL_TEST(a, cp, tol);
242 DERIV_TEST_CUSTOM_PERTURBATION(fp->cp_from_v_e, v, e, 1e-4, 1e-4);
243 }
244
245 {
246 Real a, b, c;
247 fp->cv_from_v_e(v, e, a, b, c);
248 REL_TEST(a, cv, tol);
249 DERIV_TEST_CUSTOM_PERTURBATION(fp->cv_from_v_e, v, e, 1e-4, 1e-4);
250 }
251
252 {
253 Real a, b, c;
254 fp->mu_from_v_e(v, e, a, b, c);
255 REL_TEST(a, mu, tol);
256 DERIV_TEST_CUSTOM_PERTURBATION(fp->mu_from_v_e, v, e, 1e-4, 1e-4);
257 }
258
259 {
260 Real a, b, c;
261 fp->k_from_v_e(v, e, a, b, c);
262 REL_TEST(a, k, tol);
263 DERIV_TEST_CUSTOM_PERTURBATION(fp->k_from_v_e, v, e, 1e-4, 1e-4);
264 }
265
266 {
267 Real a, b, c;
268 fp->s_from_v_e(v, e, a, b, c);
269 REL_TEST(a, s, tol);
270 DERIV_TEST_CUSTOM_PERTURBATION(fp->s_from_v_e, v, e, 1e-4, 1e-4);
271 }
272
273 {
274 Real a, b, c;
275 fp->s_from_p_T(p, T, a, b, c);
276 REL_TEST(a, s, tol);
277 DERIV_TEST_CUSTOM_PERTURBATION(fp->s_from_p_T, p, T, 1e-4, 1e-4);
278 }
279
280 {
281 Real a, b, c;
282 fp->s_from_h_p(h, p, a, b, c);
283 REL_TEST(a, s, tol);
284 DERIV_TEST_CUSTOM_PERTURBATION(fp->s_from_h_p, h, p, 1e-4, 1e-4);
285 }
286
287 {
288 Real a, b, c;
289 fp->e_from_v_h(v, h, a, b, c);
290 REL_TEST(a, e, tol);
291 DERIV_TEST_CUSTOM_PERTURBATION(fp->e_from_v_h, v, h, 1e-4, 1e-4);
292 }
293
294 {
295 Real a, b, c;
296 fp->rho_from_p_T(p, T, a, b, c);
297 REL_TEST(a, rho, tol);
298 DERIV_TEST_CUSTOM_PERTURBATION(fp->rho_from_p_T, p, T, 1e-4, 1e-4);
299 }
300
301 {
302 Real a, b, c;
303 fp->e_from_p_rho(p, rho, a, b, c);
304 REL_TEST(a, e, tol);
305 DERIV_TEST_CUSTOM_PERTURBATION(fp->e_from_p_rho, p, rho, 1e-4, 1e-4);
306 }
307
308 {
309 Real a, b, c;
310 fp->e_from_T_v(T, v, a, b, c);
311 REL_TEST(a, e, tol);
312 DERIV_TEST_CUSTOM_PERTURBATION(fp->e_from_T_v, T, v, 1e-4, 1e-4);
313 }
314
315 {
316 Real a, b, c;
317 fp->p_from_T_v(T, v, a, b, c);
318 REL_TEST(a, p, tol);
319 DERIV_TEST_CUSTOM_PERTURBATION(fp->p_from_T_v, T, v, 1e-4, 1e-4);
320 }
321
322 {
323 Real a, b, c;
324 fp->h_from_T_v(T, v, a, b, c);
325 REL_TEST(a, h, tol);
326 DERIV_TEST_CUSTOM_PERTURBATION(fp->h_from_T_v, T, v, 1e-4, 1e-4);
327 }
328
329 {
330 Real a, b, c;
331 fp->s_from_T_v(T, v, a, b, c);
332 REL_TEST(a, s, tol);
333 DERIV_TEST_CUSTOM_PERTURBATION(fp->s_from_T_v, T, v, 1e-4, 1e-4);
334 }
335
336 {
337 Real a, b, c;
338 fp->h_from_p_T(p, T, a, b, c);
339 REL_TEST(a, h, tol);
340 DERIV_TEST_CUSTOM_PERTURBATION(fp->h_from_p_T, p, T, 1e-4, 1e-4);
341 }
342
343 {
344 Real a, b, c;
345 fp->e_from_p_T(p, T, a, b, c);
346 REL_TEST(a, e, tol);
347 DERIV_TEST_CUSTOM_PERTURBATION(fp->e_from_p_T, p, T, 1e-4, 1e-4);
348 }
349
350 {
351 Real a, b, c;
352 fp->T_from_p_h(p, h, a, b, c);
353 REL_TEST(a, T, tol);
354 DERIV_TEST_CUSTOM_PERTURBATION(fp->T_from_p_h, p, h, 1e-4, 1e-4);
355 }
356
357 {
358 Real a, b, c;
359 fp->cv_from_p_T(p, T, a, b, c);
360 REL_TEST(a, cv, tol);
361 DERIV_TEST_CUSTOM_PERTURBATION(fp->cv_from_p_T, p, T, 1e-4, 1e-4);
362 }
363
364 {
365 Real a, b, c;
366 fp->cp_from_p_T(p, T, a, b, c);
367 REL_TEST(a, cp, tol);
368 DERIV_TEST_CUSTOM_PERTURBATION(fp->cp_from_p_T, p, T, 1e-4, 1e-4);
369 }
370
371 {
372 Real a, b, c;
373 fp->mu_from_p_T(p, T, a, b, c);
374 REL_TEST(a, mu, tol);
375 DERIV_TEST_CUSTOM_PERTURBATION(fp->mu_from_p_T, p, T, 1e-4, 1e-4);
376 }
377
378 {
379 Real a, b, c;
380 fp->k_from_p_T(p, T, a, b, c);
381 REL_TEST(a, k, tol);
382 DERIV_TEST_CUSTOM_PERTURBATION(fp->k_from_p_T, p, T, 1e-4, 1e-4);
383 }
384
385 {
386 Real a, b, c;
387 fp->gamma_from_p_T(p, T, a, b, c);
388 REL_TEST(a, gamma, tol);
389 DERIV_TEST_CUSTOM_PERTURBATION(fp->gamma_from_p_T, p, T, 1e-4, 1e-4);
390 }
391
392 {
393 Real a, b, c;
394 fp->gamma_from_v_e(v, e, a, b, c);
395 REL_TEST(a, gamma, tol);
396 DERIV_TEST_CUSTOM_PERTURBATION(fp->gamma_from_v_e, v, e, 1e-4, 1e-4);
397 }
398
399 {
400 Real a, b, c;
401 fp->c_from_v_e(v, e, a, b, c);
402 REL_TEST(a, ssound, tol);
403 DERIV_TEST_CUSTOM_PERTURBATION(fp->c_from_v_e, v, e, 1e-4, 1e-4);
404 }
405
406 {
407 Real a, b, c;
408 fp->c_from_p_T(p, T, a, b, c);
409 REL_TEST(a, ssound, tol);
410 DERIV_TEST_CUSTOM_PERTURBATION(fp->c_from_p_T, p, T, 1e-4, 1e-4);
411 }
412 }
413
414 // test entropy functions
415 {
416 Real T = 489.305;
417 Real Z = 0.5 * (80459 + 80460.7);
418 Real p = 1.0e6;
419 const Real rho = fp->rho_from_p_T(p, T);
420 const Real v = 1.0 / rho;
421 const Real v0 = 1.0;
422 Real e = fp->e_from_p_T(p, T);
423 Real h = fp->h_from_p_T(p, T);
424 Real s = Z + Rs * std::log(v / v0);
425
426 REL_TEST(fp->s_from_p_T(p, T), s, 1e-6);
427 REL_TEST(fp->s_from_v_e(v, e), s, 1e-6);
428 REL_TEST(fp->s_from_h_p(h, p), s, 1e-6);
429 REL_TEST(fp->s_from_T_v(T, v), s, 1e-6);
430
431 // test 5 arg functions with derivatives for s(p, T)
432 {
433 Real s_alt, ds_dp, ds_dT;
434 fp->s_from_p_T(p, T, s_alt, ds_dp, ds_dT);
435 REL_TEST(s_alt, s, 1e-5);
436 DERIV_TEST_CUSTOM_PERTURBATION(fp->s_from_p_T, p, T, 1e-4, 1e-4);
437 }
438
439 // test 5 arg functions with derivatives for s(e, v)
440 {
441 Real s_alt, ds_dv, ds_de;
442 fp->s_from_v_e(v, e, s_alt, ds_dv, ds_de);
443 REL_TEST(s_alt, s, 1e-5);
444 DERIV_TEST_CUSTOM_PERTURBATION(fp->s_from_v_e, v, e, 1e-4, 1e-4);
445 }
446
447 // test 5 arg functions with derivatives for s(h, p)
448 {
449 Real s_alt, ds_dh, ds_dp;
450 fp->s_from_h_p(h, p, s_alt, ds_dh, ds_dp);
451 REL_TEST(s_alt, s, 1e-5);
452 DERIV_TEST_CUSTOM_PERTURBATION(fp->s_from_h_p, h, p, 1e-4, 1e-4);
453 }
454 }
455
456 // test out of bounds call for temperature
457 {
458 try
459 {
460 fp->cp_from_p_T(1.0e6, 600.0);
461 FAIL();
462 }
463 catch (const std::exception & err)
464 {
465 std::size_t pos = std::string(err.what()).find("which is outside of the bounds of");
466 ASSERT_TRUE(pos != std::string::npos);
467 }
468
469 try
470 {
471 fp->cp_from_p_T(1.0e6, 99.0);
472 FAIL();
473 }
474 catch (const std::exception & err)
475 {
476 std::size_t pos = std::string(err.what()).find("which is outside of the bounds of");
477 ASSERT_TRUE(pos != std::string::npos);
478 }
479 }
480}
481
483{
484 // Testing case where e(T) is not monotonic
485 const CaloricallyImperfectGas * fp_bad_e_fn;
486 std::vector<Real> T = {100, 200, 300, 400, 500};
487 std::vector<Real> bad_e = {2859400, 8578200, 17156400, 8578200, 42891000};
488 InputParameters bad_e_fn_params = _factory.getValidParams("PiecewiseLinear");
489 bad_e_fn_params.set<std::vector<Real>>("x") = T;
490 bad_e_fn_params.set<std::vector<Real>>("y") = bad_e;
491 _fe_problem->addFunction("PiecewiseLinear", "bad_e_fn", bad_e_fn_params);
492
493 InputParameters uo_pars_bad_e_fn = _factory.getValidParams("CaloricallyImperfectGas");
494 uo_pars_bad_e_fn.set<Real>("molar_mass") = 0.002;
495 uo_pars_bad_e_fn.set<FunctionName>("e") = "bad_e_fn";
496 uo_pars_bad_e_fn.set<FunctionName>("mu") = "default_fn";
497 uo_pars_bad_e_fn.set<FunctionName>("k") = "default_fn";
498 uo_pars_bad_e_fn.set<Real>("min_temperature") = 100.0;
499 uo_pars_bad_e_fn.set<Real>("max_temperature") = 500.0;
500 _fe_problem->addUserObject("CaloricallyImperfectGas", "fp_bad_e_fn", uo_pars_bad_e_fn);
501 fp_bad_e_fn = &_fe_problem->getUserObject<CaloricallyImperfectGas>("fp_bad_e_fn");
502
503 try
504 {
505 const_cast<CaloricallyImperfectGas *>(fp_bad_e_fn)->initialSetup();
506 FAIL();
507 }
508 catch (const std::exception & err)
509 {
510 std::size_t pos = std::string(err.what()).find("e(T) is not monotonically increasing with T");
511 ASSERT_TRUE(pos != std::string::npos);
512 }
513}
514
516{
517 // test for bad temperature values that violate min/max temperature
518 const CaloricallyImperfectGas * fp_bad_e_fn2;
519 std::vector<Real> e = {1825110, 5272540, 10342290, 17034360, 25348750};
520 std::vector<Real> bad_T = {150, 200, 300, 400, 500};
521 InputParameters bad_e_fn_params2 = _factory.getValidParams("PiecewiseLinear");
522 bad_e_fn_params2.set<std::vector<Real>>("x") = bad_T;
523 bad_e_fn_params2.set<std::vector<Real>>("y") = e;
524 _fe_problem->addFunction("PiecewiseLinear", "bad_e_fn2", bad_e_fn_params2);
525
526 InputParameters uo_pars_bad_e_fn2 = _factory.getValidParams("CaloricallyImperfectGas");
527 uo_pars_bad_e_fn2.set<Real>("molar_mass") = 0.002;
528 uo_pars_bad_e_fn2.set<FunctionName>("e") = "bad_e_fn2";
529 uo_pars_bad_e_fn2.set<FunctionName>("mu") = "default_fn";
530 uo_pars_bad_e_fn2.set<FunctionName>("k") = "default_fn";
531 uo_pars_bad_e_fn2.set<Real>("min_temperature") = 100.0;
532 uo_pars_bad_e_fn2.set<Real>("max_temperature") = 500.0;
533 _fe_problem->addUserObject("CaloricallyImperfectGas", "fp_bad_e_fn2", uo_pars_bad_e_fn2);
534 fp_bad_e_fn2 = &_fe_problem->getUserObject<CaloricallyImperfectGas>("fp_bad_e_fn2");
535
536 try
537 {
538 const_cast<CaloricallyImperfectGas *>(fp_bad_e_fn2)->initialSetup();
539 FAIL();
540 }
541 catch (const std::exception & err)
542 {
543 std::size_t pos = std::string(err.what()).find("e(T) is not monotonically increasing with T");
544 ASSERT_TRUE(pos != std::string::npos);
545 }
546}
547
549{
550 const IdealGasFluidProperties * ideal;
551 const CaloricallyImperfectGas * compare_with_ideal;
552 // compare ideal gas and calorically imperfect gas
553 InputParameters ideal_uo_pars = _factory.getValidParams("IdealGasFluidProperties");
554 ideal_uo_pars.set<Real>("molar_mass") = 0.002;
555 ideal_uo_pars.set<Real>("gamma") = 1.41;
556 _fe_problem->addUserObject("IdealGasFluidProperties", "ideal_fp", ideal_uo_pars);
557 ideal = &_fe_problem->getUserObject<IdealGasFluidProperties>("ideal_fp");
558
559 Real Ru = 8.31446261815324;
560 Real Rs = Ru / 0.002;
561 Real gamma = 1.41;
562 Real cp_val = gamma / (gamma - 1) * Rs;
563 Real cv_val = cp_val / gamma;
564 std::vector<Real> temps = {0.0, 500.0};
565 std::vector<Real> internal_energies = {0.0, 500.0 * cv_val};
566
567 InputParameters lin_e_fn_params = _factory.getValidParams("PiecewiseLinear");
568 lin_e_fn_params.set<std::vector<Real>>("x") = temps;
569 lin_e_fn_params.set<std::vector<Real>>("y") = internal_energies;
570 _fe_problem->addFunction("PiecewiseLinear", "lin_e_fn", lin_e_fn_params);
571
572 InputParameters compare_uo_pars = _factory.getValidParams("CaloricallyImperfectGas");
573 compare_uo_pars.set<Real>("molar_mass") = 0.002;
574 compare_uo_pars.set<FunctionName>("e") = "lin_e_fn";
575 compare_uo_pars.set<FunctionName>("mu") = "default_fn";
576 compare_uo_pars.set<FunctionName>("k") = "default_fn";
577 compare_uo_pars.set<Real>("min_temperature") = 100.0;
578 compare_uo_pars.set<Real>("max_temperature") = 500.0;
579 _fe_problem->addUserObject("CaloricallyImperfectGas", "compare_fp", compare_uo_pars);
580 compare_with_ideal = &_fe_problem->getUserObject<CaloricallyImperfectGas>("compare_fp");
581
582 const_cast<CaloricallyImperfectGas *>(compare_with_ideal)->initialSetup();
583
584 Real T = 325.0;
585 Real p = 1.0e6;
586
587 // test all functions that provide x_from_p_T, x_from_v_e, e_from_v_h, e_from_p_rho
588 {
589 Real v = ideal->v_from_p_T(p, T);
590 Real e = ideal->e_from_p_T(p, T);
591 Real rho = ideal->rho_from_p_T(p, T);
592 Real h = ideal->h_from_p_T(p, T);
593 REL_TEST(ideal->c_from_p_T(p, T), compare_with_ideal->c_from_p_T(p, T), 1e-5);
594 REL_TEST(ideal->rho_from_p_T(p, T), compare_with_ideal->rho_from_p_T(p, T), 1e-5);
595 REL_TEST(ideal->h_from_p_T(p, T), compare_with_ideal->h_from_p_T(p, T), 1e-5);
596 REL_TEST(ideal->e_from_p_T(p, T), compare_with_ideal->e_from_p_T(p, T), 1e-5);
597 REL_TEST(ideal->cv_from_p_T(p, T), compare_with_ideal->cv_from_p_T(p, T), 1e-5);
598 REL_TEST(ideal->cp_from_p_T(p, T), compare_with_ideal->cp_from_p_T(p, T), 1e-5);
599 REL_TEST(ideal->T_from_v_e(v, e), compare_with_ideal->T_from_v_e(v, e), 1e-5);
600 REL_TEST(ideal->c_from_v_e(v, e), compare_with_ideal->c_from_v_e(v, e), 1e-5);
601 REL_TEST(ideal->cv_from_v_e(v, e), compare_with_ideal->cv_from_v_e(v, e), 1e-5);
602 REL_TEST(ideal->cp_from_v_e(v, e), compare_with_ideal->cp_from_v_e(v, e), 1e-5);
603 REL_TEST(ideal->e_from_v_h(v, h), compare_with_ideal->e_from_v_h(v, h), 1e-5);
604 REL_TEST(ideal->e_from_p_rho(p, rho), compare_with_ideal->e_from_p_rho(p, rho), 1e-5);
605 REL_TEST(ideal->e_from_T_v(T, v), compare_with_ideal->e_from_T_v(T, v), 1e-5);
606 REL_TEST(ideal->p_from_T_v(T, v), compare_with_ideal->p_from_T_v(T, v), 1e-5);
607 REL_TEST(ideal->gamma_from_p_T(p, T), compare_with_ideal->gamma_from_p_T(p, T), 1e-5);
608 REL_TEST(ideal->gamma_from_v_e(v, e), compare_with_ideal->gamma_from_v_e(v, e), 1e-5);
609 }
610
611 // test derivatives for c_from_v_e
612 {
613 Real v = ideal->v_from_p_T(p, T);
614 Real e = ideal->e_from_p_T(p, T);
615 Real c = 0, dc_dv = 0, dc_de = 0;
616 ideal->c_from_v_e(v, e, c, dc_dv, dc_de);
617 Real c2 = 0, dc_dv2 = 0, dc_de2 = 0;
618 compare_with_ideal->c_from_v_e(v, e, c2, dc_dv2, dc_de2);
619 REL_TEST(dc_dv, dc_dv2, 1e-5);
620 REL_TEST(dc_de, dc_de2, 1e-5);
621 }
622
623 // test derivatives for p_from_v_e
624 {
625 Real v = ideal->v_from_p_T(p, T);
626 Real e = ideal->e_from_p_T(p, T);
627 Real pp = 0, dp_dv = 0, dp_de = 0;
628 ideal->p_from_v_e(v, e, pp, dp_dv, dp_de);
629 Real pp2 = 0, dp_dv2 = 0, dp_de2 = 0;
630 compare_with_ideal->p_from_v_e(v, e, pp2, dp_dv2, dp_de2);
631 REL_TEST(dp_dv, dp_dv2, 1e-5);
632 REL_TEST(dp_de, dp_de2, 1e-5);
633 }
634
635 // test derivatives for T_from_v_e
636 {
637 Real v = ideal->v_from_p_T(p, T);
638 Real e = ideal->e_from_p_T(p, T);
639 Real TT = 0, dT_dv = 0, dT_de = 0;
640 ideal->T_from_v_e(v, e, TT, dT_dv, dT_de);
641 Real TT2 = 0, dT_dv2 = 0, dT_de2 = 0;
642 compare_with_ideal->T_from_v_e(v, e, TT2, dT_dv2, dT_de2);
643 REL_TEST(dT_dv, dT_dv2, 1e-5);
644 REL_TEST(dT_de, dT_de2, 1e-5);
645 }
646
647 // test derivatives for e_from_v_h
648 {
649 Real v = ideal->v_from_p_T(p, T);
650 Real h = ideal->h_from_p_T(p, T);
651 Real ee = 0, de_dv = 0, de_dh = 0;
652 ideal->e_from_v_h(v, h, ee, de_dv, de_dh);
653 Real ee2 = 0, de_dv2 = 0, de_dh2 = 0;
654 compare_with_ideal->e_from_v_h(v, h, ee2, de_dv2, de_dh2);
655 REL_TEST(de_dv, de_dv2, 1e-5);
656 REL_TEST(de_dh, de_dh2, 1e-5);
657 }
658}
DualNumber< Real, DNDerivativeType, true > ADReal
TEST_F(CaloricallyImperfectGasTest, testAll)
Verify that the fluid name is correctly returned.
const double tol
const double mu
const Real p
const double rho
const double T
const double v
A calorically imperfect gas fluid property class This fluid property assumes that internal energy is ...
virtual Real e_from_v_h(Real v, Real h) const override
virtual Real p_from_v_e(Real v, Real e) const override
virtual Real c_from_p_T(Real p, Real T) const override
virtual Real cv_from_v_e(Real v, Real e) const override
virtual Real gamma_from_p_T(Real p, Real T) const override
virtual Real cp_from_v_e(Real v, Real e) const override
virtual Real e_from_p_T(Real p, Real T) const override
virtual Real h_from_p_T(Real p, Real T) const override
virtual Real e_from_T_v(Real T, Real v) const override
virtual Real T_from_v_e(Real v, Real e) const override
virtual Real cv_from_p_T(Real p, Real T) const override
virtual Real c_from_v_e(Real v, Real e) const override
virtual Real p_from_T_v(Real T, Real v) const override
virtual Real cp_from_p_T(Real p, Real T) const override
virtual Real rho_from_p_T(Real p, Real T) const override
virtual Real gamma_from_v_e(Real v, Real e) const override
Ideal gas fluid properties Default parameters are for air at atmospheric pressure and temperature.
virtual Real p_from_v_e(Real v, Real e) const override
virtual Real c_from_v_e(Real v, Real e) const override
virtual Real e_from_v_h(Real v, Real h) const override
virtual Real T_from_v_e(Real v, Real e) const override
virtual Real cv_from_p_T(Real p, Real T) const override
virtual Real e_from_p_rho(Real p, Real rho) const override
virtual Real rho_from_p_T(Real p, Real T) const override
virtual Real e_from_T_v(Real T, Real v) const override
virtual Real cp_from_p_T(Real p, Real T) const override
virtual Real c_from_p_T(Real p, Real T) const override
virtual Real gamma_from_v_e(Real v, Real e) const override
virtual Real p_from_T_v(Real T, Real v) const override
virtual Real e_from_p_T(Real p, Real T) const override
virtual Real gamma_from_p_T(Real p, Real T) const override
virtual Real h_from_p_T(Real p, Real T) const override
virtual Real cp_from_v_e(Real v, Real e) const override
virtual Real cv_from_v_e(Real v, Real e) const override
T & set(const std::string &name, bool quiet_mode=false)
const T & getUserObject(const std::string &param_name, bool is_dependency=true) const
auto raw_value(const Eigen::Map< T > &in)