Alamo
Mixture_Averaged.H
Go to the documentation of this file.
1#ifndef MODEL_GAS_TRANSPORT_MIXTURE_AVERAGED_H_
2#define MODEL_GAS_TRANSPORT_MIXTURE_AVERAGED_H_
3
4#include <vector>
5#include <memory>
6#include "IO/ParmParse.H"
9
10// Type: 0,1 determines if per species viscosity and thermal conductivity are
11// constant (type=0) or computed using kinetic theory (type=1)
12// Either way, mixture averaging is used to compute the mixture values
13//
14// For kinetic theory: Chapman-Enskog is used to compute viscosity
15// and Eucken relation used to compute conductivity
16
17
18// dynamic viscosity, mu, computed using Chapman-Enskog theory
19//
20// 5E20 sqrt(pi * m * kb * T)
21// mu = ----------------------------
22// 16 pi σ^2 Ω
23//
24// MW
25// where m = -- (mass per particle), MW: molecular weight, NA: Avogadro's number, kb: Boltzman constant
26// NA
27//
28// σ: Lennard-Jones collision diameter in Angstroms, Ω: collision integral
29
30
31// thermal conductivity coefficient, k, computed using Eucken relation
32//
33// k = mu * (cp + 1.25R), where cp and R are both per kg
34//
35
36namespace Model {
37namespace Gas {
38namespace Transport {
39
40class Mixture_Averaged // public Transport
41{
42public:
43 static constexpr const char* name = "mixture_averaged";
44
45private:
47 double Rg;
48 std::vector<double> MW;
50 std::string type;
51 std::vector<double> val1; // constant viscosity mu or Lennard-Jones collision diameter depending on type
52 std::vector<double> val2; // constant thermal conductivity or Lennard-Jones potential well depth depending on type
53
54public:
59
60 static void Parse( Mixture_Averaged & value, IO::ParmParse & pp,
61 int a_nspecies, std::vector<double> &a_MW, Thermo::Thermo<Thermo::CpConstant> a_thermo)
62 {
63 value.nspecies = a_nspecies;
64 value.MW = a_MW;
65 value.thermo = a_thermo;
66
67 // Compute individual species transport properties as "constant" or from "LJ" (Lennard-Jones) theory
68 pp.query_validate("type", value.type, {"constant", "LJ"});
69 if (value.type == "constant")
70 {
71 // Dynamic viscosity if type=constant
72 pp.queryarr_required("mu", value.val1, Unit::Pressure() * Unit::Time());
73 // Thermal conductivity if type=constant
75 }
76 else if (value.type == "LJ")
77 {
78 // Lennard-Jones diameter if type=LJ
79 pp.queryarr_required("LJdiameter", value.val1, Unit::Length());
80 // Lennard-Jones well depth if type=LJ
81 pp.queryarr_required("LJwelldepth", value.val2, Unit::Temperature());
82 }
83 else
84 {
85 Util::Abort(INFO, "Unrecognized type for transport model ", value.type);
86 }
87 //pp.query_default("P_1atm", value.P_1atm, "1_atm", Unit::Pressure());
88
89 Util::Assert(INFO, TEST(value.val1.size() == (size_t)value.nspecies));
90 Util::Assert(INFO, TEST(value.val2.size() == (size_t)value.nspecies));
91 }
92
93private:
94 double collision_integral(double Tstar) const {
95 double S = 1.16145 * pow(Tstar, -0.14874)
96 + 0.52487 / exp(0.77320 * Tstar)
97 + 2.16178 / exp(2.43787 * Tstar);
98 return S;
99 }
100 double mu_enskog(double T, int i) const {
101 return 2.669570e-6 * sqrt(MW[i] * T) / (val1[i] * val1[i] * collision_integral(T / val2[i]));
102 }
103 double k_eucken(double T, Set::Patch<const Set::Scalar>& X, int i, int j, int k, int n) const
104 {
105 double cp = thermo.cp_mol(T, X, i, j, k);
106 return mu_enskog(T, n) * (X(i, j, k, n) * cp + 1.25 * Rg) / MW[n];
107 }
108
109public:
110 double dynamic_viscosity(double T, Set::Patch<const Set::Scalar>& X, int i, int j, int k) const
111 {
112 // Wilke's Average: Dynamic viscosity, Pa-s
113 double mu_mix = 0.0;
114 if ( type == "constant" )
115 {
116 // dynamic viscosity, mu, is constant per species
117 for (int a = 0; a < nspecies; ++a) {
118 double mua = val1[a];
119 double MWa = MW[a];
120 double phi = 0.0;
121 for (int b = 0; b < nspecies; ++b) {
122 double mub = val1[b];
123 double MWb = MW[b];
124 double ratio = pow(MWb / MWa, 0.25);
125 double mu_ratio = sqrt(mua / mub);
126 double term = sqrt(1.0 + MWa / MWb);
127 phi += X(i,j,k,b) * pow(1.0 + mu_ratio * ratio, 2.0) / (sqrt(8.0) * term);
128 }
129 mu_mix += X(i, j, k, a) * mua / phi;
130 }
131 }
132 else if ( type == "LJ" )
133 {
134 // dynamic viscosity, mu, computed by Chapman-Enskog per species
135 for (int a = 0; a < nspecies; ++a) {
136 double mua = mu_enskog(T, a);
137 double MWa = MW[a];
138 double phi = 0.0;
139 for (int b = 0; b < nspecies; ++b) {
140 double mub = mu_enskog(T, b);
141 double MWb = MW[b];
142 double ratio = pow(MWb / MWa, 0.25);
143 double mu_ratio = sqrt(mua / mub);
144 double term = sqrt(1.0 + MWa / MWb);
145 phi += X(i, j, k, b) * pow(1.0 + mu_ratio * ratio, 2.0) / (sqrt(8.0) * term);
146 }
147 mu_mix += X(i, j, k, a) * mua / phi;
148 }
149 }
150 else
151 {
152 Util::Abort(INFO, "[Transport::Mixture_Averaged] Unknown type.");
153 }
154
155 if (!(mu_mix == mu_mix) ) mu_mix = 0.0;
156 return mu_mix;
157 }
158
159 double thermal_conductivity(double T, Set::Patch<const Set::Scalar>& X, int i, int j, int k) const
160 {
161 // Wilke's Average: Thermal conductivity coefficient, W/(m-K)
162 double k_mix = 0.0;
163 if ( type == "constant" )
164 {
165 // thermal conductivity coefficient, k, is constant per species
166 for (int a = 0; a < nspecies; ++a) {
167 double mua = val1[a];
168 double MWa = MW[a];
169 double phi = 0.0;
170 for (int b = 0; b < nspecies; ++b) {
171 double mub = val1[b];
172 double MWb = MW[b];
173 double ratio = pow(MWb / MWa, 0.25);
174 double mu_ratio = sqrt(mua / mub);
175 double term = sqrt(1.0 + MWa / MWb);
176 phi += X(i, j, k, b) * pow(1.0 + mu_ratio * ratio, 2.0) / (sqrt(8.0) * term);
177 }
178 k_mix += X(i, j, k, a) * val2[a] / phi;
179 }
180 }
181 else if ( type == "LJ" )
182 {
183 // thermal conductivity coefficient, k, computed by Eucken relation per species
184 for (int a = 0; a < nspecies; ++a) {
185 double mua = mu_enskog(T, a);
186 double MWa = MW[a];
187 double phi = 0.0;
188 for (int b = 0; b < nspecies; ++b) {
189 double mub = mu_enskog(T, b);
190 double MWb = MW[b];
191 double ratio = pow(MWb / MWa, 0.25);
192 double mu_ratio = sqrt(mua / mub);
193 double term = sqrt(1.0 + MWa / MWb);
194 phi += X(i, j, k, b) * pow(1.0 + mu_ratio * ratio, 2.0) / (sqrt(8.0) * term);
195 }
196 k_mix += X(i, j, k, a) * k_eucken(T, X, i, j, k, a) / phi;
197 }
198 }
199 else
200 {
201 Util::Abort(INFO, "[Transport::Mixture_Averaged] Unknown type.");
202 }
203
204 return k_mix;
205 }
206
208 Set::Patch<Set::Scalar>& DKM, double T, double P,
209 Set::Patch<const Set::Scalar>& X, int i, int j, int k) const
210 {
211 // Mixture diffusion coefficients (Chapman–Enskog), m^2/s
212 for (int a = 0; a < nspecies; ++a) {
213 double sumD = 0.0;
214 for (int b = 0; b < nspecies; ++b) {
215 if (a == b) continue;
216
217 double sigmaAB = 0.5 * (val1[a] + val1[b]);
218 double epsAB = sqrt(val2[a] * val2[b]);
219 double Tstar = T / epsAB;
220
221 double omegaAB =
222 1.06036 / pow(Tstar, 0.15610) +
223 0.19300 / exp(0.47635 * Tstar) +
224 1.03587 / exp(1.52996 * Tstar) +
225 1.76474 / exp(3.89411 * Tstar);
226
227 double DAB =
228 0.0018583 * sqrt(T*T*T * (1.0 / MW[a] + 1.0 / MW[b])) /
229 ( (P / 101325.0) * sigmaAB*sigmaAB * omegaAB );
230 DAB /= 1.0e4;
231
232 sumD += X(i, j, k, b) / DAB;
233 }
234
235 DKM(i, j, k, a) = (1.0 - X(i, j, k ,a)) / sumD;
236 if (!(DKM(i, j, k, a) == DKM(i, j, k, a))) DKM(i, j, k, a) = 0.0; // NaN guard
237 }
238 }
239
240}; // class Mixture_Averaged
241
242} // namespace Transport
243} // namespace Gas
244} // namespace Model
245
246#endif
#define X(name)
#define TEST(x)
Definition Util.H:25
#define INFO
Definition Util.H:24
int queryarr_required(std::string name, std::vector< T > &value)
Definition ParmParse.H:643
int query_validate(std::string name, int &value, std::vector< int > possibleintvals)
Definition ParmParse.H:336
double dynamic_viscosity(double T, Set::Patch< const Set::Scalar > &X, int i, int j, int k) const
static constexpr const char * name
void diffusion_coeffs(Set::Patch< Set::Scalar > &DKM, double T, double P, Set::Patch< const Set::Scalar > &X, int i, int j, int k) const
double thermal_conductivity(double T, Set::Patch< const Set::Scalar > &X, int i, int j, int k) const
static void Parse(Mixture_Averaged &value, IO::ParmParse &pp, int a_nspecies, std::vector< double > &a_MW, Thermo::Thermo< Thermo::CpConstant > a_thermo)
double collision_integral(double Tstar) const
double mu_enskog(double T, int i) const
double k_eucken(double T, Set::Patch< const Set::Scalar > &X, int i, int j, int k, int n) const
Thermo::Thermo< Thermo::CpConstant > thermo
Set::Scalar Rg
Definition Set.cpp:14
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, 1 > Vector
Definition Base.H:21
void Abort(const char *msg)
Definition Util.cpp:268
AMREX_FORCE_INLINE void Assert(std::string file, std::string func, int line, std::string smt, bool pass, Args const &... args)
Definition Util.H:58
static Unit Time()
Definition Unit.H:199
static Unit Temperature()
Definition Unit.H:201
static Unit Pressure()
Definition Unit.H:217
static Unit Power()
Definition Unit.H:219
static Unit Length()
Definition Unit.H:198