[Thermo] Merge functionality of VPSSMgr into VPStandardStateTP

Remove the now-unused VPSSMgr class and descendants.
This commit is contained in:
Ray Speth 2017-02-11 15:45:56 -05:00
parent 50ed3f2e72
commit b39537bfcb
31 changed files with 214 additions and 3274 deletions

View file

@ -89,13 +89,9 @@
* class listed above. These classes assume that there exists a standard state
* for each species in the phase, where the Thermodynamic functions are specified
* as a function of temperature and pressure. Standard state objects for each
* species are all derived from the PDSS virtual base class. Calculators for these
* standard state, which coordinate the calculation for all of the species
* in a phase, are all derived from the virtual base class VPSSMgr.
* In turn, these standard states may employ reference state calculation to
* aid in their calculations. And the VPSSMgr calculators may also employ
* SimpleThermo calculators to help in calculating the properties for all of the
* species in a phase. However, there are some PDSS objects which do not employ
* species are all derived from the PDSS virtual base class. In turn, these
* standard states may employ reference state calculation to aid in their
* calculations. However, there are some PDSS objects which do not employ
* reference state calculations. An example of this is real equation of state for
* liquid water used within the calculation of brine thermodynamics.
* In general, the independent variables that completely describe the state of the
@ -497,15 +493,6 @@
* pick a manager, i.e., a derivative of the SpeciesThermo
* object, to use.
*
* If a temperature and pressure dependent standard state is needed
* then a call to VPSSMgrFactory::newVPSSMgr()
* is made in order
* pick a manager, i.e., a derivative of the VPSSMgr
* object, to use. Along with the VPSSMgr designation comes a
* determination of whether there is an accompanying SpeciesThermo
* and what type of SpeciesThermo object to use in the
* VPSSMgr calculations.
*
* Once these determinations are made, the %ThermoPhase object is
* ready to start reading in the species information, which includes
* all of the available standard state information about the
@ -524,16 +511,9 @@
* call to read the XML data from the input file and install the
* correct SpeciesThermoInterpType object into the SpeciesThermo object.
*
* Within installSpecies(), for standard states, the routine,
* SpeciesThermoFactory::installVPThermoForSpecies() is
* called. However, this is just a shell routine for calling
* the VPSSMgr's derived VPSSMgr::createInstallPDSS() routine.
* Within the VPSSMgr::createInstallPDSS() routine of the derived VPSSMgr's
* object, the XML data from the input file is read and the
* calculations for the species standard state is installed.
* Additionally, the derived PDSS object is created and installed
* into the VPStandardStateTP list containing all of the PDSS objects
* for that phase.
* Within installSpecies(), for standard states, derived PDSS object is created
* and installed into the VPStandardStateTP list containing all of the PDSS
* objects for that phase.
*
* Now that all of the species standard states are read in and
* installed into the ThermoPhase object, control once again
@ -574,9 +554,6 @@
* In general, factory routines throw specific errors when encountering
* unknown thermodynamics models in XML files. All of the error classes
* derive from the class, CanteraError.
* The newVPSSMgr() routines throws the UnknownVPSSMgr class error when
* they encounter an unknown string in the XML input file specifying the
* VPSSMgr class to use.
*
* Many of the important member functions in factory routines are
* virtual classes. This means that a user may write their own

View file

@ -72,17 +72,6 @@ public:
virtual void modifySpecies(size_t index,
shared_ptr<SpeciesThermoInterpType> spec);
//! Install a PDSS object to handle the reference state thermodynamics
//! calculation
/*!
* @param k species index
* @param PDSS_ptr Pressure dependent standard state (PDSS) object
* that will handle the reference state calc
* @param vpssmgr_ptr Pointer to the variable pressure standard state
* manager that handles the PDSS object.
*/
void installPDSShandler(size_t k, PDSS* PDSS_ptr, VPSSMgr* vpssmgr_ptr);
//! Like update(), but only updates the single species k.
/*!
* @param k species index
@ -255,10 +244,6 @@ protected:
//! indicates if data for species has been installed
std::vector<bool> m_installed;
//! Make the class VPSSMgr a friend because we need to access the function
//! provideSTIT()
friend class VPSSMgr;
};
}

View file

@ -49,14 +49,12 @@ namespace Cantera
*
* Class PDSS is the base class for a family of classes that compute properties
* of a single species in a phase at its standard states, for a range of
* temperatures and pressures.
*
* Phases which use the VPSSMGr class must have their respective ThermoPhase
* objects actually be derivatives of the VPStandardState class. These classes
* assume that there exists a standard state for each species in the phase,
* where the Thermodynamic functions are specified as a function of temperature
* and pressure. Standard state objects for each species in the phase are all
* derived from the PDSS virtual base class.
* temperatures and pressures. PDSS objects are used by derivatives of the
* VPStandardState class. These classes assume that there exists a standard
* state for each species in the phase, where the thermodynamic functions are
* specified as a function of temperature and pressure. Standard state objects
* for each species in the phase are all derived from the PDSS virtual base
* class.
*
* The following classes inherit from PDSS. Each of these classes handles just
* one species.
@ -99,16 +97,9 @@ namespace Cantera
* - This model assumes that the species follows the HKFT pressure dependent
* equation of state
*
* The choice of which VPSSMGr object to be used is either implicitly made by
* Cantera by querying the XML data file for compatibility or it may be
* explicitly requested in the XML file.
*
* Normally the PDSS object is not called directly. Instead the VPSSMgr object
* manages the calls to the PDSS object for the entire set of species that
* comprise a phase. Additionally, sometimes the VPSSMgr object will not call
* the PDSS object at all to calculate thermodynamic properties, instead relying
* on its own determination/knowledge for how to calculate thermo quantities
* quickly given what it knows about the PDSS objects under its control.
* Normally the PDSS object is not called directly. Instead the
* VPStandardStateTP object manages the calls to the PDSS object for the entire
* set of species that comprise a phase.
*
* The PDSS objects may or may not utilize the MultiSpeciesThermo reference state
* manager class to calculate the reference state thermodynamics functions in
@ -138,7 +129,6 @@ namespace Cantera
class XML_Node;
class MultiSpeciesThermo;
class VPStandardStateTP;
class VPSSMgr;
//! Virtual base class for a species with a pressure dependent standard state
/*!
@ -368,8 +358,7 @@ public:
//! Sets the pressure in the object
/*!
* Currently, this sets the pressure in the PDSS object. It is indeterminant
* what happens to the owning VPStandardStateTP object and to the VPSSMgr
* object.
* what happens to the owning VPStandardStateTP object.
*
* @param pres Pressure to be set (Pascal)
*/
@ -510,9 +499,6 @@ protected:
*/
VPStandardStateTP* m_tp;
//! Pointer to the VPSS manager for this object
VPSSMgr* m_vpssmgr_ptr;
//! Molecular Weight of the species
doublereal m_mw;

View file

