27double Frot(
double tr,
double sqtr)
29 const double c1 = 0.5*sqrt(
Pi)*
Pi;
30 const double c2 = 0.25*
Pi*
Pi + 2.0;
31 const double c3 = sqrt(
Pi)*
Pi;
32 return 1.0 + c1*sqtr + c2*tr + c3*sqtr*tr;
43 m_a.resize(3*
m_nsp, 1.0);
44 m_b.resize(3*
m_nsp, 0.0);
47 m_frot_298.resize(
m_nsp);
48 m_rotrelax.resize(
m_nsp);
49 m_cinternal.resize(
m_nsp);
56 m_lmatrix_soln_ok =
false;
57 m_thermal_tlast =
Undef;
60 m_spwork1.resize(
m_nsp);
61 m_spwork2.resize(
m_nsp);
62 m_spwork3.resize(
m_nsp);
66 for (
size_t i = 0; i <
m_nsp; i++) {
67 for (
size_t j = i; j <
m_nsp; j++) {
69 m_log_eps_k(j,i) = m_log_eps_k(i,j);
75 const double sq298 = sqrt(298.0);
77 m_sqrt_eps_k.resize(
m_nsp);
78 for (
size_t k = 0; k <
m_nsp; k++) {
80 m_frot_298[k] =
Frot(
m_eps[k]/kb298, m_sqrt_eps_k[k]/sq298);
87 m_thermal_tlast =
Undef;
89 m_lmatrix_soln_ok =
false;
95 solveLMatrixEquation();
97 for (
size_t k = 0; k < 2*
m_nsp; k++) {
106 solveLMatrixEquation();
108 for (
size_t k = 0; k <
m_nsp; k++) {
113double MultiTransport::pressure_ig()
118void MultiTransport::solveLMatrixEquation()
123 if (m_lmatrix_soln_ok) {
130 for (
size_t k = 0; k <
m_nsp; k++) {
145 for (
size_t k = 0; k <
m_nsp; k++) {
146 if (!hasInternalModes(k)) {
147 m_b[2*
m_nsp + k] = 0.0;
168 solve(m_Lmatrix, m_a);
169 m_lmatrix_soln_ok =
true;
176 size_t ldx, span<const double> grad_X,
177 size_t ldf, span<double> fluxes)
180 throw CanteraError(
"MultiTransport::getSpeciesFluxes",
"ldx is too small");
183 throw CanteraError(
"MultiTransport::getSpeciesFluxes",
"ldf is too small");
185 checkArraySize(
"MultiTransport::getSpeciesFluxes: grad_T", grad_T.size(), ndim);
186 checkArraySize(
"MultiTransport::getSpeciesFluxes: grad_X", grad_X.size(), ldx * ndim);
187 checkArraySize(
"MultiTransport::getSpeciesFluxes: fluxes", fluxes.size(), ldf * ndim);
194 bool addThermalDiffusion =
false;
195 for (
size_t i = 0; i < ndim; i++) {
196 if (grad_T[i] != 0.0) {
197 addThermalDiffusion =
true;
200 if (addThermalDiffusion) {
207 for (
size_t i = 0; i <
m_nsp; i++) {
209 for (
size_t j = 0; j <
m_nsp; j++) {
220 double gradmax = -1.0;
221 for (
size_t j = 0; j <
m_nsp; j++) {
222 if (fabs(grad_X[j]) > gradmax) {
223 gradmax = fabs(grad_X[j]);
230 for (
size_t j = 0; j <
m_nsp; j++) {
233 vector<double> gsave(ndim), grx(ldx*
m_nsp);
234 for (
size_t n = 0; n < ldx*ndim; n++) {
239 for (
size_t n = 0; n < ndim; n++) {
240 auto gx = grad_X.subspan(ldx * n,
m_nsp);
241 auto fx = fluxes.subspan(ldf * n,
m_nsp);
242 std::copy(gx.begin(), gx.end(), fx.begin());
247 solve(m_aa, fluxes, ndim, ldf);
248 double pp = pressure_ig();
252 for (
size_t n = 0; n < ndim; n++) {
254 for (
size_t i = 0; i <
m_nsp; i++) {
255 fluxes[i +
offset] *= rho * y[i] / pp;
260 if (addThermalDiffusion) {
261 for (
size_t n = 0; n < ndim; n++) {
263 double grad_logt = grad_T[n]/
m_temp;
264 for (
size_t i = 0; i <
m_nsp; i++) {
272 span<const double> state2,
273 double delta, span<double> fluxes)
278 span<double> x1(m_spwork1);
279 span<double> x2(m_spwork2);
280 span<double> x3(m_spwork3);
284 double t1 = state1[0];
289 double t2 = state2[0];
292 double p = 0.5*(p1 + p2);
293 double t = 0.5*(state1[0] + state2[0]);
295 for (
size_t n = 0; n < nsp; n++) {
296 x3[n] = 0.5*(x1[n] + x2[n]);
307 bool addThermalDiffusion =
false;
308 if (state1[0] != state2[0]) {
309 addThermalDiffusion =
true;
315 for (
size_t i = 0; i <
m_nsp; i++) {
317 for (
size_t j = 0; j <
m_nsp; j++) {
328 double gradmax = -1.0;
329 for (
size_t j = 0; j <
m_nsp; j++) {
330 if (fabs(x2[j] - x1[j]) > gradmax) {
331 gradmax = fabs(x1[j] - x2[j]) / delta;
338 for (
size_t j = 0; j <
m_nsp; j++) {
340 fluxes[j] = (x2[j] - x1[j]) / delta;
347 double pp = pressure_ig();
350 for (
size_t i = 0; i <
m_nsp; i++) {
351 fluxes[i] *= rho * y[i] / pp;
355 if (addThermalDiffusion) {
356 double grad_logt = (t2 - t1) /
m_temp / delta;
357 for (
size_t i = 0; i <
m_nsp; i++) {
364 span<const double> state2,
const double delta, span<double> fluxes)
367 for (
size_t k = 0; k <
m_thermo->nSpecies(); k++) {
368 fluxes[k] /=
m_mw[k];
375 throw CanteraError(
"MultiTransport::getMultiDiffCoeffs",
"ld is too small");
378 double p = pressure_ig();
396 m_lmatrix_soln_ok =
false;
398 double prefactor = 16.0 *
m_temp
399 *
m_thermo->meanMolecularWeight()/(25.0 * p);
400 for (
size_t i = 0; i <
m_nsp; i++) {
401 for (
size_t j = 0; j <
m_nsp; j++) {
402 double c = prefactor/
m_mw[j];
404 (m_Lmatrix(i,j) - m_Lmatrix(i,i));
415 GasTransport::update_T();
418 m_lmatrix_soln_ok =
false;
427 for (
size_t k = 0; k <
m_nsp; k++) {
434 m_lmatrix_soln_ok =
false;
441 if (m_thermal_tlast ==
m_thermo->temperature()) {
449 for (
size_t i = 0; i <
m_nsp; i++) {
450 for (
size_t j = i; j <
m_nsp; j++) {
469 for (
size_t k = 0; k <
m_nsp; k++) {
471 double sqtr = m_sqrt_eps_k[k] /
m_sqrt_t;
472 m_rotrelax[k] = std::max(1.0,
m_zrot[k]) * m_frot_298[k]/
Frot(tr, sqtr);
476 for (
size_t k = 0; k <
m_nsp; k++) {
489 vector<double> cp(
m_thermo->nSpecies());
491 for (
size_t k = 0; k <
m_nsp; k++) {
492 m_cinternal[k] = cp[k] - 2.5;
494 m_thermal_tlast =
m_thermo->temperature();
500bool MultiTransport::hasInternalModes(
size_t j)
507 double prefactor = 16.0*
m_temp/25.0;
509 for (
size_t i = 0; i <
m_nsp; i++) {
513 for (
size_t k = 0; k <
m_nsp; k++) {
518 for (
size_t j = 0; j !=
m_nsp; ++j) {
519 m_Lmatrix(i,j) = prefactor * x[j]
523 m_Lmatrix(i,i) = 0.0;
529 double prefactor = 1.6*
m_temp;
530 for (
size_t j = 0; j <
m_nsp; j++) {
534 for (
size_t i = 0; i <
m_nsp; i++) {
535 m_Lmatrix(i,j +
m_nsp) = - prefactor * x[i] * xj *
m_mw[i] *
541 sum -= m_Lmatrix(i,j+
m_nsp);
543 m_Lmatrix(j,j+
m_nsp) += sum;
549 for (
size_t j = 0; j <
m_nsp; j++) {
550 for (
size_t i = 0; i <
m_nsp; i++) {
556void MultiTransport::eval_L1010(span<const double> x)
558 const double fiveover3pi = 5.0/(3.0*
Pi);
559 double prefactor = (16.0*
m_temp)/25.0;
561 for (
size_t j = 0; j <
m_nsp; j++) {
563 double constant1 = prefactor*x[j];
565 double constant2 = 13.75*wjsq;
566 double constant3 =
m_crot[j]/m_rotrelax[j];
567 double constant4 = 7.5*wjsq;
568 double fourmj = 4.0*
m_mw[j];
569 double threemjsq = 3.0*
m_mw[j]*
m_mw[j];
571 for (
size_t i = 0; i <
m_nsp; i++) {
573 double term1 =
m_bdiff(i,j) * sumwij*sumwij;
574 double term2 = fourmj*
m_astar(i,j)*(1.0 + fiveover3pi*
575 (constant3 + (
m_crot[i]/m_rotrelax[i])));
578 (constant2 - threemjsq*
m_bstar(i,j)
581 sum += x[i] /(term1) *
590void MultiTransport::eval_L1001(span<const double> x)
592 double prefactor = 32.00*
m_temp/(5.00*
Pi);
593 for (
size_t j = 0; j <
m_nsp; j++) {
595 if (hasInternalModes(j)) {
596 double constant = prefactor*
m_mw[j]*x[j]*
m_crot[j]/(m_cinternal[j]*m_rotrelax[j]);
598 for (
size_t i = 0; i <
m_nsp; i++) {
606 for (
size_t i = 0; i <
m_nsp; i++) {
613void MultiTransport::eval_L0001()
615 for (
size_t j = 0; j <
m_nsp; j++) {
616 for (
size_t i = 0; i <
m_nsp; i++) {
617 m_Lmatrix(i,j+2*
m_nsp) = 0.0;
622void MultiTransport::eval_L0100()
624 for (
size_t j = 0; j <
m_nsp; j++) {
625 for (
size_t i = 0; i <
m_nsp; i++) {
626 m_Lmatrix(i+2*
m_nsp,j) = 0.0;
631void MultiTransport::eval_L0110()
633 for (
size_t j = 0; j <
m_nsp; j++) {
634 for (
size_t i = 0; i <
m_nsp; i++) {
640void MultiTransport::eval_L0101(span<const double> x)
642 for (
size_t i = 0; i <
m_nsp; i++) {
643 if (hasInternalModes(i)) {
645 double constant1 = 4*
m_temp*x[i]/m_cinternal[i];
647 (5*
Pi*m_cinternal[i]*m_rotrelax[i]);
649 for (
size_t k = 0; k <
m_nsp; k++) {
651 double diff_int =
m_bdiff(i,k);
653 sum += x[k]/diff_int;
655 sum += x[k]*
m_astar(i,k)*constant2 / (
m_mw[k]*diff_int);
664 for (
size_t k = 0; k <
m_nsp; k++) {
ThermoPhase object for the ideal gas equation of state - workhorse for Cantera (see Thermodynamic Pro...
Interface for class MultiTransport.
Base class for exceptions thrown by Cantera classes.
void resize(size_t n, size_t m, double v=0.0) override
Resize the matrix.
vector< double > m_mw
Local copy of the species molecular weights.
vector< double > m_molefracs
Vector of species mole fractions.
double m_temp
Current value of the temperature [K] at which the properties in this object are calculated.
vector< double > m_eps
Lennard-Jones well-depth [J] of the species in the current phase.
virtual void updateDiff_T()
Update the binary diffusion coefficients.
DenseMatrix m_epsilon
The effective well depth [J] for (i,j) collisions.
vector< double > m_spwork
work space length = m_nsp
vector< double > m_zrot
Rotational relaxation number for each species.
int m_mode
Type of the polynomial fits to temperature.
double m_logt
Current value of the log of the temperature.
vector< double > m_visc
vector of species viscosities [Pa·s].
virtual void updateSpeciesViscosities()
Update the pure-species viscosities.
double m_sqrt_t
current value of temperature to 1/2 power
DenseMatrix m_bdiff
Matrix of binary diffusion coefficients at the reference pressure and the current temperature Size is...
vector< double > m_crot
Dimensionless rotational heat capacity of each species.
void invalidateCache() override
Invalidate any cached values which are normally updated only when a change in state is detected.
double m_kbt
Current value of Boltzmann constant times the temperature [J].
vector< vector< int > > m_star_poly_uses_actualT
Flag to indicate for which (i,j) interaction pairs the actual temperature is used instead of the redu...
vector< vector< double > > m_bstar_poly
Fit for bstar collision integral.
vector< vector< double > > m_astar_poly
Fit for astar collision integral.
vector< vector< int > > m_poly
Indices for the (i,j) interaction in collision integral fits.
void init(shared_ptr< ThermoPhase > thermo, int mode=0) override
Initialize a transport manager.
vector< vector< double > > m_cstar_poly
Fit for cstar collision integral.
bool m_l0000_ok
Boolean indicating viscosity is up to date.
void update_T() override
Update basic temperature-dependent quantities if the temperature has changed.
double thermalConductivity() override
Get the mixture thermal conductivity [W/m/K].
DenseMatrix m_astar
Dense matrix for astar.
void updateThermal_T()
Update the temperature-dependent terms needed to compute the thermal conductivity and thermal diffusi...
void eval_L0010(span< const double > x)
Evaluate the L0010 matrices.
vector< double > m_molefracs_last
Mole fraction vector from last L-matrix evaluation.
DenseMatrix m_cstar
Dense matrix for cstar.
void update_C() override
Update basic concentration-dependent quantities if the concentrations have changed.
void invalidateCache() override
Invalidate any cached values which are normally updated only when a change in state is detected.
void getThermalDiffCoeffs(span< double > dt) override
Return the thermal diffusion coefficients [kg/m/s].
void getMolarFluxes(span< const double > state1, span< const double > state2, const double delta, span< double > fluxes) override
Get the molar diffusional fluxes [kmol/m²/s] of the species, given the thermodynamic state at two nea...
void init(shared_ptr< ThermoPhase > thermo, int mode=0) override
Initialize a transport manager.
void getSpeciesFluxes(size_t ndim, span< const double > grad_T, size_t ldx, span< const double > grad_X, size_t ldf, span< double > fluxes) override
Get the species diffusive mass fluxes [kg/m²/s] with respect to the mass averaged velocity,...
void eval_L0000(span< const double > x)
Evaluate the L0000 matrices.
void getMassFluxes(span< const double > state1, span< const double > state2, double delta, span< double > fluxes) override
Get the mass diffusional fluxes [kg/m²/s] of the species, given the thermodynamic state at two nearby...
DenseMatrix m_bstar
Dense matrix for bstar.
void eval_L1000()
Evaluate the L1000 matrices.
void getMultiDiffCoeffs(const size_t ld, span< double > d) override
Return the multicomponent diffusion coefficients [m²/s].
shared_ptr< ThermoPhase > m_thermo
pointer to the object representing the phase
size_t m_nsp
Number of species in the phase.
ThermoPhase & thermo()
Phase object.
auto poly8(D x, const C &c)
Templated evaluation of a polynomial of order 8.
auto poly6(D x, const C &c)
Templated evaluation of a polynomial of order 6.
const double Boltzmann
Boltzmann constant [J/K].
const double GasConstant
Universal Gas Constant [J/kmol/K].
Namespace for the Cantera kernel.
const double Tiny
Small number to compare differences of mole fractions against.
const double Undef
Fairly random number to be used to initialize variables against to see if they are subsequently defin...
void solve(DenseMatrix &A, span< double > b, size_t nrhs, size_t ldb)
Solve Ax = b. Array b is overwritten on exit with x.
offset
Offsets of solution components in the 1D solution array.
static const double Min_C_Internal
Constant to compare dimensionless heat capacities against zero.
void invert(DenseMatrix &A, size_t nn)
invert A. A is overwritten with A^-1.
double Frot(double tr, double sqtr)
The Parker temperature correction to the rotational collision number.
void checkArraySize(const char *procedure, size_t available, size_t required)
Wrapper for throwing ArraySizeError.
Contains declarations for string manipulation functions within Cantera.
Various templated functions that carry out common vector and polynomial operations (see Templated Arr...