https://mooseframework.inl.gov
Loading...
Searching...
No Matches
HydrogenFluidProperties.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#include "Conversion.h"
12#include "MathUtils.h"
13#include "libmesh/utility.h"
14
16
19{
21 params.addClassDescription("Fluid properties for Hydrogen (H2)");
22 return params;
23}
24
26 : HelmholtzFluidProperties(parameters),
27 _Mh2(2.01588e-3),
28 _p_critical(1.315e6),
29 _T_critical(33.19),
30 _rho_molar_critical(15.508),
31 _rho_critical(1000.0 * _rho_molar_critical * _Mh2),
32 _p_triple(7.7e3),
33 _T_triple(13.952)
34{
35}
36
37std::string
39{
40 return "hydrogen";
41}
42
43Real
45{
46 return _Mh2;
47}
48
49Real
54
55Real
60
61Real
66
67Real
72
73Real
78
79Real
80HydrogenFluidProperties::mu_from_rho_T(Real density, Real temperature) const
81{
82 // Scaled variables
83 const Real Tstar = temperature / 30.41;
84 const Real logTstar = std::log(Tstar);
85 const Real Tr = temperature / _T_critical;
86 const Real rhor = density / 90.5;
87
88 // Ideal gas component
89 Real sum = 0.0;
90 for (std::size_t i = 0; i < _amu.size(); ++i)
91 sum += _amu[i] * MathUtils::pow(logTstar, i);
92
93 const Real mu0 =
94 0.021357 * std::sqrt(1000.0 * _Mh2 * temperature) / (0.297 * 0.297 * std::exp(sum));
95
96 // The excess contribution due to density
97 Real sumr = 0.0;
98 for (std::size_t i = 0; i < _bmu.size(); ++i)
99 sumr += _bmu[i];
100
101 const Real mu1 = MathUtils::pow(0.297, 3) * sumr * mu0 / Tstar;
102
103 // The viscosity is then
104 const Real mu =
105 mu0 + mu1 * density +
106 _cmu[0] * rhor * rhor *
107 std::exp(_cmu[1] * Tr + _cmu[2] / Tr + _cmu[3] * rhor * rhor / (_cmu[4] + Tr) +
108 _cmu[5] * MathUtils::pow(rhor, 6));
109
110 return mu * 1.0e-6;
111}
112
113void
115 Real temperature,
116 Real ddensity_dT,
117 Real & mu,
118 Real & dmu_drho,
119 Real & dmu_dT) const
120{
121 // Scaled variables
122 const Real Tstar = temperature / 30.41;
123 const Real logTstar = std::log(Tstar);
124 const Real Tr = temperature / _T_critical;
125 const Real rhor = density / 90.5;
126 const Real drhor_drho = 1.0 / 90.5;
127 const Real dTr_dT = 1.0 / _T_critical;
128
129 // The dilute gas component
130 Real sum = 0.0, dsum_dT = 0.0;
131 for (std::size_t i = 0; i < _amu.size(); ++i)
132 {
133 sum += _amu[i] * MathUtils::pow(logTstar, i);
134 dsum_dT += i * _amu[i] * MathUtils::pow(logTstar, i) / (temperature * logTstar);
135 }
136
137 const Real mu0 =
138 0.021357 * std::sqrt(1000.0 * _Mh2 * temperature) / (0.297 * 0.297 * std::exp(sum));
139 const Real dmu0_dT = 21.357 * _Mh2 * (1.0 - 2.0 * temperature * dsum_dT) * std::exp(-sum) /
140 (2.0 * std::sqrt(1000.0 * _Mh2 * temperature) * 0.297 * 0.297);
141
142 // The excess contribution due to density
143 Real sumr = 0.0;
144 for (std::size_t i = 0; i < _bmu.size(); ++i)
145 sumr += _bmu[i];
146
147 const Real mu1 = MathUtils::pow(0.297, 3) * sumr * mu0 / Tstar;
148 const Real dmu1_dT =
149 MathUtils::pow(0.297, 3) * sumr * (dmu0_dT / Tstar - mu0 / (30.41 * Tstar * Tstar));
150
151 // The viscosity and derivatives are then
152 const Real exponent = _cmu[1] * Tr + _cmu[2] / Tr + _cmu[3] * rhor * rhor / (_cmu[4] + Tr) +
153 _cmu[5] * MathUtils::pow(rhor, 6);
154 const Real dexponent_drho =
155 (2.0 * _cmu[3] * rhor / (_cmu[4] + Tr) + 6.0 * _cmu[5] * MathUtils::pow(rhor, 5)) *
156 drhor_drho;
157 const Real dexponent_dT =
158 (_cmu[1] - _cmu[2] / Tr / Tr - _cmu[3] * rhor * rhor / (_cmu[4] + Tr) / (_cmu[4] + Tr)) *
159 dTr_dT;
160
161 mu = (mu0 + mu1 * density + _cmu[0] * rhor * rhor * std::exp(exponent)) * 1.0e-6;
162 dmu_drho =
163 (mu1 + _cmu[0] * rhor * std::exp(exponent) * (2.0 * drhor_drho + rhor * dexponent_drho)) *
164 1.0e-6;
165 dmu_dT =
166 (dmu0_dT + density * dmu1_dT + _cmu[0] * rhor * rhor * dexponent_dT * std::exp(exponent)) *
167 1.0e-6 +
168 dmu_drho * ddensity_dT;
169}
170
171Real
172HydrogenFluidProperties::mu_from_p_T(Real pressure, Real temperature) const
173{
174 // Require density first
175 const Real density = rho_from_p_T(pressure, temperature);
176 return mu_from_rho_T(density, temperature);
177}
178
179void
181 Real pressure, Real temperature, Real & mu, Real & dmu_dp, Real & dmu_dT) const
182{
183 Real rho, drho_dp, drho_dT;
184 rho_from_p_T(pressure, temperature, rho, drho_dp, drho_dT);
185
186 Real dmu_drho;
187 mu_from_rho_T(rho, temperature, drho_dT, mu, dmu_drho, dmu_dT);
188 dmu_dp = dmu_drho * drho_dp;
189}
190
191void
193 Real temperature,
194 Real & rho,
195 Real & mu) const
196{
197 rho = rho_from_p_T(pressure, temperature);
198 mu = mu_from_rho_T(rho, temperature);
199}
200
201void
203 Real temperature,
204 Real & rho,
205 Real & drho_dp,
206 Real & drho_dT,
207 Real & mu,
208 Real & dmu_dp,
209 Real & dmu_dT) const
210{
211 rho_from_p_T(pressure, temperature, rho, drho_dp, drho_dT);
212 Real dmu_drho;
213 mu_from_rho_T(rho, temperature, drho_dT, mu, dmu_drho, dmu_dT);
214 dmu_dp = dmu_drho * drho_dp;
215}
216
217Real
218HydrogenFluidProperties::k_from_rho_T(Real density, Real temperature) const
219{
220 // // Scaled variables
221 const Real Tr = temperature / 33.145;
222 const Real rhor = density / 31.262;
223
224 // The ideal gas component
225 Real sum1 = 0.0;
226 for (std::size_t i = 0; i < _a1k.size(); ++i)
227 sum1 += _a1k[i] * MathUtils::pow(Tr, i);
228
229 Real sum2 = 0.0;
230 for (std::size_t i = 0; i < _a2k.size(); ++i)
231 sum2 += _a2k[i] * MathUtils::pow(Tr, i);
232
233 const Real lambda0 = sum1 / sum2;
234
235 // The excess contribution due to density
236 Real lambdah = 0.0;
237 for (std::size_t i = 0; i < _b1k.size(); ++i)
238 lambdah += (_b1k[i] + _b2k[i] * Tr) * MathUtils::pow(rhor, i + 1);
239
240 // The critical enhancement
241 const Real lambdac = 6.24e-4 / (-2.58e-7 + std::abs(Tr - 1.0)) *
242 std::exp(-MathUtils::pow(0.837 * (rhor - 1.0), 2));
243
244 // The thermal conductivity
245 return lambda0 + lambdah + lambdac;
246}
247
248Real
249HydrogenFluidProperties::k_from_p_T(Real pressure, Real temperature) const
250{
251 // Require density first
252 const Real density = rho_from_p_T(pressure, temperature);
253 return k_from_rho_T(density, temperature);
254}
255
256void
258 Real pressure, Real temperature, Real & k, Real & dk_dp, Real & dk_dT) const
259{
260 k = this->k_from_p_T(pressure, temperature);
261 // Calculate derivatives using finite differences
262 const Real eps = 1.0e-6;
263 const Real peps = pressure * eps;
264 const Real Teps = temperature * eps;
265
266 dk_dp = (this->k_from_p_T(pressure + peps, temperature) - k) / peps;
267 dk_dT = (this->k_from_p_T(pressure, temperature + Teps) - k) / Teps;
268}
269
270std::vector<Real>
272{
273 return {-4.73284, 6.08954, 6.06066};
274}
275
276Real
278{
279 if (temperature < _T_triple || temperature > _T_critical)
280 throw MooseException("Temperature is out of range in " + name() + ": vaporPressure()");
281
282 const Real Tr = temperature / _T_critical;
283 const Real theta = 1.0 - Tr;
284
285 const Real logpressure = (-4.89789 * theta + 0.988588 * std::pow(theta, 1.5) +
286 0.349689 * Utility::pow<2>(theta) + 0.499356 * std::pow(theta, 2.85)) /
287 Tr;
288
289 return _p_critical * std::exp(logpressure);
290}
291
292void
293HydrogenFluidProperties::vaporPressure(Real, Real &, Real &) const
294{
295 mooseError("vaporPressure() is not implemented");
296}
297
298Real
299HydrogenFluidProperties::alpha(Real delta, Real tau) const
300{
301 // Ideal gas component of the Helmholtz free energy
302 Real alpha0 = std::log(delta) + 1.5 * std::log(tau) - 1.4579856475 + 1.888076782 * tau;
303
304 for (std::size_t i = 0; i < _a.size(); ++i)
305 alpha0 += _a[i] * std::log(1.0 - std::exp(_b[i] * tau));
306
307 // Residual component of the Helmholtz free energy
308 Real alphar = 0.0;
309
310 for (std::size_t i = 0; i < _t1.size(); ++i)
311 alphar += _N1[i] * MathUtils::pow(delta, _d1[i]) * std::pow(tau, _t1[i]);
312
313 for (std::size_t i = 0; i < _t2.size(); ++i)
314 alphar += _N2[i] * MathUtils::pow(delta, _d2[i]) * std::pow(tau, _t2[i]) * std::exp(-delta);
315
316 for (std::size_t i = 0; i < _t3.size(); ++i)
317 alphar += _N3[i] * MathUtils::pow(delta, _d3[i]) * std::pow(tau, _t3[i]) *
318 std::exp(_phi3[i] * Utility::pow<2>(delta - _D3[i]) +
319 _beta3[i] * Utility::pow<2>(tau - _gamma3[i]));
320
321 // The Helmholtz free energy is the sum of these two
322 return alpha0 + alphar;
323}
324
325Real
326HydrogenFluidProperties::dalpha_ddelta(Real delta, Real tau) const
327{
328 // Ideal gas component of the Helmholtz free energy
329 Real dalpha0 = 1.0 / delta;
330
331 // Residual component of the Helmholtz free energy
332 Real dalphar = 0.0;
333
334 for (std::size_t i = 0; i < _t1.size(); ++i)
335 dalphar += _N1[i] * _d1[i] * MathUtils::pow(delta, _d1[i]) * std::pow(tau, _t1[i]);
336
337 for (std::size_t i = 0; i < _t2.size(); ++i)
338 dalphar += _N2[i] * MathUtils::pow(delta, _d2[i]) * std::pow(tau, _t2[i]) * std::exp(-delta) *
339 (_d2[i] - delta);
340
341 for (std::size_t i = 0; i < _t3.size(); ++i)
342 dalphar += _N3[i] * MathUtils::pow(delta, _d3[i]) * std::pow(tau, _t3[i]) *
343 std::exp(_phi3[i] * Utility::pow<2>(delta - _D3[i]) +
344 _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
345 (_d3[i] + delta * (2.0 * _phi3[i] * (delta - _D3[i])));
346
347 // The Helmholtz free energy is the sum of these two
348 return dalpha0 + dalphar / delta;
349}
350
351Real
352HydrogenFluidProperties::dalpha_dtau(Real delta, Real tau) const
353{
354 // Ideal gas component of the Helmholtz free energy
355 Real dalpha0 = 1.5 / tau + 1.888076782;
356
357 for (std::size_t i = 0; i < _a.size(); ++i)
358 dalpha0 += _a[i] * _b[i] * (1.0 - 1.0 / (1.0 - std::exp(_b[i] * tau)));
359
360 // Residual component of the Helmholtz free energy
361 Real dalphar = 0.0;
362
363 for (std::size_t i = 0; i < _t1.size(); ++i)
364 dalphar += _N1[i] * _t1[i] * MathUtils::pow(delta, _d1[i]) * std::pow(tau, _t1[i]);
365
366 for (std::size_t i = 0; i < _t2.size(); ++i)
367 dalphar +=
368 _N2[i] * _t2[i] * MathUtils::pow(delta, _d2[i]) * std::pow(tau, _t2[i]) * std::exp(-delta);
369
370 for (std::size_t i = 0; i < _t3.size(); ++i)
371 dalphar += _N3[i] * MathUtils::pow(delta, _d3[i]) * std::pow(tau, _t3[i]) *
372 std::exp(_phi3[i] * Utility::pow<2>(delta - _D3[i]) +
373 _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
374 (_t3[i] + tau * (2.0 * _beta3[i] * (tau - _gamma3[i])));
375
376 // The Helmholtz free energy is the sum of these two
377 return dalpha0 + dalphar / tau;
378}
379
380Real
382{
383 // Ideal gas component of the Helmholtz free energy
384 Real dalpha0 = -1.0 / delta / delta;
385
386 // Residual component of the Helmholtz free energy
387 Real dalphar = 0.0;
388
389 for (std::size_t i = 0; i < _t1.size(); ++i)
390 dalphar +=
391 _N1[i] * _d1[i] * (_d1[i] - 1.0) * MathUtils::pow(delta, _d1[i]) * std::pow(tau, _t1[i]);
392
393 for (std::size_t i = 0; i < _t2.size(); ++i)
394 dalphar += _N2[i] * MathUtils::pow(delta, _d2[i]) * std::pow(tau, _t2[i]) * std::exp(-delta) *
395 (delta * delta - 2.0 * _d2[i] * delta + _d2[i] * (_d2[i] - 1.0));
396
397 for (std::size_t i = 0; i < _t3.size(); ++i)
398 dalphar += _N3[i] * MathUtils::pow(delta, _d3[i]) * std::pow(tau, _t3[i]) *
399 std::exp(_phi3[i] * Utility::pow<2>(delta - _D3[i]) +
400 _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
401 (_d3[i] * _d3[i] +
402 2.0 * delta * delta * _phi3[i] *
403 (1.0 + 2.0 * _phi3[i] * (_D3[i] - delta) * (_D3[i] - delta)) +
404 _d3[i] * (4.0 * delta * _phi3[i] * (delta - _D3[i]) - 1.0));
405
406 // The Helmholtz free energy is the sum of these two
407 return dalpha0 + dalphar / delta / delta;
408}
409
410Real
411HydrogenFluidProperties::d2alpha_dtau2(Real delta, Real tau) const
412{
413 // Ideal gas component of the Helmholtz free energy
414 Real dalpha0 = -1.5 / tau / tau;
415
416 for (std::size_t i = 0; i < _a.size(); ++i)
417 {
418 Real exptau = std::exp(_b[i] * tau);
419 dalpha0 -= _a[i] * (_b[i] * _b[i] * exptau / (1.0 - exptau) * (exptau / (1.0 - exptau) + 1.0));
420 }
421
422 // Residual component of the Helmholtz free energy
423 Real dalphar = 0.0;
424
425 for (std::size_t i = 0; i < _t1.size(); ++i)
426 dalphar +=
427 _N1[i] * _t1[i] * (_t1[i] - 1.0) * MathUtils::pow(delta, _d1[i]) * std::pow(tau, _t1[i]);
428
429 for (std::size_t i = 0; i < _t2.size(); ++i)
430 dalphar += _N2[i] * _t2[i] * (_t2[i] - 1.0) * MathUtils::pow(delta, _d2[i]) *
431 std::pow(tau, _t2[i]) * std::exp(-delta);
432
433 for (std::size_t i = 0; i < _t3.size(); ++i)
434 dalphar += _N3[i] * MathUtils::pow(delta, _d3[i]) * std::pow(tau, _t3[i]) *
435 std::exp(_phi3[i] * Utility::pow<2>(delta - _D3[i]) +
436 _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
437 (_t3[i] * _t3[i] +
438 2.0 * _beta3[i] * tau * tau *
439 (1.0 + 2.0 * _beta3[i] * MathUtils::pow(tau - _gamma3[i], 2)) -
440 _t3[i] * (1.0 + 4.0 * _beta3[i] * tau * (tau - _gamma3[i])));
441
442 // The Helmholtz free energy is the sum of these two
443 return dalpha0 + dalphar / tau / tau;
444}
445
446Real
448{
449 // Residual component of the Helmholtz free energy
450 Real dalphar = 0.0;
451
452 for (std::size_t i = 0; i < _t1.size(); ++i)
453 dalphar += _N1[i] * _d1[i] * _t1[i] * std::pow(delta, _d1[i]) * std::pow(tau, _t1[i]);
454
455 for (std::size_t i = 0; i < _t2.size(); ++i)
456 dalphar += _N2[i] * _t2[i] * std::pow(delta, _d2[i]) * std::pow(tau, _t2[i]) *
457 std::exp(-delta) * (_d2[i] - delta);
458
459 for (std::size_t i = 0; i < _t3.size(); ++i)
460 dalphar += _N3[i] * std::pow(delta, _d3[i]) * std::pow(tau, _t3[i]) *
461 std::exp(_phi3[i] * Utility::pow<2>(delta - _D3[i]) +
462 _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
463 (_d3[i] + delta * (2.0 * _phi3[i] * (delta - _D3[i]))) *
464 (_t3[i] + 2.0 * _beta3[i] * tau * (tau - _gamma3[i]));
465
466 // The Helmholtz free energy is the sum of these two
467 return dalphar / delta / tau;
468}
const double mu
const double rho
registerMooseObject("FluidPropertiesApp", HydrogenFluidProperties)
const std::string name
Definition Setup.h:21
Base class equation of state for fluids that use a Helmholtz free energy alpha(delta,...
static InputParameters validParams()
virtual Real rho_from_p_T(Real pressure, Real temperature) const override
Hydrogen (H2) fluid properties as a function of pressure (Pa) and temperature (K).
const std::array< Real, 5 > _a
Coefficients for ideal gas component of the Helmholtz free energy.
const std::array< Real, 2 > _N2
const std::array< Real, 4 > _a2k
const Real _Mh2
Hydrogen molar mass (kg/mol)
virtual Real molarMass() const override
Molar mass [kg/mol].
const std::array< Real, 5 > _D3
const std::array< Real, 5 > _b2k
virtual Real criticalPressure() const override
Critical pressure.
virtual Real criticalTemperature() const override
Critical temperature.
virtual Real criticalDensity() const override
Critical density.
const std::array< Real, 6 > _cmu
const std::array< Real, 2 > _t2
virtual Real dalpha_dtau(Real delta, Real tau) const override
Derivative of Helmholtz free energy wrt tau.
virtual Real mu_from_rho_T(Real density, Real temperature) const override
const std::array< unsigned int, 5 > _d3
const std::array< Real, 5 > _N3
virtual Real dalpha_ddelta(Real delta, Real tau) const override
Derivative of Helmholtz free energy wrt delta.
virtual Real vaporPressure(Real temperature) const override
Vapor pressure.
const std::array< Real, 7 > _bmu
virtual void rho_mu_from_p_T(Real pressure, Real temperature, Real &rho, Real &mu) const override
Combined methods.
virtual std::string fluidName() const override
Fluid name.
const std::array< Real, 5 > _b1k
virtual Real triplePointPressure() const override
Triple point pressure.
virtual Real alpha(Real delta, Real tau) const override
Helmholtz free energy for H2 From Leachman et al (reference above)
const Real _p_critical
Critical pressure (Pa)
const Real _rho_critical
Critical density (kg/m^3)
const std::array< Real, 5 > _gamma3
const std::array< Real, 5 > _phi3
const std::array< Real, 7 > _a1k
Coefficients for thermal conductivity.
virtual Real mu_from_p_T(Real pressure, Real temperature) const override
virtual Real d2alpha_ddelta2(Real delta, Real tau) const override
Second derivative of Helmholtz free energy wrt delta.
const Real _p_triple
Triple point pressure (Pa)
virtual Real d2alpha_ddeltatau(Real delta, Real tau) const override
Second derivative of Helmholtz free energy wrt delta and tau.
const std::array< Real, 5 > _t3
const std::array< unsigned int, 7 > _d1
const Real _T_triple
Triple point temperature (K)
virtual Real d2alpha_dtau2(Real delta, Real tau) const override
Second derivative of Helmholtz free energy wrt tau.
const std::array< Real, 7 > _t1
const std::array< Real, 7 > _N1
Coefficients for residual component of the Helmholtz free energy.
virtual Real k_from_rho_T(Real density, Real temperature) const override
const std::array< Real, 5 > _amu
Coefficients for viscosity.
HydrogenFluidProperties(const InputParameters &parameters)
virtual std::vector< Real > henryCoefficients() const override
Henry's law coefficients for dissolution in water.
const std::array< unsigned int, 2 > _d2
const Real _T_critical
Critical temperature (K)
static InputParameters validParams()
const std::array< Real, 5 > _beta3
virtual Real k_from_p_T(Real pressure, Real temperature) const override
virtual Real triplePointTemperature() const override
Triple point temperature.
const std::array< Real, 5 > _b
void addClassDescription(const std::string &doc_string)
void mooseError(Args &&... args) const
T pow(T x, int e)