From 4cee810c1862771d7d3f6641443b394d91d81590 Mon Sep 17 00:00:00 2001 From: John Hewson Date: Mon, 30 Nov 2009 23:21:19 +0000 Subject: [PATCH] Added member to TransportBase to allow specification of the reference velocity. This allows selection of a mass-averaged, mole-averaged or solvent specified reference velocity using the member m_velocityBasis or the methods setVelocityBasis() and getVelocityBasis(). Parsing of input needs to be added for this still. An enum has been added enum VelocityBasis { VB_MOLEAVG = -2, VB_MASSAVG = -1 }; Other values can correspond to species indices. In LiquidTransport, the Stefan Maxwell solve now checks to see what the m_velocityBasis member says the reference velocity should be and fills the matrix accordingly. To allow mass averaged we have added members m_massfracs and m_massfracs_tran. Added methods to extract the diffusion velocity in a similar manner to the diffusive fluxes. The diffusion velocity will be needed to not force the porosity/tortuosity into the Transport classes for porous flow. These methods are getSpeciesVdiff() and getSpeciesVdiffES(). --- Cantera/src/transport/LiquidTransport.cpp | 115 +++++++++++++++++++++- Cantera/src/transport/LiquidTransport.h | 78 +++++++++++++++ Cantera/src/transport/TransportBase.cpp | 5 +- Cantera/src/transport/TransportBase.h | 81 +++++++++++++++ 4 files changed, 274 insertions(+), 5 deletions(-) diff --git a/Cantera/src/transport/LiquidTransport.cpp b/Cantera/src/transport/LiquidTransport.cpp index ebf2d03c8..faa351d56 100644 --- a/Cantera/src/transport/LiquidTransport.cpp +++ b/Cantera/src/transport/LiquidTransport.cpp @@ -117,6 +117,8 @@ namespace Cantera { m_lambdaMixModel = right.m_lambdaMixModel; m_diffMixModel = right.m_diffMixModel; m_iStateMF = -1; + m_massfracs = right.m_massfracs; + m_massfracs_tran = right.m_massfracs_tran; m_molefracs = right.m_molefracs; m_molefracs_tran = right.m_molefracs_tran; m_concentrations = right.m_concentrations; @@ -267,6 +269,8 @@ namespace Cantera { m_mode = tr.mode_; + m_massfracs.resize(m_nsp); + m_massfracs_tran.resize(m_nsp); m_molefracs.resize(m_nsp); m_molefracs_tran.resize(m_nsp); m_concentrations.resize(m_nsp); @@ -510,6 +514,48 @@ namespace Cantera { } } + /** + * @param ndim The number of spatial dimensions (1, 2, or 3). + * @param grad_T The temperature gradient (ignored in this model). + * @param ldx Leading dimension of the grad_X array. + * The diffusive mass flux of species \e k is computed from + * + * \f[ + * \vec{j}_k = -n M_k D_k \nabla X_k. + * \f] + */ + void LiquidTransport::getSpeciesVdiff(int ndim, + const doublereal* grad_T, + int ldx, const doublereal* grad_X, + int ldf, doublereal* Vdiff) { + set_Grad_T(grad_T); + set_Grad_X(grad_X); + getSpeciesVdiffExt(ldf, Vdiff); + } + + /** + * @param ndim The number of spatial dimensions (1, 2, or 3). + * @param grad_T The temperature gradient (ignored in this model). + * @param ldx Leading dimension of the grad_X array. + * The diffusive mass flux of species \e k is computed from + * + * \f[ + * \vec{j}_k = -n M_k D_k \nabla X_k. + * \f] + */ + void LiquidTransport::getSpeciesVdiffES(int ndim, + const doublereal* grad_T, + int ldx, + const doublereal* grad_X, + int ldf, + const doublereal* grad_V, + doublereal* Vdiff) { + set_Grad_T(grad_T); + set_Grad_X(grad_X); + set_Grad_V(grad_V); + getSpeciesVdiffExt(ldf, Vdiff); + } + /** * @param ndim The number of spatial dimensions (1, 2, or 3). * @param grad_T The temperature gradient (ignored in this model). @@ -552,6 +598,33 @@ namespace Cantera { getSpeciesFluxesExt(ldf, fluxes); } + /** + * @param ndim The number of spatial dimensions (1, 2, or 3). + * @param grad_T The temperature gradient (ignored in this model). + * @param ldx Leading dimension of the grad_X array. + * The diffusive mass flux of species \e k is computed from + * + * \f[ + * \vec{j}_k = -n M_k D_k \nabla X_k. + * \f] + */ + void LiquidTransport::getSpeciesVdiffExt(int ldf, doublereal* Vdiff) { + int n, k; + + update_T(); + update_C(); + + update_Grad_lnAC(); + + stefan_maxwell_solve(); + + for (n = 0; n < m_nDim; n++) { + for (k = 0; k < m_nsp; k++) { + Vdiff[n*ldf + k] = m_Vdiff(k,n); + } + } + } + /** * @param ndim The number of spatial dimensions (1, 2, or 3). * @param grad_T The temperature gradient (ignored in this model). @@ -577,7 +650,6 @@ namespace Cantera { fluxes[n*ldf + k] = m_flux(k,n); } } - /* getMixDiffCoeffs(DATA_PTR(m_spwork)); const array_fp& mw = m_thermo->molecularWeights(); @@ -716,6 +788,7 @@ namespace Cantera { int iStateNew = m_thermo->stateMFNumber(); if (iStateNew != m_iStateMF) { qReturn = false; + m_thermo->getMassFractions(DATA_PTR(m_massfracs)); m_thermo->getMoleFractions(DATA_PTR(m_molefracs)); m_thermo->getConcentrations(DATA_PTR(m_concentrations)); concTot_ = 0.0; @@ -723,6 +796,7 @@ namespace Cantera { for (int k = 0; k < m_nsp; k++) { m_molefracs[k] = fmaxx(0.0, m_molefracs[k]); m_molefracs_tran[k] = fmaxx(MIN_X, m_molefracs[k]); + m_massfracs_tran[k] = fmaxx(MIN_X, m_massfracs[k]); concTot_tran_ += m_molefracs_tran[k]; concTot_ += m_concentrations[k]; } @@ -1000,8 +1074,19 @@ namespace Cantera { switch (m_nDim) { case 1: /* 1-D approximation */ m_B(0,0) = 0.0; + //equation for the reference velocity for (j = 0; j < m_nsp; j++) { - m_A(0,j) = m_molefracs_tran[j]; + if ( m_velocityBasis == VB_MOLEAVG ) + m_A(0,j) = m_molefracs_tran[j]; + else if ( m_velocityBasis == VB_MASSAVG ) + m_A(0,j) = m_massfracs_tran[j]; + else if ( ( m_velocityBasis >= 0 ) + && ( m_velocityBasis < m_nsp ) ) + // use species number m_velocityBasis as reference velocity + if ( m_velocityBasis == j ) m_A(0,j) = 1.0; + else + throw CanteraError("LiquidTransport::stefan_maxwell_solve", + "Unknown reference velocity provided."); } for (i = 1; i < m_nsp; i++){ m_B(i,0) = m_Grad_mu[i] / (GasConstant * T); @@ -1025,8 +1110,19 @@ namespace Cantera { case 2: /* 2-D approximation */ m_B(0,0) = 0.0; m_B(0,1) = 0.0; + //equation for the reference velocity for (j = 0; j < m_nsp; j++) { - m_A(0,j) = m_molefracs_tran[j]; + if ( m_velocityBasis == VB_MOLEAVG ) + m_A(0,j) = m_molefracs_tran[j]; + else if ( m_velocityBasis == VB_MASSAVG ) + m_A(0,j) = m_massfracs_tran[j]; + else if ( ( m_velocityBasis >= 0 ) + && ( m_velocityBasis < m_nsp ) ) + // use species number m_velocityBasis as reference velocity + if ( m_velocityBasis == j ) m_A(0,j) = 1.0; + else + throw CanteraError("LiquidTransport::stefan_maxwell_solve", + "Unknown reference velocity provided."); } for (i = 1; i < m_nsp; i++){ m_B(i,0) = m_Grad_mu[i] / (GasConstant * T); @@ -1054,8 +1150,19 @@ namespace Cantera { m_B(0,0) = 0.0; m_B(0,1) = 0.0; m_B(0,2) = 0.0; + //equation for the reference velocity for (j = 0; j < m_nsp; j++) { - m_A(0,j) = m_molefracs_tran[j]; + if ( m_velocityBasis == VB_MOLEAVG ) + m_A(0,j) = m_molefracs_tran[j]; + else if ( m_velocityBasis == VB_MASSAVG ) + m_A(0,j) = m_massfracs_tran[j]; + else if ( ( m_velocityBasis >= 0 ) + && ( m_velocityBasis < m_nsp ) ) + // use species number m_velocityBasis as reference velocity + if ( m_velocityBasis == j ) m_A(0,j) = 1.0; + else + throw CanteraError("LiquidTransport::stefan_maxwell_solve", + "Unknown reference velocity provided."); } for (i = 1; i < m_nsp; i++){ m_B(i,0) = m_Grad_mu[i] / (GasConstant * T); diff --git a/Cantera/src/transport/LiquidTransport.h b/Cantera/src/transport/LiquidTransport.h index b537d56c3..177293afe 100644 --- a/Cantera/src/transport/LiquidTransport.h +++ b/Cantera/src/transport/LiquidTransport.h @@ -334,6 +334,64 @@ namespace Cantera { */ virtual void update_Grad_lnAC(); + //! Get the species diffusive velocities wrt to + //! the mass averaged velocity, + //! given the gradients in mole fraction and temperature + /*! + * Units for the returned fluxes are kg m-2 s-1. + * + * @param ndim Number of dimensions in the flux expressions + * @param grad_T Gradient of the temperature + * (length = ndim) + * @param ldx Leading dimension of the grad_X array + * (usually equal to m_nsp but not always) + * @param grad_X Gradients of the mole fraction + * Flat vector with the m_nsp in the inner loop. + * length = ldx * ndim + * @param ldf Leading dimension of the fluxes array + * (usually equal to m_nsp but not always) + * @param Vdiff Output of the diffusive velocities. + * Flat vector with the m_nsp in the inner loop. + * length = ldx * ndim + */ + virtual void getSpeciesVdiff(int ndim, + const doublereal* grad_T, + int ldx, + const doublereal* grad_X, + int ldf, + doublereal* Vdiff) ; + + //! Get the species diffusive mass fluxes wrt to + //! the mass averaged velocity, + //! given the gradients in mole fraction, temperature + //! and electrostatic potential. + /*! + * Units for the returned fluxes are kg m-2 s-1. + * + * @param ndim Number of dimensions in the flux expressions + * @param grad_T Gradient of the temperature + * (length = ndim) + * @param ldx Leading dimension of the grad_X array + * (usually equal to m_nsp but not always) + * @param grad_X Gradients of the mole fraction + * Flat vector with the m_nsp in the inner loop. + * length = ldx * ndim + * @param ldf Leading dimension of the fluxes array + * (usually equal to m_nsp but not always) + * @param grad_Phi Gradients of the electrostatic potential + * (length = ndim) + * @param fluxes Output of the diffusive mass fluxes + * Flat vector with the m_nsp in the inner loop. + * length = ldx * ndim + */ + virtual void getSpeciesVdiffES(int ndim, + const doublereal* grad_T, + int ldx, + const doublereal* grad_X, + int ldf, + const doublereal* grad_Phi, + doublereal* Vdiff) ; + /** * @param ndim The number of spatial dimensions (1, 2, or 3). * @param grad_T The temperature gradient (ignored in this model). @@ -391,6 +449,11 @@ namespace Cantera { const doublereal* grad_Phi, doublereal* fluxes); + //! Return the species diffusive velocities relative to + //! the (mass) averaged velocity. + //! See getSpeciesFluxesExt for further details. + virtual void getSpeciesVdiffExt(int ldf, doublereal* Vdiff); + //! Return the species diffusive mass fluxes wrt to //! the mass averaged velocity, /*! @@ -736,6 +799,21 @@ namespace Cantera { //! State of the mole fraction vector. int m_iStateMF; + //! Local copy of the mass fractions of the species in the phase + /*! + * The mass fraction vector comes from the ThermoPhase object. + * + * length = m_nsp + */ + vector_fp m_massfracs; + + //! Local copy of the mass fractions of the species in the phase + /** + * This version of the mass fraction vector is adjusted to a + * minimum lower bound of MIN_X for use in transport calculations. + */ + vector_fp m_massfracs_tran; + //! Local copy of the mole fractions of the species in the phase /*! * The mole fractions here are assumed to be bounded by 0.0 and 1.0 diff --git a/Cantera/src/transport/TransportBase.cpp b/Cantera/src/transport/TransportBase.cpp index f0c881907..dcd317875 100644 --- a/Cantera/src/transport/TransportBase.cpp +++ b/Cantera/src/transport/TransportBase.cpp @@ -38,7 +38,8 @@ namespace Cantera { m_ready(false), m_nmin(0), m_index(-1), - m_nDim(ndim) + m_nDim(ndim), + m_velocityBasis(VB_MASSAVG) { } @@ -49,6 +50,7 @@ namespace Cantera { m_nmin = right.m_nmin; m_index = right.m_index; m_nDim = right.m_nDim; + m_velocityBasis = right.m_velocityBasis; } @@ -61,6 +63,7 @@ namespace Cantera { m_nmin = right.m_nmin; m_index = right.m_index; m_nDim = right.m_nDim; + m_velocityBasis = right.m_velocityBasis; return *this; } diff --git a/Cantera/src/transport/TransportBase.h b/Cantera/src/transport/TransportBase.h index 1d9070555..414c82d12 100644 --- a/Cantera/src/transport/TransportBase.h +++ b/Cantera/src/transport/TransportBase.h @@ -56,6 +56,17 @@ namespace Cantera { // forward reference class XML_Writer; + /** The diffusion velocities can be referenced to a variety of things. + * Most typical is to reference to the mass averaged velocity, but + * referencing to the mole averaged velocity is suitable for some + * liquid flows and referencing to a single species is suitable for + * some solvent mixtures. This enum should provide a means to identify + * the reference velocity used for the transport model. + */ + enum VelocityBasis { + VB_MOLEAVG = -2, + VB_MASSAVG = -1 + }; /** * Base class for transport property managers. All classes that @@ -306,6 +317,69 @@ namespace Cantera { } + //! Get the species diffusive velocities wrt to + //! the mass averaged velocity, + //! given the gradients in mole fraction and temperature + /*! + * Units for the returned fluxes are kg m-2 s-1. + * + * @param ndim Number of dimensions in the flux expressions + * @param grad_T Gradient of the temperature + * (length = ndim) + * @param ldx Leading dimension of the grad_X array + * (usually equal to m_nsp but not always) + * @param grad_X Gradients of the mole fraction + * Flat vector with the m_nsp in the inner loop. + * length = ldx * ndim + * @param ldf Leading dimension of the fluxes array + * (usually equal to m_nsp but not always) + * @param Vdiff Output of the diffusive velocities. + * Flat vector with the m_nsp in the inner loop. + * length = ldx * ndim + */ + virtual void getSpeciesVdiff(int ndim, + const doublereal* grad_T, + int ldx, + const doublereal* grad_X, + int ldf, + doublereal* Vdiff) { + err("getSpeciesVdiff"); + } + + //! Get the species diffusive mass fluxes wrt to + //! the mass averaged velocity, + //! given the gradients in mole fraction, temperature + //! and electrostatic potential. + /*! + * Units for the returned fluxes are kg m-2 s-1. + * + * @param ndim Number of dimensions in the flux expressions + * @param grad_T Gradient of the temperature + * (length = ndim) + * @param ldx Leading dimension of the grad_X array + * (usually equal to m_nsp but not always) + * @param grad_X Gradients of the mole fraction + * Flat vector with the m_nsp in the inner loop. + * length = ldx * ndim + * @param ldf Leading dimension of the fluxes array + * (usually equal to m_nsp but not always) + * @param grad_Phi Gradients of the electrostatic potential + * (length = ndim) + * @param fluxes Output of the diffusive mass fluxes + * Flat vector with the m_nsp in the inner loop. + * length = ldx * ndim + */ + virtual void getSpeciesVdiffES(int ndim, + const doublereal* grad_T, + int ldx, + const doublereal* grad_X, + int ldf, + const doublereal* grad_Phi, + doublereal* Vdiff) { + getSpeciesVdiff( ndim, grad_T, ldx, grad_X, ldf, Vdiff ); + } + + //! Get the molar fluxes [kmol/m^2/s], given the thermodynamic //! state at two nearby points. /*! @@ -390,6 +464,10 @@ namespace Cantera { const doublereal* const p); + void setVelocityBasis( int ivb ) { m_velocityBasis = ivb; } + + int getVelocityBasis( ) { return m_velocityBasis; } + friend class TransportFactory; @@ -447,6 +525,9 @@ namespace Cantera { //! Number of dimensions used in flux expresions int m_nDim; + //! velocity basis from which diffusion velocities are computed. + //! Defaults to mass averaged = -2 + int m_velocityBasis; private: