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"); + } } /**