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");
159 double rp = 1.0/
m_thermo->pressure();
160 for (
size_t i = 0; i <
m_nsp; i++) {
161 for (
size_t j = 0; j <
m_nsp; j++) {
162 d[ld*j + i] = rp *
m_bdiff(i,j);
177 double mmw =
m_thermo->meanMolecularWeight();
182 for (
size_t k = 0; k <
m_nsp; k++) {
184 for (
size_t j = 0; j <
m_nsp; j++) {
212 for (
size_t k = 0; k <
m_nsp; k++) {
214 for (
size_t j = 0; j <
m_nsp; j++) {
238 double mmw =
m_thermo->meanMolecularWeight();
244 for (
size_t k=0; k<
m_nsp; k++) {
247 for (
size_t i=0; i<
m_nsp; i++) {
256 d[k] = 1.0 / (sum1 + sum2);
283 for (
size_t j = 0; j <
m_nsp; j++) {
284 for (
size_t k = j; k <
m_nsp; k++) {
311 const vector<double>& mw =
m_thermo->molecularWeights();
314 for (
size_t i = 0; i <
m_nsp; i++) {
319 double f_eps, f_sigma;
321 for (
size_t i = 0; i <
m_nsp; i++) {
322 for (
size_t j = i; j <
m_nsp; j++) {
365 double tstar_min = 1.e8, tstar_max = 0.0;
366 for (
size_t i = 0; i <
m_nsp; i++) {
367 for (
size_t j = i; j <
m_nsp; j++) {
383 integrals.
init(tstar_min, tstar_max);
391 for (
size_t k = 0; k <
m_thermo->nSpecies(); k++) {
392 shared_ptr<Species> s =
m_thermo->species(k);
397 "Missing gas-phase transport data for species '{}'.", s->name);
402 }
else if (sptran->
geometry ==
"linear") {
404 }
else if (sptran->
geometry ==
"nonlinear") {
414 if (s->input.hasKey(
"critical-parameters") &&
415 s->input[
"critical-parameters"].hasKey(
"acentric-factor"))
417 m_w_ac[k] = s->input[
"critical-parameters"][
"acentric-factor"].asDouble();
427 double& f_eps,
double& f_sigma)
438 size_t kp = (
m_polar[i] ? i : j);
439 size_t knp = (i == kp ? j : i);
440 double d3np, d3p, alpha_star, mu_p_star, xi;
443 alpha_star =
m_alpha[knp]/d3np;
445 xi = 1.0 + 0.25 * alpha_star * mu_p_star * mu_p_star *
447 f_sigma = pow(xi, -1.0/6.0);
455 vector<double> fitlist;
460 for (
size_t i = 0; i <
m_nsp; i++) {
461 for (
size_t j = i; j <
m_nsp; j++) {
470 auto dptr = find(fitlist.begin(), fitlist.end(), dstar);
471 if (dptr == fitlist.end()) {
472 vector<double> ca(degree+1), cb(degree+1), cc(degree+1);
473 vector<double> co22(degree+1);
474 integrals.fit(degree, dstar, ca.data(), cb.data(), cc.data());
475 integrals.fit_omega22(degree, dstar, co22.data());
482 fitlist.push_back(dstar);
485 m_poly[i][j] =
static_cast<int>((dptr - fitlist.begin()));
497 const size_t np = 50;
498 int degree = (
m_mode == CK_Mode ? 3 : 4);
500 vector<double> tlog(np), spvisc(np), spcond(np);
501 vector<double> w(np), w2(np);
507 for (
size_t n = 0; n < np; n++) {
508 double t =
m_thermo->minTemp() + dt*n;
513 vector<double> c(degree + 1), c2(degree + 1);
516 double visc, err, relerr,
517 mxerr = 0.0, mxrelerr = 0.0, mxerr_cond = 0.0, mxrelerr_cond = 0.0;
518 double T_save =
m_thermo->temperature();
519 const vector<double>& mw =
m_thermo->molecularWeights();
520 for (
size_t k = 0; k <
m_nsp; k++) {
524 double fz_298 = 1.0 + pow(
Pi, 1.5) / sqrt(tstar) * (0.5 + 1.0 / tstar) +
525 (0.25 *
Pi *
Pi + 2) / tstar;
527 for (
size_t n = 0; n < np; n++) {
528 double t =
m_thermo->minTemp() + dt*n;
530 vector<double> cp_R_all(
m_thermo->nSpecies());
531 m_thermo->getCp_R_ref(&cp_R_all[0]);
532 double cp_R = cp_R_all[k];
534 double sqrt_T = sqrt(t);
535 double om22 = integrals.omega22(tstar,
m_delta(k,k));
536 double om11 = integrals.omega11(tstar,
m_delta(k,k));
548 double f_int = mw[k]/(
GasConstant * t) * diffcoeff/visc;
549 double cv_rot =
m_crot[k];
550 double A_factor = 2.5 - f_int;
551 double fz_tstar = 1.0 + pow(
Pi, 1.5) / sqrt(tstar) * (0.5 + 1.0 / tstar) +
552 (0.25 *
Pi *
Pi + 2) / tstar;
553 double B_factor =
m_zrot[k] * fz_298 / fz_tstar + 2.0/
Pi * (5.0/3.0 * cv_rot + f_int);
554 double c1 = 2.0/
Pi * A_factor/B_factor;
555 double cv_int = cp_R - 2.5 - cv_rot;
556 double f_rot = f_int * (1.0 + c1);
557 double f_trans = 2.5 * (1.0 - c1 * cv_rot/1.5);
558 double cond = (visc/mw[k])*
GasConstant*(f_trans * 1.5
559 + f_rot * cv_rot + f_int * cv_int);
562 spvisc[n] = log(visc);
563 spcond[n] = log(cond);
573 spvisc[n] = sqrt(visc/sqrt_T);
578 spcond[n] = cond/sqrt_T;
579 w[n] = 1.0/(spvisc[n]*spvisc[n]);
580 w2[n] = 1.0/(spcond[n]*spcond[n]);
583 polyfit(np, degree, tlog.data(), spvisc.data(), w.data(), c.data());
584 polyfit(np, degree, tlog.data(), spcond.data(), w2.data(), c2.data());
587 for (
size_t n = 0; n < np; n++) {
590 val = exp(spvisc[n]);
591 fit = exp(
poly3(tlog[n], c.data()));
593 double sqrt_T = exp(0.5*tlog[n]);
594 val = sqrt_T * pow(spvisc[n],2);
595 fit = sqrt_T * pow(
poly4(tlog[n], c.data()),2);
599 mxerr = std::max(mxerr, fabs(err));
600 mxrelerr = std::max(mxrelerr, fabs(relerr));
606 for (
size_t n = 0; n < np; n++) {
609 val = exp(spcond[n]);
610 fit = exp(
poly3(tlog[n], c2.data()));
612 double sqrt_T = exp(0.5*tlog[n]);
613 val = sqrt_T * spcond[n];
614 fit = sqrt_T *
poly4(tlog[n], c2.data());
618 mxerr_cond = std::max(mxerr_cond, fabs(err));
619 mxrelerr_cond = std::max(mxrelerr_cond, fabs(relerr));
633 const size_t np = 50;
634 int degree = (
m_mode == CK_Mode ? 3 : 4);
636 vector<double> tlog(np);
637 vector<double> w(np), w2(np);
640 for (
size_t n = 0; n < np; n++) {
641 double t =
m_thermo->minTemp() + dt*n;
646 vector<double> c(degree + 1), c2(degree + 1);
647 double err, relerr, mxerr = 0.0, mxrelerr = 0.0;
649 vector<double> diff(np + 1);
651 for (
size_t k = 0; k <
m_nsp; k++) {
652 for (
size_t j = k; j <
m_nsp; j++) {
653 for (
size_t n = 0; n < np; n++) {
654 double t =
m_thermo->minTemp() + dt*n;
657 double sigma =
m_diam(j,k);
658 double om11 = integrals.omega11(tstar,
m_delta(j,k));
660 * pow(
Boltzmann * t, 1.5) / (
Pi * sigma * sigma * om11);
668 diff[n] = log(diffcoeff);
671 diff[n] = diffcoeff/pow(t, 1.5);
672 w[n] = 1.0/(diff[n]*diff[n]);
675 polyfit(np, degree, tlog.data(), diff.data(), w.data(), c.data());
677 for (
size_t n = 0; n < np; n++) {
681 fit = exp(
poly3(tlog[n], c.data()));
683 double t = exp(tlog[n]);
684 double pre = pow(t, 1.5);
686 fit = pre *
poly4(tlog[n], c.data());
690 mxerr = std::max(mxerr, fabs(err));
691 mxrelerr = std::max(mxrelerr, fabs(relerr));
702 size_t k,
size_t j,
double xk,
double xj,
double& fkj,
double& fjk)
704 double w1 =
m_thermo->molecularWeight(k);
705 double w2 =
m_thermo->molecularWeight(j);
706 double wsum = w1 + w2;
707 double wmwp = (w1 - w2)/wsum;
708 double sqw12 = sqrt(w1*w2);
712 double sigratio = sig1*sig1/(sig2*sig2);
713 double sigratio2 = sig1*sig1/(sig12*sig12);
714 double sigratio3 = sig2*sig2/(sig12*sig12);
718 double om22_1 = integrals.omega22(tstar1,
m_delta(k,k));
719 double om22_2 = integrals.omega22(tstar2,
m_delta(j,j));
720 double om11_12 = integrals.omega11(tstar12,
m_delta(k,j));
721 double astar_12 = integrals.astar(tstar12,
m_delta(k,j));
722 double bstar_12 = integrals.bstar(tstar12,
m_delta(k,j));
723 double cstar_12 = integrals.cstar(tstar12,
m_delta(k,j));
725 double cnst = sigratio * sqrt(2.0*w2/wsum) * 2.0 * w1*w1/(wsum * w2);
726 double p1 = cnst * om22_1 / om11_12;
728 cnst = (1.0/sigratio) * sqrt(2.0*w1/wsum) * 2.0*w2*w2/(wsum*w1);
729 double p2 = cnst * om22_2 / om11_12;
730 double p12 = 15.0 * wmwp*wmwp + 8.0*w1*w2*astar_12/(wsum*wsum);
732 cnst = (2.0/(w2*wsum))*sqrt(2.0*w2/wsum)*sigratio2;
733 double q1 = cnst*((2.5 - 1.2*bstar_12)*w1*w1 + 3.0*w2*w2
734 + 1.6*w1*w2*astar_12);
736 cnst = (2.0/(w1*wsum))*sqrt(2.0*w1/wsum)*sigratio3;
737 double q2 = cnst*((2.5 - 1.2*bstar_12)*w2*w2 + 3.0*w1*w1
738 + 1.6*w1*w2*astar_12);
739 double q12 = wmwp*wmwp*15.0*(2.5 - 1.2*bstar_12)
740 + 4.0*w1*w2*astar_12*(11.0 - 2.4*bstar_12)/(wsum*wsum)
741 + 1.6*wsum*om22_1*om22_2/(om11_12*om11_12*sqw12)
742 * sigratio2 * sigratio3;
744 cnst = 6.0*cstar_12 - 5.0;
745 fkj = 1.0 + 0.1*cnst*cnst *
746 (p1*xk*xk + p2*xj*xj + p12*xk*xj)/
747 (q1*xk*xk + q2*xj*xj + q12*xk*xj);
748 fjk = 1.0 + 0.1*cnst*cnst *
749 (p2*xk*xk + p1*xj*xj + p12*xk*xj)/
750 (q2*xk*xk + q1*xj*xj + q12*xk*xj);
756 for (
int k = 0; k < (
m_mode == CK_Mode ? 4 : 5); k++) {
764 for (
int k = 0; k < (
m_mode == CK_Mode ? 4 : 5); k++) {
773 size_t mi = (j >= i? i : j);
774 size_t mj = (j >= i? j : i);
776 for (
size_t ii = 0; ii < mi; ii++) {
781 for (
int k = 0; k < (
m_mode == CK_Mode ? 4 : 5); k++) {
787 double* astar_coeffs,
788 double* bstar_coeffs,
789 double* cstar_coeffs)
const
803 for (
int k = 0; k < (
m_mode == CK_Mode ? 4 : 5); k++) {
812 for (
int k = 0; k < (
m_mode == CK_Mode ? 4 : 5); k++) {
822 size_t mi = (j >= i? i : j);
823 size_t mj = (j >= i? j : i);
825 for (
size_t ii = 0; ii < mi; ii++) {
830 for (
int k = 0; k < (
m_mode == CK_Mode ? 4 : 5); k++) {
837 double* astar_coeffs,
838 double* bstar_coeffs,
839 double* cstar_coeffs,
bool actualT)
844 vector<double> ca(degree+1), cb(degree+1), cc(degree+1);
846 for (
size_t k = 0; k < degree+1; k++) {
847 ca[k] = astar_coeffs[k];
848 cb[k] = bstar_coeffs[k];
849 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.
virtual void getTransportData()
Read the transport database.
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 getBinaryDiffCoeffs(const size_t ld, double *const d) override
Returns the matrix of binary diffusion coefficients [m²/s].
vector< double > m_quad_polar
Quadrupole polarizability.
void setCollisionIntegralPolynomial(size_t i, size_t j, double *astar_coeffs, double *bstar_coeffs, double *cstar_coeffs, bool actualT) override
Modify the polynomial fits to the collision integral of species pair (i, j)
void getCollisionIntegralPolynomial(size_t i, size_t j, double *astar_coeffs, double *bstar_coeffs, double *cstar_coeffs) const override
Return the polynomial fits to the collision integral of species pair (i, j)
void setBinDiffusivityPolynomial(size_t i, size_t j, double *coeffs) override
Modify the polynomial fits to the binary diffusivity of species pair (i, j)
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.
DenseMatrix m_wratkj1
Holds square roots of molecular weight ratios.
void getMixDiffCoeffs(double *const d) override
Returns the Mixture-averaged diffusion coefficients [m²/s].
virtual void fitDiffCoeffs(MMCollisionInt &integrals)
Generate polynomial fits to the binary diffusion coefficients.
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.
void getBinDiffusivityPolynomial(size_t i, size_t j, double *coeffs) const override
Return the polynomial fits to the binary diffusivity of species pair (i, j)
DenseMatrix m_diam
hard-sphere diameter [m] for (i,j) collision
void getMixDiffCoeffsMole(double *const d) override
Returns the mixture-averaged diffusion coefficients [m²/s].
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 getViscosityPolynomial(size_t i, double *coeffs) const override
Return the polynomial fits to the viscosity of species i.
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 init(ThermoPhase *thermo, int mode=0) override
Initialize a transport manager.
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 getConductivityPolynomial(size_t i, double *coeffs) const override
Return the temperature fits of the heat conductivity of species i.
void setViscosityPolynomial(size_t i, double *coeffs) override
Modify the polynomial fits to the viscosity of species i
void invalidateCache() override
Invalidate any cached values which are normally updated only when a change in state is detected.
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.
vector< vector< int > > m_poly
Indices for the (i,j) interaction in collision integral fits.
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 setConductivityPolynomial(size_t i, double *coeffs) override
Modify the temperature fits of the heat conductivity of species i
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.
void getMixDiffCoeffsMass(double *const d) override
Returns the mixture-averaged diffusion coefficients [m²/s].
Calculation of Collision integrals.
void init(double tsmin, double tsmax)
Initialize the object for calculation.
Base class for a phase with thermodynamic properties.
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,...
double dot5(const V &x, const V &y)
Templated Inner product of two vectors of length 5.
R poly4(D x, R *c)
Evaluates a polynomial of order 4.
R poly3(D x, R *c)
Templated evaluation of a polynomial of order 3.
double dot4(const V &x, const V &y)
Templated Inner product of two vectors of length 4.
double polyfit(size_t n, size_t deg, const double *xp, const double *yp, const double *wp, double *pp)
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, const double *const b, double *const prod)
Multiply A*b and return the result in prod. Uses BLAS routine DGEMV.
Contains declarations for string manipulation functions within Cantera.
Various templated functions that carry out common vector and polynomial operations (see Templated Arr...