From 157e62be5f88e9732dbba7d7a9bd9098b6b2bfd6 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Fri, 31 May 2024 18:29:57 -0400 Subject: [PATCH 01/37] initial work on transport updates --- .../transport/HighPressureGasTransport.h | 27 ++- src/transport/HighPressureGasTransport.cpp | 213 +++++++++++++----- src/transport/MMCollisionInt.cpp | 10 +- src/transport/MMCollisionInt.h | 27 ++- 4 files changed, 202 insertions(+), 75 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index c5e6e7c08c..eba84af257 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -74,18 +74,35 @@ class HighPressureGasTransport : public MultiTransport protected: double Tcrit_i(size_t i); - double Pcrit_i(size_t i); - double Vcrit_i(size_t i); - double Zcrit_i(size_t i); - vector store(size_t i, size_t nsp); + double low_pressure_nondimensional_viscosity(double Tr, double FP, double FQ); + double high_pressure_nondimensional_viscosity(double Tr, double Pr, double FP_low, double FQ_low, double P_vap, double P_crit) + /** + * @brief Returns the quantum correction term for a species based on Tr + * and MW, used in viscosity calculation: + * + * @param Q + * @param Tr // Reduced temperature + * @param MW // Molecular weight + * @return double + */ double FQ_i(double Q, double Tr, double MW); - double setPcorr(double Pr, double Tr); + double FP_i(double mu_r, double Tr, double Z_c); + + /** + * @brief Returns interpolated value of (D*P)_R obtained from the data + * in Table 2 of the Takahashi 1975 paper, given a value of the reduced + * pressure (Pr) and reduced temperature (Tr). + * + * @param Pr Reduced pressure + * @param Tr Reduced temperature +\ */ + double compute_correction_factor(double Pr, double Tr); }; } #endif diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 8fe7117ec3..174852c98e 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -128,16 +128,14 @@ void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* cons m_thermo->getMoleFractions(&molefracs[0]); update_T(); - // Evaluate the binary diffusion coefficients from the polynomial fits. - // This should perhaps be preceded by a check to see whether any of T, P, or - // C have changed. - //if (!m_bindiff_ok) { - updateDiff_T(); - //} - if (ld < nsp) { - throw CanteraError("HighPressureGasTransport::getBinaryDiffCoeffs", - "ld is too small"); + // if necessary, evaluate the binary diffusion coefficients from the polynomial fits + if (!m_bindiff_ok) { + updateDiff_T(); + } + if (ld < m_nsp) { + throw CanteraError("HighPressureGasTransport::getBinaryDiffCoeffs", "ld is too small"); } + double rp = 1.0/m_thermo->pressure(); for (size_t i = 0; i < nsp; i++) { for (size_t j = 0; j < nsp; j++) { @@ -155,21 +153,15 @@ void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* cons double Pr_ij = m_thermo->pressure()/(x_i*Pcrit_i(i) + x_j*Pcrit_i(j)); double P_corr_ij; - if (Pr_ij < 0.1) { - // If pressure is low enough, no correction is needed: - P_corr_ij = 1; - }else { - // Otherwise, calculate the parameters for Takahashi correlation - // by interpolating on Pr_ij: - P_corr_ij = setPcorr(Pr_ij, Tr_ij); - // If the reduced temperature is too low, the correction factor - // P_corr_ij will be < 0: - if (P_corr_ij<0) { - P_corr_ij = Tiny; - } - } + // Calculate the parameters for Takahashi correlation + P_corr_ij = compute_correction_factor(Pr_ij, Tr_ij); + // If the reduced temperature is too low, the correction factor + // P_corr_ij will be < 0: + if (P_corr_ij<0) { + P_corr_ij = Tiny; + } // Multiply the standard low-pressure binary diffusion coefficient // (m_bdiff) by the Takahashi correction factor P_corr_ij: d[ld*j + i] = P_corr_ij*rp * m_bdiff(i,j); @@ -221,7 +213,7 @@ void HighPressureGasTransport::getMultiDiffCoeffs(const size_t ld, double* const if (Pr_ij < 0.1) { P_corr_ij = 1; }else { - P_corr_ij = setPcorr(Pr_ij, Tr_ij); + P_corr_ij = compute_correction_factor(Pr_ij, Tr_ij); if (P_corr_ij<0) { P_corr_ij = Tiny; } @@ -381,10 +373,14 @@ double HighPressureGasTransport::viscosity() // Pure species critical properties - Tc, Pc, Vc, Zc: double HighPressureGasTransport::Tcrit_i(size_t i) { - // Store current molefracs and set temp molefrac of species i to 1.0: - vector molefracs = store(i, m_thermo->nSpecies()); + vector molefracs(m_thermo->nSpecies()); + m_thermo->getMoleFractions(&molefracs[0]); + vector mf_temp(m_thermo->nSpecies(), 0.0); + mf_temp[i] = 1; + m_thermo->setMoleFractions(&mf_temp[0]); double tc = m_thermo->critTemperature(); + // Restore actual molefracs: m_thermo->setMoleFractions(&molefracs[0]); return tc; @@ -392,10 +388,14 @@ double HighPressureGasTransport::Tcrit_i(size_t i) double HighPressureGasTransport::Pcrit_i(size_t i) { - // Store current molefracs and set temp molefrac of species i to 1.0: - vector molefracs = store(i, m_thermo->nSpecies()); + vector molefracs(m_thermo->nSpecies()); + m_thermo->getMoleFractions(&molefracs[0]); + vector mf_temp(m_thermo->nSpecies(), 0.0); + mf_temp[i] = 1; + m_thermo->setMoleFractions(&mf_temp[0]); double pc = m_thermo->critPressure(); + // Restore actual molefracs: m_thermo->setMoleFractions(&molefracs[0]); return pc; @@ -403,10 +403,14 @@ double HighPressureGasTransport::Pcrit_i(size_t i) double HighPressureGasTransport::Vcrit_i(size_t i) { - // Store current molefracs and set temp molefrac of species i to 1.0: - vector molefracs = store(i, m_thermo->nSpecies()); + vector molefracs(m_thermo->nSpecies()); + m_thermo->getMoleFractions(&molefracs[0]); + vector mf_temp(m_thermo->nSpecies(), 0.0); + mf_temp[i] = 1; + m_thermo->setMoleFractions(&mf_temp[0]); double vc = m_thermo->critVolume(); + // Restore actual molefracs: m_thermo->setMoleFractions(&molefracs[0]); return vc; @@ -414,37 +418,125 @@ double HighPressureGasTransport::Vcrit_i(size_t i) double HighPressureGasTransport::Zcrit_i(size_t i) { - // Store current molefracs and set temp molefrac of species i to 1.0: - vector molefracs = store(i, m_thermo->nSpecies()); + vector molefracs(m_thermo->nSpecies()); + m_thermo->getMoleFractions(&molefracs[0]); + vector mf_temp(m_thermo->nSpecies(), 0.0); + mf_temp[i] = 1; + m_thermo->setMoleFractions(&mf_temp[0]); double zc = m_thermo->critCompressibility(); + // Restore actual molefracs: m_thermo->setMoleFractions(&molefracs[0]); return zc; } -vector HighPressureGasTransport::store(size_t i, size_t nsp) -{ - vector molefracs(nsp); - m_thermo->getMoleFractions(&molefracs[0]); - vector mf_temp(nsp, 0.0); - mf_temp[i] = 1; - m_thermo->setMoleFractions(&mf_temp[0]); - return molefracs; +// The low-pressure nondimensional viscosity equation 9-4.16 in Poling et al. (2001). +// This relation is used for pure species and mixtures at low pressure. The only +// difference is the the values that are passed to the function. +double HighPressureGasTransport::low_pressure_nondimensional_viscosity(double Tr, double FP, double FQ) { + double first_term = 0.807*pow(Tr,0.618) - 0.357*exp(-0.449*Tr); + double second_term = 0.340*exp(-4.058*Tr) + 0.018; + return (first_term + second_term)*FP*FQ; } -// Calculates quantum correction term for a species based on Tr and MW, used in -// viscosity calculation: + +double HighPressureGasTransport::high_pressure_nondimensional_viscosity(double Tr, double Pr, double FP_low, double FQ_low, double P_vap, double P_crit){ + + double Z_1 = low_pressure_nondimensional_viscosity(Tr, FP_low, FQ_low); // This is η_0*ξ + + double Z_2; + if (Tr <= 1.0) { + if (Pr < P_vap/P_crit) { + double alpha = 3.262 + 14.98*pow(Pr, 5.508); + double beta = 1.390 + 5.746*Pr; + Z_2 = 0.600 + 0.760*pow(Pr, alpha) + (0.6990*pow(Pr, beta) - 0.60) * (1-Tr); + } else { + throw CanteraError("HighPressureGasTransport::viscosity", + "State is outside the limits of the Lucas model, Tr <= 1"); + } + } else if ((Tr > 1.0) && (Tr < 40.0)) { + if ((Pr > 0.0) && (Pr <= 100.0)) { + // The following expressions are given in page 9.36 of Poling et al. (2001) + // and correspond to parameters in equation 9-6.8. + double a_1 = 1.245e-3; + double a_2 = 5.1726; + double gamma = -0.3286; + double a = a_1*exp(a_2*pow(Tr,gamma))/Tr; + + double b_1 = 1.6553; + double b_2 = 1.2723; + double b = a*(b_1*Tr - b_2); + + double c_1 = 0.4489; + double c_2 = 3.0578; + double delta = -37.7332; + double c = c_1*exp(c_2*pow(Tr, delta))/Tr; + + double d_1 = 1.7368; + double d_2 = 2.2310; + double epsilon = -7.6351; + double d = d_1*exp(d_2*pow(Tr, epsilon))/Tr; + + double e = 1.3088; + + double f_1 = 0.9425; + double f_2 = -0.1853; + double zeta = 0.4489; + double f = f_1*exp(f_2*pow(Tr, zeta)); + + Z_2 = Z_1*(1 + (a*pow(Pr,e)) / (b*pow(Pr,f) + pow(1+c*pow(Pr,d),-1))); + } else { + throw CanteraError("HighPressureGasTransport::viscosity", + "State is outside the limits of the Lucas model, 1.0 < Tr < 40"); + } + } else { + throw CanteraError("HighPressureGasTransport::viscosity", + "State is outside the limits of the Lucas model, Tr > 40"); + } + + double Y = Z_2 / Z_1; + double FP = (1 + (FP_low - 1)*pow(Y,-3.0)) / FP_low; + double FQ = (1 + (FQ_low - 1)*(1.0/Y - 0.007*pow(log(Y),4.0))) / FQ_low; + + // Return the non-dimensional viscosity η*ξ + return Z_2 * FP * FQ; +} + +// Calculates quantum correction term of the Lucas method for a species based +// on Tr and MW, used in viscosity calculation from equation 9-4.19 in +// Poling et al. (2001): double HighPressureGasTransport::FQ_i(double Q, double Tr, double MW) { - return 1.22*pow(Q,0.15)*(1 + 0.00385*pow(pow(Tr - 12.,2.),1./MW) - *fabs(Tr-12)/(Tr-12)); + return 1.22*pow(Q,0.15)*(1 + 0.00385*pow(pow(Tr - 12.0, 2.0), 1.0/MW) + *sign(Tr - 12.0)); +} + +// Sign function for use in the quantum correction term calculation. +template +int sign(T val) { + if (val > 0) return 1; + if (val < 0) return -1; + return 0; } -// Set value of parameter values for Takahashi correlation, by interpolating -// table of constants vs. Pr: -double HighPressureGasTransport::setPcorr(double Pr, double Tr) +// Calculates the pressure correction factor for the Lucas method that +// is used to calculate high pressure pure fluid viscosity. This is equation +// 9-4.18 in Poling et al. (2001): +double HighPressureGasTransport::FP_i(double mu_r, double Tr, double Z_crit) { + if (mu_r < 0.022) { + return 1; + } else if (mu_r < 0.075) { + return 1 + 30.55*pow(0.292 - Z_crit, 1.72); + } else { + return 1 + 30.55*pow(0.292 - Z_crit, 1.72)*fabs(0.96 + 0.1*(Tr - 0.7)); + } +} + +double HighPressureGasTransport::compute_correction_factor(double Pr, double Tr) +{ + // Data from Table 2 of Takahashi 1975 paper: const static double Pr_lookup[17] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0, 4.0, 5.0}; const static double DP_Rt_lookup[17] = {1.01, 1.01, 1.01, 1.01, 1.01, 1.01, @@ -460,11 +552,13 @@ double HighPressureGasTransport::setPcorr(double Pr, double Tr) const static double E_ij_lookup[17] = {1., 1., 1., 1., 1., 1., 1., 13.45454, 14., 10.00900, 8.57519, 10.37483, 11.21674, 1., 6.19043, 1., 1.}; - // Interpolate Pr vs. those used in Takahashi table: + // Interpolate to obtain the value of the constants (DP)_R, A, B, C, E at + // the provided value of the reduced pressure (Pr): int Pr_i = 0; - double frac = 0.; + double frac = 0.0; + double A, B, C,E, DP_Rt; - if (Pr < 0.1) { + if (Pr < 0.1) { // In the low pressure limit, no correction is needed: frac = (Pr - Pr_lookup[0])/(Pr_lookup[1] - Pr_lookup[0]); } else { for (int j = 1; j < 17; j++) { @@ -474,20 +568,19 @@ double HighPressureGasTransport::setPcorr(double Pr, double Tr) } Pr_i++; } - } - // If Pr is greater than the greatest value used by Takahashi (5.0), use the - // final table value. Should eventually add in an extrapolation: - if (Pr_i == 17) { + // If this loop completes without finding a bounding value of Pr, use + // the final table value. frac = 1.0; } - double P_corr_1 = DP_Rt_lookup[Pr_i]*(1.0 - A_ij_lookup[Pr_i] - *pow(Tr,-B_ij_lookup[Pr_i]))*(1-C_ij_lookup[Pr_i] - *pow(Tr,-E_ij_lookup[Pr_i])); - double P_corr_2 = DP_Rt_lookup[Pr_i+1]*(1.0 - A_ij_lookup[Pr_i+1] - *pow(Tr,-B_ij_lookup[Pr_i+1]))*(1-C_ij_lookup[Pr_i+1] - *pow(Tr,-E_ij_lookup[Pr_i+1])); - return P_corr_1*(1.0-frac) + P_corr_2*frac; + DP_Rt = DP_Rt_lookup[Pr_i]*(1.0 - frac) + DP_Rt_lookup[Pr_i+1]*frac; + A = A_ij_lookup[Pr_i]*(1.0 - frac) + A_ij_lookup[Pr_i+1]*frac; + B = B_ij_lookup[Pr_i]*(1.0 - frac) + B_ij_lookup[Pr_i+1]*frac; + C = C_ij_lookup[Pr_i]*(1.0 - frac) + C_ij_lookup[Pr_i+1]*frac; + E = E_ij_lookup[Pr_i]*(1.0 - frac) + E_ij_lookup[Pr_i+1]*frac; + + double DP_R = DP_Rt*(1.0 - A*pow(Tr,-B))*(1.0 - C*pow(Tr,-E)); + return DP_R; } } diff --git a/src/transport/MMCollisionInt.cpp b/src/transport/MMCollisionInt.cpp index 90b421b947..8d97aedde1 100644 --- a/src/transport/MMCollisionInt.cpp +++ b/src/transport/MMCollisionInt.cpp @@ -19,7 +19,7 @@ double MMCollisionInt::delta[8] = {0.0, 0.25, 0.50, 0.75, 1.0, 1.5, 2.0, 2.5 }; -double quadInterp(double x0, double* x, double* y) +double MMCollisionInt::quadInterp(double x0, double* x, double* y) { double dx21 = x[1] - x[0]; double dx32 = x[2] - x[1]; @@ -213,7 +213,7 @@ double MMCollisionInt::cstar_table[39*8] = { 0.94444, 0.94444,0.94444,0.94444,0.94444,0.94444,0.94444,0.94444 }; -void MMCollisionInt::init(double tsmin, double tsmax, int log_level) +void MMCollisionInt::init(double tstar_min, double tstar_max, int log_level) { m_loglevel = log_level; debuglog("Collision Integral Polynomial Fits\n", m_loglevel > 0); @@ -221,10 +221,10 @@ void MMCollisionInt::init(double tsmin, double tsmax, int log_level) m_nmax = -1; for (int n = 0; n < 37; n++) { - if (tsmin > tstar[n+1]) { + if (tstar_min > tstar[n+1]) { m_nmin = n; } - if (tsmax > tstar[n+1]) { + if (tstar_max > tstar[n+1]) { m_nmax = n+1; } } @@ -312,7 +312,7 @@ double MMCollisionInt::fitDelta(int table, int ntstar, int degree, double* c) default: return 0.0; } - w[0] = -1.0; + w[0] = -1.0; // to activate weight values of unity return polyfit(8, degree, delta, begin, w.data(), c); } diff --git a/src/transport/MMCollisionInt.h b/src/transport/MMCollisionInt.h index 6fd2323a99..6b7b751729 100644 --- a/src/transport/MMCollisionInt.h +++ b/src/transport/MMCollisionInt.h @@ -19,6 +19,17 @@ namespace Cantera * This class provides functions that interpolate the tabulated collision * integrals in Monchick and Mason @cite monchick1961. * + * The collision integrals computed by Monchick and Mason use the Stockmayer + * potential, which models a polar molecule as a spherical potential with a + * point dipole at the center). + * + * @f[ + * \phi(r) = 4\epsilon \left[ \left(\frac{\sigma}{r}\right)^{12} - \left(\frac{\sigma}{r}\right)^6 + \delta \left(\frac{\sigma}{r}\right)^3 \right] + * @f] + * + * The tabulated data comes from the averaged collision integrals in tables + * V through VIII of Monchick and Mason @cite monchick1961. + * * @ingroup tranprops */ class MMCollisionInt @@ -48,6 +59,7 @@ class MMCollisionInt private: double fitDelta(int table, int ntstar, int degree, double* c); + double quadInterp(double x0, double* x, double* y); vector> m_o22poly; vector> m_apoly; @@ -57,25 +69,30 @@ class MMCollisionInt static double delta[8]; static double tstar22[37]; - //! Table of omega22 values from MM + //! Table of omega22 values static double omega22_table[37*8]; - //! table of tstar values + //! T* values (reduced temperature) static double tstar[39]; - //! astar table from MM + //! astar table static double astar_table[39*8]; - //! bstar table from MM + //! bstar table static double bstar_table[39*8]; - //! cstar table from MM + //! cstar table static double cstar_table[39*8]; //! Log temp vector m_logTemp; + //! Index of the tstar array that encompasses the minimum temperature + //! fitting range value of tsmin. int m_nmin; + + //! Index of the tstar array that encompasses the maximum temperature + //! fitting range value of tsmax. int m_nmax; //! loglevel From c47b1c2aef0495b2327475f5fb281836858301f7 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Wed, 5 Jun 2024 17:47:14 -0400 Subject: [PATCH 02/37] changed high pressure transport to mixture averaged and added new Chung option --- .../transport/HighPressureGasTransport.h | 131 +++++- src/transport/HighPressureGasTransport.cpp | 437 +++++++++++------- 2 files changed, 374 insertions(+), 194 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index eba84af257..202a18adcd 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -12,7 +12,7 @@ // Cantera includes #include "GasTransport.h" #include "cantera/numerics/DenseMatrix.h" -#include "cantera/transport/MultiTransport.h" +#include "cantera/transport/MixTransport.h" namespace Cantera { @@ -37,7 +37,7 @@ namespace Cantera * * @ingroup tranprops */ -class HighPressureGasTransport : public MultiTransport +class HighPressureGasTransport : public MixTransport { protected: //! default constructor @@ -48,13 +48,8 @@ class HighPressureGasTransport : public MultiTransport return "HighPressureGas"; } - //! Return the thermal diffusion coefficients (kg/m/s) - /*! - * Currently not implemented for this model - */ - void getThermalDiffCoeffs(double* const dt) override; - double thermalConductivity() override; + double viscosity() override; /** * Returns the matrix of binary diffusion coefficients @@ -66,10 +61,6 @@ class HighPressureGasTransport : public MultiTransport */ void getBinaryDiffCoeffs(const size_t ld, double* const d) override; - void getMultiDiffCoeffs(const size_t ld, double* const d) override; - - double viscosity() override; - friend class TransportFactory; protected: @@ -79,11 +70,11 @@ class HighPressureGasTransport : public MultiTransport double Zcrit_i(size_t i); double low_pressure_nondimensional_viscosity(double Tr, double FP, double FQ); - double high_pressure_nondimensional_viscosity(double Tr, double Pr, double FP_low, double FQ_low, double P_vap, double P_crit) + double high_pressure_nondimensional_viscosity(double Tr, double Pr, double FP_low, double FQ_low, double P_vap, double P_crit); /** * @brief Returns the quantum correction term for a species based on Tr - * and MW, used in viscosity calculation: + * and MW, used in viscosity calculation. * * @param Q * @param Tr // Reduced temperature @@ -92,10 +83,114 @@ class HighPressureGasTransport : public MultiTransport */ double FQ_i(double Q, double Tr, double MW); + /** + * @brief Returns the polarity correction term for a species based on Tr + * and MW, used in viscosity calculation. + * + * @param Q + * @param Tr // Reduced temperature + * @param MW // Molecular weight + * @return double + */ double FP_i(double mu_r, double Tr, double Z_c); /** - * @brief Returns interpolated value of (D*P)_R obtained from the data + * @brief Returns interpolated value of (DP)_R obtained from the data + * in Table 2 of the Takahashi 1975 paper, given a value of the reduced + * pressure (Pr) and reduced temperature (Tr). + * + * @param Pr Reduced pressure + * @param Tr Reduced temperature +\ */ + double compute_correction_factor(double Pr, double Tr); +}; + + + +//These are the parameters that are needed to calculate the viscosity using the Chung method. +struct ChungMixtureParameters +{ + // Mixture critical properties used by the Chung viscosity model. + double Vc_mix = 0; + double Tc_mix = 0; + + // Values associated with the calculation of sigma and the molecular weight used in the Chung viscosity model. + double sigma_mix = 0; + double epsilon_over_k_mix = 0; + double MW_mix = 0; + + // Values associated with the calculation of the Fc factor in the Chung viscosity model. + double mu_mix = 0; + double mu_r_mix = 0; + double acentric_factor_mix = 0; + double kappa_mix = 0; +}; + +//! Class ChungHighPressureTransport implements transport properties for +//! high pressure gas mixtures. +/*! + * The implementation employs a method of corresponding states, using the Takahashi + * @cite takahashi1975 approach for binary diffusion coefficients (using mixture + * averaging rules for the mixture properties), and the Chung method for the viscosity + * and thermal conductivity of a high-pressure gas mixture. All methods are described in Poling et al. + * @cite poling2001 (viscosity in Ch. 9, thermal conductivity in Ch. 10, and diffusion + * coefficients in Ch. 11). + * + * + * + * @ingroup tranprops + */ +class ChungHighPressureGasTransport : public MixTransport +{ +protected: + //! default constructor + ChungHighPressureGasTransport() = default; + +public: + string transportModel() const override { + return "ChungHighPressureGas"; + } + + double viscosity() override; + double thermalConductivity() override; + + /** + * Returns the matrix of binary diffusion coefficients + * + * d[ld*j + i] = rp*m_bdiff(i,j)*(DP)_R; + * + * @param ld offset of rows in the storage + * @param d output vector of diffusion coefficients. Units of m**2 / s + */ + void getBinaryDiffCoeffs(const size_t ld, double* const d) override; + + friend class TransportFactory; + +protected: + double Tcrit_i(size_t i); + double Pcrit_i(size_t i); + double Vcrit_i(size_t i); + double Zcrit_i(size_t i); + + // Uses the low-pressure Chung viscosity model to calculate the viscosity + // Defined by equation 9-4.10 in Poling et al. + // Gives viscosity in units of micropoise + // T must be units of K + // MW must be units of kg/kmol + // sigma must be units of Angstroms + double low_pressure_viscosity(double T, double T_star, double MW, double acentric_factor, double mu_r, double sigma, double kappa); + + // Computes the high-pressure viscosity using the Chung method (Equation 9-6.18). + // Gives viscosity in units of micropoise + double high_pressure_viscosity(double T_star, double MW, double rho, double Vc, double Tc, double acentric_factor, double mu_r, double kappa); + + // Computes and store composition-dependent values of the parameters needed for the Chung viscosity model. + void compute_mixture_parameters(ChungMixtureParameters& params); + + + + /** + * @brief Returns interpolated value of (DP)_R obtained from the data * in Table 2 of the Takahashi 1975 paper, given a value of the reduced * pressure (Pr) and reduced temperature (Tr). * @@ -104,5 +199,11 @@ class HighPressureGasTransport : public MultiTransport \ */ double compute_correction_factor(double Pr, double Tr); }; + + + + + + } #endif diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 174852c98e..8841e03a56 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -109,26 +109,14 @@ double HighPressureGasTransport::thermalConductivity() return Lprime_m + Lstar_m; } -void HighPressureGasTransport::getThermalDiffCoeffs(double* const dt) -{ - // Method for MultiTransport class: - // solveLMatrixEquation(); - // const double c = 1.6/GasConstant; - // for (size_t k = 0; k < m_nsp; k++) { - // dt[k] = c * m_mw[k] * m_molefracs[k] * m_a[k]; - // } - throw NotImplementedError("HighPressureGasTransport::getThermalDiffCoeffs"); -} - void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* const d) { - vector PcP(5); size_t nsp = m_thermo->nSpecies(); vector molefracs(nsp); m_thermo->getMoleFractions(&molefracs[0]); update_T(); - // if necessary, evaluate the binary diffusion coefficients from the polynomial fits + // If necessary, evaluate the binary diffusion coefficients from the polynomial fits if (!m_bindiff_ok) { updateDiff_T(); } @@ -140,137 +128,66 @@ void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* cons for (size_t i = 0; i < nsp; i++) { for (size_t j = 0; j < nsp; j++) { // Add an offset to avoid a condition where x_i and x_j both equal - // zero (this would lead to Pr_ij = Inf): + // zero (this would lead to Pr_ij = Inf). double x_i = std::max(Tiny, molefracs[i]); double x_j = std::max(Tiny, molefracs[j]); - // Weight mole fractions of i and j so that X_i + X_j = 1.0: + // Weight mole fractions of i and j so that X_i + X_j = 1.0. x_i = x_i/(x_i + x_j); x_j = x_j/(x_i + x_j); - //Calculate Tr and Pr based on mole-fraction-weighted crit constants: + // Calculate Tr and Pr based on mole-fraction-weighted critical constants. double Tr_ij = m_temp/(x_i*Tcrit_i(i) + x_j*Tcrit_i(j)); double Pr_ij = m_thermo->pressure()/(x_i*Pcrit_i(i) + x_j*Pcrit_i(j)); - double P_corr_ij; - // Calculate the parameters for Takahashi correlation + double P_corr_ij; P_corr_ij = compute_correction_factor(Pr_ij, Tr_ij); // If the reduced temperature is too low, the correction factor - // P_corr_ij will be < 0: + // P_corr_ij will be < 0. if (P_corr_ij<0) { P_corr_ij = Tiny; } // Multiply the standard low-pressure binary diffusion coefficient - // (m_bdiff) by the Takahashi correction factor P_corr_ij: - d[ld*j + i] = P_corr_ij*rp * m_bdiff(i,j); + // (m_bdiff) by the Takahashi correction factor P_corr_ij. + d[ld*j + i] = P_corr_ij*(rp * m_bdiff(i,j)); } } } -void HighPressureGasTransport::getMultiDiffCoeffs(const size_t ld, double* const d) -{ - // Not currently implemented. m_Lmatrix inversion returns NaN. Needs to be - // fixed. --SCD - 2-28-2014 - throw NotImplementedError("HighPressureGasTransport:getMultiDiffCoeffs"); - // Calculate the multi-component Stefan-Maxwell diffusion coefficients, - // based on the Takahashi-correlation-corrected binary diffusion coefficients. - - // update the mole fractions - update_C(); - - // update the binary diffusion coefficients - update_T(); - updateThermal_T(); - - // Correct the binary diffusion coefficients for high-pressure effects; this - // is basically the same routine used in 'getBinaryDiffCoeffs,' above: - size_t nsp = m_thermo->nSpecies(); - vector molefracs(nsp); - m_thermo->getMoleFractions(&molefracs[0]); - update_T(); - // Evaluate the binary diffusion coefficients from the polynomial fits - - // this should perhaps be preceded by a check for changes in T, P, or C. - updateDiff_T(); - - if (ld < m_nsp) { - throw CanteraError("HighPressureGasTransport::getMultiDiffCoeffs", - "ld is too small"); - } - for (size_t i = 0; i < m_nsp; i++) { - for (size_t j = 0; j < m_nsp; j++) { - // Add an offset to avoid a condition where x_i and x_j both equal - // zero (this would lead to Pr_ij = Inf): - double x_i = std::max(Tiny, molefracs[i]); - double x_j = std::max(Tiny, molefracs[j]); - x_i = x_i/(x_i+x_j); - x_j = x_j/(x_i+x_j); - double Tr_ij = m_temp/(x_i*Tcrit_i(i) + x_j*Tcrit_i(j)); - double Pr_ij = m_thermo->pressure()/(x_i*Pcrit_i(i) + x_j*Pcrit_i(j)); - - double P_corr_ij; - if (Pr_ij < 0.1) { - P_corr_ij = 1; - }else { - P_corr_ij = compute_correction_factor(Pr_ij, Tr_ij); - if (P_corr_ij<0) { - P_corr_ij = Tiny; - } - } - - m_bdiff(i,j) *= P_corr_ij; - } - } - m_bindiff_ok = false; // m_bdiff is overwritten by the above routine. - - // Having corrected m_bdiff for pressure and concentration effects, the - // routine now proceeds the same as in the low-pressure case: - - // evaluate L0000 if the temperature or concentrations have - // changed since it was last evaluated. - if (!m_l0000_ok) { - eval_L0000(molefracs.data()); - } - - // invert L00,00 - int ierr = invert(m_Lmatrix, m_nsp); - if (ierr != 0) { - throw CanteraError("HighPressureGasTransport::getMultiDiffCoeffs", - "invert returned ierr = {}", ierr); - } - m_l0000_ok = false; // matrix is overwritten by inverse - m_lmatrix_soln_ok = false; - - double prefactor = 16.0 * m_temp - *m_thermo->meanMolecularWeight()/(25.0*m_thermo->pressure()); - - for (size_t i = 0; i < m_nsp; i++) { - for (size_t j = 0; j < m_nsp; j++) { - double c = prefactor/m_mw[j]; - d[ld*j + i] = c*molefracs[i]*(m_Lmatrix(i,j) - m_Lmatrix(i,i)); - } - } -} +// Calculate the high-pressure mixture viscosity, based on the Lucas method +// described in chapter 9-7 of Poling et al. (2001). +// +// The mixture pseudo-critical temperature and pressure are calculated using +// equation 9-5.18 and 9-5.19 in Poling et al. (2001). +// +// The mixture molecular weight is computed using equation 9-5.20 in Poling et al. (2001). +// +// The mixture values of the low-pressure polarity and quantum correction factors are +// computed using equations 9-5.21 and 9-5.22 in Poling et al. (2001). double HighPressureGasTransport::viscosity() { - // Calculate the high-pressure mixture viscosity, based on the Lucas method. - double Tc_mix = 0.; - double Pc_mix_n = 0.; - double Pc_mix_d = 0.; + // Most of this function consists of computing mixture values of various critical + // properties and other parameters that are used in the viscosity calculation. + double Tc_mix = 0.0; + double Pc_mix_n = 0.0; // Numerator in equation 9-5.18 in Poling et al. (2001) + double Pc_mix_d = 0.0; // Denominator in equation 9-5.18 in Poling et al. (2001) double MW_mix = m_thermo->meanMolecularWeight(); - double MW_H = m_mw[0]; - double MW_L = m_mw[0]; - double FP_mix_o = 0; - double FQ_mix_o = 0; + + double FP_mix_o = 0; // The mole-fraction-weighted mixture average of the low-pressure polarity correction factor + double FQ_mix_o = 0; // The mole-fraction-weighted mixture average of the low-pressure quantum correction factor + double MW_H = m_mw[0]; // Holds the molecular weight of the heaviest species + double MW_L = m_mw[0]; // Holds the molecular weight of the lightest species + double tKelvin = m_thermo->temperature(); - double Pvp_mix = m_thermo->satPressure(tKelvin); + double P_vap_mix = m_thermo->satPressure(tKelvin); size_t nsp = m_thermo->nSpecies(); vector molefracs(nsp); m_thermo->getMoleFractions(&molefracs[0]); - double x_H = molefracs[0]; + double x_H = molefracs[0]; // Holds the mole fraction of the heaviest species for (size_t i = 0; i < m_nsp; i++) { // Calculate pure-species critical constants and add their contribution // to the mole-fraction-weighted mixture averages: @@ -281,36 +198,33 @@ double HighPressureGasTransport::viscosity() Pc_mix_n += molefracs[i]*Zc; //numerator Pc_mix_d += molefracs[i]*Vcrit_i(i); //denominator - // Need to calculate ratio of heaviest to lightest species: + // Calculate ratio of heaviest to lightest species if (m_mw[i] > MW_H) { MW_H = m_mw[i]; x_H = molefracs[i]; } else if (m_mw[i] < MW_L) { - MW_L = m_mw[i]; } - - // Calculate reduced dipole moment for polar correction term: - double mu_ri = 52.46*100000*m_dipole(i,i)*m_dipole(i,i) - *Pcrit_i(i)/(Tc*Tc); - if (mu_ri < 0.022) { - FP_mix_o += molefracs[i]; - } else if (mu_ri < 0.075) { - FP_mix_o += molefracs[i]*(1. + 30.55*pow(0.292 - Zc, 1.72)); - } else { FP_mix_o += molefracs[i]*(1. + 30.55*pow(0.292 - Zc, 1.72) - *fabs(0.96 + 0.1*(Tr - 0.7))); + MW_L = m_mw[i]; } + // Calculate pure-species reduced dipole moment for pure-species + // polar correction term. + // Equation 9-4.17 in Poling et al. (2001) requires the pressure + // to be in units of bar, so we convert from Pa to bar. + double pascals_to_bar = 1e-5; + double mu_ri = 52.46*m_dipole(i,i)*m_dipole(i,i)*(Pcrit_i(i)*pascals_to_bar)/(Tc*Tc); + FP_mix_o += molefracs[i] * FP_i(mu_ri, Tr, Zc); // mole-fraction weighting of pure-species polar correction term + + // Calculate contribution to quantum correction term. - // SCD Note: This assumes the species of interest (He, H2, and D2) have - // been named in this specific way. They are perhaps the most obvious - // names, but it would of course be preferred to have a more general - // approach, here. + // Note: This assumes the species of interest (He, H2, and D2) have + // been named in this specific way. vector spnames = m_thermo->speciesNames(); if (spnames[i] == "He") { - FQ_mix_o += molefracs[i]*FQ_i(1.38,Tr,m_mw[i]); + FQ_mix_o += molefracs[i]*FQ_i(1.38, Tr, m_mw[i]); } else if (spnames[i] == "H2") { - FQ_mix_o += molefracs[i]*(FQ_i(0.76,Tr,m_mw[i])); + FQ_mix_o += molefracs[i]*(FQ_i(0.76, Tr, m_mw[i])); } else if (spnames[i] == "D2") { - FQ_mix_o += molefracs[i]*(FQ_i(0.52,Tr,m_mw[i])); + FQ_mix_o += molefracs[i]*(FQ_i(0.52, Tr, m_mw[i])); } else { FQ_mix_o += molefracs[i]; } @@ -319,61 +233,32 @@ double HighPressureGasTransport::viscosity() double Tr_mix = tKelvin/Tc_mix; double Pc_mix = GasConstant*Tc_mix*Pc_mix_n/Pc_mix_d; double Pr_mix = m_thermo->pressure()/Pc_mix; - double ratio = MW_H/MW_L; - double ksi = pow(GasConstant*Tc_mix*3.6277*pow(10.0,53.0)/(pow(MW_mix,3) - *pow(Pc_mix,4)),1.0/6.0); + // Compute the mixture value of the low-pressure quantum correction factor + double ratio = MW_H/MW_L; + double A = 1.0; if (ratio > 9 && x_H > 0.05 && x_H < 0.7) { - FQ_mix_o *= 1 - 0.01*pow(ratio,0.87); + A = 1 - 0.01*pow(ratio,0.87); } + FQ_mix_o *= A; - // Calculate Z1m - double Z1m = (0.807*pow(Tr_mix,0.618) - 0.357*exp(-0.449*Tr_mix) - + 0.340*exp(-4.058*Tr_mix)+0.018)*FP_mix_o*FQ_mix_o; - - // Calculate Z2m: - double Z2m; - if (Tr_mix <= 1.0) { - if (Pr_mix < Pvp_mix/Pc_mix) { - double alpha = 3.262 + 14.98*pow(Pr_mix,5.508); - double beta = 1.390 + 5.746*Pr_mix; - Z2m = 0.600 + 0.760*pow(Pr_mix,alpha) + (0.6990*pow(Pr_mix,beta) - - 0.60)*(1- Tr_mix); - } else { - throw CanteraError("HighPressureGasTransport::viscosity", - "State is outside the limits of the Lucas model, Tr <= 1"); - } - } else if ((Tr_mix > 1.0) && (Tr_mix < 40.0)) { - if ((Pr_mix > 0.0) && (Pr_mix <= 100.0)) { - double a_fac = 0.001245*exp(5.1726*pow(Tr_mix,-0.3286))/Tr_mix; - double b_fac = a_fac*(1.6553*Tr_mix - 1.2723); - double c_fac = 0.4489*exp(3.0578*pow(Tr_mix,-37.7332))/Tr_mix; - double d_fac = 1.7368*exp(2.2310*pow(Tr_mix,-7.6351))/Tr_mix; - double f_fac = 0.9425*exp(-0.1853*pow(Tr_mix,0.4489)); - - Z2m = Z1m*(1 + a_fac*pow(Pr_mix,1.3088)/(b_fac*pow(Pr_mix,f_fac) - + pow(1+c_fac*pow(Pr_mix,d_fac),-1))); - } else { - throw CanteraError("HighPressureGasTransport::viscosity", - "State is outside the limits of the Lucas model, 1.0 < Tr < 40"); - } - } else { - throw CanteraError("HighPressureGasTransport::viscosity", - "State is outside the limits of the Lucas model, Tr > 40"); - } - // Calculate Y: - double Y = Z2m/Z1m; + // This is η*ξ + double nondimensional_viscosity = high_pressure_nondimensional_viscosity(Tr_mix, Pr_mix, FP_mix_o, FQ_mix_o, P_vap_mix, Pc_mix); + + // Using equation 9-4.14 in Poling et al. (2001), with units of 1/(Pa*s) + double numerator = GasConstant*Tc_mix*pow(Avogadro,2.0); + double denominator = pow(MW_mix,3.0)*pow(Pc_mix,4.0); + double ksi = pow(numerator / denominator, 1.0/6.0); - // Return the viscosity: - return Z2m*(1 + (FP_mix_o - 1)*pow(Y,-3))*(1 + (FQ_mix_o - 1) - *(1/Y - 0.007*pow(log(Y),4)))/(ksi*FP_mix_o*FQ_mix_o); + // Return the viscosity in kg/m/s + return nondimensional_viscosity / ksi; } // Pure species critical properties - Tc, Pc, Vc, Zc: double HighPressureGasTransport::Tcrit_i(size_t i) { - vector molefracs(m_thermo->nSpecies()); + vector molefracs(m_thermo->nSpecies()); m_thermo->getMoleFractions(&molefracs[0]); vector mf_temp(m_thermo->nSpecies(), 0.0); mf_temp[i] = 1; @@ -433,14 +318,18 @@ double HighPressureGasTransport::Zcrit_i(size_t i) // The low-pressure nondimensional viscosity equation 9-4.16 in Poling et al. (2001). // This relation is used for pure species and mixtures at low pressure. The only -// difference is the the values that are passed to the function. +// difference is the the values that are passed to the function (pure values versus mixture values). double HighPressureGasTransport::low_pressure_nondimensional_viscosity(double Tr, double FP, double FQ) { double first_term = 0.807*pow(Tr,0.618) - 0.357*exp(-0.449*Tr); double second_term = 0.340*exp(-4.058*Tr) + 0.018; return (first_term + second_term)*FP*FQ; } - +// The high-pressure nondimensional viscosity equation 9-6.12 in Poling et al. (2001). +// This relation is used for pure species and mixtures at high pressure. The only +// difference is the the values that are passed to the function (pure values versus mixture values). +// This returns the value of η*ξ (by multiplying both sides of 9-6.12 by ξ and simply returning the RHS of the +// resulting equation) double HighPressureGasTransport::high_pressure_nondimensional_viscosity(double Tr, double Pr, double FP_low, double FQ_low, double P_vap, double P_crit){ double Z_1 = low_pressure_nondimensional_viscosity(Tr, FP_low, FQ_low); // This is η_0*ξ @@ -584,3 +473,193 @@ double HighPressureGasTransport::compute_correction_factor(double Pr, double Tr) } } + + +namespace Cantera +{ + + +double ChungHighPressureGasTransport::viscosity() +{ + + // Vc needs to be in units of cm^3/mol + // Starting on page 9-7 in the "Method of Chung, et. al. (1984, 1988)" section + double epsilon_over_k = Tc / 1.2593; + + // Equation 9-4.1 + double T_star = T / epsilon_over_k; + +} + + + +// Implementation of equation the mixing rules defined on page 9.25 of Poling et al. (2001) +// for the Chung method's composition dependent parameters. +void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParameters& params) +{ + + size_t nsp = m_thermo->nSpecies(); + vector molefracs(nsp); + m_thermo->getMoleFractions(&molefracs[0]); + + + // First fill the species-specific values that will then later be used in the combining + // rules for the Chung method. + vector sigma_i(nsp), epsilon_over_k_i(nsp), acentric_factor_i(nsp), MW_i(nsp), kappa_i(nsp); + for (size_t i = 0; i < m_nsp; i++) { + // From equation 9-5.32 in Poling et al. (2001) + sigma_i[i] = 0.809*pow(Vcrit_i(i), 1.0/3.0); + + // From equation 9-5.34 in Poling et al. (2001) + epsilon_over_k_i[i] = Tcrit_i(i)/1.2593; + + // NOTE: The association parameter is assumed to be zero for all species, but + // is left here for completeness or future revision. + kappa_i[i] = 0.0; + + // These values are available from the base class + acentric_factor_i[i] = m_w_ac[i]; + MW_i[i] = m_mw[i]; + } + + // Here we use the combining rules defined on page 9.25 of Poling et al. (2001) + // We have ASSUMED that the binary interaction parameters are unity for all species + // as was done in the Chung method. + // + // The sigma & kappa relations can be fully computed in the loop. The other ones require a final + // division by the final mixture values, and so the quantities in the loop are only the + // numerators of the equations that are referenced in the comments. After the loop, the + // final mixture values are computed and stored. + for (size_t i = 0; i < m_nsp; i++) { + for (size_t j = 0; j a = {6.324, 1.210e-3, 5.283, 6.623, 19.745, -1.900, 24.275, 0.7972, -0.2382, 0.06863}; + vector b = {50.412, -1.154e-3, 254.209, 38.096, 7.630, -12.537, 3.450, 1.117, 0.06770, 0.3479}; + vector c = {-51.680, -6.257e-3, -168.48, -8.464, -14.354, 4.958, -11.291, 0.01235, -0.8163, 0.5926}; + vector d ={1189.0, 0.03728, 3898.0, 31.42, 31.53, -18.15, 69.35, -4.117, 4.025, -0.727}; + + // This is slightly pedantic, but this is done to have the naming convention in the + // equations used match the variable names in the code. + double E_1, E_2, E_3, E_4, E_5, E_6, E_7, E_8, E_9, E_10; + E_1 = a[0] + b[0]*acentric_factor + c[0]*pow(mu_r, 4.0) + d[0]*kappa; + E_2 = a[1] + b[1]*acentric_factor + c[1]*pow(mu_r, 4.0) + d[1]*kappa; + E_3 = a[2] + b[2]*acentric_factor + c[2]*pow(mu_r, 4.0) + d[2]*kappa; + E_4 = a[3] + b[3]*acentric_factor + c[3]*pow(mu_r, 4.0) + d[3]*kappa; + E_5 = a[4] + b[4]*acentric_factor + c[4]*pow(mu_r, 4.0) + d[4]*kappa; + E_6 = a[5] + b[5]*acentric_factor + c[5]*pow(mu_r, 4.0) + d[5]*kappa; + E_7 = a[6] + b[6]*acentric_factor + c[6]*pow(mu_r, 4.0) + d[6]*kappa; + E_8 = a[7] + b[7]*acentric_factor + c[7]*pow(mu_r, 4.0) + d[7]*kappa; + E_9 = a[8] + b[8]*acentric_factor + c[8]*pow(mu_r, 4.0) + d[8]*kappa; + E_10 = a[9] + b[9]*acentric_factor + c[9]*pow(mu_r, 4.0) + d[9]*kappa; + + double y = rho*Vc/6.0; // Equation 9-6.20 + + double G_1 = (1.0 - 0.5*y)/(pow(1.0-y, 3.0)); // Equation 9-6.21 + + // Equation 9-6.22 + double G_2 = (E_1*((1.0-exp(-E_4*y)) / y) + E_2*G_1*exp(E_5*y) + E_3*G_1)/ (E_1*E_4 + E_2 + E_3); + + double eta_2 = E_7*y*y*G_2*exp(E_8 + E_9/T_star + E_10/(T_star*T_star)); // Equation 9-6.23 + + // Equation 9-4.3 in Poling et al. (2001) + double omega = neufeld_collision_integral(T_star); + + // Molecular shapes and polarities factor, equation 9-4.11 + double Fc = 1 -0.2756*acentric_factor + 0.059035*pow(mu_r, 4.0) + kappa; + + double eta_1 = (sqrt(T_star)/omega) * (Fc*(1.0/G_2 + E_6*y)) + eta_2; // Equation 9-6.19 + + double eta = eta_1 * 36.344 * sqrt(MW*Tc) / pow(Vc, 2.0/3.0); // Equation 9-6.18 + + return eta +} + + +} \ No newline at end of file From d6d60fe12e801693d390a01978c22053a2b96f8f Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Wed, 5 Jun 2024 19:07:18 -0400 Subject: [PATCH 03/37] added a test, and fixed names for transport objects --- .../transport/HighPressureGasTransport.h | 5 +- src/transport/HighPressureGasTransport.cpp | 94 ++++++++++--------- src/transport/TransportFactory.cpp | 1 + test/python/test_transport.py | 13 +++ 4 files changed, 64 insertions(+), 49 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index 202a18adcd..e158b1480f 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -11,7 +11,6 @@ // Cantera includes #include "GasTransport.h" -#include "cantera/numerics/DenseMatrix.h" #include "cantera/transport/MixTransport.h" namespace Cantera @@ -45,7 +44,7 @@ class HighPressureGasTransport : public MixTransport public: string transportModel() const override { - return "HighPressureGas"; + return "high-pressure"; } double thermalConductivity() override; @@ -148,7 +147,7 @@ class ChungHighPressureGasTransport : public MixTransport public: string transportModel() const override { - return "ChungHighPressureGas"; + return "high-pressure-chung"; } double viscosity() override; diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 8841e03a56..96992c31d4 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -7,7 +7,6 @@ // at https://cantera.org/license.txt for license and copyright information. #include "cantera/transport/HighPressureGasTransport.h" -#include "cantera/numerics/ctlapack.h" #include "cantera/base/utilities.h" #include "cantera/thermo/IdealGasPhase.h" #include "cantera/transport/TransportFactory.h" @@ -401,14 +400,6 @@ double HighPressureGasTransport::FQ_i(double Q, double Tr, double MW) *sign(Tr - 12.0)); } -// Sign function for use in the quantum correction term calculation. -template -int sign(T val) { - if (val > 0) return 1; - if (val < 0) return -1; - return 0; -} - // Calculates the pressure correction factor for the Lucas method that // is used to calculate high pressure pure fluid viscosity. This is equation // 9-4.18 in Poling et al. (2001): @@ -425,6 +416,12 @@ double HighPressureGasTransport::FP_i(double mu_r, double Tr, double Z_crit) double HighPressureGasTransport::compute_correction_factor(double Pr, double Tr) { + // In the low pressure limit, no correction is needed. Interpolate + // the value towards 1 as pressure drops below the 0.1 threshold. + if (Pr < 0.1) { + return 1.0; + } + // Data from Table 2 of Takahashi 1975 paper: const static double Pr_lookup[17] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0, 4.0, 5.0}; @@ -442,25 +439,22 @@ double HighPressureGasTransport::compute_correction_factor(double Pr, double Tr) 14., 10.00900, 8.57519, 10.37483, 11.21674, 1., 6.19043, 1., 1.}; // Interpolate to obtain the value of the constants (DP)_R, A, B, C, E at - // the provided value of the reduced pressure (Pr): + // the provided value of the reduced pressure (Pr). int Pr_i = 0; double frac = 0.0; double A, B, C,E, DP_Rt; - if (Pr < 0.1) { // In the low pressure limit, no correction is needed: - frac = (Pr - Pr_lookup[0])/(Pr_lookup[1] - Pr_lookup[0]); - } else { - for (int j = 1; j < 17; j++) { - if (Pr_lookup[j] > Pr) { - frac = (Pr - Pr_lookup[j-1])/(Pr_lookup[j] - Pr_lookup[j-1]); - break; - } - Pr_i++; + for (int j = 1; j < 17; j++){ + if (Pr_lookup[j] > Pr) { + frac = (Pr - Pr_lookup[j-1])/(Pr_lookup[j] - Pr_lookup[j-1]); + break; } - // If this loop completes without finding a bounding value of Pr, use - // the final table value. - frac = 1.0; + Pr_i++; } + // If this loop completes without finding a bounding value of Pr, use + // the final table value. + frac = 1.0; + DP_Rt = DP_Rt_lookup[Pr_i]*(1.0 - frac) + DP_Rt_lookup[Pr_i+1]*frac; A = A_ij_lookup[Pr_i]*(1.0 - frac) + A_ij_lookup[Pr_i+1]*frac; @@ -478,16 +472,25 @@ double HighPressureGasTransport::compute_correction_factor(double Pr, double Tr) namespace Cantera { - +// This implements the high-pressure gas mixture viscosity model of Chung +// described in chapter 9-7 of Poling et al. (2001). double ChungHighPressureGasTransport::viscosity() { + ChungMixtureParameters params; + compute_mixture_parameters(params); + + // Compute T_star using equation 9-5.26, using the mixture parameters + double tKelvin = m_thermo->temperature(); + double T_star = tKelvin / params.epsilon_over_k_mix; + + double density = m_thermo->density(); // The density is required for high-pressure gases - // Vc needs to be in units of cm^3/mol - // Starting on page 9-7 in the "Method of Chung, et. al. (1984, 1988)" section - double epsilon_over_k = Tc / 1.2593; + // This result is in units of micropoise + double viscosity = high_pressure_viscosity(T_star, params.MW_mix, density, params.Vc_mix, params.Tc_mix, params.acentric_factor_mix, params.mu_r_mix, params.kappa_mix); - // Equation 9-4.1 - double T_star = T / epsilon_over_k; + double micropoise_to_pascals_second = 1e-7; + + return viscosity*micropoise_to_pascals_second; } @@ -577,23 +580,6 @@ void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParam } -// This function is structured such that it can be used for pure species or mixtures, with the -// only difference being the values that are passed to the function (pure values versus mixture values). -double ChungHighPressureGasTransport::low_pressure_viscosity(double T, double T_star, double MW, double acentric_factor, double mu_r, double sigma, double kappa) -{ - // Equation 9-4.3 in Poling et al. (2001) - double omega = neufeld_collision_integral(T_star); - - // Molecular shapes and polarities factor, equation 9-4.11 - double Fc = 1 -0.2756*acentric_factor + 0.059035*pow(mu_r, 4.0) + kappa; - - // Equation 9-3.9 in Poling et al. (2001), multiplied by the Chung factor, Fc - // (another way of writing 9-4.10 that avoids explicit use of the critical volume in this method) - double viscosity = Fc* (26.69*sqrt(MW*T)/(sigma*sigma*omega)); - - return viscosity; -} - // Implementation of equation 9-4.3 in Poling et al. (2001). // Applicable over the range of 0.3 <= T_star <= 100. double neufeld_collision_integral(double T_star) @@ -610,6 +596,22 @@ double neufeld_collision_integral(double T_star) return omega; } +// This function is structured such that it can be used for pure species or mixtures, with the +// only difference being the values that are passed to the function (pure values versus mixture values). +double ChungHighPressureGasTransport::low_pressure_viscosity(double T, double T_star, double MW, double acentric_factor, double mu_r, double sigma, double kappa) +{ + // Equation 9-4.3 in Poling et al. (2001) + double omega = neufeld_collision_integral(T_star); + + // Molecular shapes and polarities factor, equation 9-4.11 + double Fc = 1 -0.2756*acentric_factor + 0.059035*pow(mu_r, 4.0) + kappa; + + // Equation 9-3.9 in Poling et al. (2001), multiplied by the Chung factor, Fc + // (another way of writing 9-4.10 that avoids explicit use of the critical volume in this method) + double viscosity = Fc* (26.69*sqrt(MW*T)/(sigma*sigma*omega)); + + return viscosity; +} // Computes the high-pressure viscosity using the Chung method (Equation 9-6.18). // This function is structured such that it can be used for pure species or mixtures, with the @@ -658,7 +660,7 @@ double ChungHighPressureGasTransport::high_pressure_viscosity(double T_star, dou double eta = eta_1 * 36.344 * sqrt(MW*Tc) / pow(Vc, 2.0/3.0); // Equation 9-6.18 - return eta + return eta; } diff --git a/src/transport/TransportFactory.cpp b/src/transport/TransportFactory.cpp index f721ca08e0..ceef2150dc 100644 --- a/src/transport/TransportFactory.cpp +++ b/src/transport/TransportFactory.cpp @@ -46,6 +46,7 @@ TransportFactory::TransportFactory() addDeprecatedAlias("water", "Water"); reg("high-pressure", []() { return new HighPressureGasTransport(); }); addDeprecatedAlias("high-pressure", "HighP"); + reg("high-pressure-chung", []() { return new ChungHighPressureGasTransport(); }); m_CK_mode["CK_Mix"] = m_CK_mode["mixture-averaged-CK"] = true; m_CK_mode["CK_Multi"] = m_CK_mode["multicomponent-CK"] = true; } diff --git a/test/python/test_transport.py b/test/python/test_transport.py index 513958c631..c1ea726b1d 100644 --- a/test/python/test_transport.py +++ b/test/python/test_transport.py @@ -147,6 +147,19 @@ def test_add_species_multi(self, cantera_data_path): assert gas1.thermal_conductivity == approx(gas2.thermal_conductivity) assert gas1.multi_diff_coeffs == approx(gas2.multi_diff_coeffs) + def test_high_pressure_chung_viscosity(self): + state = 520, 6e7, 'NH3:1.0' + + gas1 = ct.Solution('gri30.yaml') + gas1.transport_model = 'high-pressure-chung' + gas1.TPX = state + + # Values from Poling et al. (2001), example 9-12 for ammonia + experimental_viscosity = 466e-7 # 466 micropoise = 466e-7 Pa s + + error = abs(gas1.viscosity - experimental_viscosity) / experimental_viscosity + assert error <= 0.05 # Error should be less than 5% + def test_species_visosities(self, phase): for species_name in phase.species_names: # check that species viscosity matches overall for single-species From fff6bd4d215f7675037a01f9a624a8aab18bd8d7 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Thu, 6 Jun 2024 19:25:00 -0400 Subject: [PATCH 04/37] working Chung method, bug fixes in Lucas method --- .../transport/HighPressureGasTransport.h | 13 +- src/transport/HighPressureGasTransport.cpp | 399 +++++++++++++++--- 2 files changed, 344 insertions(+), 68 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index e158b1480f..bed713d5a7 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -93,15 +93,6 @@ class HighPressureGasTransport : public MixTransport */ double FP_i(double mu_r, double Tr, double Z_c); - /** - * @brief Returns interpolated value of (DP)_R obtained from the data - * in Table 2 of the Takahashi 1975 paper, given a value of the reduced - * pressure (Pr) and reduced temperature (Tr). - * - * @param Pr Reduced pressure - * @param Tr Reduced temperature -\ */ - double compute_correction_factor(double Pr, double Tr); }; @@ -186,7 +177,9 @@ class ChungHighPressureGasTransport : public MixTransport // Computes and store composition-dependent values of the parameters needed for the Chung viscosity model. void compute_mixture_parameters(ChungMixtureParameters& params); - + // Computes the thermal conductivity using the Chung method (Equation 10-5.5). + // Gives thermal conductivity in units of W/m/K + double high_pressure_thermal_conductivity(double T, double T_star, double MW, double rho, double Cv, double Vc, double Tc, double sigma, double acentric_factor, double mu_r, double kappa); /** * @brief Returns interpolated value of (DP)_R obtained from the data diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 96992c31d4..d42817284f 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -18,6 +18,68 @@ using namespace std; namespace Cantera { +/** + * @brief Returns interpolated value of (DP)_R obtained from the data + * in Table 2 of the Takahashi 1975 paper, given a value of the reduced + * pressure (Pr) and reduced temperature (Tr). + * + * @param Pr Reduced pressure + * @param Tr Reduced temperature + */ +double takahashi_correction_factor(double Pr, double Tr) +{ + // In the low pressure limit, no correction is needed. Interpolate + // the value towards 1 as pressure drops below the 0.1 threshold. + if (Pr < 0.1) { + return 1.0; + } + + // Data from Table 2 of Takahashi 1975 paper: + const static double Pr_lookup[17] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1.0, + 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0, 4.0, 5.0}; + const static double DP_Rt_lookup[17] = {1.01, 1.01, 1.01, 1.01, 1.01, 1.01, + 1.01, 1.02, 1.02, 1.02, 1.02, 1.03, 1.03, 1.04, 1.05, 1.06, 1.07}; + const static double A_ij_lookup[17] = {0.038042, 0.067433, 0.098317, + 0.137610, 0.175081, 0.216376, 0.314051, 0.385736, 0.514553, 0.599184, + 0.557725, 0.593007, 0.696001, 0.790770, 0.502100, 0.837452, 0.890390}; + const static double B_ij_lookup[17] = {1.52267, 2.16794, 2.42910, 2.77605, + 2.98256, 3.11384, 3.50264, 3.07773, 3.54744, 3.61216, 3.41882, 3.18415, + 3.37660, 3.27984, 3.39031, 3.23513, 3.13001}; + const static double C_ij_lookup[17] = {0., 0., 0., 0., 0., 0., 0., 0.141211, + 0.278407, 0.372683, 0.504894, 0.678469, 0.665702, 0., 0.602907, 0., 0.}; + const static double E_ij_lookup[17] = {1., 1., 1., 1., 1., 1., 1., 13.45454, + 14., 10.00900, 8.57519, 10.37483, 11.21674, 1., 6.19043, 1., 1.}; + + // Interpolate to obtain the value of the constants (DP)_R, A, B, C, E at + // the provided value of the reduced pressure (Pr). + int Pr_i = 0; + double frac = 0.0; + double A, B, C,E, DP_Rt; + + for (int j = 1; j < 17; j++){ + if (Pr_lookup[j] > Pr) { + frac = (Pr - Pr_lookup[j-1])/(Pr_lookup[j] - Pr_lookup[j-1]); + break; + } + Pr_i++; + } + // If this loop completes without finding a bounding value of Pr, use + // the final table value. + frac = 1.0; + + + DP_Rt = DP_Rt_lookup[Pr_i]*(1.0 - frac) + DP_Rt_lookup[Pr_i+1]*frac; + A = A_ij_lookup[Pr_i]*(1.0 - frac) + A_ij_lookup[Pr_i+1]*frac; + B = B_ij_lookup[Pr_i]*(1.0 - frac) + B_ij_lookup[Pr_i+1]*frac; + C = C_ij_lookup[Pr_i]*(1.0 - frac) + C_ij_lookup[Pr_i+1]*frac; + E = E_ij_lookup[Pr_i]*(1.0 - frac) + E_ij_lookup[Pr_i+1]*frac; + + double DP_R = DP_Rt*(1.0 - A*pow(Tr,-B))*(1.0 - C*pow(Tr,-E)); + return DP_R; +} + + + double HighPressureGasTransport::thermalConductivity() { // Method of Ely and Hanley: @@ -141,7 +203,7 @@ void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* cons // Calculate the parameters for Takahashi correlation double P_corr_ij; - P_corr_ij = compute_correction_factor(Pr_ij, Tr_ij); + P_corr_ij = takahashi_correction_factor(Pr_ij, Tr_ij); // If the reduced temperature is too low, the correction factor // P_corr_ij will be < 0. @@ -195,7 +257,7 @@ double HighPressureGasTransport::viscosity() double Zc = Zcrit_i(i); Tc_mix += Tc*molefracs[i]; Pc_mix_n += molefracs[i]*Zc; //numerator - Pc_mix_d += molefracs[i]*Vcrit_i(i); //denominator + Pc_mix_d += molefracs[i]*Vcrit_i(i); //denominator (Units of Vcrit_i are m^3/kmol, which are fine because they cancel out with the Cantera gas constant's units used later) // Calculate ratio of heaviest to lightest species if (m_mw[i] > MW_H) { @@ -209,8 +271,12 @@ double HighPressureGasTransport::viscosity() // polar correction term. // Equation 9-4.17 in Poling et al. (2001) requires the pressure // to be in units of bar, so we convert from Pa to bar. + // The dipole moment is stored in SI units, and it needs to be in + // units of Debye for the Lucas method. double pascals_to_bar = 1e-5; - double mu_ri = 52.46*m_dipole(i,i)*m_dipole(i,i)*(Pcrit_i(i)*pascals_to_bar)/(Tc*Tc); + double SI_to_Debye = 1.0 / 3.335e-30; // Conversion factor from C*m to Debye + double dipole_ii = m_dipole(i,i)*SI_to_Debye; + double mu_ri = 52.46*dipole_ii*dipole_ii*(Pcrit_i(i)*pascals_to_bar)/(Tc*Tc); FP_mix_o += molefracs[i] * FP_i(mu_ri, Tr, Zc); // mole-fraction weighting of pure-species polar correction term @@ -331,6 +397,14 @@ double HighPressureGasTransport::low_pressure_nondimensional_viscosity(double Tr // resulting equation) double HighPressureGasTransport::high_pressure_nondimensional_viscosity(double Tr, double Pr, double FP_low, double FQ_low, double P_vap, double P_crit){ + //cout << "Input values are:" << endl; + //cout << "Tr: " << Tr << endl; + //cout << "Pr: " << Pr << endl; + //cout << "FP_low: " << FP_low << endl; + //cout << "FQ_low: " << FQ_low << endl; + //cout << "P_vap: " << P_vap << endl; + //cout << "P_crit: " << P_crit << endl; + double Z_1 = low_pressure_nondimensional_viscosity(Tr, FP_low, FQ_low); // This is η_0*ξ double Z_2; @@ -393,7 +467,7 @@ double HighPressureGasTransport::high_pressure_nondimensional_viscosity(double T // Calculates quantum correction term of the Lucas method for a species based // on Tr and MW, used in viscosity calculation from equation 9-4.19 in -// Poling et al. (2001): +// Poling et al. (2001) double HighPressureGasTransport::FQ_i(double Q, double Tr, double MW) { return 1.22*pow(Q,0.15)*(1 + 0.00385*pow(pow(Tr - 12.0, 2.0), 1.0/MW) @@ -402,75 +476,185 @@ double HighPressureGasTransport::FQ_i(double Q, double Tr, double MW) // Calculates the pressure correction factor for the Lucas method that // is used to calculate high pressure pure fluid viscosity. This is equation -// 9-4.18 in Poling et al. (2001): +// 9-4.18 in Poling et al. (2001). +// +// NOTE: The original description in the book neglects to mention what happens +// when the quantity raised to the 1.72 power goes negative. That is an undefined +// operation that generates real+imaginary numbers. For now, I simply am +// taking the absolute value of the argument and raising it to the power. double HighPressureGasTransport::FP_i(double mu_r, double Tr, double Z_crit) { + //cout << "HighPressureGasTransport::FP_i Inputs:" << endl; + //cout << "mu_r: " << mu_r << endl; + //cout << "Tr: " << Tr << endl; + //cout << "Z_crit: " << Z_crit << endl; + if (mu_r < 0.022) { return 1; } else if (mu_r < 0.075) { - return 1 + 30.55*pow(0.292 - Z_crit, 1.72); + return 1 + 30.55*pow(fabs(0.292 - Z_crit), 1.72); } else { - return 1 + 30.55*pow(0.292 - Z_crit, 1.72)*fabs(0.96 + 0.1*(Tr - 0.7)); + return 1 + 30.55*pow(fabs(0.292 - Z_crit), 1.72)*fabs(0.96 + 0.1*(Tr - 0.7)); } } -double HighPressureGasTransport::compute_correction_factor(double Pr, double Tr) +} + +//Chung Implementation +namespace Cantera { - // In the low pressure limit, no correction is needed. Interpolate - // the value towards 1 as pressure drops below the 0.1 threshold. - if (Pr < 0.1) { - return 1.0; + +void ChungHighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* const d) +{ + size_t nsp = m_thermo->nSpecies(); + vector molefracs(nsp); + m_thermo->getMoleFractions(&molefracs[0]); + + update_T(); + // If necessary, evaluate the binary diffusion coefficients from the polynomial fits + if (!m_bindiff_ok) { + updateDiff_T(); + } + if (ld < m_nsp) { + throw CanteraError("ChungHighPressureGasTransport::getBinaryDiffCoeffs", "ld is too small"); } - // Data from Table 2 of Takahashi 1975 paper: - const static double Pr_lookup[17] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1.0, - 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0, 4.0, 5.0}; - const static double DP_Rt_lookup[17] = {1.01, 1.01, 1.01, 1.01, 1.01, 1.01, - 1.01, 1.02, 1.02, 1.02, 1.02, 1.03, 1.03, 1.04, 1.05, 1.06, 1.07}; - const static double A_ij_lookup[17] = {0.038042, 0.067433, 0.098317, - 0.137610, 0.175081, 0.216376, 0.314051, 0.385736, 0.514553, 0.599184, - 0.557725, 0.593007, 0.696001, 0.790770, 0.502100, 0.837452, 0.890390}; - const static double B_ij_lookup[17] = {1.52267, 2.16794, 2.42910, 2.77605, - 2.98256, 3.11384, 3.50264, 3.07773, 3.54744, 3.61216, 3.41882, 3.18415, - 3.37660, 3.27984, 3.39031, 3.23513, 3.13001}; - const static double C_ij_lookup[17] = {0., 0., 0., 0., 0., 0., 0., 0.141211, - 0.278407, 0.372683, 0.504894, 0.678469, 0.665702, 0., 0.602907, 0., 0.}; - const static double E_ij_lookup[17] = {1., 1., 1., 1., 1., 1., 1., 13.45454, - 14., 10.00900, 8.57519, 10.37483, 11.21674, 1., 6.19043, 1., 1.}; + double rp = 1.0/m_thermo->pressure(); + for (size_t i = 0; i < nsp; i++) { + for (size_t j = 0; j < nsp; j++) { + // Add an offset to avoid a condition where x_i and x_j both equal + // zero (this would lead to Pr_ij = Inf). + double x_i = std::max(Tiny, molefracs[i]); + double x_j = std::max(Tiny, molefracs[j]); - // Interpolate to obtain the value of the constants (DP)_R, A, B, C, E at - // the provided value of the reduced pressure (Pr). - int Pr_i = 0; - double frac = 0.0; - double A, B, C,E, DP_Rt; + // Weight mole fractions of i and j so that X_i + X_j = 1.0. + x_i = x_i/(x_i + x_j); + x_j = x_j/(x_i + x_j); - for (int j = 1; j < 17; j++){ - if (Pr_lookup[j] > Pr) { - frac = (Pr - Pr_lookup[j-1])/(Pr_lookup[j] - Pr_lookup[j-1]); - break; + // Calculate Tr and Pr based on mole-fraction-weighted critical constants. + double Tr_ij = m_temp/(x_i*Tcrit_i(i) + x_j*Tcrit_i(j)); + double Pr_ij = m_thermo->pressure()/(x_i*Pcrit_i(i) + x_j*Pcrit_i(j)); + + // Calculate the parameters for Takahashi correlation + double P_corr_ij; + P_corr_ij = takahashi_correction_factor(Pr_ij, Tr_ij); + + // If the reduced temperature is too low, the correction factor + // P_corr_ij will be < 0. + if (P_corr_ij<0) { + P_corr_ij = Tiny; + } + // Multiply the standard low-pressure binary diffusion coefficient + // (m_bdiff) by the Takahashi correction factor P_corr_ij. + d[ld*j + i] = P_corr_ij*(rp * m_bdiff(i,j)); } - Pr_i++; } - // If this loop completes without finding a bounding value of Pr, use - // the final table value. - frac = 1.0; +} +// Calculate the high-pressure mixture thermal conductivity, based on the Chung method +// described in on page 10.23 of Poling et al. (2001). +// +// The mixture pseudo-critical temperature and pressure are calculated using +// the equations defined on page 9.25 of Poling et al. (2001). +// +// The mixture value of the specific heat is computed using equation 10-6.6. +double ChungHighPressureGasTransport::thermalConductivity() +{ + ChungMixtureParameters params; + compute_mixture_parameters(params); - DP_Rt = DP_Rt_lookup[Pr_i]*(1.0 - frac) + DP_Rt_lookup[Pr_i+1]*frac; - A = A_ij_lookup[Pr_i]*(1.0 - frac) + A_ij_lookup[Pr_i+1]*frac; - B = B_ij_lookup[Pr_i]*(1.0 - frac) + B_ij_lookup[Pr_i+1]*frac; - C = C_ij_lookup[Pr_i]*(1.0 - frac) + C_ij_lookup[Pr_i+1]*frac; - E = E_ij_lookup[Pr_i]*(1.0 - frac) + E_ij_lookup[Pr_i+1]*frac; + // Compute T_star using equation 9-5.26, using the mixture parameters + double tKelvin = m_thermo->temperature(); + double T_star = tKelvin / params.epsilon_over_k_mix; - double DP_R = DP_Rt*(1.0 - A*pow(Tr,-B))*(1.0 - C*pow(Tr,-E)); - return DP_R; -} + // The density is required for high-pressure gases. + // The Chung method requires density to be units of mol/cm^3 + // We use the mixture molecular weight (units of kg/kmol) here. + double kg_per_m3_to_mol_per_cm3 = (1.0 / params.MW_mix)*1e-3; // 1 kmol/m^3 = 1e-3 mol/cm^3 + double density = m_thermo->density()*kg_per_m3_to_mol_per_cm3; + + // The value of Cv is already a mole-weighted average of the pure species values + double Cv_mix = m_thermo->cv_mole(); // Specific heat at constant volume, units are J/kmol/K + // This result is in units of W/m/K + double thermal_conductivity = high_pressure_thermal_conductivity(tKelvin, T_star, params.MW_mix, density, Cv_mix, params.Vc_mix, params.Tc_mix, params.sigma_mix, params.acentric_factor_mix, params.mu_r_mix, params.kappa_mix); + + // Return the thermal conductivity in W/m/K + return thermal_conductivity; } -namespace Cantera + +// Computes the high-pressure thermal conductivity using the Chung method (Equation 10-5.5). +// This function is structured such that it can be used for pure species or mixtures, with the +// only difference being the values that are passed to the function (pure values versus mixture values). +// +// This method utilizes the low-pressure Chung viscosity as that is a required parameter in the model, and +// thus makes a call to the low pressure viscosity implementation. +// +// M_prime (M' in the model) has units of kg/mol, and is just the molecular weight (kg/kmol) divided by 1000. +double ChungHighPressureGasTransport::high_pressure_thermal_conductivity(double T, double T_star, double MW, double rho, double Cv, double Vc, double Tc, double sigma, double acentric_factor, double mu_r, double kappa) { + // Calculate the low-pressure viscosity using the Chung method + // This method returns viscosity in micropoise, but the thermal + // conductivity model needs the low-pressure viscosity to be in units of Pa*s + double micropoise_to_pascals_second = 1e-7; + double viscosity = low_pressure_viscosity(T, T_star, MW, acentric_factor, mu_r, sigma, kappa)*micropoise_to_pascals_second; + //cout << "Low-pressure viscosity: " << viscosity << " Pa*s" << endl; + + double M_prime = MW / 1000.0; // Converting to kg/mol + + // Definition of tabulated coefficients for the Chung method, as shown in Table 10-3 on page 10.23 of Poling et al. (2001) + vector a = {2.44166, -5.0924e-1, 6.6107, 1.4543e1, 7.9274e-1, -5.8634, 9.1089e1}; + vector b = {7.4824e-1, -1.5094, 5.6207, -8.9139, 8.2019e-1, 1.2801e1, 1.2811e2}; + vector c = {-9.1858e-1, -4.9991e1, 6.4760e1, -5.6379, -6.9369e-1, 9.5893, -5.4217e1}; + vector d ={1.2172e2, 6.9983e1, 2.7039e1, 7.4344e1, 6.3173, 6.5529e1, 5.2381e2}; + + // This is slightly pedantic, but this is done to have the naming convention in the + // equations used match the variable names in the code. + double B_1, B_2, B_3, B_4, B_5, B_6, B_7; + B_1 = a[0] + b[0]*acentric_factor + c[0]*pow(mu_r, 4.0) + d[0]*kappa; + B_2 = a[1] + b[1]*acentric_factor + c[1]*pow(mu_r, 4.0) + d[1]*kappa; + B_3 = a[2] + b[2]*acentric_factor + c[2]*pow(mu_r, 4.0) + d[2]*kappa; + B_4 = a[3] + b[3]*acentric_factor + c[3]*pow(mu_r, 4.0) + d[3]*kappa; + B_5 = a[4] + b[4]*acentric_factor + c[4]*pow(mu_r, 4.0) + d[4]*kappa; + B_6 = a[5] + b[5]*acentric_factor + c[5]*pow(mu_r, 4.0) + d[5]*kappa; + B_7 = a[6] + b[6]*acentric_factor + c[6]*pow(mu_r, 4.0) + d[6]*kappa; + + double y = rho*Vc/6.0; // Equation 10-5.6 (with rho = 1/V) + + double G_1 = (1.0 - 0.5*y)/(pow(1.0-y, 3.0)); // Equation 10-5.7 + + // Equation 10-5.8 + double G_2 = (B_1*((1.0-exp(-B_4*y)) / y) + B_2*G_1*exp(B_5*y) + B_3*G_1)/ (B_1*B_4 + B_2 + B_3); + + double q = 3.586e-3*sqrt(Tc/M_prime) / pow(Vc, 2.0/3.0); // Shown below equation 10-5.5 + + double Tr = T/Tc; // Reduced temperature + double alpha = (Cv / GasConstant) - 3.0/2.0; // Shown below equation 10-3.14, using Cantera's R (J/kmol/K ) + double beta = 0.7862 - 0.7109*acentric_factor + 1.3168*acentric_factor*acentric_factor; // Shown below Equation 10-3.14 + double Z = 2.0 + 10.5*Tr*Tr; // Shown below Equation 10-3.14 + double psi = 1.0 + alpha*((0.215 + 0.28288*alpha - 1.061*beta + 0.26665*Z) / (0.6366 + beta*Z + 1.061*alpha*beta)); // Shown below Equation 10-3.14 + + //cout << "Parameters: " << endl; + //cout << "y: " << y << endl; + //cout << "G_1: " << G_1 << endl; + //cout << "G_2: " << G_2 << endl; + //cout << "q: " << q << endl; + //cout << "Tr: " << Tr << endl; + //cout << "alpha: " << alpha << endl; + //cout << "beta: " << beta << endl; + //cout << "Z: " << Z << endl; + //cout << "psi: " << psi << endl; + + double lambda = (31.2*viscosity*psi/M_prime)*(1.0/G_2 + B_6*y) + q*B_7*y*y*sqrt(Tr)*G_2; // Equation 10-5.5 + + // Units are W/m/K + return lambda; +} + + + // This implements the high-pressure gas mixture viscosity model of Chung // described in chapter 9-7 of Poling et al. (2001). @@ -483,13 +667,16 @@ double ChungHighPressureGasTransport::viscosity() double tKelvin = m_thermo->temperature(); double T_star = tKelvin / params.epsilon_over_k_mix; - double density = m_thermo->density(); // The density is required for high-pressure gases + // The density is required for high-pressure gases. + // The Chung method requires density to be units of mol/cm^3 + // We use the mixture molecular weight (units of kg/kmol) here. + double kg_per_m3_to_mol_per_cm3 = (1.0 / params.MW_mix)*1e-3; // 1 kmol/m^3 = 1e-3 mol/cm^3 + double density = m_thermo->density()*kg_per_m3_to_mol_per_cm3; // This result is in units of micropoise double viscosity = high_pressure_viscosity(T_star, params.MW_mix, density, params.Vc_mix, params.Tc_mix, params.acentric_factor_mix, params.mu_r_mix, params.kappa_mix); double micropoise_to_pascals_second = 1e-7; - return viscosity*micropoise_to_pascals_second; } @@ -500,18 +687,18 @@ double ChungHighPressureGasTransport::viscosity() // for the Chung method's composition dependent parameters. void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParameters& params) { - size_t nsp = m_thermo->nSpecies(); vector molefracs(nsp); m_thermo->getMoleFractions(&molefracs[0]); - // First fill the species-specific values that will then later be used in the combining // rules for the Chung method. vector sigma_i(nsp), epsilon_over_k_i(nsp), acentric_factor_i(nsp), MW_i(nsp), kappa_i(nsp); for (size_t i = 0; i < m_nsp; i++) { // From equation 9-5.32 in Poling et al. (2001) - sigma_i[i] = 0.809*pow(Vcrit_i(i), 1.0/3.0); + double m3_per_kmol_to_cm3_per_mol = 1e3; // Convert from m^3/kmol to cm^3/mol + double Vc = Vcrit_i(i) * m3_per_kmol_to_cm3_per_mol; + sigma_i[i] = 0.809*pow(Vc, 1.0/3.0); // From equation 9-5.34 in Poling et al. (2001) epsilon_over_k_i[i] = Tcrit_i(i)/1.2593; @@ -549,8 +736,12 @@ void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParam double acentric_factor_ij = 0.5*(acentric_factor_i[i] + acentric_factor_i[j]); // Equation 9-5.36 params.acentric_factor_mix += molefracs[i]*molefracs[j]*acentric_factor_ij*pow(sigma_ij,3.0); // Equation 9-5.29 - // Using the base class' dipole moment values - params.mu_mix += molefracs[i]*molefracs[j]*pow(m_dipole(i,i),2.0)*pow(m_dipole(j,j),2.0)/pow(sigma_ij,3.0); // Equation 9-5.30 + // Using the base class' dipole moment values. These are in the SI units, so we need to convert to + // Debye units. + double SI_to_Debye = 1.0 / 3.335e-30; // Conversion factor from C*m to Debye + double dipole_ii = m_dipole(i,i)*SI_to_Debye; + double dipole_jj = m_dipole(j,j)*SI_to_Debye; + params.mu_mix += molefracs[i]*molefracs[j]*pow(dipole_ii,2.0)*pow(dipole_jj,2.0)/pow(sigma_ij,3.0); // Equation 9-5.30 // Using equation 9-5.31 double kappa_ij = sqrt(kappa_i[i]*kappa_i[j]); // Equation 9-5.38 @@ -573,11 +764,22 @@ void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParam params.Tc_mix = 1.2593*params.epsilon_over_k_mix; // Vc_mix is computed using equation 9-5.43 in Poling et al. (2001) - params.Vc_mix = pow(params.acentric_factor_mix/0.809, 3.0); + params.Vc_mix = pow(params.sigma_mix/0.809, 3.0); // mu_r_mix is computed using equation 9-5.42 in Poling et al. (2001) params.mu_r_mix = 131.3*params.mu_mix/sqrt(params.Vc_mix*params.Tc_mix); + //cout << "Mixture parameters are:" << endl; + //cout << "sigma_mix: " << params.sigma_mix << endl; + //cout << "epsilon_over_k_mix: " << params.epsilon_over_k_mix << endl; + //cout << "MW_mix: " << params.MW_mix << endl; + //cout << "acentric_factor_mix: " << params.acentric_factor_mix << endl; + //cout << "mu_mix: " << params.mu_mix << endl; + //cout << "Tc_mix: " << params.Tc_mix << endl; + //cout << "Vc_mix: " << params.Vc_mix << endl; + //cout << "mu_r_mix: " << params.mu_r_mix << endl; + //cout << "kappa_mix: " << params.kappa_mix << endl; + } // Implementation of equation 9-4.3 in Poling et al. (2001). @@ -592,7 +794,6 @@ double neufeld_collision_integral(double T_star) double F = 2.43787; double omega = A / pow(T_star, B) + C / exp(D*T_star) + E / exp(F*T_star); - return omega; } @@ -600,11 +801,21 @@ double neufeld_collision_integral(double T_star) // only difference being the values that are passed to the function (pure values versus mixture values). double ChungHighPressureGasTransport::low_pressure_viscosity(double T, double T_star, double MW, double acentric_factor, double mu_r, double sigma, double kappa) { + //cout << "Input values are:" << endl; + //cout << "T: " << T << endl; + //cout << "T_star: " << T_star << endl; + //cout << "MW: " << MW << endl; + //cout << "acentric_factor: " << acentric_factor << endl; + //cout << "mu_r: " << mu_r << endl; + //cout << "sigma: " << sigma << endl; + //cout << "kappa: " << kappa << endl; + // Equation 9-4.3 in Poling et al. (2001) double omega = neufeld_collision_integral(T_star); // Molecular shapes and polarities factor, equation 9-4.11 double Fc = 1 -0.2756*acentric_factor + 0.059035*pow(mu_r, 4.0) + kappa; + //cout << "Fc: " << Fc << ", Omega: " << omega << endl; // Equation 9-3.9 in Poling et al. (2001), multiplied by the Chung factor, Fc // (another way of writing 9-4.10 that avoids explicit use of the critical volume in this method) @@ -621,6 +832,16 @@ double ChungHighPressureGasTransport::low_pressure_viscosity(double T, double T_ // naming simplicity. double ChungHighPressureGasTransport::high_pressure_viscosity(double T_star, double MW, double rho, double Vc, double Tc, double acentric_factor, double mu_r, double kappa) { + //cout << "Input values are:" << endl; + //cout << "T_star: " << T_star << endl; + //cout << "MW: " << MW << endl; + //cout << "rho: " << rho << endl; + //cout << "Vc: " << Vc << endl; + //cout << "Tc: " << Tc << endl; + //cout << "acentric_factor: " << acentric_factor << endl; + //cout << "mu_r: " << mu_r << endl; + //cout << "kappa: " << kappa << endl; + // Definition of tabulated coefficients for the Chung method, as shown in Table 9-6 on page 9.40 of Poling et al. (2001) vector a = {6.324, 1.210e-3, 5.283, 6.623, 19.745, -1.900, 24.275, 0.7972, -0.2382, 0.06863}; vector b = {50.412, -1.154e-3, 254.209, 38.096, 7.630, -12.537, 3.450, 1.117, 0.06770, 0.3479}; @@ -664,4 +885,66 @@ double ChungHighPressureGasTransport::high_pressure_viscosity(double T_star, dou } +// Pure species critical properties - Tc, Pc, Vc, Zc: +double ChungHighPressureGasTransport::Tcrit_i(size_t i) +{ + vector molefracs(m_thermo->nSpecies()); + m_thermo->getMoleFractions(&molefracs[0]); + vector mf_temp(m_thermo->nSpecies(), 0.0); + mf_temp[i] = 1; + m_thermo->setMoleFractions(&mf_temp[0]); + + double tc = m_thermo->critTemperature(); + + // Restore actual molefracs: + m_thermo->setMoleFractions(&molefracs[0]); + return tc; +} + +double ChungHighPressureGasTransport::Pcrit_i(size_t i) +{ + vector molefracs(m_thermo->nSpecies()); + m_thermo->getMoleFractions(&molefracs[0]); + vector mf_temp(m_thermo->nSpecies(), 0.0); + mf_temp[i] = 1; + m_thermo->setMoleFractions(&mf_temp[0]); + + double pc = m_thermo->critPressure(); + + // Restore actual molefracs: + m_thermo->setMoleFractions(&molefracs[0]); + return pc; +} + +double ChungHighPressureGasTransport::Vcrit_i(size_t i) +{ + vector molefracs(m_thermo->nSpecies()); + m_thermo->getMoleFractions(&molefracs[0]); + vector mf_temp(m_thermo->nSpecies(), 0.0); + mf_temp[i] = 1; + m_thermo->setMoleFractions(&mf_temp[0]); + + double vc = m_thermo->critVolume(); + + // Restore actual molefracs: + m_thermo->setMoleFractions(&molefracs[0]); + return vc; +} + +double ChungHighPressureGasTransport::Zcrit_i(size_t i) +{ + vector molefracs(m_thermo->nSpecies()); + m_thermo->getMoleFractions(&molefracs[0]); + vector mf_temp(m_thermo->nSpecies(), 0.0); + mf_temp[i] = 1; + m_thermo->setMoleFractions(&mf_temp[0]); + + double zc = m_thermo->critCompressibility(); + + // Restore actual molefracs: + m_thermo->setMoleFractions(&molefracs[0]); + return zc; +} + + } \ No newline at end of file From d0a5e5198506c7eabd2127782b894decdf396478 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Tue, 18 Jun 2024 17:40:57 -0400 Subject: [PATCH 05/37] improvements to docstrings and comments --- .../transport/HighPressureGasTransport.h | 94 +++++++++++++-- src/transport/HighPressureGasTransport.cpp | 111 +++++++++--------- 2 files changed, 135 insertions(+), 70 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index bed713d5a7..839b9f25bc 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -126,6 +126,8 @@ struct ChungMixtureParameters * @cite poling2001 (viscosity in Ch. 9, thermal conductivity in Ch. 10, and diffusion * coefficients in Ch. 11). * + * @note: All equations that are cited in this implementation are from the 5th edition + * of the book "The Properties of Gases and Liquids" by Poling, Prausnitz, and O'Connell. * * * @ingroup tranprops @@ -142,10 +144,51 @@ class ChungHighPressureGasTransport : public MixTransport } double viscosity() override; + + /** + * Calculates the high-pressure mixture thermal conductivity using the Chung method. + * + * The Chung method is described in on page 10.23. + * + * @f[ + * \lambda = \frac{31.2 \eta^0 \Psi}{M'} \left( G_1^{-1} + B_6 y \right) + q B_7 y^2 T_r^{1/2} G_2 + * @f] + ** where: + * + * @f[ + * \begin{align*} + * \lambda &= \text{thermal conductivity, W/(m·K)} \\ + * \eta^0 &= \text{low-pressure gas viscosity, N·s/m}^2 \\ + * M' &= \text{molecular weight, kg/mol} \\ + * \Psi &= f(C_v, \omega, T_r) \text{ [as defined under Eq. (10-3.14)]} \\ + * q &= 3.586 \times 10^{-3} \left( \frac{T_c}{M'} \right)^{1/2} V_c^{2/3} \\ + * T &= \text{temperature, K} \\ + * T_c &= \text{critical temperature, K} \\ + * T_r &= \text{reduced temperature, } \frac{T}{T_c} \\ + * V_c &= \text{critical volume, cm}^3/\text{mol} \\ + * \gamma &= \frac{V_c}{6V} + * \end{align*} + * @f] + * + * The details about the parameters and constants used in the expression are + * found in the Poling book. + * + * The mixture values of the pseudo-critical temperature and other model parameters + * are calculated using the Chung mixing rules defined on page 9.25. + * + * The mixture value of the specific heat is computed using equation 10-6.6, which + * is the mole fraction weighted sum of the pure species specific heats. + * + * @f[ + * C_{v,m} = \sum_i y_i C_{v,i} + * #f] + * + */ double thermalConductivity() override; /** - * Returns the matrix of binary diffusion coefficients + * Returns the matrix of binary diffusion coefficients, augmented by the + * Takahashi correction factor. * * d[ld*j + i] = rp*m_bdiff(i,j)*(DP)_R; * @@ -162,23 +205,50 @@ class ChungHighPressureGasTransport : public MixTransport double Vcrit_i(size_t i); double Zcrit_i(size_t i); - // Uses the low-pressure Chung viscosity model to calculate the viscosity - // Defined by equation 9-4.10 in Poling et al. - // Gives viscosity in units of micropoise - // T must be units of K - // MW must be units of kg/kmol - // sigma must be units of Angstroms - double low_pressure_viscosity(double T, double T_star, double MW, double acentric_factor, double mu_r, double sigma, double kappa); + /** + * Returns the low-pressure mixture viscosity using the Chung method in micropoise. + * + * Defined by equation 9-4.10. + * + * @f[ + * \eta = 26.69 F_c \frac{(M*T)^(\frac{1}{2})}{\sigma^2 \Omega} + * @f] + * + * T must be in units of K, MW must be units of kg/kmol, and sigma must be units of Angstroms + * + * This function is structured such that it can be used for pure species or mixtures, with the + * only difference being the values that are passed to the function (pure values versus mixture values). + */ + double low_pressure_viscosity(double T, double T_star, double MW, double acentric_factor, + double mu_r, double sigma, double kappa); // Computes the high-pressure viscosity using the Chung method (Equation 9-6.18). // Gives viscosity in units of micropoise - double high_pressure_viscosity(double T_star, double MW, double rho, double Vc, double Tc, double acentric_factor, double mu_r, double kappa); + double high_pressure_viscosity(double T_star, double MW, double rho, double Vc, double Tc, + double acentric_factor, double mu_r, double kappa); - // Computes and store composition-dependent values of the parameters needed for the Chung viscosity model. + /** + * Returns the composition-dependent values of the parameters needed for the Chung viscosity model. + * + * The equations for the mixing rules defined on page 9.25 for the Chung method's + * composition dependent parameters. + */ void compute_mixture_parameters(ChungMixtureParameters& params); - // Computes the thermal conductivity using the Chung method (Equation 10-5.5). - // Gives thermal conductivity in units of W/m/K + /** + * Computes the high-pressure thermal conductivity using the Chung method (Equation 10-5.5). + * + * Gives thermal conductivity in units of W/m/K. + * + * This function is structured such that it can be used for pure species or mixtures, with the + * only difference being the values that are passed to the function (pure values versus mixture values). + * + * This method utilizes the low-pressure Chung viscosity as that is a required parameter in the model, and + * thus makes a call to the low pressure viscosity implementation. This is why it requires parameters + * typically associated with the viscosity calculation. + * + * M_prime (M' in the model) has units of kg/mol, and is just the molecular weight (kg/kmol) divided by 1000. + */ double high_pressure_thermal_conductivity(double T, double T_star, double MW, double rho, double Cv, double Vc, double Tc, double sigma, double acentric_factor, double mu_r, double kappa); /** diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index d42817284f..a7c7d747cd 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -551,13 +551,6 @@ void ChungHighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* } } -// Calculate the high-pressure mixture thermal conductivity, based on the Chung method -// described in on page 10.23 of Poling et al. (2001). -// -// The mixture pseudo-critical temperature and pressure are calculated using -// the equations defined on page 9.25 of Poling et al. (2001). -// -// The mixture value of the specific heat is computed using equation 10-6.6. double ChungHighPressureGasTransport::thermalConductivity() { ChungMixtureParameters params; @@ -569,49 +562,52 @@ double ChungHighPressureGasTransport::thermalConductivity() // The density is required for high-pressure gases. // The Chung method requires density to be units of mol/cm^3 - // We use the mixture molecular weight (units of kg/kmol) here. + // We use the mixture molecular weight (units of kg/kmol). double kg_per_m3_to_mol_per_cm3 = (1.0 / params.MW_mix)*1e-3; // 1 kmol/m^3 = 1e-3 mol/cm^3 double density = m_thermo->density()*kg_per_m3_to_mol_per_cm3; // The value of Cv is already a mole-weighted average of the pure species values - double Cv_mix = m_thermo->cv_mole(); // Specific heat at constant volume, units are J/kmol/K + double Cv_mix = m_thermo->cv_mole(); // Units are J/kmol/K // This result is in units of W/m/K - double thermal_conductivity = high_pressure_thermal_conductivity(tKelvin, T_star, params.MW_mix, density, Cv_mix, params.Vc_mix, params.Tc_mix, params.sigma_mix, params.acentric_factor_mix, params.mu_r_mix, params.kappa_mix); + double thermal_conductivity = high_pressure_thermal_conductivity(tKelvin, T_star, + params.MW_mix, density, + Cv_mix, params.Vc_mix, + params.Tc_mix, params.sigma_mix, + params.acentric_factor_mix, + params.mu_r_mix, params.kappa_mix); // Return the thermal conductivity in W/m/K return thermal_conductivity; } - - -// Computes the high-pressure thermal conductivity using the Chung method (Equation 10-5.5). -// This function is structured such that it can be used for pure species or mixtures, with the -// only difference being the values that are passed to the function (pure values versus mixture values). -// -// This method utilizes the low-pressure Chung viscosity as that is a required parameter in the model, and -// thus makes a call to the low pressure viscosity implementation. -// -// M_prime (M' in the model) has units of kg/mol, and is just the molecular weight (kg/kmol) divided by 1000. -double ChungHighPressureGasTransport::high_pressure_thermal_conductivity(double T, double T_star, double MW, double rho, double Cv, double Vc, double Tc, double sigma, double acentric_factor, double mu_r, double kappa) +double ChungHighPressureGasTransport::high_pressure_thermal_conductivity(double T, double T_star, + double MW, double rho, + double Cv, double Vc, + double Tc, double sigma, + double acentric_factor, + double mu_r, double kappa) { - // Calculate the low-pressure viscosity using the Chung method + // Calculate the low-pressure viscosity using the Chung method. // This method returns viscosity in micropoise, but the thermal - // conductivity model needs the low-pressure viscosity to be in units of Pa*s + // conductivity model needs the low-pressure viscosity to be in units of Pa*s. double micropoise_to_pascals_second = 1e-7; - double viscosity = low_pressure_viscosity(T, T_star, MW, acentric_factor, mu_r, sigma, kappa)*micropoise_to_pascals_second; + double viscosity = micropoise_to_pascals_second*low_pressure_viscosity(T, T_star, MW, + acentric_factor, mu_r, + sigma, kappa); //cout << "Low-pressure viscosity: " << viscosity << " Pa*s" << endl; - double M_prime = MW / 1000.0; // Converting to kg/mol + double M_prime = MW / 1000.0; // Convert kg/kmol to kg/mol - // Definition of tabulated coefficients for the Chung method, as shown in Table 10-3 on page 10.23 of Poling et al. (2001) + // Definition of tabulated coefficients for the Chung method, as shown in + // Table 10-3 on page 10.23. vector a = {2.44166, -5.0924e-1, 6.6107, 1.4543e1, 7.9274e-1, -5.8634, 9.1089e1}; vector b = {7.4824e-1, -1.5094, 5.6207, -8.9139, 8.2019e-1, 1.2801e1, 1.2811e2}; vector c = {-9.1858e-1, -4.9991e1, 6.4760e1, -5.6379, -6.9369e-1, 9.5893, -5.4217e1}; vector d ={1.2172e2, 6.9983e1, 2.7039e1, 7.4344e1, 6.3173, 6.5529e1, 5.2381e2}; // This is slightly pedantic, but this is done to have the naming convention in the - // equations used match the variable names in the code. + // equations used match the variable names in the code. This is equation 10-5.9. double B_1, B_2, B_3, B_4, B_5, B_6, B_7; B_1 = a[0] + b[0]*acentric_factor + c[0]*pow(mu_r, 4.0) + d[0]*kappa; B_2 = a[1] + b[1]*acentric_factor + c[1]*pow(mu_r, 4.0) + d[1]*kappa; @@ -631,7 +627,7 @@ double ChungHighPressureGasTransport::high_pressure_thermal_conductivity(double double q = 3.586e-3*sqrt(Tc/M_prime) / pow(Vc, 2.0/3.0); // Shown below equation 10-5.5 double Tr = T/Tc; // Reduced temperature - double alpha = (Cv / GasConstant) - 3.0/2.0; // Shown below equation 10-3.14, using Cantera's R (J/kmol/K ) + double alpha = (Cv / GasConstant) - 3.0/2.0; // Shown below equation 10-3.14, using R(J/kmol/K ) double beta = 0.7862 - 0.7109*acentric_factor + 1.3168*acentric_factor*acentric_factor; // Shown below Equation 10-3.14 double Z = 2.0 + 10.5*Tr*Tr; // Shown below Equation 10-3.14 double psi = 1.0 + alpha*((0.215 + 0.28288*alpha - 1.061*beta + 0.26665*Z) / (0.6366 + beta*Z + 1.061*alpha*beta)); // Shown below Equation 10-3.14 @@ -654,8 +650,6 @@ double ChungHighPressureGasTransport::high_pressure_thermal_conductivity(double } - - // This implements the high-pressure gas mixture viscosity model of Chung // described in chapter 9-7 of Poling et al. (2001). double ChungHighPressureGasTransport::viscosity() @@ -674,17 +668,16 @@ double ChungHighPressureGasTransport::viscosity() double density = m_thermo->density()*kg_per_m3_to_mol_per_cm3; // This result is in units of micropoise - double viscosity = high_pressure_viscosity(T_star, params.MW_mix, density, params.Vc_mix, params.Tc_mix, params.acentric_factor_mix, params.mu_r_mix, params.kappa_mix); + double viscosity = high_pressure_viscosity(T_star, params.MW_mix, density, + params.Vc_mix, params.Tc_mix, + params.acentric_factor_mix, + params.mu_r_mix, params.kappa_mix); double micropoise_to_pascals_second = 1e-7; return viscosity*micropoise_to_pascals_second; } - - -// Implementation of equation the mixing rules defined on page 9.25 of Poling et al. (2001) -// for the Chung method's composition dependent parameters. void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParameters& params) { size_t nsp = m_thermo->nSpecies(); @@ -695,12 +688,12 @@ void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParam // rules for the Chung method. vector sigma_i(nsp), epsilon_over_k_i(nsp), acentric_factor_i(nsp), MW_i(nsp), kappa_i(nsp); for (size_t i = 0; i < m_nsp; i++) { - // From equation 9-5.32 in Poling et al. (2001) + // From equation 9-5.32. double m3_per_kmol_to_cm3_per_mol = 1e3; // Convert from m^3/kmol to cm^3/mol double Vc = Vcrit_i(i) * m3_per_kmol_to_cm3_per_mol; sigma_i[i] = 0.809*pow(Vc, 1.0/3.0); - // From equation 9-5.34 in Poling et al. (2001) + // From equation 9-5.34. epsilon_over_k_i[i] = Tcrit_i(i)/1.2593; // NOTE: The association parameter is assumed to be zero for all species, but @@ -712,7 +705,7 @@ void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParam MW_i[i] = m_mw[i]; } - // Here we use the combining rules defined on page 9.25 of Poling et al. (2001) + // Here we use the combining rules defined on page 9.25. // We have ASSUMED that the binary interaction parameters are unity for all species // as was done in the Chung method. // @@ -736,7 +729,7 @@ void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParam double acentric_factor_ij = 0.5*(acentric_factor_i[i] + acentric_factor_i[j]); // Equation 9-5.36 params.acentric_factor_mix += molefracs[i]*molefracs[j]*acentric_factor_ij*pow(sigma_ij,3.0); // Equation 9-5.29 - // Using the base class' dipole moment values. These are in the SI units, so we need to convert to + // The base class' dipole moment values are in the SI units, so we need to convert to // Debye units. double SI_to_Debye = 1.0 / 3.335e-30; // Conversion factor from C*m to Debye double dipole_ii = m_dipole(i,i)*SI_to_Debye; @@ -744,7 +737,7 @@ void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParam params.mu_mix += molefracs[i]*molefracs[j]*pow(dipole_ii,2.0)*pow(dipole_jj,2.0)/pow(sigma_ij,3.0); // Equation 9-5.30 // Using equation 9-5.31 - double kappa_ij = sqrt(kappa_i[i]*kappa_i[j]); // Equation 9-5.38 + double kappa_ij = sqrt(kappa_i[i]*kappa_i[j]); // Equation 9-5.39 params.kappa_mix += molefracs[i]*molefracs[j]*kappa_ij; // Equation 9-5.31 } } @@ -756,17 +749,17 @@ void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParam // The MW_mix was only the numerator inside the brackets of equation 9-5.28 params.MW_mix = pow(params.MW_mix/(params.epsilon_over_k_mix*pow(params.sigma_mix,2.0)), 2.0); - params.acentric_factor_mix /= pow(params.sigma_mix,3.0); + params.acentric_factor_mix /= pow(params.sigma_mix, 3.0); - params.mu_mix = pow(pow(params.sigma_mix,3.0)*params.mu_mix, 1.0/4.0); // Equation 9-5.30 computed the 4th power of mu_mix + params.mu_mix = pow(pow(params.sigma_mix, 3.0)*params.mu_mix, 1.0/4.0); // Equation 9-5.30 computed the 4th power of mu_mix - // Tc_mix is computed using equation 9-5.44 in Poling et al. (2001) + // Tc_mix is computed using equation 9-5.44. params.Tc_mix = 1.2593*params.epsilon_over_k_mix; - // Vc_mix is computed using equation 9-5.43 in Poling et al. (2001) + // Vc_mix is computed using equation 9-5.43. params.Vc_mix = pow(params.sigma_mix/0.809, 3.0); - // mu_r_mix is computed using equation 9-5.42 in Poling et al. (2001) + // mu_r_mix is computed using equation 9-5.42. params.mu_r_mix = 131.3*params.mu_mix/sqrt(params.Vc_mix*params.Tc_mix); //cout << "Mixture parameters are:" << endl; @@ -782,8 +775,9 @@ void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParam } -// Implementation of equation 9-4.3 in Poling et al. (2001). -// Applicable over the range of 0.3 <= T_star <= 100. +//! Returns the value of the Neufeld collision integral for a given dimensionless temperature. +//! Implementation of equation 9-4.3. +//! Applicable over the range of 0.3 <= T_star <= 100. double neufeld_collision_integral(double T_star) { double A = 1.16145; @@ -797,9 +791,9 @@ double neufeld_collision_integral(double T_star) return omega; } -// This function is structured such that it can be used for pure species or mixtures, with the -// only difference being the values that are passed to the function (pure values versus mixture values). -double ChungHighPressureGasTransport::low_pressure_viscosity(double T, double T_star, double MW, double acentric_factor, double mu_r, double sigma, double kappa) +double ChungHighPressureGasTransport::low_pressure_viscosity(double T, double T_star, double MW, + double acentric_factor, double mu_r, + double sigma, double kappa) { //cout << "Input values are:" << endl; //cout << "T: " << T << endl; @@ -810,14 +804,14 @@ double ChungHighPressureGasTransport::low_pressure_viscosity(double T, double T_ //cout << "sigma: " << sigma << endl; //cout << "kappa: " << kappa << endl; - // Equation 9-4.3 in Poling et al. (2001) + // Equation 9-4.3. double omega = neufeld_collision_integral(T_star); - // Molecular shapes and polarities factor, equation 9-4.11 + // Molecular shapes and polarities factor, Equation 9-4.11 double Fc = 1 -0.2756*acentric_factor + 0.059035*pow(mu_r, 4.0) + kappa; //cout << "Fc: " << Fc << ", Omega: " << omega << endl; - // Equation 9-3.9 in Poling et al. (2001), multiplied by the Chung factor, Fc + // Equation 9-3.9, multiplied by the Chung factor, Fc // (another way of writing 9-4.10 that avoids explicit use of the critical volume in this method) double viscosity = Fc* (26.69*sqrt(MW*T)/(sigma*sigma*omega)); @@ -830,7 +824,9 @@ double ChungHighPressureGasTransport::low_pressure_viscosity(double T, double T_ // // Renamed eta_star and eta_star_star from the Poling description to eta_1 and eta_2 for // naming simplicity. -double ChungHighPressureGasTransport::high_pressure_viscosity(double T_star, double MW, double rho, double Vc, double Tc, double acentric_factor, double mu_r, double kappa) +double ChungHighPressureGasTransport::high_pressure_viscosity(double T_star, double MW, double rho, + double Vc, double Tc, double acentric_factor, + double mu_r, double kappa) { //cout << "Input values are:" << endl; //cout << "T_star: " << T_star << endl; @@ -871,10 +867,10 @@ double ChungHighPressureGasTransport::high_pressure_viscosity(double T_star, dou double eta_2 = E_7*y*y*G_2*exp(E_8 + E_9/T_star + E_10/(T_star*T_star)); // Equation 9-6.23 - // Equation 9-4.3 in Poling et al. (2001) - double omega = neufeld_collision_integral(T_star); - // Molecular shapes and polarities factor, equation 9-4.11 + double omega = neufeld_collision_integral(T_star); // Equation 9-4.3 + + // Molecular shapes and polarities factor, Equation 9-4.11 double Fc = 1 -0.2756*acentric_factor + 0.059035*pow(mu_r, 4.0) + kappa; double eta_1 = (sqrt(T_star)/omega) * (Fc*(1.0/G_2 + E_6*y)) + eta_2; // Equation 9-6.19 @@ -884,7 +880,6 @@ double ChungHighPressureGasTransport::high_pressure_viscosity(double T_star, dou return eta; } - // Pure species critical properties - Tc, Pc, Vc, Zc: double ChungHighPressureGasTransport::Tcrit_i(size_t i) { From 890fe1a61a6f081ba0ce1377f47f3c9b238090cb Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Wed, 19 Jun 2024 17:53:27 -0400 Subject: [PATCH 06/37] documentation updates --- .../transport/HighPressureGasTransport.h | 243 ++++++++++++++---- src/transport/HighPressureGasTransport.cpp | 29 +-- 2 files changed, 192 insertions(+), 80 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index 839b9f25bc..947663c27a 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -16,6 +16,16 @@ namespace Cantera { +/** + * @brief Returns interpolated value of (DP)_R obtained from the data + * in Table 2 of the Takahashi 1975 paper, given a value of the reduced + * pressure (Pr) and reduced temperature (Tr). + * + * @param Pr Reduced pressure + * @param Tr Reduced temperature + */ +double takahashi_correction_factor(double Pr, double Tr); + //! Class MultiTransport implements transport properties for //! high pressure gas mixtures. /*! @@ -28,9 +38,9 @@ namespace Cantera * https://github.com/Cantera/cantera/issues/267 for additional information. * * The implementation employs a method of corresponding states, using the Takahashi - * @cite takahashi1975 approach for binary diffusion coefficients (using multicomponent - * averaging rules for the mixture properties), and the Lucas method for the viscosity - * of a high-pressure gas mixture. All methods are described in Poling et al. + * @cite takahashi1975 approach for binary diffusion coefficients (using mixture + * averaging rules for the mixture properties), the Lucas method for the viscosity, and + * a method from Ely and Hanley. All methods are described in Poling et al. * @cite poling2001 (viscosity in Ch. 9, thermal conductivity in Ch. 10, and diffusion * coefficients in Ch. 11). * @@ -47,11 +57,29 @@ class HighPressureGasTransport : public MixTransport return "high-pressure"; } + /** + * Returns the mixture high-pressure thermal conductivity in W/m/K + * a method by Ely and Hanley. + * + */ double thermalConductivity() override; + + /** + * Returns the mixture high-pressure viscosity in Pa*s using the Lucas method. + * + * This uses the approach described in chapter 9-7. + * + * The mixture pseudo-critical temperature and pressure are calculated using + * Equations 9-5.18 and 9-5.19. The mixture molecular weight is computed using + * Equation 9-5.20. The mixture values of the low-pressure polarity and quantum + * correction factors are computed using Equations 9-5.21 and 9-5.22. + * + */ double viscosity() override; /** - * Returns the matrix of binary diffusion coefficients + * Returns the matrix of binary diffusion coefficients using the Takahashi + * correction factor. * * d[ld*j + i] = rp*m_bdiff(i,j)*(DP)_R; * @@ -68,7 +96,27 @@ class HighPressureGasTransport : public MixTransport double Vcrit_i(size_t i); double Zcrit_i(size_t i); + + /** + * Returns the non-dimensional low-pressure mixture viscosity in using the Lucas method. + * + * Defined by equation 9-4.16. + * + * @f[ + * \eta \xi = [0.807 T_r^{0.618} - 0.357 e^{-0.449 T_r} + 0.340e^{-4.058 T_r} + 0.018] F_P^{\t{o}} F_Q^{\t{o}} + * @f] + * + * This function is structured such that it can be used for pure species or mixtures, with the + * only difference being the values that are passed to the function (pure values versus mixture values). + * + * @param Tr // Reduced temperature [unitless] + * @param FP // Polarity correction factor [unitless] + * @param FQ // Quantum correction factor [unitless] + * @return double + */ double low_pressure_nondimensional_viscosity(double Tr, double FP, double FQ); + + double high_pressure_nondimensional_viscosity(double Tr, double Pr, double FP_low, double FQ_low, double P_vap, double P_crit); /** @@ -96,7 +144,6 @@ class HighPressureGasTransport : public MixTransport }; - //These are the parameters that are needed to calculate the viscosity using the Chung method. struct ChungMixtureParameters { @@ -122,14 +169,13 @@ struct ChungMixtureParameters * The implementation employs a method of corresponding states, using the Takahashi * @cite takahashi1975 approach for binary diffusion coefficients (using mixture * averaging rules for the mixture properties), and the Chung method for the viscosity - * and thermal conductivity of a high-pressure gas mixture. All methods are described in Poling et al. - * @cite poling2001 (viscosity in Ch. 9, thermal conductivity in Ch. 10, and diffusion - * coefficients in Ch. 11). + * and thermal conductivity of a high-pressure gas mixture. All methods are described + * in Poling et al. @cite poling2001 (viscosity in Ch. 9, thermal conductivity in + * Ch. 10, and diffusion coefficients in Ch. 11). * * @note: All equations that are cited in this implementation are from the 5th edition * of the book "The Properties of Gases and Liquids" by Poling, Prausnitz, and O'Connell. * - * * @ingroup tranprops */ class ChungHighPressureGasTransport : public MixTransport @@ -200,56 +246,153 @@ class ChungHighPressureGasTransport : public MixTransport friend class TransportFactory; protected: + /** + * @brief Returns the estimate of the critical temperature that is given + * from the thermo object for species i. + * + * This method sets the species composition vector to unity for + * species i and zero for all other species, and then queries the + * thermo object for the critical temperature. It then resets the + * composition vector to the original state. + * + * @param i // Species index + * @return double + */ double Tcrit_i(size_t i); + + /** + * @brief Returns the estimate of the critical pressure that is given + * from the thermo object for species i. + * + * This method sets the species composition vector to unity for + * species i and zero for all other species, and then queries the + * thermo object for the critical temperature. It then resets the + * composition vector to the original state. + * + * @param i // Species index + * @return double + */ double Pcrit_i(size_t i); + + /** + * @brief Returns the estimate of the critical volume that is given + * from the thermo object for species i. + * + * This method sets the species composition vector to unity for + * species i and zero for all other species, and then queries the + * thermo object for the critical temperature. It then resets the + * composition vector to the original state. + * + * @param i // Species index + * @return double + */ double Vcrit_i(size_t i); + + /** + * @brief Returns the estimate of the critical compressibility that is given + * from the thermo object for species i. + * + * This method sets the species composition vector to unity for + * species i and zero for all other species, and then queries the + * thermo object for the critical temperature. It then resets the + * composition vector to the original state. + * + * @param i // Species index + * @return double + */ double Zcrit_i(size_t i); /** - * Returns the low-pressure mixture viscosity using the Chung method in micropoise. - * - * Defined by equation 9-4.10. - * - * @f[ - * \eta = 26.69 F_c \frac{(M*T)^(\frac{1}{2})}{\sigma^2 \Omega} - * @f] - * - * T must be in units of K, MW must be units of kg/kmol, and sigma must be units of Angstroms - * - * This function is structured such that it can be used for pure species or mixtures, with the - * only difference being the values that are passed to the function (pure values versus mixture values). - */ + * Returns the composition-dependent values of the parameters needed for the Chung viscosity model. + * + * The equations for the mixing rules defined on page 9.25 for the Chung method's + * composition dependent parameters. + */ + void compute_mixture_parameters(ChungMixtureParameters& params); + + /** + * Returns the low-pressure mixture viscosity in micropoise using the Chung method. + * + * Defined by equation 9-4.10. + * + * @f[ + * \eta = 26.69 F_c \frac{(M*T)^(\frac{1}{2})}{\sigma^2 \Omega} + * @f] + * + * T must be in units of K, MW must be units of kg/kmol, and sigma must be units of Angstroms + * + * This function is structured such that it can be used for pure species or mixtures, with the + * only difference being the values that are passed to the function (pure values versus mixture values). + * + * @param T // Temperature [K] + * @param T_star // Reduced temperature [unitless] + * @param MW // Molecular weight [kg/kmol] + * @param acentric_factor // Acentric factor [unitless] + * @param mu_r // Dipole moment [Debye] + * @param sigma // Lennard-Jones collision diameter [Angstroms] + * @param kappa // Polar correction factor [unitless] + * @return double + */ double low_pressure_viscosity(double T, double T_star, double MW, double acentric_factor, double mu_r, double sigma, double kappa); - // Computes the high-pressure viscosity using the Chung method (Equation 9-6.18). - // Gives viscosity in units of micropoise + /** + * Returns the high-pressure mixture viscosity in micropoise using the Chung method. + * + * Defined by equation 9-6.18. + * + * @f[ + * \eta = \eta^* \frac{36.344 (M*T_c)^(\frac{1}{2})}{V^{\frac{2}{3}}} + * @f] + * + * $T_c$ must be in units of K, MW must be units of kg/kmol, and sigma must be units of Angstroms + * + * This function is structured such that it can be used for pure species or mixtures, with the + * only difference being the values that are passed to the function (pure values versus mixture values). + * + * @param T_star // Reduced temperature [unitless] + * @param MW // Molecular weight [kg/kmol] + * @param rho // Density [mol/cm^3] + * @param Vc // Critical volume [cm^3/mol] + * @param Tc // Critical temperature [K] + * @param acentric_factor // Acentric factor [unitless] + * @param mu_r // Dipole moment [Debye] + * @param kappa // Polar correction factor [unitless] + * @return double + */ double high_pressure_viscosity(double T_star, double MW, double rho, double Vc, double Tc, double acentric_factor, double mu_r, double kappa); /** - * Returns the composition-dependent values of the parameters needed for the Chung viscosity model. - * - * The equations for the mixing rules defined on page 9.25 for the Chung method's - * composition dependent parameters. - */ - void compute_mixture_parameters(ChungMixtureParameters& params); - - /** - * Computes the high-pressure thermal conductivity using the Chung method (Equation 10-5.5). - * - * Gives thermal conductivity in units of W/m/K. - * - * This function is structured such that it can be used for pure species or mixtures, with the - * only difference being the values that are passed to the function (pure values versus mixture values). - * - * This method utilizes the low-pressure Chung viscosity as that is a required parameter in the model, and - * thus makes a call to the low pressure viscosity implementation. This is why it requires parameters - * typically associated with the viscosity calculation. - * - * M_prime (M' in the model) has units of kg/mol, and is just the molecular weight (kg/kmol) divided by 1000. - */ - double high_pressure_thermal_conductivity(double T, double T_star, double MW, double rho, double Cv, double Vc, double Tc, double sigma, double acentric_factor, double mu_r, double kappa); + * Computes the high-pressure thermal conductivity using the Chung method (Equation 10-5.5). + * + * Gives thermal conductivity in units of W/m/K. + * + * This function is structured such that it can be used for pure species or mixtures, with the + * only difference being the values that are passed to the function (pure values versus mixture values). + * + * This method utilizes the low-pressure Chung viscosity as that is a required parameter in the model, and + * thus makes a call to the low pressure viscosity implementation. This is why it requires parameters + * typically associated with the viscosity calculation. + * + * M_prime (M' in the model) has units of kg/mol, and is just the molecular weight (kg/kmol) divided by 1000. + * + * @param T // Temperature [K] + * @param T_star // Reduced temperature [unitless] + * @param MW // Molecular weight [kg/kmol] + * @param rho // Density [mol/cm^3] + * @param Vc // Critical volume [cm^3/mol] + * @param Tc // Critical temperature [K] + * @param acentric_factor // Acentric factor [unitless] + * @param mu_r // Dipole moment [Debye] + * @param kappa // Polar correction factor [unitless] + * @return double + */ + double high_pressure_thermal_conductivity(double T, double T_star, double MW, + double rho, double Cv, double Vc, + double Tc, double sigma, + double acentric_factor, double mu_r, + double kappa); /** * @brief Returns interpolated value of (DP)_R obtained from the data @@ -258,14 +401,8 @@ class ChungHighPressureGasTransport : public MixTransport * * @param Pr Reduced pressure * @param Tr Reduced temperature -\ */ - double compute_correction_factor(double Pr, double Tr); + */ }; - - - - - } #endif diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index a7c7d747cd..ba1f59c0eb 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -18,14 +18,6 @@ using namespace std; namespace Cantera { -/** - * @brief Returns interpolated value of (DP)_R obtained from the data - * in Table 2 of the Takahashi 1975 paper, given a value of the reduced - * pressure (Pr) and reduced temperature (Tr). - * - * @param Pr Reduced pressure - * @param Tr Reduced temperature - */ double takahashi_correction_factor(double Pr, double Tr) { // In the low pressure limit, no correction is needed. Interpolate @@ -67,7 +59,6 @@ double takahashi_correction_factor(double Pr, double Tr) // the final table value. frac = 1.0; - DP_Rt = DP_Rt_lookup[Pr_i]*(1.0 - frac) + DP_Rt_lookup[Pr_i+1]*frac; A = A_ij_lookup[Pr_i]*(1.0 - frac) + A_ij_lookup[Pr_i+1]*frac; B = B_ij_lookup[Pr_i]*(1.0 - frac) + B_ij_lookup[Pr_i+1]*frac; @@ -78,8 +69,6 @@ double takahashi_correction_factor(double Pr, double Tr) return DP_R; } - - double HighPressureGasTransport::thermalConductivity() { // Method of Ely and Hanley: @@ -217,17 +206,6 @@ void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* cons } } - -// Calculate the high-pressure mixture viscosity, based on the Lucas method -// described in chapter 9-7 of Poling et al. (2001). -// -// The mixture pseudo-critical temperature and pressure are calculated using -// equation 9-5.18 and 9-5.19 in Poling et al. (2001). -// -// The mixture molecular weight is computed using equation 9-5.20 in Poling et al. (2001). -// -// The mixture values of the low-pressure polarity and quantum correction factors are -// computed using equations 9-5.21 and 9-5.22 in Poling et al. (2001). double HighPressureGasTransport::viscosity() { // Most of this function consists of computing mixture values of various critical @@ -498,12 +476,9 @@ double HighPressureGasTransport::FP_i(double mu_r, double Tr, double Z_crit) } } -} - -//Chung Implementation -namespace Cantera -{ +// Chung Implementation +// -------------------- void ChungHighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* const d) { size_t nsp = m_thermo->nSpecies(); From ef12226172839fa5d6b800672a78d41a55200818 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Thu, 20 Jun 2024 14:21:37 -0400 Subject: [PATCH 07/37] more documentation added --- .../transport/HighPressureGasTransport.h | 173 +++++++++++++++++- src/transport/HighPressureGasTransport.cpp | 105 ++++++----- 2 files changed, 220 insertions(+), 58 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index 947663c27a..bbd2b6c632 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -26,6 +26,21 @@ namespace Cantera */ double takahashi_correction_factor(double Pr, double Tr); + + +//These are the parameters that are needed to calculate the viscosity using the Lucas method. +struct LucasMixtureParameters +{ + double FQ_mix_o; + double FP_mix_o; + double Tr_mix; + double Pr_mix; + double Pc_mix; + double Tc_mix; + double MW_mix; + double P_vap_mix; +}; + //! Class MultiTransport implements transport properties for //! high pressure gas mixtures. /*! @@ -97,6 +112,55 @@ class HighPressureGasTransport : public MixTransport double Zcrit_i(size_t i); + /** + * Returns the composition-dependent values of the parameters needed for + * the Lucas viscosity model. + * + * The equations for the mixing rules defined on page 9.23 for the Lucas method's + * composition dependent parameters. The primary mixing rules are defined below, + * and the reduced properties are just the properties divided by the pseudo-critical + * mixture properties defined below. + * + * @f[ + * T_{\t{c,m}} = \sum_i y_i T_{\t{c,i}} + * @f] + * + * @f[ + * P_{\t{c,m}} = R T_{\t{c,m}} \frac{\sum_i y_i Z_{\t{c,i}}}{\sum_i y_i V_{\t{c,i}}} + * @f] + * + * @f[ + * M_m = \sum y_i M_i + * @f] + * + * @f[ + * F_{P,m}^{\t{o}} = \sum y_i F_{P,i}^{\t{o}} + * @f] + * + * @f[ + * F_{Q,m}^{\t{o}} = \left ( \sum y_i F_{Q,i}^{\t{o}} \right ) A + * @f] + * + * @f[ + * A = 1 - 0.01 \left ( \frac{M_H}{M_L} \right )^{0.87} + * @f] + * + * For $\frac{M_H}{M_L} > 9$ and $ 0.05 < y_H < 0.7$, otherwise A = 1. In the + * above equation, $M_H$ and $M_L$ are the molecular weights of the heaviest + * and lightest components in the mixture, and $y_H$ is the mole fraction of + * the heaviest component. + * + * While it isn't returned as a parameter, the species-specific reduced dipole + * moment is used to compute the mixture polarity correction factor. It is + * defined as: + * + * @f[ + * \mu_r = 52.46 \frac{\mu^2 P_{\t{c,i}}}{T_{\t{c,i}} + * @f] + * + */ + void compute_mixture_parameters(LucasMixtureParameters& params); + /** * Returns the non-dimensional low-pressure mixture viscosity in using the Lucas method. * @@ -116,14 +180,45 @@ class HighPressureGasTransport : public MixTransport */ double low_pressure_nondimensional_viscosity(double Tr, double FP, double FQ); - - double high_pressure_nondimensional_viscosity(double Tr, double Pr, double FP_low, double FQ_low, double P_vap, double P_crit); + /** + * Returns the non-dimensional high-pressure mixture viscosity in using the Lucas method. + * + * Defined by equation 9-6.12. + * + * @f[ + * \eta \xi = Z_2 F_P F_Q + * @f] + * + * This returns the value of η*ξ (by multiplying both sides of 9-6.12 by ξ and + * simply returning the right-side of the resulting equation). + * + * This function is structured such that it can be used for pure species or mixtures, with the + * only difference being the values that are passed to the function (pure values versus mixture values). + * + * @param Tr // Reduced temperature [unitless] + * @param Pr // Reduced pressure [unitless] + * @param FP_low // Low-pressure polarity correction factor [unitless] + * @param FQ_low // Low-pressure quantum correction factor [unitless] + * @param P_vap // Vapor pressure [Pa] + * @param P_crit // Critical pressure [Pa] + * @return double + */ + double high_pressure_nondimensional_viscosity(double Tr, double Pr, double FP_low, + double FQ_low, double P_vap, double P_crit); /** * @brief Returns the quantum correction term for a species based on Tr * and MW, used in viscosity calculation. * - * @param Q + * Calculates quantum correction term of the Lucas method for a species based + * on the reduced temperature(Tr) and molecular weight(MW), used in viscosity + * calculation from equation 9-4.19. + * + * @f[ + * F_{Q}^{\text{o}} = 1.22 Q^{0.15} \left( 1 + 0.00385 \left ( \left ( T_r - 12 \right ) ^2 \right ) ^{\frac{1}{MW}} sign(T_r - 12 \right ) \right ) + * @f] + * + * @param Q // Species-specific constant * @param Tr // Reduced temperature * @param MW // Molecular weight * @return double @@ -131,12 +226,32 @@ class HighPressureGasTransport : public MixTransport double FQ_i(double Q, double Tr, double MW); /** - * @brief Returns the polarity correction term for a species based on Tr - * and MW, used in viscosity calculation. + * @brief Returns the polarity correction term for a species based on reduced + * temperature, reduced dipole moment, and critical compressibility. Used in + * the viscosity calculation. + * + * Calculates polarity correction term of the Lucas method for a species based + * on the reduced temperature(Tr) and molecular weight(MW). Equation 9.4.18. * - * @param Q + * @f[ + * \begin{equation} + * F_P^0 = + * \begin{cases} + * 1 & 0 \leq \mu_r < 0.022 \\ + * 1 + 30.55(0.292 - Z_c)^{1.72} & 0.022 \leq \mu_r < 0.075 \\ + * 1 + 30.55(0.292 - Z_c)^{1.72} \times 0.96 + 0.1(T_r - 0.7) & 0.075 \leq \mu_r + * \end{cases} + * \end{equation} + * + + * @note The original description in Poling(2001) neglects to mention what happens + * when the quantity raised to the 1.72 power goes negative. That is an undefined + * operation that generates real+imaginary numbers. For now, we + * take the absolute value of the argument. + * + * @param mu_r // Species Reduced dipole moment * @param Tr // Reduced temperature - * @param MW // Molecular weight + * @param Z_c // Species Critical compressibility * @return double */ double FP_i(double mu_r, double Tr, double Z_c); @@ -246,6 +361,7 @@ class ChungHighPressureGasTransport : public MixTransport friend class TransportFactory; protected: + /** * @brief Returns the estimate of the critical temperature that is given * from the thermo object for species i. @@ -303,10 +419,49 @@ class ChungHighPressureGasTransport : public MixTransport double Zcrit_i(size_t i); /** - * Returns the composition-dependent values of the parameters needed for the Chung viscosity model. + * Returns the composition-dependent values of the parameters needed for + * the Chung viscosity model. * * The equations for the mixing rules defined on page 9.25 for the Chung method's - * composition dependent parameters. + * composition dependent parameters. The primary mixing rules are defined below. + * + * @f[ + * T_{\t{c,m}} = \sum_i y_i T_{\t{c,i}} + * @f] + * + * @f[ + * P_{\t{c,m}} = R T_{\t{c,m}} \frac{\sum_i y_i Z_{\t{c,i}}}{\sum_i y_i V_{\t{c,i}}} + * @f] + * + * @f[ + * M_m = \sum y_i M_i + * @f] + * + * @f[ + * F_{P,m}^{\t{o}} = \sum y_i F_{P,i}^{\t{o}} + * @f] + * + * @f[ + * F_{Q,m}^{\t{o}} = \left ( \sum y_i F_{Q,i}^{\t{o}} \right ) A + * @f] + * + * @f[ + * A = 1 - 0.01 \left ( \frac{M_H}{M_L} \right )^{0.87} + * @f] + * + * For $\frac{M_H}{M_L} > 9$ and $ 0.05 < y_H < 0.7$, otherwise A = 1. In the + * above equation, $M_H$ and $M_L$ are the molecular weights of the heaviest + * and lightest components in the mixture, and $y_H$ is the mole fraction of + * the heaviest component. + * + * While it isn't returned as a parameter, the species-specific reduced dipole + * moment is used to compute the mixture polarity correction factor. It is + * defined as: + * + * @f[ + * \mu_r = 52.46 \frac{\mu^2 P_{\t{c,i}}}{T_{\t{c,i}} + * @f] + * */ void compute_mixture_parameters(ChungMixtureParameters& params); diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index ba1f59c0eb..2c3da9266b 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -208,12 +208,34 @@ void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* cons double HighPressureGasTransport::viscosity() { - // Most of this function consists of computing mixture values of various critical - // properties and other parameters that are used in the viscosity calculation. + LucasMixtureParameters params; + compute_mixture_parameters(params); + + // This is η*ξ + double nondimensional_viscosity = high_pressure_nondimensional_viscosity(params.Tr_mix, + params.Pr_mix, + params.FP_mix_o, + params.FQ_mix_o, + params.P_vap_mix, + params.Pc_mix); + + // Using equation 9-4.14, with units of 1/(Pa*s) + double numerator = GasConstant*params.Tc_mix*pow(Avogadro,2.0); + double denominator = pow(params.MW_mix,3.0)*pow(params.Pc_mix,4.0); + double ksi = pow(numerator / denominator, 1.0/6.0); + + // Return the viscosity in kg/m/s + return nondimensional_viscosity / ksi; +} + + +void HighPressureGasTransport::compute_mixture_parameters(LucasMixtureParameters& params) +{ + double Tc_mix = 0.0; - double Pc_mix_n = 0.0; // Numerator in equation 9-5.18 in Poling et al. (2001) - double Pc_mix_d = 0.0; // Denominator in equation 9-5.18 in Poling et al. (2001) - double MW_mix = m_thermo->meanMolecularWeight(); + double Pc_mix_n = 0.0; // Numerator in equation 9-5.19 + double Pc_mix_d = 0.0; // Denominator in equation 9-5.19 + double MW_mix = m_thermo->meanMolecularWeight(); // Equation 9.5.20, Cantera already mole-weights the molecular weights double FP_mix_o = 0; // The mole-fraction-weighted mixture average of the low-pressure polarity correction factor double FQ_mix_o = 0; // The mole-fraction-weighted mixture average of the low-pressure quantum correction factor @@ -233,11 +255,16 @@ double HighPressureGasTransport::viscosity() double Tc = Tcrit_i(i); double Tr = tKelvin/Tc; double Zc = Zcrit_i(i); - Tc_mix += Tc*molefracs[i]; - Pc_mix_n += molefracs[i]*Zc; //numerator - Pc_mix_d += molefracs[i]*Vcrit_i(i); //denominator (Units of Vcrit_i are m^3/kmol, which are fine because they cancel out with the Cantera gas constant's units used later) - // Calculate ratio of heaviest to lightest species + Tc_mix += Tc*molefracs[i]; // Equation 9-5.18 + + Pc_mix_n += molefracs[i]*Zc; // Numerator of 9-5.19 + // (Units of Vcrit_i are m^3/kmol, which are fine because they cancel out + // with the Cantera gas constant's units used later) + Pc_mix_d += molefracs[i]*Vcrit_i(i); // Denominator of 9-5.19 + + // Calculate ratio of heaviest to lightest species, used in + // Equation 9-5.23. if (m_mw[i] > MW_H) { MW_H = m_mw[i]; x_H = molefracs[i]; @@ -247,7 +274,7 @@ double HighPressureGasTransport::viscosity() // Calculate pure-species reduced dipole moment for pure-species // polar correction term. - // Equation 9-4.17 in Poling et al. (2001) requires the pressure + // Equation 9-4.17 requires the pressure // to be in units of bar, so we convert from Pa to bar. // The dipole moment is stored in SI units, and it needs to be in // units of Debye for the Lucas method. @@ -257,7 +284,6 @@ double HighPressureGasTransport::viscosity() double mu_ri = 52.46*dipole_ii*dipole_ii*(Pcrit_i(i)*pascals_to_bar)/(Tc*Tc); FP_mix_o += molefracs[i] * FP_i(mu_ri, Tr, Zc); // mole-fraction weighting of pure-species polar correction term - // Calculate contribution to quantum correction term. // Note: This assumes the species of interest (He, H2, and D2) have // been named in this specific way. @@ -278,6 +304,7 @@ double HighPressureGasTransport::viscosity() double Pr_mix = m_thermo->pressure()/Pc_mix; // Compute the mixture value of the low-pressure quantum correction factor + // Equation 9-5.23. double ratio = MW_H/MW_L; double A = 1.0; if (ratio > 9 && x_H > 0.05 && x_H < 0.7) { @@ -286,16 +313,15 @@ double HighPressureGasTransport::viscosity() FQ_mix_o *= A; - // This is η*ξ - double nondimensional_viscosity = high_pressure_nondimensional_viscosity(Tr_mix, Pr_mix, FP_mix_o, FQ_mix_o, P_vap_mix, Pc_mix); - - // Using equation 9-4.14 in Poling et al. (2001), with units of 1/(Pa*s) - double numerator = GasConstant*Tc_mix*pow(Avogadro,2.0); - double denominator = pow(MW_mix,3.0)*pow(Pc_mix,4.0); - double ksi = pow(numerator / denominator, 1.0/6.0); + params.FQ_mix_o = FQ_mix_o; + params.FP_mix_o = FP_mix_o; + params.Tc_mix = Tc_mix; + params.Tr_mix = Tr_mix; + params.Pc_mix = Pc_mix; + params.Pr_mix = Pr_mix; + params.MW_mix = MW_mix; + params.P_vap_mix = P_vap_mix; - // Return the viscosity in kg/m/s - return nondimensional_viscosity / ksi; } // Pure species critical properties - Tc, Pc, Vc, Zc: @@ -359,29 +385,21 @@ double HighPressureGasTransport::Zcrit_i(size_t i) return zc; } -// The low-pressure nondimensional viscosity equation 9-4.16 in Poling et al. (2001). -// This relation is used for pure species and mixtures at low pressure. The only -// difference is the the values that are passed to the function (pure values versus mixture values). -double HighPressureGasTransport::low_pressure_nondimensional_viscosity(double Tr, double FP, double FQ) { +double HighPressureGasTransport::low_pressure_nondimensional_viscosity(double Tr, + double FP, + double FQ) { double first_term = 0.807*pow(Tr,0.618) - 0.357*exp(-0.449*Tr); double second_term = 0.340*exp(-4.058*Tr) + 0.018; return (first_term + second_term)*FP*FQ; } -// The high-pressure nondimensional viscosity equation 9-6.12 in Poling et al. (2001). -// This relation is used for pure species and mixtures at high pressure. The only -// difference is the the values that are passed to the function (pure values versus mixture values). -// This returns the value of η*ξ (by multiplying both sides of 9-6.12 by ξ and simply returning the RHS of the -// resulting equation) -double HighPressureGasTransport::high_pressure_nondimensional_viscosity(double Tr, double Pr, double FP_low, double FQ_low, double P_vap, double P_crit){ - - //cout << "Input values are:" << endl; - //cout << "Tr: " << Tr << endl; - //cout << "Pr: " << Pr << endl; - //cout << "FP_low: " << FP_low << endl; - //cout << "FQ_low: " << FQ_low << endl; - //cout << "P_vap: " << P_vap << endl; - //cout << "P_crit: " << P_crit << endl; +double HighPressureGasTransport::high_pressure_nondimensional_viscosity(double Tr, + double Pr, + double FP_low, + double FQ_low, + double P_vap, + double P_crit) +{ double Z_1 = low_pressure_nondimensional_viscosity(Tr, FP_low, FQ_low); // This is η_0*ξ @@ -443,23 +461,12 @@ double HighPressureGasTransport::high_pressure_nondimensional_viscosity(double T return Z_2 * FP * FQ; } -// Calculates quantum correction term of the Lucas method for a species based -// on Tr and MW, used in viscosity calculation from equation 9-4.19 in -// Poling et al. (2001) double HighPressureGasTransport::FQ_i(double Q, double Tr, double MW) { return 1.22*pow(Q,0.15)*(1 + 0.00385*pow(pow(Tr - 12.0, 2.0), 1.0/MW) *sign(Tr - 12.0)); } -// Calculates the pressure correction factor for the Lucas method that -// is used to calculate high pressure pure fluid viscosity. This is equation -// 9-4.18 in Poling et al. (2001). -// -// NOTE: The original description in the book neglects to mention what happens -// when the quantity raised to the 1.72 power goes negative. That is an undefined -// operation that generates real+imaginary numbers. For now, I simply am -// taking the absolute value of the argument and raising it to the power. double HighPressureGasTransport::FP_i(double mu_r, double Tr, double Z_crit) { //cout << "HighPressureGasTransport::FP_i Inputs:" << endl; From bc2b9980f81c382387a0addd552e258c72a14837 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Thu, 20 Jun 2024 18:01:32 -0400 Subject: [PATCH 08/37] more documentation --- .../transport/HighPressureGasTransport.h | 170 ++++++++++++------ src/transport/HighPressureGasTransport.cpp | 47 ----- 2 files changed, 113 insertions(+), 104 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index bbd2b6c632..7a8e35d9ac 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -27,6 +27,15 @@ namespace Cantera double takahashi_correction_factor(double Pr, double Tr); +/** + * @brief Returns the value of the Neufeld collision integral for a given + * dimensionless temperature. Implementation of equation 9-4.3. + * Applicable over the range of 0.3 <= T_star <= 100. + * + * @param T_star Dimensionless temperature (Defined in Equation 9-4.1) + */ +double neufeld_collision_integral(double T_star); + //These are the parameters that are needed to calculate the viscosity using the Lucas method. struct LucasMixtureParameters @@ -173,9 +182,9 @@ class HighPressureGasTransport : public MixTransport * This function is structured such that it can be used for pure species or mixtures, with the * only difference being the values that are passed to the function (pure values versus mixture values). * - * @param Tr // Reduced temperature [unitless] - * @param FP // Polarity correction factor [unitless] - * @param FQ // Quantum correction factor [unitless] + * @param Tr Reduced temperature [unitless] + * @param FP Polarity correction factor [unitless] + * @param FQ Quantum correction factor [unitless] * @return double */ double low_pressure_nondimensional_viscosity(double Tr, double FP, double FQ); @@ -195,12 +204,12 @@ class HighPressureGasTransport : public MixTransport * This function is structured such that it can be used for pure species or mixtures, with the * only difference being the values that are passed to the function (pure values versus mixture values). * - * @param Tr // Reduced temperature [unitless] - * @param Pr // Reduced pressure [unitless] - * @param FP_low // Low-pressure polarity correction factor [unitless] - * @param FQ_low // Low-pressure quantum correction factor [unitless] - * @param P_vap // Vapor pressure [Pa] - * @param P_crit // Critical pressure [Pa] + * @param Tr Reduced temperature [unitless] + * @param Pr Reduced pressure [unitless] + * @param FP_low Low-pressure polarity correction factor [unitless] + * @param FQ_low Low-pressure quantum correction factor [unitless] + * @param P_vap Vapor pressure [Pa] + * @param P_crit Critical pressure [Pa] * @return double */ double high_pressure_nondimensional_viscosity(double Tr, double Pr, double FP_low, @@ -218,9 +227,9 @@ class HighPressureGasTransport : public MixTransport * F_{Q}^{\text{o}} = 1.22 Q^{0.15} \left( 1 + 0.00385 \left ( \left ( T_r - 12 \right ) ^2 \right ) ^{\frac{1}{MW}} sign(T_r - 12 \right ) \right ) * @f] * - * @param Q // Species-specific constant - * @param Tr // Reduced temperature - * @param MW // Molecular weight + * @param Q Species-specific constant + * @param Tr Reduced temperature + * @param MW Molecular weight * @return double */ double FQ_i(double Q, double Tr, double MW); @@ -249,9 +258,9 @@ class HighPressureGasTransport : public MixTransport * operation that generates real+imaginary numbers. For now, we * take the absolute value of the argument. * - * @param mu_r // Species Reduced dipole moment - * @param Tr // Reduced temperature - * @param Z_c // Species Critical compressibility + * @param mu_r Species Reduced dipole moment + * @param Tr Reduced temperature + * @param Z_c Species Critical compressibility * @return double */ double FP_i(double mu_r, double Tr, double Z_c); @@ -371,7 +380,7 @@ class ChungHighPressureGasTransport : public MixTransport * thermo object for the critical temperature. It then resets the * composition vector to the original state. * - * @param i // Species index + * @param i Species index * @return double */ double Tcrit_i(size_t i); @@ -385,7 +394,7 @@ class ChungHighPressureGasTransport : public MixTransport * thermo object for the critical temperature. It then resets the * composition vector to the original state. * - * @param i // Species index + * @param i Species index * @return double */ double Pcrit_i(size_t i); @@ -399,7 +408,7 @@ class ChungHighPressureGasTransport : public MixTransport * thermo object for the critical temperature. It then resets the * composition vector to the original state. * - * @param i // Species index + * @param i Species index * @return double */ double Vcrit_i(size_t i); @@ -413,7 +422,7 @@ class ChungHighPressureGasTransport : public MixTransport * thermo object for the critical temperature. It then resets the * composition vector to the original state. * - * @param i // Species index + * @param i Species index * @return double */ double Zcrit_i(size_t i); @@ -426,42 +435,89 @@ class ChungHighPressureGasTransport : public MixTransport * composition dependent parameters. The primary mixing rules are defined below. * * @f[ - * T_{\t{c,m}} = \sum_i y_i T_{\t{c,i}} + * \sigma_m^3 = \sum_{i} \sum_{j} y_i y_j \sigma_{ij}^3 * @f] * * @f[ - * P_{\t{c,m}} = R T_{\t{c,m}} \frac{\sum_i y_i Z_{\t{c,i}}}{\sum_i y_i V_{\t{c,i}}} + * T_m^* = \frac{T}{\left( \frac{\epsilon}{k} \right )_m} * @f] * * @f[ - * M_m = \sum y_i M_i + * \left ( \frac{\epsilon}{k} \right )_m = \frac{\sum_{i} \sum_{j} y_i y_j \left ( \frac{\epsilon_{ij}}{k} \right ) \sigma_{ij}^3}{\sigma_m^3} * @f] * * @f[ - * F_{P,m}^{\t{o}} = \sum y_i F_{P,i}^{\t{o}} + * MW_m = \left [ \frac{\sum_{i} \sum_{j} y_i y_j \left ( \frac{\epsilon_{ij}}{k} \right ) \sigma_{ij}^2 MW_{ij}^{\frac{1}{2}}}{\left ( \frac{\epsilon}{k} \right )_m \sigma_m^2} \right ]^2 * @f] * * @f[ - * F_{Q,m}^{\t{o}} = \left ( \sum y_i F_{Q,i}^{\t{o}} \right ) A + * \omega_m = \frac{\sum_{i} \sum_{j} y_i y_j \omega_{ij} \sigma+{ij}^3}{\sigma_m^3} * @f] * * @f[ - * A = 1 - 0.01 \left ( \frac{M_H}{M_L} \right )^{0.87} + * \mu_m^4 = \sigma_m^3 \sum_{i} \sum_{j} \left( \frac{y_i y_j \mu_i^2 \mu_j^2}{\sigma_{ij}^3} \right) * @f] * - * For $\frac{M_H}{M_L} > 9$ and $ 0.05 < y_H < 0.7$, otherwise A = 1. In the - * above equation, $M_H$ and $M_L$ are the molecular weights of the heaviest - * and lightest components in the mixture, and $y_H$ is the mole fraction of - * the heaviest component. + * @f[ + * \kappa_m = \sum_{i} \sum_{j} y_i y_j \kappa_{ij} + * @f] * - * While it isn't returned as a parameter, the species-specific reduced dipole - * moment is used to compute the mixture polarity correction factor. It is - * defined as: + * The combining rules are defined as: * * @f[ - * \mu_r = 52.46 \frac{\mu^2 P_{\t{c,i}}}{T_{\t{c,i}} + * \sigma_{i} = 0.809 V_{c,i}^{1/3} + * @f] + * + * @f[ + * \sigma_{ij} = \xi_{ij} \left( \sigma_{i} \sigma_{j} \right)^{1/2} + * @f] + * + * @f[ + * \left( \frac{\epsilon_i}{k} \right) = \frac{T_{c,i}}{1.2593} * @f] * + * @f[ + * \left( \frac{\epsilon_{ij}}{k} \right) = \zeta_{ij} \left( \right) ^{\frac{1}{2}} + * @f] + * + * @f[ + * \omega_{ij} = \frac{\omega_i + \omega_j}{2} + * @f] + * + * @f[ + * \kappa_{ij} = \left( \kappa_i \kappa_j \right)^{1/2} + * @f] + * + * @f[ + * MW_{ij} = \frac{2 MW_i MW_j}{MW_i + MW_j} + * @f] + * + * $\xi and \zeta$ are the binary interaction parameters, and are assumed to be unity + * in this implementation, in keeping with the Chung method. + * + * The Chung viscosity correction factor is defined as: + * + * @f[ + * F_{c,m} = 1 - 0.275 \omega_m + 0.059035 \mu_{r,m}^4 + \kappa_m + * @f] + * + * The reduced dipole moment computed using: + * + * @f[ + * \mu_{r,m} = \frac{131.3 \mu_m}{\left( V_{c,m} T_{c,m}\right)^{\frac{1}{2}}} + * @f] + * + * @f[ + * V_{c,m} = \left( \frac{\sigma_m}{0.809} \right) + * @f] + * + * @f[ + * T_{c,m} = 1.2593 \left( \frac{\epsilon}{k} \right)_m + * @f] + * + * In the equations, $T_c$ must be in units of K, $V_c$ must be in units of cm^3/mol, + * and $\mu$ must be in units of Debye. + * */ void compute_mixture_parameters(ChungMixtureParameters& params); @@ -479,13 +535,13 @@ class ChungHighPressureGasTransport : public MixTransport * This function is structured such that it can be used for pure species or mixtures, with the * only difference being the values that are passed to the function (pure values versus mixture values). * - * @param T // Temperature [K] - * @param T_star // Reduced temperature [unitless] - * @param MW // Molecular weight [kg/kmol] - * @param acentric_factor // Acentric factor [unitless] - * @param mu_r // Dipole moment [Debye] - * @param sigma // Lennard-Jones collision diameter [Angstroms] - * @param kappa // Polar correction factor [unitless] + * @param T Temperature [K] + * @param T_star Reduced temperature [unitless] + * @param MW Molecular weight [kg/kmol] + * @param acentric_factor Acentric factor [unitless] + * @param mu_r Dipole moment [Debye] + * @param sigma Lennard-Jones collision diameter [Angstroms] + * @param kappa Polar correction factor [unitless] * @return double */ double low_pressure_viscosity(double T, double T_star, double MW, double acentric_factor, @@ -505,14 +561,14 @@ class ChungHighPressureGasTransport : public MixTransport * This function is structured such that it can be used for pure species or mixtures, with the * only difference being the values that are passed to the function (pure values versus mixture values). * - * @param T_star // Reduced temperature [unitless] - * @param MW // Molecular weight [kg/kmol] - * @param rho // Density [mol/cm^3] - * @param Vc // Critical volume [cm^3/mol] - * @param Tc // Critical temperature [K] - * @param acentric_factor // Acentric factor [unitless] - * @param mu_r // Dipole moment [Debye] - * @param kappa // Polar correction factor [unitless] + * @param T_star Reduced temperature [unitless] + * @param MW Molecular weight [kg/kmol] + * @param rho Density [mol/cm^3] + * @param Vc Critical volume [cm^3/mol] + * @param Tc Critical temperature [K] + * @param acentric_factor Acentric factor [unitless] + * @param mu_r Dipole moment [Debye] + * @param kappa Polar correction factor [unitless] * @return double */ double high_pressure_viscosity(double T_star, double MW, double rho, double Vc, double Tc, @@ -532,15 +588,15 @@ class ChungHighPressureGasTransport : public MixTransport * * M_prime (M' in the model) has units of kg/mol, and is just the molecular weight (kg/kmol) divided by 1000. * - * @param T // Temperature [K] - * @param T_star // Reduced temperature [unitless] - * @param MW // Molecular weight [kg/kmol] - * @param rho // Density [mol/cm^3] - * @param Vc // Critical volume [cm^3/mol] - * @param Tc // Critical temperature [K] - * @param acentric_factor // Acentric factor [unitless] - * @param mu_r // Dipole moment [Debye] - * @param kappa // Polar correction factor [unitless] + * @param T Temperature [K] + * @param T_star Reduced temperature [unitless] + * @param MW Molecular weight [kg/kmol] + * @param rho Density [mol/cm^3] + * @param Vc Critical volume [cm^3/mol] + * @param Tc Critical temperature [K] + * @param acentric_factor Acentric factor [unitless] + * @param mu_r Dipole moment [Debye] + * @param kappa Polar correction factor [unitless] * @return double */ double high_pressure_thermal_conductivity(double T, double T_star, double MW, diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 2c3da9266b..92da6c80a7 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -577,7 +577,6 @@ double ChungHighPressureGasTransport::high_pressure_thermal_conductivity(double double viscosity = micropoise_to_pascals_second*low_pressure_viscosity(T, T_star, MW, acentric_factor, mu_r, sigma, kappa); - //cout << "Low-pressure viscosity: " << viscosity << " Pa*s" << endl; double M_prime = MW / 1000.0; // Convert kg/kmol to kg/mol @@ -614,24 +613,12 @@ double ChungHighPressureGasTransport::high_pressure_thermal_conductivity(double double Z = 2.0 + 10.5*Tr*Tr; // Shown below Equation 10-3.14 double psi = 1.0 + alpha*((0.215 + 0.28288*alpha - 1.061*beta + 0.26665*Z) / (0.6366 + beta*Z + 1.061*alpha*beta)); // Shown below Equation 10-3.14 - //cout << "Parameters: " << endl; - //cout << "y: " << y << endl; - //cout << "G_1: " << G_1 << endl; - //cout << "G_2: " << G_2 << endl; - //cout << "q: " << q << endl; - //cout << "Tr: " << Tr << endl; - //cout << "alpha: " << alpha << endl; - //cout << "beta: " << beta << endl; - //cout << "Z: " << Z << endl; - //cout << "psi: " << psi << endl; - double lambda = (31.2*viscosity*psi/M_prime)*(1.0/G_2 + B_6*y) + q*B_7*y*y*sqrt(Tr)*G_2; // Equation 10-5.5 // Units are W/m/K return lambda; } - // This implements the high-pressure gas mixture viscosity model of Chung // described in chapter 9-7 of Poling et al. (2001). double ChungHighPressureGasTransport::viscosity() @@ -743,23 +730,8 @@ void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParam // mu_r_mix is computed using equation 9-5.42. params.mu_r_mix = 131.3*params.mu_mix/sqrt(params.Vc_mix*params.Tc_mix); - - //cout << "Mixture parameters are:" << endl; - //cout << "sigma_mix: " << params.sigma_mix << endl; - //cout << "epsilon_over_k_mix: " << params.epsilon_over_k_mix << endl; - //cout << "MW_mix: " << params.MW_mix << endl; - //cout << "acentric_factor_mix: " << params.acentric_factor_mix << endl; - //cout << "mu_mix: " << params.mu_mix << endl; - //cout << "Tc_mix: " << params.Tc_mix << endl; - //cout << "Vc_mix: " << params.Vc_mix << endl; - //cout << "mu_r_mix: " << params.mu_r_mix << endl; - //cout << "kappa_mix: " << params.kappa_mix << endl; - } -//! Returns the value of the Neufeld collision integral for a given dimensionless temperature. -//! Implementation of equation 9-4.3. -//! Applicable over the range of 0.3 <= T_star <= 100. double neufeld_collision_integral(double T_star) { double A = 1.16145; @@ -777,15 +749,6 @@ double ChungHighPressureGasTransport::low_pressure_viscosity(double T, double T_ double acentric_factor, double mu_r, double sigma, double kappa) { - //cout << "Input values are:" << endl; - //cout << "T: " << T << endl; - //cout << "T_star: " << T_star << endl; - //cout << "MW: " << MW << endl; - //cout << "acentric_factor: " << acentric_factor << endl; - //cout << "mu_r: " << mu_r << endl; - //cout << "sigma: " << sigma << endl; - //cout << "kappa: " << kappa << endl; - // Equation 9-4.3. double omega = neufeld_collision_integral(T_star); @@ -810,16 +773,6 @@ double ChungHighPressureGasTransport::high_pressure_viscosity(double T_star, dou double Vc, double Tc, double acentric_factor, double mu_r, double kappa) { - //cout << "Input values are:" << endl; - //cout << "T_star: " << T_star << endl; - //cout << "MW: " << MW << endl; - //cout << "rho: " << rho << endl; - //cout << "Vc: " << Vc << endl; - //cout << "Tc: " << Tc << endl; - //cout << "acentric_factor: " << acentric_factor << endl; - //cout << "mu_r: " << mu_r << endl; - //cout << "kappa: " << kappa << endl; - // Definition of tabulated coefficients for the Chung method, as shown in Table 9-6 on page 9.40 of Poling et al. (2001) vector a = {6.324, 1.210e-3, 5.283, 6.623, 19.745, -1.900, 24.275, 0.7972, -0.2382, 0.06863}; vector b = {50.412, -1.154e-3, 254.209, 38.096, 7.630, -12.537, 3.450, 1.117, 0.06770, 0.3479}; From 6ef442926a4f52a650168976a1750f647142c66e Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Thu, 20 Jun 2024 18:33:47 -0400 Subject: [PATCH 09/37] more documentation & reverted Takahashi method to original approach --- .../transport/HighPressureGasTransport.h | 60 ++++++++++++++++--- src/transport/HighPressureGasTransport.cpp | 45 ++++++++++---- 2 files changed, 84 insertions(+), 21 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index 7a8e35d9ac..e2f589fc6a 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -115,9 +115,60 @@ class HighPressureGasTransport : public MixTransport friend class TransportFactory; protected: + /** + * @brief Returns the estimate of the critical temperature that is given + * from the thermo object for species i. + * + * This method sets the species composition vector to unity for + * species i and zero for all other species, and then queries the + * thermo object for the critical temperature. It then resets the + * composition vector to the original state. + * + * @param i Species index + * @return double + */ double Tcrit_i(size_t i); + + /** + * @brief Returns the estimate of the critical pressure that is given + * from the thermo object for species i. + * + * This method sets the species composition vector to unity for + * species i and zero for all other species, and then queries the + * thermo object for the critical pressure. It then resets the + * composition vector to the original state. + * + * @param i Species index + * @return double + */ double Pcrit_i(size_t i); + + /** + * @brief Returns the estimate of the critical volume that is given + * from the thermo object for species i. + * + * This method sets the species composition vector to unity for + * species i and zero for all other species, and then queries the + * thermo object for the critical volume. It then resets the + * composition vector to the original state. + * + * @param i Species index + * @return double + */ double Vcrit_i(size_t i); + + /** + * @brief Returns the estimate of the critical compressibility that is given + * from the thermo object for species i. + * + * This method sets the species composition vector to unity for + * species i and zero for all other species, and then queries the + * thermo object for the critical compressibility. It then resets the + * composition vector to the original state. + * + * @param i Species index + * @return double + */ double Zcrit_i(size_t i); @@ -604,15 +655,6 @@ class ChungHighPressureGasTransport : public MixTransport double Tc, double sigma, double acentric_factor, double mu_r, double kappa); - - /** - * @brief Returns interpolated value of (DP)_R obtained from the data - * in Table 2 of the Takahashi 1975 paper, given a value of the reduced - * pressure (Pr) and reduced temperature (Tr). - * - * @param Pr Reduced pressure - * @param Tr Reduced temperature - */ }; } diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 92da6c80a7..f7447f4c3f 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -42,31 +42,52 @@ double takahashi_correction_factor(double Pr, double Tr) const static double E_ij_lookup[17] = {1., 1., 1., 1., 1., 1., 1., 13.45454, 14., 10.00900, 8.57519, 10.37483, 11.21674, 1., 6.19043, 1., 1.}; - // Interpolate to obtain the value of the constants (DP)_R, A, B, C, E at + // Interpolate to obtain the value of (DP)_R at // the provided value of the reduced pressure (Pr). - int Pr_i = 0; + int Pr_lower = 0; // Index of the lower bounding value of Pr + int Pr_upper = 0; // Index of the upper bounding value of Pr double frac = 0.0; - double A, B, C,E, DP_Rt; + + bool found = false; for (int j = 1; j < 17; j++){ if (Pr_lookup[j] > Pr) { frac = (Pr - Pr_lookup[j-1])/(Pr_lookup[j] - Pr_lookup[j-1]); + found = true; + Pr_lower = j-1; + Pr_upper = j; break; } - Pr_i++; } // If this loop completes without finding a bounding value of Pr, use // the final table value. - frac = 1.0; + if (!found) { + Pr_lower = 16; + Pr_upper = 16; + frac = 1.0; + } + + // Compute the value of (DP)_R at the given Pr value by interpolating the + // bounding values of (DP)_R. + double A, B, C, E, DP_Rt, DP_R_lower, DP_R_upper; + DP_Rt = DP_Rt_lookup[Pr_lower]; + A = A_ij_lookup[Pr_lower]; + B = B_ij_lookup[Pr_lower]; + C = C_ij_lookup[Pr_lower]; + E = E_ij_lookup[Pr_lower]; + + DP_R_lower = DP_Rt*(1.0 - A*pow(Tr,-B))*(1.0 - C*pow(Tr,-E)); + + DP_Rt = DP_Rt_lookup[Pr_upper]; + A = A_ij_lookup[Pr_upper]; + B = B_ij_lookup[Pr_upper]; + C = C_ij_lookup[Pr_upper]; + E = E_ij_lookup[Pr_upper]; - DP_Rt = DP_Rt_lookup[Pr_i]*(1.0 - frac) + DP_Rt_lookup[Pr_i+1]*frac; - A = A_ij_lookup[Pr_i]*(1.0 - frac) + A_ij_lookup[Pr_i+1]*frac; - B = B_ij_lookup[Pr_i]*(1.0 - frac) + B_ij_lookup[Pr_i+1]*frac; - C = C_ij_lookup[Pr_i]*(1.0 - frac) + C_ij_lookup[Pr_i+1]*frac; - E = E_ij_lookup[Pr_i]*(1.0 - frac) + E_ij_lookup[Pr_i+1]*frac; + DP_R_upper = DP_Rt*(1.0 - A*pow(Tr,-B))*(1.0 - C*pow(Tr,-E)); - double DP_R = DP_Rt*(1.0 - A*pow(Tr,-B))*(1.0 - C*pow(Tr,-E)); - return DP_R; + // Linear interpolation of the two bounding values of (DP)_R. + return DP_R_lower*(1.0 - frac) + DP_R_upper*frac; } double HighPressureGasTransport::thermalConductivity() From d4274a26835c524b9230a4ac031d05b2357dbf87 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Fri, 21 Jun 2024 20:39:30 -0400 Subject: [PATCH 10/37] [Doc] Add LaTeX macro file for Doxygen These correspond to the macros already available for use in Sphinx-generated pages. --- doc/doxygen/Doxyfile | 2 +- doc/doxygen/macros.tex | 3 +++ doc/sphinx/conf.py | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 doc/doxygen/macros.tex diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile index b68399a50b..6636936cc9 100644 --- a/doc/doxygen/Doxyfile +++ b/doc/doxygen/Doxyfile @@ -1725,7 +1725,7 @@ FORMULA_FONTSIZE = 10 # to create new LaTeX commands to be used in formulas as building blocks. See # the section "Including formulas" for details. -FORMULA_MACROFILE = +FORMULA_MACROFILE = doc/doxygen/macros.tex # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # https://www.mathjax.org) which uses client side JavaScript for the rendering diff --git a/doc/doxygen/macros.tex b/doc/doxygen/macros.tex new file mode 100644 index 0000000000..cb5d02e57a --- /dev/null +++ b/doc/doxygen/macros.tex @@ -0,0 +1,3 @@ +% Macros defined here should also be defined in Sphinx conf.py +\newcommand{\t}[1]{\mathrm{#1}} +\newcommand{\pxpy}[2]{\frac{\partial #1}{\partial #2}} diff --git a/doc/sphinx/conf.py b/doc/sphinx/conf.py index 473b8e622d..52d242bc08 100644 --- a/doc/sphinx/conf.py +++ b/doc/sphinx/conf.py @@ -220,6 +220,7 @@ def escape_splats(app, what, name, obj, options, lines): "attrs_block", ] +# For Doxygen pages, these macros are also defined in doc/doxygen/macros.tex mathjax3_config = { 'tex': { 'macros': { From 74bb0d85ce45b1b94649b1ba3031918707a1ff65 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Mon, 1 Jul 2024 17:08:40 -0400 Subject: [PATCH 11/37] first pass at review edits --- .../transport/HighPressureGasTransport.h | 236 ++++++++--------- src/transport/HighPressureGasTransport.cpp | 245 ++++++++---------- src/transport/MMCollisionInt.h | 38 ++- 3 files changed, 246 insertions(+), 273 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index e2f589fc6a..a2bb6ef936 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -16,28 +16,7 @@ namespace Cantera { -/** - * @brief Returns interpolated value of (DP)_R obtained from the data - * in Table 2 of the Takahashi 1975 paper, given a value of the reduced - * pressure (Pr) and reduced temperature (Tr). - * - * @param Pr Reduced pressure - * @param Tr Reduced temperature - */ -double takahashi_correction_factor(double Pr, double Tr); - - -/** - * @brief Returns the value of the Neufeld collision integral for a given - * dimensionless temperature. Implementation of equation 9-4.3. - * Applicable over the range of 0.3 <= T_star <= 100. - * - * @param T_star Dimensionless temperature (Defined in Equation 9-4.1) - */ -double neufeld_collision_integral(double T_star); - - -//These are the parameters that are needed to calculate the viscosity using the Lucas method. +// These are the parameters that are needed to calculate the viscosity using the Lucas method. struct LucasMixtureParameters { double FQ_mix_o; @@ -50,23 +29,13 @@ struct LucasMixtureParameters double P_vap_mix; }; -//! Class MultiTransport implements transport properties for -//! high pressure gas mixtures. -/*! - * @attention This class currently does not have any test cases or examples. Its - * implementation may be incomplete, and future changes to %Cantera may - * unexpectedly cause this class to stop working. If you use this class, - * please consider contributing examples or test cases. In the absence of - * new tests or examples, this class may be deprecated and removed in a - * future version of %Cantera. See - * https://github.com/Cantera/cantera/issues/267 for additional information. - * +/** * The implementation employs a method of corresponding states, using the Takahashi * @cite takahashi1975 approach for binary diffusion coefficients (using mixture * averaging rules for the mixture properties), the Lucas method for the viscosity, and - * a method from Ely and Hanley. All methods are described in Poling et al. - * @cite poling2001 (viscosity in Ch. 9, thermal conductivity in Ch. 10, and diffusion - * coefficients in Ch. 11). + * a method from Ely and Hanley for the thermal conductivity. All methods are described + * in Poling et al. @cite poling2001 (viscosity in Ch. 9, thermal conductivity in + * Ch. 10, and diffusion coefficients in Ch. 11). * * @ingroup tranprops */ @@ -83,7 +52,7 @@ class HighPressureGasTransport : public MixTransport /** * Returns the mixture high-pressure thermal conductivity in W/m/K - * a method by Ely and Hanley. + * using a method by Ely and Hanley. * */ double thermalConductivity() override; @@ -116,65 +85,56 @@ class HighPressureGasTransport : public MixTransport protected: /** - * @brief Returns the estimate of the critical temperature that is given - * from the thermo object for species i. + * Returns the estimate of the critical temperature that is given from the thermo + * object for species i. * - * This method sets the species composition vector to unity for - * species i and zero for all other species, and then queries the - * thermo object for the critical temperature. It then resets the - * composition vector to the original state. + * This method sets the species composition vector to unity for species i and zero + * for all other species, and then queries the thermo object for the critical + * temperature. It then resets the composition vector to the original state. * * @param i Species index - * @return double */ double Tcrit_i(size_t i); /** - * @brief Returns the estimate of the critical pressure that is given - * from the thermo object for species i. + * Returns the estimate of the critical pressure that is given from the thermo + * object for species i. * - * This method sets the species composition vector to unity for - * species i and zero for all other species, and then queries the - * thermo object for the critical pressure. It then resets the - * composition vector to the original state. + * This method sets the species composition vector to unity for species i and zero + * for all other species, and then queries the thermo object for the critical + * pressure. It then resets the composition vector to the original state. * * @param i Species index - * @return double */ double Pcrit_i(size_t i); /** - * @brief Returns the estimate of the critical volume that is given - * from the thermo object for species i. + * Returns the estimate of the critical volume that is given from the thermo + * object for species i. * - * This method sets the species composition vector to unity for - * species i and zero for all other species, and then queries the - * thermo object for the critical volume. It then resets the - * composition vector to the original state. + * This method sets the species composition vector to unity for species i and zero + * for all other species, and then queries the thermo object for the critical + * volume. It then resets the composition vector to the original state. * * @param i Species index - * @return double */ double Vcrit_i(size_t i); /** - * @brief Returns the estimate of the critical compressibility that is given - * from the thermo object for species i. + * Returns the estimate of the critical compressibility that is given from the + * thermo object for species i. * - * This method sets the species composition vector to unity for - * species i and zero for all other species, and then queries the - * thermo object for the critical compressibility. It then resets the - * composition vector to the original state. + * This method sets the species composition vector to unity for species i and zero + * for all other species, and then queries the thermo object for the critical + * compressibility. It then resets the composition vector to the original state. * * @param i Species index - * @return double */ double Zcrit_i(size_t i); - /** - * Returns the composition-dependent values of the parameters needed for - * the Lucas viscosity model. + * Returns the composition-dependent values of the parameters needed for the Lucas + * viscosity model. * * The equations for the mixing rules defined on page 9.23 for the Lucas method's * composition dependent parameters. The primary mixing rules are defined below, @@ -205,21 +165,21 @@ class HighPressureGasTransport : public MixTransport * A = 1 - 0.01 \left ( \frac{M_H}{M_L} \right )^{0.87} * @f] * - * For $\frac{M_H}{M_L} > 9$ and $ 0.05 < y_H < 0.7$, otherwise A = 1. In the - * above equation, $M_H$ and $M_L$ are the molecular weights of the heaviest - * and lightest components in the mixture, and $y_H$ is the mole fraction of - * the heaviest component. + * For @f$ \frac{M_H}{M_L} > 9 @f$ and @f$ 0.05 < y_H < 0.7 @f$, otherwise A = 1. + * In the above equation, $M_H$ and $M_L$ are the molecular weights of the + * heaviest and lightest components in the mixture, and @f$ y_H @f$ is the mole + * fraction of the heaviest component. * * While it isn't returned as a parameter, the species-specific reduced dipole - * moment is used to compute the mixture polarity correction factor. It is - * defined as: + * moment is used to compute the mixture polarity correction factor. It is defined + * as: * * @f[ - * \mu_r = 52.46 \frac{\mu^2 P_{\t{c,i}}}{T_{\t{c,i}} + * \mu_r = 52.46 \frac{\mu^2 P_{\t{c,i}}}{T_{\t{c,i}}} * @f] * */ - void compute_mixture_parameters(LucasMixtureParameters& params); + void computeMixtureParameters(LucasMixtureParameters& params); /** * Returns the non-dimensional low-pressure mixture viscosity in using the Lucas method. @@ -238,7 +198,7 @@ class HighPressureGasTransport : public MixTransport * @param FQ Quantum correction factor [unitless] * @return double */ - double low_pressure_nondimensional_viscosity(double Tr, double FP, double FQ); + double lowPressureNondimensionalViscosity(double Tr, double FP, double FQ); /** * Returns the non-dimensional high-pressure mixture viscosity in using the Lucas method. @@ -263,7 +223,7 @@ class HighPressureGasTransport : public MixTransport * @param P_crit Critical pressure [Pa] * @return double */ - double high_pressure_nondimensional_viscosity(double Tr, double Pr, double FP_low, + double highPressureNondimensionalViscosity(double Tr, double Pr, double FP_low, double FQ_low, double P_vap, double P_crit); /** @@ -275,7 +235,7 @@ class HighPressureGasTransport : public MixTransport * calculation from equation 9-4.19. * * @f[ - * F_{Q}^{\text{o}} = 1.22 Q^{0.15} \left( 1 + 0.00385 \left ( \left ( T_r - 12 \right ) ^2 \right ) ^{\frac{1}{MW}} sign(T_r - 12 \right ) \right ) + * F_{Q}^{\text{o}} = 1.22 Q^{0.15} \left( 1 + 0.00385 \left ( \left ( T_r - 12 \right ) ^2 \right ) ^{\frac{1}{MW}} \test{sign} \left( T_r - 12 \right ) \right ) * @f] * * @param Q Species-specific constant @@ -283,7 +243,7 @@ class HighPressureGasTransport : public MixTransport * @param MW Molecular weight * @return double */ - double FQ_i(double Q, double Tr, double MW); + double quantumCorrectionFactor(double Q, double Tr, double MW); /** * @brief Returns the polarity correction term for a species based on reduced @@ -297,25 +257,24 @@ class HighPressureGasTransport : public MixTransport * \begin{equation} * F_P^0 = * \begin{cases} - * 1 & 0 \leq \mu_r < 0.022 \\ + * 1 & 0 \leq \mu_r < 0.022 \\ * 1 + 30.55(0.292 - Z_c)^{1.72} & 0.022 \leq \mu_r < 0.075 \\ * 1 + 30.55(0.292 - Z_c)^{1.72} \times 0.96 + 0.1(T_r - 0.7) & 0.075 \leq \mu_r * \end{cases} * \end{equation} + * @f] * - * @note The original description in Poling(2001) neglects to mention what happens * when the quantity raised to the 1.72 power goes negative. That is an undefined - * operation that generates real+imaginary numbers. For now, we - * take the absolute value of the argument. + * operation that generates real+imaginary numbers. For now, only positive values + * are allowed. * * @param mu_r Species Reduced dipole moment * @param Tr Reduced temperature * @param Z_c Species Critical compressibility * @return double */ - double FP_i(double mu_r, double Tr, double Z_c); - + double polarityCorrectionFactor(double mu_r, double Tr, double Z_c); }; @@ -338,9 +297,10 @@ struct ChungMixtureParameters double kappa_mix = 0; }; -//! Class ChungHighPressureTransport implements transport properties for -//! high pressure gas mixtures. -/*! +/** + * Transport properties for high pressure gas mixtures using the Chung method for + * viscosity and thermal conductivity. + * * The implementation employs a method of corresponding states, using the Takahashi * @cite takahashi1975 approach for binary diffusion coefficients (using mixture * averaging rules for the mixture properties), and the Chung method for the viscosity @@ -348,7 +308,7 @@ struct ChungMixtureParameters * in Poling et al. @cite poling2001 (viscosity in Ch. 9, thermal conductivity in * Ch. 10, and diffusion coefficients in Ch. 11). * - * @note: All equations that are cited in this implementation are from the 5th edition + * @note All equations that are cited in this implementation are from the 5th edition * of the book "The Properties of Gases and Liquids" by Poling, Prausnitz, and O'Connell. * * @ingroup tranprops @@ -364,6 +324,14 @@ class ChungHighPressureGasTransport : public MixTransport return "high-pressure-chung"; } + + /** + * Returns the high-pressure mixture viscosity in Pa*s using the Chung method. + * + * Based on the high-pressure gas mixture viscosity model of Chung described in + * chapter 9-7 of Poling. + * + */ double viscosity() override; /** @@ -402,7 +370,7 @@ class ChungHighPressureGasTransport : public MixTransport * * @f[ * C_{v,m} = \sum_i y_i C_{v,i} - * #f] + * @f] * */ double thermalConductivity() override; @@ -423,58 +391,50 @@ class ChungHighPressureGasTransport : public MixTransport protected: /** - * @brief Returns the estimate of the critical temperature that is given - * from the thermo object for species i. + * Returns the estimate of the critical temperature that is given from the thermo + * object for species i. * - * This method sets the species composition vector to unity for - * species i and zero for all other species, and then queries the - * thermo object for the critical temperature. It then resets the - * composition vector to the original state. + * This method sets the species composition vector to unity for species i and zero + * for all other species, and then queries the thermo object for the critical + * temperature. It then resets the composition vector to the original state. * * @param i Species index - * @return double */ double Tcrit_i(size_t i); /** - * @brief Returns the estimate of the critical pressure that is given - * from the thermo object for species i. + * Returns the estimate of the critical pressure that is given from the thermo + * object for species i. * - * This method sets the species composition vector to unity for - * species i and zero for all other species, and then queries the - * thermo object for the critical temperature. It then resets the - * composition vector to the original state. + * This method sets the species composition vector to unity for species i and zero + * for all other species, and then queries the thermo object for the critical + * pressure. It then resets the composition vector to the original state. * * @param i Species index - * @return double */ double Pcrit_i(size_t i); /** - * @brief Returns the estimate of the critical volume that is given - * from the thermo object for species i. + * Returns the estimate of the critical volume that is given from the thermo + * object for species i. * - * This method sets the species composition vector to unity for - * species i and zero for all other species, and then queries the - * thermo object for the critical temperature. It then resets the - * composition vector to the original state. + * This method sets the species composition vector to unity for species i and zero + * for all other species, and then queries the thermo object for the critical + * volume. It then resets the composition vector to the original state. * * @param i Species index - * @return double */ double Vcrit_i(size_t i); /** - * @brief Returns the estimate of the critical compressibility that is given - * from the thermo object for species i. + * Returns the estimate of the critical compressibility that is given from the + * thermo object for species i. * - * This method sets the species composition vector to unity for - * species i and zero for all other species, and then queries the - * thermo object for the critical temperature. It then resets the - * composition vector to the original state. + * This method sets the species composition vector to unity for species i and zero + * for all other species, and then queries the thermo object for the critical + * compressibility. It then resets the composition vector to the original state. * * @param i Species index - * @return double */ double Zcrit_i(size_t i); @@ -543,7 +503,7 @@ class ChungHighPressureGasTransport : public MixTransport * MW_{ij} = \frac{2 MW_i MW_j}{MW_i + MW_j} * @f] * - * $\xi and \zeta$ are the binary interaction parameters, and are assumed to be unity + * @f$ \xi @f$ and @f$ \zeta @f$ are the binary interaction parameters, and are assumed to be unity * in this implementation, in keeping with the Chung method. * * The Chung viscosity correction factor is defined as: @@ -566,14 +526,14 @@ class ChungHighPressureGasTransport : public MixTransport * T_{c,m} = 1.2593 \left( \frac{\epsilon}{k} \right)_m * @f] * - * In the equations, $T_c$ must be in units of K, $V_c$ must be in units of cm^3/mol, - * and $\mu$ must be in units of Debye. + * In the equations, @f$ T_c @f$ must be in units of K, @f$ V_c @f$ must be in units of cm^3/mol, + * and @f$ \mu @f$ must be in units of Debye. * */ - void compute_mixture_parameters(ChungMixtureParameters& params); + void computeMixtureParameters(ChungMixtureParameters& params); /** - * Returns the low-pressure mixture viscosity in micropoise using the Chung method. + * Returns the low-pressure mixture viscosity in Pa*s using the Chung method. * * Defined by equation 9-4.10. * @@ -581,10 +541,13 @@ class ChungHighPressureGasTransport : public MixTransport * \eta = 26.69 F_c \frac{(M*T)^(\frac{1}{2})}{\sigma^2 \Omega} * @f] * - * T must be in units of K, MW must be units of kg/kmol, and sigma must be units of Angstroms + * T must be in units of K, MW must be units of kg/kmol, and sigma must be units + * of Angstroms. The viscosity is computed in micropoise, but the return value is + * in standard SI units (Pa*s). * - * This function is structured such that it can be used for pure species or mixtures, with the - * only difference being the values that are passed to the function (pure values versus mixture values). + * This function is structured such that it can be used for pure species or + * mixtures, with the only difference being the values that are passed to the + * function (pure values versus mixture values). * * @param T Temperature [K] * @param T_star Reduced temperature [unitless] @@ -593,10 +556,9 @@ class ChungHighPressureGasTransport : public MixTransport * @param mu_r Dipole moment [Debye] * @param sigma Lennard-Jones collision diameter [Angstroms] * @param kappa Polar correction factor [unitless] - * @return double */ - double low_pressure_viscosity(double T, double T_star, double MW, double acentric_factor, - double mu_r, double sigma, double kappa); + double lowPressureViscosity(double T, double T_star, double MW, double acentric_factor, + double mu_r, double sigma, double kappa); /** * Returns the high-pressure mixture viscosity in micropoise using the Chung method. @@ -607,7 +569,8 @@ class ChungHighPressureGasTransport : public MixTransport * \eta = \eta^* \frac{36.344 (M*T_c)^(\frac{1}{2})}{V^{\frac{2}{3}}} * @f] * - * $T_c$ must be in units of K, MW must be units of kg/kmol, and sigma must be units of Angstroms + * @f$ T_c @f$ must be in units of K, MW must be units of kg/kmol, and @f$ V_c @f$ + * must be units of cm^3/mol. * * This function is structured such that it can be used for pure species or mixtures, with the * only difference being the values that are passed to the function (pure values versus mixture values). @@ -622,8 +585,8 @@ class ChungHighPressureGasTransport : public MixTransport * @param kappa Polar correction factor [unitless] * @return double */ - double high_pressure_viscosity(double T_star, double MW, double rho, double Vc, double Tc, - double acentric_factor, double mu_r, double kappa); + double highPressureViscosity(double T_star, double MW, double rho, double Vc, double Tc, + double acentric_factor, double mu_r, double kappa); /** * Computes the high-pressure thermal conductivity using the Chung method (Equation 10-5.5). @@ -639,18 +602,23 @@ class ChungHighPressureGasTransport : public MixTransport * * M_prime (M' in the model) has units of kg/mol, and is just the molecular weight (kg/kmol) divided by 1000. * + * For mixtures, the mixture values of the input variables are computed using the mixing rules of Chung, + * @see computeMixtureParameters() . + * * @param T Temperature [K] * @param T_star Reduced temperature [unitless] * @param MW Molecular weight [kg/kmol] * @param rho Density [mol/cm^3] + * @param Cv Specific heat [J/kg/K] * @param Vc Critical volume [cm^3/mol] * @param Tc Critical temperature [K] + * @param sigma Lennard-Jones collision diameter [Angstroms] * @param acentric_factor Acentric factor [unitless] * @param mu_r Dipole moment [Debye] * @param kappa Polar correction factor [unitless] * @return double */ - double high_pressure_thermal_conductivity(double T, double T_star, double MW, + double highPressureThermalConductivity(double T, double T_star, double MW, double rho, double Cv, double Vc, double Tc, double sigma, double acentric_factor, double mu_r, diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index f7447f4c3f..7bd88d58df 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -18,7 +18,15 @@ using namespace std; namespace Cantera { -double takahashi_correction_factor(double Pr, double Tr) +/** + * @brief Returns interpolated value of (DP)_R obtained from the data in Table 2 of + * the Takahashi 1975 paper, given a value of the reduced pressure (Pr) and reduced + * temperature (Tr). + * + * @param Pr Reduced pressure + * @param Tr Reduced temperature + */ +double takahashiCorrectionFactor(double Pr, double Tr) { // In the low pressure limit, no correction is needed. Interpolate // the value towards 1 as pressure drops below the 0.1 threshold. @@ -182,10 +190,7 @@ double HighPressureGasTransport::thermalConductivity() void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* const d) { - size_t nsp = m_thermo->nSpecies(); - vector molefracs(nsp); - m_thermo->getMoleFractions(&molefracs[0]); - + update_C(); update_T(); // If necessary, evaluate the binary diffusion coefficients from the polynomial fits if (!m_bindiff_ok) { @@ -196,12 +201,12 @@ void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* cons } double rp = 1.0/m_thermo->pressure(); - for (size_t i = 0; i < nsp; i++) { - for (size_t j = 0; j < nsp; j++) { + for (size_t i = 0; i < m_nsp; i++) { + for (size_t j = 0; j < m_nsp; j++) { // Add an offset to avoid a condition where x_i and x_j both equal // zero (this would lead to Pr_ij = Inf). - double x_i = std::max(Tiny, molefracs[i]); - double x_j = std::max(Tiny, molefracs[j]); + double x_i = std::max(Tiny, m_molefracs[i]); + double x_j = std::max(Tiny, m_molefracs[j]); // Weight mole fractions of i and j so that X_i + X_j = 1.0. x_i = x_i/(x_i + x_j); @@ -213,7 +218,7 @@ void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* cons // Calculate the parameters for Takahashi correlation double P_corr_ij; - P_corr_ij = takahashi_correction_factor(Pr_ij, Tr_ij); + P_corr_ij = takahashiCorrectionFactor(Pr_ij, Tr_ij); // If the reduced temperature is too low, the correction factor // P_corr_ij will be < 0. @@ -230,29 +235,25 @@ void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* cons double HighPressureGasTransport::viscosity() { LucasMixtureParameters params; - compute_mixture_parameters(params); + computeMixtureParameters(params); // This is η*ξ - double nondimensional_viscosity = high_pressure_nondimensional_viscosity(params.Tr_mix, - params.Pr_mix, - params.FP_mix_o, - params.FQ_mix_o, - params.P_vap_mix, - params.Pc_mix); + double nondimensional_viscosity = highPressureNondimensionalViscosity( + params.Tr_mix, params.Pr_mix, params.FP_mix_o, params.FQ_mix_o, + params.P_vap_mix, params.Pc_mix); // Using equation 9-4.14, with units of 1/(Pa*s) double numerator = GasConstant*params.Tc_mix*pow(Avogadro,2.0); double denominator = pow(params.MW_mix,3.0)*pow(params.Pc_mix,4.0); - double ksi = pow(numerator / denominator, 1.0/6.0); + double xi = pow(numerator / denominator, 1.0/6.0); // Return the viscosity in kg/m/s - return nondimensional_viscosity / ksi; + return nondimensional_viscosity / xi; } -void HighPressureGasTransport::compute_mixture_parameters(LucasMixtureParameters& params) +void HighPressureGasTransport::computeMixtureParameters(LucasMixtureParameters& params) { - double Tc_mix = 0.0; double Pc_mix_n = 0.0; // Numerator in equation 9-5.19 double Pc_mix_d = 0.0; // Denominator in equation 9-5.19 @@ -303,18 +304,18 @@ void HighPressureGasTransport::compute_mixture_parameters(LucasMixtureParameters double SI_to_Debye = 1.0 / 3.335e-30; // Conversion factor from C*m to Debye double dipole_ii = m_dipole(i,i)*SI_to_Debye; double mu_ri = 52.46*dipole_ii*dipole_ii*(Pcrit_i(i)*pascals_to_bar)/(Tc*Tc); - FP_mix_o += molefracs[i] * FP_i(mu_ri, Tr, Zc); // mole-fraction weighting of pure-species polar correction term + FP_mix_o += molefracs[i] * polarityCorrectionFactor(mu_ri, Tr, Zc); // mole-fraction weighting of pure-species polar correction term // Calculate contribution to quantum correction term. // Note: This assumes the species of interest (He, H2, and D2) have // been named in this specific way. vector spnames = m_thermo->speciesNames(); if (spnames[i] == "He") { - FQ_mix_o += molefracs[i]*FQ_i(1.38, Tr, m_mw[i]); + FQ_mix_o += molefracs[i]*quantumCorrectionFactor(1.38, Tr, m_mw[i]); } else if (spnames[i] == "H2") { - FQ_mix_o += molefracs[i]*(FQ_i(0.76, Tr, m_mw[i])); + FQ_mix_o += molefracs[i]*(quantumCorrectionFactor(0.76, Tr, m_mw[i])); } else if (spnames[i] == "D2") { - FQ_mix_o += molefracs[i]*(FQ_i(0.52, Tr, m_mw[i])); + FQ_mix_o += molefracs[i]*(quantumCorrectionFactor(0.52, Tr, m_mw[i])); } else { FQ_mix_o += molefracs[i]; } @@ -342,7 +343,6 @@ void HighPressureGasTransport::compute_mixture_parameters(LucasMixtureParameters params.Pr_mix = Pr_mix; params.MW_mix = MW_mix; params.P_vap_mix = P_vap_mix; - } // Pure species critical properties - Tc, Pc, Vc, Zc: @@ -406,23 +406,19 @@ double HighPressureGasTransport::Zcrit_i(size_t i) return zc; } -double HighPressureGasTransport::low_pressure_nondimensional_viscosity(double Tr, - double FP, - double FQ) { +double HighPressureGasTransport::lowPressureNondimensionalViscosity( + double Tr, double FP, double FQ) +{ double first_term = 0.807*pow(Tr,0.618) - 0.357*exp(-0.449*Tr); double second_term = 0.340*exp(-4.058*Tr) + 0.018; return (first_term + second_term)*FP*FQ; } -double HighPressureGasTransport::high_pressure_nondimensional_viscosity(double Tr, - double Pr, - double FP_low, - double FQ_low, - double P_vap, - double P_crit) +double HighPressureGasTransport::highPressureNondimensionalViscosity( + double Tr, double Pr, double FP_low, double FQ_low, double P_vap, double P_crit) { - double Z_1 = low_pressure_nondimensional_viscosity(Tr, FP_low, FQ_low); // This is η_0*ξ + double Z_1 = lowPressureNondimensionalViscosity(Tr, FP_low, FQ_low); // This is η_0*ξ double Z_2; if (Tr <= 1.0) { @@ -431,11 +427,11 @@ double HighPressureGasTransport::high_pressure_nondimensional_viscosity(double T double beta = 1.390 + 5.746*Pr; Z_2 = 0.600 + 0.760*pow(Pr, alpha) + (0.6990*pow(Pr, beta) - 0.60) * (1-Tr); } else { - throw CanteraError("HighPressureGasTransport::viscosity", - "State is outside the limits of the Lucas model, Tr <= 1"); + throw CanteraError("HighPressureGasTransport::highPressureNondimensionalViscosity", + "State is outside the limits of the Lucas model, Pr >= P_vap / P_crit when Tr <= 1.0"); } - } else if ((Tr > 1.0) && (Tr < 40.0)) { - if ((Pr > 0.0) && (Pr <= 100.0)) { + } else if (Tr > 1.0 && Tr < 40.0) { + if (Pr > 0.0 && Pr <= 100.0) { // The following expressions are given in page 9.36 of Poling et al. (2001) // and correspond to parameters in equation 9-6.8. double a_1 = 1.245e-3; @@ -466,12 +462,12 @@ double HighPressureGasTransport::high_pressure_nondimensional_viscosity(double T Z_2 = Z_1*(1 + (a*pow(Pr,e)) / (b*pow(Pr,f) + pow(1+c*pow(Pr,d),-1))); } else { - throw CanteraError("HighPressureGasTransport::viscosity", - "State is outside the limits of the Lucas model, 1.0 < Tr < 40"); + throw CanteraError("HighPressureGasTransport::highPressureNondimensionalViscosity", + "State is outside the limits of the Lucas model, valid values of Pr are: 0.0 < Pr <= 100"); } } else { - throw CanteraError("HighPressureGasTransport::viscosity", - "State is outside the limits of the Lucas model, Tr > 40"); + throw CanteraError("HighPressureGasTransport::highPressureNondimensionalViscosity", + "State is outside the limits of the Lucas model, valid values of Tr are: 1.0 < Tr < 40"); } double Y = Z_2 / Z_1; @@ -482,25 +478,20 @@ double HighPressureGasTransport::high_pressure_nondimensional_viscosity(double T return Z_2 * FP * FQ; } -double HighPressureGasTransport::FQ_i(double Q, double Tr, double MW) +double HighPressureGasTransport::quantumCorrectionFactor(double Q, double Tr, double MW) { return 1.22*pow(Q,0.15)*(1 + 0.00385*pow(pow(Tr - 12.0, 2.0), 1.0/MW) *sign(Tr - 12.0)); } -double HighPressureGasTransport::FP_i(double mu_r, double Tr, double Z_crit) +double HighPressureGasTransport::polarityCorrectionFactor(double mu_r, double Tr, double Z_crit) { - //cout << "HighPressureGasTransport::FP_i Inputs:" << endl; - //cout << "mu_r: " << mu_r << endl; - //cout << "Tr: " << Tr << endl; - //cout << "Z_crit: " << Z_crit << endl; - if (mu_r < 0.022) { return 1; } else if (mu_r < 0.075) { - return 1 + 30.55*pow(fabs(0.292 - Z_crit), 1.72); + return 1 + 30.55*pow(max(0.292 - Z_crit,0.0), 1.72); } else { - return 1 + 30.55*pow(fabs(0.292 - Z_crit), 1.72)*fabs(0.96 + 0.1*(Tr - 0.7)); + return 1 + 30.55*pow(max(0.292 - Z_crit, 0.0), 1.72)*fabs(0.96 + 0.1*(Tr - 0.7)); } } @@ -509,10 +500,7 @@ double HighPressureGasTransport::FP_i(double mu_r, double Tr, double Z_crit) // -------------------- void ChungHighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* const d) { - size_t nsp = m_thermo->nSpecies(); - vector molefracs(nsp); - m_thermo->getMoleFractions(&molefracs[0]); - + update_C(); update_T(); // If necessary, evaluate the binary diffusion coefficients from the polynomial fits if (!m_bindiff_ok) { @@ -523,12 +511,12 @@ void ChungHighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* } double rp = 1.0/m_thermo->pressure(); - for (size_t i = 0; i < nsp; i++) { - for (size_t j = 0; j < nsp; j++) { + for (size_t i = 0; i < m_nsp; i++) { + for (size_t j = 0; j < m_nsp; j++) { // Add an offset to avoid a condition where x_i and x_j both equal // zero (this would lead to Pr_ij = Inf). - double x_i = std::max(Tiny, molefracs[i]); - double x_j = std::max(Tiny, molefracs[j]); + double x_i = std::max(Tiny, m_molefracs[i]); + double x_j = std::max(Tiny, m_molefracs[j]); // Weight mole fractions of i and j so that X_i + X_j = 1.0. x_i = x_i/(x_i + x_j); @@ -539,8 +527,7 @@ void ChungHighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* double Pr_ij = m_thermo->pressure()/(x_i*Pcrit_i(i) + x_j*Pcrit_i(j)); // Calculate the parameters for Takahashi correlation - double P_corr_ij; - P_corr_ij = takahashi_correction_factor(Pr_ij, Tr_ij); + double P_corr_ij = takahashiCorrectionFactor(Pr_ij, Tr_ij); // If the reduced temperature is too low, the correction factor // P_corr_ij will be < 0. @@ -557,7 +544,7 @@ void ChungHighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* double ChungHighPressureGasTransport::thermalConductivity() { ChungMixtureParameters params; - compute_mixture_parameters(params); + computeMixtureParameters(params); // Compute T_star using equation 9-5.26, using the mixture parameters double tKelvin = m_thermo->temperature(); @@ -573,51 +560,42 @@ double ChungHighPressureGasTransport::thermalConductivity() double Cv_mix = m_thermo->cv_mole(); // Units are J/kmol/K // This result is in units of W/m/K - double thermal_conductivity = high_pressure_thermal_conductivity(tKelvin, T_star, - params.MW_mix, density, - Cv_mix, params.Vc_mix, - params.Tc_mix, params.sigma_mix, - params.acentric_factor_mix, - params.mu_r_mix, params.kappa_mix); + double thermal_conductivity = highPressureThermalConductivity( + tKelvin, T_star, params.MW_mix, density, Cv_mix, params.Vc_mix, + params.Tc_mix, params.sigma_mix, params.acentric_factor_mix, + params.mu_r_mix, params.kappa_mix); // Return the thermal conductivity in W/m/K return thermal_conductivity; } -double ChungHighPressureGasTransport::high_pressure_thermal_conductivity(double T, double T_star, - double MW, double rho, - double Cv, double Vc, - double Tc, double sigma, - double acentric_factor, - double mu_r, double kappa) +double ChungHighPressureGasTransport::highPressureThermalConductivity( + double T, double T_star, double MW, double rho, double Cv, double Vc, + double Tc, double sigma, double acentric_factor, double mu_r, + double kappa) { - // Calculate the low-pressure viscosity using the Chung method. - // This method returns viscosity in micropoise, but the thermal - // conductivity model needs the low-pressure viscosity to be in units of Pa*s. - double micropoise_to_pascals_second = 1e-7; - double viscosity = micropoise_to_pascals_second*low_pressure_viscosity(T, T_star, MW, - acentric_factor, mu_r, - sigma, kappa); + // Calculate the low-pressure viscosity using the Chung method (units of Pa*s) + double viscosity = lowPressureViscosity(T, T_star, MW, acentric_factor, mu_r, + sigma, kappa); double M_prime = MW / 1000.0; // Convert kg/kmol to kg/mol // Definition of tabulated coefficients for the Chung method, as shown in // Table 10-3 on page 10.23. - vector a = {2.44166, -5.0924e-1, 6.6107, 1.4543e1, 7.9274e-1, -5.8634, 9.1089e1}; - vector b = {7.4824e-1, -1.5094, 5.6207, -8.9139, 8.2019e-1, 1.2801e1, 1.2811e2}; - vector c = {-9.1858e-1, -4.9991e1, 6.4760e1, -5.6379, -6.9369e-1, 9.5893, -5.4217e1}; - vector d ={1.2172e2, 6.9983e1, 2.7039e1, 7.4344e1, 6.3173, 6.5529e1, 5.2381e2}; + static const vector a = {2.44166, -5.0924e-1, 6.6107, 1.4543e1, 7.9274e-1, -5.8634, 9.1089e1}; + static const vector b = {7.4824e-1, -1.5094, 5.6207, -8.9139, 8.2019e-1, 1.2801e1, 1.2811e2}; + static const vector c = {-9.1858e-1, -4.9991e1, 6.4760e1, -5.6379, -6.9369e-1, 9.5893, -5.4217e1}; + static const vector d ={1.2172e2, 6.9983e1, 2.7039e1, 7.4344e1, 6.3173, 6.5529e1, 5.2381e2}; // This is slightly pedantic, but this is done to have the naming convention in the // equations used match the variable names in the code. This is equation 10-5.9. - double B_1, B_2, B_3, B_4, B_5, B_6, B_7; - B_1 = a[0] + b[0]*acentric_factor + c[0]*pow(mu_r, 4.0) + d[0]*kappa; - B_2 = a[1] + b[1]*acentric_factor + c[1]*pow(mu_r, 4.0) + d[1]*kappa; - B_3 = a[2] + b[2]*acentric_factor + c[2]*pow(mu_r, 4.0) + d[2]*kappa; - B_4 = a[3] + b[3]*acentric_factor + c[3]*pow(mu_r, 4.0) + d[3]*kappa; - B_5 = a[4] + b[4]*acentric_factor + c[4]*pow(mu_r, 4.0) + d[4]*kappa; - B_6 = a[5] + b[5]*acentric_factor + c[5]*pow(mu_r, 4.0) + d[5]*kappa; - B_7 = a[6] + b[6]*acentric_factor + c[6]*pow(mu_r, 4.0) + d[6]*kappa; + double B_1 = a[0] + b[0]*acentric_factor + c[0]*pow(mu_r, 4.0) + d[0]*kappa; + double B_2 = a[1] + b[1]*acentric_factor + c[1]*pow(mu_r, 4.0) + d[1]*kappa; + double B_3 = a[2] + b[2]*acentric_factor + c[2]*pow(mu_r, 4.0) + d[2]*kappa; + double B_4 = a[3] + b[3]*acentric_factor + c[3]*pow(mu_r, 4.0) + d[3]*kappa; + double B_5 = a[4] + b[4]*acentric_factor + c[4]*pow(mu_r, 4.0) + d[4]*kappa; + double B_6 = a[5] + b[5]*acentric_factor + c[5]*pow(mu_r, 4.0) + d[5]*kappa; + double B_7 = a[6] + b[6]*acentric_factor + c[6]*pow(mu_r, 4.0) + d[6]*kappa; double y = rho*Vc/6.0; // Equation 10-5.6 (with rho = 1/V) @@ -640,12 +618,10 @@ double ChungHighPressureGasTransport::high_pressure_thermal_conductivity(double return lambda; } -// This implements the high-pressure gas mixture viscosity model of Chung -// described in chapter 9-7 of Poling et al. (2001). double ChungHighPressureGasTransport::viscosity() { ChungMixtureParameters params; - compute_mixture_parameters(params); + computeMixtureParameters(params); // Compute T_star using equation 9-5.26, using the mixture parameters double tKelvin = m_thermo->temperature(); @@ -658,17 +634,17 @@ double ChungHighPressureGasTransport::viscosity() double density = m_thermo->density()*kg_per_m3_to_mol_per_cm3; // This result is in units of micropoise - double viscosity = high_pressure_viscosity(T_star, params.MW_mix, density, - params.Vc_mix, params.Tc_mix, - params.acentric_factor_mix, - params.mu_r_mix, params.kappa_mix); + double viscosity = highPressureViscosity(T_star, params.MW_mix, density, + params.Vc_mix, params.Tc_mix, + params.acentric_factor_mix, + params.mu_r_mix, params.kappa_mix); double micropoise_to_pascals_second = 1e-7; return viscosity*micropoise_to_pascals_second; } -void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParameters& params) +void ChungHighPressureGasTransport::computeMixtureParameters(ChungMixtureParameters& params) { size_t nsp = m_thermo->nSpecies(); vector molefracs(nsp); @@ -721,10 +697,10 @@ void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParam // The base class' dipole moment values are in the SI units, so we need to convert to // Debye units. - double SI_to_Debye = 1.0 / 3.335e-30; // Conversion factor from C*m to Debye + double SI_to_Debye = lightSpeed; // Conversion factor from C*m to Debye double dipole_ii = m_dipole(i,i)*SI_to_Debye; double dipole_jj = m_dipole(j,j)*SI_to_Debye; - params.mu_mix += molefracs[i]*molefracs[j]*pow(dipole_ii,2.0)*pow(dipole_jj,2.0)/pow(sigma_ij,3.0); // Equation 9-5.30 + params.mu_mix += molefracs[i]*molefracs[j]*pow(dipole_ii*dipole_jj,2.0)/pow(sigma_ij,3.0); // Equation 9-5.30 // Using equation 9-5.31 double kappa_ij = sqrt(kappa_i[i]*kappa_i[j]); // Equation 9-5.39 @@ -737,7 +713,7 @@ void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParam params.epsilon_over_k_mix /= pow(params.sigma_mix,3.0); // The MW_mix was only the numerator inside the brackets of equation 9-5.28 - params.MW_mix = pow(params.MW_mix/(params.epsilon_over_k_mix*pow(params.sigma_mix,2.0)), 2.0); + params.MW_mix = pow(params.MW_mix/(params.epsilon_over_k_mix*params.sigma_mix*params.sigma_mix), 2.0); params.acentric_factor_mix /= pow(params.sigma_mix, 3.0); @@ -753,6 +729,13 @@ void ChungHighPressureGasTransport::compute_mixture_parameters(ChungMixtureParam params.mu_r_mix = 131.3*params.mu_mix/sqrt(params.Vc_mix*params.Tc_mix); } +/** + * Returns the value of the Neufeld collision integral for a given + * dimensionless temperature. Implementation of equation 9-4.3. + * Applicable over the range of 0.3 <= T_star <= 100. + * + * @param T_star Dimensionless temperature (Defined in Equation 9-4.1) + */ double neufeld_collision_integral(double T_star) { double A = 1.16145; @@ -762,26 +745,25 @@ double neufeld_collision_integral(double T_star) double E = 2.16178; double F = 2.43787; - double omega = A / pow(T_star, B) + C / exp(D*T_star) + E / exp(F*T_star); - return omega; + return A / pow(T_star, B) + C / exp(D*T_star) + E / exp(F*T_star); } -double ChungHighPressureGasTransport::low_pressure_viscosity(double T, double T_star, double MW, +double ChungHighPressureGasTransport::lowPressureViscosity(double T, double T_star, double MW, double acentric_factor, double mu_r, double sigma, double kappa) { - // Equation 9-4.3. - double omega = neufeld_collision_integral(T_star); + double omega = neufeld_collision_integral(T_star); // Equation 9-4.3. // Molecular shapes and polarities factor, Equation 9-4.11 double Fc = 1 -0.2756*acentric_factor + 0.059035*pow(mu_r, 4.0) + kappa; - //cout << "Fc: " << Fc << ", Omega: " << omega << endl; // Equation 9-3.9, multiplied by the Chung factor, Fc // (another way of writing 9-4.10 that avoids explicit use of the critical volume in this method) double viscosity = Fc* (26.69*sqrt(MW*T)/(sigma*sigma*omega)); - return viscosity; + double micropoise_to_pascals_second = 1e-7; // Conversion factor from micropoise to Pa*s + + return micropoise_to_pascals_second*viscosity; } // Computes the high-pressure viscosity using the Chung method (Equation 9-6.18). @@ -790,36 +772,35 @@ double ChungHighPressureGasTransport::low_pressure_viscosity(double T, double T_ // // Renamed eta_star and eta_star_star from the Poling description to eta_1 and eta_2 for // naming simplicity. -double ChungHighPressureGasTransport::high_pressure_viscosity(double T_star, double MW, double rho, - double Vc, double Tc, double acentric_factor, - double mu_r, double kappa) +double ChungHighPressureGasTransport::highPressureViscosity(double T_star, double MW, double rho, + double Vc, double Tc, double acentric_factor, + double mu_r, double kappa) { // Definition of tabulated coefficients for the Chung method, as shown in Table 9-6 on page 9.40 of Poling et al. (2001) - vector a = {6.324, 1.210e-3, 5.283, 6.623, 19.745, -1.900, 24.275, 0.7972, -0.2382, 0.06863}; - vector b = {50.412, -1.154e-3, 254.209, 38.096, 7.630, -12.537, 3.450, 1.117, 0.06770, 0.3479}; - vector c = {-51.680, -6.257e-3, -168.48, -8.464, -14.354, 4.958, -11.291, 0.01235, -0.8163, 0.5926}; - vector d ={1189.0, 0.03728, 3898.0, 31.42, 31.53, -18.15, 69.35, -4.117, 4.025, -0.727}; + static const vector a = {6.324, 1.210e-3, 5.283, 6.623, 19.745, -1.900, 24.275, 0.7972, -0.2382, 0.06863}; + static const vector b = {50.412, -1.154e-3, 254.209, 38.096, 7.630, -12.537, 3.450, 1.117, 0.06770, 0.3479}; + static const vector c = {-51.680, -6.257e-3, -168.48, -8.464, -14.354, 4.958, -11.291, 0.01235, -0.8163, 0.5926}; + static const vector d ={1189.0, 0.03728, 3898.0, 31.42, 31.53, -18.15, 69.35, -4.117, 4.025, -0.727}; // This is slightly pedantic, but this is done to have the naming convention in the // equations used match the variable names in the code. - double E_1, E_2, E_3, E_4, E_5, E_6, E_7, E_8, E_9, E_10; - E_1 = a[0] + b[0]*acentric_factor + c[0]*pow(mu_r, 4.0) + d[0]*kappa; - E_2 = a[1] + b[1]*acentric_factor + c[1]*pow(mu_r, 4.0) + d[1]*kappa; - E_3 = a[2] + b[2]*acentric_factor + c[2]*pow(mu_r, 4.0) + d[2]*kappa; - E_4 = a[3] + b[3]*acentric_factor + c[3]*pow(mu_r, 4.0) + d[3]*kappa; - E_5 = a[4] + b[4]*acentric_factor + c[4]*pow(mu_r, 4.0) + d[4]*kappa; - E_6 = a[5] + b[5]*acentric_factor + c[5]*pow(mu_r, 4.0) + d[5]*kappa; - E_7 = a[6] + b[6]*acentric_factor + c[6]*pow(mu_r, 4.0) + d[6]*kappa; - E_8 = a[7] + b[7]*acentric_factor + c[7]*pow(mu_r, 4.0) + d[7]*kappa; - E_9 = a[8] + b[8]*acentric_factor + c[8]*pow(mu_r, 4.0) + d[8]*kappa; - E_10 = a[9] + b[9]*acentric_factor + c[9]*pow(mu_r, 4.0) + d[9]*kappa; + double E_1 = a[0] + b[0]*acentric_factor + c[0]*pow(mu_r, 4.0) + d[0]*kappa; + double E_2 = a[1] + b[1]*acentric_factor + c[1]*pow(mu_r, 4.0) + d[1]*kappa; + double E_3 = a[2] + b[2]*acentric_factor + c[2]*pow(mu_r, 4.0) + d[2]*kappa; + double E_4 = a[3] + b[3]*acentric_factor + c[3]*pow(mu_r, 4.0) + d[3]*kappa; + double E_5 = a[4] + b[4]*acentric_factor + c[4]*pow(mu_r, 4.0) + d[4]*kappa; + double E_6 = a[5] + b[5]*acentric_factor + c[5]*pow(mu_r, 4.0) + d[5]*kappa; + double E_7 = a[6] + b[6]*acentric_factor + c[6]*pow(mu_r, 4.0) + d[6]*kappa; + double E_8 = a[7] + b[7]*acentric_factor + c[7]*pow(mu_r, 4.0) + d[7]*kappa; + double E_9 = a[8] + b[8]*acentric_factor + c[8]*pow(mu_r, 4.0) + d[8]*kappa; + double E_10 = a[9] + b[9]*acentric_factor + c[9]*pow(mu_r, 4.0) + d[9]*kappa; double y = rho*Vc/6.0; // Equation 9-6.20 double G_1 = (1.0 - 0.5*y)/(pow(1.0-y, 3.0)); // Equation 9-6.21 // Equation 9-6.22 - double G_2 = (E_1*((1.0-exp(-E_4*y)) / y) + E_2*G_1*exp(E_5*y) + E_3*G_1)/ (E_1*E_4 + E_2 + E_3); + double G_2 = (E_1*((1.0-exp(-E_4*y)) / y) + E_2*G_1*exp(E_5*y) + E_3*G_1) / (E_1*E_4 + E_2 + E_3); double eta_2 = E_7*y*y*G_2*exp(E_8 + E_9/T_star + E_10/(T_star*T_star)); // Equation 9-6.23 diff --git a/src/transport/MMCollisionInt.h b/src/transport/MMCollisionInt.h index 6b7b751729..92d20ccc13 100644 --- a/src/transport/MMCollisionInt.h +++ b/src/transport/MMCollisionInt.h @@ -15,18 +15,42 @@ namespace Cantera { //! Calculation of Collision integrals -/*! - * This class provides functions that interpolate the tabulated collision - * integrals in Monchick and Mason @cite monchick1961. +/** + * This class provides functions that interpolate the tabulated collision integrals in + * Monchick and Mason @cite monchick1961. + * + * The collision integrals computed by Monchick and Mason use the Stockmayer potential, + * which models a polar molecule as a spherical potential with a point dipole at the + * center). Equation 16 of Monchick and Mason @cite monchick1961 gives the potential + * as: + * + * @f[ + * \phi(r) = 4 \epsilon_0 \left[ \left(\frac{\sigma_0}{r}\right)^{12} - \left(\frac{\sigma_0}{r}\right)^6 + \delta \left(\frac{\sigma_0}{r}\right)^3 \right] + * @f] * - * The collision integrals computed by Monchick and Mason use the Stockmayer - * potential, which models a polar molecule as a spherical potential with a - * point dipole at the center). + * Where @f$ \epsilon_0 @f$ is the depth of the potential well, @f$ \sigma_0 @f$ is the + * distance at which the potential between the two molecules is zero, @f$ \delta @f$ is + * defined as: * * @f[ - * \phi(r) = 4\epsilon \left[ \left(\frac{\sigma}{r}\right)^{12} - \left(\frac{\sigma}{r}\right)^6 + \delta \left(\frac{\sigma}{r}\right)^3 \right] + * \delta = \frac{1}{4} (\mu^*)^2 \zeta \left( \theta_1, \theta_2, \phi \right) * @f] * + * @f$ \mu^* @f$ is the reduced dipole moment. @f$ \theta_1 @f$ , @f$ \theta_2 @f$ , + * and @f$ \phi @f$ are angles related to trajectories of colliding molecules. In the + * work of Monchick and Mason, these details are not what is presented in the tables. + * Instead, the tables are presented as being functions of the reduced temperature, + * @f$ T^* @f$, and the @f$ \delta @f$ parameter. The reduced dipole moment, + * @f$ \mu^* @f$ is defined as: + * + * @f[ + * \mu^* = \frac{\mu}{\sqrt{\epsilon_0 \sigma_0^3}} + * @f] + * + * Where @f$ \mu @f$ is the dipole moment of the molecule and the other parameters + * have been defined earlier. This work considers only the collisions of like + * molecules, so only a single value is needed. + * * The tabulated data comes from the averaged collision integrals in tables * V through VIII of Monchick and Mason @cite monchick1961. * From 64d830afb2117d91ac0bda0b1d731e4315c9d711 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Tue, 2 Jul 2024 17:52:14 -0400 Subject: [PATCH 12/37] more documentation updates --- .../transport/HighPressureGasTransport.h | 221 +++++++++++++----- src/transport/HighPressureGasTransport.cpp | 10 +- 2 files changed, 166 insertions(+), 65 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index a2bb6ef936..86251ad9c3 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -60,7 +60,11 @@ class HighPressureGasTransport : public MixTransport /** * Returns the mixture high-pressure viscosity in Pa*s using the Lucas method. * - * This uses the approach described in chapter 9-7. + * This uses the approach described in chapter 9-7. In this method, the mixture + * viscosity at high pressure is computed using the pure-fluid high pressure + * relation of Lucas with the difference being that mixture values of the + * model parameters are used. These mixture values are computed using the mixing + * rules described in @see computeMixtureParameters() . * * The mixture pseudo-critical temperature and pressure are calculated using * Equations 9-5.18 and 9-5.19. The mixture molecular weight is computed using @@ -133,36 +137,50 @@ class HighPressureGasTransport : public MixTransport double Zcrit_i(size_t i); /** - * Returns the composition-dependent values of the parameters needed for the Lucas - * viscosity model. + * Returns the composition-dependent values of parameters that are needed for the + * Lucas viscosity model. * - * The equations for the mixing rules defined on page 9.23 for the Lucas method's - * composition dependent parameters. The primary mixing rules are defined below, - * and the reduced properties are just the properties divided by the pseudo-critical - * mixture properties defined below. + * The equations for the mixing rules defined on page 9.23 of @cite poling2001 for + * the Lucas method's composition dependent parameters. The primary mixing rules + * are defined below, and the reduced properties are just the properties divided + * by the pseudo-critical mixture properties defined below. + * + * @note Equation numbers are from @cite poling2001 * * @f[ - * T_{\t{c,m}} = \sum_i y_i T_{\t{c,i}} + * T_{\text{c,m}} = \sum_i y_i T_{\text{c,i}} + * + * \quad \text{( Equation 9-5.18)} * @f] * * @f[ - * P_{\t{c,m}} = R T_{\t{c,m}} \frac{\sum_i y_i Z_{\t{c,i}}}{\sum_i y_i V_{\t{c,i}}} + * P_{\text{c,m}} = R T_{\text{c,m}} \frac{\sum_i y_i Z_{\text{c,i}}}{\sum_i y_i V_{\text{c,i}}} + * + * \quad \text{(Equation 9-5.19)} * @f] * * @f[ * M_m = \sum y_i M_i + * + * \quad \text{(Equation 9-5.20)} * @f] * * @f[ - * F_{P,m}^{\t{o}} = \sum y_i F_{P,i}^{\t{o}} + * F_{P,m}^{\text{o}} = \sum y_i F_{P,i}^{\text{o}} + * + * \quad \text{(Equation 9-5.21)} * @f] * * @f[ - * F_{Q,m}^{\t{o}} = \left ( \sum y_i F_{Q,i}^{\t{o}} \right ) A + * F_{Q,m}^{\text{o}} = \left ( \sum y_i F_{Q,i}^{\text{o}} \right ) A + * + * \quad \text{(Equation 9-5.22)} * @f] * * @f[ * A = 1 - 0.01 \left ( \frac{M_H}{M_L} \right )^{0.87} + * + * \quad \text{(Equation 9-5.23)} * @f] * * For @f$ \frac{M_H}{M_L} > 9 @f$ and @f$ 0.05 < y_H < 0.7 @f$, otherwise A = 1. @@ -175,7 +193,9 @@ class HighPressureGasTransport : public MixTransport * as: * * @f[ - * \mu_r = 52.46 \frac{\mu^2 P_{\t{c,i}}}{T_{\t{c,i}}} + * \mu_r = 52.46 \frac{\mu^2 P_{\text{c,i}}}{T_{\text{c,i}}} + * + * \quad \text{(Equation 9-4.17)} * @f] * */ @@ -187,7 +207,7 @@ class HighPressureGasTransport : public MixTransport * Defined by equation 9-4.16. * * @f[ - * \eta \xi = [0.807 T_r^{0.618} - 0.357 e^{-0.449 T_r} + 0.340e^{-4.058 T_r} + 0.018] F_P^{\t{o}} F_Q^{\t{o}} + * \eta \xi = [0.807 T_r^{0.618} - 0.357 e^{-0.449 T_r} + 0.340e^{-4.058 T_r} + 0.018] F_P^{\text{o}} F_Q^{\text{o}} * @f] * * This function is structured such that it can be used for pure species or mixtures, with the @@ -201,19 +221,21 @@ class HighPressureGasTransport : public MixTransport double lowPressureNondimensionalViscosity(double Tr, double FP, double FQ); /** - * Returns the non-dimensional high-pressure mixture viscosity in using the Lucas method. - * - * Defined by equation 9-6.12. + * Returns the non-dimensional high-pressure mixture viscosity in using the Lucas + * method. * * @f[ * \eta \xi = Z_2 F_P F_Q + * + * \quad \text{(Equation 9-6.12)} * @f] * * This returns the value of η*ξ (by multiplying both sides of 9-6.12 by ξ and - * simply returning the right-side of the resulting equation). + * returning the right-side of the resulting equation). * - * This function is structured such that it can be used for pure species or mixtures, with the - * only difference being the values that are passed to the function (pure values versus mixture values). + * This function is structured such that it can be used for pure species or + * mixtures, with the only difference being the values that are passed to the + * function (pure values versus mixture values). * * @param Tr Reduced temperature [unitless] * @param Pr Reduced pressure [unitless] @@ -221,34 +243,32 @@ class HighPressureGasTransport : public MixTransport * @param FQ_low Low-pressure quantum correction factor [unitless] * @param P_vap Vapor pressure [Pa] * @param P_crit Critical pressure [Pa] - * @return double */ double highPressureNondimensionalViscosity(double Tr, double Pr, double FP_low, - double FQ_low, double P_vap, double P_crit); + double FQ_low, double P_vap, + double P_crit); /** - * @brief Returns the quantum correction term for a species based on Tr - * and MW, used in viscosity calculation. - * * Calculates quantum correction term of the Lucas method for a species based * on the reduced temperature(Tr) and molecular weight(MW), used in viscosity - * calculation from equation 9-4.19. + * calculation. * * @f[ - * F_{Q}^{\text{o}} = 1.22 Q^{0.15} \left( 1 + 0.00385 \left ( \left ( T_r - 12 \right ) ^2 \right ) ^{\frac{1}{MW}} \test{sign} \left( T_r - 12 \right ) \right ) + * F_{Q}^{\text{o}} = 1.22 Q^{0.15} {1 + 0.00385[ (T_r - 12)^2 ]^{\frac{1}{MW}} \text{sign} (T_r - 12 )} + * + * \quad \text{(Equation 9-4.19)} * @f] * * @param Q Species-specific constant - * @param Tr Reduced temperature - * @param MW Molecular weight - * @return double + * @param Tr Reduced temperature [unitless] + * @param MW Molecular weight [kg/kmol] */ double quantumCorrectionFactor(double Q, double Tr, double MW); /** - * @brief Returns the polarity correction term for a species based on reduced - * temperature, reduced dipole moment, and critical compressibility. Used in - * the viscosity calculation. + * Returns the polarity correction term for a species based on reduced temperature, + * reduced dipole moment, and critical compressibility. Used in the calculation of + * viscosity. * * Calculates polarity correction term of the Lucas method for a species based * on the reduced temperature(Tr) and molecular weight(MW). Equation 9.4.18. @@ -266,13 +286,12 @@ class HighPressureGasTransport : public MixTransport * * @note The original description in Poling(2001) neglects to mention what happens * when the quantity raised to the 1.72 power goes negative. That is an undefined - * operation that generates real+imaginary numbers. For now, only positive values + * operation that generates real and imaginary numbers. For now, only positive values * are allowed. * * @param mu_r Species Reduced dipole moment * @param Tr Reduced temperature * @param Z_c Species Critical compressibility - * @return double */ double polarityCorrectionFactor(double mu_r, double Tr, double Z_c); }; @@ -329,7 +348,14 @@ class ChungHighPressureGasTransport : public MixTransport * Returns the high-pressure mixture viscosity in Pa*s using the Chung method. * * Based on the high-pressure gas mixture viscosity model of Chung described in - * chapter 9-7 of Poling. + * chapter 9-7 of Poling. This method uses the pure species high-pressure viscosity + * relation of Chung with the difference being that mixture values of the model + * are computed using a set of mixing rules given by Chung + * @see computeMixtureParameters() . The mixing rules are defined in section + * 9-5 of @cite poling2001. + * + * Because this method is using the high-pressure viscosity model with mixture + * parameters, @see highPressureViscosity() for details on the model. * */ double viscosity() override; @@ -360,7 +386,7 @@ class ChungHighPressureGasTransport : public MixTransport * @f] * * The details about the parameters and constants used in the expression are - * found in the Poling book. + * found in @cite poling2001 . * * The mixture values of the pseudo-critical temperature and other model parameters * are calculated using the Chung mixing rules defined on page 9.25. @@ -561,19 +587,54 @@ class ChungHighPressureGasTransport : public MixTransport double mu_r, double sigma, double kappa); /** - * Returns the high-pressure mixture viscosity in micropoise using the Chung method. - * - * Defined by equation 9-6.18. + * Returns the high-pressure mixture viscosity in micropoise using the Chung + * method. * * @f[ * \eta = \eta^* \frac{36.344 (M*T_c)^(\frac{1}{2})}{V^{\frac{2}{3}}} + * + * \quad \text{(Equation 9-6.18)} * @f] * - * @f$ T_c @f$ must be in units of K, MW must be units of kg/kmol, and @f$ V_c @f$ - * must be units of cm^3/mol. + * where: * - * This function is structured such that it can be used for pure species or mixtures, with the - * only difference being the values that are passed to the function (pure values versus mixture values). + * @f[ + * \begin{align*} + * \eta &= \text{viscosity, \mu P)} \\ + * M &= \text{molecular wight, kg/kmol} \\ + * T_c &= \text{critical temperature, K} \\ + * V_c &= \text{critical molar volume, cm}^3 / \text{mol} \\ + * \end{align*} + * @f] + * + * and, + * + * @f[ + * \eta^* = \frac{(T^*)^{\frac{1}{2}}}{\Omega_v} {F_c[(G_2)^{-1} + E_6 y]} + \eta^{**} + * + * \quad \text{(Equation 9-6.19)} + * @f] + * + * The values of @f$ T^* @f$ and @f$ F_c @f$ are defined as follows. + * + * @f[ + * T^* = 1.2593 T_r + * + * \quad \text{(Equation 9-4.9)} + * @f] + * + * @f[ + * F_c = 1 - 0.275 \omega + 0.059035 \mu_r^4 + \kappa + * + * \quad \text{(Equation 9-4.11)} + * @f] + * + * The value of @f$ \Omega_v @f$ is the viscosity collision integral evaluated at + * the non-dimensional reduced temperature @f$ T^* @f$. @see neufeldCollisionIntegral() . + * + * This function is structured such that it can be used for pure species or + * mixtures, with the only difference being the values that are passed to the + * function (pure values versus mixture values). * * @param T_star Reduced temperature [unitless] * @param MW Molecular weight [kg/kmol] @@ -583,27 +644,69 @@ class ChungHighPressureGasTransport : public MixTransport * @param acentric_factor Acentric factor [unitless] * @param mu_r Dipole moment [Debye] * @param kappa Polar correction factor [unitless] - * @return double */ - double highPressureViscosity(double T_star, double MW, double rho, double Vc, double Tc, - double acentric_factor, double mu_r, double kappa); + double highPressureViscosity(double T_star, double MW, double rho, double Vc, + double Tc, double acentric_factor, double mu_r, double kappa); /** - * Computes the high-pressure thermal conductivity using the Chung method (Equation 10-5.5). + * Computes the high-pressure thermal conductivity using the Chung method in units + * of W/m/K * - * Gives thermal conductivity in units of W/m/K. + * The Chung method for computing high-pressure thermal conductivity is described + * on page 10.23 of @cite poling2001 . * - * This function is structured such that it can be used for pure species or mixtures, with the - * only difference being the values that are passed to the function (pure values versus mixture values). + * @f[ + * \lambda = \frac{31.2 \eta^0 \Psi}{M'} \left( G_1^{-1} + B_6 y \right) + * + q B_7 y^2 T_r^{1/2} G_2 * - * This method utilizes the low-pressure Chung viscosity as that is a required parameter in the model, and - * thus makes a call to the low pressure viscosity implementation. This is why it requires parameters - * typically associated with the viscosity calculation. + * \quad \text{(Equation 10-5.5)} + * @f] * - * M_prime (M' in the model) has units of kg/mol, and is just the molecular weight (kg/kmol) divided by 1000. + * where: + * + * @f[ + * \begin{align*} + * \lambda &= \text{thermal conductivity, W/(m·K)} \\ + * \eta^0 &= \text{low-pressure gas viscosity, N·s/m}^2 \\ + * M' &= \text{molecular weight, kg/mol} \\ + * \Psi &= f(C_v, \omega, T_r) \text{ [as defined under Eq. (10-3.14)]} \\ + * q &= 3.586 \times 10^{-3} \left( \frac{T_c}{M'} \right)^{1/2} V_c^{2/3} \\ + * T &= \text{temperature, K} \\ + * T_c &= \text{critical temperature, K} \\ + * T_r &= \text{reduced temperature, } \frac{T}{T_c} \\ + * V_c &= \text{critical molar volume, cm}^3/\text{mol} \\ + * \gamma &= \frac{V_c}{6V} + * \end{align*} + * @f] + * + * The details about the parameters and constants used in the expression are + * found in @cite poling2001 . + * + * M_prime (M' in the model) has units of kg/mol, and is just the molecular weight + * (kg/kmol) divided by 1000. + * + * The mixture values of the pseudo-critical temperature and other model parameters + * are calculated using the Chung mixing rules defined on page 9.25. + * + * The mixture value of the specific heat is computed using equation 10-6.6, which + * is the mole fraction weighted sum of the pure species specific heats. + * + * @f[ + * C_{v,m} = \sum_i y_i C_{v,i} + * @f] + * + * + * This method utilizes the low-pressure Chung viscosity as that is a required + * parameter in the model, and thus calls the low pressure viscosity + * implementation. This is why it requires parameters typically associated with + * the viscosity calculation. + * + * This function is structured such that it can be used for pure species or + * mixtures, with the only difference being the values that are passed to the + * function (pure values versus mixture values). * - * For mixtures, the mixture values of the input variables are computed using the mixing rules of Chung, - * @see computeMixtureParameters() . + * For mixtures, the mixture values of the input variables are computed using the + * mixing rules of Chung, @see computeMixtureParameters() . * * @param T Temperature [K] * @param T_star Reduced temperature [unitless] @@ -619,10 +722,8 @@ class ChungHighPressureGasTransport : public MixTransport * @return double */ double highPressureThermalConductivity(double T, double T_star, double MW, - double rho, double Cv, double Vc, - double Tc, double sigma, - double acentric_factor, double mu_r, - double kappa); + double rho, double Cv, double Vc, double Tc, double sigma, + double acentric_factor, double mu_r, double kappa); }; } diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 7bd88d58df..6e305b9522 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -432,8 +432,8 @@ double HighPressureGasTransport::highPressureNondimensionalViscosity( } } else if (Tr > 1.0 && Tr < 40.0) { if (Pr > 0.0 && Pr <= 100.0) { - // The following expressions are given in page 9.36 of Poling et al. (2001) - // and correspond to parameters in equation 9-6.8. + // The following expressions are given in page 9.36 of Poling and + // correspond to parameters in equation 9-6.8. double a_1 = 1.245e-3; double a_2 = 5.1726; double gamma = -0.3286; @@ -736,7 +736,7 @@ void ChungHighPressureGasTransport::computeMixtureParameters(ChungMixtureParamet * * @param T_star Dimensionless temperature (Defined in Equation 9-4.1) */ -double neufeld_collision_integral(double T_star) +double neufeldCollisionIntegral(double T_star) { double A = 1.16145; double B = 0.14874; @@ -752,7 +752,7 @@ double ChungHighPressureGasTransport::lowPressureViscosity(double T, double T_st double acentric_factor, double mu_r, double sigma, double kappa) { - double omega = neufeld_collision_integral(T_star); // Equation 9-4.3. + double omega = neufeldCollisionIntegral(T_star); // Equation 9-4.3. // Molecular shapes and polarities factor, Equation 9-4.11 double Fc = 1 -0.2756*acentric_factor + 0.059035*pow(mu_r, 4.0) + kappa; @@ -805,7 +805,7 @@ double ChungHighPressureGasTransport::highPressureViscosity(double T_star, doubl double eta_2 = E_7*y*y*G_2*exp(E_8 + E_9/T_star + E_10/(T_star*T_star)); // Equation 9-6.23 - double omega = neufeld_collision_integral(T_star); // Equation 9-4.3 + double omega = neufeldCollisionIntegral(T_star); // Equation 9-4.3 // Molecular shapes and polarities factor, Equation 9-4.11 double Fc = 1 -0.2756*acentric_factor + 0.059035*pow(mu_r, 4.0) + kappa; From d05b7c6b7ebe80aef1ae9e62df83d7ea39724c28 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Wed, 3 Jul 2024 18:07:20 -0400 Subject: [PATCH 13/37] more documentation updates --- .../transport/HighPressureGasTransport.h | 277 +++++++++++++----- src/transport/HighPressureGasTransport.cpp | 109 ++++--- 2 files changed, 261 insertions(+), 125 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index 86251ad9c3..c7c5993737 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -148,48 +148,63 @@ class HighPressureGasTransport : public MixTransport * @note Equation numbers are from @cite poling2001 * * @f[ - * T_{\text{c,m}} = \sum_i y_i T_{\text{c,i}} + * T_{\text{c,m}} = \sum_i X_i T_{\text{c,i}} * * \quad \text{( Equation 9-5.18)} * @f] * + * Where @f$ T_{\text{c,i}} @f$ is the critical temperature of species i, + * and @f$ X_i @f$ is the mole fraction of species i. + * * @f[ - * P_{\text{c,m}} = R T_{\text{c,m}} \frac{\sum_i y_i Z_{\text{c,i}}}{\sum_i y_i V_{\text{c,i}}} + * P_{\text{c,m}} = R T_{\text{c,m}} \frac{\sum_i X_i Z_{\text{c,i}}}{\sum_i X_i V_{\text{c,i}}} * * \quad \text{(Equation 9-5.19)} * @f] * + * Where @f$ Z_{\text{c,i}} @f$ is the critical compressibility of species i, and + * @f$ V_{\text{c,i}} @f$ is the critical volume of species i. + * + * * @f[ - * M_m = \sum y_i M_i + * M_m = \sum X_i M_i * * \quad \text{(Equation 9-5.20)} * @f] * + * Where @f$ M_i @f$ is the molecular weight of species i. + * * @f[ - * F_{P,m}^{\text{o}} = \sum y_i F_{P,i}^{\text{o}} + * F_{P,m}^{\text{o}} = \sum X_i F_{P,i}^{\text{o}} * * \quad \text{(Equation 9-5.21)} * @f] * + * Where @f$ F_{P,i}^{\text{o}} @f$ is the low-pressure polarity correction + * factor of species i from equation 9-4.18. + * * @f[ - * F_{Q,m}^{\text{o}} = \left ( \sum y_i F_{Q,i}^{\text{o}} \right ) A + * F_{Q,m}^{\text{o}} = \left ( \sum X_i F_{Q,i}^{\text{o}} \right ) A * * \quad \text{(Equation 9-5.22)} * @f] * + * Where @f$ F_{Q,i}^{\text{o}} @f$ is the low-pressure quantum correction factor + * of species i from equation 9-4.19, and A is defined below. + * * @f[ * A = 1 - 0.01 \left ( \frac{M_H}{M_L} \right )^{0.87} * * \quad \text{(Equation 9-5.23)} * @f] * - * For @f$ \frac{M_H}{M_L} > 9 @f$ and @f$ 0.05 < y_H < 0.7 @f$, otherwise A = 1. + * For @f$ \frac{M_H}{M_L} > 9 @f$ and @f$ 0.05 < X_H < 0.7 @f$, otherwise A = 1. * In the above equation, $M_H$ and $M_L$ are the molecular weights of the - * heaviest and lightest components in the mixture, and @f$ y_H @f$ is the mole + * heaviest and lightest components in the mixture, and @f$ X_H @f$ is the mole * fraction of the heaviest component. * * While it isn't returned as a parameter, the species-specific reduced dipole - * moment is used to compute the mixture polarity correction factor. It is defined + * moment (@f$ \mu_r @f$) is used to compute the mixture polarity correction factor. It is defined * as: * * @f[ @@ -202,21 +217,26 @@ class HighPressureGasTransport : public MixTransport void computeMixtureParameters(LucasMixtureParameters& params); /** - * Returns the non-dimensional low-pressure mixture viscosity in using the Lucas method. - * - * Defined by equation 9-4.16. + * Returns the non-dimensional low-pressure mixture viscosity in using the Lucas + * method. * * @f[ - * \eta \xi = [0.807 T_r^{0.618} - 0.357 e^{-0.449 T_r} + 0.340e^{-4.058 T_r} + 0.018] F_P^{\text{o}} F_Q^{\text{o}} + * \eta \xi = F_P^{\text{o}} F_Q^{\text{o}} [0.807 T_r^{0.618} + * - 0.357 e^{-0.449 T_r} + * + 0.340e^{-4.058 T_r} + 0.018] + * + * \quad \text{(Equation 9-4.16)} * @f] * - * This function is structured such that it can be used for pure species or mixtures, with the - * only difference being the values that are passed to the function (pure values versus mixture values). + * This function is structured such that it can be used for pure species or + * mixtures, with the only difference being the values that are passed to the + * function (pure values versus mixture values). + * + * For the definition of the mixture rules, see @see computeMixtureParameters() . * * @param Tr Reduced temperature [unitless] * @param FP Polarity correction factor [unitless] * @param FQ Quantum correction factor [unitless] - * @return double */ double lowPressureNondimensionalViscosity(double Tr, double FP, double FQ); @@ -237,6 +257,8 @@ class HighPressureGasTransport : public MixTransport * mixtures, with the only difference being the values that are passed to the * function (pure values versus mixture values). * + * For the definition of the mixture rules, see @see computeMixtureParameters() . + * * @param Tr Reduced temperature [unitless] * @param Pr Reduced pressure [unitless] * @param FP_low Low-pressure polarity correction factor [unitless] @@ -254,7 +276,8 @@ class HighPressureGasTransport : public MixTransport * calculation. * * @f[ - * F_{Q}^{\text{o}} = 1.22 Q^{0.15} {1 + 0.00385[ (T_r - 12)^2 ]^{\frac{1}{MW}} \text{sign} (T_r - 12 )} + * F_{Q}^{\text{o}} = 1.22 Q^{0.15} {1 + 0.00385[ (T_r - 12)^2 ]^{\frac{1}{MW}} + * \text{sign} (T_r - 12 )} * * \quad \text{(Equation 9-4.19)} * @f] @@ -286,8 +309,8 @@ class HighPressureGasTransport : public MixTransport * * @note The original description in Poling(2001) neglects to mention what happens * when the quantity raised to the 1.72 power goes negative. That is an undefined - * operation that generates real and imaginary numbers. For now, only positive values - * are allowed. + * operation that generates real and imaginary numbers. For now, only positive + * values are allowed. * * @param mu_r Species Reduced dipole moment * @param Tr Reduced temperature @@ -363,41 +386,27 @@ class ChungHighPressureGasTransport : public MixTransport /** * Calculates the high-pressure mixture thermal conductivity using the Chung method. * - * The Chung method is described in on page 10.23. - * - * @f[ - * \lambda = \frac{31.2 \eta^0 \Psi}{M'} \left( G_1^{-1} + B_6 y \right) + q B_7 y^2 T_r^{1/2} G_2 - * @f] - ** where: - * - * @f[ - * \begin{align*} - * \lambda &= \text{thermal conductivity, W/(m·K)} \\ - * \eta^0 &= \text{low-pressure gas viscosity, N·s/m}^2 \\ - * M' &= \text{molecular weight, kg/mol} \\ - * \Psi &= f(C_v, \omega, T_r) \text{ [as defined under Eq. (10-3.14)]} \\ - * q &= 3.586 \times 10^{-3} \left( \frac{T_c}{M'} \right)^{1/2} V_c^{2/3} \\ - * T &= \text{temperature, K} \\ - * T_c &= \text{critical temperature, K} \\ - * T_r &= \text{reduced temperature, } \frac{T}{T_c} \\ - * V_c &= \text{critical volume, cm}^3/\text{mol} \\ - * \gamma &= \frac{V_c}{6V} - * \end{align*} - * @f] - * - * The details about the parameters and constants used in the expression are - * found in @cite poling2001 . + * This method obtains appropriate mixture values of the parameters needed for the + * Chung model and then calls the highPressureThermalConductivity() method to + * obtain the mixture thermal conductivity. * * The mixture values of the pseudo-critical temperature and other model parameters * are calculated using the Chung mixing rules defined on page 9.25. + * @see computeMixtureParameters() . * * The mixture value of the specific heat is computed using equation 10-6.6, which - * is the mole fraction weighted sum of the pure species specific heats. + * is the mole fraction weighted sum of the pure species specific heats. This value + * is not directly computed by the computeMixtureParameters() method. * * @f[ - * C_{v,m} = \sum_i y_i C_{v,i} + * C_{v,m} = \sum_i X_i C_{v,i} + * + * \quad \text{(Equation 10-6.6)} * @f] * + * Where @f$ C_{v,i} @f$ is the specific heat of species i, and @f$ X_i @f$ is the + * mole fraction of species i. + * */ double thermalConductivity() override; @@ -472,104 +481,177 @@ class ChungHighPressureGasTransport : public MixTransport * composition dependent parameters. The primary mixing rules are defined below. * * @f[ - * \sigma_m^3 = \sum_{i} \sum_{j} y_i y_j \sigma_{ij}^3 + * \sigma_m^3 = \sum_{i} \sum_{j} X_i X_j \sigma_{ij}^3 + * + * \quad \text{(Equation 9-5.25)} * @f] * + * Where @f$ \sigma_{ij} @f$ is the molecular diameter + * * @f[ * T_m^* = \frac{T}{\left( \frac{\epsilon}{k} \right )_m} + * + * \quad \text{(Equation 9-5.26)} * @f] * + * Where @f$ k @f$ is the Boltzmann constant and @f$ \epsilon @f$ is the minimum + * of the pair-potential energy. In these equations, we do not need to worry about + * what the values of @f$ \epsilon @f$ and @f$ k @f$ are. + * * @f[ - * \left ( \frac{\epsilon}{k} \right )_m = \frac{\sum_{i} \sum_{j} y_i y_j \left ( \frac{\epsilon_{ij}}{k} \right ) \sigma_{ij}^3}{\sigma_m^3} + * \left( \frac{\epsilon}{k} \right)_m = \frac{\sum_{i} \sum_{j} X_i X_j + * \left( \frac{\epsilon_{ij}}{k} \right) + * \sigma_{ij}^3}{\sigma_m^3} + * + * \quad \text{(Equation 9-5.27)} * @f] * * @f[ - * MW_m = \left [ \frac{\sum_{i} \sum_{j} y_i y_j \left ( \frac{\epsilon_{ij}}{k} \right ) \sigma_{ij}^2 MW_{ij}^{\frac{1}{2}}}{\left ( \frac{\epsilon}{k} \right )_m \sigma_m^2} \right ]^2 + * MW_m = \left[ \frac{\sum_{i} \sum_{j} X_i X_j \left( \frac{\epsilon_{ij}}{k} \right) + * \sigma_{ij}^2 MW_{ij}^{\frac{1}{2}}}{\left( \frac{\epsilon}{k} \right)_m + * \sigma_m^2} \right]^2 + * + * \quad \text{(Equation 9-5.28)} * @f] * + * Where MW is the molecular weight. + * * @f[ - * \omega_m = \frac{\sum_{i} \sum_{j} y_i y_j \omega_{ij} \sigma+{ij}^3}{\sigma_m^3} + * \omega_m = \frac{\sum_{i} \sum_{j} X_i X_j \omega_{ij} \sigma{ij}^3}{\sigma_m^3} + * + * \quad \text{(Equation 9-5.29)} * @f] * + * Where @f$ \omega @f$ is the acentric factor. + * * @f[ - * \mu_m^4 = \sigma_m^3 \sum_{i} \sum_{j} \left( \frac{y_i y_j \mu_i^2 \mu_j^2}{\sigma_{ij}^3} \right) + * \mu_m^4 = \sigma_m^3 \sum_{i} \sum_{j} \left( \frac{X_i X_j \mu_i^2 \mu_j^2} + * {\sigma_{ij}^3} \right) + * + * \quad \text{(Equation 9-5.30)} * @f] * + * Where @f$ \mu @f$ is the dipole moment. + * * @f[ - * \kappa_m = \sum_{i} \sum_{j} y_i y_j \kappa_{ij} + * \kappa_m = \sum_{i} \sum_{j} X_i X_j \kappa_{ij} + * + * \quad \text{(Equation 9-5.31)} * @f] * - * The combining rules are defined as: + * Where @f$ \kappa @f$ is the association factor, which is used for highly polar + * molecules. In this work, the value is assumed to be zero for all species. + * + * The combining rules for species-species values (subscripted with ij in the above + * equations) are defined below. * * @f[ * \sigma_{i} = 0.809 V_{c,i}^{1/3} + * + * \quad \text{(Equation 9-5.32)} * @f] * + * Where @f$ V_{c,i} @f$ is the critical volume of species i. + * * @f[ * \sigma_{ij} = \xi_{ij} \left( \sigma_{i} \sigma_{j} \right)^{1/2} + * + * \quad \text{(Equation 9-5.33)} * @f] * + * Where @f$ \xi @f$ is a binary interaction parameter. + * * @f[ * \left( \frac{\epsilon_i}{k} \right) = \frac{T_{c,i}}{1.2593} + * + * \quad \text{(Equation 9-5.34)} * @f] * * @f[ - * \left( \frac{\epsilon_{ij}}{k} \right) = \zeta_{ij} \left( \right) ^{\frac{1}{2}} + * \frac{\epsilon_{ij}}{k} = \zeta_{ij} \left( \right)^{\frac{1}{2}} + * + * \quad \text{(Equation 9-5.35)} * @f] * + * Where @f$ \zeta @f$ is a binary interaction parameter. + * * @f[ * \omega_{ij} = \frac{\omega_i + \omega_j}{2} + * + * \quad \text{(Equation 9-5.37)} * @f] * + * Where @f$ \omega @f$ is the acentric factor. + * * @f[ * \kappa_{ij} = \left( \kappa_i \kappa_j \right)^{1/2} + * + * \quad \text{(Equation 9-5.39)} * @f] * + * Where @f$ \kappa @f$ is the association factor. + * * @f[ * MW_{ij} = \frac{2 MW_i MW_j}{MW_i + MW_j} + * + * \quad \text{(Equation 9-5.40)} * @f] * - * @f$ \xi @f$ and @f$ \zeta @f$ are the binary interaction parameters, and are assumed to be unity - * in this implementation, in keeping with the Chung method. + * @f$ \xi @f$ and @f$ \zeta @f$ are the binary interaction parameters, and are + * assumed to be unity in this implementation, in keeping with the Chung method. * * The Chung viscosity correction factor is defined as: * * @f[ * F_{c,m} = 1 - 0.275 \omega_m + 0.059035 \mu_{r,m}^4 + \kappa_m + * + * \quad \text{(Equation 9-5.41)} * @f] * - * The reduced dipole moment computed using: + * Where @f$ \omega_m @f$ is the mixture acentric factor, @f$ \mu_{r,m} @f$ is the + * mixture reduced dipole moment, and @f$ \kappa_m @f$ is the mixture association + * factor. + * + * The mixture reduced dipole moment is computed using: * * @f[ - * \mu_{r,m} = \frac{131.3 \mu_m}{\left( V_{c,m} T_{c,m}\right)^{\frac{1}{2}}} + * \mu_{r,m} = \frac{131.3 \mu_m}{( V_{c,m} T_{c,m})^{\frac{1}{2}}} + * + * \quad \text{(Equation 9-5.42)} * @f] * + * Where @f$ V_{c,m} @f$ and @f$ T_{c,m} @f$ are computed using the following + * equations. + * * @f[ - * V_{c,m} = \left( \frac{\sigma_m}{0.809} \right) + * V_{c,m} = \left( \frac{\sigma_m}{0.809} \right)^3 + * + * \quad \text{(Equation 9-5.43)} * @f] * * @f[ - * T_{c,m} = 1.2593 \left( \frac{\epsilon}{k} \right)_m - * @f] + * T_{c,m} = 1.2593 \left( \frac{\epsilon}{k} \right)_m * - * In the equations, @f$ T_c @f$ must be in units of K, @f$ V_c @f$ must be in units of cm^3/mol, - * and @f$ \mu @f$ must be in units of Debye. + * \quad \text{(Equation 9-5.44)} + * @f] * + * In the equations, @f$ T_c @f$ must be in units of K, @f$ V_c @f$ must be in + * units of cm^3/mol, and @f$ \mu @f$ must be in units of Debye. */ void computeMixtureParameters(ChungMixtureParameters& params); /** * Returns the low-pressure mixture viscosity in Pa*s using the Chung method. * - * Defined by equation 9-4.10. - * * @f[ - * \eta = 26.69 F_c \frac{(M*T)^(\frac{1}{2})}{\sigma^2 \Omega} + * \eta = 26.69 F_c \frac{(MW*T)^(\frac{1}{2})}{\sigma^2 \Omega} + * + * \quad \text{(Equation 9-4.10)} * @f] * - * T must be in units of K, MW must be units of kg/kmol, and sigma must be units - * of Angstroms. The viscosity is computed in micropoise, but the return value is - * in standard SI units (Pa*s). + * T must be in units of K, MW must be units of kg/kmol, and @f$ \sigma @f$ must + * be in units of Angstroms. The viscosity is computed in micropoise, but the + * return value is in standard SI units (Pa*s). * * This function is structured such that it can be used for pure species or * mixtures, with the only difference being the values that are passed to the @@ -656,7 +738,7 @@ class ChungHighPressureGasTransport : public MixTransport * on page 10.23 of @cite poling2001 . * * @f[ - * \lambda = \frac{31.2 \eta^0 \Psi}{M'} \left( G_1^{-1} + B_6 y \right) + * \lambda = \frac{31.2 \eta^0 \Psi}{M'} \left( G_2^{-1} + B_6 y \right) * + q B_7 y^2 T_r^{1/2} G_2 * * \quad \text{(Equation 10-5.5)} @@ -675,26 +757,65 @@ class ChungHighPressureGasTransport : public MixTransport * T_c &= \text{critical temperature, K} \\ * T_r &= \text{reduced temperature, } \frac{T}{T_c} \\ * V_c &= \text{critical molar volume, cm}^3/\text{mol} \\ - * \gamma &= \frac{V_c}{6V} * \end{align*} * @f] * - * The details about the parameters and constants used in the expression are - * found in @cite poling2001 . + * where, * - * M_prime (M' in the model) has units of kg/mol, and is just the molecular weight - * (kg/kmol) divided by 1000. + * @f[ + * y = \frac{V_c}{6V} * - * The mixture values of the pseudo-critical temperature and other model parameters - * are calculated using the Chung mixing rules defined on page 9.25. + * \quad \text{(Equation 10-5.6)} + * @f] * - * The mixture value of the specific heat is computed using equation 10-6.6, which - * is the mole fraction weighted sum of the pure species specific heats. + * V is the molar volume of the fluid in cm^3/mol. * * @f[ - * C_{v,m} = \sum_i y_i C_{v,i} + * G_1 = \frac{1 - 0.5y}{(1-y)^3} + * + * \quad \text{(Equation 10-5.7)} + * @f] + * + * @f[ + * G_2 = \frac{(B_1 / y)[1 - \text{exp}(-B_4 y)] + B_2 G_1 \text{exp}(B_5 y) + B_3 G_1}{B_1 B_4 + B_2 + B_3} + * + * \quad \text{(Equation 10-5.8)} * @f] * + * The coefficients @f$ B_1 @f$, through @f$ B_7 @f$ are functions of the + * acentric factor, reduced dipole moment and the association factor. + * + * @f[ + * B_i = a_i + b_i \omega + c_i \mu_r^4 + d_i \kappa + * + * \quad \text{(Equation 10-5.9)} + * @f] + * + * The constants in the above equation are from table 10-3 on page 10.23 of + * @cite poling2001. + * + * The definition of the @f$ \Psi @f$ function is given by: + * + * @f[ + * \Psi = 1 + \alpha {\frac{0.215 + 0.28288\alpha - 1.061\beta + 0.26665Z}{0.6366 + \beta Z + 1.061 \alpha \beta}} + * @f] + * + * with, + * + * @f[ + * \alpha = \frac{C_v}{R} - \frac{3}{2} + * @f] + * + * @f[ + * \beta = 0.7862 - 0.7109 \omega + 1.3168 \omega^2 + * @f] + * + * @f[ + * Z = 2.0 + 10.5 T_r^2 + * @f] + * + * These functions are from page 10.12 of @cite poling2001 . + * * * This method utilizes the low-pressure Chung viscosity as that is a required * parameter in the model, and thus calls the low pressure viscosity diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 6e305b9522..32e21a8eb0 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -192,12 +192,14 @@ void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* cons { update_C(); update_T(); - // If necessary, evaluate the binary diffusion coefficients from the polynomial fits + // If necessary, evaluate the binary diffusion coefficients from the polynomial + // fits if (!m_bindiff_ok) { updateDiff_T(); } if (ld < m_nsp) { - throw CanteraError("HighPressureGasTransport::getBinaryDiffCoeffs", "ld is too small"); + throw CanteraError("HighPressureGasTransport::getBinaryDiffCoeffs", + "ld is too small"); } double rp = 1.0/m_thermo->pressure(); @@ -251,18 +253,25 @@ double HighPressureGasTransport::viscosity() return nondimensional_viscosity / xi; } - void HighPressureGasTransport::computeMixtureParameters(LucasMixtureParameters& params) { double Tc_mix = 0.0; double Pc_mix_n = 0.0; // Numerator in equation 9-5.19 double Pc_mix_d = 0.0; // Denominator in equation 9-5.19 - double MW_mix = m_thermo->meanMolecularWeight(); // Equation 9.5.20, Cantera already mole-weights the molecular weights - double FP_mix_o = 0; // The mole-fraction-weighted mixture average of the low-pressure polarity correction factor - double FQ_mix_o = 0; // The mole-fraction-weighted mixture average of the low-pressure quantum correction factor - double MW_H = m_mw[0]; // Holds the molecular weight of the heaviest species - double MW_L = m_mw[0]; // Holds the molecular weight of the lightest species + // Equation 9.5.20, Cantera already mole-weights the molecular weights + double MW_mix = m_thermo->meanMolecularWeight(); + + // Mole-fraction-weighted mixture average of the low-pressure polarity correction + // factor + double FP_mix_o = 0; + + // Mole-fraction-weighted mixture average of the low-pressure quantum correction + // factor + double FQ_mix_o = 0; + + double MW_H = m_mw[0]; // Molecular weight of the heaviest species + double MW_L = m_mw[0]; // Molecular weight of the lightest species double tKelvin = m_thermo->temperature(); double P_vap_mix = m_thermo->satPressure(tKelvin); @@ -304,7 +313,9 @@ void HighPressureGasTransport::computeMixtureParameters(LucasMixtureParameters& double SI_to_Debye = 1.0 / 3.335e-30; // Conversion factor from C*m to Debye double dipole_ii = m_dipole(i,i)*SI_to_Debye; double mu_ri = 52.46*dipole_ii*dipole_ii*(Pcrit_i(i)*pascals_to_bar)/(Tc*Tc); - FP_mix_o += molefracs[i] * polarityCorrectionFactor(mu_ri, Tr, Zc); // mole-fraction weighting of pure-species polar correction term + + // mole-fraction weighting of pure-species polar correction term + FP_mix_o += molefracs[i] * polarityCorrectionFactor(mu_ri, Tr, Zc); // Calculate contribution to quantum correction term. // Note: This assumes the species of interest (He, H2, and D2) have @@ -334,7 +345,6 @@ void HighPressureGasTransport::computeMixtureParameters(LucasMixtureParameters& } FQ_mix_o *= A; - params.FQ_mix_o = FQ_mix_o; params.FP_mix_o = FP_mix_o; params.Tc_mix = Tc_mix; @@ -578,6 +588,7 @@ double ChungHighPressureGasTransport::highPressureThermalConductivity( double viscosity = lowPressureViscosity(T, T_star, MW, acentric_factor, mu_r, sigma, kappa); + double M_prime = MW / 1000.0; // Convert kg/kmol to kg/mol // Definition of tabulated coefficients for the Chung method, as shown in @@ -602,17 +613,23 @@ double ChungHighPressureGasTransport::highPressureThermalConductivity( double G_1 = (1.0 - 0.5*y)/(pow(1.0-y, 3.0)); // Equation 10-5.7 // Equation 10-5.8 - double G_2 = (B_1*((1.0-exp(-B_4*y)) / y) + B_2*G_1*exp(B_5*y) + B_3*G_1)/ (B_1*B_4 + B_2 + B_3); + double G_2 = (B_1*((1.0-exp(-B_4*y)) / y) + B_2*G_1*exp(B_5*y) + B_3*G_1) + / (B_1*B_4 + B_2 + B_3); - double q = 3.586e-3*sqrt(Tc/M_prime) / pow(Vc, 2.0/3.0); // Shown below equation 10-5.5 + double q = 3.586e-3*sqrt(Tc/M_prime) / pow(Vc, 2.0/3.0); // Below equation 10-5.5 double Tr = T/Tc; // Reduced temperature - double alpha = (Cv / GasConstant) - 3.0/2.0; // Shown below equation 10-3.14, using R(J/kmol/K ) - double beta = 0.7862 - 0.7109*acentric_factor + 1.3168*acentric_factor*acentric_factor; // Shown below Equation 10-3.14 - double Z = 2.0 + 10.5*Tr*Tr; // Shown below Equation 10-3.14 - double psi = 1.0 + alpha*((0.215 + 0.28288*alpha - 1.061*beta + 0.26665*Z) / (0.6366 + beta*Z + 1.061*alpha*beta)); // Shown below Equation 10-3.14 - - double lambda = (31.2*viscosity*psi/M_prime)*(1.0/G_2 + B_6*y) + q*B_7*y*y*sqrt(Tr)*G_2; // Equation 10-5.5 + // The following 4 equations are defined below Equation 10-3.14 + double alpha = (Cv / GasConstant) - 3.0/2.0; // GasConstant(R) has units (J/kmol/K) + double beta = 0.7862 - 0.7109*acentric_factor + + 1.3168*acentric_factor*acentric_factor; + double Z = 2.0 + 10.5*Tr*Tr; + double psi = 1.0 + alpha*((0.215 + 0.28288*alpha - 1.061*beta + 0.26665*Z) + / (0.6366 + beta*Z + 1.061*alpha*beta)); + + // Equation 10-5.5 + double lambda = (31.2*viscosity*psi/M_prime)*(1.0/G_2 + B_6*y) + + q*B_7*y*y*sqrt(Tr)*G_2; // Units are W/m/K return lambda; @@ -631,10 +648,10 @@ double ChungHighPressureGasTransport::viscosity() // The Chung method requires density to be units of mol/cm^3 // We use the mixture molecular weight (units of kg/kmol) here. double kg_per_m3_to_mol_per_cm3 = (1.0 / params.MW_mix)*1e-3; // 1 kmol/m^3 = 1e-3 mol/cm^3 - double density = m_thermo->density()*kg_per_m3_to_mol_per_cm3; + double molar_density = m_thermo->density()*kg_per_m3_to_mol_per_cm3; // This result is in units of micropoise - double viscosity = highPressureViscosity(T_star, params.MW_mix, density, + double viscosity = highPressureViscosity(T_star, params.MW_mix, molar_density, params.Vc_mix, params.Tc_mix, params.acentric_factor_mix, params.mu_r_mix, params.kappa_mix); @@ -650,8 +667,8 @@ void ChungHighPressureGasTransport::computeMixtureParameters(ChungMixtureParamet vector molefracs(nsp); m_thermo->getMoleFractions(&molefracs[0]); - // First fill the species-specific values that will then later be used in the combining - // rules for the Chung method. + // First fill the species-specific values that will then later be used in the + // combining rules for the Chung method. vector sigma_i(nsp), epsilon_over_k_i(nsp), acentric_factor_i(nsp), MW_i(nsp), kappa_i(nsp); for (size_t i = 0; i < m_nsp; i++) { // From equation 9-5.32. @@ -675,10 +692,10 @@ void ChungHighPressureGasTransport::computeMixtureParameters(ChungMixtureParamet // We have ASSUMED that the binary interaction parameters are unity for all species // as was done in the Chung method. // - // The sigma & kappa relations can be fully computed in the loop. The other ones require a final - // division by the final mixture values, and so the quantities in the loop are only the - // numerators of the equations that are referenced in the comments. After the loop, the - // final mixture values are computed and stored. + // The sigma & kappa relations can be fully computed in the loop. The other ones + // require a final division by the final mixture values, and so the quantities in + // the loop are only the numerators of the equations that are referenced in the + // comments. After the loop, the final mixture values are computed and stored. for (size_t i = 0; i < m_nsp; i++) { for (size_t j = 0; j a = {6.324, 1.210e-3, 5.283, 6.623, 19.745, -1.900, 24.275, 0.7972, -0.2382, 0.06863}; static const vector b = {50.412, -1.154e-3, 254.209, 38.096, 7.630, -12.537, 3.450, 1.117, 0.06770, 0.3479}; static const vector c = {-51.680, -6.257e-3, -168.48, -8.464, -14.354, 4.958, -11.291, 0.01235, -0.8163, 0.5926}; @@ -810,6 +823,8 @@ double ChungHighPressureGasTransport::highPressureViscosity(double T_star, doubl // Molecular shapes and polarities factor, Equation 9-4.11 double Fc = 1 -0.2756*acentric_factor + 0.059035*pow(mu_r, 4.0) + kappa; + // Renamed eta_star and eta_star_star from the Poling description to eta_1 and + // eta_2 for naming simplicity. double eta_1 = (sqrt(T_star)/omega) * (Fc*(1.0/G_2 + E_6*y)) + eta_2; // Equation 9-6.19 double eta = eta_1 * 36.344 * sqrt(MW*Tc) / pow(Vc, 2.0/3.0); // Equation 9-6.18 From 913814b922e186c693222fb4f5b7be5f6717e11b Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Fri, 5 Jul 2024 18:44:12 -0400 Subject: [PATCH 14/37] addressing comments, new sample added --- data/methane_co2.yaml | 66 +++++ .../transport/HighPressureGasTransport.h | 107 ++++---- .../transport/high_pressure_transport.py | 57 +++++ src/transport/HighPressureGasTransport.cpp | 232 +++++++++--------- 4 files changed, 300 insertions(+), 162 deletions(-) create mode 100644 data/methane_co2.yaml create mode 100644 samples/python/transport/high_pressure_transport.py diff --git a/data/methane_co2.yaml b/data/methane_co2.yaml new file mode 100644 index 0000000000..146c8d5880 --- /dev/null +++ b/data/methane_co2.yaml @@ -0,0 +1,66 @@ +units: {length: cm, quantity: mol, activation-energy: cal/mol} + +phases: +- name: methane_co2 + species: [CH4, CO2] + thermo: Peng-Robinson + kinetics: gas + transport: mixture-averaged + reactions: none + state: + T: 300 + P: 1 atm + +species: +- name: CH4 + composition: {C: 1, H: 4} + thermo: + model: NASA7 + temperature-ranges: [200.0, 1000.0, 3500.0] + data: + - [5.14987613, -0.0136709788, 4.91800599e-05, -4.84743026e-08, 1.66693956e-11, + -1.02466476e+04, -4.64130376] + - [0.074851495, 0.0133909467, -5.73285809e-06, 1.22292535e-09, -1.0181523e-13, + -9468.34459, 18.437318] + note: L8/88 + transport: + model: gas + geometry: nonlinear + well-depth: 141.4 + diameter: 3.746 + polarizability: 2.6 + rotational-relaxation: 13.0 + critical-parameters: + critical-temperature: 190.7 + critical-pressure: 4.63e+06 + critical-molar-volume: 0.0989 + critical-compressibility: 0.288 + acentric-factor: 0.011 + +- name: CO2 + composition: {C: 1, O: 2} + thermo: + model: NASA7 + temperature-ranges: [200.0, 1000.0, 3500.0] + data: + - [2.35677352, 8.98459677e-03, -7.12356269e-06, 2.45919022e-09, -1.43699548e-13, + -4.83719697e+04, 9.90105222] + - [3.85746029, 4.41437026e-03, -2.21481404e-06, 5.23490188e-10, -4.72084164e-14, + -4.8759166e+04, 2.27163806] + note: L7/88 + transport: + model: gas + geometry: linear + well-depth: 244.0 + diameter: 3.763 + polarizability: 2.65 + rotational-relaxation: 2.1 + critical-parameters: + critical-temperature: 304.2 + critical-pressure: 7.39e+06 + critical-molar-volume: 0.0948 + critical-compressibility: 0.275 + acentric-factor: 0.228 + + + diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index c7c5993737..a6694762a1 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -43,13 +43,14 @@ class HighPressureGasTransport : public MixTransport { protected: //! default constructor - HighPressureGasTransport() = default; + HighPressureGasTransport()=default; public: string transportModel() const override { return "high-pressure"; } + void init(ThermoPhase* thermo, int mode=0, int log_level=0) override; /** * Returns the mixture high-pressure thermal conductivity in W/m/K * using a method by Ely and Hanley. @@ -88,49 +89,42 @@ class HighPressureGasTransport : public MixTransport friend class TransportFactory; protected: + /** - * Returns the estimate of the critical temperature that is given from the thermo - * object for species i. + * Computes and stores the estimate of the critical properties for each species. * * This method sets the species composition vector to unity for species i and zero * for all other species, and then queries the thermo object for the critical - * temperature. It then resets the composition vector to the original state. + * properties and stores them. It then resets the composition vector to the original + * state. This method only needs to be called once, as the critical properties for + * the pure species do not change. + * + */ + void initializeCriticalProperties(); + + /** + * Returns the stored value of the critical temperature. * * @param i Species index */ double Tcrit_i(size_t i); /** - * Returns the estimate of the critical pressure that is given from the thermo - * object for species i. - * - * This method sets the species composition vector to unity for species i and zero - * for all other species, and then queries the thermo object for the critical - * pressure. It then resets the composition vector to the original state. + * Returns the stored value of the critical pressure. * * @param i Species index */ double Pcrit_i(size_t i); /** - * Returns the estimate of the critical volume that is given from the thermo - * object for species i. - * - * This method sets the species composition vector to unity for species i and zero - * for all other species, and then queries the thermo object for the critical - * volume. It then resets the composition vector to the original state. + * Returns the stored value of the critical volume. * * @param i Species index */ double Vcrit_i(size_t i); /** - * Returns the estimate of the critical compressibility that is given from the - * thermo object for species i. - * - * This method sets the species composition vector to unity for species i and zero - * for all other species, and then queries the thermo object for the critical - * compressibility. It then resets the composition vector to the original state. + * Returns the stored value of the critical compressibility. * * @param i Species index */ @@ -165,7 +159,6 @@ class HighPressureGasTransport : public MixTransport * Where @f$ Z_{\text{c,i}} @f$ is the critical compressibility of species i, and * @f$ V_{\text{c,i}} @f$ is the critical volume of species i. * - * * @f[ * M_m = \sum X_i M_i * @@ -317,6 +310,15 @@ class HighPressureGasTransport : public MixTransport * @param Z_c Species Critical compressibility */ double polarityCorrectionFactor(double mu_r, double Tr, double Z_c); + + + private: + //! Critical properties of each species. + std::vector m_Tcrit; + std::vector m_Pcrit; + std::vector m_Vcrit; + std::vector m_Zcrit; + }; @@ -359,13 +361,14 @@ class ChungHighPressureGasTransport : public MixTransport { protected: //! default constructor - ChungHighPressureGasTransport() = default; + ChungHighPressureGasTransport()=default; public: string transportModel() const override { return "high-pressure-chung"; } + void init(ThermoPhase* thermo, int mode=0, int log_level=0) override; /** * Returns the high-pressure mixture viscosity in Pa*s using the Chung method. @@ -426,48 +429,47 @@ class ChungHighPressureGasTransport : public MixTransport protected: /** - * Returns the estimate of the critical temperature that is given from the thermo - * object for species i. + * Computes and stores the estimate of the critical properties for each species. * * This method sets the species composition vector to unity for species i and zero * for all other species, and then queries the thermo object for the critical - * temperature. It then resets the composition vector to the original state. + * properties and stores them. It then resets the composition vector to the original + * state. This method only needs to be called once, as the critical properties for + * the pure species do not change. + * + */ + void initializeCriticalProperties(); + + /** + * Computes and stores pure-fluid specific properties each species. + * + * + */ + void initializePureFluidProperties(); + + /** + * Returns the stored value of the critical temperature. * * @param i Species index */ double Tcrit_i(size_t i); /** - * Returns the estimate of the critical pressure that is given from the thermo - * object for species i. - * - * This method sets the species composition vector to unity for species i and zero - * for all other species, and then queries the thermo object for the critical - * pressure. It then resets the composition vector to the original state. + * Returns the stored value of the critical pressure. * * @param i Species index */ double Pcrit_i(size_t i); /** - * Returns the estimate of the critical volume that is given from the thermo - * object for species i. - * - * This method sets the species composition vector to unity for species i and zero - * for all other species, and then queries the thermo object for the critical - * volume. It then resets the composition vector to the original state. + * Returns the stored value of the critical volume. * * @param i Species index */ double Vcrit_i(size_t i); /** - * Returns the estimate of the critical compressibility that is given from the - * thermo object for species i. - * - * This method sets the species composition vector to unity for species i and zero - * for all other species, and then queries the thermo object for the critical - * compressibility. It then resets the composition vector to the original state. + * Returns the stored value of the critical compressibility. * * @param i Species index */ @@ -845,6 +847,21 @@ class ChungHighPressureGasTransport : public MixTransport double highPressureThermalConductivity(double T, double T_star, double MW, double rho, double Cv, double Vc, double Tc, double sigma, double acentric_factor, double mu_r, double kappa); + + private: + //! Critical properties of each species. + std::vector m_Tcrit; + std::vector m_Pcrit; + std::vector m_Vcrit; + std::vector m_Zcrit; + + //! Pure fluid properties of each species. + std::vector sigma_i; + std::vector epsilon_over_k_i; + std::vector MW_i; + std::vector acentric_factor_i; + std::vector kappa_i; + }; } diff --git a/samples/python/transport/high_pressure_transport.py b/samples/python/transport/high_pressure_transport.py new file mode 100644 index 0000000000..8d909bec6c --- /dev/null +++ b/samples/python/transport/high_pressure_transport.py @@ -0,0 +1,57 @@ +""" +High-Pressure transport using two models +======================================== + +Two high-pressure gas transport models are available in Cantera: the 'high-pressure' +and the 'high-pressure-chung' models. These models utilize critical fluid properties +and other fluid-specific parameters to calculate transport properties at high pressures. +These models are useful for fluids that are supercritical where ideal gas assumptions +do not yield accurate results. + +Requires: cantera >= 3.1.0 + +.. tags:: Python, transport, high-pressure +""" +import matplotlib.pyplot as plt +import numpy as np +import cantera as ct + +# Plot the difference between the high-pressure viscosity model and +# what an ideal gas model would give for Methane. +gas = ct.Solution('methane_co2.yaml') + +pressures = np.linspace(101325, 6e7, 100) +# Collect ideal viscosities +ideal_viscosities = [] +for pressure in pressures: + gas.TPX = 350, pressure, 'CH4:1.0' + ideal_viscosities.append(gas.viscosity) + +# Collect real viscosities using the high-pressure-chung +gas.transport_model = 'high-pressure-chung' +real_viscosities_1 = [] +for pressure in pressures: + gas.TPX = 350, pressure, 'CH4:1.0' + real_viscosities_1.append(gas.viscosity) + +# Collect real viscosities using the high-pressure model +gas.transport_model = 'high-pressure' +real_viscosities_2 = [] +for pressure in pressures: + gas.TPX = 350, pressure, 'CH4:1.0' + real_viscosities_2.append(gas.viscosity) + +# Plot the data +plt.figure(figsize=(10, 6)) +plt.plot(pressures, ideal_viscosities, label='Ideal Viscosity') +plt.plot(pressures, real_viscosities_1, label='High-Pressure Viscosity (Chung)') +plt.plot(pressures, real_viscosities_2, label='High-Pressure Viscosity (Lucas)') +plt.xlabel('Pressure (Pa)') +plt.ylabel('Viscosity (Pa·s)') +plt.title('Methane Viscosity Model Comparison') +plt.legend() +plt.grid(True) +plt.show() + + + diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 32e21a8eb0..ddd9e9a4c8 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -98,6 +98,41 @@ double takahashiCorrectionFactor(double Pr, double Tr) return DP_R_lower*(1.0 - frac) + DP_R_upper*frac; } +void HighPressureGasTransport::init(ThermoPhase* thermo, int mode, int log_level) +{ + MixTransport::init(thermo, mode, log_level); + initializeCriticalProperties(); +} + +void HighPressureGasTransport::initializeCriticalProperties() +{ + size_t nSpecies = m_thermo->nSpecies(); + m_Tcrit.resize(nSpecies); + m_Pcrit.resize(nSpecies); + m_Vcrit.resize(nSpecies); + m_Zcrit.resize(nSpecies); + + std::vector molefracs(nSpecies); + m_thermo->getMoleFractions(&molefracs[0]); + + std::vector mf_temp(nSpecies, 0.0); + + for (size_t i = 0; i < nSpecies; ++i) { + mf_temp[i] = 1.0; + m_thermo->setMoleFractions(&mf_temp[0]); + + m_Tcrit[i] = m_thermo->critTemperature(); + m_Pcrit[i] = m_thermo->critPressure(); + m_Vcrit[i] = m_thermo->critVolume(); + m_Zcrit[i] = m_thermo->critCompressibility(); + + mf_temp[i] = 0.0; // Reset for the next iteration + } + + // Restore actual mole fractions + m_thermo->setMoleFractions(&molefracs[0]); +} + double HighPressureGasTransport::thermalConductivity() { // Method of Ely and Hanley: @@ -358,62 +393,22 @@ void HighPressureGasTransport::computeMixtureParameters(LucasMixtureParameters& // Pure species critical properties - Tc, Pc, Vc, Zc: double HighPressureGasTransport::Tcrit_i(size_t i) { - vector molefracs(m_thermo->nSpecies()); - m_thermo->getMoleFractions(&molefracs[0]); - vector mf_temp(m_thermo->nSpecies(), 0.0); - mf_temp[i] = 1; - m_thermo->setMoleFractions(&mf_temp[0]); - - double tc = m_thermo->critTemperature(); - - // Restore actual molefracs: - m_thermo->setMoleFractions(&molefracs[0]); - return tc; + return m_Tcrit[i]; } double HighPressureGasTransport::Pcrit_i(size_t i) { - vector molefracs(m_thermo->nSpecies()); - m_thermo->getMoleFractions(&molefracs[0]); - vector mf_temp(m_thermo->nSpecies(), 0.0); - mf_temp[i] = 1; - m_thermo->setMoleFractions(&mf_temp[0]); - - double pc = m_thermo->critPressure(); - - // Restore actual molefracs: - m_thermo->setMoleFractions(&molefracs[0]); - return pc; + return m_Pcrit[i]; } double HighPressureGasTransport::Vcrit_i(size_t i) { - vector molefracs(m_thermo->nSpecies()); - m_thermo->getMoleFractions(&molefracs[0]); - vector mf_temp(m_thermo->nSpecies(), 0.0); - mf_temp[i] = 1; - m_thermo->setMoleFractions(&mf_temp[0]); - - double vc = m_thermo->critVolume(); - - // Restore actual molefracs: - m_thermo->setMoleFractions(&molefracs[0]); - return vc; + return m_Vcrit[i]; } double HighPressureGasTransport::Zcrit_i(size_t i) { - vector molefracs(m_thermo->nSpecies()); - m_thermo->getMoleFractions(&molefracs[0]); - vector mf_temp(m_thermo->nSpecies(), 0.0); - mf_temp[i] = 1; - m_thermo->setMoleFractions(&mf_temp[0]); - - double zc = m_thermo->critCompressibility(); - - // Restore actual molefracs: - m_thermo->setMoleFractions(&molefracs[0]); - return zc; + return m_Zcrit[i]; } double HighPressureGasTransport::lowPressureNondimensionalViscosity( @@ -435,10 +430,11 @@ double HighPressureGasTransport::highPressureNondimensionalViscosity( if (Pr < P_vap/P_crit) { double alpha = 3.262 + 14.98*pow(Pr, 5.508); double beta = 1.390 + 5.746*Pr; - Z_2 = 0.600 + 0.760*pow(Pr, alpha) + (0.6990*pow(Pr, beta) - 0.60) * (1-Tr); + Z_2 = 0.600 + 0.760*pow(Pr,alpha) + (0.6990*pow(Pr,beta) - 0.60) * (1-Tr); } else { throw CanteraError("HighPressureGasTransport::highPressureNondimensionalViscosity", - "State is outside the limits of the Lucas model, Pr >= P_vap / P_crit when Tr <= 1.0"); + "State is outside the limits of the Lucas model, Pr ({}) >= " + "P_vap / P_crit ({}) when Tr ({}) <= 1.0", Pr, P_vap / P_crit, Tr); } } else if (Tr > 1.0 && Tr < 40.0) { if (Pr > 0.0 && Pr <= 100.0) { @@ -473,11 +469,13 @@ double HighPressureGasTransport::highPressureNondimensionalViscosity( Z_2 = Z_1*(1 + (a*pow(Pr,e)) / (b*pow(Pr,f) + pow(1+c*pow(Pr,d),-1))); } else { throw CanteraError("HighPressureGasTransport::highPressureNondimensionalViscosity", - "State is outside the limits of the Lucas model, valid values of Pr are: 0.0 < Pr <= 100"); + "The value of Pr ({}) is outside the limits of the Lucas model, " + "valid values of Pr are: 0.0 < Pr <= 100", Pr); } } else { throw CanteraError("HighPressureGasTransport::highPressureNondimensionalViscosity", - "State is outside the limits of the Lucas model, valid values of Tr are: 1.0 < Tr < 40"); + "The value of Tr is outside the limits of the Lucas model, " + "valid values of Tr are: 1.0 < Tr < 40", Tr); } double Y = Z_2 / Z_1; @@ -508,6 +506,69 @@ double HighPressureGasTransport::polarityCorrectionFactor(double mu_r, double Tr // Chung Implementation // -------------------- +void ChungHighPressureGasTransport::init(ThermoPhase* thermo, int mode, int log_level) +{ + MixTransport::init(thermo, mode, log_level); + initializeCriticalProperties(); + initializePureFluidProperties(); +} + +void ChungHighPressureGasTransport::initializeCriticalProperties() +{ + m_Tcrit.resize(m_nsp); + m_Pcrit.resize(m_nsp); + m_Vcrit.resize(m_nsp); + m_Zcrit.resize(m_nsp); + + std::vector molefracs(m_nsp); + m_thermo->getMoleFractions(&molefracs[0]); + + std::vector mf_temp(m_nsp, 0.0); + + for (size_t i = 0; i < m_nsp; ++i) { + mf_temp[i] = 1.0; + m_thermo->setMoleFractions(&mf_temp[0]); + + m_Tcrit[i] = m_thermo->critTemperature(); + m_Pcrit[i] = m_thermo->critPressure(); + m_Vcrit[i] = m_thermo->critVolume(); + m_Zcrit[i] = m_thermo->critCompressibility(); + + mf_temp[i] = 0.0; // Reset for the next iteration + } + + // Restore actual mole fractions + m_thermo->setMoleFractions(&molefracs[0]); +} + +void ChungHighPressureGasTransport::initializePureFluidProperties() +{ + // First fill the species-specific values that will then be used in the + // combining rules for the Chung method. + sigma_i.resize(m_nsp); + epsilon_over_k_i.resize(m_nsp); + acentric_factor_i.resize(m_nsp); + MW_i.resize(m_nsp); + kappa_i.resize(m_nsp); + for (size_t i = 0; i < m_nsp; i++) { + // From equation 9-5.32. + double m3_per_kmol_to_cm3_per_mol = 1e3; // Convert from m^3/kmol to cm^3/mol + double Vc = Vcrit_i(i) * m3_per_kmol_to_cm3_per_mol; + sigma_i[i] = 0.809*pow(Vc, 1.0/3.0); + + // From equation 9-5.34. + epsilon_over_k_i[i] = Tcrit_i(i)/1.2593; + + // NOTE: The association parameter is assumed to be zero for all species, but + // is left here for completeness or future revision. + kappa_i[i] = 0.0; + + // These values are available from the base class + acentric_factor_i[i] = m_w_ac[i]; + MW_i[i] = m_mw[i]; + } +} + void ChungHighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* const d) { update_C(); @@ -663,31 +724,6 @@ double ChungHighPressureGasTransport::viscosity() void ChungHighPressureGasTransport::computeMixtureParameters(ChungMixtureParameters& params) { - size_t nsp = m_thermo->nSpecies(); - vector molefracs(nsp); - m_thermo->getMoleFractions(&molefracs[0]); - - // First fill the species-specific values that will then later be used in the - // combining rules for the Chung method. - vector sigma_i(nsp), epsilon_over_k_i(nsp), acentric_factor_i(nsp), MW_i(nsp), kappa_i(nsp); - for (size_t i = 0; i < m_nsp; i++) { - // From equation 9-5.32. - double m3_per_kmol_to_cm3_per_mol = 1e3; // Convert from m^3/kmol to cm^3/mol - double Vc = Vcrit_i(i) * m3_per_kmol_to_cm3_per_mol; - sigma_i[i] = 0.809*pow(Vc, 1.0/3.0); - - // From equation 9-5.34. - epsilon_over_k_i[i] = Tcrit_i(i)/1.2593; - - // NOTE: The association parameter is assumed to be zero for all species, but - // is left here for completeness or future revision. - kappa_i[i] = 0.0; - - // These values are available from the base class - acentric_factor_i[i] = m_w_ac[i]; - MW_i[i] = m_mw[i]; - } - // Here we use the combining rules defined on page 9.25. // We have ASSUMED that the binary interaction parameters are unity for all species // as was done in the Chung method. @@ -696,6 +732,8 @@ void ChungHighPressureGasTransport::computeMixtureParameters(ChungMixtureParamet // require a final division by the final mixture values, and so the quantities in // the loop are only the numerators of the equations that are referenced in the // comments. After the loop, the final mixture values are computed and stored. + vector molefracs(m_nsp); + m_thermo->getMoleFractions(&molefracs[0]); for (size_t i = 0; i < m_nsp; i++) { for (size_t j = 0; j molefracs(m_thermo->nSpecies()); - m_thermo->getMoleFractions(&molefracs[0]); - vector mf_temp(m_thermo->nSpecies(), 0.0); - mf_temp[i] = 1; - m_thermo->setMoleFractions(&mf_temp[0]); - - double tc = m_thermo->critTemperature(); - - // Restore actual molefracs: - m_thermo->setMoleFractions(&molefracs[0]); - return tc; + return m_Tcrit[i]; } double ChungHighPressureGasTransport::Pcrit_i(size_t i) { - vector molefracs(m_thermo->nSpecies()); - m_thermo->getMoleFractions(&molefracs[0]); - vector mf_temp(m_thermo->nSpecies(), 0.0); - mf_temp[i] = 1; - m_thermo->setMoleFractions(&mf_temp[0]); - - double pc = m_thermo->critPressure(); - - // Restore actual molefracs: - m_thermo->setMoleFractions(&molefracs[0]); - return pc; + return m_Pcrit[i]; } double ChungHighPressureGasTransport::Vcrit_i(size_t i) { - vector molefracs(m_thermo->nSpecies()); - m_thermo->getMoleFractions(&molefracs[0]); - vector mf_temp(m_thermo->nSpecies(), 0.0); - mf_temp[i] = 1; - m_thermo->setMoleFractions(&mf_temp[0]); - - double vc = m_thermo->critVolume(); - - // Restore actual molefracs: - m_thermo->setMoleFractions(&molefracs[0]); - return vc; + return m_Vcrit[i]; } double ChungHighPressureGasTransport::Zcrit_i(size_t i) { - vector molefracs(m_thermo->nSpecies()); - m_thermo->getMoleFractions(&molefracs[0]); - vector mf_temp(m_thermo->nSpecies(), 0.0); - mf_temp[i] = 1; - m_thermo->setMoleFractions(&mf_temp[0]); - - double zc = m_thermo->critCompressibility(); - - // Restore actual molefracs: - m_thermo->setMoleFractions(&molefracs[0]); - return zc; + return m_Zcrit[i]; } From f18aaa3c671f198cd46c6a4ddb8e331a4d4f7a0e Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Tue, 9 Jul 2024 13:14:10 -0400 Subject: [PATCH 15/37] updates for documentation of the Ely and Hanley conductivity implementation --- doc/doxygen/cantera.bib | 20 ++++ src/transport/HighPressureGasTransport.cpp | 119 +++++++++++++++------ 2 files changed, 105 insertions(+), 34 deletions(-) diff --git a/doc/doxygen/cantera.bib b/doc/doxygen/cantera.bib index ecf3566fb0..994555736c 100644 --- a/doc/doxygen/cantera.bib +++ b/doc/doxygen/cantera.bib @@ -60,6 +60,26 @@ @article{dixon-lewis1968 year = {1968}, doi = {10.1098/rspa.1968.0178}, URL = {https://royalsocietypublishing.org/doi/abs/10.1098/rspa.1968.0178}} +@article{ely-hanley1981, + author = {Ely, James F. and Hanley, H. J. M.}, + title = {Prediction of transport properties. 1. Viscosity of fluids and mixtures}, + journal = {Industrial \& Engineering Chemistry Fundamentals}, + volume = {20}, + number = {4}, + pages = {323-332}, + year = {1981}, + doi = {10.1021/i100004a004}, + URL = {https://doi.org/10.1021/i100004a004}} +@article{ely-hanley1983, + author = {Ely, James F. and Hanley, H. J. M.}, + title = {Prediction of transport properties. 2. Thermal conductivity of pure fluids and mixtures}, + journal = {Industrial \& Engineering Chemistry Fundamentals}, + volume = {22}, + number = {1}, + pages = {90-97}, + year = {1983}, + doi = {10.1021/i100009a016}, + URL = {https://doi.org/10.1021/i100009a016}} @article{gilbert1983, author = {R.~G.~Gilbert and K.~Luther and J.~Troe}, journal = {Berichte der Bunsengesellschaft für physikalische Chemie}, diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index ddd9e9a4c8..2b5dd05f03 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -133,18 +133,43 @@ void HighPressureGasTransport::initializeCriticalProperties() m_thermo->setMoleFractions(&molefracs[0]); } +/** + * @This implementation uses the method of Ely and Hanley to compute the thermal + * conductivity. + * + * The method is detailed in @cite ely-hanley1981 and @cite ely-hanley1983 . + * + * This method uses a reference fluid of methane. + * + * The Leach and Leland shape factors @f$ \theta_{\alpha,0} @f$ and @f$ \phi_{\alpha,0} @f$ are + * defined as: + * + * + */ double HighPressureGasTransport::thermalConductivity() { - // Method of Ely and Hanley: + // Method of Ely and Hanley. update_T(); double Lprime_m = 0.0; - const double c1 = 1./16.04; + const double c1 = 1./16.04; // Reciprocal of methane's molecular weight size_t nsp = m_thermo->nSpecies(); vector molefracs(nsp); m_thermo->getMoleFractions(&molefracs[0]); vector cp_0_R(nsp); m_thermo->getCp_R_ref(&cp_0_R[0]); + // Reference fluid properties + const double ref_MW = 16.04; // kg/kmol + const double ref_Tc = 190.4; // K + const double ref_Vc = 0.0986; // m^3/kmol + const double ref_Zc = 0.288; // unitless + const double ref_acentric_factor = 0.011; // unitless + + // Model constants + // A model constant from the Euken correlation for polyatomic gases, described + // below Equation 1 in @cite ely-hanley1981 . + const double f_int = 1.32; + vector L_i(nsp); vector f_i(nsp); vector h_i(nsp); @@ -162,28 +187,33 @@ double HighPressureGasTransport::thermalConductivity() double V_p = std::max(0.5,std::min(V_r,2.0)); // Calculate variables for density-independent component: - double theta_p = 1.0 + (m_w_ac[i] - 0.011)*(0.56553 - - 0.86276*log(T_p) - 0.69852/T_p); + double theta_p = 1.0 + (m_w_ac[i] - ref_acentric_factor)*(0.56553 + - 0.86276*log(T_p) - 0.69852/T_p); double phi_p = (1.0 + (m_w_ac[i] - 0.011)*(0.38560 - - 1.1617*log(T_p)))*0.288/Zcrit_i(i); - double f_fac = Tc_i*theta_p/190.4; - double h_fac = 1000*Vc_i*phi_p/99.2; + - 1.1617*log(T_p)))*ref_Zc/Zcrit_i(i); + double f_fac = (Tc_i / ref_Tc)*theta_p; + double h_fac = (Vc_i / ref_MW)*phi_p; double T_0 = m_temp/f_fac; + + // Reference fluid viscosity correlation, from Table III in @cite ely-hanley1981 double mu_0 = 1e-7*(2.90774e6/T_0 - 3.31287e6*pow(T_0,-2./3.) + 1.60810e6*pow(T_0,-1./3.) - 4.33190e5 + 7.06248e4*pow(T_0,1./3.) - 7.11662e3*pow(T_0,2./3.) + 4.32517e2*T_0 - 1.44591e1*pow(T_0,4./3.) + 2.03712e-1*pow(T_0,5./3.)); - double H = sqrt(f_fac*16.04/m_mw[i])*pow(h_fac,-2./3.); - double mu_i = mu_0*H*m_mw[i]*c1; - L_i[i] = mu_i*1.32*GasConstant*(cp_0_R[i] - 2.5)/m_mw[i]; + double H = sqrt(f_fac*(ref_MW/m_mw[i]))*pow(h_fac,-2.0/3.0); // Equation 2, @cite ely-hanley1981 + double mu_i = mu_0*H*(m_mw[i] / ref_MW); + // This is the internal contribution to the thermal conductivity of component + // i, from Equation 1 in @cite ely-hanley1981 + L_i[i] = (mu_i / m_mw[i])*f_int*GasConstant*(cp_0_R[i] - 2.5); L_i_min = min(L_i_min,L_i[i]); + // Calculate variables for density-dependent component: - double theta_s = 1 + (m_w_ac[i] - 0.011)*(0.09057 - 0.86276*log(T_p) - + (0.31664 - 0.46568/T_p)*(V_p - 0.5)); - double phi_s = (1 + (m_w_ac[i] - 0.011)*(0.39490*(V_p - 1.02355) - - 0.93281*(V_p - 0.75464)*log(T_p)))*0.288/Zcrit_i(i); - f_i[i] = Tc_i*theta_s/190.4; - h_i[i] = 1000*Vc_i*phi_s/99.2; + double theta_s = 1 + (m_w_ac[i] - ref_acentric_factor)*(0.09057 - 0.86276*log(T_p) + + (0.31664 - 0.46568/T_p)*(V_p - 0.5)); // Equation 11 @cite ely-hanley1981 + double phi_s = (1 + (m_w_ac[i] - ref_acentric_factor)*(0.39490*(V_p - 1.02355) + - 0.93281*(V_p - 0.75464)*log(T_p)))*(ref_Zc/Zcrit_i(i)); + f_i[i] = (Tc_i / ref_Tc)*theta_s; // Equation 7 @cite ely-hanley1981 + h_i[i] = (Vc_i / ref_Vc)*phi_s; // Equation 8 @cite ely-hanley1981 } double h_m = 0; @@ -192,34 +222,55 @@ double HighPressureGasTransport::thermalConductivity() for (size_t i = 0; i < m_nsp; i++) { for (size_t j = 0; j < m_nsp; j++) { // Density-independent component: - double L_ij = 2*L_i[i]*L_i[j]/(L_i[i] + L_i[j] + Tiny); - Lprime_m += molefracs[i]*molefracs[j]*L_ij; + double L_ij = 2*L_i[i]*L_i[j]/(L_i[i] + L_i[j] + Tiny); // Equation 3 @cite ely-hanley1983 + Lprime_m += molefracs[i]*molefracs[j]*L_ij; // Equation 2, @cite ely-hanley1983 + // Additional variables for density-dependent component: - double f_ij = sqrt(f_i[i]*f_i[j]); - double h_ij = 0.125*pow(pow(h_i[i],1./3.) + pow(h_i[j],1./3.),3.); - double mw_ij_inv = (m_mw[i] + m_mw[j])/(2*m_mw[i]*m_mw[j]); - f_m += molefracs[i]*molefracs[j]*f_ij*h_ij; - h_m += molefracs[i]*molefracs[j]*h_ij; - mw_m += molefracs[i]*molefracs[j]*sqrt(mw_ij_inv*f_ij)*pow(h_ij,-4./3.); + double f_ij = sqrt(f_i[i]*f_i[j]); // Equation 10, @cite ely-hanley1983 + double h_ij = 0.125*pow(pow(h_i[i],1./3.) + pow(h_i[j],1./3.),3.); // Equation 11, @cite ely-hanley1983 + double mw_ij_inv = (m_mw[i] + m_mw[j])/(2*m_mw[i]*m_mw[j]); // Equation 15, @cite ely-hanley1983 + f_m += molefracs[i]*molefracs[j]*f_ij*h_ij; // Equation 8, @cite ely-hanley1983 + h_m += molefracs[i]*molefracs[j]*h_ij; // Equation 9, @cite ely-hanley1983 + mw_m += molefracs[i]*molefracs[j]*sqrt(mw_ij_inv*f_ij)*pow(h_ij,-4.0/3.0); // Equation, 14 @cite ely-hanley1983 } } + // These two equations are the final steps for Equations 8 and 14 in @cite ely-hanley1983 . The + // previous calculations done in the loop above were for quantities that were multiplied by the + // quantity named by the variable. So this step actually generates the value from the model that + // is named by the variable. f_m = f_m/h_m; - mw_m = pow(mw_m,-2.)*f_m*pow(h_m,-8./3.); - - double rho_0 = 16.04*h_m/(1000*m_thermo->molarVolume()); - double T_0 = m_temp/f_m; - double mu_0 = 1e-7*(2.90774e6/T_0 - 3.31287e6*pow(T_0,-2./3.) + mw_m = pow(mw_m,-2.0)*f_m*pow(h_m,-8.0/3.0); + + // Equation 7, @cite ely-hanley1983 . This must be in units of g/cm^3 for use with + // the empirical equation. + const double kg_m3_to_g_cm3 = 1e-3; // Conversion factor from kg/m^3 to g/cm^3 + double rho_0 = m_thermo->density()*h_m*kg_m3_to_g_cm3; + double T_0 = m_temp/f_m; // Equation 7, @cite ely-hanley1983 + + // This is the reference gas, dilute gas viscosity (eta_0 in Table III of @cite ely-hanley1981) + // Although the paper doesn't seem to explicitly mention the units of the empirical curve fit + // for the viscosity, a plot of the correlation compared to known values of viscosity suggests + // that the correlation returns viscosity in a somewhat strange unit of 1e-7 Pa*s. + double const correlation_viscosity_conversion = 1e-7; // Conversion factor from the correlation to Pa*s + double mu_0 = correlation_viscosity_conversion*(2.90774e6/T_0 - 3.31287e6*pow(T_0,-2./3.) + 1.60810e6*pow(T_0,-1./3.) - 4.33190e5 + 7.06248e4 *pow(T_0,1./3.) - 7.11662e3*pow(T_0,2./3.) + 4.32517e2*T_0 - 1.44591e1*pow(T_0,4./3.) + 2.03712e-1*pow(T_0,5./3.)); - double L_1m = 1944*mu_0; - double L_2m = (-2.5276e-4 + 3.3433e-4*pow(1.12 - log(T_0/1.680e2),2))*rho_0; + + // Computing the individual terms of Equation 16, @cite ely-hanley1983 . THis is an + // evaluation of the expressions shown in Table I of @cite ely-hanley1983 . The + // correlation seems to return values of thermal conductivity multiplied by 1000 + // so this must be converted to W/m/K. + const double correlation_conductivity_conversion = 1e-3; // Conversion factor from the correlation to W/m/K + double L_1m = (15*GasConstant / (4*ref_MW))*mu_0; // Third term in Equation 16 + double L_2m = (-2.52762920e-1 + 3.34328590e-1*pow(1.12 - log(T_0/1.680e2),2))*rho_0; double L_3m = exp(-7.19771 + 85.67822/T_0)*(exp((12.47183 - 984.6252*pow(T_0,-1.5))*pow(rho_0,0.1) + (rho_0/0.1617 - 1) - *sqrt(rho_0)*(0.3594685 + 69.79841/T_0 - 872.8833*pow(T_0,-2))) - 1.)*1e-3; - double H_m = sqrt(f_m*16.04/mw_m)*pow(h_m,-2./3.); - double Lstar_m = H_m*(L_1m + L_2m + L_3m); + *sqrt(rho_0)*(0.3594685 + 69.79841/T_0 - 872.8833*pow(T_0,-2))) - 1.0); + double reference_fluid_translational_conductivity = correlation_conductivity_conversion*(L_1m + L_2m + L_3m); + double H_m = sqrt(f_m*ref_MW/mw_m)*pow(h_m,-2.0/3.0); // Equation 6, @cite ely-hanley1983 + double Lstar_m = H_m*reference_fluid_translational_conductivity; // Equation 5, @cite ely-hanley1983 return Lprime_m + Lstar_m; } From 06d878ee22055ed0353c66e7a04e2e725d37a3c2 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Tue, 9 Jul 2024 19:31:48 -0400 Subject: [PATCH 16/37] more work on documenting the Ely and Hanley method --- .../transport/HighPressureGasTransport.h | 4 + src/transport/HighPressureGasTransport.cpp | 81 +++++++++++-------- 2 files changed, 51 insertions(+), 34 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index a6694762a1..3107962bdf 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -130,6 +130,10 @@ class HighPressureGasTransport : public MixTransport */ double Zcrit_i(size_t i); + + double elyHanleyDiluteViscosity(double T0); + + /** * Returns the composition-dependent values of parameters that are needed for the * Lucas viscosity model. diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 2b5dd05f03..e818870c8a 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -148,17 +148,13 @@ void HighPressureGasTransport::initializeCriticalProperties() */ double HighPressureGasTransport::thermalConductivity() { - // Method of Ely and Hanley. update_T(); - double Lprime_m = 0.0; - const double c1 = 1./16.04; // Reciprocal of methane's molecular weight - size_t nsp = m_thermo->nSpecies(); - vector molefracs(nsp); + vector molefracs(m_nsp); m_thermo->getMoleFractions(&molefracs[0]); - vector cp_0_R(nsp); + vector cp_0_R(m_nsp); m_thermo->getCp_R_ref(&cp_0_R[0]); - // Reference fluid properties + // Reference fluid properties, for methane (used by the method) const double ref_MW = 16.04; // kg/kmol const double ref_Tc = 190.4; // K const double ref_Vc = 0.0986; // m^3/kmol @@ -170,14 +166,12 @@ double HighPressureGasTransport::thermalConductivity() // below Equation 1 in @cite ely-hanley1981 . const double f_int = 1.32; - vector L_i(nsp); - vector f_i(nsp); - vector h_i(nsp); - vector V_k(nsp); + vector L_i(m_nsp); + vector f_i(m_nsp); + vector h_i(m_nsp); + vector V_k(m_nsp); m_thermo -> getPartialMolarVolumes(&V_k[0]); - double L_i_min = BigNumber; - for (size_t i = 0; i < m_nsp; i++) { double Tc_i = Tcrit_i(i); double Vc_i = Vcrit_i(i); @@ -186,26 +180,24 @@ double HighPressureGasTransport::thermalConductivity() double T_p = std::min(T_r,2.0); double V_p = std::max(0.5,std::min(V_r,2.0)); - // Calculate variables for density-independent component: - double theta_p = 1.0 + (m_w_ac[i] - ref_acentric_factor)*(0.56553 - - 0.86276*log(T_p) - 0.69852/T_p); - double phi_p = (1.0 + (m_w_ac[i] - 0.011)*(0.38560 - - 1.1617*log(T_p)))*ref_Zc/Zcrit_i(i); + // Calculate variables for density-independent component, Equation 1. + // This equation requires the pure-species viscosity estimate from + // Ely and Hanley. + double theta_p = 1 + (m_w_ac[i] - ref_acentric_factor)*(0.09057 - 0.86276*log(T_p) + + (0.31664 - 0.46568/T_p)*(V_p - 0.5)); // Equation 11 @cite ely-hanley1981 + double phi_p = (1 + (m_w_ac[i] - ref_acentric_factor)*(0.39490*(V_p - 1.02355) + - 0.93281*(V_p - 0.75464)*log(T_p)))*(ref_Zc/Zcrit_i(i)); double f_fac = (Tc_i / ref_Tc)*theta_p; double h_fac = (Vc_i / ref_MW)*phi_p; double T_0 = m_temp/f_fac; // Reference fluid viscosity correlation, from Table III in @cite ely-hanley1981 - double mu_0 = 1e-7*(2.90774e6/T_0 - 3.31287e6*pow(T_0,-2./3.) - + 1.60810e6*pow(T_0,-1./3.) - 4.33190e5 + 7.06248e4*pow(T_0,1./3.) - - 7.11662e3*pow(T_0,2./3.) + 4.32517e2*T_0 - 1.44591e1*pow(T_0,4./3.) - + 2.03712e-1*pow(T_0,5./3.)); + double mu_0 = elyHanleyDiluteViscosity(T_0); double H = sqrt(f_fac*(ref_MW/m_mw[i]))*pow(h_fac,-2.0/3.0); // Equation 2, @cite ely-hanley1981 double mu_i = mu_0*H*(m_mw[i] / ref_MW); // This is the internal contribution to the thermal conductivity of component // i, from Equation 1 in @cite ely-hanley1981 L_i[i] = (mu_i / m_mw[i])*f_int*GasConstant*(cp_0_R[i] - 2.5); - L_i_min = min(L_i_min,L_i[i]); // Calculate variables for density-dependent component: double theta_s = 1 + (m_w_ac[i] - ref_acentric_factor)*(0.09057 - 0.86276*log(T_p) @@ -219,6 +211,7 @@ double HighPressureGasTransport::thermalConductivity() double h_m = 0; double f_m = 0; double mw_m = 0; + double Lprime_m = 0.0; for (size_t i = 0; i < m_nsp; i++) { for (size_t j = 0; j < m_nsp; j++) { // Density-independent component: @@ -249,21 +242,14 @@ double HighPressureGasTransport::thermalConductivity() double T_0 = m_temp/f_m; // Equation 7, @cite ely-hanley1983 // This is the reference gas, dilute gas viscosity (eta_0 in Table III of @cite ely-hanley1981) - // Although the paper doesn't seem to explicitly mention the units of the empirical curve fit - // for the viscosity, a plot of the correlation compared to known values of viscosity suggests - // that the correlation returns viscosity in a somewhat strange unit of 1e-7 Pa*s. - double const correlation_viscosity_conversion = 1e-7; // Conversion factor from the correlation to Pa*s - double mu_0 = correlation_viscosity_conversion*(2.90774e6/T_0 - 3.31287e6*pow(T_0,-2./3.) - + 1.60810e6*pow(T_0,-1./3.) - 4.33190e5 + 7.06248e4 - *pow(T_0,1./3.) - 7.11662e3*pow(T_0,2./3.) + 4.32517e2*T_0 - - 1.44591e1*pow(T_0,4./3.) + 2.03712e-1*pow(T_0,5./3.)); - - // Computing the individual terms of Equation 16, @cite ely-hanley1983 . THis is an + double mu_0 = elyHanleyDiluteViscosity(T_0); + + // Computing the individual terms of Equation 18, @cite ely-hanley1983 . THis is an // evaluation of the expressions shown in Table I of @cite ely-hanley1983 . The // correlation seems to return values of thermal conductivity multiplied by 1000 // so this must be converted to W/m/K. const double correlation_conductivity_conversion = 1e-3; // Conversion factor from the correlation to W/m/K - double L_1m = (15*GasConstant / (4*ref_MW))*mu_0; // Third term in Equation 16 + double L_1m = (15*GasConstant / (4*ref_MW))*mu_0; // First term in Equation 18 double L_2m = (-2.52762920e-1 + 3.34328590e-1*pow(1.12 - log(T_0/1.680e2),2))*rho_0; double L_3m = exp(-7.19771 + 85.67822/T_0)*(exp((12.47183 - 984.6252*pow(T_0,-1.5))*pow(rho_0,0.1) + (rho_0/0.1617 - 1) @@ -274,6 +260,33 @@ double HighPressureGasTransport::thermalConductivity() return Lprime_m + Lstar_m; } +/** + * Returns the viscosity of for the reference fluid of methane for low pressures. + * Units are Pa*s + * + * Computes the temperature dependent (referred to as the dilute viscosity in the + * reference) component only (eta_0) from the expression in Table III in + * @cite ely-hanley1981 + * + * @param T0 + */ +double HighPressureGasTransport::elyHanleyDiluteViscosity(double T_0) +{ + // Conversion factor from the correlation to Pa*s because the correlation returns + // the viscosity multiplied by 1e7. + double const correlation_viscosity_conversion = 1e-7; + + // Coefficients for the correlation from Table III of @cite ely-hanley1981 + const std::vector c = {2.907741307e6, -3.312874033e6, 1.608101838e6, + -4.331904871e5, 7.062481330e4, -7.116620750e3, 4.325174400e2, -1.445911210e1, 2.037119479e-1}; + + double mu_0 = 0.0; + for (size_t i = 0; i < 9; i++) { + mu_0 += c[i]*pow(T_0,(i+1.0-4.0)/3.0); + } + return correlation_viscosity_conversion*mu_0; +} + void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* const d) { update_C(); From e87f571a2a17396db7c18a22d8638644cd7da7d8 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Wed, 10 Jul 2024 02:49:04 -0400 Subject: [PATCH 17/37] final updates for ely and hanley method --- .../transport/HighPressureGasTransport.h | 31 ++- src/transport/HighPressureGasTransport.cpp | 197 ++++++++++-------- 2 files changed, 140 insertions(+), 88 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index 3107962bdf..e56cd28b24 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -130,9 +130,29 @@ class HighPressureGasTransport : public MixTransport */ double Zcrit_i(size_t i); - + /** + * Returns the viscosity of for the reference fluid of methane for low pressures. + * Units are Pa*s + * + * Computes the temperature dependent (referred to as the dilute viscosity in the + * reference) component only (eta_0) from the expression in Table III in + * @cite ely-hanley1981 + * + * @param T0 + */ double elyHanleyDiluteViscosity(double T0); + /** + * Returns the thermal conductivity of for the reference fluid of methane + * in units of W/m/K. + * + * Computes the temperature and density dependent reference fluid thermal conductivity + * from the expression in Table I in @cite ely-hanley1983 . + * + * @param rho0 + * @param T0 + */ + double elyHanleyReferenceThermalConductivity(double rho0, double T0); /** * Returns the composition-dependent values of parameters that are needed for the @@ -323,6 +343,15 @@ class HighPressureGasTransport : public MixTransport std::vector m_Vcrit; std::vector m_Zcrit; + // Reference fluid properties, for methane (used by the thermalConductivity() + // method) + const double ref_MW = 16.04; // kg/kmol + const double ref_Tc = 190.4; // K + const double ref_Vc = 0.0986; // m^3/kmol + const double ref_Zc = 0.288; // unitless + const double ref_rhoc = 0.1628; // g/cm^3 + const double ref_acentric_factor = 0.011; // unitless + }; diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index e818870c8a..272d3a536c 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -152,22 +152,14 @@ double HighPressureGasTransport::thermalConductivity() vector molefracs(m_nsp); m_thermo->getMoleFractions(&molefracs[0]); vector cp_0_R(m_nsp); - m_thermo->getCp_R_ref(&cp_0_R[0]); + m_thermo->getCp_R_ref(&cp_0_R[0]); // Cp/R - // Reference fluid properties, for methane (used by the method) - const double ref_MW = 16.04; // kg/kmol - const double ref_Tc = 190.4; // K - const double ref_Vc = 0.0986; // m^3/kmol - const double ref_Zc = 0.288; // unitless - const double ref_acentric_factor = 0.011; // unitless - - // Model constants // A model constant from the Euken correlation for polyatomic gases, described // below Equation 1 in @cite ely-hanley1981 . const double f_int = 1.32; - vector L_i(m_nsp); - vector f_i(m_nsp); + vector Lambda_1_i(m_nsp); // Internal contribution to thermal conductivity (lamba'') + vector f_i(m_nsp); // Pure-species model parameter vector h_i(m_nsp); vector V_k(m_nsp); @@ -177,103 +169,102 @@ double HighPressureGasTransport::thermalConductivity() double Vc_i = Vcrit_i(i); double T_r = m_thermo->temperature()/Tc_i; double V_r = V_k[i]/Vc_i; - double T_p = std::min(T_r,2.0); - double V_p = std::max(0.5,std::min(V_r,2.0)); + double T_p = std::min(std::max(T_r,0.5), 2.0); + double V_p = std::min(std::max(V_r,0.5),2.0); // Calculate variables for density-independent component, Equation 1. // This equation requires the pure-species viscosity estimate from // Ely and Hanley. - double theta_p = 1 + (m_w_ac[i] - ref_acentric_factor)*(0.09057 - 0.86276*log(T_p) - + (0.31664 - 0.46568/T_p)*(V_p - 0.5)); // Equation 11 @cite ely-hanley1981 - double phi_p = (1 + (m_w_ac[i] - ref_acentric_factor)*(0.39490*(V_p - 1.02355) - - 0.93281*(V_p - 0.75464)*log(T_p)))*(ref_Zc/Zcrit_i(i)); - double f_fac = (Tc_i / ref_Tc)*theta_p; - double h_fac = (Vc_i / ref_MW)*phi_p; - double T_0 = m_temp/f_fac; - - // Reference fluid viscosity correlation, from Table III in @cite ely-hanley1981 + double theta_i = 1 + (m_w_ac[i] - ref_acentric_factor)*(0.090569 - 0.862762*log(T_p) + + (0.316636 - 0.465684/T_p)*(V_p - 0.5)); // Equation 11 @cite ely-hanley1981 + double phi_i = (1 + (m_w_ac[i] - ref_acentric_factor)*(0.394901*(V_p - 1.023545) + - 0.932813*(V_p - 0.754639)*log(T_p)))*(ref_Zc/Zcrit_i(i)); + double f_fac = (Tc_i / ref_Tc)*theta_i; // Equation 7 @cite ely-hanley1981 + double h_fac = (Vc_i / ref_Vc)*phi_i; // Equation 8 @cite ely-hanley1981 + double T_0 = m_temp/f_fac; // Equation 3, @cite ely-hanley1981 + + // Dilute reference fluid viscosity correlation, from Table III in + // @cite ely-hanley1981 double mu_0 = elyHanleyDiluteViscosity(T_0); - double H = sqrt(f_fac*(ref_MW/m_mw[i]))*pow(h_fac,-2.0/3.0); // Equation 2, @cite ely-hanley1981 - double mu_i = mu_0*H*(m_mw[i] / ref_MW); - // This is the internal contribution to the thermal conductivity of component - // i, from Equation 1 in @cite ely-hanley1981 - L_i[i] = (mu_i / m_mw[i])*f_int*GasConstant*(cp_0_R[i] - 2.5); - - // Calculate variables for density-dependent component: - double theta_s = 1 + (m_w_ac[i] - ref_acentric_factor)*(0.09057 - 0.86276*log(T_p) - + (0.31664 - 0.46568/T_p)*(V_p - 0.5)); // Equation 11 @cite ely-hanley1981 - double phi_s = (1 + (m_w_ac[i] - ref_acentric_factor)*(0.39490*(V_p - 1.02355) - - 0.93281*(V_p - 0.75464)*log(T_p)))*(ref_Zc/Zcrit_i(i)); - f_i[i] = (Tc_i / ref_Tc)*theta_s; // Equation 7 @cite ely-hanley1981 - h_i[i] = (Vc_i / ref_Vc)*phi_s; // Equation 8 @cite ely-hanley1981 + double F = sqrt(f_fac*(m_mw[i]/ref_MW))*pow(h_fac,-2.0/3.0); // Equation 2, ely-hanley1981 + + double mu_i = mu_0*F; + // This is the internal contribution to the thermal conductivity of + // pure-species component, i, from Equation 1 in @cite ely-hanley1983 + Lambda_1_i[i] = (mu_i / m_mw[i])*f_int*GasConstant*(cp_0_R[i] - 2.5); + + // Calculate variables for density-dependent component (lambda') + f_i[i] = (Tc_i / ref_Tc)*theta_i; // Equation 12 @cite ely-hanley1983 + h_i[i] = (Vc_i / ref_Vc)*phi_i; // Equation 13 @cite ely-hanley1983 } - double h_m = 0; - double f_m = 0; - double mw_m = 0; - double Lprime_m = 0.0; + double h_m = 0; // Corresponding states parameter, h_x,0 from ely-hanley1983 + double f_m = 0; // Corresponding states parameter, f_x,0 from ely-hanley1983 + double mw_m = 0; // Mixture molecular weight + double Lambda_1_m = 0.0; // Internal component of mixture thermal conductivity for (size_t i = 0; i < m_nsp; i++) { for (size_t j = 0; j < m_nsp; j++) { - // Density-independent component: - double L_ij = 2*L_i[i]*L_i[j]/(L_i[i] + L_i[j] + Tiny); // Equation 3 @cite ely-hanley1983 - Lprime_m += molefracs[i]*molefracs[j]*L_ij; // Equation 2, @cite ely-hanley1983 - - // Additional variables for density-dependent component: - double f_ij = sqrt(f_i[i]*f_i[j]); // Equation 10, @cite ely-hanley1983 - double h_ij = 0.125*pow(pow(h_i[i],1./3.) + pow(h_i[j],1./3.),3.); // Equation 11, @cite ely-hanley1983 - double mw_ij_inv = (m_mw[i] + m_mw[j])/(2*m_mw[i]*m_mw[j]); // Equation 15, @cite ely-hanley1983 - f_m += molefracs[i]*molefracs[j]*f_ij*h_ij; // Equation 8, @cite ely-hanley1983 - h_m += molefracs[i]*molefracs[j]*h_ij; // Equation 9, @cite ely-hanley1983 - mw_m += molefracs[i]*molefracs[j]*sqrt(mw_ij_inv*f_ij)*pow(h_ij,-4.0/3.0); // Equation, 14 @cite ely-hanley1983 + // Compute the internal contribution to the thermal conductivity of the + // mixture + + // Equation 3 @cite ely-hanley1983 + double Lambda_1_ij = 2*Lambda_1_i[i]*Lambda_1_i[j] / + (Lambda_1_i[i] + Lambda_1_i[j] + Tiny); + // Equation 2, @cite ely-hanley1983 + Lambda_1_m += molefracs[i]*molefracs[j]*Lambda_1_ij; + + // Variables for density-dependent translational/collisional component of + // the mixture. + + // Equation 10, @cite ely-hanley1983 + double f_ij = sqrt(f_i[i]*f_i[j]); + + // Equation 11, @cite ely-hanley1983 + double h_ij = 0.125*pow(pow(h_i[i],1.0/3.0) + pow(h_i[j],1.0/3.0),3.0); + + // Equation 15, @cite ely-hanley1983 + double mw_ij_inv = 0.5*(m_mw[i] + m_mw[j])/(m_mw[i]*m_mw[j]); + + // Equation 8, @cite ely-hanley1983 + f_m += molefracs[i]*molefracs[j]*f_ij*h_ij; + + // Equation 9, @cite ely-hanley1983 + h_m += molefracs[i]*molefracs[j]*h_ij; + + // Equation, 14 @cite ely-hanley1983 + mw_m += molefracs[i]*molefracs[j]*sqrt(mw_ij_inv*f_ij)*pow(h_ij,-4.0/3.0); } } - // These two equations are the final steps for Equations 8 and 14 in @cite ely-hanley1983 . The - // previous calculations done in the loop above were for quantities that were multiplied by the - // quantity named by the variable. So this step actually generates the value from the model that - // is named by the variable. + // The following two equations are the final steps for Equations 8 and 14 in + // @cite ely-hanley1983 . The calculations in the loop above computed the + // right-hand-side of the equations, but the left-hand-side of the equations + // contain other variables that must be moved to the right-hand-side in order to + // get the values of the variables of interest. f_m = f_m/h_m; mw_m = pow(mw_m,-2.0)*f_m*pow(h_m,-8.0/3.0); - // Equation 7, @cite ely-hanley1983 . This must be in units of g/cm^3 for use with - // the empirical equation. + // The two relations below are from Equation 7, @cite ely-hanley1983 . This must + // be in units of g/cm^3 for use with the empirical correlation. const double kg_m3_to_g_cm3 = 1e-3; // Conversion factor from kg/m^3 to g/cm^3 double rho_0 = m_thermo->density()*h_m*kg_m3_to_g_cm3; - double T_0 = m_temp/f_m; // Equation 7, @cite ely-hanley1983 + double T_0 = m_temp/f_m; - // This is the reference gas, dilute gas viscosity (eta_0 in Table III of @cite ely-hanley1981) - double mu_0 = elyHanleyDiluteViscosity(T_0); + // Equation 18, @cite ely-hanley1983 + double Lambda_2_ref = elyHanleyReferenceThermalConductivity(rho_0, T_0); - // Computing the individual terms of Equation 18, @cite ely-hanley1983 . THis is an - // evaluation of the expressions shown in Table I of @cite ely-hanley1983 . The - // correlation seems to return values of thermal conductivity multiplied by 1000 - // so this must be converted to W/m/K. - const double correlation_conductivity_conversion = 1e-3; // Conversion factor from the correlation to W/m/K - double L_1m = (15*GasConstant / (4*ref_MW))*mu_0; // First term in Equation 18 - double L_2m = (-2.52762920e-1 + 3.34328590e-1*pow(1.12 - log(T_0/1.680e2),2))*rho_0; - double L_3m = exp(-7.19771 + 85.67822/T_0)*(exp((12.47183 - - 984.6252*pow(T_0,-1.5))*pow(rho_0,0.1) + (rho_0/0.1617 - 1) - *sqrt(rho_0)*(0.3594685 + 69.79841/T_0 - 872.8833*pow(T_0,-2))) - 1.0); - double reference_fluid_translational_conductivity = correlation_conductivity_conversion*(L_1m + L_2m + L_3m); - double H_m = sqrt(f_m*ref_MW/mw_m)*pow(h_m,-2.0/3.0); // Equation 6, @cite ely-hanley1983 - double Lstar_m = H_m*reference_fluid_translational_conductivity; // Equation 5, @cite ely-hanley1983 - return Lprime_m + Lstar_m; + // Equation 6, @cite ely-hanley1983 + double F_m = sqrt(f_m*ref_MW/mw_m)*pow(h_m,-2.0/3.0); + + // Equation 5, @cite ely-hanley1983 + double Lambda_2_m = F_m*Lambda_2_ref; + + return Lambda_1_m + Lambda_2_m; } -/** - * Returns the viscosity of for the reference fluid of methane for low pressures. - * Units are Pa*s - * - * Computes the temperature dependent (referred to as the dilute viscosity in the - * reference) component only (eta_0) from the expression in Table III in - * @cite ely-hanley1981 - * - * @param T0 - */ -double HighPressureGasTransport::elyHanleyDiluteViscosity(double T_0) +double HighPressureGasTransport::elyHanleyDiluteViscosity(double T0) { - // Conversion factor from the correlation to Pa*s because the correlation returns - // the viscosity multiplied by 1e7. + // Conversion factor from the correlation in micrograms/cm/s to Pa*s. double const correlation_viscosity_conversion = 1e-7; // Coefficients for the correlation from Table III of @cite ely-hanley1981 @@ -282,11 +273,43 @@ double HighPressureGasTransport::elyHanleyDiluteViscosity(double T_0) double mu_0 = 0.0; for (size_t i = 0; i < 9; i++) { - mu_0 += c[i]*pow(T_0,(i+1.0-4.0)/3.0); + mu_0 += c[i]*pow(T0,(i+1.0-4.0)/3.0); } return correlation_viscosity_conversion*mu_0; } +double HighPressureGasTransport::elyHanleyReferenceThermalConductivity(double rho0, double T0) +{ + // Computing the individual terms of Equation 18, @cite ely-hanley1983 . This is an + // evaluation of the expressions shown in Table I of @cite ely-hanley1983 . The + // correlation returns values of thermal conductivity in mW/m/K, + // so a conversion is needed. + const double correlation_factor = 1e-3; // mW/m/K to W/m/K + + // This is the reference gas, dilute gas viscosity (eta_0 in Table III of + // @cite ely-hanley1981) + double mu_0 = elyHanleyDiluteViscosity(T0); + + // First term in Equation 18. This expression has the correct units because + // it does not use any empirical correlation, so it is excluded at the end from + // the unit conversion. + double Lambda_ref_star = (15*GasConstant / (4*ref_MW))*mu_0; + + // Second term in Equation 18 + const vector b = {-2.52762920e-1, 3.34328590e-1, 1.12, 1.680e2}; + double Lambda_ref_1 = (b[0] + b[1]*pow(b[2] - log(T0/b[3]),2))*rho0; + + // Third term in Equation 18 + const vector a = {-7.197708227, 8.5678222640e1, 1.2471834689e1, + -9.8462522975e2, 3.5946850007e-1, 6.9798412538e1, + -8.7288332851e2}; + double delta_lambda_ref = exp(a[0] + a[1]/T0) * (exp((a[2] + a[3]*pow(T0,-1.5))*pow(rho0,0.1) + (rho0/ref_rhoc - 1) + *sqrt(rho0)*(a[4] + a[5]/T0 + a[6]*pow(T0,-2))) - 1.0); + + return Lambda_ref_star + (Lambda_ref_1 + delta_lambda_ref)*correlation_factor; +} + + void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* const d) { update_C(); From e6451c32afa4647c4b03ea9842525dfe8513aa0c Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Wed, 10 Jul 2024 15:07:28 -0400 Subject: [PATCH 18/37] detailed model description added for ely and hanley thermal conductivity --- .../transport/HighPressureGasTransport.h | 304 +++++++++++++++++- src/transport/HighPressureGasTransport.cpp | 13 - 2 files changed, 303 insertions(+), 14 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index e56cd28b24..c2b7a39609 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -51,10 +51,312 @@ class HighPressureGasTransport : public MixTransport } void init(ThermoPhase* thermo, int mode=0, int log_level=0) override; + /** * Returns the mixture high-pressure thermal conductivity in W/m/K - * using a method by Ely and Hanley. + * using a method of corresponding states by Ely and Hanley. + * + * This method for computing the thermal conductivity is described in + * @cite ely-hanley1983 . There are references to earlier work in + * @cite ely-hanley1981 in the description of the model for thermal conductivity. + * The equations referenced in this description primarily are from + * @cite ely-hanley1983 , and equations that come from @cite ely-hanley1981 are + * marked as such. The equations referenced here are the same as the ones from + * the papers from Ely and Hanley. + * + * The thermal conductivity is assumed to have two components: a translational/collisional + * part and an internal part that is related to the transfer of energy to internal degrees + * of freedom. + * + * @f[ + * \lambda_{mix}(\rho, T) = \lambda^{''}_{mix}(T) + \lambda^{'}_{mix}(\rho, T) + * @f] + * + * The first term on the right-hand side is the internal part and the second term is the + * translational part. The internal part is only a function of temperature, and the + * translational part is a function of both temperature and density. + * + * For the internal component of the thermal conductivity the following equations are + * used. + * + * @f[ + * \lambda^{''}_{mix}(T) = \sum_i \sum_j X_i X_j \lambda^{''}_{ij}(T) + * + * \quad \text{(Equation 2)} + * @f] + * + * The mixing rule for combining pure-species internal thermal conductivity components + * is given by: + * + * @f[ + * (\lambda^{''}_{ij})^{-1} = 2[(\lambda^{''}_{i})^{-1} + (\lambda^{''}_{j})^{-1}] + * + * \quad \text{(Equation 3)} + * @f] + * + * The pure species internal thermal conductivity is given by: + * + * @f[ + * \lambda^{''}_{i} = \frac{\eta_i^*}{MW_i}f_{int} \left(C_{p,i}^0 - 2.5R \right) + * + * \quad \text{(Equation 1)} + * @f] + * + * Where @f$ \eta_i^* @f$ is the referred to as the dilute gas viscosity and is the + * component that is temperature dependent described in @cite ely-hanley1981. @f$ MW_i @f$ + * is the molecular weight of species i, @f$ f_int @f$ is a constant and is 1.32, @f$ C_{p,i}^0 @f$ + * is the ideal gas heat capacity of species i, and R is the gas constant. + * + * For the translational component of the thermal conductivity the following equations are + * used. + * + * @f[ + * \lambda^{'}_{mix}(\rho, T) = \lambda^{'}_{0}(\rho_0, T_0) F_{\lambda} + * + * \quad \text{(Equation 5)} + * @f] + * + * Where @f$ \lambda^{'}_{0}(\rho_0, T_0) @f$ is the internal component of the thermal + * conductivity of a reference fluid that is at a reference temperature and density, + * @f$ T_0 @f$ and @f$ \rho_0 @f$. These reference conditions are not the same as the + * conditions that the mixture is at (@f$ T @f$ and @f$ \rho @f$). The subscript 0 refers + * to the reference fluid. + * + * @f[ + * F_{\lambda} = \left( \frac{MW_0}{MW_m} \right)^{1/2} f_{m,0}^{1/2} h_{m,0}^{-2/3} + * + * \quad \text{(Equation 6)} + * @f] + * + * Where @f$ MW_0 @f$ is the molecular weight of the reference fluid, @f$ MW_m @f$ is the + * molecular weight of the mixture, @f$ f_{m,0} @f$ and @f$ h_{m,0} @f$ are called + * reducing ratios. The @f$ h_{m,0} @f$ quantity is defined as: + * + * @f[ + * h_{m,0} = \sum_i \sum_j X_i X_j h_{ij} + * + * \quad \text{(Equation 9)} + * @f] + * + * with, + * + * @f[ + * h_{ij} = \frac{1}{8} (h_i^{1/3} + h_j^{1/3})^3 (1 - l_{ij}) + * + * \quad \text{(Equation 11)} + * @f] + * + * The variable @f$ l_{ij} @f$ is a binary interaction parameter and is assumed to + * be zero as is done by Ely and Hanley. + * + * @f[ + * h_i = \frac{V_c^i}{V_c^0} \phi_i(T_R^i, V_R^i, \omega_i) + * + * \quad \text{(Equation 13)} + * @f] + * + * Where @f$ \phi_i @f$ is a shape factor of Leach and Leland, @f$ T_R^i @f$ is + * the reduced temperature of species i, @f$ V_R^i @f$ is the reduced volume of + * species i, and @f$ \omega_i @f$ is the acentric factor of species i The shape + * factor @f$ \phi_i @f$ is defined in @cite ely-hanley1981 as follows: + * + * @f[ + * \phi_i(T_R^i, V_R^i, \omega_i) = \frac{Z_0^c}{Z_i^c} [1 + (\omega_i - \omega_0)G(T_R^i, V_R^i)] + * + * \quad \text{(Equation 12 of @cite ely-hanley1981)} + * @f] + * + * Where @f$ Z_0^c @f$ is the critical compressibility of the reference fluid, @f$ Z_i^c @f$ + * is the critical compressibility of species i, @f$ \omega_0 @f$ is the acentric factor of + * the reference fluid, and @f$ G(T_R^i, V_R^i) @f$ is a function of the reduced temperature + * and reduced volume of species i. The function @f$ G(T_R^i, V_R^i) @f$ is defined as: + * + * @f[ + * G(T_R^i, V_R^i) = a_2(V_i^+ + b_2) + c_2(V_i^+ + d_2)ln(T_R^i) + * + * \quad \text{(Equation 14 of @cite ely-hanley1981)} + * @f] + * + * Where @f$ T_i^+ @f$ and @f$ V_i^+ @f$ are limited values of the reduced temperature + * and pressure and are defined as: + * + * @f[ + * T_i^+ = min(2, max(T_R^i, 0.5)) + * + * \quad \text{(Equation 15 of @cite ely-hanley1981)} + * @f] + * + * and + * + * @f[ + * V_i^+ = min(2, max(V_R^i, 0.5)) + * + * \quad \text{(Equation 16 of @cite ely-hanley1981)} + * @f] + * + * The values of @f$ a_2 @f$, @f$ b_2 @f$, @f$ c_2 @f$, and @f$ d_2 @f$ are + * given in Table II of @cite ely-hanley1981. They are: + * + * @f[ + * a_2 = 0.394901, b_2 = -1.023545, c_2 = -0.932813, d_2 = -0.754639 + * @f] + * + * With the definitions above, the value of @f$ h_{m,0} @f$ can be computed. This + * leaves the other reducing ratio, @f$ f_{m,0} @f$, to be defined. The value of + * that reducing ratio is defined by the following equation. + * + * @f[ + * f_{m,0} = \frac{1}{h_{m,0}} \sum_i \sum_j X_i X_j f_{ij} h_{ij} + * + * \quad \text{(Equation 8)} + * @f] + * + * + * The value of @f$ h_{ij} @f$ is the same as the one defined earlier. The combining + * rule for @f$ f_{ij} @f$ is given by: + * + * @f[ + * f_{ij} = (f_i f_j)^{1/2} (1-\kappa_{ij}) + * + * \quad \text{(Equation 10)} + * @f] + * + * @f$ \kappa_{ij} @f$ is binary interaction parameters and is assumed to be zero + * as was done in the work of Ely and Hanley. The species-specific value of @f$ f_i @f$ + * is defined as: + * + * @f[ + * f_i = \frac{T_c^i}{T_c^0} \theta_i(T_R^i, V_R^i, \omega_i) + * + * \quad \text{(Equation 12 @cite ely-hanley1981)} + * @f] + * + * Where @f$ \theta_i @f$ is a shape factor of Leach and Leland, @f$ T_c^i @f$ is the + * critical temperature of species i, and @f$ T_c^0 @f$ is the critical temperature of + * the reference fluid. The shape factor @f$ \theta_i @f$ is defined in @cite ely-hanley1981 + * as: + * + * @f[ + * \theta_i(T_R^i, V_R^i, \omega_i) = 1 + (\omega_i - \omega_0)F(T_R^i, V_R^i)] + * + * \quad \text{(Equation 11 of @cite ely-hanley1981)} + * @f] + * + * Where @f$ Z_0^c @f$ is the critical compressibility of the reference fluid, @f$ Z_i^c @f$ + * is the critical compressibility of species i, @f$ \omega_0 @f$ is the acentric factor of + * the reference fluid, and @f$ G(T_R^i, V_R^i) @f$ is a function of the reduced temperature + * and reduced volume of species i. The function @f$ G(T_R^i, V_R^i) @f$ is defined as: + * + * @f[ + * F(T_R^i, V_R^i) = a_1 + b_1 ln(T_R^i) + (c_1 + d_1/T_R^i) (V_R^i - 0.5) + * + * \quad \text{(Equation 13 of @cite ely-hanley1981)} + * @f] + * + * Where @f$ T_i^+ @f$ and @f$ V_i^+ @f$ are limited values of the reduced temperature + * and pressure and have the same definition as was shown earlier. + * + * The values of @f$ a_1 @f$, @f$ b_1 @f$, @f$ c_1 @f$, and @f$ d_1 @f$ are + * given in Table II of @cite ely-hanley1981. They are: + * + * @f[ + * a_1 = 0.090569, b_1 = -0.862762, c_1 = 0.316636, d_1 = -0.465684 + * @f] + * + * With the definitions above, the value of @f$ h_{m,0} @f$ can be computed from the + * equation that defined the value of @f$ f_{m,0} h_{m,0} @f$. The value of @f$ h_{m,0} @f$ + * must be computed first and then the value of @f$ f_{m,0} @f$ can be computed. + * + * The value of @f$ MW_m @f$ is the molecular weight of the mixture and is computed using + * the following equation. This expression is somewhat complex, but the method to obtain the + * value of @f$ MW_m @f$ is to compute the right-hand-side first with the definitions of + * @f$ MW_{ij} @f$, @f$ f_{ij} @f$, and @f$ h_{ij} @f$ . Then once the right-hand-side is + * known, along with the previously computed values of @f$ f_{m,0} @f$ and @f$ h_{m,0} @f$, + * we can use simple algebra to isolate @f$ MW_m @f$. + * + * @f[ + * MW_m^{1/2} f_{m,0}^{1/2} h_{m,0}^{-4/3} = \sum_i \sum_j X_i X_j MW_{ij}^{-1/2} f_{ij}^{1/2} h_{ij}^{-4/3} + * + * \quad \text{(Equation 14)} + * @f] + * + * where, + * + * @f[ + * MW_{ij} = \frac{1}{2} (MW_i^{-1} + MW_j^{-1}) + * + * \quad \text{(Equation 15)} + * @f] + * + * For clarity, if we assume the right-hand-side of the molecular weight mixture equation is A, then + * the mixture molecular weight is given by: + * + * @f[ + * MW_m = A^{-2} f_{m,0} h_{m,0}^{-8/3} + * @f] + * + * All of the above descriptions allow for the calculation of @f$ F_{\lambda} @f$ in the expression for + * the mixture value of the translational component of the thermal conductivity. The reference fluid + * value of the translational component of the thermal conductivity is still needed. The first thing + * that needs to be done is the obtain the temperature and density of the reference fluid. The following + * relations are used to compute the reference fluid temperature and density. + * + * @f[ + * \rho_0 = \rho h_{m,0} + * + * \quad \text{(Equation 7)} + * @f] + * + * and + * + * @f[ + * T_0 = \frac{T}{f_{m,0}} + * \quad \text{(Equation 7)} + * @f] + * + * The reference fluid translational component of thermal conductivity can now be + * computed using the following equation. + * + * @f[ + * \lambda^{'}_{0}(\rho_0, T_0) = \frac{15R}{4MW_0} \eta_0^* + \lambda_0^{(1)}\rho_0 + \Delta\lambda_0(\rho_0, T_0) + * + * \quad \text{(Equation 18)} + * @f] + * + * Where @f$ \eta_0^* @f$ is the dilute gas viscosity, @f$ \lambda_0^{(1)} @f$ is the first density + * correction to the thermal conductivity, and @f$ \Delta\lambda_0 @f$ is the high-density contribution. + * Ely and Hanley provide a correlation equation to solve for this quantity for the methane reference + * fluid. The details of the correlation and the parameters are shown in Table I of @cite ely-hanley1983. + * + * For completeness, the relations are reproduced here. + * + * @f[ + * \lambda_0^*(T_0) = \frac{15R}{4MW_0} \eta_0^* + * @f] + * + * @f[ + * \eta_0^* = \sum_{n=1}^{9} C_n T_0^{(n-4)/3} + * @f] + * + * @f[ + * \lambda_0^{(1)} = b_1 + b_2[b_3 - ln(T_0 / b_4)]^2 + * @f] + * + * @f[ + * \Delta\lambda_0 = exp[a_1 + a_2/T_0] (exp[(a_3 + a_4/T_0^{3/4})\rho_0^{0.1} + * + (\rho_0 / \rho_0,c - 1)\rho_0^{0.5} + * (a_5 + a_6/T_0 + a_7/T_0^2) ] - 1) + * @f] + * + * The constants a, b, and C are not related to any ones used in the previous + * equations, their values are defined in Table I of @cite ely-hanley1983. * + * @note The correlations for the reference fluid viscosity return a value of + * micro-grams/cm/s and the parts of the thermal conductivity that utilize + * the correlation fit parameters give values in units of mW/m/K. Appropriate + * conversions were made in the relevant functions. + * @see elyHanleyDiluteViscosity() + * @see elyHanleyReferenceThermalConductivity() */ double thermalConductivity() override; diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 272d3a536c..759654bca7 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -133,19 +133,6 @@ void HighPressureGasTransport::initializeCriticalProperties() m_thermo->setMoleFractions(&molefracs[0]); } -/** - * @This implementation uses the method of Ely and Hanley to compute the thermal - * conductivity. - * - * The method is detailed in @cite ely-hanley1981 and @cite ely-hanley1983 . - * - * This method uses a reference fluid of methane. - * - * The Leach and Leland shape factors @f$ \theta_{\alpha,0} @f$ and @f$ \phi_{\alpha,0} @f$ are - * defined as: - * - * - */ double HighPressureGasTransport::thermalConductivity() { update_T(); From b0a576879892039931485fdc9fd05e2439bf4fba Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Wed, 10 Jul 2024 15:18:34 -0400 Subject: [PATCH 19/37] wrapped doxygen comment for thermal conductivity to 88 characters --- .../transport/HighPressureGasTransport.h | 151 ++++++++++-------- 1 file changed, 83 insertions(+), 68 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index c2b7a39609..e73cec162b 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -64,20 +64,20 @@ class HighPressureGasTransport : public MixTransport * marked as such. The equations referenced here are the same as the ones from * the papers from Ely and Hanley. * - * The thermal conductivity is assumed to have two components: a translational/collisional - * part and an internal part that is related to the transfer of energy to internal degrees - * of freedom. + * The thermal conductivity is assumed to have two components: a + * translational/collisional part and an internal part that is related to the + * transfer of energy to internal degrees of freedom. * * @f[ * \lambda_{mix}(\rho, T) = \lambda^{''}_{mix}(T) + \lambda^{'}_{mix}(\rho, T) * @f] * - * The first term on the right-hand side is the internal part and the second term is the - * translational part. The internal part is only a function of temperature, and the - * translational part is a function of both temperature and density. + * The first term on the right-hand side is the internal part and the second term + * is the translational part. The internal part is only a function of temperature, + * and the translational part is a function of both temperature and density. * - * For the internal component of the thermal conductivity the following equations are - * used. + * For the internal component of the thermal conductivity the following equations + * are used. * * @f[ * \lambda^{''}_{mix}(T) = \sum_i \sum_j X_i X_j \lambda^{''}_{ij}(T) @@ -85,11 +85,12 @@ class HighPressureGasTransport : public MixTransport * \quad \text{(Equation 2)} * @f] * - * The mixing rule for combining pure-species internal thermal conductivity components - * is given by: + * The mixing rule for combining pure-species internal thermal conductivity + * components is given by: * * @f[ - * (\lambda^{''}_{ij})^{-1} = 2[(\lambda^{''}_{i})^{-1} + (\lambda^{''}_{j})^{-1}] + * (\lambda^{''}_{ij})^{-1} = 2[(\lambda^{''}_{i})^{-1} + * + (\lambda^{''}_{j})^{-1}] * * \quad \text{(Equation 3)} * @f] @@ -103,12 +104,13 @@ class HighPressureGasTransport : public MixTransport * @f] * * Where @f$ \eta_i^* @f$ is the referred to as the dilute gas viscosity and is the - * component that is temperature dependent described in @cite ely-hanley1981. @f$ MW_i @f$ - * is the molecular weight of species i, @f$ f_int @f$ is a constant and is 1.32, @f$ C_{p,i}^0 @f$ - * is the ideal gas heat capacity of species i, and R is the gas constant. + * component that is temperature dependent described in @cite ely-hanley1981. + * @f$ MW_i @f$ is the molecular weight of species i, @f$ f_int @f$ is a constant + * and is 1.32, @f$ C_{p,i}^0 @f$ is the ideal gas heat capacity of species i, + * and R is the gas constant (J/kmol/K). * - * For the translational component of the thermal conductivity the following equations are - * used. + * For the translational component of the thermal conductivity the following + * equations are used. * * @f[ * \lambda^{'}_{mix}(\rho, T) = \lambda^{'}_{0}(\rho_0, T_0) F_{\lambda} @@ -116,21 +118,22 @@ class HighPressureGasTransport : public MixTransport * \quad \text{(Equation 5)} * @f] * - * Where @f$ \lambda^{'}_{0}(\rho_0, T_0) @f$ is the internal component of the thermal - * conductivity of a reference fluid that is at a reference temperature and density, - * @f$ T_0 @f$ and @f$ \rho_0 @f$. These reference conditions are not the same as the - * conditions that the mixture is at (@f$ T @f$ and @f$ \rho @f$). The subscript 0 refers - * to the reference fluid. + * Where @f$ \lambda^{'}_{0}(\rho_0, T_0) @f$ is the internal component of the + * thermal conductivity of a reference fluid that is at a reference temperature + * and density, @f$ T_0 @f$ and @f$ \rho_0 @f$. These reference conditions are not + * the same as the conditions that the mixture is at (@f$ T @f$ and @f$ \rho @f$). + * The subscript 0 refers to the reference fluid. * * @f[ - * F_{\lambda} = \left( \frac{MW_0}{MW_m} \right)^{1/2} f_{m,0}^{1/2} h_{m,0}^{-2/3} + * F_{\lambda} = \left( \frac{MW_0}{MW_m} \right)^{1/2} f_{m,0}^{1/2} + * h_{m,0}^{-2/3} * * \quad \text{(Equation 6)} * @f] * - * Where @f$ MW_0 @f$ is the molecular weight of the reference fluid, @f$ MW_m @f$ is the - * molecular weight of the mixture, @f$ f_{m,0} @f$ and @f$ h_{m,0} @f$ are called - * reducing ratios. The @f$ h_{m,0} @f$ quantity is defined as: + * Where @f$ MW_0 @f$ is the molecular weight of the reference fluid, @f$ MW_m @f$ + * is the molecular weight of the mixture, @f$ f_{m,0} @f$ and @f$ h_{m,0} @f$ are + * called reducing ratios. The @f$ h_{m,0} @f$ quantity is defined as: * * @f[ * h_{m,0} = \sum_i \sum_j X_i X_j h_{ij} @@ -161,15 +164,17 @@ class HighPressureGasTransport : public MixTransport * factor @f$ \phi_i @f$ is defined in @cite ely-hanley1981 as follows: * * @f[ - * \phi_i(T_R^i, V_R^i, \omega_i) = \frac{Z_0^c}{Z_i^c} [1 + (\omega_i - \omega_0)G(T_R^i, V_R^i)] + * \phi_i(T_R^i, V_R^i, \omega_i) = \frac{Z_0^c}{Z_i^c} [1 + (\omega_i - + * \omega_0)G(T_R^i, V_R^i)] * * \quad \text{(Equation 12 of @cite ely-hanley1981)} * @f] * - * Where @f$ Z_0^c @f$ is the critical compressibility of the reference fluid, @f$ Z_i^c @f$ - * is the critical compressibility of species i, @f$ \omega_0 @f$ is the acentric factor of - * the reference fluid, and @f$ G(T_R^i, V_R^i) @f$ is a function of the reduced temperature - * and reduced volume of species i. The function @f$ G(T_R^i, V_R^i) @f$ is defined as: + * Where @f$ Z_0^c @f$ is the critical compressibility of the reference fluid, + * @f$ Z_i^c @f$ is the critical compressibility of species i, @f$ \omega_0 @f$ + * is the acentric factor of the reference fluid, and @f$ G(T_R^i, V_R^i) @f$ is a + * function of the reduced temperature and reduced volume of species i. The + * function @f$ G(T_R^i, V_R^i) @f$ is defined as: * * @f[ * G(T_R^i, V_R^i) = a_2(V_i^+ + b_2) + c_2(V_i^+ + d_2)ln(T_R^i) @@ -177,8 +182,8 @@ class HighPressureGasTransport : public MixTransport * \quad \text{(Equation 14 of @cite ely-hanley1981)} * @f] * - * Where @f$ T_i^+ @f$ and @f$ V_i^+ @f$ are limited values of the reduced temperature - * and pressure and are defined as: + * Where @f$ T_i^+ @f$ and @f$ V_i^+ @f$ are limited values of the reduced + * temperature and pressure and are defined as: * * @f[ * T_i^+ = min(2, max(T_R^i, 0.5)) @@ -212,8 +217,8 @@ class HighPressureGasTransport : public MixTransport * @f] * * - * The value of @f$ h_{ij} @f$ is the same as the one defined earlier. The combining - * rule for @f$ f_{ij} @f$ is given by: + * The value of @f$ h_{ij} @f$ is the same as the one defined earlier. The + * combining rule for @f$ f_{ij} @f$ is given by: * * @f[ * f_{ij} = (f_i f_j)^{1/2} (1-\kappa_{ij}) @@ -222,8 +227,8 @@ class HighPressureGasTransport : public MixTransport * @f] * * @f$ \kappa_{ij} @f$ is binary interaction parameters and is assumed to be zero - * as was done in the work of Ely and Hanley. The species-specific value of @f$ f_i @f$ - * is defined as: + * as was done in the work of Ely and Hanley. The species-specific value of + * @f$ f_i @f$ is defined as: * * @f[ * f_i = \frac{T_c^i}{T_c^0} \theta_i(T_R^i, V_R^i, \omega_i) @@ -231,10 +236,10 @@ class HighPressureGasTransport : public MixTransport * \quad \text{(Equation 12 @cite ely-hanley1981)} * @f] * - * Where @f$ \theta_i @f$ is a shape factor of Leach and Leland, @f$ T_c^i @f$ is the - * critical temperature of species i, and @f$ T_c^0 @f$ is the critical temperature of - * the reference fluid. The shape factor @f$ \theta_i @f$ is defined in @cite ely-hanley1981 - * as: + * Where @f$ \theta_i @f$ is a shape factor of Leach and Leland, @f$ T_c^i @f$ is + * the critical temperature of species i, and @f$ T_c^0 @f$ is the critical + * temperature of the reference fluid. The shape factor @f$ \theta_i @f$ is defined + * in @cite ely-hanley1981 as: * * @f[ * \theta_i(T_R^i, V_R^i, \omega_i) = 1 + (\omega_i - \omega_0)F(T_R^i, V_R^i)] @@ -242,10 +247,11 @@ class HighPressureGasTransport : public MixTransport * \quad \text{(Equation 11 of @cite ely-hanley1981)} * @f] * - * Where @f$ Z_0^c @f$ is the critical compressibility of the reference fluid, @f$ Z_i^c @f$ - * is the critical compressibility of species i, @f$ \omega_0 @f$ is the acentric factor of - * the reference fluid, and @f$ G(T_R^i, V_R^i) @f$ is a function of the reduced temperature - * and reduced volume of species i. The function @f$ G(T_R^i, V_R^i) @f$ is defined as: + * Where @f$ Z_0^c @f$ is the critical compressibility of the reference fluid, + * @f$ Z_i^c @f$ is the critical compressibility of species i, @f$ \omega_0 @f$ is + * the acentric factor of the reference fluid, and @f$ G(T_R^i, V_R^i) @f$ is a + * function of the reduced temperature and reduced volume of species i. The + * function @f$ G(T_R^i, V_R^i) @f$ is defined as: * * @f[ * F(T_R^i, V_R^i) = a_1 + b_1 ln(T_R^i) + (c_1 + d_1/T_R^i) (V_R^i - 0.5) @@ -253,8 +259,8 @@ class HighPressureGasTransport : public MixTransport * \quad \text{(Equation 13 of @cite ely-hanley1981)} * @f] * - * Where @f$ T_i^+ @f$ and @f$ V_i^+ @f$ are limited values of the reduced temperature - * and pressure and have the same definition as was shown earlier. + * Where @f$ T_i^+ @f$ and @f$ V_i^+ @f$ are limited values of the reduced + * temperature and pressure and have the same definition as was shown earlier. * * The values of @f$ a_1 @f$, @f$ b_1 @f$, @f$ c_1 @f$, and @f$ d_1 @f$ are * given in Table II of @cite ely-hanley1981. They are: @@ -263,19 +269,22 @@ class HighPressureGasTransport : public MixTransport * a_1 = 0.090569, b_1 = -0.862762, c_1 = 0.316636, d_1 = -0.465684 * @f] * - * With the definitions above, the value of @f$ h_{m,0} @f$ can be computed from the - * equation that defined the value of @f$ f_{m,0} h_{m,0} @f$. The value of @f$ h_{m,0} @f$ - * must be computed first and then the value of @f$ f_{m,0} @f$ can be computed. + * With the definitions above, the value of @f$ h_{m,0} @f$ can be computed from + * the equation that defined the value of @f$ f_{m,0} h_{m,0} @f$. The value of + * @f$ h_{m,0} @f$ must be computed first and then the value of @f$ f_{m,0} @f$ + * can be computed. * - * The value of @f$ MW_m @f$ is the molecular weight of the mixture and is computed using - * the following equation. This expression is somewhat complex, but the method to obtain the - * value of @f$ MW_m @f$ is to compute the right-hand-side first with the definitions of - * @f$ MW_{ij} @f$, @f$ f_{ij} @f$, and @f$ h_{ij} @f$ . Then once the right-hand-side is - * known, along with the previously computed values of @f$ f_{m,0} @f$ and @f$ h_{m,0} @f$, - * we can use simple algebra to isolate @f$ MW_m @f$. + * The value of @f$ MW_m @f$ is the molecular weight of the mixture and is computed + * using the following equation. This expression is somewhat complex, but the + * method to obtain the value of @f$ MW_m @f$ is to compute the right-hand-side + * first with the definitions of @f$ MW_{ij} @f$, @f$ f_{ij} @f$, and + * @f$ h_{ij} @f$ . Then once the right-hand-side is known, along with the + * previously computed values of @f$ f_{m,0} @f$ and @f$ h_{m,0} @f$,we can use + * simple algebra to isolate @f$ MW_m @f$. * * @f[ - * MW_m^{1/2} f_{m,0}^{1/2} h_{m,0}^{-4/3} = \sum_i \sum_j X_i X_j MW_{ij}^{-1/2} f_{ij}^{1/2} h_{ij}^{-4/3} + * MW_m^{1/2} f_{m,0}^{1/2} h_{m,0}^{-4/3} = \sum_i \sum_j X_i X_j MW_{ij}^{-1/2} + * f_{ij}^{1/2} h_{ij}^{-4/3} * * \quad \text{(Equation 14)} * @f] @@ -288,18 +297,20 @@ class HighPressureGasTransport : public MixTransport * \quad \text{(Equation 15)} * @f] * - * For clarity, if we assume the right-hand-side of the molecular weight mixture equation is A, then - * the mixture molecular weight is given by: + * For clarity, if we assume the right-hand-side of the molecular weight mixture + * equation is A, then the mixture molecular weight is given by: * * @f[ * MW_m = A^{-2} f_{m,0} h_{m,0}^{-8/3} * @f] * - * All of the above descriptions allow for the calculation of @f$ F_{\lambda} @f$ in the expression for - * the mixture value of the translational component of the thermal conductivity. The reference fluid - * value of the translational component of the thermal conductivity is still needed. The first thing - * that needs to be done is the obtain the temperature and density of the reference fluid. The following - * relations are used to compute the reference fluid temperature and density. + * All of the above descriptions allow for the calculation of @f$ F_{\lambda} @f$ + * in the expression for the mixture value of the translational component of the + * thermal conductivity. The reference fluid value of the translational component + * of the thermal conductivity is still needed. The first thing that needs to be + * done is the obtain the temperature and density of the reference fluid. The + * following relations are used to compute the reference fluid temperature and + * density. * * @f[ * \rho_0 = \rho h_{m,0} @@ -318,15 +329,19 @@ class HighPressureGasTransport : public MixTransport * computed using the following equation. * * @f[ - * \lambda^{'}_{0}(\rho_0, T_0) = \frac{15R}{4MW_0} \eta_0^* + \lambda_0^{(1)}\rho_0 + \Delta\lambda_0(\rho_0, T_0) + * \lambda^{'}_{0}(\rho_0, T_0) = \frac{15R}{4MW_0} \eta_0^* + + * \lambda_0^{(1)}\rho_0 + + * \Delta\lambda_0(\rho_0, T_0) * * \quad \text{(Equation 18)} * @f] * - * Where @f$ \eta_0^* @f$ is the dilute gas viscosity, @f$ \lambda_0^{(1)} @f$ is the first density - * correction to the thermal conductivity, and @f$ \Delta\lambda_0 @f$ is the high-density contribution. - * Ely and Hanley provide a correlation equation to solve for this quantity for the methane reference - * fluid. The details of the correlation and the parameters are shown in Table I of @cite ely-hanley1983. + * Where @f$ \eta_0^* @f$ is the dilute gas viscosity, @f$ \lambda_0^{(1)} @f$ is + * the first density correction to the thermal conductivity, and + * @f$ \Delta\lambda_0 @f$ is the high-density contribution. Ely and Hanley provide + * a correlation equation to solve for this quantity for the methane reference + * fluid. The details of the correlation and the parameters are shown in Table I + * of @cite ely-hanley1983. * * For completeness, the relations are reproduced here. * From a0e94e1aaeb6cbfeb1080c0a6983fc671002e3e8 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Sun, 18 Aug 2024 02:26:56 -0400 Subject: [PATCH 20/37] [transport] fixed incorrect equation in binary diffusion coefficient method --- src/transport/HighPressureGasTransport.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 759654bca7..ddfb046484 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -320,8 +320,9 @@ void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* cons double x_j = std::max(Tiny, m_molefracs[j]); // Weight mole fractions of i and j so that X_i + X_j = 1.0. - x_i = x_i/(x_i + x_j); - x_j = x_j/(x_i + x_j); + double sum_x_ij = x_i + x_j; + x_i = x_i/(sum_x_ij); + x_j = x_j/(sum_x_ij); // Calculate Tr and Pr based on mole-fraction-weighted critical constants. double Tr_ij = m_temp/(x_i*Tcrit_i(i) + x_j*Tcrit_i(j)); @@ -664,8 +665,9 @@ void ChungHighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* double x_j = std::max(Tiny, m_molefracs[j]); // Weight mole fractions of i and j so that X_i + X_j = 1.0. - x_i = x_i/(x_i + x_j); - x_j = x_j/(x_i + x_j); + double sum_x_ij = x_i + x_j; + x_i = x_i/(sum_x_ij); + x_j = x_j/(sum_x_ij); // Calculate Tr and Pr based on mole-fraction-weighted critical constants. double Tr_ij = m_temp/(x_i*Tcrit_i(i) + x_j*Tcrit_i(j)); From 6df98a4fefb77f79b9a32b8e5963e18b54e75186 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Sun, 18 Aug 2024 02:45:58 -0400 Subject: [PATCH 21/37] [transport] removed mixture quantity structs and placed values as private class variables --- .../transport/HighPressureGasTransport.h | 67 +++++++------- src/transport/HighPressureGasTransport.cpp | 87 +++++++++---------- 2 files changed, 72 insertions(+), 82 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index e73cec162b..e13c0c5d8a 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -16,19 +16,6 @@ namespace Cantera { -// These are the parameters that are needed to calculate the viscosity using the Lucas method. -struct LucasMixtureParameters -{ - double FQ_mix_o; - double FP_mix_o; - double Tr_mix; - double Pr_mix; - double Pc_mix; - double Tc_mix; - double MW_mix; - double P_vap_mix; -}; - /** * The implementation employs a method of corresponding states, using the Takahashi * @cite takahashi1975 approach for binary diffusion coefficients (using mixture @@ -472,7 +459,7 @@ class HighPressureGasTransport : public MixTransport double elyHanleyReferenceThermalConductivity(double rho0, double T0); /** - * Returns the composition-dependent values of parameters that are needed for the + * Computes the composition-dependent values of parameters that are needed for the * Lucas viscosity model. * * The equations for the mixing rules defined on page 9.23 of @cite poling2001 for @@ -548,7 +535,7 @@ class HighPressureGasTransport : public MixTransport * @f] * */ - void computeMixtureParameters(LucasMixtureParameters& params); + void computeMixtureParameters(); /** * Returns the non-dimensional low-pressure mixture viscosity in using the Lucas @@ -669,26 +656,15 @@ class HighPressureGasTransport : public MixTransport const double ref_rhoc = 0.1628; // g/cm^3 const double ref_acentric_factor = 0.011; // unitless -}; - - -//These are the parameters that are needed to calculate the viscosity using the Chung method. -struct ChungMixtureParameters -{ - // Mixture critical properties used by the Chung viscosity model. - double Vc_mix = 0; - double Tc_mix = 0; - - // Values associated with the calculation of sigma and the molecular weight used in the Chung viscosity model. - double sigma_mix = 0; - double epsilon_over_k_mix = 0; - double MW_mix = 0; - - // Values associated with the calculation of the Fc factor in the Chung viscosity model. - double mu_mix = 0; - double mu_r_mix = 0; - double acentric_factor_mix = 0; - double kappa_mix = 0; + // Parameters that are needed to calculate the viscosity using the Lucas method. + double m_FQ_mix_o; // Quantum correction factor + double m_FP_mix_o; // Polarity correction factor + double m_Tr_mix; // Reduced temperature + double m_Pr_mix; // Reduced pressure + double m_Pc_mix; // Critical pressure + double m_Tc_mix; // Critical temperature + double m_MW_mix; // Molecular weight + double m_P_vap_mix; // Vapor pressure }; /** @@ -826,7 +802,7 @@ class ChungHighPressureGasTransport : public MixTransport double Zcrit_i(size_t i); /** - * Returns the composition-dependent values of the parameters needed for + * Computes the composition-dependent values of the parameters needed for * the Chung viscosity model. * * The equations for the mixing rules defined on page 9.25 for the Chung method's @@ -990,7 +966,7 @@ class ChungHighPressureGasTransport : public MixTransport * In the equations, @f$ T_c @f$ must be in units of K, @f$ V_c @f$ must be in * units of cm^3/mol, and @f$ \mu @f$ must be in units of Debye. */ - void computeMixtureParameters(ChungMixtureParameters& params); + void computeMixtureParameters(); /** * Returns the low-pressure mixture viscosity in Pa*s using the Chung method. @@ -1212,6 +1188,23 @@ class ChungHighPressureGasTransport : public MixTransport std::vector acentric_factor_i; std::vector kappa_i; + // Parameters that are needed to calculate the viscosity using the Chung method. + + // Mixture critical properties used by the Chung viscosity model. + double m_Vc_mix = 0; + double m_Tc_mix = 0; + + // Values associated with the calculation of sigma and the molecular weight used in the Chung viscosity model. + double m_sigma_mix = 0; + double m_epsilon_over_k_mix = 0; + double m_MW_mix = 0; + + // Values associated with the calculation of the Fc factor in the Chung viscosity model. + double m_mu_mix = 0; + double m_mu_r_mix = 0; + double m_acentric_factor_mix = 0; + double m_kappa_mix = 0; + }; } diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index ddfb046484..d3b265f58b 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -346,24 +346,23 @@ void HighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* cons double HighPressureGasTransport::viscosity() { - LucasMixtureParameters params; - computeMixtureParameters(params); + computeMixtureParameters(); // This is η*ξ double nondimensional_viscosity = highPressureNondimensionalViscosity( - params.Tr_mix, params.Pr_mix, params.FP_mix_o, params.FQ_mix_o, - params.P_vap_mix, params.Pc_mix); + m_Tr_mix, m_Pr_mix, m_FP_mix_o, m_FQ_mix_o, + m_P_vap_mix, m_Pc_mix); // Using equation 9-4.14, with units of 1/(Pa*s) - double numerator = GasConstant*params.Tc_mix*pow(Avogadro,2.0); - double denominator = pow(params.MW_mix,3.0)*pow(params.Pc_mix,4.0); + double numerator = GasConstant*m_Tc_mix*pow(Avogadro,2.0); + double denominator = pow(m_MW_mix,3.0)*pow(m_Pc_mix,4.0); double xi = pow(numerator / denominator, 1.0/6.0); // Return the viscosity in kg/m/s return nondimensional_viscosity / xi; } -void HighPressureGasTransport::computeMixtureParameters(LucasMixtureParameters& params) +void HighPressureGasTransport::computeMixtureParameters() { double Tc_mix = 0.0; double Pc_mix_n = 0.0; // Numerator in equation 9-5.19 @@ -455,14 +454,14 @@ void HighPressureGasTransport::computeMixtureParameters(LucasMixtureParameters& } FQ_mix_o *= A; - params.FQ_mix_o = FQ_mix_o; - params.FP_mix_o = FP_mix_o; - params.Tc_mix = Tc_mix; - params.Tr_mix = Tr_mix; - params.Pc_mix = Pc_mix; - params.Pr_mix = Pr_mix; - params.MW_mix = MW_mix; - params.P_vap_mix = P_vap_mix; + m_FQ_mix_o = FQ_mix_o; + m_FP_mix_o = FP_mix_o; + m_Tc_mix = Tc_mix; + m_Tr_mix = Tr_mix; + m_Pc_mix = Pc_mix; + m_Pr_mix = Pr_mix; + m_MW_mix = MW_mix; + m_P_vap_mix = P_vap_mix; } // Pure species critical properties - Tc, Pc, Vc, Zc: @@ -690,17 +689,16 @@ void ChungHighPressureGasTransport::getBinaryDiffCoeffs(const size_t ld, double* double ChungHighPressureGasTransport::thermalConductivity() { - ChungMixtureParameters params; - computeMixtureParameters(params); + computeMixtureParameters(); // Compute T_star using equation 9-5.26, using the mixture parameters double tKelvin = m_thermo->temperature(); - double T_star = tKelvin / params.epsilon_over_k_mix; + double T_star = tKelvin / m_epsilon_over_k_mix; // The density is required for high-pressure gases. // The Chung method requires density to be units of mol/cm^3 // We use the mixture molecular weight (units of kg/kmol). - double kg_per_m3_to_mol_per_cm3 = (1.0 / params.MW_mix)*1e-3; // 1 kmol/m^3 = 1e-3 mol/cm^3 + double kg_per_m3_to_mol_per_cm3 = (1.0 / m_MW_mix)*1e-3; // 1 kmol/m^3 = 1e-3 mol/cm^3 double density = m_thermo->density()*kg_per_m3_to_mol_per_cm3; // The value of Cv is already a mole-weighted average of the pure species values @@ -708,9 +706,9 @@ double ChungHighPressureGasTransport::thermalConductivity() // This result is in units of W/m/K double thermal_conductivity = highPressureThermalConductivity( - tKelvin, T_star, params.MW_mix, density, Cv_mix, params.Vc_mix, - params.Tc_mix, params.sigma_mix, params.acentric_factor_mix, - params.mu_r_mix, params.kappa_mix); + tKelvin, T_star, m_MW_mix, density, Cv_mix, m_Vc_mix, + m_Tc_mix, m_sigma_mix, m_acentric_factor_mix, + m_mu_r_mix, m_kappa_mix); // Return the thermal conductivity in W/m/K return thermal_conductivity; @@ -774,31 +772,30 @@ double ChungHighPressureGasTransport::highPressureThermalConductivity( double ChungHighPressureGasTransport::viscosity() { - ChungMixtureParameters params; - computeMixtureParameters(params); + computeMixtureParameters(); // Compute T_star using equation 9-5.26, using the mixture parameters double tKelvin = m_thermo->temperature(); - double T_star = tKelvin / params.epsilon_over_k_mix; + double T_star = tKelvin / m_epsilon_over_k_mix; // The density is required for high-pressure gases. // The Chung method requires density to be units of mol/cm^3 // We use the mixture molecular weight (units of kg/kmol) here. - double kg_per_m3_to_mol_per_cm3 = (1.0 / params.MW_mix)*1e-3; // 1 kmol/m^3 = 1e-3 mol/cm^3 + double kg_per_m3_to_mol_per_cm3 = (1.0 / m_MW_mix)*1e-3; // 1 kmol/m^3 = 1e-3 mol/cm^3 double molar_density = m_thermo->density()*kg_per_m3_to_mol_per_cm3; // This result is in units of micropoise - double viscosity = highPressureViscosity(T_star, params.MW_mix, molar_density, - params.Vc_mix, params.Tc_mix, - params.acentric_factor_mix, - params.mu_r_mix, params.kappa_mix); + double viscosity = highPressureViscosity(T_star, m_MW_mix, molar_density, + m_Vc_mix, m_Tc_mix, + m_acentric_factor_mix, + m_mu_r_mix, m_kappa_mix); double micropoise_to_pascals_second = 1e-7; return viscosity*micropoise_to_pascals_second; } -void ChungHighPressureGasTransport::computeMixtureParameters(ChungMixtureParameters& params) +void ChungHighPressureGasTransport::computeMixtureParameters() { // Here we use the combining rules defined on page 9.25. // We have ASSUMED that the binary interaction parameters are unity for all species @@ -813,52 +810,52 @@ void ChungHighPressureGasTransport::computeMixtureParameters(ChungMixtureParamet for (size_t i = 0; i < m_nsp; i++) { for (size_t j = 0; j Date: Sun, 18 Aug 2024 18:38:34 -0400 Subject: [PATCH 22/37] [transport] changed the chung name to high-pressure-Chung --- include/cantera/transport/HighPressureGasTransport.h | 2 +- src/transport/TransportFactory.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index e13c0c5d8a..97aff3f54e 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -691,7 +691,7 @@ class ChungHighPressureGasTransport : public MixTransport public: string transportModel() const override { - return "high-pressure-chung"; + return "high-pressure-Chung"; } void init(ThermoPhase* thermo, int mode=0, int log_level=0) override; diff --git a/src/transport/TransportFactory.cpp b/src/transport/TransportFactory.cpp index ceef2150dc..b9fc0285af 100644 --- a/src/transport/TransportFactory.cpp +++ b/src/transport/TransportFactory.cpp @@ -46,7 +46,7 @@ TransportFactory::TransportFactory() addDeprecatedAlias("water", "Water"); reg("high-pressure", []() { return new HighPressureGasTransport(); }); addDeprecatedAlias("high-pressure", "HighP"); - reg("high-pressure-chung", []() { return new ChungHighPressureGasTransport(); }); + reg("high-pressure-Chung", []() { return new ChungHighPressureGasTransport(); }); m_CK_mode["CK_Mix"] = m_CK_mode["mixture-averaged-CK"] = true; m_CK_mode["CK_Multi"] = m_CK_mode["multicomponent-CK"] = true; } From 516cf14a0c6620aa84937e67450f33f2b00a6fcb Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Sun, 18 Aug 2024 21:20:34 -0400 Subject: [PATCH 23/37] [transport] added coding to get acentric factor from critical-properties.yaml, if needed --- include/cantera/transport/GasTransport.h | 2 +- .../transport/HighPressureGasTransport.h | 26 +++++++ src/transport/HighPressureGasTransport.cpp | 71 +++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) diff --git a/include/cantera/transport/GasTransport.h b/include/cantera/transport/GasTransport.h index 4cb78e2372..2c7ba1ef3d 100644 --- a/include/cantera/transport/GasTransport.h +++ b/include/cantera/transport/GasTransport.h @@ -203,7 +203,7 @@ class GasTransport : public Transport * name of a file containing transport property parameters and a list of * species names. */ - void getTransportData(); + virtual void getTransportData(); //! Corrections for polar-nonpolar binary diffusion coefficients /*! diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index 97aff3f54e..f3e86b98f7 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -394,6 +394,19 @@ class HighPressureGasTransport : public MixTransport protected: + /** + * Obtain required parameters from the 'critical-parameters' species input section, + * and checks the critical-properties.yaml file if an acentric factor is not + * specified. + * + * The way that GasTransport parses the input file is that if an acentric + * factor is not specified, it is quietly set to 0.0. A user may have the proper + * acentric factor in the critical-properties.yaml file, so that file is checked if + * a zero value is present. + * + */ + void getTransportData() override; + /** * Computes and stores the estimate of the critical properties for each species. * @@ -754,6 +767,19 @@ class ChungHighPressureGasTransport : public MixTransport protected: + /** + * Obtain required parameters from the 'critical-parameters' species input section, + * and checks the critical-properties.yaml file if an acentric factor is not + * specified. + * + * The way that GasTransport parses the input file is that if an acentric + * factor is not specified, it is quietly set to 0.0. A user may have the proper + * acentric factor in the critical-properties.yaml file, so that file is checked if + * a zero value is present. + * + */ + void getTransportData() override; + /** * Computes and stores the estimate of the critical properties for each species. * diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index d3b265f58b..6efd08e29d 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -13,6 +13,13 @@ #include "cantera/base/stringUtils.h" #include "cantera/transport/MultiTransport.h" +#include "cantera/transport/GasTransport.h" +#include "cantera/transport/TransportData.h" +#include "cantera/thermo/ThermoPhase.h" +#include "cantera/thermo/Species.h" +#include + + using namespace std; namespace Cantera @@ -104,6 +111,38 @@ void HighPressureGasTransport::init(ThermoPhase* thermo, int mode, int log_level initializeCriticalProperties(); } +void HighPressureGasTransport::getTransportData() +{ + // Call the base class's method to fill the properties + GasTransport::getTransportData(); + + // Contents of 'critical-properties.yaml', loaded later if needed + AnyMap critPropsDb; + std::unordered_map dbSpecies; + + // If a species has a zero acentric factor, check the critical-properties.yaml + // database to see if it has a value specified for the species. + for (size_t k = 0; k < m_thermo->nSpecies(); k++) { + if (m_w_ac[k] == 0.0) { + // Load 'crit-properties.yaml' file if not already loaded + if (critPropsDb.empty()) { + critPropsDb = AnyMap::fromYamlFile("critical-properties.yaml"); + dbSpecies = critPropsDb["species"].asMap("name"); + } + + // All names in critical-properties.yaml are upper case + auto ucName = boost::algorithm::to_upper_copy(m_thermo->species(k)->name); + if (dbSpecies.count(ucName)) { + auto& spec = *dbSpecies.at(ucName); + auto& critProps = spec["critical-parameters"].as(); + if (critProps.hasKey("acentric-factor")) { + m_w_ac[k] = critProps.convert("acentric-factor", "1"); + } + } + } + } +} + void HighPressureGasTransport::initializeCriticalProperties() { size_t nSpecies = m_thermo->nSpecies(); @@ -587,6 +626,38 @@ void ChungHighPressureGasTransport::init(ThermoPhase* thermo, int mode, int log_ initializePureFluidProperties(); } +void ChungHighPressureGasTransport::getTransportData() +{ + // Call the base class's method to fill the properties + GasTransport::getTransportData(); + + // Contents of 'critical-properties.yaml', loaded later if needed + AnyMap critPropsDb; + std::unordered_map dbSpecies; + + // If a species has a zero acentric factor, check the critical-properties.yaml + // database to see if it has a value specified for the species. + for (size_t k = 0; k < m_thermo->nSpecies(); k++) { + if (m_w_ac[k] == 0.0) { + // Load 'crit-properties.yaml' file if not already loaded + if (critPropsDb.empty()) { + critPropsDb = AnyMap::fromYamlFile("critical-properties.yaml"); + dbSpecies = critPropsDb["species"].asMap("name"); + } + + // All names in critical-properties.yaml are upper case + auto ucName = boost::algorithm::to_upper_copy(m_thermo->species(k)->name); + if (dbSpecies.count(ucName)) { + auto& spec = *dbSpecies.at(ucName); + auto& critProps = spec["critical-parameters"].as(); + if (critProps.hasKey("acentric-factor")) { + m_w_ac[k] = critProps.convert("acentric-factor", "1"); + } + } + } + } +} + void ChungHighPressureGasTransport::initializeCriticalProperties() { m_Tcrit.resize(m_nsp); From 3013fdb35987701cd2047de79186f63da11a45fb Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Sun, 18 Aug 2024 23:24:36 -0400 Subject: [PATCH 24/37] [transport] added new unit test, updated example, removed old unit test that would never work --- .../transport/high_pressure_transport.py | 61 +++++++++++++++-- src/transport/HighPressureGasTransport.cpp | 5 -- test/data/methane_co2.yaml | 66 +++++++++++++++++++ test/data/methane_co2_noAcentricFactor.yaml | 66 +++++++++++++++++++ test/python/test_transport.py | 30 +++++---- 5 files changed, 203 insertions(+), 25 deletions(-) create mode 100644 test/data/methane_co2.yaml create mode 100644 test/data/methane_co2_noAcentricFactor.yaml diff --git a/samples/python/transport/high_pressure_transport.py b/samples/python/transport/high_pressure_transport.py index 8d909bec6c..3dde84460a 100644 --- a/samples/python/transport/high_pressure_transport.py +++ b/samples/python/transport/high_pressure_transport.py @@ -3,7 +3,7 @@ ======================================== Two high-pressure gas transport models are available in Cantera: the 'high-pressure' -and the 'high-pressure-chung' models. These models utilize critical fluid properties +and the 'high-pressure-Chung' models. These models utilize critical fluid properties and other fluid-specific parameters to calculate transport properties at high pressures. These models are useful for fluids that are supercritical where ideal gas assumptions do not yield accurate results. @@ -16,36 +16,71 @@ import numpy as np import cantera as ct -# Plot the difference between the high-pressure viscosity model and -# what an ideal gas model would give for Methane. + +# Nist data for Methane at 350 K. +nist_pressures = [ + 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., + 22., 23., 24., 25., 26., 27., 28., 29., 30., 31., 32., 33., 34., 35., 36., 37., 38., + 39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51., 52., 53., 54., 55., + 56., 57., 58., 59., 60.] + +nist_viscosities = [ + 1.3460e-05, 1.3660e-05, 1.3875e-05, 1.4106e-05, 1.4352e-05, 1.4613e-05, 1.4889e-05, + 1.5179e-05, 1.5482e-05, 1.5798e-05, 1.6125e-05, 1.6463e-05, 1.6811e-05, 1.7167e-05, + 1.7531e-05, 1.7901e-05, 1.8276e-05, 1.8656e-05, 1.9040e-05, 1.9426e-05, 1.9813e-05, + 2.0202e-05, 2.0591e-05, 2.0980e-05, 2.1368e-05, 2.1755e-05, 2.2140e-05, 2.2523e-05, + 2.2904e-05, 2.3283e-05, 2.3659e-05, 2.4032e-05, 2.4403e-05, 2.4771e-05, 2.5135e-05, + 2.5497e-05, 2.5855e-05, 2.6211e-05, 2.6563e-05, 2.6913e-05, 2.7259e-05, 2.7603e-05, + 2.7944e-05, 2.8281e-05, 2.8616e-05, 2.8949e-05, 2.9278e-05, 2.9605e-05, 2.9929e-05, + 3.0251e-05, 3.0571e-05, 3.0888e-05, 3.1202e-05, 3.1514e-05, 3.1824e-05, 3.2132e-05] + +nist_thermal_conductivities = [ + 0.044665, 0.045419, 0.046217, 0.047063, 0.047954, 0.048891, 0.04987, 0.050891, + 0.051949, 0.05304, 0.05416, 0.055304, 0.056466, 0.057641, 0.058824, 0.06001, + 0.061194, 0.062374, 0.063546, 0.064707, 0.065855, 0.066988, 0.068106, 0.069208, + 0.070293, 0.071362, 0.072415, 0.073451, 0.074472, 0.075477, 0.076469, 0.077446, + 0.07841, 0.079361, 0.0803, 0.081227, 0.082143, 0.083048, 0.083944, 0.084829, + 0.085705, 0.086573, 0.087431, 0.088282, 0.089124, 0.089959, 0.090787, 0.091607, + 0.092421, 0.093228, 0.094029, 0.094824, 0.095612, 0.096395, 0.097172, 0.097944] + + +# Plot the difference between the high-pressure viscosity and thermal conductivity +# models and the ideal gas model for Methane. gas = ct.Solution('methane_co2.yaml') pressures = np.linspace(101325, 6e7, 100) -# Collect ideal viscosities +# Collect ideal viscosities and thermal conductivities ideal_viscosities = [] +ideal_thermal_conductivities = [] for pressure in pressures: gas.TPX = 350, pressure, 'CH4:1.0' ideal_viscosities.append(gas.viscosity) + ideal_thermal_conductivities.append(gas.thermal_conductivity) -# Collect real viscosities using the high-pressure-chung -gas.transport_model = 'high-pressure-chung' +# Collect real viscosities using the high-pressure-Chung +gas.transport_model = 'high-pressure-Chung' real_viscosities_1 = [] +real_thermal_conductivities_1 = [] for pressure in pressures: gas.TPX = 350, pressure, 'CH4:1.0' real_viscosities_1.append(gas.viscosity) + real_thermal_conductivities_1.append(gas.thermal_conductivity) # Collect real viscosities using the high-pressure model gas.transport_model = 'high-pressure' real_viscosities_2 = [] +real_thermal_conductivities_2 = [] for pressure in pressures: gas.TPX = 350, pressure, 'CH4:1.0' real_viscosities_2.append(gas.viscosity) + real_thermal_conductivities_2.append(gas.thermal_conductivity) # Plot the data plt.figure(figsize=(10, 6)) plt.plot(pressures, ideal_viscosities, label='Ideal Viscosity') plt.plot(pressures, real_viscosities_1, label='High-Pressure Viscosity (Chung)') -plt.plot(pressures, real_viscosities_2, label='High-Pressure Viscosity (Lucas)') +plt.plot(pressures, real_viscosities_2, label='High-Pressure Viscosity') +plt.plot(nist_pressures, nist_viscosities, 'o', label='NIST Data') plt.xlabel('Pressure (Pa)') plt.ylabel('Viscosity (Pa·s)') plt.title('Methane Viscosity Model Comparison') @@ -53,5 +88,17 @@ plt.grid(True) plt.show() +plt.figure(figsize=(10, 6)) +plt.plot(pressures, ideal_thermal_conductivities, label='Ideal Thermal Conductivity') +plt.plot(pressures, real_thermal_conductivities_1, label='High-Pressure Thermal Conductivity (Chung)') +plt.plot(pressures, real_thermal_conductivities_2, label='High-Pressure Thermal Conductivity') +plt.plot(nist_pressures, nist_thermal_conductivities, 'o', label='NIST Data') +plt.xlabel('Pressure (Pa)') +plt.ylabel('Thermal Conductivity (W/m·K)') +plt.title('Methane Thermal Conductivity Model Comparison') +plt.legend() +plt.grid(True) +plt.show() + diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 6efd08e29d..f7916aff3f 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -11,11 +11,6 @@ #include "cantera/thermo/IdealGasPhase.h" #include "cantera/transport/TransportFactory.h" #include "cantera/base/stringUtils.h" -#include "cantera/transport/MultiTransport.h" - -#include "cantera/transport/GasTransport.h" -#include "cantera/transport/TransportData.h" -#include "cantera/thermo/ThermoPhase.h" #include "cantera/thermo/Species.h" #include diff --git a/test/data/methane_co2.yaml b/test/data/methane_co2.yaml new file mode 100644 index 0000000000..146c8d5880 --- /dev/null +++ b/test/data/methane_co2.yaml @@ -0,0 +1,66 @@ +units: {length: cm, quantity: mol, activation-energy: cal/mol} + +phases: +- name: methane_co2 + species: [CH4, CO2] + thermo: Peng-Robinson + kinetics: gas + transport: mixture-averaged + reactions: none + state: + T: 300 + P: 1 atm + +species: +- name: CH4 + composition: {C: 1, H: 4} + thermo: + model: NASA7 + temperature-ranges: [200.0, 1000.0, 3500.0] + data: + - [5.14987613, -0.0136709788, 4.91800599e-05, -4.84743026e-08, 1.66693956e-11, + -1.02466476e+04, -4.64130376] + - [0.074851495, 0.0133909467, -5.73285809e-06, 1.22292535e-09, -1.0181523e-13, + -9468.34459, 18.437318] + note: L8/88 + transport: + model: gas + geometry: nonlinear + well-depth: 141.4 + diameter: 3.746 + polarizability: 2.6 + rotational-relaxation: 13.0 + critical-parameters: + critical-temperature: 190.7 + critical-pressure: 4.63e+06 + critical-molar-volume: 0.0989 + critical-compressibility: 0.288 + acentric-factor: 0.011 + +- name: CO2 + composition: {C: 1, O: 2} + thermo: + model: NASA7 + temperature-ranges: [200.0, 1000.0, 3500.0] + data: + - [2.35677352, 8.98459677e-03, -7.12356269e-06, 2.45919022e-09, -1.43699548e-13, + -4.83719697e+04, 9.90105222] + - [3.85746029, 4.41437026e-03, -2.21481404e-06, 5.23490188e-10, -4.72084164e-14, + -4.8759166e+04, 2.27163806] + note: L7/88 + transport: + model: gas + geometry: linear + well-depth: 244.0 + diameter: 3.763 + polarizability: 2.65 + rotational-relaxation: 2.1 + critical-parameters: + critical-temperature: 304.2 + critical-pressure: 7.39e+06 + critical-molar-volume: 0.0948 + critical-compressibility: 0.275 + acentric-factor: 0.228 + + + diff --git a/test/data/methane_co2_noAcentricFactor.yaml b/test/data/methane_co2_noAcentricFactor.yaml new file mode 100644 index 0000000000..146c8d5880 --- /dev/null +++ b/test/data/methane_co2_noAcentricFactor.yaml @@ -0,0 +1,66 @@ +units: {length: cm, quantity: mol, activation-energy: cal/mol} + +phases: +- name: methane_co2 + species: [CH4, CO2] + thermo: Peng-Robinson + kinetics: gas + transport: mixture-averaged + reactions: none + state: + T: 300 + P: 1 atm + +species: +- name: CH4 + composition: {C: 1, H: 4} + thermo: + model: NASA7 + temperature-ranges: [200.0, 1000.0, 3500.0] + data: + - [5.14987613, -0.0136709788, 4.91800599e-05, -4.84743026e-08, 1.66693956e-11, + -1.02466476e+04, -4.64130376] + - [0.074851495, 0.0133909467, -5.73285809e-06, 1.22292535e-09, -1.0181523e-13, + -9468.34459, 18.437318] + note: L8/88 + transport: + model: gas + geometry: nonlinear + well-depth: 141.4 + diameter: 3.746 + polarizability: 2.6 + rotational-relaxation: 13.0 + critical-parameters: + critical-temperature: 190.7 + critical-pressure: 4.63e+06 + critical-molar-volume: 0.0989 + critical-compressibility: 0.288 + acentric-factor: 0.011 + +- name: CO2 + composition: {C: 1, O: 2} + thermo: + model: NASA7 + temperature-ranges: [200.0, 1000.0, 3500.0] + data: + - [2.35677352, 8.98459677e-03, -7.12356269e-06, 2.45919022e-09, -1.43699548e-13, + -4.83719697e+04, 9.90105222] + - [3.85746029, 4.41437026e-03, -2.21481404e-06, 5.23490188e-10, -4.72084164e-14, + -4.8759166e+04, 2.27163806] + note: L7/88 + transport: + model: gas + geometry: linear + well-depth: 244.0 + diameter: 3.763 + polarizability: 2.65 + rotational-relaxation: 2.1 + critical-parameters: + critical-temperature: 304.2 + critical-pressure: 7.39e+06 + critical-molar-volume: 0.0948 + critical-compressibility: 0.275 + acentric-factor: 0.228 + + + diff --git a/test/python/test_transport.py b/test/python/test_transport.py index c1ea726b1d..ea2c30d60f 100644 --- a/test/python/test_transport.py +++ b/test/python/test_transport.py @@ -147,19 +147,6 @@ def test_add_species_multi(self, cantera_data_path): assert gas1.thermal_conductivity == approx(gas2.thermal_conductivity) assert gas1.multi_diff_coeffs == approx(gas2.multi_diff_coeffs) - def test_high_pressure_chung_viscosity(self): - state = 520, 6e7, 'NH3:1.0' - - gas1 = ct.Solution('gri30.yaml') - gas1.transport_model = 'high-pressure-chung' - gas1.TPX = state - - # Values from Poling et al. (2001), example 9-12 for ammonia - experimental_viscosity = 466e-7 # 466 micropoise = 466e-7 Pa s - - error = abs(gas1.viscosity - experimental_viscosity) / experimental_viscosity - assert error <= 0.05 # Error should be less than 5% - def test_species_visosities(self, phase): for species_name in phase.species_names: # check that species viscosity matches overall for single-species @@ -552,3 +539,20 @@ def test_set_customary_units(self, gas): tr2 = gas.species('N2').transport assert tr1.dispersion_coefficient == approx(tr2.dispersion_coefficient) assert tr1.quadrupole_polarizability == approx(tr2.quadrupole_polarizability) + +class TestHighPressureGasTransport(): + def test_acentric_factor_from_critical_properties(self): + # The acentric factor should be obtained from the critical-properties.yaml + # file given the input file that lacks the acentric-factor field. + state = 370.8, 174.8e5, 'CH4:0.755, CO2:0.245' + gas = ct.Solution(self.test_data_path / 'methane_co2_noAcentricFactor.yaml') + gas.transport_model = 'high-pressure-Chung' + gas.TPX = state + thermal_conductivity_1 = gas.thermal_conductivity + + gas = ct.Solution(self.test_data_path / 'methane_co2.yaml') + gas.transport_model = 'high-pressure-Chung' + gas.TPX = state + thermal_conductivity_2 = gas.thermal_conductivity + assert thermal_conductivity_1 == pytest.approx(thermal_conductivity_2, 1e-6) + From 3b5082eaa417451aa6974d0844563fad74b7a3a8 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Mon, 19 Aug 2024 01:53:37 -0400 Subject: [PATCH 25/37] [transport] fixed bug in debye to SI conversion, minor formatting tweaks --- src/transport/HighPressureGasTransport.cpp | 25 +++++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index f7916aff3f..25f8156473 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -453,7 +453,7 @@ void HighPressureGasTransport::computeMixtureParameters() // The dipole moment is stored in SI units, and it needs to be in // units of Debye for the Lucas method. double pascals_to_bar = 1e-5; - double SI_to_Debye = 1.0 / 3.335e-30; // Conversion factor from C*m to Debye + double SI_to_Debye = lightSpeed / 1e-21; // Conversion factor from C*m to Debye double dipole_ii = m_dipole(i,i)*SI_to_Debye; double mu_ri = 52.46*dipole_ii*dipole_ii*(Pcrit_i(i)*pascals_to_bar)/(Tc*Tc); @@ -787,7 +787,7 @@ double ChungHighPressureGasTransport::highPressureThermalConductivity( { // Calculate the low-pressure viscosity using the Chung method (units of Pa*s) double viscosity = lowPressureViscosity(T, T_star, MW, acentric_factor, mu_r, - sigma, kappa); + sigma, kappa); double M_prime = MW / 1000.0; // Convert kg/kmol to kg/mol @@ -858,7 +858,6 @@ double ChungHighPressureGasTransport::viscosity() double micropoise_to_pascals_second = 1e-7; return viscosity*micropoise_to_pascals_second; - } void ChungHighPressureGasTransport::computeMixtureParameters() @@ -871,6 +870,18 @@ void ChungHighPressureGasTransport::computeMixtureParameters() // require a final division by the final mixture values, and so the quantities in // the loop are only the numerators of the equations that are referenced in the // comments. After the loop, the final mixture values are computed and stored. + + // Zero out the mixture values of the parameters + m_sigma_mix = 0.0; + m_epsilon_over_k_mix = 0.0; + m_MW_mix = 0.0; + m_acentric_factor_mix = 0.0; + m_mu_mix = 0.0; + m_kappa_mix = 0.0; + m_Tc_mix = 0.0; + m_Vc_mix = 0.0; + m_mu_r_mix = 0.0; + vector molefracs(m_nsp); m_thermo->getMoleFractions(&molefracs[0]); for (size_t i = 0; i < m_nsp; i++) { @@ -892,7 +903,7 @@ void ChungHighPressureGasTransport::computeMixtureParameters() // The base class' dipole moment values are in the SI units, so we need to // convert to Debye units. - double SI_to_Debye = lightSpeed; // Conversion factor from C*m to Debye + double SI_to_Debye = lightSpeed / 1e-21; // Conversion factor from C*m to Debye double dipole_ii = m_dipole(i,i)*SI_to_Debye; double dipole_jj = m_dipole(j,j)*SI_to_Debye; m_mu_mix += molefracs[i]*molefracs[j]*pow(dipole_ii*dipole_jj,2.0)/pow(sigma_ij,3.0); // Equation 9-5.30 @@ -949,15 +960,14 @@ double ChungHighPressureGasTransport::lowPressureViscosity(double T, double T_st double omega = neufeldCollisionIntegral(T_star); // Equation 9-4.3. // Molecular shapes and polarities factor, Equation 9-4.11 - double Fc = 1 -0.2756*acentric_factor + 0.059035*pow(mu_r, 4.0) + kappa; + double Fc = 1 - 0.2756*acentric_factor + 0.059035*pow(mu_r, 4.0) + kappa; // Equation 9-3.9, multiplied by the Chung factor, Fc // (another way of writing 9-4.10 that avoids explicit use of the critical volume // in this method) - double viscosity = Fc* (26.69*sqrt(MW*T)/(sigma*sigma*omega)); + double viscosity = Fc*(26.69*sqrt(MW*T)/(sigma*sigma*omega)); double micropoise_to_pascals_second = 1e-7; - return micropoise_to_pascals_second*viscosity; } @@ -994,7 +1004,6 @@ double ChungHighPressureGasTransport::highPressureViscosity(double T_star, doubl double eta_2 = E_7*y*y*G_2*exp(E_8 + E_9/T_star + E_10/(T_star*T_star)); // Equation 9-6.23 - double omega = neufeldCollisionIntegral(T_star); // Equation 9-4.3 // Molecular shapes and polarities factor, Equation 9-4.11 From 254a6e56fafa38c89a2bcf19b75cd7ce82c1bf8f Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Sat, 24 Aug 2024 01:25:25 -0400 Subject: [PATCH 26/37] [transport] minor comment adjustments --- src/transport/HighPressureGasTransport.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 25f8156473..2d643c56d9 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -179,8 +179,9 @@ double HighPressureGasTransport::thermalConductivity() // below Equation 1 in @cite ely-hanley1981 . const double f_int = 1.32; + // Pure-species model parameters vector Lambda_1_i(m_nsp); // Internal contribution to thermal conductivity (lamba'') - vector f_i(m_nsp); // Pure-species model parameter + vector f_i(m_nsp); vector h_i(m_nsp); vector V_k(m_nsp); @@ -797,7 +798,7 @@ double ChungHighPressureGasTransport::highPressureThermalConductivity( static const vector a = {2.44166, -5.0924e-1, 6.6107, 1.4543e1, 7.9274e-1, -5.8634, 9.1089e1}; static const vector b = {7.4824e-1, -1.5094, 5.6207, -8.9139, 8.2019e-1, 1.2801e1, 1.2811e2}; static const vector c = {-9.1858e-1, -4.9991e1, 6.4760e1, -5.6379, -6.9369e-1, 9.5893, -5.4217e1}; - static const vector d ={1.2172e2, 6.9983e1, 2.7039e1, 7.4344e1, 6.3173, 6.5529e1, 5.2381e2}; + static const vector d = {1.2172e2, 6.9983e1, 2.7039e1, 7.4344e1, 6.3173, 6.5529e1, 5.2381e2}; // This is slightly pedantic, but this is done to have the naming convention in the // equations used match the variable names in the code. This is equation 10-5.9. From a21c5f833622a34c144996ed2a6b6441fd54c85e Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Thu, 29 Aug 2024 23:43:02 -0400 Subject: [PATCH 27/37] [transport] limited ely/hanley methane correlation to 10,000 Kelvin --- include/cantera/transport/HighPressureGasTransport.h | 3 ++- src/transport/HighPressureGasTransport.cpp | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index f3e86b98f7..92bb1d4081 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -453,7 +453,8 @@ class HighPressureGasTransport : public MixTransport * * Computes the temperature dependent (referred to as the dilute viscosity in the * reference) component only (eta_0) from the expression in Table III in - * @cite ely-hanley1981 + * @cite ely-hanley1981 . Prevents inputs larger than 10,000 Kelvin by just + * returning the value at 10,000 Kelvin. * * @param T0 */ diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 2d643c56d9..8f95ca0f84 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -289,6 +289,10 @@ double HighPressureGasTransport::elyHanleyDiluteViscosity(double T0) // Conversion factor from the correlation in micrograms/cm/s to Pa*s. double const correlation_viscosity_conversion = 1e-7; + if (T0 > 10000) { + T0 = 10000; // Limit the temperature to 10000 K + } + // Coefficients for the correlation from Table III of @cite ely-hanley1981 const std::vector c = {2.907741307e6, -3.312874033e6, 1.608101838e6, -4.331904871e5, 7.062481330e4, -7.116620750e3, 4.325174400e2, -1.445911210e1, 2.037119479e-1}; From ea15a8b466148e0f83c9f6fe80398f4e0dde7339 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Thu, 29 Aug 2024 23:43:46 -0400 Subject: [PATCH 28/37] [transport] change broken high-pressure test to use RK eos instead of ideal --- test/data/transport_models_test.xml | 8 ++++---- test/data/transport_models_test.yaml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/data/transport_models_test.xml b/test/data/transport_models_test.xml index 6306739b60..be251cd3c6 100644 --- a/test/data/transport_models_test.xml +++ b/test/data/transport_models_test.xml @@ -13,7 +13,7 @@ 2666.4473684210525 H:0.002, H2:0.988, CH3:0.0002, CH4:0.01 - + @@ -28,7 +28,7 @@ 2666.4473684210525 H:0.002, H2:0.988, CH3:0.0002, CH4:0.01 - + @@ -43,7 +43,7 @@ 2666.4473684210525 H:0.002, H2:0.988, CH3:0.0002, CH4:0.01 - + @@ -58,7 +58,7 @@ 2666.4473684210525 H:0.002, H2:0.988, CH3:0.0002, CH4:0.01 - + diff --git a/test/data/transport_models_test.yaml b/test/data/transport_models_test.yaml index c5f18f37dd..6591f60b66 100644 --- a/test/data/transport_models_test.yaml +++ b/test/data/transport_models_test.yaml @@ -8,7 +8,7 @@ phases: elements: [H, C] species: - gri30.yaml/species: [H, H2, CH3, CH4] - thermo: ideal-gas + thermo: Redlich-Kwong transport: unity-Lewis-number skip-undeclared-third-bodies: true kinetics: gas @@ -20,7 +20,7 @@ phases: elements: [H, C] species: - gri30.yaml/species: [H, H2, CH3, CH4] - thermo: ideal-gas + thermo: Redlich-Kwong transport: mixture-averaged-CK skip-undeclared-third-bodies: true kinetics: gas @@ -32,7 +32,7 @@ phases: elements: [H, C] species: - gri30.yaml/species: [H, H2, CH3, CH4] - thermo: ideal-gas + thermo: Redlich-Kwong transport: multicomponent-CK skip-undeclared-third-bodies: true kinetics: gas @@ -44,7 +44,7 @@ phases: elements: [H, C] species: - gri30.yaml/species: [H, H2, CH3, CH4] - thermo: ideal-gas + thermo: Redlich-Kwong transport: high-pressure skip-undeclared-third-bodies: true kinetics: gas From e7bb98fb37ac719206f8fad56c65c070382d01eb Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Fri, 30 Aug 2024 02:45:15 -0400 Subject: [PATCH 29/37] [transport] cleaned up ely and hanley conduction, cleaned up docs on the method as well --- .../transport/HighPressureGasTransport.h | 426 ++++++++++-------- src/transport/HighPressureGasTransport.cpp | 131 ++++-- 2 files changed, 323 insertions(+), 234 deletions(-) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index 92bb1d4081..b44b8b1609 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -63,225 +63,131 @@ class HighPressureGasTransport : public MixTransport * is the translational part. The internal part is only a function of temperature, * and the translational part is a function of both temperature and density. * - * For the internal component of the thermal conductivity the following equations - * are used. + * The internal component of the thermal conductivity is defined by Equation 2 + * in @cite ely-hanley1983 : * * @f[ * \lambda^{''}_{mix}(T) = \sum_i \sum_j X_i X_j \lambda^{''}_{ij}(T) - * - * \quad \text{(Equation 2)} * @f] * * The mixing rule for combining pure-species internal thermal conductivity - * components is given by: + * components is given by Equation 3 in @cite ely-hanley1983 : * * @f[ * (\lambda^{''}_{ij})^{-1} = 2[(\lambda^{''}_{i})^{-1} * + (\lambda^{''}_{j})^{-1}] - * - * \quad \text{(Equation 3)} * @f] * - * The pure species internal thermal conductivity is given by: + * The pure species internal thermal conductivity is given by Equation 1 in + * @cite ely-hanley1983 : * * @f[ * \lambda^{''}_{i} = \frac{\eta_i^*}{MW_i}f_{int} \left(C_{p,i}^0 - 2.5R \right) - * - * \quad \text{(Equation 1)} * @f] * * Where @f$ \eta_i^* @f$ is the referred to as the dilute gas viscosity and is the - * component that is temperature dependent described in @cite ely-hanley1981. + * component that is temperature dependent described in @cite ely-hanley1981 + * (see elyHanleyDilutePureSpeciesViscosity() ), * @f$ MW_i @f$ is the molecular weight of species i, @f$ f_int @f$ is a constant * and is 1.32, @f$ C_{p,i}^0 @f$ is the ideal gas heat capacity of species i, * and R is the gas constant (J/kmol/K). * - * For the translational component of the thermal conductivity the following - * equations are used. + * For the translational component of the thermal conductivity, Equation 5 in + * @cite ely-hanley1983 is used: * * @f[ * \lambda^{'}_{mix}(\rho, T) = \lambda^{'}_{0}(\rho_0, T_0) F_{\lambda} - * - * \quad \text{(Equation 5)} * @f] * * Where @f$ \lambda^{'}_{0}(\rho_0, T_0) @f$ is the internal component of the * thermal conductivity of a reference fluid that is at a reference temperature * and density, @f$ T_0 @f$ and @f$ \rho_0 @f$. These reference conditions are not * the same as the conditions that the mixture is at (@f$ T @f$ and @f$ \rho @f$). - * The subscript 0 refers to the reference fluid. + * The subscript 0 refers to the reference fluid. The term @f$ F_{\lambda} @f$ is + * defined by Equation 6 in @cite ely-hanley1983 : * * @f[ * F_{\lambda} = \left( \frac{MW_0}{MW_m} \right)^{1/2} f_{m,0}^{1/2} * h_{m,0}^{-2/3} - * - * \quad \text{(Equation 6)} * @f] * * Where @f$ MW_0 @f$ is the molecular weight of the reference fluid, @f$ MW_m @f$ * is the molecular weight of the mixture, @f$ f_{m,0} @f$ and @f$ h_{m,0} @f$ are - * called reducing ratios. The @f$ h_{m,0} @f$ quantity is defined as: + * called reducing ratios. The @f$ h_{m,0} @f$ quantity is defined by Equation 9 + * in @cite ely-hanley1983 : * * @f[ * h_{m,0} = \sum_i \sum_j X_i X_j h_{ij} - * - * \quad \text{(Equation 9)} * @f] * - * with, + * with @f$ h_{ij} @f$ defined by Equation 11 in @cite ely-hanley1983 : * * @f[ * h_{ij} = \frac{1}{8} (h_i^{1/3} + h_j^{1/3})^3 (1 - l_{ij}) - * - * \quad \text{(Equation 11)} * @f] * * The variable @f$ l_{ij} @f$ is a binary interaction parameter and is assumed to - * be zero as is done by Ely and Hanley. + * be zero as is done by Ely and Hanley. The pure species reducing ratio @f$ h_i @f$ + * is defined by Equation 13 in @cite ely-hanley1983 : * * @f[ * h_i = \frac{V_c^i}{V_c^0} \phi_i(T_R^i, V_R^i, \omega_i) - * - * \quad \text{(Equation 13)} - * @f] - * - * Where @f$ \phi_i @f$ is a shape factor of Leach and Leland, @f$ T_R^i @f$ is - * the reduced temperature of species i, @f$ V_R^i @f$ is the reduced volume of - * species i, and @f$ \omega_i @f$ is the acentric factor of species i The shape - * factor @f$ \phi_i @f$ is defined in @cite ely-hanley1981 as follows: - * - * @f[ - * \phi_i(T_R^i, V_R^i, \omega_i) = \frac{Z_0^c}{Z_i^c} [1 + (\omega_i - - * \omega_0)G(T_R^i, V_R^i)] - * - * \quad \text{(Equation 12 of @cite ely-hanley1981)} - * @f] - * - * Where @f$ Z_0^c @f$ is the critical compressibility of the reference fluid, - * @f$ Z_i^c @f$ is the critical compressibility of species i, @f$ \omega_0 @f$ - * is the acentric factor of the reference fluid, and @f$ G(T_R^i, V_R^i) @f$ is a - * function of the reduced temperature and reduced volume of species i. The - * function @f$ G(T_R^i, V_R^i) @f$ is defined as: - * - * @f[ - * G(T_R^i, V_R^i) = a_2(V_i^+ + b_2) + c_2(V_i^+ + d_2)ln(T_R^i) - * - * \quad \text{(Equation 14 of @cite ely-hanley1981)} - * @f] - * - * Where @f$ T_i^+ @f$ and @f$ V_i^+ @f$ are limited values of the reduced - * temperature and pressure and are defined as: - * - * @f[ - * T_i^+ = min(2, max(T_R^i, 0.5)) - * - * \quad \text{(Equation 15 of @cite ely-hanley1981)} * @f] * - * and + * Where @f$ \phi_i @f$ is a shape factor of Leach and Leland (see phiShapeFactor()), + * @f$ T_R^i @f$ is the reduced temperature of species i, @f$ V_R^i @f$ is the + * reduced volume of species i, and @f$ \omega_i @f$ is the acentric factor of + * species i. * - * @f[ - * V_i^+ = min(2, max(V_R^i, 0.5)) - * - * \quad \text{(Equation 16 of @cite ely-hanley1981)} - * @f] - * - * The values of @f$ a_2 @f$, @f$ b_2 @f$, @f$ c_2 @f$, and @f$ d_2 @f$ are - * given in Table II of @cite ely-hanley1981. They are: - * - * @f[ - * a_2 = 0.394901, b_2 = -1.023545, c_2 = -0.932813, d_2 = -0.754639 - * @f] - * - * With the definitions above, the value of @f$ h_{m,0} @f$ can be computed. This - * leaves the other reducing ratio, @f$ f_{m,0} @f$, to be defined. The value of - * that reducing ratio is defined by the following equation. + * At this point, the value of @f$ h_{m,0} @f$ can be computed. This + * leaves the other reducing ratio, @f$ f_{m,0} @f$, to be computed. The value of + * that reducing ratio is defined by Equation 8 in @cite ely-hanley1983 : * * @f[ * f_{m,0} = \frac{1}{h_{m,0}} \sum_i \sum_j X_i X_j f_{ij} h_{ij} - * - * \quad \text{(Equation 8)} * @f] * * * The value of @f$ h_{ij} @f$ is the same as the one defined earlier. The - * combining rule for @f$ f_{ij} @f$ is given by: + * combining rule for @f$ f_{ij} @f$ is given by Equation 10 in + * @cite ely-hanley1983 : * * @f[ * f_{ij} = (f_i f_j)^{1/2} (1-\kappa_{ij}) - * - * \quad \text{(Equation 10)} * @f] * * @f$ \kappa_{ij} @f$ is binary interaction parameters and is assumed to be zero * as was done in the work of Ely and Hanley. The species-specific value of - * @f$ f_i @f$ is defined as: + * @f$ f_i @f$ is defined by Equation 12 in @cite ely-hanley1983 : * * @f[ * f_i = \frac{T_c^i}{T_c^0} \theta_i(T_R^i, V_R^i, \omega_i) - * - * \quad \text{(Equation 12 @cite ely-hanley1981)} - * @f] - * - * Where @f$ \theta_i @f$ is a shape factor of Leach and Leland, @f$ T_c^i @f$ is - * the critical temperature of species i, and @f$ T_c^0 @f$ is the critical - * temperature of the reference fluid. The shape factor @f$ \theta_i @f$ is defined - * in @cite ely-hanley1981 as: - * - * @f[ - * \theta_i(T_R^i, V_R^i, \omega_i) = 1 + (\omega_i - \omega_0)F(T_R^i, V_R^i)] - * - * \quad \text{(Equation 11 of @cite ely-hanley1981)} - * @f] - * - * Where @f$ Z_0^c @f$ is the critical compressibility of the reference fluid, - * @f$ Z_i^c @f$ is the critical compressibility of species i, @f$ \omega_0 @f$ is - * the acentric factor of the reference fluid, and @f$ G(T_R^i, V_R^i) @f$ is a - * function of the reduced temperature and reduced volume of species i. The - * function @f$ G(T_R^i, V_R^i) @f$ is defined as: - * - * @f[ - * F(T_R^i, V_R^i) = a_1 + b_1 ln(T_R^i) + (c_1 + d_1/T_R^i) (V_R^i - 0.5) - * - * \quad \text{(Equation 13 of @cite ely-hanley1981)} * @f] * - * Where @f$ T_i^+ @f$ and @f$ V_i^+ @f$ are limited values of the reduced - * temperature and pressure and have the same definition as was shown earlier. + * Where @f$ \theta_i @f$ is a shape factor of Leach and Leland + * (see thetaShapeFactor()), @f$ T_c^i @f$ is the critical temperature of species + * i, and @f$ T_c^0 @f$ is the critical temperature of the reference fluid. * - * The values of @f$ a_1 @f$, @f$ b_1 @f$, @f$ c_1 @f$, and @f$ d_1 @f$ are - * given in Table II of @cite ely-hanley1981. They are: - * - * @f[ - * a_1 = 0.090569, b_1 = -0.862762, c_1 = 0.316636, d_1 = -0.465684 - * @f] - * - * With the definitions above, the value of @f$ h_{m,0} @f$ can be computed from + * The value of @f$ h_{m,0} @f$ can be computed from * the equation that defined the value of @f$ f_{m,0} h_{m,0} @f$. The value of * @f$ h_{m,0} @f$ must be computed first and then the value of @f$ f_{m,0} @f$ * can be computed. * - * The value of @f$ MW_m @f$ is the molecular weight of the mixture and is computed - * using the following equation. This expression is somewhat complex, but the - * method to obtain the value of @f$ MW_m @f$ is to compute the right-hand-side - * first with the definitions of @f$ MW_{ij} @f$, @f$ f_{ij} @f$, and - * @f$ h_{ij} @f$ . Then once the right-hand-side is known, along with the - * previously computed values of @f$ f_{m,0} @f$ and @f$ h_{m,0} @f$,we can use - * simple algebra to isolate @f$ MW_m @f$. + * The expression for @f$ MW_m @f$ is somewhat complex, but keep in mind that all + * terms except @f$ MW_m @f$ are known at this point and so simple algebra can be + * used to isolate the molecular weight of the mixture. The expression for the + * mixture molecular weight is given by Equation 14 in @cite ely-hanley1983 : * * @f[ * MW_m^{1/2} f_{m,0}^{1/2} h_{m,0}^{-4/3} = \sum_i \sum_j X_i X_j MW_{ij}^{-1/2} * f_{ij}^{1/2} h_{ij}^{-4/3} - * - * \quad \text{(Equation 14)} * @f] * - * where, + * where the mixing rule for the molecular weight of the mixture is given by + * Equation 15 in @cite ely-hanley1983 : * * @f[ * MW_{ij} = \frac{1}{2} (MW_i^{-1} + MW_j^{-1}) - * - * \quad \text{(Equation 15)} * @f] * * For clarity, if we assume the right-hand-side of the molecular weight mixture @@ -294,70 +200,32 @@ class HighPressureGasTransport : public MixTransport * All of the above descriptions allow for the calculation of @f$ F_{\lambda} @f$ * in the expression for the mixture value of the translational component of the * thermal conductivity. The reference fluid value of the translational component - * of the thermal conductivity is still needed. The first thing that needs to be - * done is the obtain the temperature and density of the reference fluid. The - * following relations are used to compute the reference fluid temperature and - * density. + * of the thermal conductivity ( @f$ \lambda^{'}_{0}(\rho_0, T_0) @f$ ) is still + * needed, which requires the the temperature and density of the reference fluid. + * + * The reference fluid density is computed using Equation 7 in + * @cite ely-hanley1983 : * * @f[ * \rho_0 = \rho h_{m,0} - * - * \quad \text{(Equation 7)} * @f] * - * and + * The reference fluid temperature is computed using Equation 7 in + * @cite ely-hanley1983 : * * @f[ * T_0 = \frac{T}{f_{m,0}} - * \quad \text{(Equation 7)} * @f] * * The reference fluid translational component of thermal conductivity can now be - * computed using the following equation. - * - * @f[ - * \lambda^{'}_{0}(\rho_0, T_0) = \frac{15R}{4MW_0} \eta_0^* + - * \lambda_0^{(1)}\rho_0 + - * \Delta\lambda_0(\rho_0, T_0) - * - * \quad \text{(Equation 18)} - * @f] - * - * Where @f$ \eta_0^* @f$ is the dilute gas viscosity, @f$ \lambda_0^{(1)} @f$ is - * the first density correction to the thermal conductivity, and - * @f$ \Delta\lambda_0 @f$ is the high-density contribution. Ely and Hanley provide - * a correlation equation to solve for this quantity for the methane reference - * fluid. The details of the correlation and the parameters are shown in Table I - * of @cite ely-hanley1983. - * - * For completeness, the relations are reproduced here. - * - * @f[ - * \lambda_0^*(T_0) = \frac{15R}{4MW_0} \eta_0^* - * @f] - * - * @f[ - * \eta_0^* = \sum_{n=1}^{9} C_n T_0^{(n-4)/3} - * @f] - * - * @f[ - * \lambda_0^{(1)} = b_1 + b_2[b_3 - ln(T_0 / b_4)]^2 - * @f] - * - * @f[ - * \Delta\lambda_0 = exp[a_1 + a_2/T_0] (exp[(a_3 + a_4/T_0^{3/4})\rho_0^{0.1} - * + (\rho_0 / \rho_0,c - 1)\rho_0^{0.5} - * (a_5 + a_6/T_0 + a_7/T_0^2) ] - 1) - * @f] - * - * The constants a, b, and C are not related to any ones used in the previous - * equations, their values are defined in Table I of @cite ely-hanley1983. + * computed using Equation 18 in @cite ely-hanley1983. + * See elyHanleyReferenceThermalConductivity(). * * @note The correlations for the reference fluid viscosity return a value of * micro-grams/cm/s and the parts of the thermal conductivity that utilize * the correlation fit parameters give values in units of mW/m/K. Appropriate * conversions were made in the relevant functions. - * @see elyHanleyDiluteViscosity() + * @see elyHanleyDiluteReferenceViscosity() * @see elyHanleyReferenceThermalConductivity() */ double thermalConductivity() override; @@ -447,6 +315,157 @@ class HighPressureGasTransport : public MixTransport */ double Zcrit_i(size_t i); + /** + * Returns the viscosity of a pure species using the method of Ely and Hanley. + * Units are Pa*s + * + * Uses the method outlined in @cite ely-hanley1981 to compute the viscosity of a + * pure species. + * + * The primary equation is given by Equation 1 in @cite ely-hanley1981 : + * + * @f[ + * \eta_i(\rho,T) = \eta_0(\rho_0, T_0) F_{\eta} + * @f] + * + * Where @f$ F_{\eta} @f$ is defined by Equation 2 in @cite ely-hanley1981 : + * + * @f[ + * F_{\eta} = \left( \frac{MW_i}{MW_0} \right)^{1/2} f_{i,0}^{1/2} h_{i,0}^{-2/3} + * @f] + * + * The `0` subscripts refer to the reference fluid, which is methane in this case, + * and the `i` subscripts refer to the species of interest. No mixing rules + * need to be used here because this is for a pure species. As such, the terms + * @f$ f_{i,0} @f$ and @f$ h_{i,0} @f$ have simpler expressions. The value of + * @f$ f_{i,0} @f$ is given by Equation 7 in @cite ely-hanley1981 : + * + * @f[ + * f_{i,0} = \frac{T_c^i}{T_c^0} \theta_i(T_R^i, V_R^i, \omega_i) + * @f] + * + * and the value of @f$ h_{i,0} @f$ is given by Equation 8 in @cite ely-hanley1981 : + * + * @f[ + * h_{i,0} = \frac{V_c^i}{V_c^0} \phi_i(T_R^i, V_R^i, Z_{c,i}, \omega_i) + * @f] + * + * Where @f$ \theta_i @f$ and @f$ \phi_i @f$ are shape factors of Leach and Leland + * ( see thetaShapeFactor() and phiShapeFactor() ), @f$ T_c^i @f$ is the critical + * temperature of species i, @f$ T_c^0 @f$ is the critical temperature of the + * reference fluid, @f$ V_c^i @f$ is the critical volume of species i, + * @f$ V_c^0 @f$ is the critical volume of the reference fluid, @f$ Z_{c,i} @f$ + * is the critical compressibility of species i, and @f$ \omega_i @f$ + * is the acentric factor of species i. + * + * @param V Molar volume of the species + * @param Tc Critical temperature of the species + * @param Vc Critical volume of the species + * @param Zc Critical compressibility of the species + * @param acentric_factor Acentric factor of the species + * @param mw Molecular weight of the species + */ + double elyHanleyDilutePureSpeciesViscosity(double V, double Tc, double Vc, + double Zc, double acentric_factor, + double mw); + + + /** + * Returns the theta shape factor of Leach and Leland for a pure species. + * + * The shape factor @f$ \theta_i @f$ is defined by Equation 11 in @cite ely-hanley1981 + * as follows: + * + * @f[ + * \theta_i(T_R^i, V_R^i, \omega_i) = 1 + (\omega_i - \omega_0)F(T_R^i, V_R^i)] + * @f] + * + * Where @f$ \omega_i @f$ is the acentric factor of species i, @f$ \omega_0 @f$ is + * the acentric factor of the reference fluid, and @f$ F(T_R^i, V_R^i) @f$ is a + * function of the reduced temperature and reduced volume of species i. The + * function @f$ F(T_R^i, V_R^i) @f$ is defined by Equation 13 in + * @cite ely-hanley1981: + * + * @f[ + * F(T_R^i, V_R^i) = a_1 + b_1 ln(T_+^i) + (c_1 + d_1/T_+^i) (V_+^i - 0.5) + * @f] + * + * Where @f$ T_+^i @f$ and @f$ V_+^i @f$ are limited values of the reduced + * temperature and pressure. The limited temperature is defined by Equation 15 in + * @cite ely-hanley1981: + * + * @f[ + * T_+^i = \text{min}(2, \text{max}(T_R^i, 0.5)) + * @f] + * + * and the limited pressure is defined by Equation 16 in @cite ely-hanley1981: + * + * @f[ + * V_i^+ = \text{min}(2, \text{max}(V_R^i, 0.5)) + * @f] + * + * The values of @f$ a_1 @f$, @f$ b_1 @f$, @f$ c_1 @f$, and @f$ d_1 @f$ are + * given in Table II of @cite ely-hanley1981. They are: + * + * @f[ + * a_1 = 0.090569, b_1 = -0.862762, c_1 = 0.316636, d_1 = -0.465684 + * @f] + * + * @param Tr Reduced temperature + * @param Vr Reduced volume + * @param acentric_factor Acentric factor + */ + double thetaShapeFactor(double Tr, double Vr, double acentric_factor); + + + /** + * Returns the phi shape factor of Leach and Leland for a pure species. + * + * The shape factor @f$ \phi_i @f$ is defined by Equation 12 in @cite ely-hanley1981 as follows: + * + * @f[ + * \phi_i(T_R^i, V_R^i, \omega_i, Z_c^i) = \frac{Z_c^0}{Z_c^i} [1 + (\omega_i - + * \omega_0)G(T_R^i, V_R^i)] + * @f] + * + * Where @f$ Z_c^0 @f$ is the critical compressibility of the reference fluid, + * @f$ Z_c^i @f$ is the critical compressibility of species i, @f$ \omega_0 @f$ + * is the acentric factor of the reference fluid, and @f$ G(T_R^i, V_R^i) @f$ is a + * function of the reduced temperature and reduced volume of species i. The + * function @f$ G(T_R^i, V_R^i) @f$ is defined by Equation 14 in @cite ely-hanley1981 : + * + * @f[ + * G(T_R^i, V_R^i) = a_2(V_+^i + b_2) + c_2(V_+^i + d_2)ln(T_+^i) + * @f] + * + * Where @f$ T_+^i @f$ and @f$ V_+^i @f$ are limited values of the reduced + * temperature and pressure. The limited temperature is defined by Equation 15 in + * @cite ely-hanley1981 : + * + * @f[ + * T_+^i = \text{min}(2, \text{max}(T_R^i, 0.5)) + * @f] + * + * and the limited pressure is defined by Equation 16 in @cite ely-hanley1981 : + * + * @f[ + * V_i^+ = \text{min}(2, \text{max}(V_R^i, 0.5)) + * @f] + * + * The values of @f$ a_2 @f$, @f$ b_2 @f$, @f$ c_2 @f$, and @f$ d_2 @f$ are + * given in Table II of @cite ely-hanley1981. They are: + * + * @f[ + * a_2 = 0.394901, b_2 = -1.023545, c_2 = -0.932813, d_2 = -0.754639 + * @f] + * + * @param Tr Reduced temperature + * @param Vr Reduced volume + * @param Zc Critical compressibility + * @param acentric_factor Acentric factor + */ + double phiShapeFactor(double Tr, double Vr, double Zc, double acentric_factor); + /** * Returns the viscosity of for the reference fluid of methane for low pressures. * Units are Pa*s @@ -456,19 +475,58 @@ class HighPressureGasTransport : public MixTransport * @cite ely-hanley1981 . Prevents inputs larger than 10,000 Kelvin by just * returning the value at 10,000 Kelvin. * - * @param T0 + * @param T0 Temperature of the reference fluid */ - double elyHanleyDiluteViscosity(double T0); + double elyHanleyDiluteReferenceViscosity(double T0); /** * Returns the thermal conductivity of for the reference fluid of methane * in units of W/m/K. * - * Computes the temperature and density dependent reference fluid thermal conductivity - * from the expression in Table I in @cite ely-hanley1983 . + * Computes the temperature and density dependent reference fluid thermal + * conductivity from the expression in Table I in @cite ely-hanley1983 . + * + * The reference fluid translational component of thermal conductivity is computed + * using Equation 18 in @cite ely-hanley1983 : + * + * @f[ + * \lambda^{'}_{0}(\rho_0, T_0) = \frac{15R}{4MW_0} \eta_0^* + + * \lambda_0^{(1)}\rho_0 + + * \Delta\lambda_0(\rho_0, T_0) + * @f] + * + * Where @f$ \eta_0^* @f$ is the dilute reference gas viscosity, + * @f$ \lambda_0^{(1)} @f$ is the first density correction to the thermal + * conductivity, and @f$ \Delta\lambda_0 @f$ is the high-density contribution. + * Ely and Hanley provide a correlation equation to solve for this quantity for + * the methane reference fluid. The details of the correlation and the parameters + * are shown in Table I of @cite ely-hanley1983. + * + * For completeness, the relations are reproduced here. + * + * @f[ + * \lambda_0^*(T_0) = \frac{15R}{4MW_0} \eta_0^* + * @f] + * + * @f[ + * \eta_0^* = \sum_{n=1}^{9} C_n T_0^{(n-4)/3} + * @f] + * + * @f[ + * \lambda_0^{(1)} = b_1 + b_2[b_3 - ln(T_0 / b_4)]^2 + * @f] + * + * @f[ + * \Delta\lambda_0 = \text{exp}[a_1 + a_2/T_0] (exp[(a_3 + a_4/T_0^{3/4})\rho_0^{0.1} + * + (\rho_0 / \rho_0,c - 1)\rho_0^{0.5} + * (a_5 + a_6/T_0 + a_7/T_0^2) ] - 1) + * @f] + * + * The constants a, b, and C are not related to any ones used in the previous + * equations, their values are defined in Table I of @cite ely-hanley1983. * - * @param rho0 - * @param T0 + * @param rho0 Density of the reference fluid + * @param T0 Temperature of the reference fluid */ double elyHanleyReferenceThermalConductivity(double rho0, double T0); diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 8f95ca0f84..92c0bca47c 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -176,7 +176,7 @@ double HighPressureGasTransport::thermalConductivity() m_thermo->getCp_R_ref(&cp_0_R[0]); // Cp/R // A model constant from the Euken correlation for polyatomic gases, described - // below Equation 1 in @cite ely-hanley1981 . + // below Equation 1 in ely-hanley1981 . const double f_int = 1.32; // Pure-species model parameters @@ -187,37 +187,24 @@ double HighPressureGasTransport::thermalConductivity() m_thermo -> getPartialMolarVolumes(&V_k[0]); for (size_t i = 0; i < m_nsp; i++) { - double Tc_i = Tcrit_i(i); - double Vc_i = Vcrit_i(i); - double T_r = m_thermo->temperature()/Tc_i; - double V_r = V_k[i]/Vc_i; - double T_p = std::min(std::max(T_r,0.5), 2.0); - double V_p = std::min(std::max(V_r,0.5),2.0); - - // Calculate variables for density-independent component, Equation 1. - // This equation requires the pure-species viscosity estimate from + // Calculate variables for density-independent component, Equation 1, + // the equation requires the pure-species viscosity estimate from // Ely and Hanley. - double theta_i = 1 + (m_w_ac[i] - ref_acentric_factor)*(0.090569 - 0.862762*log(T_p) - + (0.316636 - 0.465684/T_p)*(V_p - 0.5)); // Equation 11 @cite ely-hanley1981 - double phi_i = (1 + (m_w_ac[i] - ref_acentric_factor)*(0.394901*(V_p - 1.023545) - - 0.932813*(V_p - 0.754639)*log(T_p)))*(ref_Zc/Zcrit_i(i)); - double f_fac = (Tc_i / ref_Tc)*theta_i; // Equation 7 @cite ely-hanley1981 - double h_fac = (Vc_i / ref_Vc)*phi_i; // Equation 8 @cite ely-hanley1981 - double T_0 = m_temp/f_fac; // Equation 3, @cite ely-hanley1981 - - // Dilute reference fluid viscosity correlation, from Table III in - // @cite ely-hanley1981 - double mu_0 = elyHanleyDiluteViscosity(T_0); - double F = sqrt(f_fac*(m_mw[i]/ref_MW))*pow(h_fac,-2.0/3.0); // Equation 2, ely-hanley1981 - - double mu_i = mu_0*F; + double mu_i = elyHanleyDilutePureSpeciesViscosity(V_k[i], Tcrit_i(i), Vcrit_i(i), + Zcrit_i(i), m_w_ac[i], m_mw[i]); + // This is the internal contribution to the thermal conductivity of - // pure-species component, i, from Equation 1 in @cite ely-hanley1983 + // pure-species component, i, from Equation 1 in ely-hanley1983 Lambda_1_i[i] = (mu_i / m_mw[i])*f_int*GasConstant*(cp_0_R[i] - 2.5); // Calculate variables for density-dependent component (lambda') - f_i[i] = (Tc_i / ref_Tc)*theta_i; // Equation 12 @cite ely-hanley1983 - h_i[i] = (Vc_i / ref_Vc)*phi_i; // Equation 13 @cite ely-hanley1983 + double Tr = m_thermo->temperature() / Tcrit_i(i); + double Vr = V_k[i] / Vcrit_i(i); + double theta_i = thetaShapeFactor(Tr, Vr, m_w_ac[i]); + double phi_i = phiShapeFactor(Tr, Vr, Zcrit_i(i), m_w_ac[i]); + + f_i[i] = (Tcrit_i(i) / ref_Tc)*theta_i; // Equation 12 ely-hanley1983 + h_i[i] = (Vcrit_i(i) / ref_Vc)*phi_i; // Equation 13 ely-hanley1983 } double h_m = 0; // Corresponding states parameter, h_x,0 from ely-hanley1983 @@ -229,62 +216,104 @@ double HighPressureGasTransport::thermalConductivity() // Compute the internal contribution to the thermal conductivity of the // mixture - // Equation 3 @cite ely-hanley1983 + // Equation 3 ely-hanley1983 double Lambda_1_ij = 2*Lambda_1_i[i]*Lambda_1_i[j] / (Lambda_1_i[i] + Lambda_1_i[j] + Tiny); - // Equation 2, @cite ely-hanley1983 + // Equation 2, ely-hanley1983 Lambda_1_m += molefracs[i]*molefracs[j]*Lambda_1_ij; // Variables for density-dependent translational/collisional component of // the mixture. - // Equation 10, @cite ely-hanley1983 + // Equation 10, ely-hanley1983 double f_ij = sqrt(f_i[i]*f_i[j]); - // Equation 11, @cite ely-hanley1983 - double h_ij = 0.125*pow(pow(h_i[i],1.0/3.0) + pow(h_i[j],1.0/3.0),3.0); + // Equation 11, ely-hanley1983 + double h_ij = 0.125*pow(pow(h_i[i],1.0/3.0) + pow(h_i[j],1.0/3.0), 3.0); - // Equation 15, @cite ely-hanley1983 + // Equation 15, ely-hanley1983 double mw_ij_inv = 0.5*(m_mw[i] + m_mw[j])/(m_mw[i]*m_mw[j]); - // Equation 8, @cite ely-hanley1983 + // Equation 8, ely-hanley1983 f_m += molefracs[i]*molefracs[j]*f_ij*h_ij; - // Equation 9, @cite ely-hanley1983 + // Equation 9, ely-hanley1983 h_m += molefracs[i]*molefracs[j]*h_ij; - // Equation, 14 @cite ely-hanley1983 + // Equation, 14 ely-hanley1983 mw_m += molefracs[i]*molefracs[j]*sqrt(mw_ij_inv*f_ij)*pow(h_ij,-4.0/3.0); } } // The following two equations are the final steps for Equations 8 and 14 in - // @cite ely-hanley1983 . The calculations in the loop above computed the + // ely-hanley1983 . The calculations in the loop above computed the // right-hand-side of the equations, but the left-hand-side of the equations // contain other variables that must be moved to the right-hand-side in order to // get the values of the variables of interest. f_m = f_m/h_m; mw_m = pow(mw_m,-2.0)*f_m*pow(h_m,-8.0/3.0); - // The two relations below are from Equation 7, @cite ely-hanley1983 . This must + // The two relations below are from Equation 7, ely-hanley1983 . This must // be in units of g/cm^3 for use with the empirical correlation. const double kg_m3_to_g_cm3 = 1e-3; // Conversion factor from kg/m^3 to g/cm^3 double rho_0 = m_thermo->density()*h_m*kg_m3_to_g_cm3; double T_0 = m_temp/f_m; - // Equation 18, @cite ely-hanley1983 + // Equation 18, ely-hanley1983 double Lambda_2_ref = elyHanleyReferenceThermalConductivity(rho_0, T_0); - // Equation 6, @cite ely-hanley1983 + // Equation 6, ely-hanley1983 double F_m = sqrt(f_m*ref_MW/mw_m)*pow(h_m,-2.0/3.0); - // Equation 5, @cite ely-hanley1983 + // Equation 5, ely-hanley1983 double Lambda_2_m = F_m*Lambda_2_ref; return Lambda_1_m + Lambda_2_m; } -double HighPressureGasTransport::elyHanleyDiluteViscosity(double T0) +double HighPressureGasTransport::elyHanleyDilutePureSpeciesViscosity(double V, double Tc, double Vc, + double Zc, double acentric_factor, double mw) +{ + double Tr = m_thermo->temperature() / Tc; + double Vr = V / Vc; + double theta_i = thetaShapeFactor(Tr, Vr, acentric_factor); + double phi_i = phiShapeFactor(Tr, Vr, Zc, acentric_factor); + + double f_fac = (Tc / ref_Tc)*theta_i; // Equation 7 ely-hanley1981 + double h_fac = (Vc / ref_Vc)*phi_i; // Equation 8 ely-hanley1981 + double T_0 = m_temp/f_fac; // Equation 3, ely-hanley1981 + + // Dilute reference fluid viscosity correlation, from Table III in + // ely-hanley1981 + double mu_0 = elyHanleyDiluteReferenceViscosity(T_0); + double F = sqrt(f_fac*(mw/ref_MW))*pow(h_fac,-2.0/3.0); // Equation 2, ely-hanley1981 + + return mu_0*F; +} + +double HighPressureGasTransport::thetaShapeFactor(double Tr, double Vr, + double acentric_factor) +{ + double T_p = std::min(std::max(Tr,0.5), 2.0); + double V_p = std::min(std::max(Vr,0.5), 2.0); + + return 1 + (acentric_factor - ref_acentric_factor)*(0.090569 - 0.862762*log(T_p) + + (0.316636 - 0.465684/T_p)*(V_p - 0.5)); + +} + +double HighPressureGasTransport::phiShapeFactor(double Tr, double Vr, double Zc, + double acentric_factor) +{ + double T_p = std::min(std::max(Tr,0.5), 2.0); + double V_p = std::min(std::max(Vr,0.5), 2.0); + + return (1 + (acentric_factor - ref_acentric_factor)*(0.394901*(V_p - 1.023545) + - 0.932813*(V_p - 0.754639)*log(T_p)))*(ref_Zc/Zc); + +} + +double HighPressureGasTransport::elyHanleyDiluteReferenceViscosity(double T0) { // Conversion factor from the correlation in micrograms/cm/s to Pa*s. double const correlation_viscosity_conversion = 1e-7; @@ -293,9 +322,10 @@ double HighPressureGasTransport::elyHanleyDiluteViscosity(double T0) T0 = 10000; // Limit the temperature to 10000 K } - // Coefficients for the correlation from Table III of @cite ely-hanley1981 + // Coefficients for the correlation from Table III of ely-hanley1981 const std::vector c = {2.907741307e6, -3.312874033e6, 1.608101838e6, - -4.331904871e5, 7.062481330e4, -7.116620750e3, 4.325174400e2, -1.445911210e1, 2.037119479e-1}; + -4.331904871e5, 7.062481330e4, -7.116620750e3, + 4.325174400e2, -1.445911210e1, 2.037119479e-1}; double mu_0 = 0.0; for (size_t i = 0; i < 9; i++) { @@ -304,17 +334,18 @@ double HighPressureGasTransport::elyHanleyDiluteViscosity(double T0) return correlation_viscosity_conversion*mu_0; } -double HighPressureGasTransport::elyHanleyReferenceThermalConductivity(double rho0, double T0) +double HighPressureGasTransport::elyHanleyReferenceThermalConductivity(double rho0, + double T0) { - // Computing the individual terms of Equation 18, @cite ely-hanley1983 . This is an - // evaluation of the expressions shown in Table I of @cite ely-hanley1983 . The + // Computing the individual terms of Equation 18, ely-hanley1983 . This is an + // evaluation of the expressions shown in Table I of ely-hanley1983 . The // correlation returns values of thermal conductivity in mW/m/K, // so a conversion is needed. const double correlation_factor = 1e-3; // mW/m/K to W/m/K // This is the reference gas, dilute gas viscosity (eta_0 in Table III of - // @cite ely-hanley1981) - double mu_0 = elyHanleyDiluteViscosity(T0); + // ely-hanley1981) + double mu_0 = elyHanleyDiluteReferenceViscosity(T0); // First term in Equation 18. This expression has the correct units because // it does not use any empirical correlation, so it is excluded at the end from @@ -323,7 +354,7 @@ double HighPressureGasTransport::elyHanleyReferenceThermalConductivity(double rh // Second term in Equation 18 const vector b = {-2.52762920e-1, 3.34328590e-1, 1.12, 1.680e2}; - double Lambda_ref_1 = (b[0] + b[1]*pow(b[2] - log(T0/b[3]),2))*rho0; + double Lambda_ref_1 = (b[0] + b[1]*pow(b[2] - log(T0/b[3]), 2))*rho0; // Third term in Equation 18 const vector a = {-7.197708227, 8.5678222640e1, 1.2471834689e1, From 504bfd14bf3103380c1cdcd7bc1538eadef8726f Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Mon, 21 Oct 2024 23:56:06 -0400 Subject: [PATCH 30/37] [transport] prevent species that have a=0, b=0 from being used in the high pressure transport model --- include/cantera/transport/HighPressureGasTransport.h | 8 ++++++++ src/transport/HighPressureGasTransport.cpp | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index b44b8b1609..776c136c48 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -284,6 +284,10 @@ class HighPressureGasTransport : public MixTransport * state. This method only needs to be called once, as the critical properties for * the pure species do not change. * + * All species must have critical properties defined in the input file, either via + * critical properties or by specific values of the equation of state that are + * not zero. + * */ void initializeCriticalProperties(); @@ -848,6 +852,10 @@ class ChungHighPressureGasTransport : public MixTransport * state. This method only needs to be called once, as the critical properties for * the pure species do not change. * + * All species must have critical properties defined in the input file, either via + * critical properties or by specific values of the equation of state that are + * not zero. + * */ void initializeCriticalProperties(); diff --git a/src/transport/HighPressureGasTransport.cpp b/src/transport/HighPressureGasTransport.cpp index 92c0bca47c..cc709a7807 100644 --- a/src/transport/HighPressureGasTransport.cpp +++ b/src/transport/HighPressureGasTransport.cpp @@ -155,6 +155,12 @@ void HighPressureGasTransport::initializeCriticalProperties() mf_temp[i] = 1.0; m_thermo->setMoleFractions(&mf_temp[0]); + if (m_thermo->critTemperature() > 1e4) { + throw CanteraError("HighPressureGasTransport::initializeCriticalProperties", + "Species '{}' must have critical properties defined or non-zero cubic parameters. " + "Check the species definition or the thermo data file.", + m_thermo->species(i)->name); + } m_Tcrit[i] = m_thermo->critTemperature(); m_Pcrit[i] = m_thermo->critPressure(); m_Vcrit[i] = m_thermo->critVolume(); @@ -705,6 +711,12 @@ void ChungHighPressureGasTransport::initializeCriticalProperties() mf_temp[i] = 1.0; m_thermo->setMoleFractions(&mf_temp[0]); + if (m_thermo->critTemperature() > 1e4) { + throw CanteraError("ChungHighPressureGasTransport::initializeCriticalProperties", + "Species '{}' must have critical properties defined or non-zero cubic parameters. " + "Check the species definition or the thermo data file.", + m_thermo->species(i)->name); + } m_Tcrit[i] = m_thermo->critTemperature(); m_Pcrit[i] = m_thermo->critPressure(); m_Vcrit[i] = m_thermo->critVolume(); From d2395a9ed451ca37fb3e2a25022f07a242b6c91a Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Wed, 23 Oct 2024 22:35:29 -0400 Subject: [PATCH 31/37] [transport] added new unit test and fixed some issues with unit test input files --- test/data/methane_co2_noAcentricFactor.yaml | 7 --- test/data/methane_co2_noCritProp.yaml | 64 +++++++++++++++++++++ test/python/test_transport.py | 34 +++++++++-- 3 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 test/data/methane_co2_noCritProp.yaml diff --git a/test/data/methane_co2_noAcentricFactor.yaml b/test/data/methane_co2_noAcentricFactor.yaml index 146c8d5880..77219f6018 100644 --- a/test/data/methane_co2_noAcentricFactor.yaml +++ b/test/data/methane_co2_noAcentricFactor.yaml @@ -30,13 +30,6 @@ species: diameter: 3.746 polarizability: 2.6 rotational-relaxation: 13.0 - critical-parameters: - critical-temperature: 190.7 - critical-pressure: 4.63e+06 - critical-molar-volume: 0.0989 - critical-compressibility: 0.288 - acentric-factor: 0.011 - - name: CO2 composition: {C: 1, O: 2} thermo: diff --git a/test/data/methane_co2_noCritProp.yaml b/test/data/methane_co2_noCritProp.yaml new file mode 100644 index 0000000000..842fea541e --- /dev/null +++ b/test/data/methane_co2_noCritProp.yaml @@ -0,0 +1,64 @@ +units: {length: cm, quantity: mol, activation-energy: cal/mol} + +phases: +- name: methane_co2 + species: [CH4, CO2] + thermo: Peng-Robinson + kinetics: gas + transport: mixture-averaged + reactions: none + state: + T: 300 + P: 1 atm + +species: +- name: CH4 + composition: {C: 1, H: 4} + thermo: + model: NASA7 + temperature-ranges: [200.0, 1000.0, 3500.0] + data: + - [5.14987613, -0.0136709788, 4.91800599e-05, -4.84743026e-08, 1.66693956e-11, + -1.02466476e+04, -4.64130376] + - [0.074851495, 0.0133909467, -5.73285809e-06, 1.22292535e-09, -1.0181523e-13, + -9468.34459, 18.437318] + note: L8/88 + transport: + model: gas + geometry: nonlinear + well-depth: 141.4 + diameter: 3.746 + polarizability: 2.6 + rotational-relaxation: 13.0 + critical-parameters: + critical-temperature: 190.7 + critical-pressure: 4.63e+06 + critical-molar-volume: 0.0989 + critical-compressibility: 0.288 + acentric-factor: 0.011 + +- name: CO2 + composition: {C: 1, O: 2} + thermo: + model: NASA7 + temperature-ranges: [200.0, 1000.0, 3500.0] + data: + - [2.35677352, 8.98459677e-03, -7.12356269e-06, 2.45919022e-09, -1.43699548e-13, + -4.83719697e+04, 9.90105222] + - [3.85746029, 4.41437026e-03, -2.21481404e-06, 5.23490188e-10, -4.72084164e-14, + -4.8759166e+04, 2.27163806] + note: L7/88 + transport: + model: gas + geometry: linear + well-depth: 244.0 + diameter: 3.763 + polarizability: 2.65 + rotational-relaxation: 2.1 + equation-of-state: + model: Peng-Robinson + a: 0 + b: 0 + acentric-factor: 0.228 + + diff --git a/test/python/test_transport.py b/test/python/test_transport.py index ea2c30d60f..8ea0192627 100644 --- a/test/python/test_transport.py +++ b/test/python/test_transport.py @@ -541,18 +541,42 @@ def test_set_customary_units(self, gas): assert tr1.quadrupole_polarizability == approx(tr2.quadrupole_polarizability) class TestHighPressureGasTransport(): - def test_acentric_factor_from_critical_properties(self): - # The acentric factor should be obtained from the critical-properties.yaml - # file given the input file that lacks the acentric-factor field. + def test_acentric_factor_from_critical_properties(self, test_data_path): + """ + The acentric factor should be obtained from the critical-properties.yaml + file given the input file that lacks the acentric-factor field, as would + be the case when the cubic equation of state parameters are provided + directly. + """ + + # Missing acentric factor state = 370.8, 174.8e5, 'CH4:0.755, CO2:0.245' - gas = ct.Solution(self.test_data_path / 'methane_co2_noAcentricFactor.yaml') + gas = ct.Solution(test_data_path / 'methane_co2_noAcentricFactor.yaml') gas.transport_model = 'high-pressure-Chung' gas.TPX = state thermal_conductivity_1 = gas.thermal_conductivity - gas = ct.Solution(self.test_data_path / 'methane_co2.yaml') + # Has acentric factor + gas = ct.Solution(test_data_path / 'methane_co2.yaml') gas.transport_model = 'high-pressure-Chung' gas.TPX = state thermal_conductivity_2 = gas.thermal_conductivity + assert thermal_conductivity_1 == pytest.approx(thermal_conductivity_2, 1e-6) + def test_failure_for_species_with_no_properties(self, test_data_path): + """ + All species must have critical properties defined to use the high pressure + transport model. This test uses a YAML file with a specified value of the + a and b parameters for the Peng-Robinson equation of state, which should + be parsed by the thermo model and will set the critical properties to + non-physical values. These non-physical values should trigger an error + in the high-pressure transport model. + """ + gas = ct.Solution(test_data_path / 'methane_co2_noCritProp.yaml') + + with pytest.raises(ct.CanteraError, match="must have critical properties defined"): + gas.transport_model = 'high-pressure-Chung' + + with pytest.raises(ct.CanteraError, match="must have critical properties defined"): + gas.transport_model = 'high-pressure' From 58c8b23bf60a4670f6eb887829cadaa6593be6b9 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Wed, 23 Oct 2024 22:45:46 -0400 Subject: [PATCH 32/37] [transport] fixed whitespace issues --- data/methane_co2.yaml | 9 ++------- samples/python/transport/high_pressure_transport.py | 3 --- test/data/methane_co2.yaml | 9 ++------- test/data/methane_co2_noAcentricFactor.yaml | 8 ++------ test/data/methane_co2_noCritProp.yaml | 6 +----- 5 files changed, 7 insertions(+), 28 deletions(-) diff --git a/data/methane_co2.yaml b/data/methane_co2.yaml index 146c8d5880..0c493a965f 100644 --- a/data/methane_co2.yaml +++ b/data/methane_co2.yaml @@ -10,8 +10,7 @@ phases: state: T: 300 P: 1 atm - -species: +species: - name: CH4 composition: {C: 1, H: 4} thermo: @@ -36,7 +35,6 @@ species: critical-molar-volume: 0.0989 critical-compressibility: 0.288 acentric-factor: 0.011 - - name: CO2 composition: {C: 1, O: 2} thermo: @@ -60,7 +58,4 @@ species: critical-pressure: 7.39e+06 critical-molar-volume: 0.0948 critical-compressibility: 0.275 - acentric-factor: 0.228 - - - + acentric-factor: 0.228 diff --git a/samples/python/transport/high_pressure_transport.py b/samples/python/transport/high_pressure_transport.py index 3dde84460a..828c10b1a0 100644 --- a/samples/python/transport/high_pressure_transport.py +++ b/samples/python/transport/high_pressure_transport.py @@ -99,6 +99,3 @@ plt.legend() plt.grid(True) plt.show() - - - diff --git a/test/data/methane_co2.yaml b/test/data/methane_co2.yaml index 146c8d5880..0c493a965f 100644 --- a/test/data/methane_co2.yaml +++ b/test/data/methane_co2.yaml @@ -10,8 +10,7 @@ phases: state: T: 300 P: 1 atm - -species: +species: - name: CH4 composition: {C: 1, H: 4} thermo: @@ -36,7 +35,6 @@ species: critical-molar-volume: 0.0989 critical-compressibility: 0.288 acentric-factor: 0.011 - - name: CO2 composition: {C: 1, O: 2} thermo: @@ -60,7 +58,4 @@ species: critical-pressure: 7.39e+06 critical-molar-volume: 0.0948 critical-compressibility: 0.275 - acentric-factor: 0.228 - - - + acentric-factor: 0.228 diff --git a/test/data/methane_co2_noAcentricFactor.yaml b/test/data/methane_co2_noAcentricFactor.yaml index 77219f6018..286be47ece 100644 --- a/test/data/methane_co2_noAcentricFactor.yaml +++ b/test/data/methane_co2_noAcentricFactor.yaml @@ -10,8 +10,7 @@ phases: state: T: 300 P: 1 atm - -species: +species: - name: CH4 composition: {C: 1, H: 4} thermo: @@ -53,7 +52,4 @@ species: critical-pressure: 7.39e+06 critical-molar-volume: 0.0948 critical-compressibility: 0.275 - acentric-factor: 0.228 - - - + acentric-factor: 0.228 diff --git a/test/data/methane_co2_noCritProp.yaml b/test/data/methane_co2_noCritProp.yaml index 842fea541e..ae7a8b4722 100644 --- a/test/data/methane_co2_noCritProp.yaml +++ b/test/data/methane_co2_noCritProp.yaml @@ -10,8 +10,7 @@ phases: state: T: 300 P: 1 atm - -species: +species: - name: CH4 composition: {C: 1, H: 4} thermo: @@ -36,7 +35,6 @@ species: critical-molar-volume: 0.0989 critical-compressibility: 0.288 acentric-factor: 0.011 - - name: CO2 composition: {C: 1, O: 2} thermo: @@ -60,5 +58,3 @@ species: a: 0 b: 0 acentric-factor: 0.228 - - From d0e2f7522e16ac66823e0f83d2254c5cd4d7a1bd Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Thu, 24 Oct 2024 00:31:33 -0400 Subject: [PATCH 33/37] [transport] fixed unit test failure for transport_models_test, added common species to crit database, and updated keywords file to prevent CI failure for new example --- data/critical-properties.yaml | 11 +++++++++++ doc/example-keywords.txt | 3 ++- test/data/transport_models_test.xml | 12 ++++++------ test/data/transport_models_test.yaml | 15 +++++++-------- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/data/critical-properties.yaml b/data/critical-properties.yaml index 525dfd6af6..854f41bfa0 100644 --- a/data/critical-properties.yaml +++ b/data/critical-properties.yaml @@ -6295,3 +6295,14 @@ species: source: |- The acentric factor is calculated using the pure fluid saturation data from Lemmon et al. (2022). +- name: H2 + descriptive-name: hydrogen + molecular-weight: 2.016 + critical-parameters: + critical-temperature: 32.98 + critical-pressure: 1.293e6 + critical-molar-volume: 0.0642 + critical-compressibility: 0.303 + acentric-factor: -0.217 + source: |- + Properties of Gases and Liquids, 5th edition, Poling. \ No newline at end of file diff --git a/doc/example-keywords.txt b/doc/example-keywords.txt index d8da59667d..e86f9da105 100644 --- a/doc/example-keywords.txt +++ b/doc/example-keywords.txt @@ -16,6 +16,7 @@ Fortran 77 Fortran 90 fuel cell heat transfer +high-pressure ignition delay internal combustion engine jet-stirred reactor @@ -40,9 +41,9 @@ reaction path analysis reactor network saving output sensitivity analysis +shock tube strained flame surface chemistry -shock tube thermodynamic cycle thermodynamics transport diff --git a/test/data/transport_models_test.xml b/test/data/transport_models_test.xml index be251cd3c6..895f64baea 100644 --- a/test/data/transport_models_test.xml +++ b/test/data/transport_models_test.xml @@ -13,7 +13,7 @@ 2666.4473684210525 H:0.002, H2:0.988, CH3:0.0002, CH4:0.01 - + @@ -28,7 +28,7 @@ 2666.4473684210525 H:0.002, H2:0.988, CH3:0.0002, CH4:0.01 - + @@ -43,20 +43,20 @@ 2666.4473684210525 H:0.002, H2:0.988, CH3:0.0002, CH4:0.01 - + - H C - H H2 CH3 CH4 + H C O + CO2 CH4 1200.0 2666.4473684210525 - H:0.002, H2:0.988, CH3:0.0002, CH4:0.01 + CO2: 0.988, CH4: 0.012 diff --git a/test/data/transport_models_test.yaml b/test/data/transport_models_test.yaml index 6591f60b66..e7679001ee 100644 --- a/test/data/transport_models_test.yaml +++ b/test/data/transport_models_test.yaml @@ -8,7 +8,7 @@ phases: elements: [H, C] species: - gri30.yaml/species: [H, H2, CH3, CH4] - thermo: Redlich-Kwong + thermo: ideal-gas transport: unity-Lewis-number skip-undeclared-third-bodies: true kinetics: gas @@ -20,7 +20,7 @@ phases: elements: [H, C] species: - gri30.yaml/species: [H, H2, CH3, CH4] - thermo: Redlich-Kwong + thermo: ideal-gas transport: mixture-averaged-CK skip-undeclared-third-bodies: true kinetics: gas @@ -32,7 +32,7 @@ phases: elements: [H, C] species: - gri30.yaml/species: [H, H2, CH3, CH4] - thermo: Redlich-Kwong + thermo: ideal-gas transport: multicomponent-CK skip-undeclared-third-bodies: true kinetics: gas @@ -41,14 +41,13 @@ phases: state: {T: 1200.0 K, P: 2666.4473684210525 Pa, X: {H: 2.0e-03, H2: 0.988, CH3: 2.0e-04, CH4: 0.01}} - name: HighP - elements: [H, C] + elements: [H, C, O] species: - - gri30.yaml/species: [H, H2, CH3, CH4] + - methane_co2.yaml/species: [CO2, CH4] thermo: Redlich-Kwong transport: high-pressure skip-undeclared-third-bodies: true kinetics: gas reactions: - - gri30.yaml/reactions: declared-species - state: {T: 1200.0 K, P: 2666.4473684210525 Pa, X: {H: 2.0e-03, H2: 0.988, CH3: 2.0e-04, - CH4: 0.01}} + - gri30.yaml/reactions: none + state: {T: 1200.0 K, P: 2666.4473684210525 Pa, X: {CO2: 0.988, CH4: 0.012}} From 666ed9e8f29d7763386a9ec403a9af55c3a03730 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Mon, 4 Nov 2024 18:04:10 -0500 Subject: [PATCH 34/37] [transport] updated docs on high pressure transport models --- doc/example-keywords.txt | 1 - doc/sphinx/reference/transport/index.md | 19 +++++-- doc/sphinx/yaml/phases.rst | 2 + .../transport/high_pressure_transport.py | 57 ++++++++++++------- 4 files changed, 51 insertions(+), 28 deletions(-) diff --git a/doc/example-keywords.txt b/doc/example-keywords.txt index e86f9da105..df6d4db8c2 100644 --- a/doc/example-keywords.txt +++ b/doc/example-keywords.txt @@ -16,7 +16,6 @@ Fortran 77 Fortran 90 fuel cell heat transfer -high-pressure ignition delay internal combustion engine jet-stirred reactor diff --git a/doc/sphinx/reference/transport/index.md b/doc/sphinx/reference/transport/index.md index d8f2d1c06b..057b1e44fe 100644 --- a/doc/sphinx/reference/transport/index.md +++ b/doc/sphinx/reference/transport/index.md @@ -44,11 +44,20 @@ Mixture-averaged to `mixture-averaged`. Implemented by class {ct}`MixTransport`. High-pressure Gas -: A model for high-pressure gas transport properties based on a method of corresponding - states {cite:p}`takahashi1975,poling2001`. The high-pressure gas transport model can - be specified in the YAML format by setting the [`transport`](sec-yaml-phase-transport) - field of the phase entry to `high-pressure`. Implemented by - class {ct}`HighPressureGasTransport`. +: A model for high-pressure gas transport properties that uses the Lucas method of + corresponding states {cite:p}`poling2001` for viscosity and thermal + conductivity and the Takahashi method {cite:p}`takahashi1975,poling2001` for the + diffusion coefficient. This high-pressure gas transport model can be specified in + the YAML format by setting the [`transport`](sec-yaml-phase-transport) field of the + phase entry to `high-pressure`. Implemented by class {ct}`HighPressureGasTransport`. + +Chung high-pressure Gas +: A model for high-pressure gas transport properties that usesthe method of Chung + {cite:p}`poling2001` for viscosity and thermal conductivity and the Takahashi method + {cite:p}`takahashi1975,poling2001` for the diffusion coefficient. This high-pressure + gas transport model can be specified in the YAML format by setting the + [`transport`](sec-yaml-phase-transport) field of the phase entry to + `high-pressure-Chung`. Implemented by class {ct}`ChungHighPressureGasTransport`. Ionized Gas : A model implementing the Stockmayer-(n,6,4) model for transport of ions in a gas. The diff --git a/doc/sphinx/yaml/phases.rst b/doc/sphinx/yaml/phases.rst index e742878b29..9ddb90284b 100644 --- a/doc/sphinx/yaml/phases.rst +++ b/doc/sphinx/yaml/phases.rst @@ -166,6 +166,8 @@ and optionally reactions that can take place in that phase. The fields of a - ``none`` - ``high-pressure``: A model for high-pressure gas transport properties based on a method of corresponding states (:ct:`details `) + - ``high-pressure-Chung``: A model for high-pressure gas transport properties based + on the method Chung (:ct:`details `) - ``ionized-gas``: A model implementing the Stockmayer-(n,6,4) model for transport of ions in a gas (:ct:`details `) - ``mixture-averaged``: The mixture-averaged transport model for ideal gases diff --git a/samples/python/transport/high_pressure_transport.py b/samples/python/transport/high_pressure_transport.py index 828c10b1a0..572c936de0 100644 --- a/samples/python/transport/high_pressure_transport.py +++ b/samples/python/transport/high_pressure_transport.py @@ -10,7 +10,7 @@ Requires: cantera >= 3.1.0 -.. tags:: Python, transport, high-pressure +.. tags:: Python, transport, non-ideal fluid """ import matplotlib.pyplot as plt import numpy as np @@ -43,10 +43,21 @@ 0.085705, 0.086573, 0.087431, 0.088282, 0.089124, 0.089959, 0.090787, 0.091607, 0.092421, 0.093228, 0.094029, 0.094824, 0.095612, 0.096395, 0.097172, 0.097944] +# Create the gas object using a subset of the gri30 mechanism for the methane-co2 +# system +phasedef = """ + phases: + - name: methane_co2 + species: + - gri30.yaml/species: [CH4, CO2] + thermo: Peng-Robinson + transport: mixture-averaged + state: {T: 300, P: 1 atm} +""" +gas = ct.Solution(yaml=phasedef) # Plot the difference between the high-pressure viscosity and thermal conductivity # models and the ideal gas model for Methane. -gas = ct.Solution('methane_co2.yaml') pressures = np.linspace(101325, 6e7, 100) # Collect ideal viscosities and thermal conductivities @@ -75,27 +86,29 @@ real_viscosities_2.append(gas.viscosity) real_thermal_conductivities_2.append(gas.thermal_conductivity) +# %% # Plot the data -plt.figure(figsize=(10, 6)) -plt.plot(pressures, ideal_viscosities, label='Ideal Viscosity') -plt.plot(pressures, real_viscosities_1, label='High-Pressure Viscosity (Chung)') -plt.plot(pressures, real_viscosities_2, label='High-Pressure Viscosity') -plt.plot(nist_pressures, nist_viscosities, 'o', label='NIST Data') -plt.xlabel('Pressure (Pa)') -plt.ylabel('Viscosity (Pa·s)') -plt.title('Methane Viscosity Model Comparison') -plt.legend() -plt.grid(True) +# ------------- +mpa_to_pa = 1e6 # conversion factor from MPa to Pa +fig, ax = plt.subplots() +ax.plot(pressures, ideal_viscosities, label='Ideal Viscosity') +ax.plot(pressures, real_viscosities_1, label='High-Pressure Viscosity (Chung)') +ax.plot(pressures, real_viscosities_2, label='High-Pressure Viscosity') +ax.plot(nist_pressures*mpa_to_pa, nist_viscosities, 'o', label='NIST Data') +ax.set(xlabel='Pressure (Pa)', ylabel ='Viscosity (Pa·s)', + title='Methane Viscosity Model Comparison') +ax.legend() +ax.grid(True) plt.show() -plt.figure(figsize=(10, 6)) -plt.plot(pressures, ideal_thermal_conductivities, label='Ideal Thermal Conductivity') -plt.plot(pressures, real_thermal_conductivities_1, label='High-Pressure Thermal Conductivity (Chung)') -plt.plot(pressures, real_thermal_conductivities_2, label='High-Pressure Thermal Conductivity') -plt.plot(nist_pressures, nist_thermal_conductivities, 'o', label='NIST Data') -plt.xlabel('Pressure (Pa)') -plt.ylabel('Thermal Conductivity (W/m·K)') -plt.title('Methane Thermal Conductivity Model Comparison') -plt.legend() -plt.grid(True) +# %% +fig, ax = plt.subplots() +ax.plot(pressures, ideal_thermal_conductivities, label='Ideal Thermal Conductivity') +ax.plot(pressures, real_thermal_conductivities_1, label='High-Pressure Thermal Conductivity (Chung)') +ax.plot(pressures, real_thermal_conductivities_2, label='High-Pressure Thermal Conductivity') +ax.plot(nist_pressures*mpa_to_pa, nist_thermal_conductivities, 'o', label='NIST Data') +ax.set(xlabel='Pressure (Pa)', ylabel ='Thermal Conductivity (W/m·K)', + title='Methane Thermal Conductivity Model Comparison') +ax.legend() +ax.grid(True) plt.show() From 8c4f8588b6ac14cdaa8ce0ba9ab487350d7fd4fb Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Mon, 4 Nov 2024 18:06:22 -0500 Subject: [PATCH 35/37] [transport] added regression-type test for high pressure transport models --- test/data/HighPressureChungTest.csv | 100 +++++++++++++++++++++++ test/data/HighPressureTest.csv | 100 +++++++++++++++++++++++ test/python/conftest.py | 2 +- test/python/test_transport.py | 122 ++++++++++++++++++++++------ 4 files changed, 300 insertions(+), 24 deletions(-) create mode 100644 test/data/HighPressureChungTest.csv create mode 100644 test/data/HighPressureTest.csv diff --git a/test/data/HighPressureChungTest.csv b/test/data/HighPressureChungTest.csv new file mode 100644 index 0000000000..7cc1325c22 --- /dev/null +++ b/test/data/HighPressureChungTest.csv @@ -0,0 +1,100 @@ +1.013250e+05, 1.317510e-05, 3.304087e-02, 4.409307e-05, 1.607365e-05 +7.063621e+05, 1.320969e-05, 3.320920e-02, 6.324986e-06, 2.305705e-06 +1.311399e+06, 1.326275e-05, 3.344689e-02, 3.406843e-06, 1.241927e-06 +1.916436e+06, 1.333452e-05, 3.375287e-02, 2.331270e-06, 8.498390e-07 +2.521473e+06, 1.342518e-05, 3.412586e-02, 1.771873e-06, 6.459169e-07 +3.126511e+06, 1.353486e-05, 3.456439e-02, 1.428983e-06, 5.209202e-07 +3.731548e+06, 1.366365e-05, 3.506673e-02, 1.197286e-06, 4.364576e-07 +4.336585e+06, 1.381157e-05, 3.563097e-02, 1.030242e-06, 3.755634e-07 +4.941622e+06, 1.397858e-05, 3.625495e-02, 9.041021e-07, 3.295805e-07 +5.546659e+06, 1.416459e-05, 3.693632e-02, 8.054814e-07, 2.936294e-07 +6.151696e+06, 1.436943e-05, 3.767249e-02, 7.262600e-07, 2.647501e-07 +6.756733e+06, 1.459286e-05, 3.846072e-02, 6.612264e-07, 2.410429e-07 +7.361770e+06, 1.483458e-05, 3.929806e-02, 6.068826e-07, 2.212324e-07 +7.966808e+06, 1.509423e-05, 4.018141e-02, 5.607931e-07, 2.044310e-07 +8.571845e+06, 1.537138e-05, 4.110758e-02, 5.212100e-07, 1.900014e-07 +9.176882e+06, 1.566553e-05, 4.207325e-02, 4.868463e-07, 1.774745e-07 +9.781919e+06, 1.597614e-05, 4.307505e-02, 4.567336e-07, 1.664972e-07 +1.038696e+07, 1.630262e-05, 4.410959e-02, 4.301290e-07, 1.567988e-07 +1.099199e+07, 1.664433e-05, 4.517351e-02, 4.064532e-07, 1.481681e-07 +1.159703e+07, 1.700060e-05, 4.626348e-02, 3.852478e-07, 1.404379e-07 +1.220207e+07, 1.737074e-05, 4.737628e-02, 3.661454e-07, 1.334743e-07 +1.280710e+07, 1.775403e-05, 4.850881e-02, 3.488478e-07, 1.271687e-07 +1.341214e+07, 1.814977e-05, 4.965812e-02, 3.331109e-07, 1.214319e-07 +1.401718e+07, 1.855722e-05, 5.082147e-02, 3.187325e-07, 1.161905e-07 +1.462222e+07, 1.897568e-05, 5.199632e-02, 3.055440e-07, 1.113827e-07 +1.522725e+07, 1.940447e-05, 5.318034e-02, 2.934036e-07, 1.069571e-07 +1.583229e+07, 1.984292e-05, 5.437147e-02, 2.821911e-07, 1.028697e-07 +1.643733e+07, 2.029037e-05, 5.556785e-02, 2.718040e-07, 9.908317e-08 +1.704236e+07, 2.074624e-05, 5.676791e-02, 2.621544e-07, 9.556552e-08 +1.764740e+07, 2.120996e-05, 5.797029e-02, 2.531665e-07, 9.228908e-08 +1.825244e+07, 2.168098e-05, 5.917386e-02, 2.447745e-07, 8.922985e-08 +1.885748e+07, 2.215882e-05, 6.037773e-02, 2.369209e-07, 8.636694e-08 +1.946251e+07, 2.264304e-05, 6.158119e-02, 2.295557e-07, 8.368202e-08 +2.006755e+07, 2.313322e-05, 6.278372e-02, 2.226346e-07, 8.115901e-08 +2.067259e+07, 2.362899e-05, 6.398497e-02, 2.161186e-07, 7.878368e-08 +2.127762e+07, 2.413003e-05, 6.518474e-02, 2.099732e-07, 7.654343e-08 +2.188266e+07, 2.463604e-05, 6.638296e-02, 2.041676e-07, 7.442707e-08 +2.248770e+07, 2.514674e-05, 6.757967e-02, 1.986744e-07, 7.242459e-08 +2.309274e+07, 2.566192e-05, 6.877500e-02, 1.934691e-07, 7.052705e-08 +2.369777e+07, 2.618138e-05, 6.996916e-02, 1.885296e-07, 6.872639e-08 +2.430281e+07, 2.670493e-05, 7.116242e-02, 1.838360e-07, 6.701540e-08 +2.490785e+07, 2.723242e-05, 7.235510e-02, 1.793704e-07, 6.538752e-08 +2.551288e+07, 2.776373e-05, 7.354758e-02, 1.751166e-07, 6.383686e-08 +2.611792e+07, 2.829875e-05, 7.474022e-02, 1.710600e-07, 6.235804e-08 +2.672296e+07, 2.883738e-05, 7.593343e-02, 1.671870e-07, 6.094619e-08 +2.732800e+07, 2.937954e-05, 7.712762e-02, 1.634855e-07, 5.959685e-08 +2.793303e+07, 2.992518e-05, 7.832321e-02, 1.599444e-07, 5.830597e-08 +2.853807e+07, 3.047425e-05, 7.952061e-02, 1.565534e-07, 5.706982e-08 +2.914311e+07, 3.102669e-05, 8.072021e-02, 1.533032e-07, 5.588500e-08 +2.974814e+07, 3.158249e-05, 8.192241e-02, 1.501852e-07, 5.474837e-08 +3.035318e+07, 3.214162e-05, 8.312759e-02, 1.471915e-07, 5.365706e-08 +3.095822e+07, 3.270407e-05, 8.433610e-02, 1.443149e-07, 5.260840e-08 +3.156326e+07, 3.326983e-05, 8.554829e-02, 1.415485e-07, 5.159995e-08 +3.216829e+07, 3.383889e-05, 8.676447e-02, 1.388862e-07, 5.062943e-08 +3.277333e+07, 3.441127e-05, 8.798495e-02, 1.363222e-07, 4.969475e-08 +3.337837e+07, 3.498696e-05, 8.921002e-02, 1.338511e-07, 4.879395e-08 +3.398340e+07, 3.556599e-05, 9.043993e-02, 1.314680e-07, 4.792523e-08 +3.458844e+07, 3.614836e-05, 9.167492e-02, 1.291683e-07, 4.708690e-08 +3.519348e+07, 3.673410e-05, 9.291521e-02, 1.269477e-07, 4.627739e-08 +3.579852e+07, 3.732323e-05, 9.416101e-02, 1.248021e-07, 4.549525e-08 +3.640355e+07, 3.791577e-05, 9.541249e-02, 1.227279e-07, 4.473911e-08 +3.700859e+07, 3.851175e-05, 9.666983e-02, 1.207215e-07, 4.400769e-08 +3.761363e+07, 3.911120e-05, 9.793317e-02, 1.187796e-07, 4.329980e-08 +3.821866e+07, 3.971416e-05, 9.920263e-02, 1.168992e-07, 4.261432e-08 +3.882370e+07, 4.032065e-05, 1.004783e-01, 1.150774e-07, 4.195021e-08 +3.942874e+07, 4.093071e-05, 1.017604e-01, 1.133115e-07, 4.130648e-08 +4.003378e+07, 4.154439e-05, 1.030489e-01, 1.115990e-07, 4.068221e-08 +4.063881e+07, 4.216172e-05, 1.043439e-01, 1.099375e-07, 4.007653e-08 +4.124385e+07, 4.278274e-05, 1.056454e-01, 1.083248e-07, 3.948861e-08 +4.184889e+07, 4.340750e-05, 1.069536e-01, 1.067587e-07, 3.891770e-08 +4.245392e+07, 4.403604e-05, 1.082684e-01, 1.052372e-07, 3.836306e-08 +4.305896e+07, 4.466842e-05, 1.095900e-01, 1.037584e-07, 3.782401e-08 +4.366400e+07, 4.530467e-05, 1.109182e-01, 1.023207e-07, 3.729989e-08 +4.426903e+07, 4.594485e-05, 1.122531e-01, 1.009223e-07, 3.679010e-08 +4.487407e+07, 4.658902e-05, 1.135948e-01, 9.956152e-08, 3.629406e-08 +4.547911e+07, 4.723722e-05, 1.149431e-01, 9.823699e-08, 3.581122e-08 +4.608415e+07, 4.788951e-05, 1.162982e-01, 9.694724e-08, 3.534106e-08 +4.668918e+07, 4.854596e-05, 1.176599e-01, 9.569092e-08, 3.488308e-08 +4.729422e+07, 4.920661e-05, 1.190283e-01, 9.446674e-08, 3.443682e-08 +4.789926e+07, 4.987153e-05, 1.204034e-01, 9.327349e-08, 3.400183e-08 +4.850429e+07, 5.054078e-05, 1.217850e-01, 9.211000e-08, 3.357770e-08 +4.910933e+07, 5.121442e-05, 1.231732e-01, 9.097519e-08, 3.316401e-08 +4.971437e+07, 5.189252e-05, 1.245680e-01, 8.986800e-08, 3.276040e-08 +5.031941e+07, 5.257515e-05, 1.259692e-01, 8.878743e-08, 3.236649e-08 +5.092444e+07, 5.326237e-05, 1.273768e-01, 8.773254e-08, 3.198194e-08 +5.152948e+07, 5.395426e-05, 1.287908e-01, 8.670242e-08, 3.160642e-08 +5.213452e+07, 5.465088e-05, 1.302111e-01, 8.569621e-08, 3.123962e-08 +5.273955e+07, 5.535231e-05, 1.316377e-01, 8.471309e-08, 3.088123e-08 +5.334459e+07, 5.605863e-05, 1.330705e-01, 8.375227e-08, 3.053098e-08 +5.394963e+07, 5.676990e-05, 1.345095e-01, 8.281300e-08, 3.018858e-08 +5.455467e+07, 5.748621e-05, 1.359545e-01, 8.189457e-08, 2.985377e-08 +5.515970e+07, 5.820764e-05, 1.374056e-01, 8.099628e-08, 2.952631e-08 +5.576474e+07, 5.893426e-05, 1.388626e-01, 8.011749e-08, 2.920595e-08 +5.636978e+07, 5.966616e-05, 1.403255e-01, 7.925756e-08, 2.889248e-08 +5.697481e+07, 6.040342e-05, 1.417942e-01, 7.841589e-08, 2.858566e-08 +5.757985e+07, 6.114613e-05, 1.432686e-01, 7.759191e-08, 2.828528e-08 +5.818489e+07, 6.189438e-05, 1.447488e-01, 7.678507e-08, 2.799116e-08 +5.878993e+07, 6.264824e-05, 1.462346e-01, 7.599484e-08, 2.770309e-08 +5.939496e+07, 6.340781e-05, 1.477259e-01, 7.522070e-08, 2.742088e-08 +6.000000e+07, 6.417319e-05, 1.492226e-01, 7.446218e-08, 2.714437e-08 diff --git a/test/data/HighPressureTest.csv b/test/data/HighPressureTest.csv new file mode 100644 index 0000000000..afbf33cdbd --- /dev/null +++ b/test/data/HighPressureTest.csv @@ -0,0 +1,100 @@ +1.013250e+05, 1.442875e-05, 3.739638e-02, 4.409307e-05, 1.607365e-05 +7.063621e+05, 1.449119e-05, 3.838306e-02, 6.324986e-06, 2.305705e-06 +1.311399e+06, 1.457793e-05, 3.918746e-02, 3.406843e-06, 1.241927e-06 +1.916436e+06, 1.468156e-05, 3.994860e-02, 2.331270e-06, 8.498390e-07 +2.521473e+06, 1.479968e-05, 4.069512e-02, 1.771873e-06, 6.459169e-07 +3.126511e+06, 1.493108e-05, 4.143940e-02, 1.428983e-06, 5.209202e-07 +3.731548e+06, 1.507498e-05, 4.218841e-02, 1.197286e-06, 4.364576e-07 +4.336585e+06, 1.523085e-05, 4.294667e-02, 1.030242e-06, 3.755634e-07 +4.941622e+06, 1.539823e-05, 4.371740e-02, 9.041021e-07, 3.295805e-07 +5.546659e+06, 1.557676e-05, 4.450308e-02, 8.054814e-07, 2.936294e-07 +6.151696e+06, 1.576608e-05, 4.530568e-02, 7.262600e-07, 2.647501e-07 +6.756733e+06, 1.596587e-05, 4.612680e-02, 6.612264e-07, 2.410429e-07 +7.361770e+06, 1.617578e-05, 4.696780e-02, 6.068826e-07, 2.212324e-07 +7.966808e+06, 1.639550e-05, 4.782979e-02, 5.607931e-07, 2.044310e-07 +8.571845e+06, 1.662470e-05, 4.871374e-02, 5.212100e-07, 1.900014e-07 +9.176882e+06, 1.686305e-05, 4.962041e-02, 4.868463e-07, 1.774745e-07 +9.781919e+06, 1.711020e-05, 5.055043e-02, 4.567336e-07, 1.664972e-07 +1.038696e+07, 1.736582e-05, 5.152217e-02, 4.301290e-07, 1.567988e-07 +1.099199e+07, 1.762957e-05, 5.252126e-02, 4.064532e-07, 1.481681e-07 +1.159703e+07, 1.790111e-05, 5.354049e-02, 3.852478e-07, 1.404379e-07 +1.220207e+07, 1.818009e-05, 5.458024e-02, 3.661454e-07, 1.334743e-07 +1.280710e+07, 1.846616e-05, 5.564071e-02, 3.488478e-07, 1.271687e-07 +1.341214e+07, 1.875899e-05, 5.672195e-02, 3.331109e-07, 1.214319e-07 +1.401718e+07, 1.905823e-05, 5.782386e-02, 3.187325e-07, 1.161905e-07 +1.462222e+07, 1.936355e-05, 5.894626e-02, 3.055440e-07, 1.113827e-07 +1.522725e+07, 1.967461e-05, 6.008881e-02, 2.934036e-07, 1.069571e-07 +1.583229e+07, 1.999109e-05, 6.125110e-02, 2.821911e-07, 1.028697e-07 +1.643733e+07, 2.031265e-05, 6.243265e-02, 2.718040e-07, 9.908317e-08 +1.704236e+07, 2.063900e-05, 6.363289e-02, 2.621544e-07, 9.556552e-08 +1.764740e+07, 2.096981e-05, 6.485119e-02, 2.531665e-07, 9.228908e-08 +1.825244e+07, 2.130478e-05, 6.608689e-02, 2.447745e-07, 8.922985e-08 +1.885748e+07, 2.164362e-05, 6.733928e-02, 2.369209e-07, 8.636694e-08 +1.946251e+07, 2.198604e-05, 6.860764e-02, 2.295557e-07, 8.368202e-08 +2.006755e+07, 2.233177e-05, 6.989122e-02, 2.226346e-07, 8.115901e-08 +2.067259e+07, 2.268054e-05, 7.118927e-02, 2.161186e-07, 7.878368e-08 +2.127762e+07, 2.303209e-05, 7.250103e-02, 2.099732e-07, 7.654343e-08 +2.188266e+07, 2.338616e-05, 7.382577e-02, 2.041676e-07, 7.442707e-08 +2.248770e+07, 2.374252e-05, 7.516273e-02, 1.986744e-07, 7.242459e-08 +2.309274e+07, 2.410093e-05, 7.651121e-02, 1.934691e-07, 7.052705e-08 +2.369777e+07, 2.446117e-05, 7.787050e-02, 1.885296e-07, 6.872639e-08 +2.430281e+07, 2.482303e-05, 7.923991e-02, 1.838360e-07, 6.701540e-08 +2.490785e+07, 2.518630e-05, 8.061880e-02, 1.793704e-07, 6.538752e-08 +2.551288e+07, 2.555078e-05, 8.200652e-02, 1.751166e-07, 6.383686e-08 +2.611792e+07, 2.591630e-05, 8.340248e-02, 1.710600e-07, 6.235804e-08 +2.672296e+07, 2.628267e-05, 8.480609e-02, 1.671870e-07, 6.094619e-08 +2.732800e+07, 2.664971e-05, 8.621680e-02, 1.634855e-07, 5.959685e-08 +2.793303e+07, 2.701728e-05, 8.763408e-02, 1.599444e-07, 5.830597e-08 +2.853807e+07, 2.738522e-05, 8.905744e-02, 1.565534e-07, 5.706982e-08 +2.914311e+07, 2.775337e-05, 9.048640e-02, 1.533032e-07, 5.588500e-08 +2.974814e+07, 2.812161e-05, 9.192052e-02, 1.501852e-07, 5.474837e-08 +3.035318e+07, 2.848980e-05, 9.335938e-02, 1.471915e-07, 5.365706e-08 +3.095822e+07, 2.885782e-05, 9.480256e-02, 1.443149e-07, 5.260840e-08 +3.156326e+07, 2.922556e-05, 9.624970e-02, 1.415485e-07, 5.159995e-08 +3.216829e+07, 2.959289e-05, 9.770043e-02, 1.388862e-07, 5.062943e-08 +3.277333e+07, 2.995973e-05, 9.915443e-02, 1.363222e-07, 4.969475e-08 +3.337837e+07, 3.032596e-05, 1.006114e-01, 1.338511e-07, 4.879395e-08 +3.398340e+07, 3.069151e-05, 1.020710e-01, 1.314680e-07, 4.792523e-08 +3.458844e+07, 3.105629e-05, 1.035329e-01, 1.291683e-07, 4.708690e-08 +3.519348e+07, 3.142021e-05, 1.049970e-01, 1.269477e-07, 4.627739e-08 +3.579852e+07, 3.178320e-05, 1.064629e-01, 1.248021e-07, 4.549525e-08 +3.640355e+07, 3.214519e-05, 1.079305e-01, 1.227279e-07, 4.473911e-08 +3.700859e+07, 3.250612e-05, 1.093994e-01, 1.207215e-07, 4.400769e-08 +3.761363e+07, 3.286592e-05, 1.108695e-01, 1.187796e-07, 4.329980e-08 +3.821866e+07, 3.322454e-05, 1.123407e-01, 1.168992e-07, 4.261432e-08 +3.882370e+07, 3.358193e-05, 1.138126e-01, 1.150774e-07, 4.195021e-08 +3.942874e+07, 3.393803e-05, 1.152860e-01, 1.133115e-07, 4.130648e-08 +4.003378e+07, 3.429281e-05, 1.167624e-01, 1.115990e-07, 4.068221e-08 +4.063881e+07, 3.464623e-05, 1.182393e-01, 1.099375e-07, 4.007653e-08 +4.124385e+07, 3.499824e-05, 1.197165e-01, 1.083248e-07, 3.948861e-08 +4.184889e+07, 3.534881e-05, 1.211938e-01, 1.067587e-07, 3.891770e-08 +4.245392e+07, 3.569790e-05, 1.226712e-01, 1.052372e-07, 3.836306e-08 +4.305896e+07, 3.604551e-05, 1.241485e-01, 1.037584e-07, 3.782401e-08 +4.366400e+07, 3.639158e-05, 1.256256e-01, 1.023207e-07, 3.729989e-08 +4.426903e+07, 3.673611e-05, 1.271024e-01, 1.009223e-07, 3.679010e-08 +4.487407e+07, 3.707907e-05, 1.285788e-01, 9.956152e-08, 3.629406e-08 +4.547911e+07, 3.742045e-05, 1.300546e-01, 9.823699e-08, 3.581122e-08 +4.608415e+07, 3.776022e-05, 1.315299e-01, 9.694724e-08, 3.534106e-08 +4.668918e+07, 3.809837e-05, 1.330044e-01, 9.569092e-08, 3.488308e-08 +4.729422e+07, 3.843490e-05, 1.344782e-01, 9.446674e-08, 3.443682e-08 +4.789926e+07, 3.876979e-05, 1.359511e-01, 9.327349e-08, 3.400183e-08 +4.850429e+07, 3.910302e-05, 1.374231e-01, 9.211000e-08, 3.357770e-08 +4.910933e+07, 3.943461e-05, 1.388941e-01, 9.097519e-08, 3.316401e-08 +4.971437e+07, 3.976453e-05, 1.403641e-01, 8.986800e-08, 3.276040e-08 +5.031941e+07, 4.009278e-05, 1.418329e-01, 8.878743e-08, 3.236649e-08 +5.092444e+07, 4.041937e-05, 1.433005e-01, 8.773254e-08, 3.198194e-08 +5.152948e+07, 4.074429e-05, 1.447668e-01, 8.670242e-08, 3.160642e-08 +5.213452e+07, 4.106754e-05, 1.462319e-01, 8.569621e-08, 3.123962e-08 +5.273955e+07, 4.138912e-05, 1.476956e-01, 8.471309e-08, 3.088123e-08 +5.334459e+07, 4.170903e-05, 1.491579e-01, 8.375227e-08, 3.053098e-08 +5.394963e+07, 4.202727e-05, 1.506188e-01, 8.281300e-08, 3.018858e-08 +5.455467e+07, 4.234386e-05, 1.520782e-01, 8.189457e-08, 2.985377e-08 +5.515970e+07, 4.265878e-05, 1.535360e-01, 8.099628e-08, 2.952631e-08 +5.576474e+07, 4.297206e-05, 1.549923e-01, 8.011749e-08, 2.920595e-08 +5.636978e+07, 4.328368e-05, 1.564470e-01, 7.925756e-08, 2.889248e-08 +5.697481e+07, 4.359367e-05, 1.579001e-01, 7.841589e-08, 2.858566e-08 +5.757985e+07, 4.390203e-05, 1.593515e-01, 7.759191e-08, 2.828528e-08 +5.818489e+07, 4.420875e-05, 1.608011e-01, 7.678507e-08, 2.799116e-08 +5.878993e+07, 4.451387e-05, 1.622491e-01, 7.599484e-08, 2.770309e-08 +5.939496e+07, 4.481737e-05, 1.636953e-01, 7.522070e-08, 2.742088e-08 +6.000000e+07, 4.511927e-05, 1.651397e-01, 7.446218e-08, 2.714437e-08 diff --git a/test/python/conftest.py b/test/python/conftest.py index 9453760d56..2110f4be5d 100644 --- a/test/python/conftest.py +++ b/test/python/conftest.py @@ -21,7 +21,7 @@ def pytest_addoption(parser): "--save-reference", action="store", default=None, help="Save the reference output files for specific tests. " "Options: diffusion, counterflow_premixed, counterflow_premixed_nonideal, " - "combustor, wall" + "combustor, wall, high_pressure_transport, high_pressure_chung_transport" ) def pytest_configure(config): diff --git a/test/python/test_transport.py b/test/python/test_transport.py index 8ea0192627..a886f00081 100644 --- a/test/python/test_transport.py +++ b/test/python/test_transport.py @@ -4,7 +4,9 @@ from pytest import approx import cantera as ct - +from .utilities import ( + compareProfiles +) class TestTransport: @@ -541,28 +543,15 @@ def test_set_customary_units(self, gas): assert tr1.quadrupole_polarizability == approx(tr2.quadrupole_polarizability) class TestHighPressureGasTransport(): - def test_acentric_factor_from_critical_properties(self, test_data_path): - """ - The acentric factor should be obtained from the critical-properties.yaml - file given the input file that lacks the acentric-factor field, as would - be the case when the cubic equation of state parameters are provided - directly. - """ - - # Missing acentric factor - state = 370.8, 174.8e5, 'CH4:0.755, CO2:0.245' - gas = ct.Solution(test_data_path / 'methane_co2_noAcentricFactor.yaml') - gas.transport_model = 'high-pressure-Chung' - gas.TPX = state - thermal_conductivity_1 = gas.thermal_conductivity - - # Has acentric factor - gas = ct.Solution(test_data_path / 'methane_co2.yaml') - gas.transport_model = 'high-pressure-Chung' - gas.TPX = state - thermal_conductivity_2 = gas.thermal_conductivity - - assert thermal_conductivity_1 == pytest.approx(thermal_conductivity_2, 1e-6) + """ + Note: to re-create the reference file: + (1) Set PYTHONPATH to build/python. + (2) Go into test/python directory and run: + pytest --save-reference=high_pressure_transport test_transport.py::TestHighPressureGasTransport::test_high_pressure_transport + pytest --save-reference=high_pressure_chung_transport test_transport.py::TestHighPressureGasTransport::test_high_pressure_chung_transport + (3) Compare the reference files created in the current working directory with + the ones in test/data and replace them if needed. + """ def test_failure_for_species_with_no_properties(self, test_data_path): """ @@ -580,3 +569,90 @@ def test_failure_for_species_with_no_properties(self, test_data_path): with pytest.raises(ct.CanteraError, match="must have critical properties defined"): gas.transport_model = 'high-pressure' + + def test_high_pressure_transport(self, request, test_data_path): + """ + This test compares the viscosity and thermal conductivities of a mixture of + CH4 and CO2 over a range of pressures using the high-pressure transport + model and compares the results to a reference file. This is a regression test. + """ + referenceFile = "HighPressureTest.csv" + + phasedef = """ + phases: + - name: methane_co2 + species: + - gri30.yaml/species: [CH4, CO2] + thermo: Peng-Robinson + transport: mixture-averaged + state: {T: 300, P: 1 atm} + """ + gas = ct.Solution(yaml=phasedef) + gas.transport_model = 'high-pressure' + + pressures = np.linspace(101325, 6e7, 100) + # Collect viscosities and thermal conductivities + viscosities = [] + thermal_conductivities = [] + diffusion_coefficients = [] + for pressure in pressures: + gas.TPX = 350, pressure, 'CH4:0.755, CO2:0.245' + viscosities.append(gas.viscosity) + thermal_conductivities.append(gas.thermal_conductivity) + diffusion_coefficients.append(gas.mix_diff_coeffs) + + data = np.empty((len(viscosities), 3+ len(diffusion_coefficients[0]))) + data[:,0] = pressures + data[:,1] = viscosities + data[:,2] = thermal_conductivities + for i in range(len(diffusion_coefficients[0])): + data[:,3+i] = [d[i] for d in diffusion_coefficients] + + saveReference = request.config.getoption("--save-reference") + if saveReference == 'high_pressure_transport': + np.savetxt(referenceFile, data, '%11.6e', ', ') + else: + bad = compareProfiles(test_data_path / referenceFile, data, + rtol=1e-2, atol=1e-8, xtol=1e-2) + assert not bad, bad + + def test_high_pressure_chung_transport(self, request, test_data_path): + referenceFile = "HighPressureChungTest.csv" + + phasedef = """ + phases: + - name: methane_co2 + species: + - gri30.yaml/species: [CH4, CO2] + thermo: Peng-Robinson + transport: mixture-averaged + state: {T: 300, P: 1 atm} + """ + gas = ct.Solution(yaml=phasedef) + gas.transport_model = 'high-pressure-Chung' + + pressures = np.linspace(101325, 6e7, 100) + # Collect viscosities and thermal conductivities + viscosities = [] + thermal_conductivities = [] + diffusion_coefficients = [] + for pressure in pressures: + gas.TPX = 350, pressure, 'CH4:0.755, CO2:0.245' + viscosities.append(gas.viscosity) + thermal_conductivities.append(gas.thermal_conductivity) + diffusion_coefficients.append(gas.mix_diff_coeffs) + + data = np.empty((len(viscosities), 3+len(diffusion_coefficients[0]))) + data[:,0] = pressures + data[:,1] = viscosities + data[:,2] = thermal_conductivities + for i in range(len(diffusion_coefficients[0])): + data[:,3+i] = [d[i] for d in diffusion_coefficients] + + saveReference = request.config.getoption("--save-reference") + if saveReference == 'high_pressure_chung_transport': + np.savetxt(referenceFile, data, '%11.6e', ', ') + else: + bad = compareProfiles(test_data_path / referenceFile, data, + rtol=1e-2, atol=1e-8, xtol=1e-2) + assert not bad, bad From 29cbbc6bd9585427622ceff9e6cfcde8659dee00 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Mon, 4 Nov 2024 18:06:54 -0500 Subject: [PATCH 36/37] [transport] fixing formatting & removing unused files --- data/critical-properties.yaml | 2 +- data/methane_co2.yaml | 61 ------------------- .../transport/HighPressureGasTransport.h | 6 +- test/data/methane_co2_noAcentricFactor.yaml | 55 ----------------- 4 files changed, 4 insertions(+), 120 deletions(-) delete mode 100644 data/methane_co2.yaml delete mode 100644 test/data/methane_co2_noAcentricFactor.yaml diff --git a/data/critical-properties.yaml b/data/critical-properties.yaml index 854f41bfa0..024628710b 100644 --- a/data/critical-properties.yaml +++ b/data/critical-properties.yaml @@ -6305,4 +6305,4 @@ species: critical-compressibility: 0.303 acentric-factor: -0.217 source: |- - Properties of Gases and Liquids, 5th edition, Poling. \ No newline at end of file + Properties of Gases and Liquids, 5th edition, Poling. diff --git a/data/methane_co2.yaml b/data/methane_co2.yaml deleted file mode 100644 index 0c493a965f..0000000000 --- a/data/methane_co2.yaml +++ /dev/null @@ -1,61 +0,0 @@ -units: {length: cm, quantity: mol, activation-energy: cal/mol} - -phases: -- name: methane_co2 - species: [CH4, CO2] - thermo: Peng-Robinson - kinetics: gas - transport: mixture-averaged - reactions: none - state: - T: 300 - P: 1 atm -species: -- name: CH4 - composition: {C: 1, H: 4} - thermo: - model: NASA7 - temperature-ranges: [200.0, 1000.0, 3500.0] - data: - - [5.14987613, -0.0136709788, 4.91800599e-05, -4.84743026e-08, 1.66693956e-11, - -1.02466476e+04, -4.64130376] - - [0.074851495, 0.0133909467, -5.73285809e-06, 1.22292535e-09, -1.0181523e-13, - -9468.34459, 18.437318] - note: L8/88 - transport: - model: gas - geometry: nonlinear - well-depth: 141.4 - diameter: 3.746 - polarizability: 2.6 - rotational-relaxation: 13.0 - critical-parameters: - critical-temperature: 190.7 - critical-pressure: 4.63e+06 - critical-molar-volume: 0.0989 - critical-compressibility: 0.288 - acentric-factor: 0.011 -- name: CO2 - composition: {C: 1, O: 2} - thermo: - model: NASA7 - temperature-ranges: [200.0, 1000.0, 3500.0] - data: - - [2.35677352, 8.98459677e-03, -7.12356269e-06, 2.45919022e-09, -1.43699548e-13, - -4.83719697e+04, 9.90105222] - - [3.85746029, 4.41437026e-03, -2.21481404e-06, 5.23490188e-10, -4.72084164e-14, - -4.8759166e+04, 2.27163806] - note: L7/88 - transport: - model: gas - geometry: linear - well-depth: 244.0 - diameter: 3.763 - polarizability: 2.65 - rotational-relaxation: 2.1 - critical-parameters: - critical-temperature: 304.2 - critical-pressure: 7.39e+06 - critical-molar-volume: 0.0948 - critical-compressibility: 0.275 - acentric-factor: 0.228 diff --git a/include/cantera/transport/HighPressureGasTransport.h b/include/cantera/transport/HighPressureGasTransport.h index 776c136c48..86403bddcd 100644 --- a/include/cantera/transport/HighPressureGasTransport.h +++ b/include/cantera/transport/HighPressureGasTransport.h @@ -388,7 +388,7 @@ class HighPressureGasTransport : public MixTransport * the acentric factor of the reference fluid, and @f$ F(T_R^i, V_R^i) @f$ is a * function of the reduced temperature and reduced volume of species i. The * function @f$ F(T_R^i, V_R^i) @f$ is defined by Equation 13 in - * @cite ely-hanley1981: + * @cite ely-hanley1981 : * * @f[ * F(T_R^i, V_R^i) = a_1 + b_1 ln(T_+^i) + (c_1 + d_1/T_+^i) (V_+^i - 0.5) @@ -396,13 +396,13 @@ class HighPressureGasTransport : public MixTransport * * Where @f$ T_+^i @f$ and @f$ V_+^i @f$ are limited values of the reduced * temperature and pressure. The limited temperature is defined by Equation 15 in - * @cite ely-hanley1981: + * @cite ely-hanley1981 : * * @f[ * T_+^i = \text{min}(2, \text{max}(T_R^i, 0.5)) * @f] * - * and the limited pressure is defined by Equation 16 in @cite ely-hanley1981: + * and the limited pressure is defined by Equation 16 in @cite ely-hanley1981 : * * @f[ * V_i^+ = \text{min}(2, \text{max}(V_R^i, 0.5)) diff --git a/test/data/methane_co2_noAcentricFactor.yaml b/test/data/methane_co2_noAcentricFactor.yaml deleted file mode 100644 index 286be47ece..0000000000 --- a/test/data/methane_co2_noAcentricFactor.yaml +++ /dev/null @@ -1,55 +0,0 @@ -units: {length: cm, quantity: mol, activation-energy: cal/mol} - -phases: -- name: methane_co2 - species: [CH4, CO2] - thermo: Peng-Robinson - kinetics: gas - transport: mixture-averaged - reactions: none - state: - T: 300 - P: 1 atm -species: -- name: CH4 - composition: {C: 1, H: 4} - thermo: - model: NASA7 - temperature-ranges: [200.0, 1000.0, 3500.0] - data: - - [5.14987613, -0.0136709788, 4.91800599e-05, -4.84743026e-08, 1.66693956e-11, - -1.02466476e+04, -4.64130376] - - [0.074851495, 0.0133909467, -5.73285809e-06, 1.22292535e-09, -1.0181523e-13, - -9468.34459, 18.437318] - note: L8/88 - transport: - model: gas - geometry: nonlinear - well-depth: 141.4 - diameter: 3.746 - polarizability: 2.6 - rotational-relaxation: 13.0 -- name: CO2 - composition: {C: 1, O: 2} - thermo: - model: NASA7 - temperature-ranges: [200.0, 1000.0, 3500.0] - data: - - [2.35677352, 8.98459677e-03, -7.12356269e-06, 2.45919022e-09, -1.43699548e-13, - -4.83719697e+04, 9.90105222] - - [3.85746029, 4.41437026e-03, -2.21481404e-06, 5.23490188e-10, -4.72084164e-14, - -4.8759166e+04, 2.27163806] - note: L7/88 - transport: - model: gas - geometry: linear - well-depth: 244.0 - diameter: 3.763 - polarizability: 2.65 - rotational-relaxation: 2.1 - critical-parameters: - critical-temperature: 304.2 - critical-pressure: 7.39e+06 - critical-molar-volume: 0.0948 - critical-compressibility: 0.275 - acentric-factor: 0.228 From c4a16cc16d385e20d029330f141214488c3ebee2 Mon Sep 17 00:00:00 2001 From: Christopher Neal Date: Thu, 7 Nov 2024 15:55:06 -0500 Subject: [PATCH 37/37] [transport] converted list to numpy array in sample --- samples/python/transport/high_pressure_transport.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/python/transport/high_pressure_transport.py b/samples/python/transport/high_pressure_transport.py index 572c936de0..5b2fb656a7 100644 --- a/samples/python/transport/high_pressure_transport.py +++ b/samples/python/transport/high_pressure_transport.py @@ -18,13 +18,13 @@ # Nist data for Methane at 350 K. -nist_pressures = [ +nist_pressures = np.array([ 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26., 27., 28., 29., 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51., 52., 53., 54., 55., - 56., 57., 58., 59., 60.] + 56., 57., 58., 59., 60.]) -nist_viscosities = [ +nist_viscosities = np.array([ 1.3460e-05, 1.3660e-05, 1.3875e-05, 1.4106e-05, 1.4352e-05, 1.4613e-05, 1.4889e-05, 1.5179e-05, 1.5482e-05, 1.5798e-05, 1.6125e-05, 1.6463e-05, 1.6811e-05, 1.7167e-05, 1.7531e-05, 1.7901e-05, 1.8276e-05, 1.8656e-05, 1.9040e-05, 1.9426e-05, 1.9813e-05, @@ -32,16 +32,16 @@ 2.2904e-05, 2.3283e-05, 2.3659e-05, 2.4032e-05, 2.4403e-05, 2.4771e-05, 2.5135e-05, 2.5497e-05, 2.5855e-05, 2.6211e-05, 2.6563e-05, 2.6913e-05, 2.7259e-05, 2.7603e-05, 2.7944e-05, 2.8281e-05, 2.8616e-05, 2.8949e-05, 2.9278e-05, 2.9605e-05, 2.9929e-05, - 3.0251e-05, 3.0571e-05, 3.0888e-05, 3.1202e-05, 3.1514e-05, 3.1824e-05, 3.2132e-05] + 3.0251e-05, 3.0571e-05, 3.0888e-05, 3.1202e-05, 3.1514e-05, 3.1824e-05, 3.2132e-05]) -nist_thermal_conductivities = [ +nist_thermal_conductivities = np.array([ 0.044665, 0.045419, 0.046217, 0.047063, 0.047954, 0.048891, 0.04987, 0.050891, 0.051949, 0.05304, 0.05416, 0.055304, 0.056466, 0.057641, 0.058824, 0.06001, 0.061194, 0.062374, 0.063546, 0.064707, 0.065855, 0.066988, 0.068106, 0.069208, 0.070293, 0.071362, 0.072415, 0.073451, 0.074472, 0.075477, 0.076469, 0.077446, 0.07841, 0.079361, 0.0803, 0.081227, 0.082143, 0.083048, 0.083944, 0.084829, 0.085705, 0.086573, 0.087431, 0.088282, 0.089124, 0.089959, 0.090787, 0.091607, - 0.092421, 0.093228, 0.094029, 0.094824, 0.095612, 0.096395, 0.097172, 0.097944] + 0.092421, 0.093228, 0.094029, 0.094824, 0.095612, 0.096395, 0.097172, 0.097944]) # Create the gas object using a subset of the gri30 mechanism for the methane-co2 # system