ThermoFactory.h

Go to the documentation of this file.
00001 /**
00002  *  @file ThermoFactory.h
00003  *     Headers for the factory class that can create known %ThermoPhase objects
00004  *     (see \ref thermoprops and class \link Cantera::ThermoFactory ThermoFactory\endlink).
00005  *
00006  */
00007 
00008 /*
00009  * $Author: hkmoffa $
00010  * $Revision: 304 $
00011  * $Date: 2009-12-08 12:36:40 -0500 (Tue, 08 Dec 2009) $
00012  */
00013 
00014 // Copyright 2001  California Institute of Technology
00015 
00016 
00017 #ifndef THERMO_FACTORY_H
00018 #define THERMO_FACTORY_H
00019 
00020 #include "ThermoPhase.h"
00021 #include "xml.h"
00022 
00023 #if defined(THREAD_SAFE_CANTERA)
00024 #include <boost/thread/mutex.hpp>
00025 #endif
00026 
00027 #include "FactoryBase.h"
00028 
00029 namespace Cantera {
00030 
00031   class SpeciesThermoFactory;
00032   class VPSSMgr;
00033 
00034   /*!
00035    *  @addtogroup thermoprops
00036    *
00037    *  Standard %ThermoPhase objects may be instantiated by calling
00038    *  the main %Cantera factory class for %ThermoPhase objects; This class is called ThermoFactory.
00039    */
00040   //@{
00041 
00042   //! Specific error to be thrown if the type of Thermo mananger is unrecognized.
00043   /*!
00044    * This particular error class may be caught, if the application may have other
00045    * models that the main Cantera appliation doesn't know about.
00046    */
00047   class UnknownThermoPhaseModel : public CanteraError {
00048   public:
00049     //! Constructor
00050     /*!
00051      * @param proc Function name where the error occurred.
00052      * @param thermoModel Sting name of ThermoPhase which didn't match
00053      */
00054     UnknownThermoPhaseModel(std::string proc, std::string thermoModel) :
00055       CanteraError(proc, "Specified ThermoPhase model "   
00056                    + thermoModel + 
00057                    " does not match any known type.") {}
00058     //! destructor
00059     virtual ~UnknownThermoPhaseModel() throw() {}
00060   };
00061 
00062   
00063   //! Factory class for thermodynamic property managers.
00064   /*!
00065    * This class keeps a list of the known ThermoPhase classes, and is
00066    * used to create new instances of these classes.
00067    */
00068   class ThermoFactory : public FactoryBase {
00069 
00070   public:
00071 
00072     //! Static function that creates a static instance of the factory.
00073     static ThermoFactory* factory() {
00074 #if defined(THREAD_SAFE_CANTERA)
00075         boost::mutex::scoped_lock lock(thermo_mutex);
00076 #endif
00077       if (!s_factory) s_factory = new ThermoFactory;
00078       return s_factory;
00079     }
00080 
00081       //! delete the static instance of this factory
00082       virtual void deleteFactory() {
00083 #if defined(THREAD_SAFE_CANTERA)
00084           boost::mutex::scoped_lock lock(thermo_mutex);
00085 #endif
00086           if (s_factory) {
00087             delete s_factory;
00088             s_factory = 0;
00089         }
00090     }
00091     
00092     //! Destructor doesn't do anything.
00093     /*!
00094      * We do not delete statically created single instance of this
00095      * class here, because it would create an infinite loop if
00096      * destructor is called for that single instance.
00097      */
00098     virtual ~ThermoFactory() { }
00099 
00100     //! Create a new thermodynamic property manager.
00101     /*!
00102      * @param model  String to look up the model against
00103      *
00104      * @return 
00105      *   Returns a pointer to a new ThermoPhase instance matching the
00106      *   model string. Returns NULL if something went wrong.
00107      *   Throws an exception UnknownThermoPhaseModel if the string
00108      *   wasn't matched.
00109      */
00110     virtual ThermoPhase* newThermoPhase(std::string model);
00111 
00112   private:
00113     //! static member of a single instance
00114     static ThermoFactory* s_factory;
00115 
00116     //! Private constructors prevents usage
00117     ThermoFactory(){};
00118    
00119 
00120 #if defined(THREAD_SAFE_CANTERA)
00121     //! Decl for locking mutex for thermo factory singelton
00122     static boost::mutex thermo_mutex;
00123 #endif
00124 
00125   };
00126   
00127   //!  Create a new thermo manager instance.
00128   /*!
00129    * @param model   String to look up the model against
00130    * @param f       ThermoFactor instance to use in matching the string
00131    *
00132    * @return 
00133    *   Returns a pointer to a new ThermoPhase instance matching the
00134    *   model string. Returns NULL if something went wrong.
00135    *   Throws an exception UnknownThermoPhaseModel if the string
00136    *   wasn't matched.
00137    */ 
00138     inline ThermoPhase* newThermoPhase(std::string model,  
00139                                      ThermoFactory* f=0) {
00140         if (f == 0) {
00141             f = ThermoFactory::factory();
00142         }
00143         return f->newThermoPhase(model);
00144     }
00145 
00146     //! Translate the eosType id into a string
00147     /*!
00148      *  Returns a string representation of the eosType id for a phase.
00149      *  @param ieos  eosType id of the phase. This is unique for the phase
00150      *  @param length maximum length of the return string. Defaults to 100
00151      * 
00152      *  @return returns a string representation.
00153      */
00154     std::string eosTypeString(int ieos, int length = 100);
00155 
00156 
00157   /*!
00158    *  This routine first looks up the
00159    * identity of the model for the solution thermodynamics in the
00160    * model attribute of the thermo child of the xml phase
00161    * node. Then, it does a string lookup using Cantera's internal ThermoPhase Factory routines
00162    * on the model to figure out
00163    * what ThermoPhase derived class should be assigned. It creates a new
00164    * instance of that class, and then calls importPhase() to
00165    * populate that class with the correct parameters from the XML
00166    * tree.
00167    *
00168    * @param phase XML_Node reference pointing to the phase XML element.
00169    *
00170    * @return
00171    *    Returns a pointer to the completed and initialized ThermoPhase object. 
00172    *
00173    * @ingroup inputfiles
00174    */
00175   ThermoPhase* newPhase(XML_Node& phase);
00176 
00177   //! Create and Initialize a ThermoPhase object from an XML input file.
00178   /*!
00179    *  This routine is a wrapper around the newPhase(XML_Node) routine
00180    *  which does the work. The wrapper locates the input phase XML_Node
00181    *  in a file, and then instantiates the object, returning the pointer
00182    *  to the ThermoPhase object.
00183    *
00184    * @param infile name of the input file
00185    * @param id     name of the phase id in the file.
00186    *               If this is blank, the first phase in the file is used.
00187    *
00188    * @return
00189    *   Returns an initialized ThermoPhase object.
00190    */
00191   ThermoPhase* newPhase(std::string infile, std::string id);
00192 
00193   //! Import a phase information into an empty thermophase object
00194   /*!
00195    *   Here we read an XML description of the thermodynamic information
00196    *   for a phase. At the end of this routine, the phase should
00197    *   be ready to be used within applications. This routine contains
00198    *   some key routines that are used as pass back routines so that
00199    *   the phase (and the contents of the XML file) may contain
00200    *   variable paramerizations for the specification of the
00201    *   species standard states, the equation of state, and the
00202    *   specification of other nonidealities. Below, a description
00203    *   is presented of the main algorithm for bringing up a %ThermoPhase
00204    *   object, with care to present points where customizations 
00205    *   occur.
00206    *
00207    *   Before invoking this routine, either the ThermoPhase Factory routines
00208    *   are called or direct constructor routines are called that
00209    *   instantiate an inherited ThermoPhase object. This object is input
00210    *   to this routine, and therefore contains inherited routines that
00211    *   drive the custimation of the initialization process.
00212    *    
00213    *   At the start of the routine, we import descriptions of the elements 
00214    *   that make up the species in a phase.
00215    *
00216    *   We call setParametersFromXML(eos) to read parameters about
00217    *   the thermo phase before the species are read in.
00218    *
00219    *   We call addElementsFromXML() to add elements into the 
00220    *   description of the phase.
00221    *
00222    *   We create a new species thermo manager.  Function
00223    *   'newSpeciesThermoMgr' looks at the species in the database
00224    *   to see what thermodynamic property parameterizations are
00225    *   used, and selects a class that can handle the
00226    *   parameterizations found.
00227    *
00228    *   We import information about the species, including their
00229    *   reference state thermodynamic polynomials. We then freeze
00230    *   the state of the species in the element.
00231    *
00232    *   Finally, we call initThermoXML(),
00233    *   a member function of the ThermoPhase object, to "finish"
00234    *   the description. Now that the species are known, 
00235    *   additional information may be read in about the thermodynamics
00236    *   of the phase, (e.g.,  virial coefficients, which are 
00237    *   binary or ternary interaction parameters between species).
00238    *
00239    * @param phase This object must be the phase node of a
00240    *             complete XML tree
00241    *             description of the phase, including all of the
00242    *             species data. In other words while "phase" must
00243    *             point to an XML phase object, it must have
00244    *             sibling nodes "speciesData" that describe
00245    *             the species in the phase.
00246    * @param th   Pointer to the ThermoPhase object which will
00247    *             handle the thermodynamics for this phase.
00248    *             We initialize part of the Thermophase object
00249    *             here, especially for those objects which are
00250    *             part of the Cantera Kernel.
00251    *
00252    * @param spfactory species Thermo factory pointer, if
00253    *                  available. If not available, one will be
00254    *                  created.
00255    *
00256    * @ingroup thermoprops
00257    */
00258   bool importPhase(XML_Node& phase, ThermoPhase* th, 
00259                    SpeciesThermoFactory* spfactory = 0);
00260 
00261   //! Install a species into a ThermoPhase object, which defines
00262   //! the phase thermodynamics and speciation.
00263   /*!
00264    *  This routine first gathers the information from the Species XML
00265    *  tree and calls addUniqueSpecies() to add it to the
00266    *  ThermoPhase object, p.
00267    *  This information consists of:
00268    *         ecomp[] = element composition of species.
00269    *         chgr    = electric charge of species
00270    *         name    = string name of species
00271    *         sz      = size of the species 
00272    *                 (option double used a lot in thermo)
00273    *
00274    *  Then, the routine processes the "thermo" XML element and
00275    *  calls underlying utility routines to read the XML elements
00276    *  containing the thermodynamic information for the reference
00277    *  state of the species. Failures or lack of information trigger
00278    *  an "UnknownSpeciesThermoModel" exception being thrown.
00279    *
00280    * @param k     Species Index in the phase
00281    * @param s     XML_Node containing the species data for this species.          
00282    * @param p     Reference to the ThermoPhase object.
00283    * @param spthermo_ptr Reference to the SpeciesThermo object, where
00284    *              the standard state thermo properties for this
00285    *              species will be installed.
00286    * @param rule  Parameter that handles what to do with species
00287    *              who have elements that aren't declared.
00288    *              Check that all elements in the species
00289    *              exist in 'p'. If rule != 0, quietly skip 
00290    *              this species if some elements are undeclared;
00291    *              otherwise, throw an exception
00292    * @param phaseNode_ptr Pointer to the XML_Node for this phase
00293    *              (defaults to 0)
00294    * @param vpss_ptr pointer to the Manager that calculates standard
00295    *                state thermo properties
00296    * @param factory Pointer to the SpeciesThermoFactory .
00297    *              (defaults to 0)
00298    *
00299    * @return
00300    *  Returns true if everything is ok, false otherwise.
00301    */
00302   bool installSpecies(int k, const XML_Node& s, thermo_t& p, 
00303                       SpeciesThermo* spthermo_ptr, int rule, 
00304                       XML_Node *phaseNode_ptr = 0,
00305                       VPSSMgr *vpss_ptr = 0,
00306                       SpeciesThermoFactory* factory = 0);
00307 
00308   //!Search an XML tree for species data.
00309   /*!
00310    *   This utility routine will search the XML tree for the species
00311    *   named by the string, kname. It will return the XML_Node
00312    *   pointer to the species data for that species.
00313    *   Failures of any kind return the null pointer.
00314    *
00315    * @param kname String containing the name of the species.
00316    * @param phaseSpeciesData   Pointer to the XML speciesData element
00317    *              containing the species data for that phase.
00318    *
00319    *
00320    */
00321   const XML_Node *speciesXML_Node(std::string kname,
00322                                   const XML_Node *phaseSpeciesData);
00323 
00324   //@}
00325 
00326 }
00327 
00328 #endif
00329 
00330 
Generated by  doxygen 1.6.3