diff --git a/Cantera/src/thermo/GibbsExcessVPSSTP.cpp b/Cantera/src/thermo/GibbsExcessVPSSTP.cpp index d58daaac0..6958d2b6b 100644 --- a/Cantera/src/thermo/GibbsExcessVPSSTP.cpp +++ b/Cantera/src/thermo/GibbsExcessVPSSTP.cpp @@ -62,6 +62,7 @@ namespace Cantera { moleFractions_ = b.moleFractions_; lnActCoeff_Scaled_ = b.lnActCoeff_Scaled_; + dlnActCoeffdT_Scaled_ = b.dlnActCoeffdT_Scaled_; m_pp = b.m_pp; return *this; @@ -335,6 +336,7 @@ namespace Cantera { m_kk = nSpecies(); moleFractions_.resize(m_kk); lnActCoeff_Scaled_.resize(m_kk); + dlnActCoeffdT_Scaled_.resize(m_kk); m_pp.resize(m_kk); } diff --git a/Cantera/src/thermo/GibbsExcessVPSSTP.h b/Cantera/src/thermo/GibbsExcessVPSSTP.h index e8a33cce1..75242aec8 100644 --- a/Cantera/src/thermo/GibbsExcessVPSSTP.h +++ b/Cantera/src/thermo/GibbsExcessVPSSTP.h @@ -277,10 +277,6 @@ namespace Cantera { //! based for this class and classes that derive from it) at //! the current solution temperature, pressure, and solution concentration. /*! - * All standard state properties for molality-based phases are - * evaluated consistent with the molality scale. Therefore, this function - * must return molality-based activities. - * * \f[ * a_i^\triangle = \gamma_k^{\triangle} \frac{m_k}{m^\triangle} * \f] @@ -291,7 +287,20 @@ namespace Cantera { */ virtual void getActivities(doublereal* ac) const; - + + //! Get the array of temperature derivatives of the log activity coefficients + /*! + * This function is a virtual class, but it first appears in GibbsExcessVPSSTP + * class and derived classes from GibbsExcessVPSSTP. + * + * units = 1/Kelvin + * + * @param dlnActCoeffdT Output vector of temperature derivatives of the + * log Activity Coefficients. length = m_kk + */ + virtual void getdlnActCoeffdT(doublereal *dlnActCoeffdT) const { + err("getdlnActCoeffdT"); + } //@} /// @name Partial Molar Properties of the Solution @@ -519,6 +528,10 @@ namespace Cantera { //! species, divided by RT mutable std::vector lnActCoeff_Scaled_; + //! Storage for the current derivative values of the log of the + // activity coefficients of the species + mutable std::vector dlnActCoeffdT_Scaled_; + //! Temporary storage space that is fair game mutable std::vector m_pp; diff --git a/Cantera/src/thermo/IonsFromNeutralVPSSTP.cpp b/Cantera/src/thermo/IonsFromNeutralVPSSTP.cpp index b113a8965..b48dd7854 100644 --- a/Cantera/src/thermo/IonsFromNeutralVPSSTP.cpp +++ b/Cantera/src/thermo/IonsFromNeutralVPSSTP.cpp @@ -38,6 +38,8 @@ using namespace std; namespace Cantera { + static const double xxSmall = 1.0E-150; + /* * Default constructor. * @@ -52,19 +54,35 @@ namespace Cantera { numAnionSpecies_(0), numPassThroughSpecies_(0), neutralMoleculePhase_(0), - IOwnNThermoPhase_(true), - cationPhase_(0), - anionPhase_(0) + IOwnNThermoPhase_(true) { } - /* + + + // Construct and initialize an IonsFromNeutralVPSSTP object + // directly from an asci input file + /* * Working constructors * * The two constructors below are the normal way * the phase initializes itself. They are shells that call * the routine initThermo(), with a reference to the * XML database to get the info for the phase. - + * + * @param inputFile Name of the input file containing the phase XML data + * to set up the object + * @param id ID of the phase in the input file. Defaults to the + * empty string. + * @param neutralPhase The object takes a neutralPhase ThermoPhase + * object as input. It can either take a pointer + * to an existing object in the parameter list, + * in which case it does not own the object, or + * it can construct a neutral Phase as a slave + * object, in which case, it does own the slave + * object, for purposes of who gets to destroy + * the object. + * If this parameter is zero, then a slave + * neutral phase object is created and used. */ IonsFromNeutralVPSSTP::IonsFromNeutralVPSSTP(std::string inputFile, std::string id, ThermoPhase *neutralPhase) : @@ -77,9 +95,7 @@ namespace Cantera { numAnionSpecies_(0), numPassThroughSpecies_(0), neutralMoleculePhase_(neutralPhase), - IOwnNThermoPhase_(true), - cationPhase_(0), - anionPhase_(0) + IOwnNThermoPhase_(true) { if (neutralPhase) { IOwnNThermoPhase_ = false; @@ -98,9 +114,7 @@ namespace Cantera { numAnionSpecies_(0), numPassThroughSpecies_(0), neutralMoleculePhase_(neutralPhase), - IOwnNThermoPhase_(true), - cationPhase_(0), - anionPhase_(0) + IOwnNThermoPhase_(true) { if (neutralPhase) { IOwnNThermoPhase_ = false; @@ -126,9 +140,7 @@ namespace Cantera { numAnionSpecies_(0), numPassThroughSpecies_(0), neutralMoleculePhase_(0), - IOwnNThermoPhase_(true), - cationPhase_(0), - anionPhase_(0) + IOwnNThermoPhase_(true) { *this = operator=(b); } @@ -165,8 +177,6 @@ namespace Cantera { } IOwnNThermoPhase_ = b.IOwnNThermoPhase_; - cationPhase_ = b.cationPhase_; - anionPhase_ = b.anionPhase_; moleFractionsTmp_ = b.moleFractionsTmp_; return *this; @@ -472,6 +482,87 @@ namespace Cantera { } } + + // Returns an array of partial molar enthalpies for the species + // in the mixture. + /* + * Units (J/kmol) + * + * For this phase, the partial molar enthalpies are equal to the + * standard state enthalpies modified by the derivative of the + * molality-based activity coefficent wrt temperature + * + * \f[ + * \bar h_k(T,P) = h^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT} + * \f] + * + */ + void IonsFromNeutralVPSSTP::getPartialMolarEnthalpies(doublereal* hbar) const { + /* + * Get the nondimensional standard state enthalpies + */ + getEnthalpy_RT(hbar); + /* + * dimensionalize it. + */ + double T = temperature(); + double RT = GasConstant * T; + for (int k = 0; k < m_kk; k++) { + hbar[k] *= RT; + } + /* + * Update the activity coefficients, This also update the + * internally storred molalities. + */ + s_update_lnActCoeff(); + s_update_dlnActCoeffdT(); + double RTT = RT * T; + for (int k = 0; k < m_kk; k++) { + hbar[k] -= RTT * dlnActCoeffdT_Scaled_[k]; + } + } + + // Returns an array of partial molar entropies for the species + // in the mixture. + /* + * Units (J/kmol) + * + * For this phase, the partial molar enthalpies are equal to the + * standard state enthalpies modified by the derivative of the + * activity coefficent wrt temperature + * + * \f[ + * \bar s_k(T,P) = s^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT} + * \f] + * + */ + void IonsFromNeutralVPSSTP::getPartialMolarEntropies(doublereal* sbar) const { + double xx; + /* + * Get the nondimensional standard state entropies + */ + getEntropy_R(sbar); + double T = temperature(); + /* + * Update the activity coefficients, This also update the + * internally storred molalities. + */ + s_update_lnActCoeff(); + s_update_dlnActCoeffdT(); + + for (int k = 0; k < m_kk; k++) { + xx = fmaxx(moleFractions_[k], xxSmall); + sbar[k] += - lnActCoeff_Scaled_[k] -log(xx) - T * dlnActCoeffdT_Scaled_[k]; + } + /* + * dimensionalize it. + */ + for (int k = 0; k < m_kk; k++) { + sbar[k] *= GasConstant; + } + } + + // This is temporary. We will get rid of this void IonsFromNeutralVPSSTP::setTemperature(doublereal t) { double p = pressure(); @@ -887,7 +978,7 @@ namespace Cantera { moleFractionsTmp_.resize(m_kk); muNeutralMolecule_.resize(numNeutralMoleculeSpecies_); gammaNeutralMolecule_.resize(numNeutralMoleculeSpecies_); - + dlnActCoeffdT_NeutralMolecule_.resize(numNeutralMoleculeSpecies_); } static double factorOverlap(const std::vector& elnamesVN , @@ -1129,6 +1220,66 @@ namespace Cantera { } + + // Update the temperatture derivative of the ln activity coefficients + /* + * This function will be called to update the internally storred + * temperature derivative of the natural logarithm of the activity coefficients + */ + void IonsFromNeutralVPSSTP::s_update_dlnActCoeffdT() const { + int k, icat, jNeut; + doublereal fmij; + /* + * Get the activity coefficients of the neutral molecules + */ + GibbsExcessVPSSTP *geThermo = dynamic_cast(neutralMoleculePhase_); + if (!geThermo) { + fvo_zero_dbl_1(dlnActCoeffdT_Scaled_, m_kk); + return; + } + + geThermo->getdlnActCoeffdT(DATA_PTR(dlnActCoeffdT_NeutralMolecule_)); + + switch (ionSolnType_) { + case cIonSolnType_PASSTHROUGH: + break; + case cIonSolnType_SINGLEANION: + + // Do the cation list + for (k = 0; k < (int) cationList_.size(); k++) { + //! Get the id for the next cation + icat = cationList_[k]; + jNeut = fm_invert_ionForNeutral[icat]; + fmij = fm_neutralMolec_ions_[icat + jNeut * m_kk]; + dlnActCoeffdT_Scaled_[icat] = fmij * dlnActCoeffdT_NeutralMolecule_[jNeut]; + } + + // Do the anion list + icat = anionList_[0]; + jNeut = fm_invert_ionForNeutral[icat]; + dlnActCoeffdT_Scaled_[icat]= 0.0; + + // Do the list of neutral molecules + for (k = 0; k < numPassThroughSpecies_; k++) { + icat = passThroughList_[k]; + jNeut = fm_invert_ionForNeutral[icat]; + dlnActCoeffdT_Scaled_[icat] = dlnActCoeffdT_NeutralMolecule_[jNeut]; + } + break; + + case cIonSolnType_SINGLECATION: + throw CanteraError("IonsFromNeutralVPSSTP::s_update_lnActCoeff", "Unimplemented type"); + break; + case cIonSolnType_MULTICATIONANION: + throw CanteraError("IonsFromNeutralVPSSTP::s_update_lnActCoeff", "Unimplemented type"); + break; + default: + throw CanteraError("IonsFromNeutralVPSSTP::s_update_lnActCoeff", "Unimplemented type"); + break; + } + + } + /** * Format a summary of the mixture state for output. */ diff --git a/Cantera/src/thermo/IonsFromNeutralVPSSTP.h b/Cantera/src/thermo/IonsFromNeutralVPSSTP.h index eebfac268..66da9ddf0 100644 --- a/Cantera/src/thermo/IonsFromNeutralVPSSTP.h +++ b/Cantera/src/thermo/IonsFromNeutralVPSSTP.h @@ -5,7 +5,7 @@ * (see \ref thermoprops * and class \link Cantera::IonsFromNeutralVPSSTP IonsFromNeutralVPSSTP\endlink). * - * Header file for a derived class of ThermoPhase that handles + * Header file for a derived class of %ThermoPhase that handles * variable pressure standard state methods for calculating * thermodynamic properties that are further based upon activities * based on the molality scale. These include most of the methods for @@ -17,7 +17,7 @@ * U.S. Government retains certain rights in this software. */ /* - * $Id: PseudoBinaryVPSSTP.h,v 1.1 2009/03/03 21:08:31 hkmoffa Exp $ + * $Id: $ */ #ifndef CT_IONSFROMNEUTRALVPSSTP_H @@ -41,41 +41,37 @@ namespace Cantera { }; /*! - * PseudoBinaryVPSSTP is a derived class of ThermoPhase - * GibbsExcessVPSSTP that handles - * variable pressure standard state methods for calculating - * thermodynamic properties that are further based on - * expressing the Excess Gibbs free energy as a function of - * the mole fractions (or pseudo mole fractions) of consitituents. - * This category is the workhorse for describing molten salts, - * solid-phase mixtures of semiconductors, and mixtures of miscible - * and semi-miscible compounds. - * - * It includes - * . regular solutions - * . Margueles expansions - * . NTRL equation - * . Wilson's equation - * . UNIQUAC equation of state. - * - * This class adds additional functions onto the %ThermoPhase interface - * that handles the calculation of the excess Gibbs free energy. - * The %ThermoPhase - * class includes a member function, ThermoPhase::activityConvention() - * that indicates which convention the activities are based on. The - * default is to assume activities are based on the molar convention. - * That default is used here. - * - * All of the Excess Gibbs free energy formulations in this area employ + * The IonsFromNeutralVPSSTP is a derived class of ThermoPhase + * that handles the specification of the chemical potentials for + * ionic species, given a specification of the chemical potentials + * for the same phase expressed in terms of combinations of the + * ionic species that represent neutral molecules. It's expected + * that the neutral molecules will be represented in terms of + * an excess gibbs free energy approximation that is a derivative + * of the GbbsExcessVPSSTP object. All of the e Excess Gibbs free + * energy formulations in this area employ * symmetrical formulations. * - * This layer will massage the mole fraction vector to implement - * cation and anion based mole numbers in an optional manner + * This class is used for molten salts. + * + * This object actually employs 4 different mole fraction types. + * + * 1) There is a mole fraction associated the the cations and + * anions and neutrals from this ThermoPhase object. This + * is the normal mole fraction vector for this object. + * Note, however, it isn't the appropriate mole fraction + * vector to use even for obtaining the correct ideal + * free energies of mixing. + * 2) There is a mole fraction vector associated with the + * neutral molecule ThermoPhase object. + * 3) There is a mole fraction vector associated with the + * cation lattice. + * 4) There is a mole fraction vector associated with the + * anion lattice + * + * This object can translate between any of the four mole + * fraction representations. * - * The way that it collects the cation and anion based mole numbers - * is via holding two extra ThermoPhase objects. These - * can include standard states for salts. - * * */ class IonsFromNeutralVPSSTP : public GibbsExcessVPSSTP { @@ -84,11 +80,11 @@ namespace Cantera { /// Constructors /*! - * + * Default constructor */ IonsFromNeutralVPSSTP(); - //! Construct and initialize an HMWSoln ThermoPhase object + //! Construct and initialize an IonsFromNeutralVPSSTP object //! directly from an asci input file /*! * Working constructors @@ -102,17 +98,36 @@ namespace Cantera { * to set up the object * @param id ID of the phase in the input file. Defaults to the * empty string. + * @param neutralPhase The object takes a neutralPhase ThermoPhase + * object as input. It can either take a pointer + * to an existing object in the parameter list, + * in which case it does not own the object, or + * it can construct a neutral Phase as a slave + * object, in which case, it does own the slave + * object, for purposes of who gets to destroy + * the object. + * If this parameter is zero, then a slave + * neutral phase object is created and used. */ IonsFromNeutralVPSSTP(std::string inputFile, std::string id = "", ThermoPhase *neutralPhase = 0); - - //! Construct and initialize an HMWSoln ThermoPhase object + //! Construct and initialize an IonsFromNeutralVPSSTP object //! directly from an XML database /*! - * @param phaseRef XML phase node containing the description of the phase + * @param phaseRoot XML phase node containing the description of the phase * @param id id attribute containing the name of the phase. * (default is the empty string) + * @param neutralPhase The object takes a neutralPhase ThermoPhase + * object as input. It can either take a pointer + * to an existing object in the parameter list, + * in which case it does not own the object, or + * it can construct a neutral Phase as a slave + * object, in which case, it does own the slave + * object, for purposes of who gets to destroy + * the object. + * If this parameter is zero, then a slave + * neutral phase object is created and used. */ IonsFromNeutralVPSSTP(XML_Node& phaseRoot, std::string id = "", ThermoPhase *neutralPhase = 0); @@ -355,7 +370,40 @@ namespace Cantera { */ virtual void getChemPotentials(doublereal* mu) const; - + + //! Returns an array of partial molar enthalpies for the species + //! in the mixture. + /*! + * Units (J/kmol) + * + * For this phase, the partial molar enthalpies are equal to the + * standard state enthalpies modified by the derivative of the + * molality-based activity coefficent wrt temperature + * + * \f[ + * \bar h_k(T,P) = h^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT} + * \f] + * + */ + virtual void getPartialMolarEnthalpies(doublereal* hbar) const; + + //! Returns an array of partial molar entropies for the species + //! in the mixture. + /*! + * Units (J/kmol) + * + * For this phase, the partial molar enthalpies are equal to the + * standard state enthalpies modified by the derivative of the + * activity coefficent wrt temperature + * + * \f[ + * \bar s_k(T,P) = s^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT} + * - R \ln( \gamma_k X_k) + * - R T \frac{d \ln(\gamma_k) }{dT} + * \f] + */ + virtual void getPartialMolarEntropies(doublereal* sbar) const; + //@} /// @name Properties of the Standard State of the Species in the Solution @@ -507,7 +555,7 @@ namespace Cantera { /// To see how they are used, see files importCTML.cpp and /// ThermoFactory.cpp. - //! Initialization of a HMWSoln phase using an xml file + //! Initialization of an IonsFromNeutralVPSSTP phase using an xml file /*! * This routine is a precursor to initThermo(XML_Node*) * routine, which does most of the work. @@ -521,7 +569,7 @@ namespace Cantera { */ void constructPhaseFile(std::string inputFile, std::string id); - //! Import and initialize a HMWSoln phase + //! Import and initialize an IonsFromNeutralVPSSTP phase //! specification in an XML tree into the current object. /*! * Here we read an XML description of the phase. @@ -604,6 +652,13 @@ namespace Cantera { */ void s_update_lnActCoeff() const; + //! Update the temperatture derivative of the ln activity coefficients + /*! + * This function will be called to update the internally storred + * temperature derivative of the natural logarithm of the activity coefficients + */ + void s_update_dlnActCoeffdT() const; + private: //! Error function /*! @@ -706,19 +761,20 @@ namespace Cantera { /*! * Currently this is unimplemented and may be deleted */ - ThermoPhase *cationPhase_; + // ThermoPhase *cationPhase_; //! ThermoPhase for the anion lattice /*! * Currently this is unimplemented and may be deleted */ - ThermoPhase *anionPhase_; + //ThermoPhase *anionPhase_; //! Temporary mole fraction vector mutable std::vector moleFractionsTmp_; mutable std::vector muNeutralMolecule_; mutable std::vector gammaNeutralMolecule_; + mutable std::vector dlnActCoeffdT_NeutralMolecule_; private: diff --git a/Cantera/src/thermo/MargulesVPSSTP.cpp b/Cantera/src/thermo/MargulesVPSSTP.cpp index 37ca850da..c19956c1b 100644 --- a/Cantera/src/thermo/MargulesVPSSTP.cpp +++ b/Cantera/src/thermo/MargulesVPSSTP.cpp @@ -352,6 +352,11 @@ namespace Cantera { } } + /* + * ------------ Partial Molar Properties of the Solution ------------ + */ + + void MargulesVPSSTP::getElectrochemPotentials(doublereal* mu) const { getChemPotentials(mu); @@ -386,13 +391,86 @@ namespace Cantera { } - - - + // Returns an array of partial molar enthalpies for the species + // in the mixture. /* - * ------------ Partial Molar Properties of the Solution ------------ + * Units (J/kmol) + * + * For this phase, the partial molar enthalpies are equal to the + * standard state enthalpies modified by the derivative of the + * molality-based activity coefficent wrt temperature + * + * \f[ + * \bar h_k(T,P) = h^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT} + * \f] + * */ + void MargulesVPSSTP::getPartialMolarEnthalpies(doublereal* hbar) const { + /* + * Get the nondimensional standard state enthalpies + */ + getEnthalpy_RT(hbar); + /* + * dimensionalize it. + */ + double T = temperature(); + double RT = GasConstant * T; + for (int k = 0; k < m_kk; k++) { + hbar[k] *= RT; + } + /* + * Update the activity coefficients, This also update the + * internally storred molalities. + */ + s_update_lnActCoeff(); + s_update_dlnActCoeff_dT(); + double RTT = RT * T; + for (int k = 0; k < m_kk; k++) { + hbar[k] -= RTT * dlnActCoeffdT_Scaled_[k]; + } + } + // Returns an array of partial molar entropies for the species + // in the mixture. + /* + * Units (J/kmol) + * + * For this phase, the partial molar enthalpies are equal to the + * standard state enthalpies modified by the derivative of the + * activity coefficent wrt temperature + * + * \f[ + * \bar s_k(T,P) = s^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT} + * \f] + * + */ + void MargulesVPSSTP::getPartialMolarEntropies(doublereal* sbar) const { + double xx; + /* + * Get the nondimensional standard state entropies + */ + getEntropy_R(sbar); + double T = temperature(); + /* + * Update the activity coefficients, This also update the + * internally storred molalities. + */ + s_update_lnActCoeff(); + s_update_dlnActCoeff_dT(); + + for (int k = 0; k < m_kk; k++) { + xx = fmaxx(moleFractions_[k], xxSmall); + sbar[k] += - lnActCoeff_Scaled_[k] -log(xx) - T * dlnActCoeffdT_Scaled_[k]; + } + /* + * dimensionalize it. + */ + for (int k = 0; k < m_kk; k++) { + sbar[k] *= GasConstant; + } + } + + doublereal MargulesVPSSTP::err(std::string msg) const { throw CanteraError("MargulesVPSSTP","Base class method " @@ -533,6 +611,43 @@ namespace Cantera { } } + // Update the derivative of the log of the activity coefficients wrt T + /* + * This function will be called to update the internally storred + * natural logarithm of the activity coefficients + * + * he = X_A X_B(B + C(X_A - X_B)) + */ + void MargulesVPSSTP::s_update_dlnActCoeff_dT() const { + int iA, iB; + doublereal XA, XB, h0 , h1; + doublereal T = temperature(); + + fvo_zero_dbl_1(dlnActCoeffdT_Scaled_, m_kk); + + doublereal RTT = GasConstant * T * T; + for (int i = 0; i < numBinaryInteractions_; i++) { + iA = m_pSpecies_A_ij[i]; + iB = m_pSpecies_B_ij[i]; + + XA = moleFractions_[iA]; + XB = moleFractions_[iB]; + + h0 = m_HE_b_ij[i]; + h1 = m_HE_c_ij[i]; + + dlnActCoeffdT_Scaled_[iA] += -(XB * XB * (h0 + h1 * (XB - XA))) / RTT; + dlnActCoeffdT_Scaled_[iB] += -(XA * XA * h0 + XA * XB * h1 * (2 * XA))/RTT; + } + } + + void MargulesVPSSTP::getdlnActCoeffdT(doublereal *dlnActCoeffdT) const { + s_update_dlnActCoeff_dT(); + for (int k = 0; k < m_kk; k++) { + dlnActCoeffdT[k] = dlnActCoeffdT_Scaled_[k]; + } + } + void MargulesVPSSTP::resizeNumInteractions(const int num) { numBinaryInteractions_ = num; diff --git a/Cantera/src/thermo/MargulesVPSSTP.h b/Cantera/src/thermo/MargulesVPSSTP.h index cf5f25cea..5f78c12fb 100644 --- a/Cantera/src/thermo/MargulesVPSSTP.h +++ b/Cantera/src/thermo/MargulesVPSSTP.h @@ -524,6 +524,39 @@ namespace Cantera { */ virtual void getChemPotentials(doublereal* mu) const; + + //! Returns an array of partial molar enthalpies for the species + //! in the mixture. + /*! + * Units (J/kmol) + * + * For this phase, the partial molar enthalpies are equal to the + * standard state enthalpies modified by the derivative of the + * molality-based activity coefficent wrt temperature + * + * \f[ + * \bar h_k(T,P) = h^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT} + * \f] + */ + virtual void getPartialMolarEnthalpies(doublereal* hbar) const; + + //! Returns an array of partial molar entropies for the species + //! in the mixture. + /*! + * Units (J/kmol) + * + * For this phase, the partial molar enthalpies are equal to the + * standard state enthalpies modified by the derivative of the + * activity coefficent wrt temperature + * + * \f[ + * \bar s_k(T,P) = s^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT} + * - R \ln( \gamma_k X_k) + * - R T \frac{d \ln(\gamma_k) }{dT} + * \f] + */ + virtual void getPartialMolarEntropies(doublereal* sbar) const; + //! Get the species electrochemical potentials. /*! @@ -539,6 +572,19 @@ namespace Cantera { void getElectrochemPotentials(doublereal* mu) const; + //! Get the array of temperature derivatives of the log activity coefficients + /*! + * This function is a virtual class, but it first appears in GibbsExcessVPSSTP + * class and derived classes from GibbsExcessVPSSTP. + * + * units = 1/Kelvin + * + * @param dlnActCoeffdT Output vector of temperature derivatives of the + * log Activity Coefficients. length = m_kk + */ + virtual void getdlnActCoeffdT(doublereal *dlnActCoeffdT) const; + + //@} /// @name Properties of the Standard State of the Species in the Solution //@{ @@ -665,6 +711,14 @@ namespace Cantera { */ void s_update_lnActCoeff() const; + // Update the derivative of the log of the activity coefficients wrt T + /* + * This function will be called to update the internally storred + * natural logarithm of the activity coefficients + * + */ + void s_update_dlnActCoeff_dT() const; + private: //! Error function diff --git a/Cantera/src/thermo/ThermoFactory.cpp b/Cantera/src/thermo/ThermoFactory.cpp index e446ae62f..85ae9aacf 100644 --- a/Cantera/src/thermo/ThermoFactory.cpp +++ b/Cantera/src/thermo/ThermoFactory.cpp @@ -681,7 +681,10 @@ namespace Cantera { int m, nel = th.nElements(); vector_fp ecomp(nel, 0.0); for (m = 0; m < nel; m++) { - ecomp[m] = atoi(comp[th.elementName(m)].c_str()); + const char *es = comp[th.elementName(m)].c_str(); + if (strlen(es) > 0) { + ecomp[m] = atofCheck(es); + } }