MetalSHEelectrons.cpp

Go to the documentation of this file.
00001 /**
00002  * @file MetalSHEelectrons.cpp
00003  * Definition file for the %MetalSHEElectrons class, which represents the
00004  * electrons in a metal that are consistent with the
00005  * SHE electrode (see \ref thermoprops and 
00006  * class \link Cantera::MetalSHEelectrons MetalSHEelectrons\endlink)
00007  */
00008 
00009 /*
00010  * Copywrite (2005) Sandia Corporation. Under the terms of
00011  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
00012  * U.S. Government retains certain rights in this software.
00013  *
00014  */
00015 
00016 /*
00017  * $Id: MetalSHEelectrons.cpp 279 2009-12-05 19:08:43Z hkmoffa $ 
00018  */
00019 
00020 #include "ct_defs.h"
00021 
00022 #include "MetalSHEelectrons.h"
00023 #include "SingleSpeciesTP.h"
00024 #include "ThermoFactory.h"
00025 
00026 #include <string>
00027 using namespace std;
00028 using namespace Cantera;
00029 
00030 namespace Cantera {
00031 
00032   /*
00033    * ----  Constructors -------
00034    */
00035   //====================================================================================================================
00036   /*
00037    * Default Constructor for the MetalSHEelectrons class
00038    */
00039   MetalSHEelectrons::MetalSHEelectrons():
00040     SingleSpeciesTP(),
00041     xdef_(0)
00042   {
00043   }
00044   //====================================================================================================================
00045   // Create and initialize a MetalSHEelectrons ThermoPhase object 
00046   // from an asci input file
00047   /*
00048    * @param infile name of the input file
00049    * @param id     name of the phase id in the file.
00050    *               If this is blank, the first phase in the file is used.
00051    */
00052   MetalSHEelectrons::MetalSHEelectrons(std::string infile, std::string id) :
00053     SingleSpeciesTP(),
00054     xdef_(0)
00055   {
00056     XML_Node* root;
00057     if (infile == "MetalSHEelectrons_default.xml") {
00058       xdef_ = MetalSHEelectrons::makeDefaultXMLTree();
00059       root = xdef_;
00060     } else {
00061       root = get_XML_File(infile);
00062     }
00063     if (id == "-") id = "";
00064     XML_Node* xphase = get_XML_NameID("phase", std::string("#")+id, root);
00065     if (!xphase) {
00066       throw CanteraError("MetalSHEelectrons::MetalSHEelectrons",
00067                          "Couldn't find phase name in file:" + id);
00068     }
00069     // Check the model name to ensure we have compatibility
00070     const XML_Node& th = xphase->child("thermo");
00071     std::string model = th["model"];
00072     if (model != "MetalSHEelectrons") {
00073       throw CanteraError("MetalSHEelectrons::MetalSHEelectrons",
00074                          "thermo model attribute must be MetalSHEelectrons");
00075     }
00076     importPhase(*xphase, this);
00077   }
00078   //====================================================================================================================
00079   // Full Constructor.
00080   /*
00081    *  @param phaseRef XML node pointing to a MetalSHEelectrons description
00082    *  @param id       Id of the phase. 
00083    */
00084   MetalSHEelectrons::MetalSHEelectrons(XML_Node& xmlphase, std::string id) :
00085     SingleSpeciesTP(),
00086     xdef_(0)
00087   {
00088     if (id != "") {
00089       std::string idxml = xmlphase["id"];
00090       if (id != idxml) {
00091         throw CanteraError("MetalSHEelectrons::MetalSHEelectrons",
00092                            "id's don't match");
00093       }
00094     }
00095     const XML_Node& th = xmlphase.child("thermo");
00096     std::string model = th["model"];
00097     if (model != "MetalSHEelectrons") {
00098       throw CanteraError("MetalSHEelectrons::MetalSHEelectrons",
00099                          "thermo model attribute must be MetalSHEelectrons");
00100     }
00101     importPhase(xmlphase, this);
00102   }
00103   //====================================================================================================================
00104   // Copy constructor
00105   /*
00106    * @param right Object to be copied
00107    */
00108   MetalSHEelectrons::MetalSHEelectrons(const MetalSHEelectrons  &right) :
00109     SingleSpeciesTP()
00110   {
00111     operator=(right);
00112   }
00113   //====================================================================================================================
00114   /*
00115    * Destructor for the routine (virtual)
00116    *        
00117    */
00118   MetalSHEelectrons::~MetalSHEelectrons() 
00119   {
00120     if (xdef_) {
00121       delete xdef_;
00122     }
00123   }
00124   //====================================================================================================================
00125   // Assignment operator
00126   /*
00127    * @param right Object to be copied
00128    */
00129   MetalSHEelectrons &
00130   MetalSHEelectrons::operator=(const MetalSHEelectrons & right) 
00131   {
00132     if (&right != this) {
00133       SingleSpeciesTP::operator=(right);
00134     }
00135 
00136     if (xdef_) {
00137       delete xdef_;
00138     }
00139     xdef_ = new XML_Node(*right.xdef_);
00140 
00141     return *this;
00142   }
00143   //====================================================================================================================
00144   // Duplication function
00145   /*
00146    * This virtual function is used to create a duplicate of the
00147    * current phase. It's used to duplicate the phase when given
00148    * a ThermoPhase pointer to the phase.
00149    *
00150    * @return It returns a ThermoPhase pointer.
00151    */
00152   ThermoPhase *MetalSHEelectrons::duplMyselfAsThermoPhase() const {
00153     MetalSHEelectrons *stp = new MetalSHEelectrons(*this);
00154     return (ThermoPhase *) stp;
00155   }
00156   //====================================================================================================================
00157 
00158   /*
00159    * ---- Utilities -----
00160    */
00161 
00162   /*
00163    * Equation of state flag. Returns the value cStoichSubstance,
00164    * defined in mix_defs.h.
00165    */
00166   int MetalSHEelectrons::eosType() const {
00167     return cMetalSHEelectrons;
00168   }
00169   //====================================================================================================================
00170 
00171   /*
00172    * ---- Molar Thermodynamic properties of the solution ----
00173    */
00174 
00175   /**
00176    * ----- Mechanical Equation of State ------
00177    */
00178   //====================================================================================================================
00179   /*
00180    * Pressure. Units: Pa.
00181    * For an incompressible substance, the density is independent
00182    * of pressure. This method simply returns the stored
00183    * pressure value.
00184    */ 
00185   doublereal MetalSHEelectrons::pressure() const {
00186     return m_press;
00187   }
00188   //====================================================================================================================    
00189   /*
00190    * Set the pressure at constant temperature. Units: Pa.
00191    * For an incompressible substance, the density is 
00192    * independent of pressure. Therefore, this method only 
00193    * stores the specified pressure value. It does not 
00194    * modify the density.
00195    */
00196   void MetalSHEelectrons::setPressure(doublereal p) {
00197     m_press = p;
00198   }
00199   //====================================================================================================================
00200   /*
00201    * The isothermal compressibility. Units: 1/Pa.
00202    * The isothermal compressibility is defined as
00203    * \f[
00204    * \kappa_T = -\frac{1}{v}\left(\frac{\partial v}{\partial P}\right)_T
00205    * \f]
00206    *
00207    *  It's equal to zero for this model, since the molar volume
00208    *  doesn't change with pressure or temperature.
00209    */
00210   doublereal MetalSHEelectrons::isothermalCompressibility() const {
00211     return -1.0/pressure();
00212   } 
00213   //====================================================================================================================    
00214   /*
00215    * The thermal expansion coefficient. Units: 1/K.
00216    * The thermal expansion coefficient is defined as
00217    *
00218    * \f[
00219    * \beta = \frac{1}{v}\left(\frac{\partial v}{\partial T}\right)_P
00220    * \f]
00221    *
00222    *  It's equal to zero for this model, since the molar volume
00223    *  doesn't change with pressure or temperature.
00224    */
00225   doublereal MetalSHEelectrons::thermalExpansionCoeff() const {
00226      return 1.0/temperature();
00227 
00228   }
00229   //====================================================================================================================
00230   /*
00231    * ---- Chemical Potentials and Activities ----
00232    */
00233   //====================================================================================================================
00234   /*
00235    * This method returns the array of generalized
00236    * concentrations.  For a stoichiomeetric substance, there is
00237    * only one species, and the generalized concentration is 1.0.
00238    */
00239   void MetalSHEelectrons::
00240   getActivityConcentrations(doublereal* c) const {
00241     c[0] = 1.0;
00242   }
00243   //====================================================================================================================
00244   /*
00245    * The standard concentration. This is defined as the concentration 
00246    * by which the generalized concentration is normalized to produce 
00247    * the activity. 
00248    */ 
00249   doublereal MetalSHEelectrons::standardConcentration(int k) const {
00250     return 1.0;
00251   }
00252   //====================================================================================================================
00253   /*
00254    * Returns the natural logarithm of the standard 
00255    * concentration of the kth species
00256    */
00257   doublereal MetalSHEelectrons::logStandardConc(int k) const {
00258     return 0.0;
00259   }
00260   //====================================================================================================================
00261   /*
00262    * Returns the units of the standard and generalized
00263    * concentrations Note they have the same units, as their
00264    * ratio is defined to be equal to the activity of the kth
00265    * species in the solution, which is unitless.
00266    *
00267    * This routine is used in print out applications where the
00268    * units are needed. Usually, MKS units are assumed throughout
00269    * the program and in the XML input files.
00270    *
00271    *  uA[0] = kmol units - default  = 1
00272    *  uA[1] = m    units - default  = -nDim(), the number of spatial
00273    *                                dimensions in the Phase class.
00274    *  uA[2] = kg   units - default  = 0;
00275    *  uA[3] = Pa(pressure) units - default = 0;
00276    *  uA[4] = Temperature units - default = 0;
00277    *  uA[5] = time units - default = 0
00278    */
00279   void MetalSHEelectrons::
00280   getUnitsStandardConc(doublereal *uA, int k, int sizeUA) const {
00281     for (int i = 0; i < 6; i++) {
00282       uA[i] = 0;
00283     }
00284   }
00285   //====================================================================================================================
00286   /*
00287    *  ---- Partial Molar Properties of the Solution ----
00288    */
00289 
00290   //====================================================================================================================
00291 
00292   /*
00293    * ---- Properties of the Standard State of the Species in the Solution
00294    * ----
00295    */
00296   //====================================================================================================================
00297   /*
00298    * Get the array of chemical potentials at unit activity 
00299    * \f$ \mu^0_k \f$.
00300    *
00301    * For a stoichiometric substance, there is no activity term in 
00302    * the chemical potential expression, and therefore the
00303    * standard chemical potential and the chemical potential
00304    * are both equal to the molar Gibbs function.
00305    */
00306   void MetalSHEelectrons::
00307   getStandardChemPotentials(doublereal* mu0) const {
00308     getGibbs_RT(mu0);
00309     mu0[0] *= GasConstant * temperature();
00310   }
00311   //====================================================================================================================
00312   /*
00313    * Get the nondimensional Enthalpy functions for the species
00314    * at their standard states at the current 
00315    * <I>T</I> and <I>P</I> of the solution.
00316    * Molar enthalpy. Units: J/kmol.  For an incompressible,
00317    * stoichiometric substance, the internal energy is
00318    * independent of pressure, and therefore the molar enthalpy
00319    * is \f[ \hat h(T, P) = \hat u(T) + P \hat v \f], where the
00320    * molar specific volume is constant.
00321    */
00322   void MetalSHEelectrons::getEnthalpy_RT(doublereal* hrt) const {
00323     getEnthalpy_RT_ref(hrt);
00324   }
00325   //====================================================================================================================
00326   /*
00327    * Get the array of nondimensional Entropy functions for the
00328    * standard state species
00329    * at the current <I>T</I> and <I>P</I> of the solution.
00330    */
00331   void MetalSHEelectrons::getEntropy_R(doublereal* sr) const {
00332     getEntropy_R_ref(sr);
00333     doublereal tmp = log (pressure() / m_p0);
00334     sr[0] -= tmp;
00335   }
00336   //====================================================================================================================
00337   /*
00338    * Get the nondimensional Gibbs functions for the species
00339    * at their standard states of solution at the current T and P
00340    * of the solution
00341    */
00342   void MetalSHEelectrons::getGibbs_RT(doublereal* grt) const {
00343     getGibbs_RT_ref(grt);
00344     doublereal tmp = log (pressure() / m_p0);
00345     grt[0] += tmp;
00346   }
00347   //====================================================================================================================
00348   /*
00349    * Get the nondimensional Gibbs functions for the standard
00350    * state of the species at the current T and P.
00351    */
00352   void MetalSHEelectrons::getCp_R(doublereal* cpr) const {  
00353     _updateThermo();
00354     cpr[0] = m_cp0_R[0];
00355   }
00356   //====================================================================================================================
00357   /*
00358    * Molar internal energy (J/kmol).
00359    * For an incompressible,
00360    * stoichiometric substance, the molar internal energy is
00361    * independent of pressure. Since the thermodynamic properties
00362    * are specified by giving the standard-state enthalpy, the
00363    * term \f$ P_0 \hat v\f$ is subtracted from the specified molar
00364    * enthalpy to compute the molar internal energy.
00365    */
00366   void MetalSHEelectrons::getIntEnergy_RT(doublereal* urt) const {
00367     getEnthalpy_RT(urt);
00368     urt[0] -= 1.0;
00369   }
00370   //====================================================================================================================
00371   /*
00372    * ---- Thermodynamic Values for the Species Reference States ----
00373    */
00374   /*
00375    * Molar internal energy or the reference state at the current
00376    * temperature, T  (J/kmol).  
00377    * For an incompressible,
00378    * stoichiometric substance, the molar internal energy is
00379    * independent of pressure. Since the thermodynamic properties
00380    * are specified by giving the standard-state enthalpy, the
00381    * term \f$ P_0 \hat v\f$ is subtracted from the specified molar
00382    * enthalpy to compute the molar internal energy.
00383    *
00384    * Note, this is equal to the standard state internal energy
00385    * evaluated at the reference pressure.
00386    */
00387   void MetalSHEelectrons::getIntEnergy_RT_ref(doublereal* urt) const {
00388     _updateThermo();
00389     doublereal RT = GasConstant * temperature();
00390     doublereal PV = m_p0 / molarDensity();
00391     urt[0] = m_h0_RT[0] - PV / RT;
00392   }
00393               
00394   /*
00395    * ---- Saturation Properties
00396    */
00397     
00398  
00399 
00400   /*
00401    * ---- Initialization and Internal functions
00402    */
00403   //====================================================================================================================
00404   /*
00405    * @internal Initialize. This method is provided to allow
00406    * subclasses to perform any initialization required after all
00407    * species have been added. For example, it might be used to
00408    * resize internal work arrays that must have an entry for
00409    * each species.  The base class implementation does nothing,
00410    * and subclasses that do not require initialization do not
00411    * need to overload this method.  When importing a CTML phase
00412    * description, this method is called just prior to returning
00413    * from function importPhase.
00414    *
00415    * @see importCTML.cpp
00416    */
00417   void MetalSHEelectrons::initThermo() {
00418     /*
00419      * Call the base class thermo initializer
00420      */
00421     SingleSpeciesTP::initThermo();
00422   }
00423   //====================================================================================================================
00424 
00425   void MetalSHEelectrons::initThermoXML(XML_Node& phaseNode, std::string id) {
00426     /*
00427      * Find the Thermo XML node
00428      */
00429     if (!phaseNode.hasChild("thermo")) {
00430       throw CanteraError("MetalSHEelectrons::initThermoXML",
00431                          "no thermo XML node");
00432     }
00433     XML_Node &tnode = phaseNode.child("thermo");
00434     doublereal dens = 2.65E3;
00435     if (tnode.hasChild("density")) {
00436       dens = getFloatDefaultUnits(tnode, "density", "kg/m3");
00437     }
00438     setDensity(dens);
00439     SingleSpeciesTP::initThermoXML(phaseNode, id);
00440   }
00441   //====================================================================================================================
00442   XML_Node *MetalSHEelectrons::makeDefaultXMLTree() 
00443   {
00444     XML_Node *xtop = new XML_Node("ctml", 0);
00445     XML_Node &xv = xtop->addChild("validate");
00446     xv.addAttribute("reactions", "yes");
00447     xv.addAttribute("species", "yes");
00448 
00449     XML_Node &xp = xtop->addChild("phase");
00450     xp.addAttribute("dim", "3");
00451     xp.addAttribute("id", "MetalSHEelectrons");
00452     XML_Node &xe = xp.addChild("elementArray", "E");
00453     xe.addAttribute("datasrc", "elements.xml");
00454     XML_Node &xs = xp.addChild("speciesArray", "she_electron");
00455     xs.addAttribute("datasrc", "#species_Metal_SHEelectrons");
00456     XML_Node &xt = xp.addChild("thermo");
00457     xt.addAttribute("model", "metalSHEelectrons");
00458     XML_Node &xtr = xp.addChild("transport");
00459     xtr.addAttribute("model", "none");
00460     XML_Node &xk = xp.addChild("kinetics");
00461     xk.addAttribute("model", "none");
00462 
00463     XML_Node &xsd = xtop->addChild("speciesData");
00464     xsd.addAttribute("id", "species_Metal_SHEelectrons");
00465 
00466     XML_Node &xsp = xsd.addChild("species");
00467     xsp.addAttribute("name", "she_electron");
00468     xsp.addChild("atomArray", "E:1");
00469     xsp.addChild("charge", "-1");
00470     XML_Node &xspt = xsp.addChild("thermo");
00471 
00472     XML_Node &xN1 = xspt.addChild("NASA");
00473     xN1.addAttribute("Tmax", "1000.");
00474     xN1.addAttribute("Tmin", "200.");
00475     xN1.addAttribute("P0", "100000.0");
00476     XML_Node &xF1 = xsd.addChild("floatArray", 
00477                                  "1.172165560E+00,   3.990260375E-03,  -9.739075500E-06, "
00478                                  "1.007860470E-08, -3.688058805E-12, -4.589675865E+02,  3.415051190E-01" );
00479     xF1.addAttribute("name", "coeffs");
00480     xF1.addAttribute("size", "7");
00481 
00482     XML_Node &xN2 = xspt.addChild("NASA");
00483     xN2.addAttribute("Tmax", "6000.");
00484     xN2.addAttribute("Tmin", "1000.");
00485     xN2.addAttribute("P0", "100000.0");
00486     XML_Node &xF2 = xsd.addChild("floatArray", 
00487                                  "1.466432895E+00,  4.133039835E-04, -7.320116750E-08, 7.705017950E-12,"
00488                                  "-3.444022160E-16, -4.065327985E+02, -5.121644350E-01");
00489     xF2.addAttribute("name", "coeffs");
00490     xF2.addAttribute("size", "7");
00491 
00492     return xtop;
00493   }
00494   //====================================================================================================================
00495   /*
00496    * setParameters:
00497    *
00498    *   Generic routine that is used to set the parameters used
00499    *   by this model.
00500    *        C[0] = density of phase [ kg/m3 ]
00501    */
00502   void MetalSHEelectrons::setParameters(int n, doublereal * const c) {
00503     doublereal rho = c[0];
00504     setDensity(rho);
00505   }
00506   //====================================================================================================================
00507   /*
00508    * getParameters:
00509    *
00510    *   Generic routine that is used to get the parameters used
00511    *   by this model.
00512    *        n = 1
00513    *        C[0] = density of phase [ kg/m3 ]
00514    */
00515   void MetalSHEelectrons::getParameters(int &n, doublereal * const c) const {
00516     doublereal rho = density();
00517     n = 1;
00518     c[0] = rho;
00519   }
00520   //====================================================================================================================
00521   /*
00522    * Reads an xml data block for the parameters needed by this
00523    * routine. eosdata is a reference to the xml thermo block, and looks
00524    * like this:
00525    * 
00526    *   <phase id="stoichsolid" >
00527    *     <thermo model="StoichSubstance">
00528    *         <density units="g/cm3">3.52</density>
00529    *     </thermo>
00530    *   </phase>
00531    */
00532   void MetalSHEelectrons::setParametersFromXML(const XML_Node& eosdata) {
00533     std::string model = eosdata["model"];
00534     if (model != "MetalSHEelectrons") {
00535       throw CanteraError("MetalSHEelectrons::setParametersFromXML",
00536                          "thermo model attribute must be MetalSHEelectrons");
00537     }
00538     doublereal rho = 2.65E3;
00539     if (eosdata.hasChild("density")) {
00540       rho = getFloat(eosdata, "density", "toSI");
00541     }
00542     setDensity(rho);
00543   }
00544   //====================================================================================================================
00545 
00546 }
Generated by  doxygen 1.6.3