@ -21,7 +21,6 @@ namespace Cantera
{
class PDSS;
class VPSSMgr;
/**
* @defgroup spthermo Species Reference-State Thermodynamic Properties
@ -280,13 +279,10 @@ class STITbyPDSS : public SpeciesThermoInterpType
public:
//! Main Constructor
/*!
* @param vpssmgr_ptr Pointer to the Variable pressure standard state
* manager that owns the PDSS object that will handle calls for this
* object
* @param PDSS_ptr Pointer to the PDSS object that handles calls for
* this object
*/
STITbyPDSS(VPSSMgr* vpssmgr_ptr, PDSS* PDSS_ptr);
explicit STITbyPDSS(PDSS* PDSS_ptr);
virtual doublereal minTemp() const;
virtual doublereal maxTemp() const;
@ -308,10 +304,6 @@ public:
doublereal* const coeffs) const;
private:
//! Pointer to the Variable pressure standard state manager that owns the
//! PDSS object that will handle calls for this object
VPSSMgr* m_vpssmgr_ptr;
//! Pointer to the PDSS object that handles calls for this object
/*!
* This object is not owned by the current one.

View file

@ -1,741 +0,0 @@
/**
* @file VPSSMgr.h
* Declaration file for a virtual base class that manages
* the calculation of standard state properties for all of the
* species in a single phase, assuming a variable P and T standard state
* (see \ref mgrpdssthermocalc and
* class \link Cantera::VPSSMgr VPSSMgr\endlink).
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#ifndef CT_VPSSMGR_H
#define CT_VPSSMGR_H
#include "cantera/base/global.h"
namespace Cantera
{
class VPStandardStateTP;
class MultiSpeciesThermo;
class PDSS;
/**
* @defgroup mgrpdssthermocalc Managers for Calculating Standard-State
* Thermodynamics
*
* To compute the thermodynamic properties of multicomponent solutions, it is
* necessary to know something about the thermodynamic properties of the
* individual species present in the solution. Exactly what sort of species
* properties are required depends on the thermodynamic model for the solution.
* For a gaseous solution (i.e., a gas mixture), the species properties required
* are usually ideal gas properties at the mixture temperature and at a
* reference pressure (almost always at 1 bar). For other types of solutions,
* however, it may not be possible to isolate the species in a "pure" state. For
* example, the thermodynamic properties of, say, Na+ and Cl- in saltwater are
* not easily determined from data on the properties of solid NaCl, or solid Na
* metal, or chlorine gas. In this case, the solvation in water is fundamental
* to the identity of the species, and some other reference state must be used.
* One common convention for liquid solutions is to use thermodynamic data for
* the solutes in the limit of infinite dilution within the pure solvent;
* another convention is to reference all properties to unit molality.
*
* In defining these standard states for species in a phase, we make the
* following definition. A reference state is a standard state of a species in a
* phase limited to one particular pressure, the reference pressure. The
* reference state specifies the dependence of all thermodynamic functions as a
* function of the temperature, in between a minimum temperature and a maximum
* temperature. The reference state also specifies the molar volume of the
* species as a function of temperature. The molar volume is a thermodynamic
* function. A full standard state does the same thing as a reference state, but
* specifies the thermodynamics functions at all pressures.
*
* Class VPSSMgr is the base class for a family of classes that compute
* properties of all species in a phase in their standard states, for a range
* of temperatures and pressures.
*
* Phases which use the VPSSMGr class must have their respective ThermoPhase
* objects actually be derivatives of the VPStandardState class. These classes
* assume that there exists a standard state for each species in the phase,
* where the Thermodynamic functions are specified as a function of
* temperature and pressure. Standard state thermo objects for each species
* in the phase are all derived from the PDSS virtual base class. Calculators
* for these standard state thermo , which coordinate the calculation for all
* of the species in a phase, are all derived from VPSSMgr. In turn, these
* standard states may employ reference state calculation to aid in their
* calculations. And the VPSSMgr calculators may also employ SimpleThermo
* calculators to help in calculating the properties for all of the species in
* a phase. However, there are some PDSS objects which do not employ reference
* state calculations. An example of this is a real equation of state for
* liquid water used within the calculation of brine thermodynamics.
*
* Typically calls to calculate standard state thermo properties are virtual
* calls at the ThermoPhase level. It is left to the child classes of
* ThermoPhase to specify how these are carried out. Usually, this will involve
* calling the m_spthermo pointer to a MultiSpeciesThermo object to calculate the
* reference state thermodynamic properties. Then, the pressure dependence is
* added in within the child ThermoPhase object to complete the specification of
* the standard state. The VPStandardStateTP class, however, redefines the calls
* to the calculation of standard state properties to use VPSSMgr class calls.
* A listing of these classes and important pointers are supplied below.
*
* - ThermoPhase
* - \link Cantera::ThermoPhase::m_spthermo m_spthermo\endlink
* This is a pointer to a MultiSpeciesThermo manager class that
* handles the reference %state Thermodynamic calculations.
* - VPStandardStateTP (inherits from ThermoPhase)
* - \link Cantera::ThermoPhase::m_spthermo m_spthermo\endlink
* MultiSpeciesThermo manager handling reference %state Thermodynamic calculations.
* may or may not be used by the VPSSMgr class. For species
* which don't have a reference state class defined, a default
* class, called STITbyPDSS which is installed into the MultiSpeciesThermo
* class, actually calculates reference state
* thermo by calling a PDSS object.
* - \link Cantera::VPStandardStateTP::m_VPSS_ptr m_VPSS_ptr\endlink
* This is a pointer to a VPSSMgr class which handles the
* standard %state thermo calculations. It may
* or may not use the pointer, m_spthermo, in its calculations.
*
* The following classes inherit from VPSSMgr. Each of these classes handle
* multiple species and by definition all of the species in a phase. It is a
* requirement that a VPSSMgr object handles all of the species in a phase.
*
* - VPSSMgr_IdealGas
* - standardState model = "IdealGas"
* - This model assumes that all species in the phase obey the
* ideal gas law for their pressure dependence. The manager
* uses a MultiSpeciesThermo object to handle the calculation of the
* reference state.
* - VPSSMgr_ConstVol
* - standardState model = "ConstVol"
* - This model assumes that all species in the phase obey the
* constant partial molar volume pressure dependence.
* The manager uses a MultiSpeciesThermo object to handle the
* calculation of the reference state.
* - VPSSMgr_Water_ConstVol
* - standardState model = "Water_ConstVol"
* - This model assumes that all species but one in the phase obey the
* constant partial molar volume pressure dependence.
* The manager uses a MultiSpeciesThermo object to handle the
* calculation of the reference state for those species.
* Species 0 is assumed to be water, and a real equation
* of state is used to model the T, P behavior.
* - VPSSMgr_Water_HKFT
* - standardState model = "Water_HKFT"
* - This model assumes that all species but one in the phase obey the
* HKFT equation of state.
* Species 0 is assumed to be water, and a real equation
* of state is used to model the T, P behavior.
* - VPSSMgr_General
* - standardState model = "General"
* - This model is completely general. Nothing is assumed at this
* level. Calls consist of loops to PDSS property evaluations.
*
* The choice of which VPSSMgr object to be used is implicitly made by %Cantera
* by querying the XML data file for compatibility. However, each of these
* VPSSMgr objects may be explicitly requested in the XML file by adding in the
* following XML node into the thermo section of the phase XML Node. For
* example, the code example listed below explicitly requests that the
* VPSSMgr_IdealGas object be used to handle the standard state thermodynamics
* calculations.
*
* @code
* <phase id="Silane_Pyrolysis" dim="3">
* . . .
* <thermo model="VPIdealGas">
* <standardState model="IdealGas"\>
* <\thermo>
* . . .
* <\phase>
* @endcode
*
* If it turns out that the VPSSMgr_IdealGas class can not handle the standard
* state calculation, then %Cantera will fail during the instantiation phase
* printing out an informative error message.
*
* In the source code listing above, the thermo model, VPIdealGas ,was
* requested. The thermo model specifies the type of ThermoPhase object to use.
* In this case the object IdealSolnGasVPSS (with the ideal gas suboption) is
* used. IdealSolnGasVPSS inherits from VPStandardStateTP, so that it actually
* has a VPSSMgr pointer to be specified. Note, in addition to the IdealGas
* entry to the model parameter in standardState node, we could have also
* specified the "General" option. The general option will always work. An
* example of this usage is listed below.
*
* @code
* <phase id="Silane_Pyrolysis" dim="3">
* . . .
* <thermo model="VPIdealGas">
* <standardState model="General"\>
* <\thermo>
* . . .
* <\phase>
* @endcode
*
* The "General" option will cause the VPSSMgr_General VPSSMgr class to be used.
* In this manager, the calculations are all handled at the PDSS object level.
* This is completely general, but, may be significantly slower.
*
* @ingroup thermoprops
*/
//! Virtual base class for the classes that manage the calculation
//! of standard state properties for all the species in a phase.
/*!
* This class defines the interface which all subclasses must implement.
*
* Class VPSSMgr is the base class for a family of classes that compute
* properties of a set of species in their standard state at a range of
* temperatures and pressures.
*
* If #m_useTmpRefStateStorage is set to true, then the following internal
* arrays, containing information about the reference arrays,
* are calculated and kept up to date at every call.
*
* - #m_h0_RT
* - #m_g0_RT
* - #m_s0_R
* - #m_cp0_R
*
* The virtual function #_updateRefStateThermo() is supplied to do this and may
* be reimplemented in child routines. A default implementation based on the
* speciesThermo class is supplied in this base class.
* #_updateStandardStateThermo() is called whenever a reference state property
* is needed.
*
* When #m_useTmpStandardStateStorage is true, then the following internal
* arrays, containing information on the standard state properties are
* calculated and kept up to date.
*
* - #m_hss_RT;
* - #m_cpss_R;
* - #m_gss_RT;
* - #m_sss_R;
* - #m_Vss
*
* The virtual function #_updateStandardStateThermo() is supplied to do this and
* must be reimplemented in child routines, when #m_useTmpStandardStateStorage
* is true. It may be optionally reimplemented in child routines if
* #m_useTmpStandardStateStorage is false. #_updateStandardStateThermo() is
* called whenever a standard state property is needed.
*
* This class is usually used for nearly incompressible phases. For those
* phases, it makes sense to change the equation of state independent variable
* from density to pressure.
*/
class VPSSMgr
{
public:
//! Constructor
/*!
* @param vptp_ptr Pointer to the Variable pressure ThermoPhase object
* @param spth Pointer to the optional MultiSpeciesThermo object
* that will handle the calculation of the reference
* state thermodynamic coefficients.
*/
VPSSMgr(VPStandardStateTP* vptp_ptr, MultiSpeciesThermo* spth = 0);
virtual ~VPSSMgr() {}
// VPSSMgr objects are not copyable or assignable
VPSSMgr(const VPSSMgr&) = delete;
VPSSMgr& operator=(const VPSSMgr&) = delete;
//! @name Properties of the Standard State of the Species in the Solution
//! @{
//!Get the array of chemical potentials at unit activity.
/*!
* These are the standard state chemical potentials \f$ \mu^0_k(T,P)
* \f$. The values are evaluated at the current temperature and pressure.
*
* @param mu Output vector of standard state chemical potentials.
* length = m_kk. units are J / kmol.
*/
virtual void getStandardChemPotentials(doublereal* mu) const;
/**
* Get the nondimensional Gibbs functions for the species at their
* standard states of solution 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 at their
* standard states at the current *T* and *P* of the solution.
*
* @param hrt Output vector of standard state enthalpies.
* length = m_kk. units are unitless.
*/
virtual void getEnthalpy_RT(doublereal* hrt) const;
//! Return a reference to a vector of the molar enthalpies of the
//! species in their standard states
const vector_fp& enthalpy_RT() const {
return m_hss_RT;
}
/**
* Get the array of nondimensional Enthalpy functions for the standard
* state species at the current *T* and *P* of the solution.
*
* @param sr Output vector of nondimensional standard state
* entropies. length = m_kk.
*/
virtual void getEntropy_R(doublereal* sr) const;
//! Return a reference to a vector of the entropies of the species
const vector_fp& entropy_R() const {
return m_sss_R;
}
//! Returns the vector of nondimensional internal Energies of the standard
//! state at the current temperature and pressure of the solution for each
//! species.
/*!
* The internal energy is calculated from the enthalpy from the
* following formula:
*
* \f[
* u^{ss}_k(T,P) = h^{ss}_k(T) - P * V^{ss}_k
* \f]
*
* @param urt Output vector of nondimensional standard state
* internal energies. length = m_kk.
*/
virtual void getIntEnergy_RT(doublereal* urt) const;
//! Get the nondimensional Heat Capacities at constant pressure for the
//! standard state of the species at the current T and P.
/*!
* This is redefined here to call the internal function,
* _updateStandardStateThermo(), which calculates all standard state
* properties at the same time.
*
* @param cpr Output vector containing the the nondimensional Heat
* Capacities at constant pressure for the standard state of
* the species. Length: m_kk.
*/
virtual void getCp_R(doublereal* cpr) const;
//! Return a reference to a vector of the constant pressure
//! heat capacities of the species
const vector_fp& cp_R() const {
return m_cpss_R;
}
//! Get the molar volumes of each species in their standard states at the
//! current *T* and *P* of the solution.
/*!
* units = m^3 / kmol
*
* This is redefined here to call the internal function,
* _updateStandardStateThermo(), which calculates all standard state
* properties at the same time.
*
* @param vol Output vector of species volumes. length = m_kk.
* units = m^3 / kmol
*/
virtual void getStandardVolumes(doublereal* vol) const;
virtual const vector_fp& getStandardVolumes() const;
//! Return a reference to a vector of the species standard molar volumes
const vector_fp& standardVolumes() const {
return m_Vss;
}
public:
//@}
/*! @name Thermodynamic Values for the Species Reference States
* There are also temporary variables for holding the species reference-
* state values of Cp, H, S, and V at the last temperature and reference
* pressure called. These functions are not recalculated if a new call is
* made using the previous temperature. All calculations are done within
* the routine _updateRefStateThermo().
*/
//@{
/*!
* 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 contains the nondimensional enthalpies of the
* reference state of the species. length = m_kk, units = dimensionless.
*/
virtual void getEnthalpy_RT_ref(doublereal* hrt) const;
/*!
* 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 contains the nondimensional Gibbs free energies
* of the reference state of the species. length = m_kk, units =
* dimensionless.
*/
virtual void getGibbs_RT_ref(doublereal* grt) const;
//! Return a reference to the vector of Gibbs free energies of the species
const vector_fp& Gibbs_RT_ref() const {
return m_g0_RT;
}
/*!
* Returns the vector of the Gibbs function of the reference state at the
* current temperature of the solution and the reference pressure for the
* species. units = J/kmol
*
* @param g Output vector contain the Gibbs free energies of the reference
* state of the species. length = m_kk, units = J/kmol.
*/
virtual void getGibbs_ref(doublereal* g) const;
/*!
* Returns the vector of nondimensional entropies of the reference state at
* the current temperature of the solution and the reference pressure for
* the species.
*
* @param er Output vector contain the nondimensional entropies of the
* species in their reference states. length: m_kk, units:
* dimensionless.
*/
virtual void getEntropy_R_ref(doublereal* er) const;
/*!
* Returns the vector of nondimensional constant pressure heat capacities of
* the reference state at the current temperature of the solution and
* reference pressure for the species.
*
* @param cpr Output vector contains the nondimensional heat capacities of
* the species in their reference states. length: m_kk, units:
* dimensionless.
*/
virtual void getCp_R_ref(doublereal* cpr) const;
//! Get the molar volumes of the species reference states at the current *T*
//! and *P_ref* of the solution.
/*!
* units = m^3 / kmol
*
* @param vol Output vector containing the standard state volumes.
* Length: m_kk.
*/
virtual void getStandardVolumes_ref(doublereal* vol) const;
//@}
/*! @name Setting the Internal State of the System
* All calls to change the internal state of the system's T and P
* are done through these routines
* - setState_TP()
* - setState_T()
* - setState_P()
*
* These routine in turn call the following underlying virtual functions
*
* - _updateRefStateThermo()
* - _updateStandardStateThermo()
*
* An important point to note is that between calls the assumption that the
* underlying PDSS objects will retain their set Temperatures and Pressure
* CAN NOT BE MADE. For efficiency reasons, we may twiddle these to get
* derivatives.
*/
//@{
//! Set the temperature (K) and pressure (Pa)
/*!
* This sets the temperature and pressure and triggers calculation of
* underlying quantities
*
* @param T Temperature (K)
* @param P Pressure (Pa)
*/
virtual void setState_TP(doublereal T, doublereal P);
//! Set the temperature (K)
/*!
* @param T Temperature (K)
*/
virtual void setState_T(doublereal T);
//! Set the pressure (Pa)
/*!
* @param P Pressure (Pa)
*/
virtual void setState_P(doublereal P);
//! Return the temperature stored in the object
doublereal temperature() const {
return m_tlast;
}
//! Return the pressure stored in the object
doublereal pressure() const {
return m_plast;
}
//! Return the pointer to the reference-state Thermo calculator
//! MultiSpeciesThermo object.
MultiSpeciesThermo* SpeciesThermoMgr() {
return m_spthermo;
}
//! Updates the internal standard state thermodynamic vectors at the
//! current T and P of the solution.
/*!
* If you are to peek internally inside the object, you need to
* call these functions after setState functions in order to be sure
* that the vectors are current.
*/
virtual void updateStandardStateThermo();
//! Updates the internal reference state thermodynamic vectors at the
//! current T of the solution and the reference pressure.
/*!
* If you are to peek internally inside the object, you need to
* call these functions after setState functions in order to be sure
* that the vectors are current.
*/
virtual void updateRefStateThermo() const;
protected:
//! Updates the standard state thermodynamic functions at the
//! current T and P of the solution.
/*!
* @internal
*
* If m_useTmpStandardStateStorage is true, this function must be called
* for every call to functions in this class. It checks to see whether the
* temperature or pressure has changed and thus the ss thermodynamics
* functions for all of the species must be recalculated.
*
* This function is responsible for updating the following internal members,
* when m_useTmpStandardStateStorage is true.
*
* - m_hss_RT;
* - m_cpss_R;
* - m_gss_RT;
* - m_sss_R;
* - m_Vss
*
* If m_useTmpStandardStateStorage is not true, this function may be
* required to be called by child classes to update internal member data.
*
* Note, the base class implementation will throw an error. It must be
* reimplemented in derived classes.
*
* Underscore updates never check for the state of the system
* They just do the calculation.
*/
virtual void _updateStandardStateThermo();
//! Updates the reference state thermodynamic functions at the
//! current T of the solution and the reference pressure
/*!
* Underscore updates never check for the state of the system. They just do
* the calculation.
*/
virtual void _updateRefStateThermo() const;
public:
//@}
//! @name Utility Methods - Reports on various quantities
/*!
* The following methods are used in the process of reporting various states
* and attributes
*/
//@{
//! Minimum temperature.
/*!
* If no argument is supplied, this method returns the minimum temperature
* for which \e all parameterizations are valid. If an integer index k is
* supplied, then the value returned is the minimum temperature for
* species k in the phase.
*
* @param k Species index
*/
virtual doublereal minTemp(size_t k=npos) const;
//! Maximum temperature.
/*!
* If no argument is supplied, this method returns the maximum temperature
* for which \e all parameterizations are valid. If an integer index k is
* supplied, then the value returned is the maximum temperature for
* parameterization k.
*
* @param k Species Index
*/
virtual doublereal maxTemp(size_t k=npos) const;
//! The reference-state pressure for the standard state
/*!
* Returns the reference state pressure in Pascals for species k. If k is
* left out of the argument list, it returns the reference state pressure
* for the first species.
*
* @param k Species index. Default is -1, which returns the generic answer.
*/
virtual doublereal refPressure(size_t k=npos) const;
//@}
/*! @name Initialization Methods - For Internal use
* The following methods are used in the process of constructing the phase
* and setting its parameters from a specification in an input file. They
* are not normally used in application programs. To see how they are
* used, see importPhase().
*/
//@{
//! @internal Initialize the object
/*!
* This method is provided to allow subclasses to perform any
* initialization required after all species have been added. For example,
* it might be used to resize internal work arrays that must have an entry
* for each species. The base class implementation does nothing, and
* subclasses that do not require initialization do not need to overload
* this method. When importing a CTML phase description, this method is
* called just prior to returning from function importPhase().
*/
virtual void initThermo();
//! Initialize the lengths within the object
/*!
* Note this function is not virtual
*/
void initLengths();
//! Finalize the thermo after all species have been entered
/*!
* This function is the LAST initialization routine to be called. It's
* called after createInstallPDSS() has been called for each species in the
* phase, and after initThermo() has been called. It's called via an inner-
* to-outer onion shell like manner.
*
* In this routine, we currently calculate the reference pressure, the
* minimum and maximum temperature for the applicability of the thermo
* formulation.
*
* @param phaseNode Reference to the phaseNode XML node.
* @param id ID of the phase.
*/
virtual void initThermoXML(XML_Node& phaseNode, const std::string& id);
//! Install specific content for species k in the reference-state
//! thermodynamic SpeciesManager object
/*!
* This occurs before matrices are sized appropriately.
*
* @param k Species index in the phase
* @param speciesNode XML Node corresponding to the species
* @param phaseNode_ptr Pointer to the XML Node corresponding
* to the phase which owns the species
*/
void installSTSpecies(size_t k, const XML_Node& speciesNode,
const XML_Node* phaseNode_ptr);
//! Install specific content for species k in the standard-state
//! thermodynamic calculator and also create/return a PDSS object
//! for that species.
/*!
* This occurs before matrices are sized appropriately.
*
* @param k Species index in the phase
* @param speciesNode XML Node corresponding to the species
* @param phaseNode_ptr Pointer to the XML Node corresponding
* to the phase which owns the species
*/
virtual PDSS* createInstallPDSS(size_t k, const XML_Node& speciesNode,
const XML_Node* const phaseNode_ptr);
//!@}
protected:
//! Number of species in the phase
size_t m_kk;
//! Variable pressure ThermoPhase object
VPStandardStateTP* m_vptp_ptr;
//! Pointer to reference state thermo calculator
/*!
* Note, this can have a value of 0
*/
MultiSpeciesThermo* m_spthermo;
//! The last temperature at which the standard state thermodynamic
//! properties were calculated at.
mutable doublereal m_tlast;
//! The last pressure at which the Standard State thermodynamic
//! properties were calculated at.
mutable doublereal m_plast;
//! Reference pressure (Pa) for each species
mutable vector_fp m_p0;
//! minimum temperature for the standard state calculations
doublereal m_minTemp;
//! maximum temperature for the standard state calculations
doublereal m_maxTemp;
//! boolean indicating whether temporary reference state storage is used ->
//! default is false
bool m_useTmpRefStateStorage;
//! Vector containing the species reference enthalpies at T = m_tlast
//! and P = p_ref.
mutable vector_fp m_h0_RT;
//! Vector containing the species reference constant pressure heat
//! capacities at T = m_tlast and P = p_ref.
mutable vector_fp m_cp0_R;
//! Vector containing the species reference Gibbs functions at T = m_tlast
//! and P = p_ref.
mutable vector_fp m_g0_RT;
//! Vector containing the species reference entropies at T = m_tlast
//! and P = p_ref.
mutable vector_fp m_s0_R;
//! Vector containing the species reference molar volumes
mutable vector_fp m_V0;
//! boolean indicating whether temporary standard state storage is used ->
//! default is false
bool m_useTmpStandardStateStorage;
//! Vector containing the species Standard State enthalpies at T = m_tlast
//! and P = m_plast.
mutable vector_fp m_hss_RT;
//! Vector containing the species Standard State constant pressure heat
//! capacities at T = m_tlast and P = m_plast.
mutable vector_fp m_cpss_R;
//! Vector containing the species Standard State Gibbs functions at T =
//! m_tlast and P = m_plast.
mutable vector_fp m_gss_RT;
//! Vector containing the species Standard State entropies at T = m_tlast
//! and P = m_plast.
mutable vector_fp m_sss_R;
//! Vector containing the species standard state volumes at T = m_tlast and
//! P = m_plast
mutable vector_fp m_Vss;
friend class PDSS;
};
//@}
}
#endif

View file

@ -1,104 +0,0 @@
/**
* @file VPSSMgr_ConstVol.h
* Declarations for a derived class for the calculation of multiple-species thermodynamic
* property managers for variable temperature and pressure standard
* states assuming constant volume (see class
* \link Cantera::VPSSMgr_ConstVol VPSSMgr_ConstVol \endlink).
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#ifndef CT_VPSSMGR_CONSTVOL_H
#define CT_VPSSMGR_CONSTVOL_H
#include "VPSSMgr.h"
namespace Cantera
{
//! Constant Molar Volume e VPSS species thermo manager class
/*!
* The calculation of multiple-species thermodynamic property managers for
* variable temperature and pressure standard states assuming a constant partial
* molar volume assumption.
*
* @ingroup mgrpdssthermocalc
*/
class VPSSMgr_ConstVol : public VPSSMgr
{
public:
//! Constructor
/*!
* @param vp_ptr Pointer to the owning VPStandardStateTP object for the
* phase.
* @param spth Pointer to the MultiSpeciesThermo object for the phase.
*/
VPSSMgr_ConstVol(VPStandardStateTP* vp_ptr, MultiSpeciesThermo* spth);
/*!
* @name Properties of the Standard State of the Species in the Solution
*
* Within VPStandardStateTP, these properties are calculated via a common
* routine, _updateStandardStateThermo(), which must be overloaded in
* inherited objects. The values are cached within this object, and are
* not recalculated unless the temperature or pressure changes.
*/
//@{
protected:
virtual void _updateStandardStateThermo();
//@}
/*! @name Thermodynamic Values for the Species Reference States
*
* There are also temporary variables for holding the species reference-
* state values of Cp, H, S, and V at the last temperature and reference
* pressure called. These functions are not recalculated if a new call is
* made using the previous temperature. All calculations are done within
* the routine _updateRefStateThermo(). _updateRefStateThermo() is
* defined in the parent object.
*/
//@{
virtual void getGibbs_RT_ref(doublereal* grt) const;
virtual void getStandardVolumes_ref(doublereal* vol) const;
//@}
/*! @name Initialization Methods - For Internal use
* The following methods are used in the process of constructing
* the phase and setting its parameters from a specification in an
* input file. They are not normally seen by application programs
*/
//@{
public:
virtual void initThermoXML(XML_Node& phaseNode, const std::string& id);
//! Create and install a constant volume pressure dependent
//! standard state for one species within this object
/*!
* This function sets up the internal data within this object for
* handling the calculation of the standard state for the species.
*
* - It registers the species with the MultiSpeciesThermo object for the
* containing VPStandardStateTP phase.
* - It grabs the molar volume property and installs its value within
* this object.
* - It also creates a PDSS object, which basically contains a
* duplication of some of this information and returns a pointer to
* the new object.
*
* @param k Species index within the phase
* @param speciesNode Reference to the species node in the XML tree
* @param phaseNode_ptr Pointer to the phase node in the XML tree
* @return A pointer to the a newly created PDSS object containing the
* parameterization
*/
virtual PDSS* createInstallPDSS(size_t k, const XML_Node& speciesNode,
const XML_Node* const phaseNode_ptr);
//@}
};
}
#endif

