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.2964e6),
29 _T_critical(33.145),
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 if (i > 0)
135 dsum_dT += i * _amu[i] * MathUtils::pow(logTstar, i - 1) / temperature;
136 }
137
138 const Real mu0 =
139 0.021357 * std::sqrt(1000.0 * _Mh2 * temperature) / (0.297 * 0.297 * std::exp(sum));
140 const Real dmu0_dT = 21.357 * _Mh2 * (1.0 - 2.0 * temperature * dsum_dT) * std::exp(-sum) /
141 (2.0 * std::sqrt(1000.0 * _Mh2 * temperature) * 0.297 * 0.297);
142
143 // The excess contribution due to density
144 Real sumr = 0.0;
145 for (std::size_t i = 0; i < _bmu.size(); ++i)
146 sumr += _bmu[i];
147
148 const Real mu1 = MathUtils::pow(0.297, 3) * sumr * mu0 / Tstar;
149 const Real dmu1_dT =
150 MathUtils::pow(0.297, 3) * sumr * (dmu0_dT / Tstar - mu0 / (30.41 * Tstar * Tstar));
151
152 // The viscosity and derivatives are then
153 const Real exponent = _cmu[1] * Tr + _cmu[2] / Tr + _cmu[3] * rhor * rhor / (_cmu[4] + Tr) +
154 _cmu[5] * MathUtils::pow(rhor, 6);
155 const Real dexponent_drho =
156 (2.0 * _cmu[3] * rhor / (_cmu[4] + Tr) + 6.0 * _cmu[5] * MathUtils::pow(rhor, 5)) *
157 drhor_drho;
158 const Real dexponent_dT =
159 (_cmu[1] - _cmu[2] / Tr / Tr - _cmu[3] * rhor * rhor / (_cmu[4] + Tr) / (_cmu[4] + Tr)) *
160 dTr_dT;
161
162 mu = (mu0 + mu1 * density + _cmu[0] * rhor * rhor * std::exp(exponent)) * 1.0e-6;
163 dmu_drho =
164 (mu1 + _cmu[0] * rhor * std::exp(exponent) * (2.0 * drhor_drho + rhor * dexponent_drho)) *
165 1.0e-6;
166 dmu_dT =
167 (dmu0_dT + density * dmu1_dT + _cmu[0] * rhor * rhor * dexponent_dT * std::exp(exponent)) *
168 1.0e-6 +
169 dmu_drho * ddensity_dT;
170}
171
172Real
173HydrogenFluidProperties::mu_from_p_T(Real pressure, Real temperature) const
174{
175 // Require density first
176 const Real density = rho_from_p_T(pressure, temperature);
177 return mu_from_rho_T(density, temperature);
178}
179
180void
182 Real pressure, Real temperature, Real & mu, Real & dmu_dp, Real & dmu_dT) const
183{
184 Real rho, drho_dp, drho_dT;
185 rho_from_p_T(pressure, temperature, rho, drho_dp, drho_dT);
186
187 Real dmu_drho;
188 mu_from_rho_T(rho, temperature, drho_dT, mu, dmu_drho, dmu_dT);
189 dmu_dp = dmu_drho * drho_dp;
190}
191
192void
194 Real temperature,
195 Real & rho,
196 Real & mu) const
197{
198 rho = rho_from_p_T(pressure, temperature);
199 mu = mu_from_rho_T(rho, temperature);
200}
201
202void
204 Real temperature,
205 Real & rho,
206 Real & drho_dp,
207 Real & drho_dT,
208 Real & mu,
209 Real & dmu_dp,
210 Real & dmu_dT) const
211{
212 rho_from_p_T(pressure, temperature, rho, drho_dp, drho_dT);
213 Real dmu_drho;
214 mu_from_rho_T(rho, temperature, drho_dT, mu, dmu_drho, dmu_dT);
215 dmu_dp = dmu_drho * drho_dp;
216}
217
218Real
219HydrogenFluidProperties::k_from_rho_T(Real density, Real temperature) const
220{
221 // // Scaled variables
222 const Real Tr = temperature / 33.145;
223 const Real rhor = density / 31.262;
224
225 // The ideal gas component
226 Real sum1 = 0.0;
227 for (std::size_t i = 0; i < _a1k.size(); ++i)
228 sum1 += _a1k[i] * MathUtils::pow(Tr, i);
229
230 Real sum2 = 0.0;
231 for (std::size_t i = 0; i < _a2k.size(); ++i)
232 sum2 += _a2k[i] * MathUtils::pow(Tr, i);
233
234 const Real lambda0 = sum1 / sum2;
235
236 // The excess contribution due to density
237 Real lambdah = 0.0;
238 for (std::size_t i = 0; i < _b1k.size(); ++i)
239 lambdah += (_b1k[i] + _b2k[i] * Tr) * MathUtils::pow(rhor, i + 1);
240
241 // The critical enhancement
242 const Real lambdac = 6.24e-4 / (-2.58e-7 + std::abs(Tr - 1.0)) *
243 std::exp(-MathUtils::pow(0.837 * (rhor - 1.0), 2));
244
245 // The thermal conductivity
246 return lambda0 + lambdah + lambdac;
247}
248
249Real
250HydrogenFluidProperties::k_from_p_T(Real pressure, Real temperature) const
251{
252 // Require density first
253 const Real density = rho_from_p_T(pressure, temperature);
254 return k_from_rho_T(density, temperature);
255}
256
257void
259 Real pressure, Real temperature, Real & k, Real & dk_dp, Real & dk_dT) const
260{
261 k = this->k_from_p_T(pressure, temperature);
262 // Calculate derivatives using finite differences
263 const Real eps = 1.0e-6;
264 const Real peps = pressure * eps;
265 const Real Teps = temperature * eps;
266
267 dk_dp = (this->k_from_p_T(pressure + peps, temperature) - k) / peps;
268 dk_dT = (this->k_from_p_T(pressure, temperature + Teps) - k) / Teps;
269}
270
271std::vector<Real>
273{
274 return {-4.73284, 6.08954, 6.06066};
275}
276
277Real
279{
280 if (temperature < _T_triple || temperature > _T_critical)
281 throw MooseException("Temperature is out of range in " + name() + ": vaporPressure()");
282
283 const Real Tr = temperature / _T_critical;
284 const Real theta = 1.0 - Tr;
285
286 const Real logpressure = (-4.89789 * theta + 0.988588 * std::pow(theta, 1.5) +
287 0.349689 * Utility::pow<2>(theta) + 0.499356 * std::pow(theta, 2.85)) /
288 Tr;
289
290 return _p_critical * std::exp(logpressure);
291}
292
293void
294HydrogenFluidProperties::vaporPressure(Real, Real &, Real &) const
295{
296 mooseError("vaporPressure() is not implemented");
297}
298
299Real
300HydrogenFluidProperties::alpha(Real delta, Real tau) const
301{
302 // Ideal gas component of the Helmholtz free energy
303 Real alpha0 = std::log(delta) + 1.5 * std::log(tau) - 1.4579856475 + 1.888076782 * tau;
304
305 for (std::size_t i = 0; i < _a.size(); ++i)
306 alpha0 += _a[i] * std::log(1.0 - std::exp(_b[i] * tau));
307
308 // Residual component of the Helmholtz free energy
309 Real alphar = 0.0;
310
311 for (std::size_t i = 0; i < _t1.size(); ++i)
312 alphar += _N1[i] * MathUtils::pow(delta, _d1[i]) * std::pow(tau, _t1[i]);
313
314 for (std::size_t i = 0; i < _t2.size(); ++i)
315 alphar += _N2[i] * MathUtils::pow(delta, _d2[i]) * std::pow(tau, _t2[i]) * std::exp(-delta);
316
317 for (std::size_t i = 0; i < _t3.size(); ++i)
318 alphar += _N3[i] * MathUtils::pow(delta, _d3[i]) * std::pow(tau, _t3[i]) *
319 std::exp(_phi3[i] * Utility::pow<2>(delta - _D3[i]) +
320 _beta3[i] * Utility::pow<2>(tau - _gamma3[i]));
321
322 // The Helmholtz free energy is the sum of these two
323 return alpha0 + alphar;
324}
325
326Real
327HydrogenFluidProperties::dalpha_ddelta(Real delta, Real tau) const
328{
329 // Ideal gas component of the Helmholtz free energy
330 Real dalpha0 = 1.0 / delta;
331
332 // Residual component of the Helmholtz free energy
333 Real dalphar = 0.0;
334
335 for (std::size_t i = 0; i < _t1.size(); ++i)
336 dalphar += _N1[i] * _d1[i] * MathUtils::pow(delta, _d1[i]) * std::pow(tau, _t1[i]);
337
338 for (std::size_t i = 0; i < _t2.size(); ++i)
339 dalphar += _N2[i] * MathUtils::pow(delta, _d2[i]) * std::pow(tau, _t2[i]) * std::exp(-delta) *
340 (_d2[i] - delta);
341
342 for (std::size_t i = 0; i < _t3.size(); ++i)
343 dalphar += _N3[i] * MathUtils::pow(delta, _d3[i]) * std::pow(tau, _t3[i]) *
344 std::exp(_phi3[i] * Utility::pow<2>(delta - _D3[i]) +
345 _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
346 (_d3[i] + delta * (2.0 * _phi3[i] * (delta - _D3[i])));
347
348 // The Helmholtz free energy is the sum of these two
349 return dalpha0 + dalphar / delta;
350}
351
352Real
353HydrogenFluidProperties::dalpha_dtau(Real delta, Real tau) const
354{
355 // Ideal gas component of the Helmholtz free energy
356 Real dalpha0 = 1.5 / tau + 1.888076782;
357
358 for (std::size_t i = 0; i < _a.size(); ++i)
359 dalpha0 += _a[i] * _b[i] * (1.0 - 1.0 / (1.0 - std::exp(_b[i] * tau)));
360
361 // Residual component of the Helmholtz free energy
362 Real dalphar = 0.0;
363
364 for (std::size_t i = 0; i < _t1.size(); ++i)
365 dalphar += _N1[i] * _t1[i] * MathUtils::pow(delta, _d1[i]) * std::pow(tau, _t1[i]);
366
367 for (std::size_t i = 0; i < _t2.size(); ++i)
368 dalphar +=
369 _N2[i] * _t2[i] * MathUtils::pow(delta, _d2[i]) * std::pow(tau, _t2[i]) * std::exp(-delta);
370
371 for (std::size_t i = 0; i < _t3.size(); ++i)
372 dalphar += _N3[i] * MathUtils::pow(delta, _d3[i]) * std::pow(tau, _t3[i]) *
373 std::exp(_phi3[i] * Utility::pow<2>(delta - _D3[i]) +
374 _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
375 (_t3[i] + tau * (2.0 * _beta3[i] * (tau - _gamma3[i])));
376
377 // The Helmholtz free energy is the sum of these two
378 return dalpha0 + dalphar / tau;
379}
380
381Real
383{
384 // Ideal gas component of the Helmholtz free energy
385 Real dalpha0 = -1.0 / delta / delta;
386
387 // Residual component of the Helmholtz free energy
388 Real dalphar = 0.0;
389
390 for (std::size_t i = 0; i < _t1.size(); ++i)
391 dalphar +=
392 _N1[i] * _d1[i] * (_d1[i] - 1.0) * MathUtils::pow(delta, _d1[i]) * std::pow(tau, _t1[i]);
393
394 for (std::size_t i = 0; i < _t2.size(); ++i)
395 dalphar += _N2[i] * MathUtils::pow(delta, _d2[i]) * std::pow(tau, _t2[i]) * std::exp(-delta) *
396 (delta * delta - 2.0 * _d2[i] * delta + _d2[i] * (_d2[i] - 1.0));
397
398 for (std::size_t i = 0; i < _t3.size(); ++i)
399 dalphar += _N3[i] * MathUtils::pow(delta, _d3[i]) * std::pow(tau, _t3[i]) *
400 std::exp(_phi3[i] * Utility::pow<2>(delta - _D3[i]) +
401 _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
402 (_d3[i] * _d3[i] +
403 2.0 * delta * delta * _phi3[i] *
404 (1.0 + 2.0 * _phi3[i] * (_D3[i] - delta) * (_D3[i] - delta)) +
405 _d3[i] * (4.0 * delta * _phi3[i] * (delta - _D3[i]) - 1.0));
406
407 // The Helmholtz free energy is the sum of these two
408 return dalpha0 + dalphar / delta / delta;
409}
410
411Real
412HydrogenFluidProperties::d2alpha_dtau2(Real delta, Real tau) const
413{
414 // Ideal gas component of the Helmholtz free energy
415 Real dalpha0 = -1.5 / tau / tau;
416
417 for (std::size_t i = 0; i < _a.size(); ++i)
418 {
419 Real exptau = std::exp(_b[i] * tau);
420 dalpha0 -= _a[i] * (_b[i] * _b[i] * exptau / (1.0 - exptau) * (exptau / (1.0 - exptau) + 1.0));
421 }
422
423 // Residual component of the Helmholtz free energy
424 Real dalphar = 0.0;
425
426 for (std::size_t i = 0; i < _t1.size(); ++i)
427 dalphar +=
428 _N1[i] * _t1[i] * (_t1[i] - 1.0) * MathUtils::pow(delta, _d1[i]) * std::pow(tau, _t1[i]);
429
430 for (std::size_t i = 0; i < _t2.size(); ++i)
431 dalphar += _N2[i] * _t2[i] * (_t2[i] - 1.0) * MathUtils::pow(delta, _d2[i]) *
432 std::pow(tau, _t2[i]) * std::exp(-delta);
433
434 for (std::size_t i = 0; i < _t3.size(); ++i)
435 dalphar += _N3[i] * MathUtils::pow(delta, _d3[i]) * std::pow(tau, _t3[i]) *
436 std::exp(_phi3[i] * Utility::pow<2>(delta - _D3[i]) +
437 _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
438 (Utility::pow<2>(_t3[i] + 2.0 * _beta3[i] * tau * (tau - _gamma3[i])) - _t3[i] +
439 2.0 * _beta3[i] * tau * tau);
440
441 // The Helmholtz free energy is the sum of these two
442 return dalpha0 + dalphar / tau / tau;
443}
444
445Real
447{
448 // Residual component of the Helmholtz free energy
449 Real dalphar = 0.0;
450
451 for (std::size_t i = 0; i < _t1.size(); ++i)
452 dalphar += _N1[i] * _d1[i] * _t1[i] * std::pow(delta, _d1[i]) * std::pow(tau, _t1[i]);
453
454 for (std::size_t i = 0; i < _t2.size(); ++i)
455 dalphar += _N2[i] * _t2[i] * std::pow(delta, _d2[i]) * std::pow(tau, _t2[i]) *
456 std::exp(-delta) * (_d2[i] - delta);
457
458 for (std::size_t i = 0; i < _t3.size(); ++i)
459 dalphar += _N3[i] * std::pow(delta, _d3[i]) * std::pow(tau, _t3[i]) *
460 std::exp(_phi3[i] * Utility::pow<2>(delta - _D3[i]) +
461 _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
462 (_d3[i] + delta * (2.0 * _phi3[i] * (delta - _D3[i]))) *
463 (_t3[i] + 2.0 * _beta3[i] * tau * (tau - _gamma3[i]));
464
465 // The Helmholtz free energy is the sum of these two
466 return dalphar / delta / tau;
467}
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)