Added the change for the bugfix to HMWSoln to the static branch

The function getActivityConcentration in the HMWSoln object had
a bug in it that caused it to be incompatible with standardConcentration()
and getActivities(). This meant that the ROP in kinetics managers
for this object was being calculated incorrectly.

This is now fixed.
This commit is contained in:
Harry Moffat 2009-12-09 17:34:13 +00:00
parent 42f709a37f
commit 6d02467b7e
2 changed files with 162 additions and 57 deletions

View file

@ -18,7 +18,7 @@
* U.S. Government retains certain rights in this software.
*/
/*
* $Id: HMWSoln.cpp,v 1.53 2009/03/27 00:38:57 hkmoffa Exp $
* $Id: HMWSoln.cpp 306 2009-12-09 17:29:23Z hkmoffa $
*/
//@{
#ifndef MAX
@ -763,30 +763,7 @@ namespace Cantera {
* The mass density is not a function of pressure.
*/
void HMWSoln::setPressure(doublereal p) {
#ifdef DEBUG_MODE
//printf("setPressure: %g\n", p);
#endif
/*
* Store the current pressure
*/
m_Pcurrent = p;
/*
* update the standard state thermo
* -> This involves calling the water function and setting the pressure
*/
updateStandardStateThermo();
/*
* Store the internal density of the water SS.
* Note, we would have to do this for all other
* species if they had pressure dependent properties.
*/
m_densWaterSS = m_waterSS->density();
/*
* Calculate all of the other standard volumes
* -> note these are constant for now
*/
calcDensity();
setState_TP(temperature(), p);
}
void HMWSoln::calcDensity() {
@ -889,9 +866,36 @@ namespace Cantera {
* the value propagates to underlying objects.
*/
void HMWSoln::setTemperature(const doublereal temp) {
setState_TP(temp, m_Pcurrent);
}
/*
* Overwritten setTemperature(double) from State.h. This
* function sets the temperature, and makes sure that
* the value propagates to underlying objects.
*/
void HMWSoln::setState_TP(doublereal temp, doublereal pres) {
State::setTemperature(temp);
//m_waterSS->setTemperature(temp);
/*
* Store the current pressure
*/
m_Pcurrent = pres;
/*
* update the standard state thermo
* -> This involves calling the water function and setting the pressure
*/
updateStandardStateThermo();
/*
* Store the internal density of the water SS.
* Note, we would have to do this for all other
* species if they had pressure dependent properties.
*/
m_densWaterSS = m_waterSS->density();
/*
* Calculate all of the other standard volumes
* -> note these are constant for now
*/
calcDensity();
}
@ -913,10 +917,14 @@ namespace Cantera {
* reaction rate expressions within the phase.
*/
void HMWSoln::getActivityConcentrations(doublereal* c) const {
double c_solvent = standardConcentration();
double cs_solvent = standardConcentration();
getActivities(c);
for (int k = 0; k < m_kk; k++) {
c[k] *= c_solvent;
c[0] *= cs_solvent;
if (m_kk > 1) {
double cs_solute = standardConcentration(1);
for (int k = 1; k < m_kk; k++) {
c[k] *= cs_solute;
}
}
}

View file

@ -14,7 +14,7 @@
* U.S. Government retains certain rights in this software.
*/
/*
* $Id: HMWSoln.h,v 1.62 2009/03/27 00:38:57 hkmoffa Exp $
* $Id: HMWSoln.h 306 2009-12-09 17:29:23Z hkmoffa $
*/
#ifndef CT_HMWSOLN_H
@ -104,7 +104,7 @@ namespace Cantera {
* water (IAPWS 1995 formulation) is used as its standard state.
* All standard state properties for the solvent are based on
* this real model for water, and involve function calls
* to the object that handles the real water model, #WaterPropsIAPWS.
* to the object that handles the real water model, #Cantera::WaterPropsIAPWS.
*
* The standard states for solutes are on the unit molality basis.
* Therefore, in the documentation below, the normal \f$ o \f$
@ -507,7 +507,7 @@ namespace Cantera {
* \f]
*
*
* <H3> Activity of the Water Solvent </H3>
* <H3> Activity of the Water Solvent </H3>
*
* The activity for the solvent water,\f$ a_o \f$, is not independent and must be
* determined either from the Gibbs-Duhem relation or from taking the appropriate derivative
@ -1027,10 +1027,12 @@ namespace Cantera {
* this phase equal to the default concentration of the solvent at the system temperature
* and pressure multiplied by Mnaught (kg solvent / gmol solvent). The solvent
* standard concentration is just equal to its standard state concentration.
*
*
* This means that the
* kinetics operator essentially works on an generalized concentration basis (kg / m3),
* kinetics operator essentially works on an generalized concentration basis (kmol / m3),
* with units for the kinetic rate constant specified
* as if all reactants (solvent or solute) are on a concentration basis (kg /m3).
* as if all reactants (solvent or solute) are on a concentration basis (kmol /m3).
* The concentration will be modified by the activity coefficients.
*
* For example, a bulk-phase binary reaction between liquid solute species
@ -1039,39 +1041,50 @@ namespace Cantera {
* following equation for its rate of progress variable, \f$ R^1 \f$, which has
* units of kmol m-3 s-1.
*
* \f[
* R^1 = k^1 C_j^a C_k^a = k^1 (C^o_o \tilde{M}_o a_j) (C^o_o \tilde{M}_o a_k)
* \f]
*
* where
*
* \f[
* R^1 = k^1 C_j^a C_k^a = k^1 (C_o \tilde{M}_o a_j) (C_o \tilde{M}_o a_k)
* \f]
* where
* \f[
* C_j^a = C_o \tilde{M}_o a_j \quad and \quad C_k^a = C_o \tilde{M}_o a_k
* C_j^a = C^o_o \tilde{M}_o a_j \quad and \quad C_k^a = C^o_o \tilde{M}_o a_k
* \f]
*
* \f$ C_j^a \f$ is the activity concentration of species <I>j</I>, and
* \f$ C_k^a \f$ is the activity concentration of species <I>k</I>. \f$ C_o \f$
* is the concentration of water at 298 K and 1 atm. \f$ \tilde{M}_o \f$ is
* \f$ C_k^a \f$ is the activity concentration of species <I>k</I>. \f$ C^o_o \f$
* is the concentration of water at 298 K and 1 atm. \f$ \tilde{M}_o \f$
* has units of kg solvent per gmol solvent and is equal to
*
* \f[
* \tilde{M}_o = \frac{M_o}{1000}
* \f]
*
*
* \f$ a_j \f$ is
* the activity of species <I>j</I> at the current temperature and pressure
* and concentration of the liquid phase is given by the molality based
* activity coefficient multiplied by the molality of the jth species.
*
* \f[
* a_j = \gamma_j^\triangle m_j
* a_j = \gamma_j^\triangle m_j = \gamma_j^\triangle \frac{n_j}{\tilde{M}_o n_o}
* \f]
*
* \f$k^1 \f$ has units of m<SUP>3</SUP> kmol<SUP>-1</SUP> s<SUP>-1</SUP>.
*
* Therefore the generalized activity concentration of a solute species has the following form
*
* \f[
* C_j^a = C^o_o \frac{\gamma_j^\triangle n_j}{n_o}
* \f]
*
* The generalized activity concentration of the solvent has the same units, but its a simpler form
*
* \f[
* C_o^a = C^o_o a_o
* \f]
*
* The reverse rate constant can then be obtained from the law of microscopic reversibility
* and the equilibrium expression for the system.
* and the equilibrium expression for the system.
*
* \f[
* \frac{a_j a_k}{ a_l} = K^{o,1} = \exp(\frac{\mu^o_l - \mu^o_j - \mu^o_k}{R T} )
@ -1455,7 +1468,7 @@ namespace Cantera {
*/
virtual void setPressure(doublereal p);
private:
protected:
/**
* Calculate the density of the mixture using the partial
* molar volumes and mole fractions as input
@ -1532,6 +1545,16 @@ namespace Cantera {
*/
virtual void setTemperature(const doublereal temp);
//! Set the temperature (K) and pressure (Pa)
/*!
* Set the temperature and pressure.
*
* @param t Temperature (K)
* @param p Pressure (Pa)
*/
virtual void setState_TP(doublereal t, doublereal p);
/**
* The isothermal compressibility. Units: 1/Pa.
* The isothermal compressibility is defined as
@ -1577,18 +1600,31 @@ namespace Cantera {
* @{
*/
/**
* This method returns an array of generalized concentrations
* \f$ C_k\f$ that are defined such that
* \f$ a_k = C_k / C^0_k, \f$ where \f$ C^0_k \f$
//! This method returns an array of generalized activity concentrations
/*!
* The generalized activity concentrations, \f$ C_k^a\f$, are defined such that
* \f$ a_k = C^a_k / C^0_k, \f$ where \f$ C^0_k \f$
* is a standard concentration
* defined below. These generalized concentrations are used
* by kinetics manager classes to compute the forward and
* reverse rates of elementary reactions.
*
* The generalized activity concentration of a solute species has the following form
*
* \f[
* C_j^a = C^o_o \frac{\gamma_j^\triangle n_j}{n_o}
* \f]
*
* The generalized activity concentration of the solvent has the same units, but its a simpler form
*
* \f[
* C_o^a = C^o_o a_o
* \f]
*
*
* @param c Array of generalized concentrations. The
* units depend upon the implementation of the
* reaction rate expressions within the phase.
* units are kmol m-3 for both the solvent and the solute species
*/
virtual void getActivityConcentrations(doublereal* c) const;
@ -1597,12 +1633,73 @@ namespace Cantera {
* The standard concentration \f$ C^0_k \f$ used to normalize
* the activity (i.e., generalized) concentration for use
*
* For the time being, we will use the concentration of pure
* solvent at the temperature and pressure of the solution
* for the the standard concentration of all species.
* This has the effect of making mass-action reaction rates
* based on the molality of species proportional to the
* molality of the species.
* We have set the standard concentration for all solute species in
* this phase equal to the default concentration of the solvent at the system temperature
* and pressure multiplied by Mnaught (kg solvent / gmol solvent). The solvent
* standard concentration is just equal to its standard state concentration.
*
* \f[
* C_j^0 = C^o_o \tilde{M}_o \quad and C_o^0 = C^o_o
* \f]
*
* The consequence of this is that the standard concentrations have unequal units
* between the solvent and the solute. However, both the solvent and the solute
* activity concentrations will have the same units of kmol kg<SUP>-3</SUP>.
*
* This means that the
* kinetics operator essentially works on an generalized concentration basis (kmol / m3),
* with units for the kinetic rate constant specified
* as if all reactants (solvent or solute) are on a concentration basis (kmol /m3).
* The concentration will be modified by the activity coefficients.
*
* For example, a bulk-phase binary reaction between liquid solute species
* <I>j</I> and <I>k</I>, producing
* a new liquid solute species <I>l</I> would have the
* following equation for its rate of progress variable, \f$ R^1 \f$, which has
* units of kmol m-3 s-1.
*
* \f[
* R^1 = k^1 C_j^a C_k^a = k^1 (C^o_o \tilde{M}_o a_j) (C^o_o \tilde{M}_o a_k)
* \f]
*
* where
*
* \f[
* C_j^a = C^o_o \tilde{M}_o a_j \quad and \quad C_k^a = C^o_o \tilde{M}_o a_k
* \f]
*
* \f$ C_j^a \f$ is the activity concentration of species <I>j</I>, and
* \f$ C_k^a \f$ is the activity concentration of species <I>k</I>. \f$ C^o_o \f$
* is the concentration of water at 298 K and 1 atm. \f$ \tilde{M}_o \f$
* has units of kg solvent per gmol solvent and is equal to
*
* \f[
* \tilde{M}_o = \frac{M_o}{1000}
* \f]
*
* \f$ a_j \f$ is
* the activity of species <I>j</I> at the current temperature and pressure
* and concentration of the liquid phase is given by the molality based
* activity coefficient multiplied by the molality of the jth species.
*
* \f[
* a_j = \gamma_j^\triangle m_j = \gamma_j^\triangle \frac{n_j}{\tilde{M}_o n_o}
* \f]
*
* \f$k^1 \f$ has units of m<SUP>3</SUP> kmol<SUP>-1</SUP> s<SUP>-1</SUP>.
*
* Therefore the generalized activity concentration of a solute species has the following form
*
* \f[
* C_j^a = C^o_o \frac{\gamma_j^\triangle n_j}{n_o}
* \f]
*
* The generalized activity concentration of the solvent has the same units, but its a simpler form
*
* \f[
* C_o^a = C^o_o a_o
* \f]
*
*
* @param k Optional parameter indicating the species. The default
* is to assume this refers to species 0.