View file

@ -1,128 +0,0 @@
/**
* @file VPSSMgr_General.h
* Declaration file for a derived class that handles the calculation
* of standard state thermo properties for
* a set of species belonging to a single phase in a completely general
* but slow way (see \ref mgrpdssthermocalc and
* class \link Cantera::VPSSMgr_General VPSSMgr_General\endlink).
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#ifndef CT_VPSSMGR_GENERAL_H
#define CT_VPSSMGR_GENERAL_H
#include "VPSSMgr.h"
namespace Cantera
{
//! Class that handles the calculation of standard state thermo properties for
//! a set of species belonging to a single phase in a completely general
//! but slow way.
/*!
* This class manages the calculation of standard state thermo properties
* for a set of species belonging to a single phase in a completely general
* but slow way. The way this does this is to call the underlying PDSS
* routines one at a time for every species.
*
* @ingroup mgrpdssthermocalc
*/
class VPSSMgr_General : public VPSSMgr
{
public:
//! Constructor
/*!
* @param vp_ptr Pointer to the owning VPStandardStateTP object for the
* phase.
* @param spth Pointer to the MultiSpeciesThermo object for the phase.
*/
VPSSMgr_General(VPStandardStateTP* vp_ptr,
MultiSpeciesThermo* spth);
protected:
/*!
* @name Properties of the Standard State of the Species in the Solution
*
* Within VPStandardStateTP, these properties are calculated via a common
* routine, _updateStandardStateThermo(), which must be overloaded in
* inherited objects. The values are cached within this object, and are
* not recalculated unless the temperature or pressure changes.
*/
//@{
virtual void _updateStandardStateThermo();
virtual void _updateRefStateThermo() const;
//@}
/*! @name Thermodynamic Values for the Species Reference States
* There are also temporary variables for holding the species reference-
* state values of Cp, H, S, and V at the last temperature and reference
* pressure called. These functions are not recalculated if a new call is
* made using the previous temperature. All calculations are done within
* the routine _updateRefStateThermo().
*/
//@{
virtual void getGibbs_ref(doublereal* g) const;
//@}
/*! @name Initialization Methods - For Internal use
* The following methods are used in the process of constructing the phase
* and setting its parameters from a specification in an input file. They
* are not normally used in application programs. To see how they are
* used, see importPhase().
*/
//@{
virtual void initThermo();
//@}
private:
//! Local factory routine for the creation of PDSS objects
/*!
* This routine is specific to the VPSSMgr_General object. It will create
* a PDSS object for species k, by searching and querying for the
* "standardState" XML node in the standard state description of the
* species. If this XML node doesn't exist, it will assume that the
* standard state is an ideal gas. It decides on the attribute, "model",
* what PDSS object to create.
*
* @param speciesNode XML node for the standard state of the species
* @param k Species number
* @param phaseNode_ptr pointer to the phase XML node
* @param doST output variable indicating whether the
* instantiation has resulted in a MultiSpeciesThermo object
* being created and registered with the MultiSpeciesThermo
* manager class.
* @returns the pointer to a newly created PDSS object
*/
PDSS* returnPDSS_ptr(size_t k, const XML_Node& speciesNode,
const XML_Node* const phaseNode_ptr, bool& doST);
public:
//! Factory routine for the creation of PDSS objects that are
//! then internally registered with this VPSSMgr object
/*!
* This function sets up the internal data within this object for handling
* the calculation of the standard state for the species.
*
* This routine will create a PDSS object for species k, by searching and
* querying for the "standardState" XML node in the standard state
* description of the species. It will then store the object's pointer in
* a vector of pointers, and it will own the object.
*
* @param k Species number
* @param speciesNode XML node for the standard state of the species
* @param phaseNode_ptr pointer to the phase XML node
* @return the pointer to the newly created PDSS object
*/
virtual PDSS* createInstallPDSS(size_t k, const XML_Node& speciesNode,
const XML_Node* const phaseNode_ptr);
private:
//! Shallow pointers containing the PDSS objects for the species
//! in this phase. This object doesn't own these pointers.
std::vector<PDSS*> m_PDSS_ptrs;
};
}
#endif

View file

@ -1,79 +0,0 @@
/**
* @file VPSSMgr_IdealGas.h
* Declaration file for a derived class that handles the calculation
* of standard state thermo properties for
* a set of species which have an Ideal Gas dependence
* (see \ref mgrpdssthermocalc and
* class \link Cantera::VPSSMgr_IdealGas VPSSMgr_IdealGas\endlink).
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#ifndef CT_VPSSMGR_IDEALGAS_H
#define CT_VPSSMGR_IDEALGAS_H
#include "VPSSMgr.h"
namespace Cantera
{
//! A VPSSMgr where all species in the phase obey an ideal gas equation of state
/**
* @attention This class currently does not have any test cases or examples. Its
* implementation may be incomplete, and future changes to Cantera may
* unexpectedly cause this class to stop working. If you use this class,
* please consider contributing examples or test cases. In the absence of
* new tests or examples, this class may be deprecated and removed in a
* future version of Cantera. See
* https://github.com/Cantera/cantera/issues/267 for additional information.
*/
class VPSSMgr_IdealGas : public VPSSMgr
{
public:
//! Basic constructor that initializes the object
/*!
* @param vp_ptr Pointer to the owning ThermoPhase
* @param spth Species thermo pointer.
*/
VPSSMgr_IdealGas(VPStandardStateTP* vp_ptr, MultiSpeciesThermo* spth);
/*! @name Properties of the Standard State of the Species in the Solution
* Within VPStandardStateTP, these properties are calculated via a common
* routine, _updateStandardStateThermo(), which must be overloaded in
* inherited objects. The values are cached within this object, and are
* not recalculated unless the temperature or pressure changes.
*/
//@{
virtual void getIntEnergy_RT(doublereal* urt) const;
virtual void getStandardVolumes(doublereal* vol) const;
//@}
protected:
virtual void _updateStandardStateThermo();
public:
//! Create and install an ideal gas standard state manager for one species
//! within this object
/*!
* This function sets up the internal data within this object for
* handling the calculation of the standard state for the species.
*
* - It registers the species with the MultiSpeciesThermo object for the
* containing VPStandardStateTP phase.
* - It also creates a PDSS object, which basically contains a
* duplication of some of this information and returns a pointer to
* the new object.
* .
* @param k Species index within the phase
* @param speciesNode Reference to the species node in the XML tree
* @param phaseNode_ptr Pointer to the phase node in the XML tree
* @return a pointer to the a newly created PDSS object containing the
* parameterization
*/
virtual PDSS* createInstallPDSS(size_t k, const XML_Node& speciesNode,
const XML_Node* const phaseNode_ptr);
};
}
#endif

View file

@ -1,94 +0,0 @@
/**
* @file VPSSMgr_Water_ConstVol.h
* Declaration file for a derived class that handles the calculation
* of standard state thermo properties for real water and
* a set of species which have a constant molar volume pressure
* dependence
* (see \ref mgrpdssthermocalc and
* class \link Cantera::VPSSMgr_ConstVol VPSSMgr_ConstVol\endlink).
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#ifndef CT_VPSSMGR_WATER_CONSTVOL_H
#define CT_VPSSMGR_WATER_CONSTVOL_H
#include "VPSSMgr.h"
namespace Cantera
{
class PDSS_Water;
//! Handles the calculation of standard state thermo properties for real water
//! and a set of species which have a constant molar volume pressure
//! dependence.
class VPSSMgr_Water_ConstVol : public VPSSMgr
{
public:
//! Base Constructor
/*!
* Initialize the object.
*
* @param vp_ptr Pointer to the VPStandardStateTP standard state
* @param sp_ptr Pointer to the MultiSpeciesThermo standard state
*/
VPSSMgr_Water_ConstVol(VPStandardStateTP* vp_ptr, MultiSpeciesThermo* sp_ptr);
private:
/*!
* @name Properties of the Standard State of the Species in the Solution
*
* Within VPStandardStateTP, these properties are calculated via a common
* routine, _updateStandardStateThermo(), which must be overloaded in
* inherited objects. The values are cached within this object, and are
* not recalculated unless the temperature or pressure changes.
*/
//@{
virtual void _updateStandardStateThermo();
virtual void _updateRefStateThermo() const;
//@}
public:
/*! @name Thermodynamic Values for the Species Reference States
* There are also temporary variables for holding the species reference-
* state values of Cp, H, S, and V at the last temperature and reference
* pressure called. These functions are not recalculated if a new call is
* made using the previous temperature. All calculations are done within
* the routine _updateRefStateThermo().
*/
//@{
virtual void getEnthalpy_RT_ref(doublereal* hrt) const;
virtual void getGibbs_RT_ref(doublereal* grt) const;
virtual void getGibbs_ref(doublereal* g) const;
virtual void getEntropy_R_ref(doublereal* er) const;
virtual void getCp_R_ref(doublereal* cpr) const;
virtual void getStandardVolumes_ref(doublereal* vol) const;
//! @}
/*! @name Initialization Methods - For Internal use
* The following methods are used in the process of constructing
* the phase and setting its parameters from a specification in an
* input file. They are not normally used in application programs.
* To see how they are used, see importPhase().
*/
//@{
virtual void initThermoXML(XML_Node& phaseNode, const std::string& id);
//@}
virtual PDSS* createInstallPDSS(size_t k, const XML_Node& speciesNode,
const XML_Node* const phaseNode_ptr);
private:
//! Pointer to the Water PDSS object.
/*!
* This is a shallow copy. The water PDSS object is owned by the VPStandardStateTP
* object.
*/
PDSS_Water* m_waterSS;
};
}
#endif

View file

@ -1,108 +0,0 @@
/**
* @file VPSSMgr_Water_HKFT.h
* Declaration file for a derived class that handles the calculation
* of standard state thermo properties for real water and
* a set of species which have the HKFT equation of state
* (see \ref mgrpdssthermocalc and
* class \link Cantera::VPSSMgr_Water_HKFT VPSSMgr_Water_HKFT\endlink).
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#ifndef CT_VPSSMGR_WATER_HKFT_H
#define CT_VPSSMGR_WATER_HKFT_H
#include "VPSSMgr.h"
namespace Cantera
{
class PDSS_Water;
//! Manages standard state thermo properties for real water and a set of
//! species which have the HKFT equation of state.
class VPSSMgr_Water_HKFT : public VPSSMgr
{
public:
//! Constructor
/*!
* @param vptp_ptr Pointer to the Variable pressure ThermoPhase object
* @param spth Pointer to the optional MultiSpeciesThermo object
* that will handle the calculation of the reference
* state thermodynamic coefficients.
*/
VPSSMgr_Water_HKFT(VPStandardStateTP* vptp_ptr,
MultiSpeciesThermo* spth);
/*! @name Thermodynamic Values for the Species Reference States
* There are also temporary variables for holding the species reference-
* state values of Cp, H, S, and V at the last temperature and reference
* pressure called. These functions are not recalculated if a new call is
* made using the previous temperature. All calculations are done within
* the routine _updateRefStateThermo().
*/
//@{
virtual void getEnthalpy_RT_ref(doublereal* hrt) const;
virtual void getGibbs_RT_ref(doublereal* grt) const;
virtual void getGibbs_ref(doublereal* g) const;
virtual void getEntropy_R_ref(doublereal* er) const;
virtual void getCp_R_ref(doublereal* cpr) const;
virtual void getStandardVolumes_ref(doublereal* vol) const;
//@}
virtual void setState_TP(doublereal T, doublereal P);
virtual void setState_T(doublereal T);
virtual void setState_P(doublereal P);
/*! @name Setting the Internal State of the System
* All calls to change the internal state of the system's T and P
* are done through these routines
* - setState_TP()
* - setState_T()
* - setState_P()
*
* These routine in turn call the following underlying virtual functions
*
* - _updateRefStateThermo()
* - _updateStandardStateThermo()
*
* An important point to note is that between calls the assumption
* that the underlying PDSS objects will retain their set Temperatures
* and Pressure CAN NOT BE MADE. For efficiency reasons, we may twiddle
* these to get derivatives.
*/
//@{
virtual void updateRefStateThermo() const;
private:
virtual void _updateRefStateThermo() const;
virtual void _updateStandardStateThermo();
//@}
public:
/*! @name Initialization Methods - For Internal use (VPStandardState)
* The following methods are used in the process of constructing
* the phase and setting its parameters from a specification in an
* input file. They are not normally used in application programs.
* To see how they are used, see importPhase().
*/
//@{
virtual void initThermoXML(XML_Node& phaseNode, const std::string& id);
virtual PDSS* createInstallPDSS(size_t k, const XML_Node& speciesNode,
const XML_Node* const phaseNode_ptr);
//@}
private:
//! Shallow pointer to the water object
PDSS_Water* m_waterSS;
//! Last reference temperature calculated
/*!
* Reference state calculations are totally separated from
* standard state calculations.
*/
mutable doublereal m_tlastRef;
};
}
#endif

View file

@ -13,7 +13,6 @@
#define CT_VPSTANDARDSTATETP_H
#include "ThermoPhase.h"
#include "VPSSMgr.h"
#include "PDSS.h"
namespace Cantera
@ -28,8 +27,7 @@ namespace Cantera
* variables for holding the species standard state values of Cp, H, S, G, and V
* at the last temperature and pressure called. These functions are not
* recalculated if a new call is made using the previous temperature and
* pressure. Currently, these variables and the calculation method are handled
* by the VPSSMgr class, for which VPStandardStateTP owns a pointer to.
* pressure.
*
* To support the above functionality, pressure and temperature variables,
* m_Plast_ss and m_Tlast_ss, are kept which store the last pressure and
@ -250,18 +248,6 @@ public:
using Phase::addSpecies;
virtual bool addSpecies(shared_ptr<Species> spec);
//! set the VPSS Mgr
/*!
* @param vp_ptr Pointer to the manager
*/
void setVPSSMgr(VPSSMgr* vp_ptr);
//! Return a pointer to the VPSSMgr for this phase
/*!
* @returns a pointer to the VPSSMgr for this phase
*/
VPSSMgr* provideVPSSMgr();
void createInstallPDSS(size_t k, const XML_Node& s, const XML_Node* phaseNode_ptr);
PDSS* providePDSS(size_t k);
@ -287,17 +273,55 @@ protected:
//! were calculated at.
mutable doublereal m_Plast_ss;
// -> suggest making this private!
//! Pointer to the VPSS manager that calculates all of the standard state
//! info efficiently.
mutable std::unique_ptr<VPSSMgr> m_VPSS_ptr;
//! Storage for the PDSS objects for the species
/*!
* Storage is in species index order. VPStandardStateTp owns each of the
* objects. Copy operations are deep.
*/
std::vector<std::unique_ptr<PDSS>> m_PDSS_storage;
//! boolean indicating whether temporary reference state storage is used ->
//! default is true
bool m_useTmpRefStateStorage;
//! Vector containing the species reference enthalpies at T = m_tlast
//! and P = p_ref.
mutable vector_fp m_h0_RT;
//! Vector containing the species reference constant pressure heat
//! capacities at T = m_tlast and P = p_ref.
mutable vector_fp m_cp0_R;
//! Vector containing the species reference Gibbs functions at T = m_tlast
//! and P = p_ref.
mutable vector_fp m_g0_RT;
//! Vector containing the species reference entropies at T = m_tlast
//! and P = p_ref.
mutable vector_fp m_s0_R;
//! Vector containing the species reference molar volumes
mutable vector_fp m_V0;
//! Vector containing the species Standard State enthalpies at T = m_tlast
//! and P = m_plast.
mutable vector_fp m_hss_RT;
//! Vector containing the species Standard State constant pressure heat
//! capacities at T = m_tlast and P = m_plast.
mutable vector_fp m_cpss_R;
//! Vector containing the species Standard State Gibbs functions at T =
//! m_tlast and P = m_plast.
mutable vector_fp m_gss_RT;
//! Vector containing the species Standard State entropies at T = m_tlast
//! and P = m_plast.
mutable vector_fp m_sss_R;
//! Vector containing the species standard state volumes at T = m_tlast and
//! P = m_plast
mutable vector_fp m_Vss;
};
}

View file

