From 0f446fa2b86d124f05d7d63aea855d9f93d32a85 Mon Sep 17 00:00:00 2001 From: Harry Moffat Date: Thu, 20 Oct 2005 23:27:42 +0000 Subject: [PATCH] Added the SingleSpeciesTP file as a trial commit. Want to get the bugs out of adding these files to the main distribution first. --- Cantera/src/thermo/.cvsignore | 3 + Cantera/src/thermo/Makefile.in | 70 +++ Cantera/src/thermo/SingleSpeciesTP.cpp | 482 +++++++++++++++++++ Cantera/src/thermo/SingleSpeciesTP.h | 639 +++++++++++++++++++++++++ 4 files changed, 1194 insertions(+) create mode 100644 Cantera/src/thermo/.cvsignore create mode 100644 Cantera/src/thermo/Makefile.in create mode 100644 Cantera/src/thermo/SingleSpeciesTP.cpp create mode 100644 Cantera/src/thermo/SingleSpeciesTP.h diff --git a/Cantera/src/thermo/.cvsignore b/Cantera/src/thermo/.cvsignore new file mode 100644 index 000000000..2f90591ed --- /dev/null +++ b/Cantera/src/thermo/.cvsignore @@ -0,0 +1,3 @@ +*.d +.depends +Makefile diff --git a/Cantera/src/thermo/Makefile.in b/Cantera/src/thermo/Makefile.in new file mode 100644 index 000000000..b8287db93 --- /dev/null +++ b/Cantera/src/thermo/Makefile.in @@ -0,0 +1,70 @@ +#/bin/sh +############################################################### +# $Author$ +# $Date$ +# $Revision$ +# +# Copyright 2002 California Institute of Technology +# +############################################################### + +.SUFFIXES : +.SUFFIXES : .cpp .d .o .h + +INCDIR = ../../../build/include/cantera/kernel/thermo +INSTALL_TSC = ../../../bin/install_tsc +do_ranlib = @DO_RANLIB@ + +CXX_FLAGS = @CXXFLAGS@ $(CXX_OPT) + +# Extended Cantera Thermodynamics Object Files +CATHERMO_OBJ = SingleSpeciesTP.o +CATHERMO_H = SingleSpeciesTP.h + +CXX_INCLUDES = -I.. @CXX_INCLUDES@ +LIB = @buildlib@/libcaThermo.a + +DEPENDS = $(CATHERMO_OBJ:.o=.d) + +all: $(LIB) + @(@INSTALL@ -d $(INCDIR)) + @(for lh in $(CATHERMO_H) ; do \ + $(INSTALL_TSC) "$${lh}" $(INCDIR) ; \ + done) +%.d: + g++ -MM $(CXX_INCLUDES) $*.cpp > $*.d + +.cpp.o: + @CXX@ -c $< $(CXX_FLAGS) $(CXX_INCLUDES) + +$(LIB): $(CATHERMO_OBJ) $(CATHERMO_H) + @ARCHIVE@ $(LIB) $(CATHERMO_OBJ) > /dev/null +ifeq ($(do_ranlib),1) + @RANLIB@ $(LIB) +endif + +clean: + @(for lh in $(CATHERMO_H) ; do \ + th=$(INCDIR)/"$${lh}" ; \ + if test -f "$${th}" ; then \ + $(RM) "$${th}" ; \ + echo "$(RM) $${th}" ; \ + fi \ + done) + @(if test -f $(LIB) ; then \ + $(RM) $(LIB) ; \ + echo "$(RM) $(LIB)" ; \ + fi) + $(RM) *.o *~ .depends + +depends: $(DEPENDS) + cat *.d > .depends + $(RM) $(DEPENDS) + +TAGS: + etags *.h *.cpp + +ifeq ($(wildcard .depends), .depends) +include .depends +endif + diff --git a/Cantera/src/thermo/SingleSpeciesTP.cpp b/Cantera/src/thermo/SingleSpeciesTP.cpp new file mode 100644 index 000000000..9c902acbc --- /dev/null +++ b/Cantera/src/thermo/SingleSpeciesTP.cpp @@ -0,0 +1,482 @@ +/** + * @file SingleSpeciesTP.cpp + */ + +/* + * Copywrite (2005) Sandia Corporation. Under the terms of + * Contract DE-AC04-94AL85000 with Sandia Corporation, the + * U.S. Government retains certain rights in this software. + */ + +/* + * $Author$ + * $Date$ + * $Revision$ + */ + +#include "SingleSpeciesTP.h" + +namespace Cantera { + + /* + * -------------- Constructors ------------------------------------ + * + */ + + /** + * SingleSpeciesTP(): + * + * Base constructor -> does nothing but called the inherited + * class constructor + */ + SingleSpeciesTP::SingleSpeciesTP() : + ThermoPhase() + { + } + + /** + * ~SingleSpeciesTP(): + * + * destructor -> does nothing but implicitly calls the inherited + * class destructors. + */ + SingleSpeciesTP::~SingleSpeciesTP() + { + } + /** + * + * ------------------- Utilities ---------------------------------- + * + */ + + /** + * eosType(): + * Creates an error because this is not a fully formed + * class + */ + int SingleSpeciesTP::eosType() const { + err("eosType"); + return -1; + } + + /** + * ------------ Molar Thermodynamic Properties -------------------- + * + * + * For this single species template, the molar properties of + * the mixture are identified with the partial molar properties + * of species number 0. The partial molar property routines + * are called to evaluate these functions. + */ + + /** + * enthalpy_mole(): + * + * Molar enthalpy. Units: J/kmol. + */ + doublereal SingleSpeciesTP::enthalpy_mole() const { + double hbar; + getPartialMolarEnthalpies(&hbar); + return hbar; + } + + /** + * enthalpy_mole(): + * + * Molar internal energy. Units: J/kmol. + */ + doublereal SingleSpeciesTP::intEnergy_mole() const { + double ubar; + getPartialMolarIntEnergies(&ubar); + return ubar; + } + + /** + * entropy_mole(): + * + * Molar entropy of the mixture. Units: J/kmol/K. + */ + doublereal SingleSpeciesTP::entropy_mole() const { + double sbar; + getPartialMolarEntropies(&sbar); + return sbar; + } + + /** + * gibbs_mole(): + * + * Molar Gibbs free energy of the mixture. Units: J/kmol/K. + */ + doublereal SingleSpeciesTP::gibbs_mole() const { + double gbar; + /* + * Get the chemical potential of the first species. + * This is the same as the partial molar Gibbs + * free energy. + */ + getChemPotentials(&gbar); + return gbar; + } + + /** + * cp_mole(): + * + * Molar heat capacity at constant pressure of the mixture. + * Units: J/kmol/K. + */ + doublereal SingleSpeciesTP::cp_mole() const { + double cpbar; + /* + * Really should have a partial molar heat capacity + * function in ThermoPhase. However, the standard + * state heat capacity will do fine here for now. + */ + //getPartialMolarCp(&cpbar); + getCp_R(&cpbar); + cpbar *= GasConstant; + return cpbar; + } + + /** + * cv_mole(): + * + * Molar heat capacity at constant volume of the mixture. + * Units: J/kmol/K. + * + * For single species, we go directory to the + * general Cp - Cv relation + * + * Cp = Cv + alpha**2 * V * T / beta + * + * where + * alpha = volume thermal expansion coefficient + * beta = isothermal compressibility + */ + doublereal SingleSpeciesTP::cv_mole() const { + doublereal cvbar = cp_mole(); + doublereal alpha = thermalExpansionCoeff(); + doublereal beta = isothermalCompressibility(); + doublereal molecW = molecularWeight(0); + doublereal V = molecW/density(); + doublereal T = temperature(); + if (beta != 0.0) { + cvbar -= alpha * alpha * V * T / beta; + } + return cvbar; + } + + /* + * ----------- Chemical Potentials and Activities ---------------------- + */ + + /* + * ----------- Partial Molar Properties of the Solution ----------------- + * + * These are calculated by reference to the standard state properties + * of the zeroeth species. + */ + + /** + * Get the array of chemical potentials at unit activity + * These are the standard state chemical potentials. + * \f$ \mu^0_k \f$. + */ + void SingleSpeciesTP::getChemPotentials(doublereal* mu) const { + getStandardChemPotentials(mu); + } + + /** + * Get the array of non-dimensional species chemical potentials + * These are partial molar Gibbs free energies. + * \f$ \mu_k / \hat R T \f$. + * Units: unitless + */ + void SingleSpeciesTP::getChemPotentials_RT(doublereal* murt) const { + getStandardChemPotentials(murt); + double rt = GasConstant * temperature(); + murt[0] /= rt; + } + + /** + * Get the species electrochemical potentials. Units: J/kmol. + * This method adds a term \f$ Fz_k \phi_k \f$ to + * each chemical potential. + * + * This is resolved here. A single single species phase + * is not allowed to have anything other than a zero + * charge. + */ + void SingleSpeciesTP::getElectrochemPotentials(doublereal* mu) const { + getChemPotentials(mu); + } + + /** + * Get the species partial molar enthalpies. Units: J/kmol. + */ + void SingleSpeciesTP:: + getPartialMolarEnthalpies(doublereal* hbar) const { + double _rt = GasConstant * temperature(); + getEnthalpy_RT(hbar); + hbar[0] *= _rt; + } + + /** + * Get the species partial molar internal energies. Units: J/kmol. + */ + void SingleSpeciesTP:: + getPartialMolarIntEnergies(doublereal* ubar) const { + double _rt = GasConstant * temperature(); + getIntEnergy_RT(ubar); + ubar[0] *= _rt; + } + + /** + * Get the species partial molar entropy. Units: J/kmol K. + */ + void SingleSpeciesTP:: + getPartialMolarEntropies(doublereal* sbar) const { + getEntropy_R(sbar); + sbar[0] *= GasConstant; + } + + /** + * Get the species partial molar volumes. Units: m^3/kmol. + */ + void SingleSpeciesTP::getPartialMolarVolumes(doublereal* vbar) const { + double mw = molecularWeight(0); + double dens = density(); + vbar[0] = mw / dens; + } + + /* + * ----- Properties of the Standard State of the Species in the Solution + * ----- + */ + + /** + * Get the dimensional Gibbs functions for the standard + * state of the species at the current T and P. + */ + void SingleSpeciesTP::getPureGibbs(doublereal* gpure) const { + getGibbs_RT(gpure); + gpure[0] *= GasConstant * temperature(); + } + + /** + * Get the molar volumes of each species in their standard + * states at the current + * T and P of the solution. + * units = m^3 / kmol + * + * We resolve this function at this level, by assigning + * the molec weight divided by the phase density + */ + void SingleSpeciesTP::getStandardVolumes(doublereal* vbar) const { + double mw = molecularWeight(0); + double dens = density(); + vbar[0] = mw / dens; + } + + /* + * ---- Thermodynamic Values for the Species Reference States ------- + */ + + /* + * ------------------ Setting the State ------------------------ + */ + + + void SingleSpeciesTP::setState_TPX(doublereal t, doublereal p, + const doublereal* x) { + setTemperature(t); setPressure(p); + } + + void SingleSpeciesTP::setState_TPX(doublereal t, doublereal p, + compositionMap& x) { + setTemperature(t); setPressure(p); + } + + void SingleSpeciesTP::setState_TPX(doublereal t, doublereal p, + const string& x) { + setTemperature(t); setPressure(p); + } + + void SingleSpeciesTP::setState_TPY(doublereal t, doublereal p, + const doublereal* y) { + setTemperature(t); setPressure(p); + } + + void SingleSpeciesTP::setState_TPY(doublereal t, doublereal p, + compositionMap& y) { + setTemperature(t); setPressure(p); + } + + void SingleSpeciesTP::setState_TPY(doublereal t, doublereal p, + const string& y) { + setTemperature(t); setPressure(p); + } + + void SingleSpeciesTP::setState_PX(doublereal p, doublereal* x) { + if (x[0] != 1.0) { + err("setStatePX -> x[0] not 1.0"); + } + setPressure(p); + } + + void SingleSpeciesTP::setState_PY(doublereal p, doublereal* y) { + if (y[0] != 1.0) { + err("setStatePY -> x[0] not 1.0"); + } + setMassFractions(y); setPressure(p); + } + + void SingleSpeciesTP::setState_HP(doublereal h, doublereal p, + doublereal tol) { + doublereal dt; + setPressure(p); + for (int n = 0; n < 50; n++) { + dt = (h - enthalpy_mass())/cp_mass(); + if (dt > 100.0) dt = 100.0; + else if (dt < -100.0) dt = -100.0; + setState_TP(temperature() + dt, p); + if (fabs(dt) < tol) { + return; + } + } + throw CanteraError("setState_HP","no convergence. dt = " + fp2str(dt)); + } + + void SingleSpeciesTP::setState_UV(doublereal u, doublereal v, + doublereal tol) { + doublereal dt; + setDensity(1.0/v); + for (int n = 0; n < 50; n++) { + dt = (u - intEnergy_mass())/cv_mass(); + if (dt > 100.0) dt = 100.0; + else if (dt < -100.0) dt = -100.0; + setTemperature(temperature() + dt); + if (fabs(dt) < tol) { + return; + } + } + throw CanteraError("setState_UV", + "no convergence. dt = " + fp2str(dt)+"\n" + +"u = "+fp2str(u)+" v = "+fp2str(v)+"\n"); + } + + void SingleSpeciesTP::setState_SP(doublereal s, doublereal p, + doublereal tol) { + doublereal dt; + setPressure(p); + for (int n = 0; n < 50; n++) { + dt = (s - entropy_mass())*temperature()/cp_mass(); + if (dt > 100.0) dt = 100.0; + else if (dt < -100.0) dt = -100.0; + setState_TP(temperature() + dt, p); + if (fabs(dt) < tol) { + return; + } + } + throw CanteraError("setState_SP","no convergence. dt = " + fp2str(dt)); + } + + void SingleSpeciesTP::setState_SV(doublereal s, doublereal v, + doublereal tol) { + doublereal dt; + setDensity(1.0/v); + for (int n = 0; n < 50; n++) { + dt = (s - entropy_mass())*temperature()/cv_mass(); + if (dt > 100.0) dt = 100.0; + else if (dt < -100.0) dt = -100.0; + setTemperature(temperature() + dt); + if (fabs(dt) < tol) { + return; + } + } + throw CanteraError("setState_SV","no convergence. dt = " + fp2str(dt)); + } + + /** + * This private function throws a cantera exception. It's used when + * this class doesn't have an answer for the question given to it, + * because the derived class isn't overriding a function. + */ + doublereal SingleSpeciesTP::err(string msg) const { + throw CanteraError("SingleSpeciesTP","Base class method " + +msg+" called. Equation of state type: " + +int2str(eosType())); + return 0; + } + + /** + * Returns the units of the standard and general concentrations + * Note they have the same units, as their divisor is + * defined to be equal to the activity of the kth species + * in the solution, which is unitless. + * + * This routine is used in print out applications where the + * units are needed. Usually, MKS units are assumed throughout + * the program and in the XML input files. + * + * On return uA contains the powers of the units (MKS assumed) + * of the standard concentrations and generalized concentrations + * for the kth species. + * + * uA[0] = kmol units - default = 1 + * uA[1] = m units - default = -nDim(), the number of spatial + * dimensions in the Phase class. + * uA[2] = kg units - default = 0; + * uA[3] = Pa(pressure) units - default = 0; + * uA[4] = Temperature units - default = 0; + * uA[5] = time units - default = 0 + */ + void SingleSpeciesTP::getUnitsStandardConc(double *uA, int k, int sizeUA) { + for (int i = 0; i < sizeUA; i++) { + if (i == 0) uA[0] = 1.0; + if (i == 1) uA[1] = -nDim(); + if (i == 2) uA[2] = 0.0; + if (i == 3) uA[3] = 0.0; + if (i == 4) uA[4] = 0.0; + if (i == 5) uA[5] = 0.0; + } + } + + /** + * @internal Initialize. 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. + * + * Inheriting objects should call this function + * + * @see importCTML.cpp + */ + void SingleSpeciesTP::initThermo() { + /* + * Check to make sure that there is one and only one species + * in this phase. + */ + if (m_kk != 1) { + err("singleSpeciesTP ERROR m_kk != 1"); + } + /* + * Make sure the species mole fraction is equal to 1.0; + */ + double x = 1.0; + setMoleFractions(&x); + /* + * Call the base class initThermo object. + */ + ThermoPhase::initThermo(); + } + +} + + + + diff --git a/Cantera/src/thermo/SingleSpeciesTP.h b/Cantera/src/thermo/SingleSpeciesTP.h new file mode 100644 index 000000000..1140f4ac6 --- /dev/null +++ b/Cantera/src/thermo/SingleSpeciesTP.h @@ -0,0 +1,639 @@ +/** + * @file SingleSpeciesTP.h + * + * Header file for class SingleSpeciesTP + * + */ + +/* + * Copywrite (2005) Sandia Corporation. Under the terms of + * Contract DE-AC04-94AL85000 with Sandia Corporation, the + * U.S. Government retains certain rights in this software. + */ + + +/* + * $Author$ + * $Date$ + * $Revision$ + * + */ + +#ifndef CT_SINGLESPECIESTP_H +#define CT_SINGLESPECIESTP_H + +#include "ThermoPhase.h" + + +namespace Cantera { + + + /** + * @defgroup thermoprops Thermodynamic Properties + * + * These classes are used to compute thermodynamic properties. + */ + + /** + * The SingleSpeciesTP class is a filter class for ThermoPhase. + * What it does is to simplify the construction of ThermoPhase + * objects by assuming that the phase consists of one and + * only one type of species. In other words, it's a stoichiometric + * phase. However, no assumptions are made concerning the + * thermodynamic functions or the equation of state of the + * phase. Therefore it's an incomplete description of + * the thermodynamics. The complete description must be + * made in a derived class. + */ + class SingleSpeciesTP : public ThermoPhase { + + public: + + /// Constructor. + SingleSpeciesTP(); + + /// Destructor + virtual ~SingleSpeciesTP(); + + /** + * + * @name Utilities + * @{ + */ + + /** + * Equation of state type flag. The base class returns + * zero. Subclasses should define this to return a unique + * non-zero value. Constants defined for this purpose are + * listed in mix_defs.h. + */ + virtual int eosType() const; + + /** + * @} + * @name Molar Thermodynamic Properties + * @{ + */ + + /* + * These functions are resolved at this level, by reference + * to the partial molar functions + */ + /// Molar enthalpy. Units: J/kmol. + doublereal enthalpy_mole() const; + + /// Molar internal energy. Units: J/kmol. + doublereal intEnergy_mole() const; + + /// Molar entropy. Units: J/kmol/K. + doublereal entropy_mole() const; + + /// Molar Gibbs function. Units: J/kmol. + doublereal gibbs_mole() const; + + /// Molar heat capacity at constant pressure. Units: J/kmol/K. + doublereal cp_mole() const; + + /// Molar heat capacity at constant volume. Units: J/kmol/K. + doublereal cv_mole() const; + + /** + * @} + * @name Mechanical Properties + * @{ + */ + + /** + * Pressure. Return the thermodynamic pressure (Pa). This + * method must be reimplemented in derived classes. + * Since the mass density, temperature, and mass fractions + * are stored, this method should use these + * values to implement the mechanical equation of state + * \f$ P(T, \rho, Y_1, \dots, Y_K) \f$. + */ + virtual doublereal pressure() const { + return err("pressure"); + } + + /** + * Set the pressure. + * Sets the thermodynamic pressure -> must be reimplemented + * in derived classes. Units: Pa. + */ + virtual void setPressure(doublereal p) { + err("setPressure"); + } + + /** + * The isothermal compressibility. Units: 1/Pa. + * The isothermal compressibility is defined as + * \f[ + * \kappa_T = -\frac{1}{v}\left(\frac{\partial v}{\partial P}\right)_T + * \f] + */ + virtual doublereal isothermalCompressibility() const { + err("isothermalCompressibility"); return -1.0; + } + + /** + * The thermal expansion coefficient. Units: 1/K. + * The thermal expansion coefficient is defined as + * + * \f[ + * \beta = \frac{1}{v}\left(\frac{\partial v}{\partial T}\right)_P + * \f] + */ + virtual doublereal thermalExpansionCoeff() const { + err("thermalExpansionCoeff()"); return -1.0; + } + + /** + * @} + * @name Potential Energy + * + * Species may have an additional potential energy due to the + * presence of external gravitation or electric fields. These + * methods allow specifying a potential energy for individual + * species. + * @{ + */ + + /** + * Set the potential energy of species k to pe. + * Units: J/kmol. + * This function must be reimplemented in inherited classes + * of ThermoPhase. + */ + virtual void setPotentialEnergy(int k, doublereal pe) { + err("setPotentialEnergy"); + } + + /** + * Get the potential energy of species k. + * Units: J/kmol. + * This function must be reimplemented in inherited classes + * of ThermoPhase. + */ + virtual doublereal potentialEnergy(int k) const { + return err("potentialEnergy"); + } + + /** + * @} + * @name Activities and Activity Concentrations + * + * The activity \f$a_k\f$ of a species in solution is + * related to the chemical potential by \f[ \mu_k = \mu_k^0(T) + * + \hat R T \log a_k. \f] The quantity \f$\mu_k^0(T)\f$ is + * the chemical potential at unit activity, which depends only + * on temperature. + * @{ + */ + + /** + * This method returns an array of generalized concentrations + * \f$ C_k\f$ that are defined such that + * \f$ a_k = C_k / C^0_k, \f$ where \f$ C^0_k \f$ + * is a standard concentration + * defined below. These generalized concentrations are used + * by kinetics manager classes to compute the forward and + * reverse rates of elementary reactions. + * + * @param c Array of generalized concentrations. The + * units depend upon the implementation of the + * reaction rate expressions within the phase. + */ + virtual void getActivityConcentrations(doublereal* c) const { + err("getActivityConcentrations"); + } + + /** + * The standard concentration \f$ C^0_k \f$ used to normalize + * the generalized concentration. In many cases, this quantity + * will be the same for all species in a phase - for example, + * for an ideal gas \f$ C^0_k = P/\hat R T \f$. For this + * reason, this method returns a single value, instead of an + * array. However, for phases in which the standard + * concentration is species-specific (e.g. surface species of + * different sizes), this method may be called with an + * optional parameter indicating the species. + */ + virtual doublereal standardConcentration(int k=0) const { + err("standardConcentration"); + return -1.0; + } + + /** + * Returns the natural logarithm of the standard + * concentration of the kth species + */ + virtual doublereal logStandardConc(int k=0) const { + err("logStandardConc"); + return -1.0; + } + + /** + * Returns the units of the standard and generalized + * concentrations Note they have the same units, as their + * ratio is defined to be equal to the activity of the kth + * species in the solution, which is unitless. + * + * This routine is used in print out applications where the + * units are needed. Usually, MKS units are assumed throughout + * the program and in the XML input files. + * + * uA[0] = kmol units - default = 1 + * uA[1] = m units - default = -nDim(), the number of spatial + * dimensions in the Phase class. + * uA[2] = kg units - default = 0; + * uA[3] = Pa(pressure) units - default = 0; + * uA[4] = Temperature units - default = 0; + * uA[5] = time units - default = 0 + */ + virtual void getUnitsStandardConc(double *uA, int k = 0, + int sizeUA = 6); + + /** + * Get the array of non-dimensional activities at + * the current solution temperature, pressure, and + * solution concentration. + */ + void getActivities(doublereal* a) { + a[0] = 1.0; + } + + /** + * Get the array of non-dimensional activity coefficients at + * the current solution temperature, pressure, and + * solution concentration. + */ + virtual void getActivityCoefficients(doublereal* ac) const { + if (m_kk == 1) { + ac[0] = 1.0; + } else { + err("getActivityCoefficients"); + } + } + + //@} + /// @name Partial Molar Properties of the Solution ----------------- + //@{ + + /* + * These functions are all resolved here, to point to the + * standard state functions. + */ + + /** + * Get the species chemical potentials in the solution + * These are partial molar Gibbs free energies. + * Units: J/kmol. + */ + void getChemPotentials(doublereal* mu) const; + + /** + * Get the array of non-dimensional species chemical potentials + * These are partial molar Gibbs free energies. + * \f$ \mu_k / \hat R T \f$. + * Units: unitless + */ + void getChemPotentials_RT(doublereal* mu) const; + + /** + * Get the species electrochemical potentials. Units: J/kmol. + * This method adds a term \f$ Fz_k \phi_k \f$ to + * each chemical potential. + * + * This is resolved here. A single single species phase + * is not allowed to have anything other than a zero + * charge. + */ + void getElectrochemPotentials(doublereal* mu) const; + + /** + * Get the species partial molar enthalpies. Units: J/kmol. + */ + void getPartialMolarEnthalpies(doublereal* hbar) const; + + /** + * Get the species partial molar internal energies. Units: J/kmol. + */ + virtual void getPartialMolarIntEnergies(doublereal* ubar) const; + + /** + * Get the species partial molar entropies. Units: J/kmol. + */ + void getPartialMolarEntropies(doublereal* sbar) const; + + /** + * Get the species partial molar volumes. Units: m^3/kmol. + */ + void getPartialMolarVolumes(doublereal* vbar) const; + + //@} + /// @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 \f$. + */ + virtual void getStandardChemPotentials(doublereal* mu) const { + err("getStandardChemPotentials"); + } + + /** + * Get the nondimensional Enthalpy functions for the species + * at their standard states at the current + * T and P of the solution. + */ + virtual void getEnthalpy_RT(doublereal* hrt) const { + err("getEnthalpy_RT"); + } + + /** + * Get the nondimensional Enthalpy functions for the species + * at their standard states at the current + * T and P of the solution. + */ + virtual void getIntEnergy_RT(doublereal* urt) const { + err("getIntEnergy_RT"); + } + + /** + * Get the array of nondimensional Enthalpy functions for the + * standard state species + * at the current T and P of the solution. + */ + virtual void getEntropy_R(doublereal* sr) const { + err("getEntropy_R"); + } + + /** + * Get the nondimensional Gibbs functions for the species + * at their standard states of solution at the current T and P + * of the solution + */ + virtual void getGibbs_RT(doublereal* grt) const { + err("getGibbs_RT"); + } + + /** + * Get the dimensional Gibbs functions for the standard + * state of the species at the current T and P. + */ + void getPureGibbs(doublereal* gpure) const; + + /** + * Get the nondimensional Gibbs functions for the standard + * state of the species at the current T and P. + */ + virtual void getCp_R(doublereal* cpr) const { + err("getCp_RT"); + } + + /** + * Get the molar volumes of each species in their standard + * states at the current + * T and P of the solution. + * units = m^3 / kmol + * + * We resolve this function at this level, by assigning + * the molec weight divided by the phase density + */ + void getStandardVolumes(doublereal *vol) const; + + + //@} + /// @name Thermodynamic Values for the Species Reference States -------------------- + //@{ + + /** + * Returns the vector of nondimensional + * enthalpies of the reference state at the current temperature + * of the solution and the reference pressure for the species. + */ + virtual void getEnthalpy_RT_ref(doublereal *hrt) const { + err("enthalpy_RT_ref"); + } + + /** + * Returns the vector of nondimensional + * enthalpies of the reference state at the current temperature + * of the solution and the reference pressure for the species. + */ + virtual void getGibbs_RT_ref(doublereal *grt) const { + err("gibbs_RT_ref"); + } + + /** + * 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 + */ + virtual void getGibbs_ref(doublereal *g) const { + err("gibbs_ref"); + } + + /** + * Returns the vector of nondimensional + * entropies of the reference state at the current temperature + * of the solution and the reference pressure for the species. + */ + virtual void getEntropy_R_ref(doublereal *er) const { + err("entropy_R_ref"); + } + + /** + * 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. + */ + virtual void getCp_R_ref(doublereal *cprt) const { + err("cp_R_ref()"); + } + + /** + * @name Setting the State + * + * These methods set all or part of the thermodynamic + * state. + * @{ + */ + /** Set the temperature (K), pressure (Pa), and mole fractions. */ + void setState_TPX(doublereal t, doublereal p, const doublereal* x); + + /** Set the temperature (K), pressure (Pa), and mole fractions. */ + void setState_TPX(doublereal t, doublereal p, compositionMap& x); + + /** Set the temperature (K), pressure (Pa), and mole fractions. */ + void setState_TPX(doublereal t, doublereal p, const string& x); + + /** Set the temperature (K), pressure (Pa), and mass fractions. */ + void setState_TPY(doublereal t, doublereal p, const doublereal* y); + + /** Set the temperature (K), pressure (Pa), and mass fractions. */ + void setState_TPY(doublereal t, doublereal p, compositionMap& y); + + /** Set the temperature (K), pressure (Pa), and mass fractions. */ + void setState_TPY(doublereal t, doublereal p, const string& y); + + /** Set the pressure (Pa) and mole fractions. */ + void setState_PX(doublereal p, doublereal* x); + + /** Set the pressure (Pa) and mass fractions. */ + void setState_PY(doublereal p, doublereal* y); + + + /** Set the specific enthalpy (J/kg) and pressure (Pa). */ + virtual void setState_HP(doublereal h, doublereal p, + doublereal tol = 1.e-8); + + /** Set the specific enthalpy (J/kg) and specific volume (m^3/kg). */ + virtual void setState_UV(doublereal u, doublereal v, + doublereal tol = 1.e-8); + + /** Set the specific entropy (J/kg/K) and pressure (Pa). */ + virtual void setState_SP(doublereal s, doublereal p, + doublereal tol = 1.e-8); + + /** Set the specific entropy (J/kg/K) and specific volume (m^3/kg). */ + virtual void setState_SV(doublereal s, doublereal v, + doublereal tol = 1.e-8); + + //@} + + /** + * @name Chemical Equilibrium + * Chemical equilibrium. + * @{ + */ + + /** + * This method is used by the ChemEquil equilibrium solver. + * It sets the state such that the chemical potentials satisfy + * \f[ \frac{\mu_k}{\hat R T} = \sum_m A_{k,m} + * \left(\frac{\lambda_m} {\hat R T}\right) \f] where + * \f$ \lambda_m \f$ is the element potential of element m. The + * temperature is unchanged. Any phase (ideal or not) that + * implements this method can be equilibrated by ChemEquil. + */ + virtual void setToEquilState(const doublereal* lambda_RT) { + err("setToEquilState"); + } + + //@} + + + + /** + * @internal + * Set equation of state parameters. The number and meaning of + * these depends on the subclass. + * @param n number of parameters + * @param c array of \i n coefficients + * + */ + virtual void setParameters(int n, doublereal* c) {} + virtual void getParameters(int &n, doublereal * const c) {} + + /** + * Set equation of state parameter values from XML + * entries. This method is called by function importPhase in + * file importCTML.cpp when processing a phase definition in + * an input file. It should be overloaded in subclasses to set + * any parameters that are specific to that particular phase + * model. + * + * @param eosdata An XML_Node object corresponding to + * the "thermo" entry for this phase in the input file. + */ + virtual void setParametersFromXML(const XML_Node& eosdata) {} + + //--------------------------------------------------------- + /// @name Critical state properties. + /// These methods are only implemented by some subclasses. + + //@{ + + /// Critical temperature (K). + virtual doublereal critTemperature() const { + err("critTemperature"); return -1.0; + } + + /// Critical pressure (Pa). + virtual doublereal critPressure() const { + err("critPressure"); return -1.0; + } + + /// Critical density (kg/m3). + virtual doublereal critDensity() const { + err("critDensity"); return -1.0; + } + + //@} + + /// @name Saturation properties. + /// These methods are only implemented by subclasses that + /// implement full liquid-vapor equations of state. + /// + virtual doublereal satTemperature(doublereal p) const { + err("satTemperature"); return -1.0; + } + + virtual doublereal satPressure(doublereal t) const { + err("satPressure"); return -1.0; + } + + virtual doublereal vaporFraction() const { + err("vaprFraction"); return -1.0; + } + + virtual void setState_Tsat(doublereal t, doublereal x) { + err("setState_sat"); + } + + virtual void setState_Psat(doublereal p, doublereal x) { + err("setState_sat"); + } + + //@} + + + /** + * @internal Initialize. 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. + * + * @see importCTML.cpp + */ + virtual void initThermo(); + + + + + protected: + + private: + + doublereal err(string msg) const; + + }; + +} + +#endif + + + + +