Kinetics.cpp

Go to the documentation of this file.
00001 /**
00002  *  @file Kinetics.cpp
00003  *      Declarations for the base class for kinetics 
00004  *    managers (see \ref  kineticsmgr and class 
00005  *  \link Cantera::Kinetics Kinetics\endlink).
00006  *
00007  *      Kinetics managers calculate rates of progress of species due to homogeneous or heterogeneous kinetics.
00008  */
00009 /*
00010  *  $Date: 2010-02-09 15:24:11 -0500 (Tue, 09 Feb 2010) $
00011  *  $Revision: 398 $
00012  */
00013 
00014 // Copyright 2001-2004  California Institute of Technology            
00015 
00016 
00017              
00018 #include "InterfaceKinetics.h"
00019 #include "SurfPhase.h"            
00020 #include "StoichManager.h"
00021 #include "RateCoeffMgr.h"
00022                                                               
00023 #include "ImplicitSurfChem.h"
00024                     
00025 #include <iostream>
00026 using namespace std;
00027                                                             
00028                                   
00029 namespace Cantera {
00030 
00031     
00032   Kinetics::Kinetics() : m_ii(0), m_thermo(0),
00033                          m_index(-1), m_surfphase(-1), m_rxnphase(-1), 
00034                          m_mindim(4) {}
00035 
00036   Kinetics::~Kinetics(){}
00037 
00038 
00039   //  Copy Constructor for the %Kinetics object.
00040   /* 
00041    * Currently, this is not fully implemented. If called it will
00042    * throw an exception.
00043    */
00044   Kinetics::Kinetics(const Kinetics &right) :
00045     m_ii(0), 
00046     m_thermo(0),
00047     m_index(-1), 
00048     m_surfphase(-1),
00049     m_rxnphase(-1), 
00050     m_mindim(4)
00051   {
00052     /*
00053      * Call the assignment operator
00054      */
00055     *this = operator=(right);
00056   }
00057   
00058   // Assignment operator
00059   /*
00060    *  This is NOT a virtual function.
00061    *
00062    * @param right    Reference to %Kinetics object to be copied into the
00063    *                 current one.
00064    */
00065   Kinetics& Kinetics::
00066   operator=(const Kinetics &right) {
00067     /*
00068      * Check for self assignment.
00069      */
00070     if (this == &right) return *this;
00071     
00072     m_ii                = right.m_ii;
00073     m_perturb           = right.m_perturb;
00074     m_reactants         = right.m_reactants;
00075     m_products          = right.m_products;
00076    
00077     m_thermo            = right.m_thermo; //  DANGER -> shallow pointer copy
00078     
00079     m_start             = right.m_start;
00080     m_phaseindex        = right.m_phaseindex;
00081     m_index             = right.m_index;
00082     m_surfphase         = right.m_surfphase;
00083     m_rxnphase          = right.m_rxnphase;
00084     m_mindim            = right.m_mindim;
00085     m_dummygroups       = right.m_dummygroups;
00086 
00087     return *this;
00088   }
00089 
00090 
00091   // Duplication routine for objects which inherit from
00092   // Kinetics
00093   /*
00094    *  This virtual routine can be used to duplicate %Kinetics objects
00095    *  inherited from %Kinetics even if the application only has
00096    *  a pointer to %Kinetics to work with.
00097    *
00098    *  These routines are basically wrappers around the derived copy
00099    *  constructor.
00100    */
00101   Kinetics *Kinetics::duplMyselfAsKinetics() const {
00102     Kinetics* tp = new Kinetics(*this);
00103     return tp;
00104   }
00105 
00106 
00107 
00108   int Kinetics::ID() const {
00109     return 0;
00110   }
00111 
00112   int Kinetics::type() const {
00113     return 0;
00114   }
00115 
00116 
00117   /**
00118    * Takes as input an array of properties for all species in the
00119    * mechanism and copies those values beloning to a particular
00120    * phase to the output array.
00121    * @param data Input data array.
00122    * @param phase Pointer to one of the phase objects participating
00123    * in this reaction mechanism
00124    * @param phase_data Output array where the values for the the
00125    * specified phase are to be written. 
00126    */
00127   void Kinetics::selectPhase(const doublereal* data, const thermo_t* phase,
00128                              doublereal* phase_data) {
00129     int n, nsp, np = nPhases();
00130     for (n = 0; n < np; n++) {
00131       if (phase == m_thermo[n]) {
00132         nsp = phase->nSpecies();
00133         copy(data + m_start[n], 
00134              data + m_start[n] + nsp, phase_data);
00135         return;
00136       }
00137     }
00138     throw CanteraError("Kinetics::selectPhase", "Phase not found.");
00139   }
00140 
00141 
00142   /**
00143    * kineticsSpeciesName():
00144    *
00145    * Return the string name of the kth species in the kinetics
00146    * manager. k is an integer from 0 to ktot - 1, where ktot is
00147    * the number of species in the kinetics manager, which is the
00148    * sum of the number of species in all phases participating in
00149    * the kinetics manager.  If k is out of bounds, the string
00150    * "<unknown>" is returned. 
00151    */
00152   string Kinetics::kineticsSpeciesName(int k) const {
00153     int np = m_start.size();
00154     for (int n = np-1; n >= 0; n--) {
00155       if (k >= m_start[n]) {
00156         return thermo(n).speciesName(k - m_start[n]);
00157       }
00158     }
00159     return "<unknown>";
00160   }
00161 
00162   /**
00163    * kineticsSpeciesIndex():
00164    *
00165    * This routine will look up a species number based on
00166    * the input string nm. The lookup of species will
00167    * occur for all phases listed in the kinetics object,
00168    * unless the string ph refers to a specific phase of
00169    * the object. 
00170    *
00171    *  return
00172    *   - If a match is found, the position in the species list
00173    *   is returned. 
00174    *   - If a specific phase is specified and no match is found,
00175    *   the value -1 is returned.
00176    *   - If no match is found in any phase, the value -2 is returned.
00177    */
00178   int Kinetics::kineticsSpeciesIndex(std::string nm, std::string ph) const {
00179     int np = static_cast<int>(m_thermo.size());
00180     int k;
00181     string id;
00182     for (int n = 0; n < np; n++) {
00183       id = thermo(n).id();
00184       if (ph == id) {
00185         k = thermo(n).speciesIndex(nm);
00186         if (k < 0) return -1;
00187         return k + m_start[n];
00188       }
00189       else if (ph == "<any>") {
00190         /*
00191          * Call the speciesIndex() member function of the
00192          * ThermoPhase object to find a match.
00193          */
00194         k = thermo(n).speciesIndex(nm);
00195         if (k >= 0) return k + m_start[n];
00196       }                    
00197     }
00198     return -2;
00199   }
00200 
00201   /**
00202    * This function looks up the string name of a species and
00203    * returns a reference to the ThermoPhase object of the
00204    * phase where the species resides.
00205    * Will throw an error if the species string doesn't match.
00206    */
00207   thermo_t& Kinetics::speciesPhase(std::string nm) {
00208     int np = static_cast<int>(m_thermo.size());
00209     int k;
00210     string id;
00211     for (int n = 0; n < np; n++) {
00212       k = thermo(n).speciesIndex(nm);
00213       if (k >= 0) return thermo(n);
00214     }
00215     throw CanteraError("speciesPhase", "unknown species "+nm);
00216     return thermo(0);
00217   }
00218 
00219   /**
00220    * This function takes as an argument the kineticsSpecies index
00221    * (i.e., the list index in the list of species in the kinetics
00222    * manager) and returns the index of the phase owning the 
00223    * species.
00224    */
00225   int Kinetics::speciesPhaseIndex(int k) {
00226     int np = m_start.size();
00227     for (int n = np-1; n >= 0; n--) {
00228       if (k >= m_start[n]) {
00229         return n;
00230       }
00231     }
00232     throw CanteraError("speciesPhaseIndex", "illegal species index: "+int2str(k));
00233     return -1;
00234   }
00235 
00236   /*
00237    * Add a phase to the kinetics manager object. This must
00238    * be done before the function init() is called or 
00239    * before any reactions are input.
00240    * The following fields are updated:
00241    *  m_start -> vector of integers, containing the
00242    *             starting position of the species for
00243    *             each phase in the kinetics mechanism.
00244    *  m_surfphase -> index of the surface phase.
00245    *  m_thermo -> vector of pointers to ThermoPhase phases
00246    *              that participate in the kinetics 
00247    *              mechanism.
00248    *  m_phaseindex -> map containing the string id of each
00249    *              ThermoPhase phase as a key and the
00250    *              index of the phase within the kinetics
00251    *              manager object as the value.
00252    */
00253   void Kinetics::addPhase(thermo_t& thermo) {
00254 
00255     // if not the first thermo object, set the start position
00256     // to that of the last object added + the number of its species 
00257     if (m_thermo.size() > 0) {
00258       m_start.push_back(m_start.back() 
00259                         + m_thermo.back()->nSpecies());
00260     }
00261     // otherwise start at 0
00262     else {
00263       m_start.push_back(0);
00264     }
00265 
00266     // the phase with lowest dimensionality is assumed to be the
00267     // phase/interface at which reactions take place
00268     if (thermo.nDim() <= m_mindim) {
00269       m_mindim = thermo.nDim();
00270       m_rxnphase = nPhases();
00271     }
00272 
00273     // there should only be one surface phase
00274     int ptype = -100;
00275     if (type() == cEdgeKinetics) ptype = cEdge;
00276     else if (type() == cInterfaceKinetics) ptype = cSurf;
00277     if (thermo.eosType() == ptype) {
00278       //   if (m_surfphase >= 0) {
00279       //    throw CanteraError("Kinetics::addPhase",
00280       //        "cannot add more than one surface phase");
00281       // }
00282       m_surfphase = nPhases();
00283       m_rxnphase = nPhases();
00284     }
00285     m_thermo.push_back(&thermo);
00286     m_phaseindex[m_thermo.back()->id()] = nPhases();
00287   }
00288 
00289   
00290   //! Private function of the class Kinetics, indicating that a function
00291   //!  inherited from the base class hasn't had a definition assigned to it
00292   /*!
00293    * @param m String message
00294    */
00295   void Kinetics::err(std::string m) const {
00296     throw CanteraError("Kinetics::" + m, 
00297                        "The default Base class method was called, when "
00298                        "the inherited class's method should "
00299                        "have been called");
00300   }
00301 
00302 }
Generated by  doxygen 1.6.3