@ -48,19 +48,19 @@ IdealSolnGasVPSS::IdealSolnGasVPSS(const std::string& infile, std::string id_) :
doublereal IdealSolnGasVPSS::enthalpy_mole() const
{
updateStandardStateThermo();
return RT() * mean_X(m_VPSS_ptr->enthalpy_RT());
return RT() * mean_X(m_hss_RT);
}
doublereal IdealSolnGasVPSS::entropy_mole() const
{
updateStandardStateThermo();
return GasConstant * (mean_X(m_VPSS_ptr->entropy_R()) - sum_xlogx());
return GasConstant * (mean_X(m_sss_R) - sum_xlogx());
}
doublereal IdealSolnGasVPSS::cp_mole() const
{
updateStandardStateThermo();
return GasConstant * mean_X(m_VPSS_ptr->cp_R());
return GasConstant * mean_X(m_cpss_R);
}
doublereal IdealSolnGasVPSS::cv_mole() const
@ -83,7 +83,7 @@ void IdealSolnGasVPSS::calcDensity()
Phase::setDensity(dens);
} else {
const doublereal* const dtmp = moleFractdivMMW();
const vector_fp& vss = m_VPSS_ptr->getStandardVolumes();
const vector_fp& vss = getStandardVolumes();
double dens = 1.0 / dot(vss.begin(), vss.end(), dtmp);
// Set the density in the parent State object directly
@ -107,7 +107,7 @@ void IdealSolnGasVPSS::getActivityConcentrations(doublereal* c) const
if (m_idealGas) {
getConcentrations(c);
} else {
const vector_fp& vss = m_VPSS_ptr->getStandardVolumes();
const vector_fp& vss = getStandardVolumes();
switch (m_formGC) {
case 0:
for (size_t k = 0; k < m_kk; k++) {
@ -133,7 +133,7 @@ doublereal IdealSolnGasVPSS::standardConcentration(size_t k) const
if (m_idealGas) {
return pressure() / RT();
} else {
const vector_fp& vss = m_VPSS_ptr->getStandardVolumes();
const vector_fp& vss = getStandardVolumes();
switch (m_formGC) {
case 0:
return 1.0;
@ -200,7 +200,6 @@ void IdealSolnGasVPSS::getPartialMolarVolumes(doublereal* vbar) const
void IdealSolnGasVPSS::setToEquilState(const doublereal* mu_RT)
{
updateStandardStateThermo();
const vector_fp& grt = m_VPSS_ptr->Gibbs_RT_ref();
// Within the method, we protect against inf results if the exponent is too
// high.
@ -208,9 +207,9 @@ void IdealSolnGasVPSS::setToEquilState(const doublereal* mu_RT)
// If it is too low, we set the partial pressure to zero. This capability is
// needed by the elemental potential method.
doublereal pres = 0.0;
double m_p0 = m_VPSS_ptr->refPressure();
double m_p0 = refPressure();
for (size_t k = 0; k < m_kk; k++) {
double tmp = -grt[k] + mu_RT[k];
double tmp = -m_g0_RT[k] + mu_RT[k];
if (tmp < -600.) {
m_pp[k] = 0.0;
} else if (tmp > 500.0) {

View file

@ -78,13 +78,6 @@ void MultiSpeciesThermo::modifySpecies(size_t index,
m_sp[type][m_speciesLoc[index].second] = {index, spthermo};
}
void MultiSpeciesThermo::installPDSShandler(size_t k, PDSS* PDSS_ptr,
VPSSMgr* vpssmgr_ptr)
{
auto stit_ptr = make_shared<STITbyPDSS>(vpssmgr_ptr, PDSS_ptr);
install_STIT(k, stit_ptr);
}
void MultiSpeciesThermo::update_one(size_t k, doublereal t, doublereal* cp_R,
doublereal* h_RT, doublereal* s_R) const
{

View file

@ -21,7 +21,6 @@ PDSS::PDSS() :
m_minTemp(-1.0),
m_maxTemp(10000.0),
m_tp(0),
m_vpssmgr_ptr(0),
m_mw(0.0),
m_spindex(npos),
m_spthermo(0)
@ -35,7 +34,6 @@ PDSS::PDSS(VPStandardStateTP* tp, size_t spindex) :
m_minTemp(-1.0),
m_maxTemp(10000.0),
m_tp(tp),
m_vpssmgr_ptr(0),
m_mw(0.0),
m_spindex(spindex),
m_spthermo(0)
@ -43,24 +41,16 @@ PDSS::PDSS(VPStandardStateTP* tp, size_t spindex) :
if (tp) {
m_spthermo = &tp->speciesThermo();
}
if (tp) {
m_vpssmgr_ptr = tp->provideVPSSMgr();
}
}
void PDSS::initThermoXML(const XML_Node& phaseNode, const std::string& id)
{
AssertThrow(m_tp != 0, "PDSS::initThermoXML()");
m_p0 = m_vpssmgr_ptr->refPressure(m_spindex);
m_minTemp = m_vpssmgr_ptr->minTemp(m_spindex);
m_maxTemp = m_vpssmgr_ptr->maxTemp(m_spindex);
}
void PDSS::initThermo()
{
AssertThrow(m_tp != 0, "PDSS::initThermo()");
m_vpssmgr_ptr = m_tp->provideVPSSMgr();
m_vpssmgr_ptr->initThermo();
m_mw = m_tp->molecularWeight(m_spindex);
}

View file

@ -122,7 +122,6 @@ void PDSS_IdealGas::setPressure(doublereal p)
doublereal PDSS_IdealGas::temperature() const
{
m_temp = m_vpssmgr_ptr->temperature();
return m_temp;
}

View file

@ -235,7 +235,7 @@ doublereal PDSS_IonsFromNeutral::temperature() const
{
// Obtain the temperature from the owning VPStandardStateTP object if you
// can.
m_temp = m_vpssmgr_ptr->temperature();
m_temp = m_tp->temperature();
return m_temp;
}

View file

@ -18,7 +18,6 @@
#include "cantera/thermo/ConstCpPoly.h"
#include "cantera/thermo/AdsorbateThermo.h"
#include "cantera/thermo/speciesThermoTypes.h"
#include "cantera/thermo/VPSSMgr.h"
#include "cantera/thermo/VPStandardStateTP.h"
#include "cantera/base/ctml.h"
#include "cantera/base/stringUtils.h"

View file

@ -6,7 +6,6 @@
// at http://www.cantera.org/license.txt for license and copyright information.
#include "cantera/thermo/SpeciesThermoInterpType.h"
#include "cantera/thermo/VPSSMgr.h"
#include "cantera/thermo/PDSS.h"
namespace Cantera
@ -50,9 +49,7 @@ void SpeciesThermoInterpType::modifyOneHf298(const size_t k,
//=============================================================================
STITbyPDSS::STITbyPDSS(VPSSMgr* vpssmgr_ptr, PDSS* PDSS_ptr) :
SpeciesThermoInterpType(),
m_vpssmgr_ptr(vpssmgr_ptr),
STITbyPDSS::STITbyPDSS(PDSS* PDSS_ptr) :
m_PDSS_ptr(PDSS_ptr)
{
}
@ -103,8 +100,8 @@ void STITbyPDSS::reportParameters(size_t& index, int& type,
{
index = 0;
type = PDSS_TYPE;
minTemp = m_vpssmgr_ptr->minTemp();
maxTemp = m_vpssmgr_ptr->maxTemp();
minTemp = m_PDSS_ptr->minTemp();
maxTemp = m_PDSS_ptr->maxTemp();
refPressure = m_PDSS_ptr->refPressure();
}

View file

@ -14,8 +14,6 @@
#include "cantera/thermo/SpeciesThermoFactory.h"
#include "cantera/thermo/MultiSpeciesThermo.h"
#include "cantera/thermo/IdealGasPhase.h"
#include "cantera/thermo/VPSSMgr.h"
#include "VPSSMgrFactory.h"
#include "cantera/thermo/IdealSolidSolnPhase.h"
#include "cantera/thermo/MaskellSolidSolnPhase.h"
@ -335,12 +333,6 @@ void importPhase(XML_Node& phase, ThermoPhase* th)
formSpeciesXMLNodeList(spDataNodeList, spNamesList, spRuleList,
sparrays, dbases, sprule);
// Decide whether the the phase has a variable pressure ss or not
if (ssConvention == cSS_CONVENTION_VPSS) {
VPSSMgr* vp_spth = newVPSSMgr(vpss_ptr, &phase, spDataNodeList);
vpss_ptr->setVPSSMgr(vp_spth);
}
size_t nsp = spDataNodeList.size();
if (ssConvention == cSS_CONVENTION_SLAVE && nsp > 0) {
throw CanteraError("importPhase()", "For Slave standard states, "

View file

@ -1,307 +0,0 @@
/**
* @file VPSSMgr.cpp
* Definition file for a virtual base class that manages
* the calculation of standard state properties for all of the
* species in a single phase, assuming a variable P and T standard state
* (see \ref mgrpdssthermocalc and
* class \link Cantera::VPSSMgr VPSSMgr\endlink).
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#include "cantera/thermo/VPSSMgr.h"
#include "cantera/thermo/VPStandardStateTP.h"
#include "cantera/thermo/SpeciesThermoFactory.h"
#include "cantera/thermo/PDSS.h"
#include "cantera/thermo/MultiSpeciesThermo.h"
#include "cantera/base/utilities.h"
#include "cantera/base/xml.h"
using namespace std;
namespace Cantera
{
VPSSMgr::VPSSMgr(VPStandardStateTP* vptp_ptr, MultiSpeciesThermo* spthermo) :
m_kk(0),
m_vptp_ptr(vptp_ptr),
m_spthermo(spthermo),
m_tlast(-1.0),
m_plast(-1.0),
m_minTemp(-1.0),
m_maxTemp(1.0E8),
m_useTmpRefStateStorage(false),
m_useTmpStandardStateStorage(false)
{
if (!m_vptp_ptr) {
throw CanteraError("VPSSMgr",
"null pointer for VPStandardStateTP is not permissible");
}
}
// Standard States
void VPSSMgr::getStandardChemPotentials(doublereal* mu) const
{
if (m_useTmpStandardStateStorage) {
std::copy(m_gss_RT.begin(), m_gss_RT.end(), mu);
scale(mu, mu+m_kk, mu, GasConstant * m_tlast);
} else {
throw NotImplementedError("VPSSMgr::getStandardChemPotentials");
}
}
void VPSSMgr::getGibbs_RT(doublereal* grt) const
{
if (m_useTmpStandardStateStorage) {
std::copy(m_gss_RT.begin(), m_gss_RT.end(), grt);
} else {
throw NotImplementedError("VPSSMgr::getGibbs_RT");
}
}
void VPSSMgr::getEnthalpy_RT(doublereal* hrt) const
{
if (m_useTmpStandardStateStorage) {
std::copy(m_hss_RT.begin(), m_hss_RT.end(), hrt);
} else {
throw NotImplementedError("VPSSMgr::getEnthalpy_RT");
}
}
void VPSSMgr::getEntropy_R(doublereal* sr) const
{
if (m_useTmpStandardStateStorage) {
std::copy(m_sss_R.begin(), m_sss_R.end(), sr);
} else {
throw NotImplementedError("VPSSMgr::getEntropy_RT");
}
}
void VPSSMgr::getIntEnergy_RT(doublereal* urt) const
{
if (m_useTmpStandardStateStorage) {
std::copy(m_hss_RT.begin(), m_hss_RT.end(), urt);
for (size_t k = 0; k < m_kk; k++) {
urt[k] -= m_plast / (GasConstant * m_tlast) * m_Vss[k];
}
} else {
throw NotImplementedError("VPSSMgr::getEntropy_RT");
}
}
void VPSSMgr::getCp_R(doublereal* cpr) const
{
if (m_useTmpStandardStateStorage) {
std::copy(m_cpss_R.begin(), m_cpss_R.end(), cpr);
} else {
throw NotImplementedError("VPSSMgr::getCp_R");
}
}
void VPSSMgr::getStandardVolumes(doublereal* vol) const
{
if (m_useTmpStandardStateStorage) {
std::copy(m_Vss.begin(), m_Vss.end(), vol);
} else {
throw NotImplementedError("VPSSMgr::getStandardVolumes");
}
}
const vector_fp& VPSSMgr::getStandardVolumes() const
{
if (!m_useTmpStandardStateStorage) {
throw NotImplementedError("VPSSMgr::getStandardVolumes");
}
return m_Vss;
}
/*****************************************************************/
void VPSSMgr::getEnthalpy_RT_ref(doublereal* hrt) const
{
if (m_useTmpRefStateStorage) {
std::copy(m_h0_RT.begin(), m_h0_RT.end(), hrt);
} else {
throw NotImplementedError("VPSSMgr::getEnthalpy_RT_ref");
}
}
void VPSSMgr::getGibbs_RT_ref(doublereal* grt) const
{
if (m_useTmpRefStateStorage) {
std::copy(m_g0_RT.begin(), m_g0_RT.end(), grt);
} else {
throw NotImplementedError("VPSSMgr::getGibbs_RT_ref");
}
}
void VPSSMgr::getGibbs_ref(doublereal* g) const
{
if (m_useTmpRefStateStorage) {
std::copy(m_g0_RT.begin(), m_g0_RT.end(), g);
scale(g, g+m_kk, g, GasConstant * m_tlast);
} else {
throw NotImplementedError("VPSSMgr::getGibbs_ref");
}
}
void VPSSMgr::getEntropy_R_ref(doublereal* sr) const
{
if (m_useTmpRefStateStorage) {
std::copy(m_s0_R.begin(), m_s0_R.end(), sr);
} else {
throw NotImplementedError("VPSSMgr::getEntropy_R_ref");
}
}
void VPSSMgr::getCp_R_ref(doublereal* cpr) const
{
if (m_useTmpRefStateStorage) {
std::copy(m_cp0_R.begin(), m_cp0_R.end(), cpr);
} else {
throw NotImplementedError("VPSSMgr::getCp_R_ref");
}
}
void VPSSMgr::getStandardVolumes_ref(doublereal* vol) const
{
getStandardVolumes(vol);
}
/*****************************************************************/
void VPSSMgr::setState_P(doublereal pres)
{
if (m_plast != pres) {
m_plast = pres;
updateStandardStateThermo();
}
}
void VPSSMgr::setState_T(doublereal temp)
{
if (m_tlast != temp) {
m_tlast = temp;
updateRefStateThermo();
updateStandardStateThermo();
}
}
void VPSSMgr::setState_TP(doublereal temp, doublereal pres)
{
if (m_tlast != temp) {
m_tlast = temp;
m_plast = pres;
updateRefStateThermo();
updateStandardStateThermo();
} else if (m_plast != pres) {
m_plast = pres;
updateStandardStateThermo();
}
}
void VPSSMgr::updateStandardStateThermo()
{
_updateStandardStateThermo();
}
void VPSSMgr::updateRefStateThermo() const
{
_updateRefStateThermo();
}
void VPSSMgr::_updateStandardStateThermo()
{
for (size_t k = 0; k < m_kk; k++) {
PDSS* kPDSS = m_vptp_ptr->providePDSS(k);
kPDSS->setState_TP(m_tlast, m_plast);
}
throw NotImplementedError("VPSSMgr::_updateStandardStateThermo()");
}
void VPSSMgr::_updateRefStateThermo() const
{
if (m_spthermo) {
m_spthermo->update(m_tlast, &m_cp0_R[0], &m_h0_RT[0], &m_s0_R[0]);
for (size_t k = 0; k < m_kk; k++) {
m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
}
}
}
/*****************************************************************/
void VPSSMgr::initThermo()
{
initLengths();
}
void VPSSMgr::initLengths()
{
m_kk = m_vptp_ptr->nSpecies();
m_h0_RT.resize(m_kk, 0.0);
m_cp0_R.resize(m_kk, 0.0);
m_g0_RT.resize(m_kk, 0.0);
m_s0_R.resize(m_kk, 0.0);
m_V0.resize(m_kk, 0.0);
m_hss_RT.resize(m_kk, 0.0);
m_cpss_R.resize(m_kk, 0.0);
m_gss_RT.resize(m_kk, 0.0);
m_sss_R.resize(m_kk, 0.0);
m_Vss.resize(m_kk, 0.0);
}
void VPSSMgr::initThermoXML(XML_Node& phaseNode, const std::string& id)
{
for (size_t i = 0; i < m_kk; i++) {
const PDSS* kPDSS = m_vptp_ptr->providePDSS(i);
m_p0.resize(std::max(m_p0.size(), i+1));
m_p0[i] = kPDSS->refPressure();
m_minTemp = std::max(m_minTemp, kPDSS->minTemp());
m_maxTemp = std::min(m_maxTemp, kPDSS->maxTemp());
}
}
void VPSSMgr::installSTSpecies(size_t k, const XML_Node& s,
const XML_Node* phaseNode_ptr)
{
shared_ptr<SpeciesThermoInterpType> stit(newSpeciesThermoInterpType(s.child("thermo")));
stit->validate(s["name"]);
m_spthermo->install_STIT(k, stit);
m_p0.resize(std::max(m_p0.size(), k+1));
m_p0[k] = m_spthermo->refPressure(k);
}
PDSS* VPSSMgr::createInstallPDSS(size_t k, const XML_Node& s,
const XML_Node* phaseNode_ptr)
{
throw NotImplementedError("VPSSMgr::VPSSMgr::createInstallPDSS");
}
/*****************************************************************/
doublereal VPSSMgr::minTemp(size_t k) const
{
if (k != npos) {
return m_vptp_ptr->providePDSS(k)->minTemp();
}
return m_minTemp;
}
doublereal VPSSMgr::maxTemp(size_t k) const
{
if (k != npos) {
return m_vptp_ptr->providePDSS(k)->maxTemp();
}
return m_maxTemp;
}
doublereal VPSSMgr::refPressure(size_t k) const
{
if (k != npos) {
return m_vptp_ptr->providePDSS(k)->refPressure();
}
return m_p0[0];
}
}

View file

@ -1,282 +0,0 @@
/**
* @file VPSSMgrFactory.cpp
* Definitions for factory to build instances of classes that manage the
* calculation of standard state properties for all the species in a phase
* (see \ref spthermo and class
* \link Cantera::VPSSMgrFactory VPSSMgrFactory\endlink);
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#include "VPSSMgrFactory.h"
#include "cantera/thermo/VPStandardStateTP.h"
#include "cantera/thermo/VPSSMgr_IdealGas.h"
#include "cantera/thermo/VPSSMgr_ConstVol.h"
#include "cantera/thermo/VPSSMgr_Water_ConstVol.h"
#include "cantera/thermo/VPSSMgr_Water_HKFT.h"
#include "cantera/thermo/VPSSMgr_General.h"
#include "cantera/thermo/SpeciesThermoFactory.h"
#include "cantera/thermo/MultiSpeciesThermo.h"
#include "cantera/base/stringUtils.h"
#include "cantera/base/ctml.h"
using namespace std;
namespace Cantera
{
VPSSMgrFactory* VPSSMgrFactory::s_factory = 0;
// Defn of the static mutex variable that locks the VPSSMgr factory singleton
std::mutex VPSSMgrFactory::vpss_species_thermo_mutex;
//! Examine the types of species thermo parameterizations, and return a flag
//! indicating the type of parameterization needed by the species.
/*!
* @param spDataNodeList Species Data XML node. This node contains a list
* of species XML nodes underneath it.
* @param has_nasa_idealGas Boolean indicating that one species has a
* NASA ideal gas standard state
* @param has_nasa_constVol Boolean indicating that one species has a
* NASA ideal solution standard state
* @param has_shomate_idealGas Boolean indicating that one species has a
* Shomate ideal gas standard state
* @param has_shomate_constVol Boolean indicating that one species has a
* Shomate ideal solution standard state
* @param has_simple_idealGas Boolean indicating that one species has a
* simple ideal gas standard state
* @param has_simple_constVol Boolean indicating that one species has a
* simple ideal solution standard state
* @param has_water Boolean indicating that one species has a
* water standard state
* @param has_tpx Boolean indicating that one species has a
* tpx standard state
* @param has_hptx Boolean indicating that one species has a
* htpx standard state
* @param has_other Boolean indicating that one species has
* different standard state than the ones listed above
*
* @todo Make sure that spDadta_node is species Data XML node by checking
* its name is speciesData
*/
static void getVPSSMgrTypes(std::vector<XML_Node*> & spDataNodeList,
int& has_nasa_idealGas,
int& has_nasa_constVol,
int& has_shomate_idealGas,
int& has_shomate_constVol,
int& has_simple_idealGas,
int& has_simple_constVol,
int& has_water,
int& has_tpx,
int& has_hptx,
int& has_other)
{
string ssModel = "idealGas";
for (size_t n = 0; n < spDataNodeList.size(); n++) {
bool ifound = false;
XML_Node* spNode = spDataNodeList[n];
if (spNode->hasChild("standardState")) {
string mm = spNode->child("standardState")["model"];
if (mm == "waterIAPWS" || mm == "waterPDSS") {
has_water++;
ifound = true;
}
if (mm == "HKFT") {
has_hptx++;
ifound = true;
}
}
if (!ifound) {
if (spNode->hasChild("thermo")) {
const XML_Node& th = spNode->child("thermo");
if (spNode->hasChild("standardState")) {
ssModel = spNode->child("standardState")["model"];
}
if (th.hasChild("NASA")) {
if (ssModel == "idealGas") {
has_nasa_idealGas++;
} else if (ssModel == "constant_incompressible" ||
ssModel == "constantVolume") {
has_nasa_constVol++;
} else if (ssModel == "temperature_polynomial" ||
ssModel == "density_temperature_polynomial" ||
ssModel == "constant") {
has_other++;
} else {
throw CanteraError("getVPSSMgrTypes",
"Specified VPSSMgr model {} does not match any known type.",
spNode->attrib("name"));
}
ifound = true;
}
if (th.hasChild("Shomate")) {
if (ssModel == "idealGas") {
has_shomate_idealGas++;
} else if (ssModel == "constant_incompressible" ||
ssModel == "constantVolume") {
has_shomate_constVol++;
} else if (ssModel == "temperature_polynomial" ||
ssModel == "density_temperature_polynomial" ||
ssModel == "constant") {
has_other++;
} else {
throw CanteraError("getVPSSMgrTypes",
"Specified VPSSMgr model {} does not match any known type.",
spNode->attrib("name"));
}
ifound = true;
}
if (th.hasChild("const_cp")) {
if (ssModel == "idealGas") {
has_simple_idealGas++;
} else if (ssModel == "constant_incompressible" ||
ssModel == "constantVolume") {
has_simple_constVol++;
} else if (ssModel == "temperature_polynomial" ||
ssModel == "density_temperature_polynomial" ||
ssModel == "constant") {
has_other++;
} else {
throw CanteraError("getVPSSMgrTypes",
"Specified VPSSMgr model {} does not match any known type.",
spNode->attrib("name"));
}
ifound = true;
}
if (th.hasChild("poly")) {
if (th.child("poly")["order"] == "1") {
has_simple_constVol = 1;
ifound = true;
} else throw CanteraError("newSpeciesThermo",
"poly with order > 1 not yet supported");
}
if (th.hasChild("Mu0")) {
has_other++;
ifound = true;
}
if (th.hasChild("NASA9")) {
has_other++;
ifound = true;
}
if (th.hasChild("NASA9MULTITEMP")) {
has_other++;
ifound = true;
}
if (th.hasChild("adsorbate")) {
has_other++;
ifound = true;
}
if (th.hasChild("HKFT")) {
has_hptx++;
ifound = true;
}
} else {
throw CanteraError("getVPSSMgrTypes",
"Specified VPSSMgr model {} does not match any known type.",
spNode->attrib("name"));
}
}
}
}
VPSSMgrFactory::VPSSMgrFactory()
{
reg("idealgas",
[] (VPStandardStateTP* tp, MultiSpeciesThermo* st) {
return new VPSSMgr_IdealGas(tp, st); });
reg("constvol",
[] (VPStandardStateTP* tp, MultiSpeciesThermo* st) {
return new VPSSMgr_ConstVol(tp, st); });
reg("water_constvol",
[] (VPStandardStateTP* tp, MultiSpeciesThermo* st) {
return new VPSSMgr_Water_ConstVol(tp, st); });
reg("water_hkft",
[] (VPStandardStateTP* tp, MultiSpeciesThermo* st) {
return new VPSSMgr_Water_HKFT(tp, st); });
reg("general",
[] (VPStandardStateTP* tp, MultiSpeciesThermo* st) {
return new VPSSMgr_General(tp, st); });
}
void VPSSMgrFactory::deleteFactory()
{
std::unique_lock<std::mutex> lock(vpss_species_thermo_mutex);
delete s_factory;
s_factory = 0;
}
VPSSMgr* VPSSMgrFactory::newVPSSMgr(VPStandardStateTP* vp_ptr,
XML_Node* phaseNode_ptr,
std::vector<XML_Node*> & spDataNodeList)
{
std::string ssManager;
std::string vpssManager;
// First look for any explicit instructions within the XML Database for the
// standard state manager and the variable pressure standard state manager
if (phaseNode_ptr && phaseNode_ptr->hasChild("thermo")) {
const XML_Node& thermoNode = phaseNode_ptr->child("thermo");
if (thermoNode.hasChild("standardStateManager")) {
const XML_Node& ssNode = thermoNode.child("standardStateManager");
ssManager = ssNode["model"];
}
if (thermoNode.hasChild("variablePressureStandardStateManager")) {
const XML_Node& vpssNode = thermoNode.child("variablePressureStandardStateManager");
vpssManager = ba::to_lower_copy(vpssNode["model"]);
}
}
// first get the reference state handler.
MultiSpeciesThermo* spth = &vp_ptr->speciesThermo();
// Next, if we have specific directions, use them to get the VPSSSMgr object
// and return immediately
if (vpssManager != "") {
return create(vpssManager, vp_ptr, spth);
}
int inasaIG = 0, inasaCV = 0, ishomateIG = 0, ishomateCV = 0,
isimpleIG = 0, isimpleCV = 0, iwater = 0, itpx = 0, iother = 0;
int ihptx = 0;
try {
getVPSSMgrTypes(spDataNodeList, inasaIG, inasaCV, ishomateIG, ishomateCV,
isimpleIG, isimpleCV, iwater, itpx, ihptx, iother);
} catch (CanteraError) {
iother = 1;
}
if (iwater == 1) {
if (ihptx == 0) {
if (inasaIG || ishomateIG || isimpleIG) {
throw CanteraError("newVPSSMgr", "Ideal gas with liquid water");
} else {
return new VPSSMgr_Water_ConstVol(vp_ptr, spth);
}
} else {
if (inasaIG || ishomateIG || isimpleIG) {
throw CanteraError("newVPSSMgr", "Ideal gas with liquid water");
} else if (inasaCV || ishomateCV || isimpleCV) {
return new VPSSMgr_General(vp_ptr, spth);
} else {
return new VPSSMgr_Water_HKFT(vp_ptr, spth);
}
}
}
if ((inasaCV || ishomateCV || isimpleCV) &&
!inasaIG && !ishomateIG && !isimpleIG && !itpx && !ihptx && !iother) {
return new VPSSMgr_ConstVol(vp_ptr, spth);
}
return new VPSSMgr_General(vp_ptr, spth);
}
VPSSMgr* newVPSSMgr(VPStandardStateTP* tp_ptr,
XML_Node* phaseNode_ptr,
std::vector<XML_Node*> & spDataNodeList)
{
return VPSSMgrFactory::factory()->newVPSSMgr(tp_ptr, phaseNode_ptr, spDataNodeList);
}
}

View file

@ -1,123 +0,0 @@
/**
* @file VPSSMgrFactory.h
* Header for factory to build instances of classes that manage the
* standard-state thermodynamic properties of a set of species
* (see \ref mgrpdssthermocalc and class \link Cantera::VPSSMgrFactory VPSSMgrFactory\endlink);
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#ifndef VPSSSPECIESTHERMO_FACTORY_H
#define VPSSSPECIESTHERMO_FACTORY_H
#include "cantera/base/ctexceptions.h"
#include "cantera/base/FactoryBase.h"
#include "cantera/thermo/VPSSMgr.h"
namespace Cantera
{
//! Factory to build instances of classes that manage the
//! standard-state thermodynamic properties of a set of species.
/*!
* This class is responsible for making the decision concerning which
* derivative of VPSSMgr object to use. The VPSSMgr object is used to calculate
* thermodynamic functions for the standard state. It queries the database of
* species to understand what the requirements are for the submodels for all of
* the species in the phase. Then, it picks the derived VPSSMgr object to use
* and passes it back to the calling routine. It doesn't load any data into the
* derived VPSSMgr object.
*
* Making the choice of VPSSMgr types is the only thing this class does.
*
* This class is implemented as a singleton -- one in which only one instance is
* needed. The recommended way to access the factory is to call this static
* method, which instantiates the class if it is the first call, but otherwise
* simply returns the pointer to the existing instance.
*
* @ingroup mgrpdssthermocalc
*/
class VPSSMgrFactory : public Factory<VPSSMgr, VPStandardStateTP*, MultiSpeciesThermo*>
{
public:
//! Static method to return an instance of this class
/*!
* This class is implemented as a singleton -- one in which only one
* instance is needed. The recommended way to access the factory is to call
* this static method, which instantiates the class if it is the first call,
* but otherwise simply returns the pointer to the existing instance.
*/
static VPSSMgrFactory* factory() {
std::unique_lock<std::mutex> lock(vpss_species_thermo_mutex);
if (!s_factory) {
s_factory = new VPSSMgrFactory;
}
return s_factory;
}
//! Delete static instance of this class
/*!
* If it is necessary to explicitly delete the factory before the process
* terminates (for example, when checking for memory leaks) then this method
* can be called to delete it.
*/
void deleteFactory();
//! Create a new species property manager for a group of species
/*!
* This routine will look through species nodes. It will discover what each
* species needs for its species property managers. Then, it will create and
* return the proper species property manager to use.
*
* @param vp_ptr Variable pressure standard state ThermoPhase object
* that will be the owner.
* @param phaseNode_ptr Pointer to the ThermoPhase phase XML Node
* @param spDataNodeList Vector of XML_Nodes, each of which is a species XML
* Node. There are m_kk of these.
* @returns a pointer to a newly created species
* property manager object.
*/
virtual VPSSMgr* newVPSSMgr(VPStandardStateTP* vp_ptr,
XML_Node* phaseNode_ptr,
std::vector<XML_Node*> & spDataNodeList);
private:
//! pointer to the sole instance of this class
static VPSSMgrFactory* s_factory;
//! Decl of the static mutex variable that locks the
//! VPSSMgr factory singleton
static std::mutex vpss_species_thermo_mutex;
//! Constructor. This is made private, so that only the static
//! method factory() can instantiate the class.
VPSSMgrFactory();
};
////////////////////// Convenience functions ////////////////////
// These functions allow using a different factory class that
// derives from VPSSMgrFactory.
//////////////////////////////////////////////////////////////////
//! Function to return VPSSMgr manager
/*!
* This utility program will look through species nodes. It will discover what
* each species needs for its species property managers. Then, it will alloc
* and return the proper species property manager to use.
*
* These functions allow using a different factory class that
* derives from VPSSMgrFactory.
*
* @param vp_ptr Variable pressure standard state ThermoPhase object
* that will be the owner.
* @param phaseNode_ptr Pointer to the ThermoPhase phase XML Node
* @param spDataNodeList This vector contains a list
* of species XML nodes that will be in the phase
*/
VPSSMgr* newVPSSMgr(VPStandardStateTP* vp_ptr,
XML_Node* phaseNode_ptr,
std::vector<XML_Node*> & spDataNodeList);
}
#endif

View file

@ -1,117 +0,0 @@
/**
* @file VPSSMgr_ConstVol.cpp
* Definition file for a derived class that handles the calculation
* of standard state thermo properties for
* a set of species which have a constant molar volume pressure
* dependence (see \ref thermoprops and
* class \link Cantera::VPSSMgr_ConstVol VPSSMgr_ConstVol\endlink).
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#include "cantera/thermo/VPSSMgr_ConstVol.h"
#include "cantera/thermo/VPStandardStateTP.h"
#include "cantera/thermo/PDSS_ConstVol.h"
#include "cantera/base/ctml.h"
using namespace std;
namespace Cantera
{
VPSSMgr_ConstVol::VPSSMgr_ConstVol(VPStandardStateTP* vp_ptr, MultiSpeciesThermo* spth) :
VPSSMgr(vp_ptr, spth)
{
m_useTmpRefStateStorage = true;
m_useTmpStandardStateStorage = true;
}
/*
* Note, this is equal to the reference state entropies
* due to the zero volume expansivity:
* i.e., (dS/dp)_T = (dV/dT)_P = 0.0
*/
void VPSSMgr_ConstVol::_updateStandardStateThermo()
{
for (size_t k = 0; k < m_kk; k++) {
m_hss_RT[k] = m_h0_RT[k]
+ (m_plast - m_p0[k]) / (GasConstant * m_tlast) * m_Vss[k];
m_cpss_R[k] = m_cp0_R[k];
m_sss_R[k] = m_s0_R[k];
m_gss_RT[k] = m_hss_RT[k] - m_sss_R[k];
// m_Vss[k] constant
}
}
void VPSSMgr_ConstVol::getGibbs_RT_ref(doublereal* grt) const
{
if (m_useTmpRefStateStorage) {
std::copy(m_g0_RT.begin(), m_g0_RT.end(), grt);
} else {
throw CanteraError("VPSSMgr_ConstVol::getGibbs_RT_ref",
"unimplemented without m_useTmpRefStateStorage");
}
}
void VPSSMgr_ConstVol::getStandardVolumes_ref(doublereal* vol) const
{
if (m_useTmpStandardStateStorage) {
std::copy(m_Vss.begin(), m_Vss.end(), vol);
} else {
throw CanteraError("VPSSMgr_ConstVol::getStandardVolumes_ref",
"unimplemented without m_useTmpRefStateStorage");
}
}
void VPSSMgr_ConstVol::initThermoXML(XML_Node& phaseNode, const std::string& id)
{
VPSSMgr::initThermoXML(phaseNode, id);
XML_Node& speciesList = phaseNode.child("speciesArray");
XML_Node* speciesDB = get_XML_NameID("speciesData", speciesList["datasrc"],
&phaseNode.root());
for (size_t k = 0; k < m_kk; k++) {
const XML_Node* s = speciesDB->findByAttr("name", m_vptp_ptr->speciesName(k));
if (!s) {
throw CanteraError("VPSSMgr_ConstVol::initThermoXML",
"no species Node for species " + m_vptp_ptr->speciesName(k));
}
const XML_Node* ss = s->findByName("standardState");
if (!ss) {
throw CanteraError("VPSSMgr_ConstVol::initThermoXML",
"no standardState Node for species " + s->attrib("name"));
}
std::string model = ss->attrib("model");
if (model != "constant_incompressible" && model != "constantVolume") {
throw CanteraError("VPSSMgr_ConstVol::initThermoXML",
"standardState model for species isn't constant_incompressible: " + s->attrib("name"));
}
m_Vss[k] = getFloat(*ss, "molarVolume", "toSI");
}
}
PDSS* VPSSMgr_ConstVol::createInstallPDSS(size_t k, const XML_Node& speciesNode,
const XML_Node* const phaseNode_ptr)
{
const XML_Node* ss = speciesNode.findByName("standardState");
if (!ss) {
throw CanteraError("VPSSMgr_ConstVol::createInstallPDSS",
"no standardState Node for species " + speciesNode["name"]);
}
std::string model = ss->attrib("model");
if (model != "constant_incompressible" && model != "constantVolume") {
throw CanteraError("VPSSMgr_ConstVol::createInstallPDSS",
"standardState model for species isn't "
"constant_incompressible: " + speciesNode["name"]);
}
if (m_Vss.size() < k+1) {
m_Vss.resize(k+1, 0.0);
}
m_Vss[k] = getFloat(*ss, "molarVolume", "toSI");
installSTSpecies(k, speciesNode, phaseNode_ptr);
return new PDSS_ConstVol(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
}
}

View file

@ -1,154 +0,0 @@
/**
* @file VPSSMgr_General.cpp
* Definition file for a derived class that handles the calculation
* of standard state thermo properties for
* a set of species belonging to a single phase in a completely general
* but slow way (see \ref thermoprops and
* class \link Cantera::VPSSMgr_General VPSSMgr_General\endlink).
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#include "cantera/thermo/VPSSMgr_General.h"
#include "cantera/base/ctml.h"
#include "cantera/thermo/VPStandardStateTP.h"
#include "cantera/thermo/PDSS_IdealGas.h"
#include "cantera/thermo/PDSS_Water.h"
#include "cantera/thermo/PDSS_ConstVol.h"
#include "cantera/thermo/PDSS_SSVol.h"
#include "cantera/thermo/PDSS_HKFT.h"
#include "cantera/thermo/PDSS_IonsFromNeutral.h"
#include "cantera/base/utilities.h"
using namespace std;
namespace Cantera
{
VPSSMgr_General::VPSSMgr_General(VPStandardStateTP* vp_ptr,
MultiSpeciesThermo* spth) :
VPSSMgr(vp_ptr, spth)
{
// Might want to do something other than holding this true.
// However, for the sake of getting this all up and running,
// will not go there for now.
m_useTmpStandardStateStorage = true;
m_useTmpRefStateStorage = true;
}
void VPSSMgr_General::_updateRefStateThermo() const
{
if (m_useTmpRefStateStorage) {
for (size_t k = 0; k < m_kk; k++) {
PDSS* kPDSS = m_PDSS_ptrs[k];
kPDSS->setState_TP(m_tlast, m_plast);
m_h0_RT[k] = kPDSS->enthalpy_RT_ref();
m_s0_R[k] = kPDSS->entropy_R_ref();
m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
m_cp0_R[k] = kPDSS->cp_R_ref();
m_V0[k] = kPDSS->molarVolume_ref();
}
}
}
void VPSSMgr_General::_updateStandardStateThermo()
{
for (size_t k = 0; k < m_kk; k++) {
PDSS* kPDSS = m_PDSS_ptrs[k];
kPDSS->setState_TP(m_tlast, m_plast);
m_hss_RT[k] = kPDSS->enthalpy_RT();
m_sss_R[k] = kPDSS->entropy_R();
m_gss_RT[k] = m_hss_RT[k] - m_sss_R[k];
m_cpss_R[k] = kPDSS->cp_R();
m_Vss[k] = kPDSS->molarVolume();
}
}
void VPSSMgr_General::initThermo()
{
initLengths();
}
void VPSSMgr_General::getGibbs_ref(doublereal* g) const
{
if (m_useTmpRefStateStorage) {
std::copy(m_g0_RT.begin(), m_g0_RT.end(), g);
scale(g, g+m_kk, g, GasConstant * m_tlast);
} else {
for (size_t k = 0; k < m_kk; k++) {
PDSS* kPDSS = m_PDSS_ptrs[k];
kPDSS->setState_TP(m_tlast, m_plast);
double h0_RT = kPDSS->enthalpy_RT_ref();
double s0_R = kPDSS->entropy_R_ref();
g[k] = GasConstant * m_tlast * (h0_RT - s0_R);
}
}
}
PDSS* VPSSMgr_General::returnPDSS_ptr(size_t k, const XML_Node& speciesNode,
const XML_Node* const phaseNode_ptr, bool& doST)
{
PDSS* kPDSS = 0;
doST = true;
const XML_Node* const ss = speciesNode.findByName("standardState");
if (!ss) {
VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
kPDSS = new PDSS_IdealGas(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
return kPDSS;
}
std::string model = ss->attrib("model");
if (model == "constant_incompressible") {
VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
kPDSS = new PDSS_ConstVol(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
if (!kPDSS) {
throw CanteraError("VPSSMgr_General::returnPDSS_ptr", "new PDSS_ConstVol failed");
}
} else if (model == "waterIAPWS" || model == "waterPDSS") {
kPDSS = new PDSS_Water(m_vptp_ptr, 0);
m_spthermo->installPDSShandler(k, kPDSS, this);
m_useTmpRefStateStorage = false;
} else if (model == "HKFT") {
doST = false;
kPDSS = new PDSS_HKFT(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
m_spthermo->installPDSShandler(k, kPDSS, this);
} else if (model == "IonFromNeutral") {
doST = false;
kPDSS = new PDSS_IonsFromNeutral(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
if (!kPDSS) {
throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
"new PDSS_IonsFromNeutral failed");
}
m_spthermo->installPDSShandler(k, kPDSS, this);
} else if (model == "constant" || model == "temperature_polynomial" || model == "density_temperature_polynomial") {
VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
kPDSS = new PDSS_SSVol(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
if (!kPDSS) {
throw CanteraError("VPSSMgr_General::returnPDSS_ptr", "new PDSS_SSVol failed");
}
} else {
throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
"unknown standard state formulation: " + model);
}
return kPDSS;
}
PDSS* VPSSMgr_General::createInstallPDSS(size_t k, const XML_Node& speciesNode,
const XML_Node* const phaseNode_ptr)
{
bool doST;
PDSS* kPDSS = returnPDSS_ptr(k, speciesNode, phaseNode_ptr, doST);
if (m_PDSS_ptrs.size() < k+1) {
m_PDSS_ptrs.resize(k+1, 0);
}
m_PDSS_ptrs[k] = kPDSS;
m_kk = std::max(m_kk, k+1);
m_minTemp = std::max(m_minTemp, kPDSS->minTemp());
m_maxTemp = std::min(m_maxTemp, kPDSS->maxTemp());
m_p0.resize(std::max(m_p0.size(), k+1));
m_p0[k] = kPDSS->refPressure();
return kPDSS;
}
}

View file

@ -1,82 +0,0 @@
/**
* @file VPSSMgr_IdealGas.cpp
* Definition file for a derived class that handles the calculation
* of standard state thermo properties for
* a set of species which have an Ideal Gas dependence
* (see \ref thermoprops and
* class \link Cantera::VPSSMgr_IdealGas VPSSMgr_IdealGas\endlink).
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#include "cantera/thermo/VPSSMgr_IdealGas.h"
#include "cantera/base/ctml.h"
#include "cantera/thermo/SpeciesThermoFactory.h"
#include "cantera/thermo/MultiSpeciesThermo.h"
#include "cantera/thermo/PDSS_IdealGas.h"
using namespace std;
namespace Cantera
{
VPSSMgr_IdealGas::VPSSMgr_IdealGas(VPStandardStateTP* vp_ptr, MultiSpeciesThermo* spth) :
VPSSMgr(vp_ptr, spth)
{
m_useTmpRefStateStorage = true;
m_useTmpStandardStateStorage = true;
}
void VPSSMgr_IdealGas::getIntEnergy_RT(doublereal* urt) const
{
getEnthalpy_RT(urt);
for (size_t k = 0; k < m_kk; k++) {
urt[k] -= 1.0;
}
}
void VPSSMgr_IdealGas::getStandardVolumes(doublereal* vol) const
{
copy(m_Vss.begin(), m_Vss.end(), vol);
}
void VPSSMgr_IdealGas::_updateStandardStateThermo()
{
doublereal v = temperature() *GasConstant /m_plast;
for (size_t k = 0; k < m_kk; k++) {
m_hss_RT[k] = m_h0_RT[k];
m_cpss_R[k] = m_cp0_R[k];
m_sss_R[k] = m_s0_R[k] - log(m_plast / m_p0[k]);
m_gss_RT[k] = m_hss_RT[k] - m_sss_R[k];
m_Vss[k] = v;
}
}
PDSS* VPSSMgr_IdealGas::createInstallPDSS(size_t k, const XML_Node& speciesNode,
const XML_Node* const phaseNode_ptr)
{
const XML_Node* ss = speciesNode.findByName("standardState");
if (ss && ss->attrib("model") != "ideal_gas") {
throw CanteraError("VPSSMgr_IdealGas::createInstallPDSS",
"standardState model for species isn't "
"ideal_gas: " + speciesNode["name"]);
}
if (m_Vss.size() < k+1) {
m_Vss.resize(k+1, 0.0);
}
shared_ptr<SpeciesThermoInterpType> stit(
newSpeciesThermoInterpType(speciesNode.child("thermo")));
stit->validate(speciesNode["name"]);
m_spthermo->install_STIT(k, stit);
PDSS* kPDSS = new PDSS_IdealGas(m_vptp_ptr, k, speciesNode,
*phaseNode_ptr, true);
m_p0[k] = m_spthermo->refPressure(k);
return kPDSS;
}
}

View file

@ -1,231 +0,0 @@
/**
* @file VPSSMgr_Water_ConstVol.cpp
* Definition file for a derived class that handles the calculation
* of standard state thermo properties for pure water and
* a set of species which have a constant molar volume pressure
* dependence.
* (see \ref thermoprops and class
* \link Cantera::VPSSMgr_Water_ConstVol VPSSMgr_Water_ConstVol\endlink).
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#include "cantera/thermo/VPSSMgr_Water_ConstVol.h"
#include "cantera/thermo/PDSS_Water.h"
#include "cantera/thermo/PDSS_ConstVol.h"
#include "cantera/thermo/VPStandardStateTP.h"
#include "cantera/base/ctml.h"
using namespace std;
namespace Cantera
{
VPSSMgr_Water_ConstVol::VPSSMgr_Water_ConstVol(VPStandardStateTP* vp_ptr,
MultiSpeciesThermo* spth) :
VPSSMgr(vp_ptr, spth),
m_waterSS(0)
{
m_useTmpRefStateStorage = true;
m_useTmpStandardStateStorage = true;
}
void VPSSMgr_Water_ConstVol::getEnthalpy_RT_ref(doublereal* hrt) const
{
// Everything should be OK except for the water SS
m_p0[0] = m_waterSS->pref_safe(m_tlast);
if (m_p0[0] != m_plast) {
m_waterSS->setState_TP(m_tlast, m_p0[0]);
m_h0_RT[0] = (m_waterSS->enthalpy_mole()) / (GasConstant * m_tlast);
m_waterSS->setState_TP(m_tlast, m_plast);
} else {
m_h0_RT[0] = m_hss_RT[0];
}
copy(m_h0_RT.begin(), m_h0_RT.end(), hrt);
}
void VPSSMgr_Water_ConstVol::getGibbs_RT_ref(doublereal* grt) const
{
// Everything should be OK except for the water SS
m_p0[0] = m_waterSS->pref_safe(m_tlast);
if (m_p0[0] != m_plast) {
m_waterSS->setState_TP(m_tlast, m_p0[0]);
m_g0_RT[0] = (m_waterSS->gibbs_mole()) / (GasConstant * m_tlast);
m_waterSS->setState_TP(m_tlast, m_plast);
} else {
m_g0_RT[0] = m_gss_RT[0];
}
copy(m_g0_RT.begin(), m_g0_RT.end(), grt);
}
void VPSSMgr_Water_ConstVol::getGibbs_ref(doublereal* g) const
{
getGibbs_RT_ref(g);
for (size_t k = 0; k < m_kk; k++) {
g[k] *= GasConstant * m_tlast;
}
}
void VPSSMgr_Water_ConstVol::getEntropy_R_ref(doublereal* sr) const
{
// Everything should be OK except for the water SS
m_p0[0] = m_waterSS->pref_safe(m_tlast);
if (m_p0[0] != m_plast) {
m_waterSS->setState_TP(m_tlast, m_p0[0]);
m_s0_R[0] = (m_waterSS->entropy_mole()) / GasConstant;
m_waterSS->setState_TP(m_tlast, m_plast);
} else {
m_s0_R[0] = m_sss_R[0];
}
copy(m_s0_R.begin(), m_s0_R.end(), sr);
}
void VPSSMgr_Water_ConstVol::getCp_R_ref(doublereal* cpr) const
{
// Everything should be OK except for the water SS
m_p0[0] = m_waterSS->pref_safe(m_tlast);
if (m_p0[0] != m_plast) {
m_waterSS->setState_TP(m_tlast, m_p0[0]);
m_cp0_R[0] = (m_waterSS->cp_mole()) / GasConstant;
m_waterSS->setState_TP(m_tlast, m_plast);
} else {
m_cp0_R[0] = m_cpss_R[0];
}
copy(m_cp0_R.begin(), m_cp0_R.end(), cpr);
}
void VPSSMgr_Water_ConstVol::getStandardVolumes_ref(doublereal* vol) const
{
// Everything should be OK except for the water SS
m_p0[0] = m_waterSS->pref_safe(m_tlast);
if (m_p0[0] != m_plast) {
m_waterSS->setState_TP(m_tlast, m_p0[0]);
m_V0[0] = m_vptp_ptr->molecularWeight(0) / m_waterSS->density();
m_waterSS->setState_TP(m_tlast, m_plast);
} else {
m_V0[0] = m_Vss[0];
}
copy(m_V0.begin(), m_V0.end(), vol);
}
void VPSSMgr_Water_ConstVol::_updateRefStateThermo() const
{
m_p0[0] = m_waterSS->pref_safe(m_tlast);
m_spthermo->update(m_tlast, &m_cp0_R[0], &m_h0_RT[0], &m_s0_R[0]);
for (size_t k = 0; k < m_kk; k++) {
m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
m_vptp_ptr->providePDSS(k)->setTemperature(m_tlast);
}
m_waterSS->setState_TP(m_tlast, m_p0[0]);
m_h0_RT[0] = (m_waterSS->enthalpy_mole()) / (GasConstant * m_tlast);
m_s0_R[0] = (m_waterSS->entropy_mole()) / GasConstant;
m_cp0_R[0] = (m_waterSS->cp_mole()) / GasConstant;
m_g0_RT[0] = (m_h0_RT[0] - m_s0_R[0]);
m_V0[0] = m_waterSS->molarVolume();
m_waterSS->setState_TP(m_tlast, m_plast);
}
void VPSSMgr_Water_ConstVol::_updateStandardStateThermo()
{
for (size_t k = 1; k < m_kk; k++) {
m_hss_RT[k] = m_h0_RT[k] + (m_plast - m_p0[k]) / (GasConstant * m_tlast) * m_Vss[k];
m_cpss_R[k] = m_cp0_R[k];
m_sss_R[k] = m_s0_R[k];
m_gss_RT[k] = m_hss_RT[k] - m_sss_R[k];
// m_Vss[k] constant
PDSS* kPDSS = m_vptp_ptr->providePDSS(k);
kPDSS->setState_TP(m_tlast, m_plast);
}
// Do the water
m_waterSS->setState_TP(m_tlast, m_plast);
m_hss_RT[0] = (m_waterSS->enthalpy_mole()) / (GasConstant * m_tlast);
m_sss_R[0] = (m_waterSS->entropy_mole()) / GasConstant;
m_cpss_R[0] = (m_waterSS->cp_mole()) / GasConstant;
m_gss_RT[0] = (m_hss_RT[0] - m_sss_R[0]);
m_Vss[0] = m_waterSS->molarVolume();
}
void VPSSMgr_Water_ConstVol::initThermoXML(XML_Node& phaseNode,
const std::string& id)
{
VPSSMgr::initThermoXML(phaseNode, id);
XML_Node& speciesList = phaseNode.child("speciesArray");
XML_Node* speciesDB = get_XML_NameID("speciesData", speciesList["datasrc"],
&phaseNode.root());
if (!m_waterSS) {
throw CanteraError("VPSSMgr_Water_ConstVol::initThermoXML",
"bad dynamic cast");
}
m_waterSS->setState_TP(300., OneAtm);
m_Vss[0] = (m_waterSS->density()) / m_vptp_ptr->molecularWeight(0);
for (size_t k = 1; k < m_kk; k++) {
const XML_Node* s = speciesDB->findByAttr("name", m_vptp_ptr->speciesName(k));
if (!s) {
throw CanteraError("VPSSMgr_Water_ConstVol::initThermoXML",
"no species Node for species " + m_vptp_ptr->speciesName(k));
}
const XML_Node* ss = s->findByName("standardState");
if (!ss) {
throw CanteraError("VPSSMgr_Water_ConstVol::initThermoXML",
"no standardState Node for species " + s->attrib("name"));
}
if (ss->attrib("model") != "constant_incompressible") {
throw CanteraError("VPSSMgr_Water_ConstVol::initThermoXML",
"standardState model for species isn't "
"constant_incompressible: " + s->attrib("name"));
}
m_Vss[k] = getFloat(*ss, "molarVolume", "toSI");
}
}
PDSS* VPSSMgr_Water_ConstVol::createInstallPDSS(size_t k,
const XML_Node& speciesNode, const XML_Node* const phaseNode_ptr)
{
PDSS* kPDSS = 0;
// Will have to do something for water
// -> make sure it's species 0
// -> make sure it's designated as a real water EOS
if (k == 0) {
string xn = speciesNode["name"];
if (xn != "H2O(L)") {
throw CanteraError("VPSSMgr_Water_ConstVol::installSpecies",
"h2o wrong name: " + xn);
}
const XML_Node* ss = speciesNode.findByName("standardState");
std::string model = ss->attrib("model");
if (model != "waterIAPWS" && model != "waterPDSS") {
throw CanteraError("VPSSMgr_Water_ConstVol::installSpecies",
"wrong SS mode: " + model);
}
delete m_waterSS;
m_waterSS = new PDSS_Water(m_vptp_ptr, 0);
m_spthermo->installPDSShandler(k, m_waterSS, this);
kPDSS = m_waterSS;
} else {
VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
const XML_Node* ss = speciesNode.findByName("standardState");
if (!ss) {
throw CanteraError("VPSSMgr_Water_ConstVol::installSpecies",
"no standardState Node for species " + speciesNode.name());
}
if (ss->attrib("model") != "constant_incompressible") {
throw CanteraError("VPSSMgr_Water_ConstVol::initThermoXML",
"standardState model for species isn't "
"constant_incompressible: " + speciesNode.name());
}
if (m_Vss.size() < k+1) {
m_Vss.resize(k+1, 0.0);
}
m_Vss[k] = getFloat(*ss, "molarVolume", "toSI");
// instantiate a new kPDSS object
kPDSS = new PDSS_ConstVol(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
m_p0[k] = kPDSS->refPressure();
}
return kPDSS;
}
}

View file

@ -1,229 +0,0 @@
/**
* @file VPSSMgr_Water_HKFT.cpp
* Definition file for a derived class that handles the calculation
* of standard state thermo properties for pure water and
* a set of species which obey the HKFT standard state
* dependence
* (see \ref thermoprops and class
* \link Cantera::VPSSMgr_Water_HKFT VPSSMgr_Water_HKFT\endlink).
*/
// This file is part of Cantera. See License.txt in the top-level directory or
// at http://www.cantera.org/license.txt for license and copyright information.
#include "cantera/thermo/VPSSMgr_Water_HKFT.h"
#include "cantera/thermo/PDSS_Water.h"
#include "cantera/thermo/PDSS_HKFT.h"
#include "cantera/thermo/VPStandardStateTP.h"
#include "cantera/thermo/MultiSpeciesThermo.h"
#include "cantera/base/xml.h"
#include "cantera/base/stringUtils.h"
using namespace std;
namespace Cantera
{
VPSSMgr_Water_HKFT::VPSSMgr_Water_HKFT(VPStandardStateTP* vp_ptr,
MultiSpeciesThermo* spth) :
VPSSMgr(vp_ptr, spth),
m_waterSS(0),
m_tlastRef(-1.0)
{
m_useTmpRefStateStorage = true;
m_useTmpStandardStateStorage = true;
}
void VPSSMgr_Water_HKFT::getEnthalpy_RT_ref(doublereal* hrt) const
{
updateRefStateThermo();
copy(m_h0_RT.begin(), m_h0_RT.end(), hrt);
}
void VPSSMgr_Water_HKFT::getGibbs_RT_ref(doublereal* grt) const
{
updateRefStateThermo();
copy(m_g0_RT.begin(), m_g0_RT.end(), grt);
}
void VPSSMgr_Water_HKFT::getGibbs_ref(doublereal* g) const
{
getGibbs_RT_ref(g);
for (size_t k = 0; k < m_kk; k++) {
g[k] *= GasConstant * m_tlast;
}
}
void VPSSMgr_Water_HKFT::getEntropy_R_ref(doublereal* sr) const
{
updateRefStateThermo();
copy(m_s0_R.begin(), m_s0_R.end(), sr);
}
void VPSSMgr_Water_HKFT::getCp_R_ref(doublereal* cpr) const
{
updateRefStateThermo();
copy(m_cp0_R.begin(), m_cp0_R.end(), cpr);
}
void VPSSMgr_Water_HKFT::getStandardVolumes_ref(doublereal* vol) const
{
updateRefStateThermo();
copy(m_V0.begin(), m_V0.end(), vol);
}
void VPSSMgr_Water_HKFT::setState_P(doublereal pres)
{
if (m_plast != pres) {
m_plast = pres;
_updateStandardStateThermo();
}
}
void VPSSMgr_Water_HKFT::setState_T(doublereal temp)
{
if (m_tlast != temp) {
m_tlast = temp;
_updateStandardStateThermo();
}
}
void VPSSMgr_Water_HKFT::setState_TP(doublereal temp, doublereal pres)
{
if (m_tlast != temp) {
m_tlast = temp;
m_plast = pres;
_updateStandardStateThermo();
} else if (m_plast != pres) {
m_plast = pres;
_updateStandardStateThermo();
}
}
void VPSSMgr_Water_HKFT::updateRefStateThermo() const
{
if (m_tlastRef != m_tlast) {
m_tlastRef = m_tlast;
_updateRefStateThermo();
}
}
void VPSSMgr_Water_HKFT::_updateRefStateThermo() const
{
m_p0[0] = m_waterSS->pref_safe(m_tlast);
m_waterSS->setState_TP(m_tlast, m_p0[0]);
m_h0_RT[0] = (m_waterSS->enthalpy_mole()) / (GasConstant * m_tlast);
m_s0_R[0] = (m_waterSS->entropy_mole()) / GasConstant;
m_cp0_R[0] = (m_waterSS->cp_mole()) / GasConstant;
m_g0_RT[0] = (m_hss_RT[0] - m_sss_R[0]);
m_V0[0] = (m_waterSS->density()) / m_vptp_ptr->molecularWeight(0);
PDSS* ps;
for (size_t k = 1; k < m_kk; k++) {
ps = m_vptp_ptr->providePDSS(k);
ps->setState_TP(m_tlast, m_p0[0]);
m_cp0_R[k] = ps->cp_R();
m_s0_R[k] = ps->entropy_mole() / GasConstant;
m_g0_RT[k] = ps->gibbs_RT();
m_h0_RT[k] = m_g0_RT[k] + m_s0_R[k];
m_V0[k] = ps->molarVolume();
}
m_waterSS->setState_TP(m_tlast, m_plast);
for (size_t k = 1; k < m_kk; k++) {
ps = m_vptp_ptr->providePDSS(k);
ps->setState_TP(m_tlast, m_plast);
}
}
void VPSSMgr_Water_HKFT::_updateStandardStateThermo()
{
// Do the water
m_waterSS->setState_TP(m_tlast, m_plast);
m_hss_RT[0] = (m_waterSS->enthalpy_mole()) / (GasConstant * m_tlast);
m_sss_R[0] = (m_waterSS->entropy_mole()) / GasConstant;
m_cpss_R[0] = (m_waterSS->cp_mole()) / GasConstant;
m_gss_RT[0] = (m_hss_RT[0] - m_sss_R[0]);
m_Vss[0] = (m_vptp_ptr->molecularWeight(0)) / (m_waterSS->density());
for (size_t k = 1; k < m_kk; k++) {
PDSS* ps = m_vptp_ptr->providePDSS(k);
ps->setState_TP(m_tlast, m_plast);
m_cpss_R[k] = ps->cp_R();
m_sss_R[k] = ps->entropy_R();
m_gss_RT[k] = ps->gibbs_RT();
m_hss_RT[k] = m_gss_RT[k] + m_sss_R[k];
m_Vss[k] = ps->molarVolume();
}
}
void VPSSMgr_Water_HKFT::initThermoXML(XML_Node& phaseNode,
const std::string& id)
{
VPSSMgr::initThermoXML(phaseNode, id);
XML_Node& speciesList = phaseNode.child("speciesArray");
XML_Node* speciesDB = get_XML_NameID("speciesData", speciesList["datasrc"],
&phaseNode.root());
m_waterSS->setState_TP(300., OneAtm);
m_Vss[0] = (m_waterSS->density()) / m_vptp_ptr->molecularWeight(0);
for (size_t k = 1; k < m_kk; k++) {
string name = m_vptp_ptr->speciesName(k);
const XML_Node* s = speciesDB->findByAttr("name", name);
if (!s) {
throw CanteraError("VPSSMgr_Water_HKFT::initThermoXML",
"No species Node for species " + name);
}
const XML_Node* ss = s->findByName("standardState");
if (!ss) {
throw CanteraError("VPSSMgr_Water_HKFT::initThermoXML",
"No standardState Node for species " + name);
}
if (!ba::iequals(ss->attrib("model"), "hkft")) {
throw CanteraError("VPSSMgr_Water_HKFT::initThermoXML",
"Standard state model for a solute species isn't "
"the HKFT standard state model: " + name);
}
}
}
PDSS* VPSSMgr_Water_HKFT::createInstallPDSS(size_t k,
const XML_Node& speciesNode, const XML_Node* const phaseNode_ptr)
{
PDSS* kPDSS = 0;
const XML_Node* ss = speciesNode.findByName("standardState");
if (!ss) {
throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
"No standardState Node for species " + speciesNode["name"]);
}
// Will have to do something for water
// -> make sure it's species 0
// -> make sure it's designated as a real water EOS
if (k == 0) {
if (speciesNode["name"] != "H2O(L)") {
throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
"h2o wrong name: " + speciesNode["name"]);
}
std::string model = ss->attrib("model");
if (model != "waterIAPWS" && model != "waterPDSS") {
throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
"wrong SS mode: " + model);
}
delete m_waterSS;
m_waterSS = new PDSS_Water(m_vptp_ptr, 0);
m_spthermo->installPDSShandler(k, m_waterSS, this);
kPDSS = m_waterSS;
} else {
if (ss->attrib("model") != "HKFT") {
throw CanteraError("VPSSMgr_Water_HKFT::initThermoXML",
"standardState model for species isn't "
"HKFT: " + speciesNode["name"]);
}
kPDSS = new PDSS_HKFT(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
m_spthermo->installPDSShandler(k, kPDSS, this);
}
return kPDSS;
}
}

View file

@ -11,6 +11,15 @@
#include "cantera/thermo/VPStandardStateTP.h"
#include "cantera/thermo/PDSS.h"
#include "cantera/thermo/PDSS_IdealGas.h"
#include "cantera/thermo/PDSS_Water.h"
#include "cantera/thermo/PDSS_ConstVol.h"
#include "cantera/thermo/PDSS_SSVol.h"
#include "cantera/thermo/PDSS_HKFT.h"
#include "cantera/thermo/PDSS_IonsFromNeutral.h"
#include "cantera/thermo/SpeciesThermoFactory.h"
#include "cantera/base/utilities.h"
#include "cantera/base/ctml.h"
using namespace std;
@ -20,7 +29,8 @@ namespace Cantera
VPStandardStateTP::VPStandardStateTP() :
m_Pcurrent(OneAtm),
m_Tlast_ss(-1.0),
m_Plast_ss(-1.0)
m_Plast_ss(-1.0),
m_useTmpRefStateStorage(true)
{
}
@ -50,48 +60,52 @@ void VPStandardStateTP::getStandardChemPotentials(doublereal* g) const
void VPStandardStateTP::getEnthalpy_RT(doublereal* hrt) const
{
updateStandardStateThermo();
m_VPSS_ptr->getEnthalpy_RT(hrt);
std::copy(m_hss_RT.begin(), m_hss_RT.end(), hrt);
}
void VPStandardStateTP::getEntropy_R(doublereal* srt) const
void VPStandardStateTP::getEntropy_R(doublereal* sr) const
{
updateStandardStateThermo();
m_VPSS_ptr->getEntropy_R(srt);
std::copy(m_sss_R.begin(), m_sss_R.end(), sr);
}
void VPStandardStateTP::getGibbs_RT(doublereal* grt) const
{
updateStandardStateThermo();
m_VPSS_ptr->getGibbs_RT(grt);
std::copy(m_gss_RT.begin(), m_gss_RT.end(), grt);
}
void VPStandardStateTP::getPureGibbs(doublereal* g) const
{
updateStandardStateThermo();
m_VPSS_ptr->getStandardChemPotentials(g);
std::copy(m_gss_RT.begin(), m_gss_RT.end(), g);
scale(g, g+m_kk, g, RT());
}
void VPStandardStateTP::getIntEnergy_RT(doublereal* urt) const
{
updateStandardStateThermo();
m_VPSS_ptr->getIntEnergy_RT(urt);
std::copy(m_hss_RT.begin(), m_hss_RT.end(), urt);
for (size_t k = 0; k < m_kk; k++) {
urt[k] -= m_Plast_ss / RT() * m_Vss[k];
}
}
void VPStandardStateTP::getCp_R(doublereal* cpr) const
{
updateStandardStateThermo();
m_VPSS_ptr->getCp_R(cpr);
std::copy(m_cpss_R.begin(), m_cpss_R.end(), cpr);
}
void VPStandardStateTP::getStandardVolumes(doublereal* vol) const
{
updateStandardStateThermo();
m_VPSS_ptr->getStandardVolumes(vol);
std::copy(m_Vss.begin(), m_Vss.end(), vol);
}
const vector_fp& VPStandardStateTP::getStandardVolumes() const
{
updateStandardStateThermo();
return m_VPSS_ptr->getStandardVolumes();
return m_Vss;
}
// ----- Thermodynamic Values for the Species Reference States ----
@ -99,49 +113,79 @@ const vector_fp& VPStandardStateTP::getStandardVolumes() const
void VPStandardStateTP::getEnthalpy_RT_ref(doublereal* hrt) const
{
updateStandardStateThermo();
m_VPSS_ptr->getEnthalpy_RT_ref(hrt);
if (m_useTmpRefStateStorage) {
std::copy(m_h0_RT.begin(), m_h0_RT.end(), hrt);
} else {
throw NotImplementedError("VPStandardStateTP::getEnthalpy_RT_ref");
}
}
void VPStandardStateTP::getGibbs_RT_ref(doublereal* grt) const
{
updateStandardStateThermo();
m_VPSS_ptr->getGibbs_RT_ref(grt);
if (m_useTmpRefStateStorage) {
std::copy(m_g0_RT.begin(), m_g0_RT.end(), grt);
} else {
throw NotImplementedError("VPStandardStateTP::getGibbs_RT_ref");
}
}
void VPStandardStateTP::getGibbs_ref(doublereal* g) const
{
updateStandardStateThermo();
m_VPSS_ptr->getGibbs_ref(g);
if (m_useTmpRefStateStorage) {
std::copy(m_g0_RT.begin(), m_g0_RT.end(), g);
scale(g, g+m_kk, g, RT());
} else {
for (size_t k = 0; k < m_kk; k++) {
PDSS* kPDSS = m_PDSS_storage[k].get();
kPDSS->setState_TP(m_tlast, m_Plast_ss);
double h0_RT = kPDSS->enthalpy_RT_ref();
double s0_R = kPDSS->entropy_R_ref();
g[k] = RT() * (h0_RT - s0_R);
}
}
}
const vector_fp& VPStandardStateTP::Gibbs_RT_ref() const
{
updateStandardStateThermo();
return m_VPSS_ptr->Gibbs_RT_ref();
if (m_useTmpRefStateStorage) {
return m_g0_RT;
} else {
throw NotImplementedError("VPStandardStateTP::getGibbs_RT_ref");
}
}
void VPStandardStateTP::getEntropy_R_ref(doublereal* er) const
void VPStandardStateTP::getEntropy_R_ref(doublereal* sr) const
{
updateStandardStateThermo();
m_VPSS_ptr->getEntropy_R_ref(er);
if (m_useTmpRefStateStorage) {
std::copy(m_s0_R.begin(), m_s0_R.end(), sr);
} else {
throw NotImplementedError("VPStandardStateTP::getEntropy_R_ref");
}
}
void VPStandardStateTP::getCp_R_ref(doublereal* cpr) const
{
updateStandardStateThermo();
m_VPSS_ptr->getCp_R_ref(cpr);
if (m_useTmpRefStateStorage) {
std::copy(m_cp0_R.begin(), m_cp0_R.end(), cpr);
} else {
throw NotImplementedError("VPStandardStateTP::getCp_R_ref");
}
}
void VPStandardStateTP::getStandardVolumes_ref(doublereal* vol) const
{
updateStandardStateThermo();
m_VPSS_ptr->getStandardVolumes_ref(vol);
std::copy(m_Vss.begin(), m_Vss.end(), vol);
}
void VPStandardStateTP::initThermo()
{
ThermoPhase::initThermo();
m_VPSS_ptr->initThermo();
for (size_t k = 0; k < m_kk; k++) {
PDSS* kPDSS = m_PDSS_storage[k].get();
if (kPDSS) {
@ -150,16 +194,25 @@ void VPStandardStateTP::initThermo()
}
}
void VPStandardStateTP::setVPSSMgr(VPSSMgr* vp_ptr)
{
m_VPSS_ptr.reset(vp_ptr);
}
bool VPStandardStateTP::addSpecies(shared_ptr<Species> spec)
{
// Specifically skip ThermoPhase::addSpecies since the Species object
// doesn't have an associated SpeciesThermoInterpType object
return Phase::addSpecies(spec);
bool added = Phase::addSpecies(spec);
if (!added) {
return false;
}
m_h0_RT.push_back(0.0);
m_cp0_R.push_back(0.0);
m_g0_RT.push_back(0.0);
m_s0_R.push_back(0.0);
m_V0.push_back(0.0);
m_hss_RT.push_back(0.0);
m_cpss_R.push_back(0.0);
m_gss_RT.push_back(0.0);
m_sss_R.push_back(0.0);
m_Vss.push_back(0.0);
return true;
}
void VPStandardStateTP::setTemperature(const doublereal temp)
@ -201,12 +254,53 @@ void VPStandardStateTP::setState_TP(doublereal t, doublereal pres)
}
void VPStandardStateTP::createInstallPDSS(size_t k, const XML_Node& s,
const XML_Node* phaseNode_ptr)
const XML_Node* phaseNode)
{
if (m_PDSS_storage.size() < k+1) {
m_PDSS_storage.resize(k+1);
}
m_PDSS_storage[k].reset(m_VPSS_ptr->createInstallPDSS(k, s, phaseNode_ptr));
PDSS* kPDSS = nullptr;
bool use_STITbyPDSS;
const XML_Node* const ss = s.findByName("standardState");
if (!ss) {
use_STITbyPDSS = false;
kPDSS = new PDSS_IdealGas(this, k, s, *phaseNode, true);
} else {
std::string model = ss->attrib("model");
if (model == "constant_incompressible") {
kPDSS = new PDSS_ConstVol(this, k, s, *phaseNode, true);
use_STITbyPDSS = false;
} else if (model == "waterIAPWS" || model == "waterPDSS") {
kPDSS = new PDSS_Water(this, 0);
use_STITbyPDSS = true;
m_useTmpRefStateStorage = false;
} else if (model == "HKFT") {
kPDSS = new PDSS_HKFT(this, k, s, *phaseNode, true);
use_STITbyPDSS = true;
} else if (model == "IonFromNeutral") {
kPDSS = new PDSS_IonsFromNeutral(this, k, s, *phaseNode, true);
use_STITbyPDSS = true;
} else if (model == "constant" || model == "temperature_polynomial" || model == "density_temperature_polynomial") {
kPDSS = new PDSS_SSVol(this, k, s, *phaseNode, true);
use_STITbyPDSS = false;
} else {
throw CanteraError("VPStandardStateTP::createInstallPDSS",
"unknown standard state formulation: " + model);
}
}
if (use_STITbyPDSS) {
auto stit = make_shared<STITbyPDSS>(kPDSS);
m_spthermo->install_STIT(k, stit);
} else {
shared_ptr<SpeciesThermoInterpType> stit(
newSpeciesThermoInterpType(s.child("thermo")));
stit->validate(s["name"]);
m_spthermo->install_STIT(k, stit);
}
m_PDSS_storage[k].reset(kPDSS);
}
PDSS* VPStandardStateTP::providePDSS(size_t k)
@ -234,29 +328,39 @@ void VPStandardStateTP::initThermoXML(XML_Node& phaseNode, const std::string& id
kPDSS->initThermoXML(phaseNode, id);
}
}
m_VPSS_ptr->initThermoXML(phaseNode, id);
ThermoPhase::initThermoXML(phaseNode, id);
}
VPSSMgr* VPStandardStateTP::provideVPSSMgr()
{
return m_VPSS_ptr.get();
}
void VPStandardStateTP::_updateStandardStateThermo() const
{
double Tnow = temperature();
for (size_t k = 0; k < m_kk; k++) {
PDSS* kPDSS = m_PDSS_storage[k].get();
kPDSS->setState_TP(Tnow, m_Pcurrent);
// reference state thermo
if (Tnow != m_tlast && m_useTmpRefStateStorage) {
m_h0_RT[k] = kPDSS->enthalpy_RT_ref();
m_s0_R[k] = kPDSS->entropy_R_ref();
m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
m_cp0_R[k] = kPDSS->cp_R_ref();
m_V0[k] = kPDSS->molarVolume_ref();
}
// standard state thermo
m_hss_RT[k] = kPDSS->enthalpy_RT();
m_sss_R[k] = kPDSS->entropy_R();
m_gss_RT[k] = m_hss_RT[k] - m_sss_R[k];
m_cpss_R[k] = kPDSS->cp_R();
m_Vss[k] = kPDSS->molarVolume();
}
m_Plast_ss = m_Pcurrent;
m_Tlast_ss = Tnow;
AssertThrowMsg(m_VPSS_ptr != 0, "VPStandardStateTP::_updateStandardStateThermo()",
"Probably indicates that ThermoPhase object wasn't initialized correctly");
m_VPSS_ptr->setState_TP(Tnow, m_Pcurrent);
m_tlast = Tnow;
}
void VPStandardStateTP::updateStandardStateThermo() const
{
double Tnow = temperature();
if (Tnow != m_Tlast_ss || m_Pcurrent != m_Plast_ss) {
if (Tnow != m_Tlast_ss || Tnow != m_tlast || m_Pcurrent != m_Plast_ss) {
_updateStandardStateThermo();
}
}

View file

@ -1,252 +0,0 @@
<?xml version="1.0"?>
<ctml>
<phase id="water_constvol" dim="3">
<speciesArray datasrc="#species_waterSolution">
H2O(L) Cl- H+ Na+ OH-
</speciesArray>
<state>
<temperature units="K"> 298.15 </temperature>
<pressure units="Pa"> 101325.0 </pressure>
<soluteMolalities>
Na+:6.0954
Cl-:6.0954
H+:2.1628E-9
OH-:1.3977E-6
</soluteMolalities>
</state>
<thermo model="HMW">
<variablePressureStandardStateManager model="water_constvol" />
<standardConc model="solvent_volume" />
<activityCoefficients model="Pitzer">
<A_Debye> 1.175930 </A_Debye>
<B_Debye> 3.28640E9 </B_Debye>
<ionicRadius default="3.042843" units="Angstroms">
</ionicRadius>
<binarySaltParameters cation="Na+" anion="Cl-">
<beta0> 0.0765 </beta0>
<beta1> 0.2664 </beta1>
<beta2> 0.0 </beta2>
<Cphi> 0.00127 </Cphi>
<Alpha1> 2.0 </Alpha1>
</binarySaltParameters>
<binarySaltParameters cation="H+" anion="Cl-">
<beta0> 0.1775 </beta0>
<beta1> 0.2945 </beta1>
<beta2> 0.0 </beta2>
<Cphi> 0.0008 </Cphi>
<Alpha1> 2.0 </Alpha1>
</binarySaltParameters>
<binarySaltParameters cation="Na+" anion="OH-">
<beta0> 0.0864 </beta0>
<beta1> 0.253 </beta1>
<beta2> 0.0 </beta2>
<Cphi> 0.0044 </Cphi>
<Alpha1> 2.0 </Alpha1>
</binarySaltParameters>
<thetaAnion anion1="Cl-" anion2="OH-">
<theta> -0.05 </theta>
</thetaAnion>
<psiCommonCation cation="Na+" anion1="Cl-" anion2="OH-">
<theta> -0.05 </theta>
<Psi> -0.006 </Psi>
</psiCommonCation>
<thetaCation cation1="Na+" cation2="H+">
<theta> 0.036 </theta>
</thetaCation>
<psiCommonAnion anion="Cl-" cation1="Na+" cation2="H+">
<Theta> 0.036 </Theta>
<Psi> -0.004 </Psi>
</psiCommonAnion>
</activityCoefficients>
<solvent> H2O(L) </solvent>
</thermo>
<elementArray datasrc="elements.xml"> O H C E Fe Si N Na Cl </elementArray>
</phase>
<phase id="general" dim="3">
<speciesArray datasrc="#species_waterSolution">
H2O(L) Cl- H+ Na+ OH-
</speciesArray>
<state>
<temperature units="K"> 298.15 </temperature>
<pressure units="Pa"> 101325.0 </pressure>
<soluteMolalities>
Na+:6.0954
Cl-:6.0954
H+:2.1628E-9
OH-:1.3977E-6
</soluteMolalities>
</state>
<!-- thermo model identifies the inherited class
from ThermoPhase that will handle the thermodynamics.
-->
<thermo model="HMW">
<variablePressureStandardStateManager model="general" />
<standardConc model="solvent_volume" />
<activityCoefficients model="Pitzer">
<!-- A_Debye units = sqrt(kg/gmol)
This is adjusted to match the GWB value so
that numerical comparisons can be made
Aln = 0.5107
-->
<A_Debye> 1.175930 </A_Debye>
<!-- B_Debye units = sqrt(kg/gmol)/m
-->
<B_Debye> 3.28640E9 </B_Debye>
<ionicRadius default="3.042843" units="Angstroms">
</ionicRadius>
<binarySaltParameters cation="Na+" anion="Cl-">
<beta0> 0.0765 </beta0>
<beta1> 0.2664 </beta1>
<beta2> 0.0 </beta2>
<Cphi> 0.00127 </Cphi>
<Alpha1> 2.0 </Alpha1>
</binarySaltParameters>
<binarySaltParameters cation="H+" anion="Cl-">
<beta0> 0.1775 </beta0>
<beta1> 0.2945 </beta1>
<beta2> 0.0 </beta2>
<Cphi> 0.0008 </Cphi>
<Alpha1> 2.0 </Alpha1>
</binarySaltParameters>
<binarySaltParameters cation="Na+" anion="OH-">
<beta0> 0.0864 </beta0>
<beta1> 0.253 </beta1>
<beta2> 0.0 </beta2>
<Cphi> 0.0044 </Cphi>
<Alpha1> 2.0 </Alpha1>
</binarySaltParameters>
<thetaAnion anion1="Cl-" anion2="OH-">
<theta> -0.05 </theta>
</thetaAnion>
<psiCommonCation cation="Na+" anion1="Cl-" anion2="OH-">
<theta> -0.05 </theta>
<Psi> -0.006 </Psi>
</psiCommonCation>
<thetaCation cation1="Na+" cation2="H+">
<theta> 0.036 </theta>
</thetaCation>
<psiCommonAnion anion="Cl-" cation1="Na+" cation2="H+">
<Theta> 0.036 </Theta>
<Psi> -0.004 </Psi>
</psiCommonAnion>
</activityCoefficients>
<solvent> H2O(L) </solvent>
</thermo>
<elementArray datasrc="elements.xml"> O H C E Fe Si N Na Cl </elementArray>
</phase>
<speciesData id="species_waterSolution">
<species name="H2O(L)">
<atomArray>H:2 O:1 </atomArray>
<thermo>
<NASA Tmax="600.0" Tmin="273.14999999999998" P0="100000.0">
<floatArray name="coeffs" size="7">
7.255750050E+01, -6.624454020E-01, 2.561987460E-03, -4.365919230E-06,
2.781789810E-09, -4.188654990E+04, -2.882801370E+02
</floatArray>
</NASA>
</thermo>
<standardState model="waterIAPWS">
</standardState>
</species>
<species name="Na+">
<atomArray> Na:1 E:-1 </atomArray>
<charge> +1 </charge>
<thermo>
<Mu0 Pref="100000.0" Tmax="1000.0" Tmin="200.0">
<H298 units="cal/mol"> 0.0 </H298>
<numPoints> 2 </numPoints>
<floatArray size="2" title="Mu0Values" units="Dimensionless">
-125.5213, -125.5213
</floatArray>
<floatArray size="2" title="Mu0Temperatures">
298.15, 333.15
</floatArray>
</Mu0>
</thermo>
<standardState model="constant_incompressible">
<molarVolume> 1.3 </molarVolume>
</standardState>
</species>
<species name="Cl-">
<atomArray> Cl:1 E:1 </atomArray>
<charge> -1 </charge>
<standardState model="constant_incompressible">
<molarVolume> 1.3 </molarVolume>
</standardState>
<thermo>
<Mu0 Pref="100000.0" Tmax="333." Tmin="298.">
<H298 units="cal/mol"> 0.0 </H298>
<numPoints> 2 </numPoints>
<floatArray size="2" title="Mu0Values" units="Dimensionless">
-52.8716 , -52.8716
</floatArray>
<floatArray size="2" title="Mu0Temperatures">
298.15, 333.15
</floatArray>
</Mu0>
</thermo>
</species>
<species name="H+">
<atomArray> H:1 E:-1 </atomArray>
<charge> +1 </charge>
<standardState model="constant_incompressible">
<molarVolume> 1.3 </molarVolume>
</standardState>
<thermo>
<Mu0 Pref="100000.0" Tmax="333." Tmin="298.">
<H298 units="cal/mol"> 0.0 </H298>
<numPoints> 2 </numPoints>
<floatArray size="2" title="Mu0Values" units="Dimensionless">
0.0 , 0.0
</floatArray>
<floatArray size="2" title="Mu0Temperatures">
298.15, 333.15
</floatArray>
</Mu0>
</thermo>
</species>
<species name="OH-">
<atomArray> O:1 H:1 E:1 </atomArray>
<charge> -1 </charge>
<standardState model="constant_incompressible">
<molarVolume> 1.3 </molarVolume>
</standardState>
<thermo>
<Mu0 Pref="100000.0" Tmax="333." Tmin="298.">
<H298 units="cal/mol"> 0.0 </H298>
<numPoints> 2 </numPoints>
<floatArray size="2" title="Mu0Values" units="Dimensionless">
-91.523 , -91.523
</floatArray>
<floatArray size="2" title="Mu0Temperatures">
298.15, 333.15
</floatArray>
</Mu0>
</thermo>
</species>
</speciesData>
</ctml>

View file

@ -1,6 +1,5 @@
#include "gtest/gtest.h"
#include "cantera/thermo/MaskellSolidSolnPhase.h"
#include "cantera/thermo/VPSSMgr_General.h"
#include "cantera/thermo/ThermoFactory.h"
#include <iostream>

View file

@ -1,65 +0,0 @@
#include "gtest/gtest.h"
#include "cantera/thermo/HMWSoln.h"
using namespace Cantera;
TEST(HMW, VPSSMgrGeneral_vs_VPSSMgrWater_ConstVol)
{
// Calculations should give the same result using either the generic
// VPSSMgr_General class or one of the more specialized classes such as
// VPSSMgr_Water_ConstVol.
HMWSoln p1("../data/HMW_NaCl.xml", "water_constvol");
HMWSoln p2("../data/HMW_NaCl.xml", "general");
size_t n = p1.nSpecies();
vector_fp molalities(n);
p1.getMolalities(molalities.data());
molalities[2] = 2.1628E-9;
molalities[3] = 6.0997;
molalities[4] = 1.3977E-6;
molalities[1] = molalities[2] + molalities[3] - molalities[4];
p1.setMolalities(molalities.data());
p2.setMolalities(molalities.data());
p1.setState_TP(310.15, 201325);
p2.setState_TP(310.15, 201325);
vector_fp v1(n);
vector_fp v2(n);
p1.getStandardVolumes(v1.data());
p2.getStandardVolumes(v2.data());
for (size_t i = 0; i < n; i++) {
EXPECT_NEAR(v1[i], v2[i], 1e-9) << p1.speciesName(i);
}
p1.getCp_R(v1.data());
p2.getCp_R(v2.data());
for (size_t i = 0; i < n; i++) {
EXPECT_NEAR(v1[i], v2[i], 1e-10) << p1.speciesName(i);
}
p1.getEntropy_R(v1.data());
p2.getEntropy_R(v2.data());
for (size_t i = 0; i < n; i++) {
EXPECT_NEAR(v1[i], v2[i], 1e-10) << p1.speciesName(i);
}
p1.getEnthalpy_RT(v1.data());
p2.getEnthalpy_RT(v2.data());
for (size_t i = 0; i < n; i++) {
EXPECT_NEAR(v1[i], v2[i], 1e-10) << p1.speciesName(i);
}
p1.getChemPotentials_RT(v1.data());
p2.getChemPotentials_RT(v2.data());
for (size_t i = 0; i < n; i++) {
EXPECT_NEAR(v1[i], v2[i], 1e-10) << p1.speciesName(i);
}
p1.getGibbs_ref(v1.data());
p2.getGibbs_ref(v2.data());
for (size_t i = 0; i < n; i++) {
EXPECT_NEAR(v1[i], v2[i], 1e-4) << p1.speciesName(i);
}
EXPECT_NEAR(p1.entropy_mole(), p2.entropy_mole(), 1e-7);
EXPECT_NEAR(p1.enthalpy_mole(), p2.enthalpy_mole(), 1e-4);
}