00001 /** 00002 * @file ThermoPhase.h 00003 * Header file for class ThermoPhase, the base class for phases with 00004 * thermodynamic properties, and the text for the Module thermoprops 00005 * (see \ref thermoprops and class \link Cantera::ThermoPhase 00006 * ThermoPhase\endlink). 00007 */ 00008 00009 /* 00010 * $Date: 2010-02-12 17:28:49 -0500 (Fri, 12 Feb 2010) $ 00011 * $Revision: 401 $ 00012 * 00013 * Copyright 2002 California Institute of Technology 00014 * 00015 */ 00016 00017 #ifndef CT_THERMOPHASE_H 00018 #define CT_THERMOPHASE_H 00019 00020 #include "Phase.h" 00021 00022 00023 namespace Cantera { 00024 00025 /*! 00026 * @name CONSTANTS - Specification of the Molality conventention 00027 */ 00028 //@{ 00029 //! Standard state uses the molar convention 00030 const int cAC_CONVENTION_MOLAR = 0; 00031 //! Standard state uses the molality convention 00032 const int cAC_CONVENTION_MOLALITY = 1; 00033 //@} 00034 00035 /*! 00036 * @name CONSTANTS - Specification of the SS conventention 00037 */ 00038 //@{ 00039 //! Standard state uses the molar convention 00040 const int cSS_CONVENTION_TEMPERATURE = 0; 00041 //! Standard state uses the molality convention 00042 const int cSS_CONVENTION_VPSS = 1; 00043 //@} 00044 00045 00046 class XML_Node; 00047 00048 /** 00049 * @defgroup thermoprops Thermodynamic Properties 00050 * 00051 * 00052 * These classes are used to compute the thermodynamic properties of 00053 * phases of matter. The main base class for describing thermodynamic 00054 * properties of phases within %Cantera is called ThermoPhase. %ThermoPhase 00055 * is a large class that describes the interface within %Cantera to Thermodynamic 00056 * functions for a phase. 00057 * 00058 * The calculation of thermodynamic functions within %ThermoPhase is 00059 * broken down roughly into two or more steps. First, the standard state 00060 * properties 00061 * of all of the species are calculated at the current temperature and at 00062 * either 00063 * the current pressure or at a reference pressure. If the calculation is 00064 * carried out at a reference pressure instead of at the current pressure 00065 * the calculation is called a "reference state properties" calculation, 00066 * just to make the distinction (even though it may be considered to be 00067 * a fixed-pressure standard-state calculation). The next step is to 00068 * adjust the reference state calculation to the current pressure. The 00069 * thermodynamic 00070 * functions then are considered to be at the standard state of each species. 00071 * Lastly the mixing contributions are added to arrive at the thermodynamic 00072 * functions for the solution. 00073 * 00074 * The %ThermoPhase class provides interfaces to thermodynamic properties 00075 * calculated for 00076 * the reference state of each species, the standard state values for 00077 * each species, the thermodynamic functions for solution values, both 00078 * on a per mole of solution basis (i.e., enthalpy_mole()), on a per kg of 00079 * solution basis, and on a 00080 * partial molar basis for each species (i.e., 00081 * getPartialMolarEnthalpies(double *hbar)). 00082 * At each level, functions for the enthalpy, entropy, Gibbs free energy, 00083 * internal energy, and volume are provided. So, 5 levels (reference state, 00084 * standard state, partial molar, per mole of solution, and per mass of 00085 * solution) 00086 * and 5 functions multiplied together makes 25 possible functions. That's 00087 * why %ThermoPhase is such a large class. 00088 * 00089 * <H3> 00090 * Categorizing the Different %ThermoPhase Objects 00091 * </H3> 00092 * 00093 * ThermoPhase objects may be catelogged into four general bins. 00094 * 00095 * The first type are those whose underlying species have a reference state associated 00096 * with them. The reference state describes the thermodynamic functions for a 00097 * species at a single reference pressure, \f$p_0\f$. The thermodynamic functions 00098 * are specified via derived objects of the SpeciesThermoInterpType object class, and usually 00099 * consist of polynomials in temperature such as the NASA polynomial or the SHOMATE 00100 * polynomial. Calculators for these 00101 * reference states, which manage the calculation for all of the species 00102 * in a phase, are all derived from the virtual base class SimpleThermo. Calculators 00103 * are needed because the actual calculation of the reference state thermodynamics 00104 * has been shown to be relatively expensive. A great deal of work has gone 00105 * into devising efficient schemes for calculating the thermodynamic polynomials 00106 * of a set of species in a phase, in particular gas species in ideal gas phases 00107 * whose reference state thermodynamics is specified by NASA polynomials. 00108 * 00109 * The reference state thermodynamics combined with the mixing rules and 00110 * an assumption about the pressure dependence yields the thermodynamic functions for 00111 * the phase. 00112 * Expressions involving the specification of the fugacities of species would fall into 00113 * this category of %ThermoPhase objects. Note, however, that at this time, we do not 00114 * have any nontrivial examples of these types of phases. 00115 * In general, the independent variables that completely describe the state of the 00116 * system for this class are temperature, the 00117 * phase density, and \f$ N - 1 \f$ species mole or mass fractions. 00118 * Additionally, if the 00119 * phase involves charged species, the phase electric potential is an added independent variable. 00120 * Examples of the first class of %ThermoPhase functions, which includes the 00121 * IdealGasPhase object, the most commonly used object with %Cantera, are given below. 00122 * 00123 * - IdealGasPhase in IdealGasPhase.h 00124 * - StoichSubstance in StoichSubstance.h 00125 * - SurfPhase in SurfPhase.h 00126 * - EdgePhase in EdgePhase.h 00127 * - LatticePhase in LatticePhase.h 00128 * - LatticeSolidPhase in LatticeSolidPhase.h 00129 * - ConstDensityThermo in ConstDensityThermo.h 00130 * - PureFluidPhase in PureFluidPhase.h 00131 * - IdealSolidSolnPhase in IdealSolidSolnPhase.h 00132 * - VPStandardStateTP in VPStandardStateTP.h 00133 * 00134 * The second class of objects are actually all derivatives of the VPStandardState 00135 * class listed above. These classes assume that there exists a standard state 00136 * for each species in the phase, where the Thermodynamic functions are specified 00137 * as a function of temperature and pressure. Standard state objects for each 00138 * species are all derived from the PDSS virtual base class. Calculators for these 00139 * standard state, which coordinate the calculation for all of the species 00140 * in a phase, are all derived from the virtual base class VPSSMgr. 00141 * In turn, these standard states may employ reference state calculation to 00142 * aid in their calculations. And the VPSSMgr calculators may also employ 00143 * SimpleThermo calculators to help in calculating the properties for all of the 00144 * species in a phase. However, there are some PDSS objects which do not employ 00145 * reference state calculations. An example of this is real equation of state for 00146 * liquid water used within the calculation of brine thermodynamcis. 00147 * In general, the independent variables that completely describe the state of the 00148 * system for this class are temperature, the 00149 * phase pressure, and N - 1 species mole or mass fractions or molalities. 00150 * The standard state thermodynamics combined with the mixing rules yields 00151 * the thermodynamic functions for the phase. Mixing rules are given in terms 00152 * of specifying the molar-base activity coefficients or activities. 00153 * Lists of phases which belong to this group are given below 00154 * 00155 * - IdealSolnGasVPSS in IdealSolnGasVPSS.h 00156 * - MolalityVPSSTP in MolalityVPSSTP.h 00157 * 00158 * Note, the ideal gas and ideal solution approximations are lumped together 00159 * in the class IdealSolnGasVPSS, because at this level they look alike having 00160 * the same mixing rules with respect to the specification of the excess 00161 * thermodynamic properties. 00162 * 00163 * The third class of objects are actually all derivatives of the MolalityVPSSTP 00164 * object. They assume that the standard states are temperature and 00165 * pressure dependent. But, they also assume that the standard states are 00166 * molality-based. In other words they assume that the standard state of the solute 00167 * species are in a pseudo state of 1 molality but at infinite dilution. 00168 * A solvent must be specified in these calculations. The solvent is assumed 00169 * to be species zero, and its standard state is the pure solvent state. 00170 * Lists of phases which belong to this group are: 00171 * 00172 * - DebyeHuckel in DebyeHuckel.h 00173 * - IdealMolalSoln in IdealMolalSoln.h 00174 * - HMWSoln in HMWSoln.h 00175 * 00176 * The fourth class of %ThermoPhase objects are stoichiometric phases. 00177 * Stoichiometric phases are phases which consist of one and only one 00178 * species. The class SingleSpeciesTP is the base class for these 00179 * substances. Within the class, the general %ThermoPhase interface is 00180 * dumbed down so that phases consisting of one species may be 00181 * succinctly described. 00182 * These phases may have PDSS classes or SimpleThermo calculators associated 00183 * with them. 00184 * In general, the independent variables that completely describe the state of the 00185 * system for this class are temperature and either the 00186 * phase density or the phase pressure. 00187 * Lists of classes in this group are given below. 00188 * 00189 * - StoichSubstanceSSTP in StoichSubstanceSSTP.h 00190 * - WaterSSTP in WaterSSTP.h 00191 * 00192 * The reader may note that there are duplications in functionality in the 00193 * above lists. This is true. And, it's used for the internal verification of 00194 * capabilities within %Cantera's unit tests. 00195 * 00196 * 00197 * <H3> 00198 * Setting the %State of the phase 00199 * </H3> 00200 * 00201 * Typically, the way the ThermoPhase object works is that there are a set 00202 * of functions that set the state of the phase via setting the internal 00203 * independent variables. Then, there are another set of functions that 00204 * query the thermodynamic functions evalulated at the current %State of the 00205 * phase. Internally, most of the intermediate work generally occurs at the 00206 * point where the internal state of the system is set and not at the time 00207 * when individual thermodynamic functions are queried (though the actual 00208 * breakdown in work is dependent on the individual derived ThermoPhase object). 00209 * Therefore, for efficiency, the user should lump together queries of thermodynamic functions 00210 * after setting the state. Moreover, in setting the state, if the 00211 * density is the independent variable, the following order should be 00212 * used: 00213 * 00214 * - Set the temperature 00215 * - Set the mole or mass fractions or set the molalities 00216 * - set the pressure. 00217 * 00218 * For classes which inherit from VPStandardStateTP, the above order may 00219 * be used, or the following order may be used. It's not important. 00220 * 00221 * - Set the temperature 00222 * - Set the pressure 00223 * - Set the mole or mass fractions or set the molalities 00224 * 00225 * The following functions are used to set the state: 00226 * 00227 * <TABLE> 00228 * <TR> 00229 * <TD> \link ThermoPhase::setState_TPX() setState_TPX()\endlink </TD> 00230 * <TD> Sets the temperature, mole fractions and then the pressure 00231 * of the phase. </TD> 00232 * </TR> 00233 * <TR> 00234 * <TD> \link ThermoPhase::setState_TPY() setState_TPY()\endlink </TD> 00235 * <TD> Set the temperature, mass fractions and then the pressure 00236 * of the phase. </TD> 00237 * </TR> 00238 * <TR> 00239 * <TD> \link MolalityVPSSTP::setState_TPM() setState_TPM()\endlink </TD> 00240 * <TD> Set the temperature, solute molalities, and then the 00241 * pressure of the phase. Only from %ThermoPhase objects which 00242 * inherit from MolalityVPSSTP 00243 * </TD> 00244 * </TR> 00245 * <TR> 00246 * <TD> \link ThermoPhase::setState_TP() setState_TP()\endlink </TD> 00247 * <TD> Set the temperature, and then the pressure 00248 * of the phase. The mole fractions are assumed fixed. 00249 * </TD> 00250 * </TR> 00251 * <TR> 00252 * <TD> \link ThermoPhase::setState_PX() setState_PX()\endlink </TD> 00253 * <TD> Set the mole fractions and then the pressure 00254 * of the phase. The temperature is assumed fixed. 00255 * </TD> 00256 * </TR> 00257 * <TR> 00258 * <TD> \link ThermoPhase::setState_PY() setState_PY()\endlink </TD> 00259 * <TD> Set the mass fractions and then the pressure 00260 * of the phase. The temperature is assumed fixed. 00261 * </TD> 00262 * </TR> 00263 * <TR> 00264 * <TD> \link ThermoPhase::setState_HP() setState_HP()\endlink </TD> 00265 * <TD> Set the total specific enthalpy and the pressure 00266 * of the phase using an iterative process. 00267 * The mole fractions are assumed fixed 00268 * </TD> 00269 * </TR> 00270 * <TR> 00271 * <TD> \link ThermoPhase::setState_UV() setState_UV()\endlink </TD> 00272 * <TD> Set the total specific internal energy and the pressure 00273 * of the phase using an iterative process. 00274 * The mole fractions are assumed fixed. 00275 * </TD> 00276 * </TR> 00277 * <TR> 00278 * <TD> \link ThermoPhase::setState_SP() setState_SP()\endlink </TD> 00279 * <TD> Set the total specific internal energy and the pressure 00280 * of the phase using an iterative process. 00281 * The mole fractions are assumed fixed. 00282 * </TD> 00283 * </TR> 00284 * <TR> 00285 * <TD> \link ThermoPhase::setState_SV() setState_SV()\endlink </TD> 00286 * <TD> Set the total specific entropy and the total specific 00287 * molar volume of the phase using an iterative process. 00288 * The mole fractions are assumed fixed. 00289 * </TD> 00290 * </TR> 00291 * <TR> 00292 * <TD> \link State::setConcentrations() setConcentrations()\endlink </TD> 00293 * <TD> Set the concentrations of all the species in the 00294 * phase. Note this implicitly specifies the pressure and 00295 * density of the phase. The temperature is assumed fixed. 00296 * </TD> 00297 * </TR> 00298 * <TR> 00299 * <TD> \link State::setDensity() setDensity()\endlink </TD> 00300 * <TD> Set the total density of the phase. The temperature and 00301 * mole fractions are assumed fixed. Note this implicity 00302 * sets the pressure of the phase. 00303 * </TD> 00304 * </TR> 00305 * <TR> 00306 * <TD> \link State::setTemperature() setTemperature()\endlink </TD> 00307 * <TD> Set the temperature of the phase. The density and 00308 * the mole fractions of the phase are fixed. 00309 * </TD> 00310 * </TR> 00311 * <TR> 00312 * <TD> \link ThermoPhase::setToEquilState() setToEquilState()\endlink </TD> 00313 * <TD> Sets the mole fractions of the phase to their 00314 * equilibrium values assuming fixed temperature and 00315 * total density. 00316 * </TD> 00317 * </TR> 00318 * </TABLE> 00319 * 00320 * 00321 * 00322 * Some of the functions, like setState_TPX() have multiple forms depending upon 00323 * the format for how the species compositions are set. 00324 * 00325 * 00326 * Molar Basis vs. Molality Basis 00327 * 00328 * <H3> 00329 * Mechanical properties 00330 * </H3> 00331 * 00332 * The %ThermoPhase object specifies the mechanical equation of state of the 00333 * phase. Functions which are defined at the %ThermoPhase level to give the 00334 * user more information about the mechanical properties are: 00335 * 00336 * - ThermoPhase::pressure() 00337 * - ThermoPhase::isothermalCompressibility() 00338 * - ThermoPhase::thermalExpansionCoeff() 00339 * . 00340 * 00341 * <H3> 00342 * Treatment of the %Phase Potential and the electrochemical potential of a species 00343 * </H3> 00344 * 00345 * The electrochemical potential of species k in a phase p, \f$ \zeta_k \f$, 00346 * is related to the chemical potential via 00347 * the following equation, 00348 * 00349 * \f[ 00350 * \zeta_{k}(T,P) = \mu_{k}(T,P) + z_k \phi_p 00351 * \f] 00352 * 00353 * where \f$ \nu_k \f$ is the charge of species k, and \f$ \phi_p \f$ is 00354 * the electric potential of phase p. 00355 * 00356 * The potential \f$ \phi_p \f$ is tracked and internally storred within 00357 * the base %ThermoPhase object. It constitutes a specification of the 00358 * internal state of the phase; it's the third state variable, the first 00359 * two being temperature and density (or, pressure, for incompressible 00360 * equations of state). It may be set with the function, 00361 * ThermoPhase::setElectricPotential(), 00362 * and may be queried with the function ThermoPhase::electricPotential(). 00363 * 00364 * Note, the overall electrochemical potential of a phase may not be 00365 * changed by the potential because many phases enforce charge 00366 * neutrality: 00367 * 00368 * \f[ 00369 * 0 = \sum_k z_k X_k 00370 * \f] 00371 * 00372 * Whether charge neutrality is necessary for a phase is also specified 00373 * within the ThermoPhase object, by the function call 00374 * ThermoPhase::chargeNeutralityNecessary(). Note, that it is not 00375 * necessary for the IdealGas phase, currently. However, it is 00376 * necessary for liquid phases such as Cantera::DebyeHuckel and 00377 * Cantera::HMWSoln for the proper specification of the chemical potentials. 00378 * 00379 * 00380 * This equation, when applied to the \f$ \zeta_k \f$ equation described 00381 * above, results in a zero net change in the effective Gibbs free 00382 * energy of the phase. However, specific charged species in the phase 00383 * may increase or decrease their electochemical potentials, which will 00384 * have an effect on interfacial reactions involving charged species, 00385 * when there is a potential drop between phases. This effect is used 00386 * within the Cantera::InterfaceKinetics and Cantera::EdgeKinetics kinetics 00387 * objects classes. 00388 * 00389 * 00390 * Other internal state variables, that track the treatment of other 00391 * potential energy contributions, by adding contributions to the 00392 * chemical potential to create an effective chemical potential, 00393 * may be added at a later time. 00394 * 00395 * <H3> 00396 * Specification of Activities and Activity Conventions 00397 * </H3> 00398 * 00399 * 00400 * The activity \f$a_k\f$ and activity coefficient \f$ \gamma_k \f$ of a 00401 * species in solution is related to the chemical potential by 00402 * 00403 * \f[ 00404 * \mu_k = \mu_k^0(T,P) + \hat R T \log a_k.= \mu_k^0(T,P) + \hat R T \log x_k \gamma_k 00405 * \f] 00406 * 00407 * The quantity \f$\mu_k^0(T,P)\f$ is 00408 * the standard chemical potential at unit activity, 00409 * which depends on the temperature and pressure, 00410 * but not on the composition. The 00411 * activity is dimensionless. Within liquid electrolytes its common to use a 00412 * molality convention, where solute species employ the molality-based 00413 * activity coefficients: 00414 * 00415 * \f[ 00416 * \mu_k = \mu_k^\triangle(T,P) + R T ln(a_k^{\triangle}) = 00417 * \mu_k^\triangle(T,P) + R T ln(\gamma_k^{\triangle} \frac{m_k}{m^\triangle}) 00418 * \f] 00419 * 00420 * And, the solvent employs the following convention 00421 * \f[ 00422 * \mu_o = \mu^o_o(T,P) + RT ln(a_o) 00423 * \f] 00424 * 00425 * where \f$ a_o \f$ is often redefined in terms of the osmotic coefficient \f$ \phi \f$. 00426 * 00427 * \f[ 00428 * \phi = \frac{- ln(a_o)}{\tilde{M}_o \sum_{i \ne o} m_i} 00429 * \f] 00430 * 00431 * %ThermoPhase classes which employ the molality based convention are all derived 00432 * from the MolalityVPSSTP class. See the class description for further information 00433 * on its capabilities. 00434 * 00435 * The activity convention used by a %ThermoPhase object 00436 * may be queried via the ThermoPhase::activityConvention() function. A zero means molar based, 00437 * while a one means molality based. 00438 * 00439 * The function ThermoPhase::getActivities() returns a vector of activities. Whether these are 00440 * molar-based or molality-based depends on the value of activityConvention(). 00441 * 00442 * The function getActivityCoefficients() always returns molar-based activity 00443 * coefficients regardless of the activity convention used. The function 00444 * MolalityVPSSTP::getMolalityActivityCoefficients() returns molality 00445 * based activity coefficients for those ThermoPhase objects derived 00446 * from the MolalityVPSSTP class. The function MolalityVPSSTP::osmoticCoefficient() 00447 * returns the osmotic coefficient. 00448 * 00449 * <H3> 00450 * Activity Concentrations: Relationship of %ThermoPhase to %Kinetics Expressions 00451 * </H3> 00452 * 00453 * %Cantera can handle both thermodynamics and kinetics mechanisms. Reversible 00454 * kinetics 00455 * mechanisms within %Cantera must be compatible with thermodynamics in the 00456 * sense that at equilibrium, or at infinite times, the concentrations 00457 * of species must conform to thermodynamics. This means that for every 00458 * valid reversible kinetics reaction in a mechanism, it must be reducible to 00459 * an expression involving the ratio of the product activity to 00460 * the reactant activities being equal to the exponential of the 00461 * dimensionless standard state gibbs free energies of reaction. 00462 * Irreversible kinetics reactions do not have this requirement; however, 00463 * their usage can yield unexpected and inconsistent results in many 00464 * situations. 00465 * The actual units used in a kinetics expression depend 00466 * on the context or the relative field of study. For example, in 00467 * gas phase kinetics, species in kinetics expressions are expressed in 00468 * terms of concentrations, i.e., gmol cm-3. In solid phase studies, 00469 * however, kinetics is usually expressed in terms of unitless activities, 00470 * which most often equate to solid phase mole fractions. In order to 00471 * accomodate variability here, %Cantera has come up with the idea 00472 * of activity concentrations, \f$ C^a_k \f$. Activity concentrations are the expressions 00473 * used directly in kinetics expressions. 00474 * These activity (or generalized) concentrations are used 00475 * by kinetics manager classes to compute the forward and 00476 * reverse rates of elementary reactions. Note that they may 00477 * or may not have units of concentration --- they might be 00478 * partial pressures, mole fractions, or surface coverages, 00479 * The activity concentrations for species <I>k</I>, \f$ C^a_k \f$, are 00480 * related to the activity for species, k, \f$ a_k \f$, 00481 * via the following expression: 00482 * 00483 * \f[ 00484 * a_k = C^a_k / C^0_k 00485 * \f] 00486 * 00487 * \f$ C^0_k \f$ are called standard concentrations. They serve as multiplicative factors 00488 * bewteen the activities and the generalized concentrations. Standard concentrations 00489 * may be different for each species. They may depend on both the temperature 00490 * and the pressure. However, they may not depend 00491 * on the composition of the phase. For example, for the IdealGasPhase object 00492 * the standard concentration is defined as 00493 * 00494 * \f[ 00495 * C^0_k = P/ R T 00496 * \f] 00497 * 00498 * In many solid phase kinetics problems, 00499 * 00500 * \f[ 00501 * C^0_k = 1.0 , 00502 * \f] 00503 * 00504 * is employed making the units for activity concentrations in solids unitless. 00505 * 00506 * %ThermoPhase member functions dealing with this concept include 00507 * ThermoPhase::getActivityConcentrations() , which provides a vector of the current 00508 * activity concentrations. The function, ThermoPhase::standardConcentration(int k=0) returns 00509 * the standard concentration of the kth species. The function, 00510 * ThermoPhase::logStandardConc(int k=0), returns the natural log of the kth standard 00511 * concentration. The function ThermoPhase::getUnitsStandardConc() returns a vector of 00512 * doubles, specifying the MKS units of the standard concentration of the 00513 * kth species. 00514 * 00515 * 00516 * <H3> 00517 * Initialization of %ThermoPhase Objects within %Cantera 00518 * </H3> 00519 * 00520 * Instantiation of %ThermoPhase properties occurs by reading and 00521 * processing the XML data contained within an ctxml data file. 00522 * First a call to newPhase(std::string file, std::string id) or 00523 * newPhase(XML_Node &phase) 00524 * is made. The arguments serve to specify the 00525 * XML data structure containing the phase information. 00526 * 00527 * Within newPhase() a determination of what type of %ThermoPhase object should be 00528 * used is made. This is done within the routine ThermoFactory::newThermoPhase(std::string model) 00529 * or related routines. 00530 * Once the correct %ThermoPhase derived object is selected and instantiated with a 00531 * bare constructor, the 00532 * function Cantera::importPhase() is called with the %ThermoPhase derived object as 00533 * one of its arguments. 00534 * 00535 * Within importPhase(), a decision is made as to what type of 00536 * standard state, i.e., 00537 * either a reference state (just T dependent) or a standard state 00538 * (both P and T dependent), is to be used to calculate the 00539 * standard state properties of the species within the phase. 00540 * If only a reference state is needed 00541 * then a call to 00542 * \link #newSpeciesThermoMgr(std::vector<XML_Node*> spData_nodes, SpeciesThermoFactory* f=0, bool opt=false) newSpeciesThermoMgr()\endlink 00543 * is made in order 00544 * pick a manager, i.e., a derivative of the SpeciesThermo 00545 * object, to use. 00546 * 00547 * If a temperature and pressure dependent standard state is needed 00548 * then a call to VPSSMgrFactory::newVPSSMgr() 00549 * is made in order 00550 * pick a manager, i.e., a derivative of the VPSSMgr 00551 * object, to use. Along with the VPSSMgr designation comes a 00552 * determination of whether there is an accompanying SpeciesThermo 00553 * and what type of SpeciesThermo object to use in the 00554 * VPSSMgr calculations. 00555 * 00556 * Once these determinations are made, the %ThermoPhase object is 00557 * ready to start reading in the species information, which includes 00558 * all of the available standard state information about the 00559 * species. this is done within the routine installSpecies(). 00560 * 00561 * Within installSpecies(), most of the common steps for adding a 00562 * species are carried out. The element stoichiometry is read 00563 * and elements are added as needed to the list of elements 00564 * kept with the ThermoPhase object. The charge of the species 00565 * is read in. The species is added into the list 00566 * of species kept within the ThermoPhase object. Lastly, the 00567 * standard state thermodynamics for the species is read in. 00568 * For reference states, the routine, SpeciesThermoFactory::installThermoForSpecies(), 00569 * is used to read in the data. Essentially, this routine is a 00570 * factory routine for picking the correct subroutine to 00571 * call to read the XML data from the input file and install the 00572 * correct SpeciesThermoInterpType object into the SpeciesThermo object. 00573 * 00574 * Within installSpecies(), for standard states, the routine, 00575 * SpeciesThermoFactory::installVPThermoForSpecies() is 00576 * called. However, this is just a shell routine for calling 00577 * the VPSSMgr's derived VPSSMgr::createInstallPDSS() routine. 00578 * Within the VPSSMgr::createInstallPDSS() routine of the derived VPSSMgr's 00579 * object, the XML data from the input file is read and the 00580 * calculations for the species standard state is installed. 00581 * Additionally, the derived PDSS object is created and installed 00582 * into the VPStandardStateTP list containing all of the PDSS objects 00583 * for that phase. 00584 * 00585 * Now that all of the species standard states are read in and 00586 * installed into the ThermoPhase object, control once again 00587 * is returned to the importPhase() function. Two derived functions 00588 * are then called. The first one, ThermoPhase::initThermo(), is called. In this 00589 * routine, all internal arrays within the %ThermoPhase object are 00590 * dimensioned according to the number of elements and species. 00591 * Then, the function ThermoPhase::initThermoXML() is called. 00592 * This function is tasked with reading in all of the thermodynamic 00593 * function information specific to the calculation of the 00594 * phase information. This includes all of the information about 00595 * the activity coefficient calculation. 00596 * 00597 * After the ThermoPhase::initThermoXML() is finished, the 00598 * ThermoPhase routine is ready to receive requests for 00599 * thermodynamic property information. 00600 * 00601 * 00602 * There is an alternative way to instantiate %ThermoPhase objects that 00603 * is applicable to a significant proportion of %ThermoPhase classes. 00604 * The phase may be instantiated via a constructor that invokes the 00605 * XML data structure wherein the phase information is to be read directly. 00606 * In this case, the call to newPhase() and the call to 00607 * ThermoFactory::newThermoPhase(std::string model) 00608 * is not made. However, soon after that, the call to importPhase() is 00609 * made and thereafter instantiation follows the initialization course described 00610 * previously in order to avoid as much duplicate code as possible. 00611 * This alternative way to instantiate %ThermoPhase objects has the 00612 * advantage of working well with hard-coded situations. And, it 00613 * works well also with situations where new %ThermoPhase classes 00614 * are being developed and haven't yet made their way into the 00615 * factory routines. 00616 * 00617 * <H3> 00618 * Adding Additional Thermodynamics Models 00619 * </H3> 00620 * 00621 * In general, factory routines throw specific errors when encountering 00622 * unknown thermodynamics models in XML files. All of the error classes 00623 * derive from the class, CanteraError. 00624 * The newVPSSMgr() routines throws the UnknownVPSSMgr class error when 00625 * they encounter an unknown string in the XML input file specifying the 00626 * VPSSMgr class to use. 00627 * 00628 * Many of the important member functions in factory routines are 00629 * virtual classes. This means that a user may write their own 00630 * factory classes which inherit from the base %Cantera factory classes 00631 * to provide additional %ThermoPhase classes. 00632 * 00633 * 00634 * @see newPhase(std::string file, std::string id) Description for how to 00635 * read ThermoPhases from XML files. 00636 * @see newPhase(XML_Node &phase) How to call the Factory routine to create 00637 * and initialize %ThermoPhase objects. 00638 * @ingroup phases 00639 */ 00640 00641 00642 //! Base class for a phase with thermodynamic properties. 00643 /*! 00644 * Class %ThermoPhase is the base class for the family of classes 00645 * that represent phases of matter of any type. It defines a 00646 * common public interface, and implements a few methods. Most of 00647 * the methods, however, are declared virtual and are meant to be 00648 * overloaded in derived classes. The standard way used 00649 * throughout Cantera to compute properties of phases of matter is 00650 * through pointers of type ThermoPhase* that point to objects of 00651 * subclasses of ThermoPhase. 00652 * 00653 * Class %ThermoPhase extends class Phase by adding methods to compute 00654 * thermodynamic 00655 * properties in addition to the ones (temperature, density, 00656 * composition) that class Phase provides. The distinction is that 00657 * the methods declared in ThermoPhase require knowing the 00658 * particular equation of state of the phase of interest, while 00659 * those of class Phase do not, since they only involve data values 00660 * stored within the object. 00661 * 00662 * Instances of subclasses of %ThermoPhase should be created using 00663 * the factory class ThermoFactory, not by calling the constructor 00664 * directly. This allows new classes to be used with the various 00665 * Cantera language interfaces. 00666 * 00667 * To implement a new equation of state, derive a class from 00668 * ThermoPhase and overload the virtual methods in 00669 * ThermoPhase. Methods that are not needed can be left 00670 * unimplimented, which will cause an exception to be thrown if it 00671 * is called. 00672 * 00673 * Relationship with the kinetics operator: 00674 * 00675 * Describe activity coefficients. 00676 * 00677 * Describe K_a, K_p, and K_c, These are three different equilibrium 00678 * constants. 00679 * 00680 * K_a is the calculation of the equilibrium constant from the 00681 * standard state Gibbs free energy values. It is by definition 00682 * dimensionless. 00683 * 00684 * K_p is the calculation of the equilibrium constant from the 00685 * reference state gibbs free energy values. It is by definition 00686 * dimensionless. The pressure dependence is handled entirely 00687 * on the rhs of the equilibrium expression. 00688 * 00689 * K_c is the equilibrium constant calculated from the 00690 * activity concentrations. The dimensions depend on the number 00691 * of products and reactants. 00692 * 00693 * 00694 * The kinetics manager requires the calculation of K_c for the 00695 * calculation of the reverse rate constant 00696 * 00697 * 00698 * @ingroup thermoprops 00699 * @ingroup phases 00700 */ 00701 class ThermoPhase : public Phase { 00702 00703 public: 00704 00705 //! Constructor. Note that ThermoPhase is meant to be used as 00706 //! a base class, so this constructor should not be called 00707 //! explicitly. 00708 ThermoPhase(); 00709 00710 //! Destructor. Deletes the species thermo manager. 00711 virtual ~ThermoPhase(); 00712 00713 //!Copy Constructor for the %ThermoPhase object. 00714 /*! 00715 * @param right ThermoPhase to be copied 00716 */ 00717 ThermoPhase(const ThermoPhase &right); 00718 00719 //! Assignment operator 00720 /*! 00721 * This is NOT a virtual function. 00722 * 00723 * @param right Reference to %ThermoPhase object to be copied into the 00724 * current one. 00725 */ 00726 ThermoPhase& operator=(const ThermoPhase &right); 00727 00728 //! Duplication routine for objects which inherit from 00729 //! ThermoPhase. 00730 /*! 00731 * This virtual routine can be used to duplicate %ThermoPhase objects 00732 * inherited from %ThermoPhase even if the application only has 00733 * a pointer to %ThermoPhase to work with. 00734 * 00735 * These routines are basically wrappers around the derived copy 00736 * constructor. 00737 */ 00738 virtual ThermoPhase *duplMyselfAsThermoPhase() const; 00739 00740 /** 00741 * 00742 * @name Information Methods 00743 * @{ 00744 */ 00745 00746 //! Equation of state type flag. 00747 /*! 00748 * The base class returns 00749 * zero. Subclasses should define this to return a unique 00750 * non-zero value. Constants defined for this purpose are 00751 * listed in mix_defs.h. 00752 */ 00753 virtual int eosType() const { return 0; } 00754 00755 /** 00756 * Returns the reference pressure in Pa. This function is a wrapper 00757 * that calls the species thermo refPressure function. 00758 */ 00759 doublereal refPressure() const { 00760 return m_spthermo->refPressure(); 00761 } 00762 00763 00764 //! Minimum temperature for which the thermodynamic data for the species 00765 //! or phase are valid. 00766 /*! 00767 * If no argument is supplied, the 00768 * value returned will be the lowest temperature at which the 00769 * data for \e all species are valid. Otherwise, the value 00770 * will be only for species \a k. This function is a wrapper 00771 * that calls the species thermo minTemp function. 00772 * 00773 * @param k index of the species. Default is -1, which will return the max of the min value 00774 * over all species. 00775 */ 00776 doublereal minTemp(int k = -1) const { 00777 return m_spthermo->minTemp(k); 00778 } 00779 00780 #ifdef H298MODIFY_CAPABILITY 00781 00782 //! Report the 298 K Heat of Formation of the standard state of one species (J kmol-1) 00783 /*! 00784 * The 298K Heat of Formation is defined as the enthalpy change to create the standard state 00785 * of the species from its constituent elements in their standard states at 298 K and 1 bar. 00786 * 00787 * @param k species index 00788 * @return Returns the current value of the Heat of Formation at 298K and 1 bar 00789 */ 00790 doublereal Hf298SS(const int k) const { 00791 return (m_spthermo->reportOneHf298(k)); 00792 } 00793 00794 //! Modify the value of the 298 K Heat of Formation of one species in the phase (J kmol-1) 00795 /*! 00796 * The 298K heat of formation is defined as the enthalpy change to create the standard state 00797 * of the species from its constituent elements in their standard states at 298 K and 1 bar. 00798 * 00799 * @param k Species k 00800 * @param Hf298New Specify the new value of the Heat of Formation at 298K and 1 bar 00801 */ 00802 virtual void modifyOneHf298SS(const int k, const doublereal Hf298New) { 00803 m_spthermo->modifyOneHf298(k, Hf298New); 00804 } 00805 00806 #else 00807 00808 //! Report the 298 K Heat of Formation of the standard state of one species (J kmol-1) 00809 /*! 00810 * The 298K Heat of Formation is defined as the enthalpy change to create the standard state 00811 * of the species from its constituent elements in their standard states at 298 K and 1 bar. 00812 * 00813 * @param k species index 00814 * @return Returns the current value of the Heat of Formation at 298K and 1 bar 00815 */ 00816 doublereal Hf298SS(const int k) const { 00817 return err("Hf298SS - H298MODIFY_CAPABILITY not compiled in"); 00818 } 00819 00820 //! Modify the value of the 298 K Heat of Formation of one species in the phase (J kmol-1) 00821 /*! 00822 * The 298K heat of formation is defined as the enthalpy change to create the standard state 00823 * of the species from its constituent elements in their standard states at 298 K and 1 bar. 00824 * 00825 * @param k Species k 00826 * @param Hf298New Specify the new value of the Heat of Formation at 298K and 1 bar 00827 */ 00828 virtual void modifyOneHf298SS(const int k, const doublereal Hf298New) { 00829 (void) err("Hf298SS - H298MODIFY_CAPABILITY not compiled in"); 00830 } 00831 #endif 00832 00833 //! Maximum temperature for which the thermodynamic data for the species 00834 //! are valid. 00835 /*! 00836 * If no argument is supplied, the 00837 * value returned will be the highest temperature at which the 00838 * data for \e all species are valid. Otherwise, the value 00839 * will be only for species \a k. This function is a wrapper 00840 * that calls the species thermo maxTemp function. 00841 * 00842 * @param k index of the species. Default is -1, which will return the min of the max value 00843 * over all species. 00844 */ 00845 doublereal maxTemp(int k = -1) const { 00846 return m_spthermo->maxTemp(k); 00847 } 00848 00849 /** 00850 * @} 00851 * @name Molar Thermodynamic Properties of the Solution 00852 * @{ 00853 */ 00854 00855 /// Molar enthalpy. Units: J/kmol. 00856 virtual doublereal enthalpy_mole() const { 00857 return err("enthalpy_mole"); 00858 } 00859 00860 /// Molar internal energy. Units: J/kmol. 00861 virtual doublereal intEnergy_mole() const { 00862 return err("intEnergy_mole"); 00863 } 00864 00865 /// Molar entropy. Units: J/kmol/K. 00866 virtual doublereal entropy_mole() const { 00867 return err("entropy_mole"); 00868 } 00869 00870 /// Molar Gibbs function. Units: J/kmol. 00871 virtual doublereal gibbs_mole() const { 00872 return err("gibbs_mole"); 00873 } 00874 00875 /// Molar heat capacity at constant pressure. Units: J/kmol/K. 00876 virtual doublereal cp_mole() const { 00877 return err("cp_mole"); 00878 } 00879 00880 /// Molar heat capacity at constant volume. Units: J/kmol/K. 00881 virtual doublereal cv_mole() const { 00882 return err("cv_mole"); 00883 } 00884 00885 00886 //! Get the array of log concentration-like derivatives of the 00887 //! log activity coefficients 00888 /*! 00889 * This function is a virtual method. For ideal mixtures 00890 * (unity activity coefficients), this can return zero. 00891 * Implementations should take the derivative of the 00892 * logarithm of the activity coefficient with respect to the 00893 * logarithm of the concentration-like variable (i.e. mole fraction, 00894 * molality, etc.) that represents the standard state. 00895 * This quantity is to be used in conjunction with derivatives of 00896 * that concentration-like variable when the derivative of the chemical 00897 * potential is taken. 00898 * 00899 * units = dimensionless 00900 * 00901 * @param dlnActCoeffdlnC Output vector of derivatives of the 00902 * log Activity Coefficients. length = m_kk 00903 */ 00904 virtual void getdlnActCoeffdlnC(doublereal *dlnActCoeffdlnC) const { 00905 err("getdlnActCoeffdlnC"); 00906 } 00907 00908 00909 /** 00910 * @} 00911 * @name Mechanical Properties 00912 * @{ 00913 */ 00914 00915 //! Return the thermodynamic pressure (Pa). 00916 /*! 00917 * This method must be overloaded in derived classes. Since the 00918 * mass density, temperature, and mass fractions are stored, 00919 * this method should use these values to implement the 00920 * mechanical equation of state \f$ P(T, \rho, Y_1, \dots, 00921 * Y_K) \f$. 00922 */ 00923 virtual doublereal pressure() const { 00924 return err("pressure"); 00925 } 00926 00927 //! Set the internally storred pressure (Pa) at constant 00928 //! temperature and composition 00929 /*! 00930 * This method must be reimplemented in derived classes, where it 00931 * may involve the solution of a nonlinear equation. Within %Cantera, 00932 * the independent variable is the density. Therefore, this function 00933 * solves for the density that will yield the desired input pressure. 00934 * The temperature and composition iare held constant during this process. 00935 * 00936 * This base class function will print an error, if not overwritten. 00937 * 00938 * @param p input Pressure (Pa) 00939 */ 00940 virtual void setPressure(doublereal p) { 00941 err("setPressure"); 00942 } 00943 00944 //! Returns the isothermal compressibility. Units: 1/Pa. 00945 /*! 00946 * The isothermal compressibility is defined as 00947 * \f[ 00948 * \kappa_T = -\frac{1}{v}\left(\frac{\partial v}{\partial P}\right)_T 00949 * \f] 00950 * or 00951 * \f[ 00952 * \kappa_T = \frac{1}{\rho}\left(\frac{\partial \rho}{\partial P}\right)_T 00953 * \f] 00954 */ 00955 virtual doublereal isothermalCompressibility() const { 00956 err("isothermalCompressibility"); return -1.0; 00957 } 00958 00959 //! Return the volumetric thermal expansion coefficient. Units: 1/K. 00960 /*! 00961 * The thermal expansion coefficient is defined as 00962 * \f[ 00963 * \beta = \frac{1}{v}\left(\frac{\partial v}{\partial T}\right)_P 00964 * \f] 00965 */ 00966 virtual doublereal thermalExpansionCoeff() const { 00967 err("thermalExpansionCoeff()"); return -1.0; 00968 } 00969 00970 /// @deprecated 00971 virtual void updateDensity() { 00972 deprecatedMethod("ThermoPhase","updateDensity",""); 00973 } 00974 00975 /** 00976 * @} 00977 * @name Electric Potential 00978 * 00979 * The phase may be at some non-zero electrical 00980 * potential. These methods set or get the value of the 00981 * electric potential. 00982 */ 00983 //@{ 00984 00985 //! Set the electric potential of this phase (V). 00986 /*! 00987 * This is used by classes InterfaceKinetics and EdgeKinetics to 00988 * compute the rates of charge-transfer reactions, and in computing 00989 * the electrochemical potentials of the species. 00990 * 00991 * Each phase may have its own electric potential. 00992 * 00993 * @param v Input value of the electric potential in Volts 00994 */ 00995 void setElectricPotential(doublereal v) { 00996 m_phi = v; 00997 } 00998 00999 //! Returns the electric potential of this phase (V). 01000 /*! 01001 * Units are Volts (which are Joules/coulomb) 01002 */ 01003 doublereal electricPotential() const { return m_phi; } 01004 01005 /** 01006 * @} 01007 * @name Activities, Standard States, and Activity Concentrations 01008 * 01009 * The activity \f$a_k\f$ of a species in solution is related 01010 * to the chemical potential by \f[ \mu_k = \mu_k^0(T,P) + 01011 * \hat R T \log a_k. \f] The quantity \f$\mu_k^0(T,P)\f$ is 01012 * the standard chemical potential at unit activity, 01013 * which depends on temperature and pressure, 01014 * but not on composition. The 01015 * activity is dimensionless. 01016 * @{ 01017 */ 01018 01019 01020 //! This method returns the convention used in specification 01021 //! of the activities, of which there are currently two, molar- 01022 //! and molality-based conventions. 01023 /*! 01024 * Currently, there are two activity conventions: 01025 * - Molar-based activities 01026 * %Unit activity of species at either a hypothetical pure 01027 * solution of the species or at a hypothetical 01028 * pure ideal solution at infinite dilution 01029 * cAC_CONVENTION_MOLAR 0 01030 * - default 01031 * 01032 * - Molality-based acvtivities 01033 * (unit activity of solutes at a hypothetical 1 molal 01034 * solution referenced to infinite dilution at all 01035 * pressures and temperatures). 01036 * cAC_CONVENTION_MOLALITY 1 01037 */ 01038 virtual int activityConvention() const; 01039 01040 //! This method returns the convention used in specification 01041 //! of the standard state, of which there are currently two, 01042 //! temperature based, and variable pressure based. 01043 /*! 01044 * Currently, there are two standard state conventions: 01045 * - Temperature-based activities 01046 * cSS_CONVENTION_TEMPERATURE 0 01047 * - default 01048 * 01049 * - Variable Pressure and Temperature -based activities 01050 * cSS_CONVENTION_VPSS 1 01051 */ 01052 virtual int standardStateConvention() const; 01053 01054 //! This method returns an array of generalized concentrations 01055 /*! 01056 * \f$ C^a_k\f$ are defined such that \f$ a_k = C^a_k / 01057 * C^0_k, \f$ where \f$ C^0_k \f$ is a standard concentration 01058 * defined below and \f$ a_k \f$ are activities used in the 01059 * thermodynamic functions. These activity (or generalized) 01060 * concentrations are used 01061 * by kinetics manager classes to compute the forward and 01062 * reverse rates of elementary reactions. Note that they may 01063 * or may not have units of concentration --- they might be 01064 * partial pressures, mole fractions, or surface coverages, 01065 * for example. 01066 * 01067 * @param c Output array of generalized concentrations. The 01068 * units depend upon the implementation of the 01069 * reaction rate expressions within the phase. 01070 */ 01071 virtual void getActivityConcentrations(doublereal* c) const { 01072 err("getActivityConcentrations"); 01073 } 01074 01075 //! Return the standard concentration for the kth species 01076 /*! 01077 * The standard concentration \f$ C^0_k \f$ used to normalize 01078 * the activity (i.e., generalized) concentration. In many cases, this quantity 01079 * will be the same for all species in a phase - for example, 01080 * for an ideal gas \f$ C^0_k = P/\hat R T \f$. For this 01081 * reason, this method returns a single value, instead of an 01082 * array. However, for phases in which the standard 01083 * concentration is species-specific (e.g. surface species of 01084 * different sizes), this method may be called with an 01085 * optional parameter indicating the species. 01086 * 01087 * @param k Optional parameter indicating the species. The default 01088 * is to assume this refers to species 0. 01089 * @return 01090 * Returns the standard concentration. The units are by definition 01091 * dependent on the ThermoPhase and kinetics manager representation. 01092 */ 01093 virtual doublereal standardConcentration(int k=0) const { 01094 err("standardConcentration"); 01095 return -1.0; 01096 } 01097 01098 //! Natural logarithm of the standard concentration of the kth species. 01099 /*! 01100 * @param k index of the species (defaults to zero) 01101 */ 01102 virtual doublereal logStandardConc(int k=0) const; 01103 01104 //! Returns the units of the standard and generalized concentrations. 01105 /*! 01106 * Note they have the same units, as their 01107 * ratio is defined to be equal to the activity of the kth 01108 * species in the solution, which is unitless. 01109 * 01110 * This routine is used in print out applications where the 01111 * units are needed. Usually, MKS units are assumed throughout 01112 * the program and in the XML input files. 01113 * 01114 * The base %ThermoPhase class assigns the default quantities 01115 * of (kmol/m3) for all species. 01116 * Inherited classes are responsible for overriding the default 01117 * values if necessary. 01118 * 01119 * @param uA Output vector containing the units 01120 * uA[0] = kmol units - default = 1 01121 * uA[1] = m units - default = -nDim(), the number of spatial 01122 * dimensions in the Phase class. 01123 * uA[2] = kg units - default = 0; 01124 * uA[3] = Pa(pressure) units - default = 0; 01125 * uA[4] = Temperature units - default = 0; 01126 * uA[5] = time units - default = 0 01127 * @param k species index. Defaults to 0. 01128 * @param sizeUA output int containing the size of the vector. 01129 * Currently, this is equal to 6. 01130 */ 01131 virtual void getUnitsStandardConc(double *uA, int k = 0, 01132 int sizeUA = 6) const; 01133 01134 //! Get the array of non-dimensional activities at 01135 //! the current solution temperature, pressure, and solution concentration. 01136 /*! 01137 * Note, for molality based formulations, this returns the 01138 * molality based activities. 01139 * 01140 * We resolve this function at this level by calling 01141 * on the activityConcentration function. However, 01142 * derived classes may want to override this default 01143 * implementation. 01144 * 01145 * @param a Output vector of activities. Length: m_kk. 01146 */ 01147 virtual void getActivities(doublereal* a) const; 01148 01149 //! Get the array of non-dimensional molar-based activity coefficients at 01150 //! the current solution temperature, pressure, and solution concentration. 01151 /*! 01152 * @param ac Output vector of activity coefficients. Length: m_kk. 01153 */ 01154 virtual void getActivityCoefficients(doublereal* ac) const { 01155 if (m_kk == 1) { 01156 ac[0] = 1.0; 01157 } else { 01158 err("getActivityCoefficients"); 01159 } 01160 } 01161 01162 virtual void getLNActivityCoefficients(doublereal * const lnac) const; 01163 01164 //@} 01165 /// @name Partial Molar Properties of the Solution 01166 //@{ 01167 01168 /** 01169 * Get the array of non-dimensional species chemical potentials 01170 * These are partial molar Gibbs free energies. 01171 * \f$ \mu_k / \hat R T \f$. 01172 * Units: unitless 01173 * 01174 * @param mu Output vector of dimensionless chemical potentials. 01175 * Length: m_kk. 01176 */ 01177 virtual void getChemPotentials_RT(doublereal* mu) const { 01178 err("getChemPotentials_RT"); 01179 } 01180 01181 01182 //! Get the species chemical potentials. Units: J/kmol. 01183 /*! 01184 * This function returns a vector of chemical potentials of the 01185 * species in solution at the current temperature, pressure 01186 * and mole fraction of the solution. 01187 * 01188 * @param mu Output vector of species chemical 01189 * potentials. Length: m_kk. Units: J/kmol 01190 */ 01191 virtual void getChemPotentials(doublereal* mu) const { 01192 err("getChemPotentials"); 01193 } 01194 01195 //! Get the species electrochemical potentials. 01196 /*! 01197 * These are partial molar quantities. This method adds a term \f$ F z_k 01198 * \phi_p \f$ to each chemical potential. 01199 * The electrochemical potential of species k in a phase p, \f$ \zeta_k \f$, 01200 * is related to the chemical potential via 01201 * the following equation, 01202 * 01203 * \f[ 01204 * \zeta_{k}(T,P) = \mu_{k}(T,P) + F z_k \phi_p 01205 * \f] 01206 * 01207 * @param mu Output vector of species electrochemical 01208 * potentials. Length: m_kk. Units: J/kmol 01209 */ 01210 void getElectrochemPotentials(doublereal* mu) const { 01211 getChemPotentials(mu); 01212 double ve = Faraday * electricPotential(); 01213 for (int k = 0; k < m_kk; k++) { 01214 mu[k] += ve*charge(k); 01215 } 01216 } 01217 01218 //! Returns an array of partial molar enthalpies for the species 01219 //! in the mixture. Units (J/kmol) 01220 /*! 01221 * @param hbar Output vector of species partial molar enthalpies. 01222 * Length: m_kk. units are J/kmol. 01223 */ 01224 virtual void getPartialMolarEnthalpies(doublereal* hbar) const { 01225 err("getPartialMolarEnthalpies"); 01226 } 01227 01228 //! Returns an array of partial molar entropies of the species in the 01229 //! solution. Units: J/kmol/K. 01230 /*! 01231 * @param sbar Output vector of species partial molar entropies. 01232 * Length = m_kk. units are J/kmol/K. 01233 */ 01234 virtual void getPartialMolarEntropies(doublereal* sbar) const { 01235 err("getPartialMolarEntropies"); 01236 } 01237 01238 //! Return an array of partial molar internal energies for the 01239 //! species in the mixture. Units: J/kmol. 01240 /*! 01241 * @param ubar Output vector of speciar partial molar internal energies. 01242 * Length = m_kk. units are J/kmol. 01243 */ 01244 virtual void getPartialMolarIntEnergies(doublereal* ubar) const { 01245 err("getPartialMolarIntEnergies"); 01246 } 01247 01248 //! Return an array of partial molar heat capacities for the 01249 //! species in the mixture. Units: J/kmol/K 01250 /*! 01251 * @param cpbar Output vector of species partial molar heat 01252 * capacities at constant pressure. 01253 * Length = m_kk. units are J/kmol/K. 01254 */ 01255 virtual void getPartialMolarCp(doublereal* cpbar) const { 01256 err("getPartialMolarCp"); 01257 } 01258 01259 //! Return an array of partial molar volumes for the 01260 //! species in the mixture. Units: m^3/kmol. 01261 /*! 01262 * @param vbar Output vector of speciar partial molar volumes. 01263 * Length = m_kk. units are m^3/kmol. 01264 */ 01265 virtual void getPartialMolarVolumes(doublereal* vbar) const { 01266 err("getPartialMolarVolumes"); 01267 } 01268 01269 //@} 01270 /// @name Properties of the Standard State of the Species in the Solution 01271 //@{ 01272 01273 //! Get the array of chemical potentials at unit activity for the species 01274 //! at their standard states at the current <I>T</I> and <I>P</I> of the solution. 01275 /*! 01276 * These are the standard state chemical potentials \f$ \mu^0_k(T,P) 01277 * \f$. The values are evaluated at the current 01278 * temperature and pressure of the solution 01279 * 01280 * @param mu Output vector of chemical potentials. 01281 * Length: m_kk. 01282 */ 01283 virtual void getStandardChemPotentials(doublereal* mu) const { 01284 err("getStandardChemPotentials"); 01285 } 01286 01287 //! Get the nondimensional Enthalpy functions for the species 01288 //! at their standard states at the current <I>T</I> and <I>P</I> of the solution. 01289 /*! 01290 * @param hrt Output vector of nondimensional standard state enthalpies. 01291 * Length: m_kk. 01292 */ 01293 virtual void getEnthalpy_RT(doublereal* hrt) const { 01294 err("getEnthalpy_RT"); 01295 } 01296 01297 //! Get the array of nondimensional Entropy functions for the 01298 //! standard state species at the current <I>T</I> and <I>P</I> of the solution. 01299 /*! 01300 * @param sr Output vector of nondimensional standard state entropies. 01301 * Length: m_kk. 01302 */ 01303 virtual void getEntropy_R(doublereal* sr) const { 01304 err("getEntropy_R"); 01305 } 01306 01307 //! Get the nondimensional Gibbs functions for the species 01308 //! in their standard states at the current <I>T</I> and <I>P</I> of the solution. 01309 /*! 01310 * @param grt Output vector of nondimensional standard state gibbs free energies 01311 * Length: m_kk. 01312 */ 01313 virtual void getGibbs_RT(doublereal* grt) const { 01314 err("getGibbs_RT"); 01315 } 01316 01317 //! Get the Gibbs functions for the standard 01318 //! state of the species at the current <I>T</I> and <I>P</I> of the solution 01319 /*! 01320 * Units are Joules/kmol 01321 * @param gpure Output vector of standard state gibbs free energies 01322 * Length: m_kk. 01323 */ 01324 virtual void getPureGibbs(doublereal* gpure) const { 01325 err("getPureGibbs"); 01326 } 01327 01328 //! Returns the vector of nondimensional Internal Energies of the standard 01329 //! state species at the current <I>T</I> and <I>P</I> of the solution 01330 /*! 01331 * @param urt output vector of nondimensional standard state internal energies 01332 * of the species. Length: m_kk. 01333 */ 01334 virtual void getIntEnergy_RT(doublereal *urt) const { 01335 err("getIntEnergy_RT"); 01336 } 01337 01338 //! Get the nondimensional Heat Capacities at constant 01339 //! pressure for the species standard states 01340 //! at the current <I>T</I> and <I>P</I> of the solution 01341 /*! 01342 * @param cpr Output vector of nondimensional standard state heat capacities 01343 * Length: m_kk. 01344 */ 01345 virtual void getCp_R(doublereal* cpr) const { 01346 err("getCp_R"); 01347 } 01348 01349 //! Get the molar volumes of the species standard states at the current 01350 //! <I>T</I> and <I>P</I> of the solution. 01351 /*! 01352 * units = m^3 / kmol 01353 * 01354 * @param vol Output vector containing the standard state volumes. 01355 * Length: m_kk. 01356 */ 01357 virtual void getStandardVolumes(doublereal *vol) const { 01358 err("getStandardVolumes"); 01359 } 01360 01361 //@} 01362 /// @name Thermodynamic Values for the Species Reference States 01363 //@{ 01364 01365 01366 //! Returns the vector of nondimensional 01367 //! enthalpies of the reference state at the current temperature 01368 //! of the solution and the reference pressure for the species. 01369 /*! 01370 * This base function will throw a CanteraException unless 01371 * it is overwritten in a derived class. 01372 * 01373 * @param hrt Output vector containing the nondimensional reference state 01374 * enthalpies 01375 * Length: m_kk. 01376 */ 01377 virtual void getEnthalpy_RT_ref(doublereal *hrt) const { 01378 err("getEnthalpy_RT_ref"); 01379 } 01380 01381 //! Returns the vector of nondimensional 01382 //! Gibbs Free Energies of the reference state at the current temperature 01383 //! of the solution and the reference pressure for the species. 01384 /*! 01385 * @param grt Output vector containing the nondimensional reference state 01386 * Gibbs Free energies. Length: m_kk. 01387 */ 01388 virtual void getGibbs_RT_ref(doublereal *grt) const { 01389 err("getGibbs_RT_ref"); 01390 } 01391 01392 //! Returns the vector of the 01393 //! gibbs function of the reference state at the current temperature 01394 //! of the solution and the reference pressure for the species. 01395 /*! 01396 * units = J/kmol 01397 * 01398 * @param g Output vector containing the reference state 01399 * Gibbs Free energies. Length: m_kk. Units: J/kmol. 01400 */ 01401 virtual void getGibbs_ref(doublereal *g) const { 01402 err("getGibbs_ref"); 01403 } 01404 01405 //! Returns the vector of nondimensional 01406 //! entropies of the reference state at the current temperature 01407 //! of the solution and the reference pressure for each species. 01408 /*! 01409 * @param er Output vector containing the nondimensional reference state 01410 * entropies. Length: m_kk. 01411 */ 01412 virtual void getEntropy_R_ref(doublereal *er) const { 01413 err("getEntropy_R_ref"); 01414 } 01415 01416 //! Returns the vector of nondimensional 01417 //! internal Energies of the reference state at the current temperature 01418 //! of the solution and the reference pressure for each species. 01419 /*! 01420 * @param urt Output vector of nondimensional reference state 01421 * internal energies of the species. 01422 * Length: m_kk 01423 */ 01424 virtual void getIntEnergy_RT_ref(doublereal *urt) const { 01425 err("getIntEnergy_RT_ref"); 01426 } 01427 01428 //! Returns the vector of nondimensional 01429 //! constant pressure heat capacities of the reference state 01430 //! at the current temperature of the solution 01431 //! and reference pressure for each species. 01432 /*! 01433 * @param cprt Output vector of nondimensional reference state 01434 * heat capacities at constant pressure for the species. 01435 * Length: m_kk 01436 */ 01437 virtual void getCp_R_ref(doublereal *cprt) const { 01438 err("getCp_R_ref()"); 01439 } 01440 01441 //! Get the molar volumes of the species reference states at the current 01442 //! <I>T</I> and <I>P_ref</I> of the solution. 01443 /*! 01444 * units = m^3 / kmol 01445 * 01446 * @param vol Output vector containing the standard state volumes. 01447 * Length: m_kk. 01448 */ 01449 virtual void getStandardVolumes_ref(doublereal *vol) const { 01450 err("getStandardVolumes_ref"); 01451 } 01452 01453 //! Sets the reference composition 01454 /*! 01455 * @param x Mole fraction vector to set the reference composition to. 01456 * If this is zero, then the reference mole fraction 01457 * is set to the current mole fraction vector. 01458 */ 01459 virtual void setReferenceComposition(const doublereal * const x); 01460 01461 //! Gets the reference composition 01462 /*! 01463 * The reference mole fraction is a safe mole fraction. 01464 * @param x Mole fraction vector containing the reference composition. 01465 */ 01466 virtual void getReferenceComposition(doublereal * const x) const; 01467 01468 // 01469 // The methods below are not virtual, and should not 01470 // be overloaded. 01471 // 01472 01473 //@} 01474 /** 01475 * @name Specific Properties 01476 * @{ 01477 */ 01478 01479 /** 01480 * Specific enthalpy. Units: J/kg. 01481 */ 01482 doublereal enthalpy_mass() const { 01483 return enthalpy_mole()/meanMolecularWeight(); 01484 } 01485 01486 /** 01487 * Specific internal energy. Units: J/kg. 01488 */ 01489 doublereal intEnergy_mass() const { 01490 return intEnergy_mole()/meanMolecularWeight(); 01491 } 01492 01493 /** 01494 * Specific entropy. Units: J/kg/K. 01495 */ 01496 doublereal entropy_mass() const { 01497 return entropy_mole()/meanMolecularWeight(); 01498 } 01499 01500 /** 01501 * Specific Gibbs function. Units: J/kg. 01502 */ 01503 doublereal gibbs_mass() const { 01504 return gibbs_mole()/meanMolecularWeight(); 01505 } 01506 01507 /** 01508 * Specific heat at constant pressure. Units: J/kg/K. 01509 */ 01510 doublereal cp_mass() const { 01511 return cp_mole()/meanMolecularWeight(); 01512 } 01513 01514 /** 01515 * Specific heat at constant volume. Units: J/kg/K. 01516 */ 01517 doublereal cv_mass() const { 01518 return cv_mole()/meanMolecularWeight(); 01519 } 01520 //@} 01521 01522 //! Return the Gas Constant multiplied by the current temperature 01523 /*! 01524 * The units are Joules kmol-1 01525 */ 01526 doublereal _RT() const { 01527 return temperature() * GasConstant; 01528 } 01529 01530 /** 01531 * @name Setting the State 01532 * 01533 * These methods set all or part of the thermodynamic 01534 * state. 01535 * @{ 01536 */ 01537 01538 //! Set the temperature (K), pressure (Pa), and mole fractions. 01539 /*! 01540 * Note, the mole fractions are set first before the pressure is set. 01541 * Setting the pressure may involve the solution of a nonlinear equation. 01542 * 01543 * @param t Temperature (K) 01544 * @param p Pressure (Pa) 01545 * @param x Vector of mole fractions. 01546 * Length is equal to m_kk. 01547 */ 01548 void setState_TPX(doublereal t, doublereal p, const doublereal* x); 01549 01550 //! Set the temperature (K), pressure (Pa), and mole fractions. 01551 /*! 01552 * Note, the mole fractions are set first before the pressure is set. 01553 * Setting the pressure may involve the solution of a nonlinear equation. 01554 * 01555 * @param t Temperature (K) 01556 * @param p Pressure (Pa) 01557 * @param x Composition map of mole fractions. Species not in 01558 * the composition map are assumed to have zero mole fraction 01559 */ 01560 void setState_TPX(doublereal t, doublereal p, compositionMap& x); 01561 01562 //! Set the temperature (K), pressure (Pa), and mole fractions. 01563 /*! 01564 * Note, the mole fractions are set first before the pressure is set. 01565 * Setting the pressure may involve the solution of a nonlinear equation. 01566 * 01567 * @param t Temperature (K) 01568 * @param p Pressure (Pa) 01569 * @param x String containing a composition map of the mole fractions. Species not in 01570 * the composition map are assumed to have zero mole fraction 01571 */ 01572 void setState_TPX(doublereal t, doublereal p, const std::string& x); 01573 01574 //! Set the internally storred temperature (K), pressure (Pa), and mass fractions of the phase. 01575 /*! 01576 * Note, the mass fractions are set first before the pressure is set. 01577 * Setting the pressure may involve the solution of a nonlinear equation. 01578 * 01579 * @param t Temperature (K) 01580 * @param p Pressure (Pa) 01581 * @param y Vector of mass fractions. 01582 * Length is equal to m_kk. 01583 */ 01584 void setState_TPY(doublereal t, doublereal p, const doublereal* y); 01585 01586 //! Set the internally storred temperature (K), pressure (Pa), and mass fractions of the phase 01587 /*! 01588 * Note, the mass fractions are set first before the pressure is set. 01589 * Setting the pressure may involve the solution of a nonlinear equation. 01590 * 01591 * @param t Temperature (K) 01592 * @param p Pressure (Pa) 01593 * @param y Composition map of mass fractions. Species not in 01594 * the composition map are assumed to have zero mass fraction 01595 */ 01596 void setState_TPY(doublereal t, doublereal p, compositionMap& y); 01597 01598 //! Set the internally storred temperature (K), pressure (Pa), and mass fractions of the phase 01599 /*! 01600 * Note, the mass fractions are set first before the pressure is set. 01601 * Setting the pressure may involve the solution of a nonlinear equation. 01602 * 01603 * @param t Temperature (K) 01604 * @param p Pressure (Pa) 01605 * @param y String containing a composition map of the mass fractions. Species not in 01606 * the composition map are assumed to have zero mass fraction 01607 */ 01608 void setState_TPY(doublereal t, doublereal p, const std::string& y); 01609 01610 //! Set the temperature (K) and pressure (Pa) 01611 /*! 01612 * Setting the pressure may involve the solution of a nonlinear equation. 01613 * 01614 * @param t Temperature (K) 01615 * @param p Pressure (Pa) 01616 */ 01617 void setState_TP(doublereal t, doublereal p); 01618 01619 //! Set the pressure (Pa) and mole fractions. 01620 /*! 01621 * Note, the mole fractions are set first before the pressure is set. 01622 * Setting the pressure may involve the solution of a nonlinear equation. 01623 * 01624 * @param p Pressure (Pa) 01625 * @param x Vector of mole fractions. 01626 * Length is equal to m_kk. 01627 */ 01628 void setState_PX(doublereal p, doublereal* x); 01629 01630 //! Set the internally storred pressure (Pa) and mass fractions. 01631 /*! 01632 * Note, the temperature is held constant during this operation. 01633 * Note, the mass fractions are set first before the pressure is set. 01634 * Setting the pressure may involve the solution of a nonlinear equation. 01635 * 01636 * @param p Pressure (Pa) 01637 * @param y Vector of mass fractions. 01638 * Length is equal to m_kk. 01639 */ 01640 void setState_PY(doublereal p, doublereal* y); 01641 01642 //! Set the internally storred specific enthalpy (J/kg) and pressure (Pa) of the phase. 01643 /*! 01644 * @param h Specific enthalpy (J/kg) 01645 * @param p Pressure (Pa) 01646 * @param tol Optional parameter setting the tolerance of the 01647 * calculation. Defaults to 1.0E-4 01648 */ 01649 virtual void setState_HP(doublereal h, doublereal p, doublereal tol = 1.e-4); 01650 01651 //! Set the specific internal energy (J/kg) and specific volume (m^3/kg). 01652 /*! 01653 * This function fixes the internal state of the phase so that 01654 * the specific internal energy and specific volume have the value of the input parameters. 01655 * 01656 * @param u specific internal energy (J/kg) 01657 * @param v specific volume (m^3/kg). 01658 * @param tol Optional parameter setting the tolerance of the 01659 * calculation. Defaults to 1.0E-4 01660 */ 01661 virtual void setState_UV(doublereal u, doublereal v, doublereal tol = 1.e-4); 01662 01663 private: 01664 01665 //! Carry out work in HP and UV calculations. 01666 /*! 01667 * @param h Specific enthalpy or internal energy (J/kg) 01668 * @param p Pressure (Pa) or specific volume (m^3/kg) 01669 * @param tol Optional parameter setting the tolerance of the 01670 * calculation. Defaults to 1.0E-4 01671 * @param doUV True if solving for UV, false for HP. 01672 */ 01673 void setState_HPorUV(doublereal h, doublereal p, 01674 doublereal tol = 1.e-4, bool doUV = false); 01675 01676 public: 01677 01678 //! Set the specific entropy (J/kg/K) and pressure (Pa). 01679 /*! 01680 * This function fixes the internal state of the phase so that 01681 * the specific entropy and the pressure have the value of the input parameters. 01682 * 01683 * @param s specific entropy (J/kg/K) 01684 * @param p specific pressure (Pa). 01685 * @param tol Optional parameter setting the tolerance of the 01686 * calculation. Defaults to 1.0E-4 01687 */ 01688 virtual void setState_SP(doublereal s, doublereal p, doublereal tol = 1.e-4); 01689 01690 //! Set the specific entropy (J/kg/K) and specific volume (m^3/kg). 01691 /*! 01692 * This function fixes the internal state of the phase so that 01693 * the specific entropy and specific volume have the value of the input parameters. 01694 * 01695 * @param s specific entropy (J/kg/K) 01696 * @param v specific volume (m^3/kg). 01697 * @param tol Optional parameter setting the tolerance of the 01698 * calculation. Defaults to 1.0E-4 01699 */ 01700 virtual void setState_SV(doublereal s, doublereal v, doublereal tol = 1.e-4); 01701 01702 private: 01703 01704 //! Carry out work in SP and SV calculations. 01705 /*! 01706 * @param s Specific entropy (J/kg) 01707 * @param p Pressure (Pa) or specific volume (m^3/kg) 01708 * @param tol Optional parameter setting the tolerance of the 01709 * calculation. Defaults to 1.0E-4 01710 * @param doSV True if solving for SV, false for SP. 01711 */ 01712 void setState_SPorSV(doublereal s, doublereal p, 01713 doublereal tol = 1.e-4, bool doSV = false); 01714 01715 public: 01716 01717 //@} 01718 01719 /** 01720 * @name Chemical Equilibrium 01721 * Chemical equilibrium. 01722 * @{ 01723 */ 01724 01725 01726 //!This method is used by the ChemEquil equilibrium solver. 01727 /*! 01728 * It sets the state such that the chemical potentials satisfy 01729 * \f[ \frac{\mu_k}{\hat R T} = \sum_m A_{k,m} 01730 * \left(\frac{\lambda_m} {\hat R T}\right) \f] where 01731 * \f$ \lambda_m \f$ is the element potential of element m. The 01732 * temperature is unchanged. Any phase (ideal or not) that 01733 * implements this method can be equilibrated by ChemEquil. 01734 * 01735 * @param lambda_RT Input vector of dimensionless element potentials 01736 * The length is equal to nElements(). 01737 */ 01738 virtual void setToEquilState(const doublereal* lambda_RT) { 01739 err("setToEquilState"); 01740 } 01741 01742 //! Stores the element potentials in the ThermoPhase object 01743 /*! 01744 * Called by function 'equilibrate' in ChemEquil.h to transfer 01745 * the element potentials to this object after every successful 01746 * equilibration routine. 01747 * The element potentials are storred in their dimensionless 01748 * forms, calculated by dividing by RT. 01749 * 01750 * @param lambda Input vector containing the element potentials. 01751 * Length = nElements. Units are Joules/kmol. 01752 */ 01753 void setElementPotentials(const vector_fp& lambda); 01754 01755 01756 //! Returns the element potentials storred in the ThermoPhase object 01757 /*! 01758 * Returns the storred element potentials. 01759 * The element potentials are retrieved from their storred 01760 * dimensionless forms by multiplying by RT. 01761 * @param lambda Output vector containing the element potentials. 01762 * Length = nElements. Units are Joules/kmol. 01763 * @return bool indicating whether thare are any valid storred element 01764 * potentials. The calling routine should check this 01765 * bool. In the case that there aren't any, lambda is not 01766 * touched. 01767 */ 01768 bool getElementPotentials(doublereal* lambda) const; 01769 01770 //@} 01771 01772 01773 //--------------------------------------------------------- 01774 /// @name Critical State Properties. 01775 /// These methods are only implemented by some subclasses, and may 01776 /// be moved out of ThermoPhase at a later date. 01777 01778 //@{ 01779 01780 /// Critical temperature (K). 01781 virtual doublereal critTemperature() const { 01782 err("critTemperature"); return -1.0; 01783 } 01784 01785 /// Critical pressure (Pa). 01786 virtual doublereal critPressure() const { 01787 err("critPressure"); return -1.0; 01788 } 01789 01790 /// Critical density (kg/m3). 01791 virtual doublereal critDensity() const { 01792 err("critDensity"); return -1.0; 01793 } 01794 01795 //@} 01796 01797 /** @name Saturation Properties. 01798 * 01799 * These methods are only implemented by subclasses that 01800 * implement full liquid-vapor equations of state. They may be 01801 * moved out of %ThermoPhase at a later date. 01802 */ 01803 //@{ 01804 01805 //! Return the saturation temperature given the pressure 01806 /*! 01807 * @param p Pressure (Pa) 01808 */ 01809 virtual doublereal satTemperature(doublereal p) const { 01810 err("satTemperature"); return -1.0; 01811 } 01812 01813 //! Return the saturation pressure given the temperature 01814 /*! 01815 * @param t Temperature (Kelvin) 01816 */ 01817 virtual doublereal satPressure(doublereal t) const { 01818 err("satPressure"); return -1.0; 01819 } 01820 01821 //! Return the fraction of vapor at the current conditions 01822 virtual doublereal vaporFraction() const { 01823 err("vaprFraction"); return -1.0; 01824 } 01825 01826 //! Set the state to a saturated system at a particular temperature 01827 /*! 01828 * @param t Temperature (kelvin) 01829 * @param x Fraction of vapor 01830 */ 01831 virtual void setState_Tsat(doublereal t, doublereal x) { 01832 err("setState_sat"); 01833 } 01834 01835 //! Set the state to a saturated system at a particular pressure 01836 /*! 01837 * @param p Pressure (Pa) 01838 * @param x Fraction of vapor 01839 */ 01840 virtual void setState_Psat(doublereal p, doublereal x) { 01841 err("setState_sat"); 01842 } 01843 01844 //@} 01845 01846 01847 //! @name Initialization Methods - For Internal Use (%ThermoPhase) 01848 /*! 01849 * The following methods are used in the process of constructing 01850 * the phase and setting its parameters from a specification in an 01851 * input file. They are not normally used in application programs. 01852 * To see how they are used, 01853 * see files importCTML.cpp and ThermoFactory.cpp. 01854 */ 01855 //@{ 01856 01857 //! Store a reference pointer to the XML tree containing the species data 01858 //! for this phase. 01859 /*! 01860 * This is used to access data needed to construct transport manager later. 01861 * @internal 01862 * 01863 * @param k Species index 01864 * @param data Pointer to the XML_Node data containing 01865 * information about the species in the phase. 01866 */ 01867 void saveSpeciesData(const int k, const XML_Node* const data); 01868 01869 //! Return a pointer to the vector of XML nodes containing the species 01870 //! data for this phase. 01871 const std::vector<const XML_Node *> & speciesData() const; 01872 01873 //! Install a species thermodynamic property manager. 01874 /*! 01875 * The species thermodynamic property manager 01876 * computes properties of the pure species for use in 01877 * constructing solution properties. It is meant for internal 01878 * use, and some classes derived from ThermoPhase may not use 01879 * any species thermodynamic property manager. This method is 01880 * called by function importPhase() in importCTML.cpp. 01881 * 01882 * @param spthermo input pointer to the species thermodynamic property 01883 * manager. 01884 * 01885 * @internal 01886 */ 01887 void setSpeciesThermo(SpeciesThermo* spthermo) 01888 { m_spthermo = spthermo; } 01889 01890 //! Return a changeable reference to the calculation manager 01891 //! for species reference-state thermodynamic properties 01892 /*! 01893 * 01894 * @todo This method will fail if no species thermo 01895 * manager has been installed. 01896 * 01897 * @internal 01898 */ 01899 SpeciesThermo& speciesThermo() { return *m_spthermo; } 01900 01901 /** 01902 * @internal 01903 * Initialization of a ThermoPhase object using an 01904 * ctml file. 01905 * 01906 * This routine is a precursor to initThermoXML(XML_Node*) 01907 * routine, which does most of the work. 01908 * Here we read extra information about the XML description 01909 * of a phase. Regular information about elements and species 01910 * and their reference state thermodynamic information 01911 * have already been read at this point. 01912 * For example, we do not need to call this function for 01913 * ideal gas equations of state. 01914 * 01915 * @param inputFile XML file containing the description of the 01916 * phase 01917 * 01918 * @param id Optional parameter identifying the name of the 01919 * phase. If none is given, the first XML 01920 * phase element encountered will be used. 01921 */ 01922 virtual void initThermoFile(std::string inputFile, std::string id); 01923 01924 01925 //!Import and initialize a ThermoPhase object using an XML tree. 01926 /*! 01927 * @internal 01928 * 01929 * Here we read extra information about the XML description 01930 * of a phase. Regular information about elements and species 01931 * and their reference state thermodynamic information 01932 * have already been read at this point. 01933 * For example, we do not need to call this function for 01934 * ideal gas equations of state. This function is called from importPhase() 01935 * after the elements and the species are initialized with 01936 * default ideal solution level data. 01937 * 01938 * The default implementation in ThermoPhase calls the 01939 * virtual function initThermo() and then sets the "state" of the 01940 * phase by looking for an XML element named "state", and then 01941 * interpreting its contents by calling the virtual function 01942 * setStateFromXML(). 01943 * 01944 * @param phaseNode This object must be the phase node of a 01945 * complete XML tree 01946 * description of the phase, including all of the 01947 * species data. In other words while "phase" must 01948 * point to an XML phase object, it must have 01949 * sibling nodes "speciesData" that describe 01950 * the species in the phase. 01951 * @param id ID of the phase. If nonnull, a check is done 01952 * to see if phaseNode is pointing to the phase 01953 * with the correct id. 01954 */ 01955 virtual void initThermoXML(XML_Node& phaseNode, std::string id); 01956 01957 //! Initialize the ThermoPhase object after all species have been set up 01958 /*! 01959 * @internal Initialize. 01960 * 01961 * This method is provided to allow 01962 * subclasses to perform any initialization required after all 01963 * species have been added. For example, it might be used to 01964 * resize internal work arrays that must have an entry for 01965 * each species. The base class implementation does nothing, 01966 * and subclasses that do not require initialization do not 01967 * need to overload this method. When importing a CTML phase 01968 * description, this method is called from ThermoPhase::initThermoXML(), 01969 * which is called from importPhase(), 01970 * just prior to returning from function importPhase(). 01971 * 01972 * @see importCTML.cpp 01973 */ 01974 virtual void initThermo(); 01975 01976 // The following methods are used by the clib interface 01977 // library, and should not be used by application programs. 01978 01979 /*! 01980 * @internal 01981 * Index number. This method can be used to identify the 01982 * location of a phase object in a list, and is used by the 01983 * interface library (clib) routines for this purpose. 01984 */ 01985 int index() const { return m_index; } 01986 01987 01988 /** 01989 * @internal Set the index number. The Cantera interface 01990 * library uses this method to set the index number to the 01991 * location of the pointer to this object in the pointer array 01992 * it maintains. Using this method for any other purpose will 01993 * lead to unpredictable results if used in conjunction with 01994 * the interface library. 01995 * 01996 * @param m Input the index number. 01997 */ 01998 void setIndex(int m) { m_index = m; } 01999 02000 02001 //! Set the equation of state parameters 02002 /*! 02003 * @internal 02004 * The number and meaning of these depends on the subclass. 02005 * 02006 * @param n number of parameters 02007 * @param c array of \a n coefficients 02008 */ 02009 virtual void setParameters(int n, doublereal* const c) {} 02010 02011 02012 //! Get the equation of state parameters in a vector 02013 /*! 02014 * @internal 02015 * The number and meaning of these depends on the subclass. 02016 * 02017 * @param n number of parameters 02018 * @param c array of \a n coefficients 02019 */ 02020 virtual void getParameters(int &n, doublereal * const c) const {} 02021 02022 02023 //! Set equation of state parameter values from XML entries. 02024 /*! 02025 * 02026 * This method is called by function importPhase() in 02027 * file importCTML.cpp when processing a phase definition in 02028 * an input file. It should be overloaded in subclasses to set 02029 * any parameters that are specific to that particular phase 02030 * model. Note, this method is called before the phase is 02031 * initialzed with elements and/or species. 02032 * 02033 * @param eosdata An XML_Node object corresponding to 02034 * the "thermo" entry for this phase in the input file. 02035 */ 02036 virtual void setParametersFromXML(const XML_Node& eosdata) {} 02037 02038 02039 //! Set the initial state of the phase to the conditions 02040 //! specified in the state XML element. 02041 /*! 02042 * 02043 * This method sets the temperature, pressure, and mole 02044 * fraction vector to a set default value. 02045 * 02046 * @param state AN XML_Node object corresponding to 02047 * the "state" entry for this phase in the 02048 * input file. 02049 */ 02050 virtual void setStateFromXML(const XML_Node& state); 02051 02052 02053 //@} 02054 02055 //! Returns the chargeNeutralityNecessity boolean 02056 /*! 02057 * Some phases must have zero net charge in order for 02058 * their thermodynamics functions to be valid. 02059 * If this is so, then the value returned from this 02060 * function is true. 02061 * If this is not the case, then this is false. 02062 * Now, ideal gases have this parameter set to false, 02063 * while solution with molality-based activity 02064 * coefficients have this parameter set to true. 02065 */ 02066 bool chargeNeutralityNecessary() const { 02067 return m_chargeNeutralityNecessary; 02068 } 02069 02070 02071 //! returns a summary of the state of the phase as a string 02072 /*! 02073 * @param show_thermo If true, extra information is printed out 02074 * about the thermodynamic state of the system. 02075 */ 02076 virtual std::string report(bool show_thermo = true) const; 02077 02078 protected: 02079 02080 //! Pointer to the calculation manager for species 02081 //! reference-state thermodynamic properties 02082 /*! 02083 * This class is called when the reference-state thermodynamic properties 02084 * of all the species in the phase needs to be evaluated. 02085 */ 02086 SpeciesThermo* m_spthermo; 02087 02088 //! Vector of pointers to the species databases. 02089 /*! 02090 * This is used to access data needed to 02091 * construct the transport manager and other properties 02092 * later in the initialization process. 02093 * We create a copy of the XML_Node data read in here. Therefore, we own this 02094 * data. 02095 */ 02096 std::vector<const XML_Node *> m_speciesData; 02097 02098 //! Index number of the phase 02099 /*! 02100 * The Cantera interface library uses this member to set the index number to the 02101 * location of the pointer to this object in the pointer array of ThermoPhase's 02102 * it maintains. Using this member for any other purpose will 02103 * lead to unpredictable results if used in conjunction with 02104 * the interface library. 02105 */ 02106 int m_index; 02107 02108 //! Storred value of the electric potential for this phase 02109 /*! 02110 * Units are Volts 02111 */ 02112 doublereal m_phi; 02113 02114 /// Vector of element potentials. 02115 /// -> length equal to number of elements 02116 vector_fp m_lambdaRRT; 02117 02118 //! Boolean indicating whether there is a valid set of saved element potentials 02119 //! for this phase 02120 bool m_hasElementPotentials; 02121 02122 //! Boolean indicating whether a charge neutrality condition is a necessity 02123 /*! 02124 * Note, the charge neutrality condition is not a necessity for ideal gas phases. There may 02125 * be a net charge in those phases, because the NASA polynomials for ionized species 02126 * in Ideal gases take this condition into account. 02127 * However, liquid phases usually require charge neutrality in order for their derived 02128 * thermodynamics to be valid. 02129 */ 02130 bool m_chargeNeutralityNecessary; 02131 02132 //! Contains the standard state convention 02133 int m_ssConvention; 02134 02135 //! Reference Mole Fraction Composition 02136 /*! 02137 * Occasionally, the need arises to find a safe mole fraction vector to initialize 02138 * the object to. This contains such a vector. 02139 * The algorithm will pick up the mole fraction vector that is applied from 02140 * the state xml file in the input file 02141 */ 02142 std::vector<doublereal> xMol_Ref; 02143 02144 private: 02145 02146 //! Error function that gets called for unhandled cases 02147 /*! 02148 * @param msg String containing the message. 02149 */ 02150 doublereal err(std::string msg) const; 02151 02152 }; 02153 02154 //! typedef for the ThermoPhase class 02155 typedef ThermoPhase thermophase_t; 02156 02157 //! typedef for the ThermoPhase class 02158 typedef ThermoPhase thermo_t; 02159 02160 //! Format a summary of the mixture state for output. 02161 /*! 02162 * @param th ThermoPhase object to create a report about 02163 * @param show_thermo Boolean indicating whether the thermo functions 02164 * of the phase should be written out 02165 * 02166 * @return Returns a string containing the report 02167 */ 02168 02169 std::string report(const ThermoPhase& th, const bool show_thermo = true); 02170 02171 02172 } 02173 02174 #endif 02175