From c391bae70392283fbde88bd05571b9ee95f42764 Mon Sep 17 00:00:00 2001 From: Harry Moffat Date: Thu, 17 May 2007 15:02:56 +0000 Subject: [PATCH] Added several missing thermodynamics routines to SurfPhase object. Added error checking to make sure that a ThermoPhase object has at least one species defined in it. Currently, it just won't work if there are 0 species in the object, so we might as well throw an error early to indicate this. Added error checking to the SurfPhase object to indicate when setCoverages is called with no coverages specified. This condition had caused NaN's. Now, it throws a CanteraError. --- Cantera/src/thermo/SurfPhase.cpp | 95 ++++++++++++++++++++++++------ Cantera/src/thermo/SurfPhase.h | 69 +++++++++++++++++++++- Cantera/src/thermo/ThermoPhase.cpp | 6 +- 3 files changed, 148 insertions(+), 22 deletions(-) diff --git a/Cantera/src/thermo/SurfPhase.cpp b/Cantera/src/thermo/SurfPhase.cpp index 938be29f6..dd4718d4d 100644 --- a/Cantera/src/thermo/SurfPhase.cpp +++ b/Cantera/src/thermo/SurfPhase.cpp @@ -75,6 +75,10 @@ namespace Cantera { doublereal SurfPhase:: intEnergy_mole() const { return enthalpy_mole(); } + void SurfPhase::getPartialMolarVolumes(doublereal* vbar) const { + getStandardVolumes(vbar); + } + void SurfPhase:: getStandardChemPotentials(doublereal* mu0) const { _updateThermo(); @@ -88,7 +92,8 @@ namespace Cantera { int k; getActivityConcentrations(DATA_PTR(m_work)); for (k = 0; k < m_kk; k++) { - mu[k] += GasConstant * temperature() * (log(m_work[k]) - logStandardConc(k)); + mu[k] += GasConstant * temperature() * + (log(m_work[k]) - logStandardConc(k)); } } @@ -122,7 +127,14 @@ namespace Cantera { } m_logn0 = log(m_n0); } - + + void SurfPhase:: + getGibbs_RT(doublereal* grt) const { + _updateThermo(); + double rrt = 1.0/(GasConstant*temperature()); + scale(m_mu0.begin(), m_mu0.end(), grt, rrt); + } + void SurfPhase:: getEnthalpy_RT(doublereal* hrt) const { _updateThermo(); @@ -137,22 +149,56 @@ namespace Cantera { scale(m_s0.begin(), m_s0.end(), sr, rr); } + void SurfPhase:: + getCp_R(doublereal* cpr) const { + _updateThermo(); + double rr = 1.0/GasConstant; + scale(m_cp0.begin(), m_cp0.end(), cpr, rr); + } + + void SurfPhase:: + getStandardVolumes(doublereal* vol) const { + _updateThermo(); + for (int k = 0; k < m_kk; k++) { + vol[k] = 1.0/standardConcentration(k); + } + } + void SurfPhase:: - initThermo() { - m_h0.resize(m_kk); - m_s0.resize(m_kk); - m_cp0.resize(m_kk); - m_mu0.resize(m_kk); - m_work.resize(m_kk); - m_pe.resize(m_kk, 0.0); - vector_fp cov(m_kk, 0.0); - cov[0] = 1.0; - setCoverages(DATA_PTR(cov)); - m_logsize.resize(m_kk); - for (int k = 0; k < m_kk; k++) - m_logsize[k] = log(size(k)); + getGibbs_RT_ref(doublereal* grt) const { + getGibbs_RT(grt); } + void SurfPhase:: + getEnthalpy_RT_ref(doublereal* hrt) const { + getEnthalpy_RT(hrt); + } + + void SurfPhase:: + getEntropy_R_ref(doublereal* sr) const { + getEntropy_R(sr); + } + + void SurfPhase:: + initThermo() { + if (m_kk <= 0) { + throw CanteraError("SurfPhase::initThermo", + "Number of species is less than or equal to zero"); + } + m_h0.resize(m_kk); + m_s0.resize(m_kk); + m_cp0.resize(m_kk); + m_mu0.resize(m_kk); + m_work.resize(m_kk); + m_pe.resize(m_kk, 0.0); + vector_fp cov(m_kk, 0.0); + cov[0] = 1.0; + setCoverages(DATA_PTR(cov)); + m_logsize.resize(m_kk); + for (int k = 0; k < m_kk; k++) + m_logsize[k] = log(size(k)); + } + void SurfPhase:: setPotentialEnergy(int k, doublereal pe) { m_pe[k] = pe; @@ -188,8 +234,13 @@ namespace Cantera { setCoverages(const doublereal* theta) { double sum = 0.0; int k; - for (k = 0; k < m_kk; k++) sum += theta[k]; - + for (k = 0; k < m_kk; k++) { + sum += theta[k]; + } + if (sum <= 0.0) { + throw CanteraError("SurfPhase::setCoverages", + "Sum of Coverage fractions is zero or negative"); + } for (k = 0; k < m_kk; k++) { m_work[k] = m_n0*theta[k]/(sum*size(k)); } @@ -231,10 +282,18 @@ namespace Cantera { parseCompString(cov, cc); doublereal c; vector_fp cv(kk, 0.0); + bool ifound = false; for (k = 0; k < kk; k++) { c = cc[speciesName(k)]; - if (c > 0.0) cv[k] = c; + if (c > 0.0) { + ifound = true; + cv[k] = c; + } } + if (!ifound) { + throw CanteraError("SurfPhase::setCoveragesByName", + "Input coverages are all zero or negative"); + } setCoverages(DATA_PTR(cv)); } diff --git a/Cantera/src/thermo/SurfPhase.h b/Cantera/src/thermo/SurfPhase.h index b93a04ab4..7afed2142 100644 --- a/Cantera/src/thermo/SurfPhase.h +++ b/Cantera/src/thermo/SurfPhase.h @@ -1,6 +1,7 @@ /** * @file SurfPhase.h - * Header for a simple thermoydnamics model of a surface phase derived from ThermoPhase, + * Header for a simple thermoydnamics model of a surface phase + * derived from ThermoPhase, * assuming an ideal solution model * (see \ref thermoprops and class \link Cantera::SurfPhase SurfPhase\endlink). */ @@ -25,7 +26,8 @@ namespace Cantera { - //! A simple thermoydnamics model for a surface phase, assuming an ideal solution model. + //! A simple thermoydnamics model for a surface phase, + //! assuming an ideal solution model. /*! * The surface consists of a grid of equivalent sites. Surface species may be defined to * occupy one or more sites. The surface species are assumed to be @@ -200,6 +202,14 @@ namespace Cantera { */ virtual doublereal intEnergy_mole() const; + //! Return an array of partial molar volumes for the + //! species in the mixture. Units: m^3/kmol. + /*! + * @param vbar Output vector of speciar partial molar volumes. + * Length = m_kk. units are m^3/kmol. + */ + virtual void getPartialMolarVolumes(doublereal* vbar) const; + //! Get the array of chemical potentials at unit activity for the //! standard state species at the current T and P of the solution. /*! @@ -230,7 +240,7 @@ namespace Cantera { * Activity concentrations are * * \f[ - * C^a_k = C^s_k = \frac{\theta_k n_0}{s_k} + * C^a_k = C^s_k = \frac{\theta_k n_0}{s_k} * \f] * * where \f$ \theta_k \f$ is the surface site fraction for species k, @@ -378,6 +388,14 @@ namespace Cantera { */ void setSiteDensity(doublereal n0); + //! Get the nondimensional Gibbs functions for the species + //! in their standard states at the current T and P of the solution. + /*! + * @param grt Output vector of nondimensional standard state gibbs free energies + * Length: m_kk. + */ + virtual void getGibbs_RT(doublereal* grt) const; + //! Get the nondimensional Enthalpy functions for the species standard states //! at their standard states at the current T and P of the solution. /*! @@ -394,6 +412,25 @@ namespace Cantera { */ void getEntropy_R(doublereal* sr) const; + //! Get the nondimensional Heat Capacities at constant + //! pressure for the species standard states + //! at the current T and P of the solution + /*! + * @param cpr Output vector of nondimensional standard state heat capacities + * Length: m_kk. + */ + virtual void getCp_R(doublereal* cpr) const; + + //! Get the molar volumes of the species standard states at the current + //! T and P of the solution. + /*! + * units = m^3 / kmol + * + * @param vol Output vector containing the standard state volumes. + * Length: m_kk. + */ + virtual void getStandardVolumes(doublereal *vol) const; + //! Return the thermodynamic pressure (Pa). /*! * This method must be overloaded in derived classes. Since the @@ -423,6 +460,32 @@ namespace Cantera { m_press = p; } + //! Returns the vector of nondimensional + //! Gibbs Free Energies of the reference state at the current temperature + //! of the solution and the reference pressure for the species. + /*! + * @param grt Output vector containing the nondimensional reference state + * Gibbs Free energies. Length: m_kk. + */ + virtual void getGibbs_RT_ref(doublereal *grt) const; + + //! Returns the vector of nondimensional + //! enthalpies of the reference state at the current temperature + //! of the solution and the reference pressure for the species. + /*! + * @param hrt Output vector of nondimensional standard state enthalpies. + * Length: m_kk. + */ + virtual void getEnthalpy_RT_ref(doublereal* hrt) const; + + //! Returns the vector of nondimensional + //! entropies of the reference state at the current temperature + //! of the solution and the reference pressure for each species. + /*! + * @param er Output vector containing the nondimensional reference state + * entropies. Length: m_kk. + */ + virtual void getEntropy_R_ref(doublereal *er) const; //------- new methods defined in this class ---------- diff --git a/Cantera/src/thermo/ThermoPhase.cpp b/Cantera/src/thermo/ThermoPhase.cpp index 9ea82e315..16ba43d2a 100644 --- a/Cantera/src/thermo/ThermoPhase.cpp +++ b/Cantera/src/thermo/ThermoPhase.cpp @@ -406,7 +406,11 @@ namespace Cantera { * @see importCTML.cpp */ void ThermoPhase::initThermo() { - + // Check to see that there is at least one species defined in the phase + if (m_kk <= 0) { + throw CanteraError("ThermoPhase::initThermo()", + "Number of species is less than or equal to zero"); + } } /**