VPSSMgr_General.cpp

Go to the documentation of this file.
00001 /**
00002  *  @file VPSSMgr_General.cpp
00003  *  Definition file for a derived class that handles the calculation
00004  *  of standard state thermo properties for
00005  *  a set of species belonging to a single phase in a completely general
00006  *  but slow way (see \ref thermoprops and
00007  *  class \link Cantera::VPSSMgr_General VPSSMgr_General\endlink).
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  *  $Author: hkmoffa $
00016  *  $Date: 2009-12-05 14:08:43 -0500 (Sat, 05 Dec 2009) $
00017  *  $Revision: 279 $
00018  */
00019 
00020 // turn off warnings under Windows
00021 #ifdef WIN32
00022 #pragma warning(disable:4786)
00023 #pragma warning(disable:4503)
00024 #endif
00025 
00026 #include "VPSSMgr_General.h"
00027 #include "PDSS.h"
00028 #include "xml.h"
00029 #include "ctml.h"
00030 #include "PDSS_IdealGas.h"
00031 #include "PDSS_Water.h"
00032 #include "PDSS_ConstVol.h"
00033 #include "PDSS_SSVol.h"
00034 #include "PDSS_HKFT.h"
00035 #include "PDSS_IonsFromNeutral.h"
00036 #include "GeneralSpeciesThermo.h"
00037 
00038 using namespace std;
00039 
00040 namespace Cantera {
00041 
00042 
00043   VPSSMgr_General::VPSSMgr_General(VPStandardStateTP *vp_ptr,
00044                                    SpeciesThermo *spth) :
00045     VPSSMgr(vp_ptr, spth)
00046   {
00047     // Might want to do something other than holding this true.
00048     //    However, for the sake of getting this all up and running, 
00049     //    will not go there for now.
00050     m_useTmpStandardStateStorage = true;
00051     m_useTmpRefStateStorage = true;
00052   }
00053 
00054 
00055   VPSSMgr_General::~VPSSMgr_General() 
00056   {
00057   }
00058 
00059   VPSSMgr_General::VPSSMgr_General(const VPSSMgr_General &right) :
00060     VPSSMgr(right.m_vptp_ptr, right.m_spthermo)
00061   {
00062     m_useTmpStandardStateStorage = true;
00063     m_useTmpRefStateStorage = true;
00064     *this = right;
00065   }
00066   //====================================================================================================================
00067   VPSSMgr_General& VPSSMgr_General::operator=(const VPSSMgr_General &b) 
00068   {
00069     if (&b == this) {
00070       return *this;
00071     }
00072     VPSSMgr::operator=(b);
00073     /*
00074      *  Must fill in the shallow pointers. These must have already been transfered
00075      *  and storred in the owning VPStandardStateTP class.  Note we are aware that at this point
00076      *  m_vptr_ptr may refer back to the wrong ThermoPhase object. However, the shallow copy 
00077      *  performed here is consistent with the assignment operator's general functionality.
00078      */
00079     m_PDSS_ptrs.resize(m_kk);
00080     for (int k = 0; k < m_kk; k++) {
00081        m_PDSS_ptrs[k] = m_vptp_ptr->providePDSS(k);
00082     }
00083     return *this;
00084   }
00085 
00086   VPSSMgr *VPSSMgr_General::duplMyselfAsVPSSMgr() const {
00087     VPSSMgr_General *vpm = new VPSSMgr_General(*this);
00088     return (VPSSMgr *) vpm;
00089   }
00090   //====================================================================================================================
00091   // Initialize the internal shallow pointers in this object
00092   /*
00093    * There are a bunch of internal shallow pointers that point to the owning
00094    * VPStandardStateTP and SpeciesThermo objects. This function reinitializes
00095    * them. This function is called like an onion.
00096    * 
00097    *  @param vp_ptr   Pointer to the VPStandardStateTP standard state
00098    *  @param sp_ptr   Poitner to the SpeciesThermo standard state
00099    */
00100   void VPSSMgr_General::initAllPtrs(VPStandardStateTP *vp_ptr, SpeciesThermo *sp_ptr)
00101   {
00102     VPSSMgr::initAllPtrs(vp_ptr, sp_ptr);
00103     /*
00104      *  Must fill in the shallow pointers. These must have already been transfered
00105      *  and storred in the owning VPStandardStateTP class.
00106      */
00107     m_PDSS_ptrs.resize(m_kk);
00108     for (int k = 0; k < m_kk; k++) {
00109       m_PDSS_ptrs[k] = m_vptp_ptr->providePDSS(k);
00110     }
00111   }
00112   //====================================================================================================================
00113   void VPSSMgr_General::_updateRefStateThermo() const
00114   {
00115     if (m_useTmpRefStateStorage) {
00116       for (int k = 0; k < m_kk; k++) {
00117         PDSS *kPDSS = m_PDSS_ptrs[k];
00118         kPDSS->setState_TP(m_tlast, m_plast);
00119         m_h0_RT[k] = kPDSS->enthalpy_RT_ref();
00120         m_s0_R[k]  = kPDSS->entropy_R_ref();
00121         m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
00122         m_cp0_R[k] = kPDSS->cp_R_ref();
00123         m_V0[k]    = kPDSS->molarVolume_ref();
00124       }
00125     }
00126   }
00127 
00128   void VPSSMgr_General::_updateStandardStateThermo()
00129   {
00130     for (int k = 0; k < m_kk; k++) {
00131       PDSS *kPDSS = m_PDSS_ptrs[k];
00132       kPDSS->setState_TP(m_tlast, m_plast);
00133       m_hss_RT[k] = kPDSS->enthalpy_RT();
00134       m_sss_R[k]  = kPDSS->entropy_R();
00135       m_gss_RT[k] = m_hss_RT[k] - m_sss_R[k];
00136       m_cpss_R[k] = kPDSS->cp_R();
00137       m_Vss[k]    = kPDSS->molarVolume();
00138     }
00139   }
00140   
00141 
00142   void VPSSMgr_General::initThermo() {
00143     initLengths();
00144   }
00145 
00146   /*!
00147    *  Returns the vector of the
00148    *  gibbs function of the reference state at the current temperature
00149    *  of the solution and the reference pressure for the species.
00150    *  units = J/kmol
00151    *
00152    * @param g   Output vector contain the Gibbs free energies
00153    *            of the reference state of the species
00154    *            length = m_kk, units = J/kmol.
00155    */
00156   void VPSSMgr_General::getGibbs_ref(doublereal *g) const {
00157     doublereal _rt = GasConstant * m_tlast;
00158     if (m_useTmpRefStateStorage) {
00159       std::copy(m_g0_RT.begin(), m_g0_RT.end(), g);  
00160       scale(g, g+m_kk, g, _rt);
00161     } else {
00162       for (int k = 0; k < m_kk; k++) {
00163         PDSS *kPDSS = m_PDSS_ptrs[k];
00164         kPDSS->setState_TP(m_tlast, m_plast);
00165         double h0_RT = kPDSS->enthalpy_RT_ref();
00166         double s0_R  = kPDSS->entropy_R_ref();
00167         g[k] = _rt * (h0_RT - s0_R);
00168       }
00169     }
00170   }
00171 
00172   void 
00173   VPSSMgr_General::initThermoXML(XML_Node& phaseNode, std::string id) {
00174     VPSSMgr::initThermoXML(phaseNode, id);
00175   }
00176 
00177   PDSS*  
00178   VPSSMgr_General::returnPDSS_ptr(int k, const XML_Node& speciesNode,
00179                                   const XML_Node * const phaseNode_ptr, bool &doST) {
00180     PDSS *kPDSS = 0;
00181     doST = true;
00182     GeneralSpeciesThermo *genSpthermo = dynamic_cast<GeneralSpeciesThermo *>(m_spthermo);
00183   
00184 
00185     const XML_Node * const ss = speciesNode.findByName("standardState");
00186     if (!ss) {
00187       VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
00188       kPDSS = new PDSS_IdealGas(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
00189       return kPDSS;
00190     } 
00191     std::string model = (*ss)["model"];
00192     if (model == "constant_incompressible") {
00193       VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
00194       kPDSS = new PDSS_ConstVol(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
00195       if (!kPDSS) {
00196         throw CanteraError("VPSSMgr_General::returnPDSS_ptr", "new PDSS_ConstVol failed");
00197       }
00198     } else if (model == "waterIAPWS" || model == "waterPDSS") { 
00199       // VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
00200       kPDSS = new PDSS_Water(m_vptp_ptr, 0);
00201       if (!genSpthermo) {
00202         throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
00203                            "failed dynamic cast");
00204       }
00205       genSpthermo->installPDSShandler(k, kPDSS, this);
00206       m_useTmpRefStateStorage = false;
00207     } else if (model == "HKFT") {
00208       doST = false;
00209       kPDSS = new PDSS_HKFT(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
00210       if (!genSpthermo) {
00211         throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
00212                            "failed dynamic cast");
00213       }
00214       genSpthermo->installPDSShandler(k, kPDSS, this);
00215 
00216     } else if (model == "IonFromNeutral") {
00217       if (!genSpthermo) {
00218         throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
00219                            "failed dynamic cast");
00220       }
00221       doST = false;
00222       kPDSS = new PDSS_IonsFromNeutral(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
00223       if (!kPDSS) {
00224         throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
00225                            "new PDSS_IonsFromNeutral failed");
00226       }
00227       genSpthermo->installPDSShandler(k, kPDSS, this);
00228 
00229     } else if (model == "constant" || model == "temperature_polynomial" || model == "density_temperature_polynomial") {
00230       VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
00231       kPDSS = new PDSS_SSVol(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
00232       if (!kPDSS) {
00233         throw CanteraError("VPSSMgr_General::returnPDSS_ptr", "new PDSS_SSVol failed");
00234       }
00235     } else {
00236       throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
00237                          "unknown standard state formulation: " + model);
00238     }
00239     return kPDSS;
00240   }
00241 
00242   PDSS *
00243   VPSSMgr_General::createInstallPDSS(int k, const XML_Node& speciesNode,  
00244                                      const XML_Node * const phaseNode_ptr) {
00245     bool doST;
00246     PDSS *kPDSS = returnPDSS_ptr(k, speciesNode, phaseNode_ptr, doST);
00247     // VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
00248     if ((int) m_PDSS_ptrs.size() < k+1) {
00249       m_PDSS_ptrs.resize(k+1, 0);
00250     }
00251     m_PDSS_ptrs[k] = kPDSS;
00252     if ((k+1) >= m_kk) {
00253       m_kk = k+1;
00254     }
00255 
00256     doublereal minTemp = kPDSS->minTemp();
00257     if (minTemp > m_minTemp) {
00258       m_minTemp = minTemp;
00259     }
00260 
00261     doublereal maxTemp = kPDSS->maxTemp();
00262     if (maxTemp < m_maxTemp) {
00263       m_maxTemp = maxTemp;
00264     }
00265 
00266     doublereal p0 = kPDSS->refPressure();
00267     if (k == 0) {
00268       m_p0 = p0;
00269     }
00270     return kPDSS;
00271   }
00272 
00273   PDSS_enumType VPSSMgr_General::reportPDSSType(int k) const {
00274     PDSS *kPDSS = m_PDSS_ptrs[k];
00275     return  kPDSS->reportPDSSType();
00276   }
00277 
00278 
00279   VPSSMgr_enumType  VPSSMgr_General::reportVPSSMgrType() const {
00280     return cVPSSMGR_GENERAL;
00281   }
00282 }
00283 
00284 
Generated by  doxygen 1.6.3