21#define COLL_INT_POLY_DEGREE 8
23GasTransport::GasTransport() :
28void GasTransport::update_T()
30 if (m_thermo->nSpecies() != m_nsp) {
32 init(m_thermo, m_mode);
35 double T = m_thermo->temperature();
43 m_sqrt_t = sqrt(m_temp);
44 m_t14 = sqrt(m_sqrt_t);
47 m_polytempvec[0] = 1.0;
48 m_polytempvec[1] = m_logt;
49 m_polytempvec[2] = m_logt*m_logt;
50 m_polytempvec[3] = m_logt*m_logt*m_logt;
51 m_polytempvec[4] = m_logt*m_logt*m_logt*m_logt;
77 for (
size_t k = 0; k <
m_nsp; k++) {
91 for (
size_t j = 0; j <
m_nsp; j++) {
92 for (
size_t k = j; k <
m_nsp; k++) {
109 for (
size_t k = 0; k <
m_nsp; k++) {
114 for (
size_t k = 0; k <
m_nsp; k++) {
129 for (
size_t i = 0; i <
m_nsp; i++) {
130 for (
size_t j = i; j <
m_nsp; j++) {
137 for (
size_t i = 0; i <
m_nsp; i++) {
138 for (
size_t j = i; j <
m_nsp; j++) {
157 throw CanteraError(
"GasTransport::getBinaryDiffCoeffs",
"ld is too small");
160 double rp = 1.0/
m_thermo->pressure();
161 for (
size_t i = 0; i <
m_nsp; i++) {
162 for (
size_t j = 0; j <
m_nsp; j++) {
163 d[ld*j + i] = rp *
m_bdiff(i,j);
179 double mmw =
m_thermo->meanMolecularWeight();
184 for (
size_t k = 0; k <
m_nsp; k++) {
186 for (
size_t j = 0; j <
m_nsp; j++) {
215 for (
size_t k = 0; k <
m_nsp; k++) {
217 for (
size_t j = 0; j <
m_nsp; j++) {
242 double mmw =
m_thermo->meanMolecularWeight();
248 for (
size_t k=0; k<
m_nsp; k++) {
251 for (
size_t i=0; i<
m_nsp; i++) {
260 d[k] = 1.0 / (sum1 + sum2);
288 for (
size_t j = 0; j <
m_nsp; j++) {
289 for (
size_t k = j; k <
m_nsp; k++) {
316 auto mw =
m_thermo->molecularWeights();
319 for (
size_t i = 0; i <
m_nsp; i++) {
324 double f_eps, f_sigma;
326 for (
size_t i = 0; i <
m_nsp; i++) {
327 for (
size_t j = i; j <
m_nsp; j++) {
370 double tstar_min = 1.e8, tstar_max = 0.0;
371 for (
size_t i = 0; i <
m_nsp; i++) {
372 for (
size_t j = i; j <
m_nsp; j++) {
388 integrals.
init(tstar_min, tstar_max);
396 for (
size_t k = 0; k <
m_thermo->nSpecies(); k++) {
397 shared_ptr<Species> s =
m_thermo->species(k);
402 "Missing gas-phase transport data for species '{}'.", s->name);
407 }
else if (sptran->
geometry ==
"linear") {
409 }
else if (sptran->
geometry ==
"nonlinear") {
419 if (s->input.hasKey(
"critical-parameters") &&
420 s->input[
"critical-parameters"].hasKey(
"acentric-factor"))
422 m_w_ac[k] = s->input[
"critical-parameters"][
"acentric-factor"].asDouble();
432 double& f_eps,
double& f_sigma)
443 size_t kp = (
m_polar[i] ? i : j);
444 size_t knp = (i == kp ? j : i);
445 double d3np, d3p, alpha_star, mu_p_star, xi;
448 alpha_star =
m_alpha[knp]/d3np;
450 xi = 1.0 + 0.25 * alpha_star * mu_p_star * mu_p_star *
452 f_sigma = pow(xi, -1.0/6.0);
460 vector<double> fitlist;
465 for (
size_t i = 0; i <
m_nsp; i++) {
466 for (
size_t j = i; j <
m_nsp; j++) {
475 auto dptr = find(fitlist.begin(), fitlist.end(), dstar);
476 if (dptr == fitlist.end()) {
477 vector<double> ca(degree+1), cb(degree+1), cc(degree+1);
478 vector<double> co22(degree+1);
479 integrals.fit(degree, dstar, ca, cb, cc);
480 integrals.fit_omega22(degree, dstar, co22);
487 fitlist.push_back(dstar);
490 m_poly[i][j] =
static_cast<int>((dptr - fitlist.begin()));
502 const size_t np = 50;
503 int degree = (
m_mode == CK_Mode ? 3 : 4);
505 vector<double> tlog(np), spvisc(np), spcond(np);
506 vector<double> w(np), w2(np);
512 for (
size_t n = 0; n < np; n++) {
513 double t =
m_thermo->minTemp() + dt*n;
518 vector<double> c(degree + 1), c2(degree + 1);
521 double visc, err, relerr,
522 mxerr = 0.0, mxrelerr = 0.0, mxerr_cond = 0.0, mxrelerr_cond = 0.0;
523 double T_save =
m_thermo->temperature();
524 auto mw =
m_thermo->molecularWeights();
525 for (
size_t k = 0; k <
m_nsp; k++) {
529 double fz_298 = 1.0 + pow(
Pi, 1.5) / sqrt(tstar) * (0.5 + 1.0 / tstar) +
530 (0.25 *
Pi *
Pi + 2) / tstar;
532 for (
size_t n = 0; n < np; n++) {
533 double t =
m_thermo->minTemp() + dt*n;
535 vector<double> cp_R_all(
m_thermo->nSpecies());
537 double cp_R = cp_R_all[k];
539 double sqrt_T = sqrt(t);
540 double om22 = integrals.omega22(tstar,
m_delta(k,k));
541 double om11 = integrals.omega11(tstar,
m_delta(k,k));
553 double f_int = mw[k]/(
GasConstant * t) * diffcoeff/visc;
554 double cv_rot =
m_crot[k];
555 double A_factor = 2.5 - f_int;
556 double fz_tstar = 1.0 + pow(
Pi, 1.5) / sqrt(tstar) * (0.5 + 1.0 / tstar) +
557 (0.25 *
Pi *
Pi + 2) / tstar;
558 double B_factor =
m_zrot[k] * fz_298 / fz_tstar + 2.0/
Pi * (5.0/3.0 * cv_rot + f_int);
559 double c1 = 2.0/
Pi * A_factor/B_factor;
560 double cv_int = cp_R - 2.5 - cv_rot;
561 double f_rot = f_int * (1.0 + c1);
562 double f_trans = 2.5 * (1.0 - c1 * cv_rot/1.5);
563 double cond = (visc/mw[k])*
GasConstant*(f_trans * 1.5
564 + f_rot * cv_rot + f_int * cv_int);
567 spvisc[n] = log(visc);
568 spcond[n] = log(cond);
578 spvisc[n] = sqrt(visc/sqrt_T);
583 spcond[n] = cond/sqrt_T;
584 w[n] = 1.0/(spvisc[n]*spvisc[n]);
585 w2[n] = 1.0/(spcond[n]*spcond[n]);
588 polyfit(degree, tlog, spvisc, w, c);
589 polyfit(degree, tlog, spcond, w2, c2);
592 for (
size_t n = 0; n < np; n++) {
595 val = exp(spvisc[n]);
596 fit = exp(
poly3(tlog[n], c));
598 double sqrt_T = exp(0.5*tlog[n]);
599 val = sqrt_T * pow(spvisc[n],2);
600 fit = sqrt_T * pow(
poly4(tlog[n], c),2);
604 mxerr = std::max(mxerr, fabs(err));
605 mxrelerr = std::max(mxrelerr, fabs(relerr));
611 for (
size_t n = 0; n < np; n++) {
614 val = exp(spcond[n]);
615 fit = exp(
poly3(tlog[n], c2));
617 double sqrt_T = exp(0.5*tlog[n]);
618 val = sqrt_T * spcond[n];
619 fit = sqrt_T *
poly4(tlog[n], c2);
623 mxerr_cond = std::max(mxerr_cond, fabs(err));
624 mxrelerr_cond = std::max(mxrelerr_cond, fabs(relerr));
638 const size_t np = 50;
639 int degree = (
m_mode == CK_Mode ? 3 : 4);
641 vector<double> tlog(np);
642 vector<double> w(np), w2(np);
645 for (
size_t n = 0; n < np; n++) {
646 double t =
m_thermo->minTemp() + dt*n;
651 vector<double> c(degree + 1), c2(degree + 1);
652 double err, relerr, mxerr = 0.0, mxrelerr = 0.0;
654 vector<double> diff(np + 1);
656 for (
size_t k = 0; k <
m_nsp; k++) {
657 for (
size_t j = k; j <
m_nsp; j++) {
658 for (
size_t n = 0; n < np; n++) {
659 double t =
m_thermo->minTemp() + dt*n;
662 double sigma =
m_diam(j,k);
663 double om11 = integrals.omega11(tstar,
m_delta(j,k));
665 * pow(
Boltzmann * t, 1.5) / (
Pi * sigma * sigma * om11);
673 diff[n] = log(diffcoeff);
676 diff[n] = diffcoeff/pow(t, 1.5);
677 w[n] = 1.0/(diff[n]*diff[n]);
680 polyfit(degree, tlog, diff, w, c);
682 for (
size_t n = 0; n < np; n++) {
686 fit = exp(
poly3(tlog[n], c));
688 double t = exp(tlog[n]);
689 double pre = pow(t, 1.5);
691 fit = pre *
poly4(tlog[n], c);
695 mxerr = std::max(mxerr, fabs(err));
696 mxrelerr = std::max(mxrelerr, fabs(relerr));
707 size_t k,
size_t j,
double xk,
double xj,
double& fkj,
double& fjk)
709 double w1 =
m_thermo->molecularWeight(k);
710 double w2 =
m_thermo->molecularWeight(j);
711 double wsum = w1 + w2;
712 double wmwp = (w1 - w2)/wsum;
713 double sqw12 = sqrt(w1*w2);
717 double sigratio = sig1*sig1/(sig2*sig2);
718 double sigratio2 = sig1*sig1/(sig12*sig12);
719 double sigratio3 = sig2*sig2/(sig12*sig12);
723 double om22_1 = integrals.omega22(tstar1,
m_delta(k,k));
724 double om22_2 = integrals.omega22(tstar2,
m_delta(j,j));
725 double om11_12 = integrals.omega11(tstar12,
m_delta(k,j));
726 double astar_12 = integrals.astar(tstar12,
m_delta(k,j));
727 double bstar_12 = integrals.bstar(tstar12,
m_delta(k,j));
728 double cstar_12 = integrals.cstar(tstar12,
m_delta(k,j));
730 double cnst = sigratio * sqrt(2.0*w2/wsum) * 2.0 * w1*w1/(wsum * w2);
731 double p1 = cnst * om22_1 / om11_12;
733 cnst = (1.0/sigratio) * sqrt(2.0*w1/wsum) * 2.0*w2*w2/(wsum*w1);
734 double p2 = cnst * om22_2 / om11_12;
735 double p12 = 15.0 * wmwp*wmwp + 8.0*w1*w2*astar_12/(wsum*wsum);
737 cnst = (2.0/(w2*wsum))*sqrt(2.0*w2/wsum)*sigratio2;
738 double q1 = cnst*((2.5 - 1.2*bstar_12)*w1*w1 + 3.0*w2*w2
739 + 1.6*w1*w2*astar_12);
741 cnst = (2.0/(w1*wsum))*sqrt(2.0*w1/wsum)*sigratio3;
742 double q2 = cnst*((2.5 - 1.2*bstar_12)*w2*w2 + 3.0*w1*w1
743 + 1.6*w1*w2*astar_12);
744 double q12 = wmwp*wmwp*15.0*(2.5 - 1.2*bstar_12)
745 + 4.0*w1*w2*astar_12*(11.0 - 2.4*bstar_12)/(wsum*wsum)
746 + 1.6*wsum*om22_1*om22_2/(om11_12*om11_12*sqw12)
747 * sigratio2 * sigratio3;
749 cnst = 6.0*cstar_12 - 5.0;
750 fkj = 1.0 + 0.1*cnst*cnst *
751 (p1*xk*xk + p2*xj*xj + p12*xk*xj)/
752 (q1*xk*xk + q2*xj*xj + q12*xk*xj);
753 fjk = 1.0 + 0.1*cnst*cnst *
754 (p2*xk*xk + p1*xj*xj + p12*xk*xj)/
755 (q2*xk*xk + q1*xj*xj + q12*xk*xj);
761 size_t N = (
m_mode == CK_Mode) ? 4 : 5;
762 checkArraySize(
"GasTransport::getViscosityPolynomial", coeffs.size(), N);
763 for (
size_t k = 0; k < N; k++) {
771 size_t N = (
m_mode == CK_Mode) ? 4 : 5;
772 checkArraySize(
"GasTransport::getConductivityPolynomial", coeffs.size(), N);
773 for (
size_t k = 0; k < N; k++) {
782 size_t N = (
m_mode == CK_Mode) ? 4 : 5;
783 checkArraySize(
"GasTransport::getBinDiffusivityPolynomial", coeffs.size(), N);
784 size_t mi = (j >= i? i : j);
785 size_t mj = (j >= i? j : i);
787 for (
size_t ii = 0; ii < mi; ii++) {
792 for (
size_t k = 0; k < N; k++) {
798 span<double> astar_coeffs,
799 span<double> bstar_coeffs,
800 span<double> cstar_coeffs)
const
805 checkArraySize(
"GasTransport::getCollisionIntegralPolynomial[astar]",
806 astar_coeffs.size(), N);
807 checkArraySize(
"GasTransport::getCollisionIntegralPolynomial[bstar]",
808 bstar_coeffs.size(), N);
809 checkArraySize(
"GasTransport::getCollisionIntegralPolynomial[cstar]",
810 cstar_coeffs.size(), N);
811 for (
size_t k = 0; k < N; k++) {
821 size_t N = (
m_mode == CK_Mode) ? 4 : 5;
822 checkArraySize(
"GasTransport::setViscosityPolynomial", coeffs.size(), N);
823 for (
size_t k = 0; k < N; k++) {
832 size_t N = (
m_mode == CK_Mode) ? 4 : 5;
833 checkArraySize(
"GasTransport::setConductivityPolynomial", coeffs.size(), N);
834 for (
size_t k = 0; k < N; k++) {
844 size_t N = (
m_mode == CK_Mode) ? 4 : 5;
845 checkArraySize(
"GasTransport::setBinDiffusivityPolynomial", coeffs.size(), N);
846 size_t mi = (j >= i? i : j);
847 size_t mj = (j >= i? j : i);
849 for (
size_t ii = 0; ii < mi; ii++) {
854 for (
size_t k = 0; k < N; k++) {
861 span<double> astar_coeffs, span<double> bstar_coeffs, span<double> cstar_coeffs,
867 checkArraySize(
"GasTransport::setCollisionIntegralPolynomial[astar]",
868 astar_coeffs.size(), N);
869 checkArraySize(
"GasTransport::setCollisionIntegralPolynomial[bstar]",
870 bstar_coeffs.size(), N);
871 checkArraySize(
"GasTransport::setCollisionIntegralPolynomial[cstar]",
872 cstar_coeffs.size(), N);
873 vector<double> ca(N), cb(N), cc(N);
875 for (
size_t k = 0; k < N; k++) {
876 ca[k] = astar_coeffs[k];
877 cb[k] = bstar_coeffs[k];
878 cc[k] = cstar_coeffs[k];
#define COLL_INT_POLY_DEGREE
polynomial degree used for fitting collision integrals except in CK mode, where the degree is 6.
Monchick and Mason collision integrals.
Declaration for class Cantera::Species.
Header file for class ThermoPhase, the base class for phases with thermodynamic properties,...
Base class for exceptions thrown by Cantera classes.
Transport data for a single gas-phase species which can be used in mixture-averaged or multicomponent...
double polarizability
The polarizability of the molecule [m³]. Default 0.0.
double diameter
The Lennard-Jones collision diameter [m].
double acentric_factor
Pitzer's acentric factor [dimensionless]. Default 0.0.
double quadrupole_polarizability
quadrupole. Default 0.0.
double rotational_relaxation
The rotational relaxation number (the number of collisions it takes to equilibrate the rotational deg...
double dispersion_coefficient
dispersion normalized by the square of the elementary charge. [m⁵] Default 0.0.
double dipole
The permanent dipole moment of the molecule [Coulomb-m]. Default 0.0.
double well_depth
The Lennard-Jones well depth [J].
string geometry
A string specifying the molecular geometry.
vector< bool > m_polar
Vector of booleans indicating whether a species is a polar molecule.
void getViscosityPolynomial(size_t i, span< double > coeffs) const override
Return the polynomial fits to the viscosity of species i.
virtual void getTransportData()
Read the transport database.
void getMixDiffCoeffsMole(span< double > d) override
Returns the mixture-averaged diffusion coefficients [m²/s].
virtual void setupCollisionParameters()
Setup parameters for a new kinetic-theory-based transport manager for low-density gases.
double m_t14
Current value of temperature to 1/4 power.
vector< double > m_mw
Local copy of the species molecular weights.
vector< double > m_molefracs
Vector of species mole fractions.
void setBinDiffusivityPolynomial(size_t i, size_t j, span< double > coeffs) override
Modify the polynomial fits to the binary diffusivity of species pair (i, j).
vector< double > m_quad_polar
Quadrupole polarizability.
double m_temp
Current value of the temperature [K] at which the properties in this object are calculated.
virtual void fitProperties(MMCollisionInt &integrals)
Generate polynomial fits to the viscosity and conductivity .
vector< vector< double > > m_visccoeffs
Polynomial fits to the viscosity of each species.
bool m_visc_ok
Update boolean for mixture rule for the mixture viscosity.
void getMixDiffCoeffsMass(span< double > d) override
Returns the mixture-averaged diffusion coefficients [m²/s].
DenseMatrix m_wratkj1
Holds square roots of molecular weight ratios.
virtual void fitDiffCoeffs(MMCollisionInt &integrals)
Generate polynomial fits to the binary diffusion coefficients.
void getCollisionIntegralPolynomial(size_t i, size_t j, span< double > astar_coeffs, span< double > bstar_coeffs, span< double > cstar_coeffs) const override
Return the polynomial fits to the collision integral of species pair (i, j).
vector< double > m_disp
Dispersion coefficient normalized by the square of the elementary charge [m⁵].
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.
vector< double > m_sqvisc
vector of square root of species viscosities.
DenseMatrix m_wratjk
Holds square roots of molecular weight ratios.
bool m_bindiff_ok
Update boolean for the binary diffusivities at unit pressure.
DenseMatrix m_epsilon
The effective well depth [J] for (i,j) collisions.
DenseMatrix m_diam
hard-sphere diameter [m] for (i,j) collision
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.
void fitCollisionIntegrals(MMCollisionInt &integrals)
Generate polynomial fits to collision integrals.
virtual void updateViscosity_T()
Update the temperature-dependent viscosity terms.
double m_viscmix
Internal storage for the viscosity of the mixture [Pa·s].
vector< double > m_sigma
Lennard-Jones diameter [m] of the species in the current phase.
bool m_spvisc_ok
Update boolean for the species viscosities.
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...
void setViscosityPolynomial(size_t i, span< double > coeffs) override
Modify the polynomial fits to the viscosity of species i.
vector< vector< double > > m_omega22_poly
Fit for omega22 collision integral.
vector< double > m_polytempvec
Powers of the ln temperature, up to fourth order.
DenseMatrix m_dipole
The effective dipole moment [Coulomb·m] for (i,j) collisions.
vector< double > m_crot
Dimensionless rotational heat capacity of each species.
vector< vector< double > > m_diffcoeffs
Polynomial fits to the binary diffusivity of each species.
void getBinaryDiffCoeffs(const size_t ld, span< double > d) override
Returns the matrix of binary diffusion coefficients [m²/s].
void getConductivityPolynomial(size_t i, span< double > coeffs) const override
Return the temperature fits of the heat conductivity of species i.
void invalidateCache() override
Invalidate any cached values which are normally updated only when a change in state is detected.
void setCollisionIntegralPolynomial(size_t i, size_t j, span< double > astar_coeffs, span< double > bstar_coeffs, span< double > cstar_coeffs, bool actualT) override
Modify the polynomial fits to the collision integral of species pair (i, j).
DenseMatrix m_reducedMass
This is the reduced mass [kg] of the interaction between species i and 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...
double viscosity() override
Get the viscosity [Pa·s] of the mixture.
vector< double > m_w_ac
Pitzer acentric factor [dimensionless].
vector< vector< double > > m_bstar_poly
Fit for bstar collision integral.
vector< vector< double > > m_astar_poly
Fit for astar collision integral.
void getMixDiffCoeffs(span< double > d) override
Returns the Mixture-averaged diffusion coefficients [m²/s].
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.
void getBinDiffusivityPolynomial(size_t i, size_t j, span< double > coeffs) const override
Return the polynomial fits to the binary diffusivity of species pair (i, j).
void setConductivityPolynomial(size_t i, span< double > coeffs) override
Modify the temperature fits of the heat conductivity of species i.
vector< vector< double > > m_condcoeffs
temperature fits of the heat conduction
bool m_viscwt_ok
Update boolean for the weighting factors for the mixture viscosity.
vector< vector< double > > m_cstar_poly
Fit for cstar collision integral.
vector< double > m_alpha
Polarizability [m³] of each species in the phase.
DenseMatrix m_delta
Reduced dipole moment of the interaction between two species.
DenseMatrix m_phi
Viscosity weighting function. size = m_nsp * m_nsp.
void setupCollisionIntegral()
Setup range for polynomial fits to collision integrals of Monchick & Mason monchick1961.
void makePolarCorrections(size_t i, size_t j, double &f_eps, double &f_sigma)
Corrections for polar-nonpolar binary diffusion coefficients.
void getBinDiffCorrection(double t, MMCollisionInt &integrals, size_t k, size_t j, double xk, double xj, double &fkj, double &fjk)
Second-order correction to the binary diffusion coefficients.
Calculation of Collision integrals.
void init(double tsmin, double tsmax)
Initialize the object for calculation.
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.
AnyMap m_fittingErrors
Maximum errors associated with fitting pure species transport properties.
virtual void invalidateCache()
Invalidate any cached values which are normally updated only when a change in state is detected.
size_t checkSpeciesIndex(size_t k) const
Check that the specified species index is in range.
This file contains definitions for utility functions and text for modules, inputfiles and logging,...
auto dot5(const X &x, const Y &y)
Templated Inner product of two vectors of length 5.
auto poly4(D x, const C &c)
Evaluates a polynomial of order 4.
auto poly3(D x, const C &c)
Templated evaluation of a polynomial of order 3.
auto dot4(const X &x, const Y &y)
Templated Inner product of two vectors of length 4.
double polyfit(size_t deg, span< const double > x, span< const double > y, span< const double > w, span< double > p)
Fits a polynomial function to a set of data points.
const double Boltzmann
Boltzmann constant [J/K].
const double Avogadro
Avogadro's Number [number/kmol].
const double epsilon_0
Permittivity of free space [F/m].
const double GasConstant
Universal Gas Constant [J/kmol/K].
Namespace for the Cantera kernel.
const double Undef
Fairly random number to be used to initialize variables against to see if they are subsequently defin...
void multiply(const DenseMatrix &A, span< const double > b, span< double > prod)
Multiply A*b and return the result in prod. Uses BLAS routine DGEMV.
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...