https://mooseframework.inl.gov
Loading...
Searching...
No Matches
IdealGasMixtureFluidProperties.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
14
18#define define_mass_specific_prop_from_p_T(prop) \
19 Real IdealGasMixtureFluidProperties::prop##_from_p_T( \
20 Real p, Real T, const std::vector<Real> & x_secondary) const \
21 { \
22 const auto x = secondaryToAllMassFractions(x_secondary); \
23 mooseAssert(x.size() == _n_components, "Size mismatch"); \
24 \
25 Real z = 0; \
26 for (const auto i : make_range(_n_components)) \
27 z += x[i] * _component_fps[i]->prop##_from_p_T(p, T); \
28 \
29 return z; \
30 } \
31 ADReal IdealGasMixtureFluidProperties::prop##_from_p_T( \
32 const ADReal & p, const ADReal & T, const std::vector<ADReal> & x_secondary) const \
33 { \
34 const auto x = secondaryToAllMassFractions(x_secondary); \
35 mooseAssert(x.size() == _n_components, "Size mismatch"); \
36 \
37 ADReal z = 0; \
38 for (const auto i : make_range(_n_components)) \
39 z += x[i] * _component_fps[i]->prop##_from_p_T(p, T); \
40 \
41 return z; \
42 }
43
47#define define_transport_prop_from_p_T(prop) \
48 Real IdealGasMixtureFluidProperties::prop##_from_p_T( \
49 Real p, Real T, const std::vector<Real> & x_secondary) const \
50 { \
51 const auto x = secondaryToAllMassFractions(x_secondary); \
52 const auto psi = molarFractionsFromMassFractions(x); \
53 mooseAssert(psi.size() == _n_components, "Size mismatch"); \
54 \
55 Real y = 0; \
56 for (const auto i : make_range(_n_components)) \
57 y += psi[i] * _component_fps[i]->prop##_from_p_T(p, T); \
58 \
59 return y; \
60 } \
61 ADReal IdealGasMixtureFluidProperties::prop##_from_p_T( \
62 const ADReal & p, const ADReal & T, const std::vector<ADReal> & x_secondary) const \
63 { \
64 const auto x = secondaryToAllMassFractions(x_secondary); \
65 const auto psi = molarFractionsFromMassFractions(x); \
66 mooseAssert(psi.size() == _n_components, "Size mismatch"); \
67 \
68 ADReal y = 0; \
69 for (const auto i : make_range(_n_components)) \
70 y += psi[i] * _component_fps[i]->prop##_from_p_T(p, T); \
71 \
72 return y; \
73 }
74
75// clang-format off
81
82define_transport_prop_from_p_T(mu)
83define_transport_prop_from_p_T(k)
84
85#undef define_mass_specific_prop_from_p_T
86#undef define_transport_prop_from_p_T
87
89// clang-format on
90{
92 params += NaNInterface::validParams();
93
94 params.addClassDescription("Class for fluid properties of an ideal gas mixture");
95
96 params.addRequiredParam<std::vector<UserObjectName>>(
97 "component_fluid_properties",
98 "Name of component fluid properties user objects. The first entry should be the primary "
99 "component.");
100
101 return params;
102}
103
105 : VaporMixtureFluidProperties(parameters),
106 NaNInterface(this),
107 _component_fp_names(getParam<std::vector<UserObjectName>>("component_fluid_properties")),
108 _n_components(_component_fp_names.size()),
109 _n_secondary_components(_n_components - 1)
110{
111 if (_n_components == 0)
112 mooseError("There must be at least one entry in 'component_fluid_properties'.");
113
115 for (const auto i : make_range(_n_components))
116 {
117 const auto & single_phase_fp =
118 getUserObjectByName<SinglePhaseFluidProperties>(_component_fp_names[i]);
119 _component_fps[i] = dynamic_cast<const IdealGasFluidProperties *>(&single_phase_fp);
120 if (!_component_fps[i])
122 "Each entry in 'component_fluid_properties' must have type 'IdealGasFluidProperties'.");
123 }
124}
125
131
134{
135 mooseAssert(i < getNumberOfSecondaryVapors(), "Requested secondary index too high.");
136 return *_component_fps[i + 1];
137}
138
139template <typename CppType>
140std::vector<CppType>
142 const std::vector<CppType> & x_secondary) const
143{
144 mooseAssert(x_secondary.size() == _n_secondary_components, "Size mismatch");
145
146 CppType sum = 0;
147 for (const auto i : make_range(_n_secondary_components))
148 sum += x_secondary[i];
149
150 const CppType x_primary = 1.0 - sum;
151
152 std::vector<CppType> x;
153 x.push_back(x_primary);
154 x.insert(x.end(), x_secondary.begin(), x_secondary.end());
155
156 return x;
157}
158
159std::vector<ADReal>
161 const std::vector<ADReal> & x_secondary) const
162{
163 return secondaryToAllMassFractions_templ(x_secondary);
164}
165
166std::vector<Real>
168 const std::vector<Real> & x_secondary) const
169{
170 return secondaryToAllMassFractions_templ(x_secondary);
171}
172
173template <typename CppType>
174CppType
176{
177 mooseAssert(x.size() == _n_components, "Size mismatch");
178
179 CppType sum = 0;
180 for (const auto i : make_range(_n_components))
181 sum += x[i] / _component_fps[i]->molarMass();
182
183 return 1.0 / sum;
184}
185
186ADReal
187IdealGasMixtureFluidProperties::mixtureMolarMass(const std::vector<ADReal> & x) const
188{
190}
191
192Real
194{
196}
197
198template <typename CppType>
199CppType
201{
202 mooseAssert(x.size() == _n_components, "Size mismatch");
203
204 CppType cp_mix = 0, cv_mix = 0;
205 for (const auto i : make_range(_n_components))
206 {
207 // cp and cv are constant due to ideal gas assumption; any (p, T) is fine:
208 cp_mix += x[i] * _component_fps[i]->cp_from_p_T(0, 0);
209 cv_mix += x[i] * _component_fps[i]->cv_from_p_T(0, 0);
210 }
211
212 return cp_mix / cv_mix;
213}
214
215ADReal
217{
219}
220
221Real
226
227template <typename CppType>
228std::vector<CppType>
230 const std::vector<CppType> & x) const
231{
232 mooseAssert(x.size() == _n_components, "Size mismatch");
233
234 const auto M = mixtureMolarMass(x);
235 std::vector<CppType> psi(_n_components);
236 for (const auto i : make_range(_n_components))
237 psi[i] = x[i] * M / _component_fps[i]->molarMass();
238
239 return psi;
240}
241
242std::vector<ADReal>
247
248std::vector<Real>
253
254ADReal
255IdealGasMixtureFluidProperties::rho_from_p_T(const ADReal & p,
256 const ADReal & T,
257 const std::vector<ADReal> & x_secondary) const
258{
259 return 1.0 / v_from_p_T(p, T, x_secondary);
260}
261
262Real
263IdealGasMixtureFluidProperties::rho_from_p_T(Real p,
264 Real T,
265 const std::vector<Real> & x_secondary) const
266{
267 return 1.0 / v_from_p_T(p, T, x_secondary);
268}
269
270template <typename CppType>
271CppType
272IdealGasMixtureFluidProperties::e_from_p_rho_templ(const CppType & p,
273 const CppType & rho,
274 const std::vector<CppType> & x_secondary) const
275{
276 const auto x = secondaryToAllMassFractions(x_secondary);
277 mooseAssert(x.size() == _n_components, "Size mismatch");
278
279 const auto M = mixtureMolarMass(x);
280
281 CppType e_ref_sum = 0;
282 CppType cv_sum = 0;
283 for (const auto i : make_range(_n_components))
284 {
285 e_ref_sum += x[i] * _component_fps[i]->referenceSpecificInternalEnergy();
286 // cv is constant due to ideal gas assumption; any (p, T) is fine:
287 cv_sum += x[i] * _component_fps[i]->cv_from_p_T(0, 0);
288 }
289
290 return cv_sum * M * p / (_R * rho) + e_ref_sum;
291}
292
293ADReal
294IdealGasMixtureFluidProperties::e_from_p_rho(const ADReal & p,
295 const ADReal & rho,
296 const std::vector<ADReal> & x_secondary) const
297{
298 return e_from_p_rho_templ(p, rho, x_secondary);
299}
300
301Real
302IdealGasMixtureFluidProperties::e_from_p_rho(Real p,
303 Real rho,
304 const std::vector<Real> & x_secondary) const
305{
306 return e_from_p_rho_templ(p, rho, x_secondary);
307}
308
309template <typename CppType>
310CppType
311IdealGasMixtureFluidProperties::p_from_v_e_templ(const CppType & v,
312 const CppType & e,
313 const std::vector<CppType> & x_secondary) const
314{
315 const auto x = secondaryToAllMassFractions(x_secondary);
316 const auto M = mixtureMolarMass(x);
317
318 return _R * T_from_v_e(v, e, x_secondary) / (M * v);
319}
320
321ADReal
322IdealGasMixtureFluidProperties::p_from_v_e(const ADReal & v,
323 const ADReal & e,
324 const std::vector<ADReal> & x_secondary) const
325{
326 return p_from_v_e_templ(v, e, x_secondary);
327}
328
329Real
330IdealGasMixtureFluidProperties::p_from_v_e(Real v,
331 Real e,
332 const std::vector<Real> & x_secondary) const
333{
334 return p_from_v_e_templ(v, e, x_secondary);
335}
336
337template <typename CppType>
338CppType
339IdealGasMixtureFluidProperties::T_from_v_e_templ(const CppType & /*v*/,
340 const CppType & e,
341 const std::vector<CppType> & x_secondary) const
342{
343 const auto x = secondaryToAllMassFractions(x_secondary);
344 mooseAssert(x.size() == _n_components, "Size mismatch");
345
346 CppType e_ref_sum = 0;
347 CppType cv_sum = 0;
348 for (const auto i : make_range(_n_components))
349 {
350 e_ref_sum += x[i] * _component_fps[i]->referenceSpecificInternalEnergy();
351 // cv is constant due to ideal gas assumption; any (p, T) is fine:
352 cv_sum += x[i] * _component_fps[i]->cv_from_p_T(0, 0);
353 }
354
355 return (e - e_ref_sum) / cv_sum;
356}
357
358ADReal
359IdealGasMixtureFluidProperties::T_from_v_e(const ADReal & v,
360 const ADReal & e,
361 const std::vector<ADReal> & x_secondary) const
362{
363 return T_from_v_e_templ(v, e, x_secondary);
364}
365
366Real
367IdealGasMixtureFluidProperties::T_from_v_e(Real v,
368 Real e,
369 const std::vector<Real> & x_secondary) const
370{
371 return T_from_v_e_templ(v, e, x_secondary);
372}
373
374template <typename CppType>
375CppType
376IdealGasMixtureFluidProperties::c_from_p_T_templ(const CppType & /*p*/,
377 const CppType & T,
378 const std::vector<CppType> & x_secondary) const
379{
380 using std::sqrt;
381
382 const auto x = secondaryToAllMassFractions(x_secondary);
383 const auto M = mixtureMolarMass(x);
384 const auto gamma = mixtureSpecificHeatRatio(x);
385
386 return sqrt(gamma * _R * T / M);
387}
388
389ADReal
390IdealGasMixtureFluidProperties::c_from_p_T(const ADReal & p,
391 const ADReal & T,
392 const std::vector<ADReal> & x_secondary) const
393{
394 return c_from_p_T_templ(p, T, x_secondary);
395}
396
397Real
398IdealGasMixtureFluidProperties::c_from_p_T(Real p,
399 Real T,
400 const std::vector<Real> & x_secondary) const
401{
402 return c_from_p_T_templ(p, T, x_secondary);
403}
DualNumber< Real, DNDerivativeType, true > ADReal
const std::vector< double > x
const double M
const double mu
const Real p
const double rho
const double T
const double v
define_mass_specific_prop_from_p_T(v)
registerMooseObject("FluidPropertiesApp", IdealGasMixtureFluidProperties)
static const Real _R
Universal gas constant (J/mol/K)
Ideal gas fluid properties Default parameters are for air at atmospheric pressure and temperature.
Class for fluid properties of an ideal gas mixture.
std::vector< ADReal > secondaryToAllMassFractions(const std::vector< ADReal > &x_secondary) const
std::vector< CppType > molarFractionsFromMassFractions_templ(const std::vector< CppType > &x) const
Computes molar fractions.
CppType mixtureMolarMass_templ(const std::vector< CppType > &x) const
Computes the mixture molar mass.
virtual const SinglePhaseFluidProperties & getPrimaryFluidProperties() const override
Gets the primary component single-phase fluid properties.
ADReal mixtureMolarMass(const std::vector< ADReal > &x) const
ADReal mixtureSpecificHeatRatio(const std::vector< ADReal > &x) const
IdealGasMixtureFluidProperties(const InputParameters &parameters)
std::vector< CppType > secondaryToAllMassFractions_templ(const std::vector< CppType > &x_secondary) const
Computes all mass fractions.
const unsigned int _n_secondary_components
Number of secondary components.
std::vector< ADReal > molarFractionsFromMassFractions(const std::vector< ADReal > &x) const
const std::vector< UserObjectName > _component_fp_names
Names of component fluid properties.
static InputParameters validParams()
std::vector< const IdealGasFluidProperties * > _component_fps
Component fluid properties objects.
virtual const SinglePhaseFluidProperties & getSecondaryFluidProperties(unsigned int i=0) const override
Gets a secondary component single-phase fluid properties.
const unsigned int _n_components
Number of components.
CppType mixtureSpecificHeatRatio_templ(const std::vector< CppType > &x) const
Computes the mixture specific heat ratio.
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void mooseError(Args &&... args) const
Interface class for producing errors, warnings, or just quiet NaNs.
static InputParameters validParams()
Common class for single phase fluid properties.
Base class for fluid properties of vapor mixtures.
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)