From 40255fcf4c2aa1050d20f433ca480bf4aa30038c Mon Sep 17 00:00:00 2001 From: Harry Moffat Date: Thu, 29 Mar 2007 23:54:32 +0000 Subject: [PATCH] doxygen update More work on MultiPhase. Fixed some errors in elementAbundance calc too. Added the definitions AssertTrace(), AssertThrow(), and AssertThrowMsg() for a debug assertion capability. Added them to a test problem to make sure that they actually compile. --- Cantera/src/MultiPhase.cpp | 185 +++++++++++------------ Cantera/src/MultiPhase.h | 163 +++++++++++++++----- Cantera/src/ctexceptions.h | 76 +++++++++- test_problems/diamondSurf/runDiamond.cpp | 11 +- 4 files changed, 299 insertions(+), 136 deletions(-) diff --git a/Cantera/src/MultiPhase.cpp b/Cantera/src/MultiPhase.cpp index aafa2e200..3bc0be5c3 100644 --- a/Cantera/src/MultiPhase.cpp +++ b/Cantera/src/MultiPhase.cpp @@ -103,10 +103,10 @@ namespace Cantera { } - /// Process phases and build atomic composition array. This method - /// must be called after all phases are added, before doing - /// anything else with the mixture. After init() has been called, - /// no more phases may be added. + // Process phases and build atomic composition array. This method + // must be called after all phases are added, before doing + // anything else with the mixture. After init() has been called, + // no more phases may be added. void MultiPhase::init() { if (m_init) return; index_t ip, kp, k = 0, nsp, m; @@ -116,6 +116,7 @@ namespace Cantera { // allocate space for the atomic composition matrix m_atoms.resize(m_nel, m_nsp, 0.0); m_moleFractions.resize(m_nsp, 0.0); + m_elemAbundances.resize(m_nel, 0.0); // iterate over the elements // -> fill in m_atoms(m,k), m_snames(k), m_spphase(k), @@ -159,23 +160,21 @@ namespace Cantera { /// set the initial composition within each phase to the /// mole fractions stored in the phase objects m_init = true; - updateMoleFractions(); + + updateMoleFractions(); - m_elemAbundances.resize(m_nel, 0.0); - - calcElemAbundances(); } - /// Return a reference to phase n. The state of phase n is - /// also updated to match the state stored locally in the - /// mixture object. - MultiPhase::phase_t& MultiPhase::phase(index_t n) { - if (!m_init) init(); - m_phase[n]->setState_TPX(m_temp, m_press, - DATA_PTR(m_moleFractions) + m_spstart[n]); - return *m_phase[n]; - } + // Return a reference to phase n. The state of phase n is + // also updated to match the state stored locally in the + // mixture object. + MultiPhase::phase_t& MultiPhase::phase(index_t n) { + if (!m_init) init(); + m_phase[n]->setState_TPX(m_temp, m_press, + DATA_PTR(m_moleFractions) + m_spstart[n]); + return *m_phase[n]; + } /// Moles of species \c k. doublereal MultiPhase::speciesMoles(index_t k) const { @@ -340,58 +339,57 @@ namespace Cantera { p->setState_TPX(m_temp, m_press, x); } - /// Set the species moles using a map. The map \a xMap maps - /// species name strings to mole numbers. Mole numbers that are - /// less than or equal to zero will be set to zero. - void MultiPhase::setMolesByName(compositionMap& xMap) { - int kk = nSpecies(); - doublereal x; - vector_fp moles(kk, 0.0); - for (int k = 0; k < kk; k++) { - x = xMap[speciesName(k)]; - if (x > 0.0) moles[k] = x; - } - setMoles(DATA_PTR(moles)); + // Set the species moles using a map. The map \a xMap maps + // species name strings to mole numbers. Mole numbers that are + // less than or equal to zero will be set to zero. + void MultiPhase::setMolesByName(compositionMap& xMap) { + int kk = nSpecies(); + doublereal x; + vector_fp moles(kk, 0.0); + for (int k = 0; k < kk; k++) { + x = xMap[speciesName(k)]; + if (x > 0.0) moles[k] = x; + } + setMoles(DATA_PTR(moles)); + } + + // Set the species moles using a string. Unspecified species are + // set to zero. + void MultiPhase::setMolesByName(const string& x) { + compositionMap xx; + + // add an entry in the map for every species, with value -1.0. + // Function parseCompString (stringUtils.cpp) uses the names + // in the map to specify the allowed species. + int kk = nSpecies(); + for (int k = 0; k < kk; k++) { + xx[speciesName(k)] = -1.0; } - - /// Set the species moles using a string. Unspecified species are - /// set to zero. - void MultiPhase::setMolesByName(const string& x) { - compositionMap xx; - - // add an entry in the map for every species, with value -1.0. - // Function parseCompString (stringUtils.cpp) uses the names - // in the map to specify the allowed species. - int kk = nSpecies(); - for (int k = 0; k < kk; k++) { - xx[speciesName(k)] = -1.0; - } - - // build the composition map from the string, and then set the - // moles. - parseCompString(x, xx); - setMolesByName(xx); - } + // build the composition map from the string, and then set the + // moles. + parseCompString(x, xx); + setMolesByName(xx); + } - /// Get the mole numbers of all species in the multiphase - /// object - void MultiPhase::getMoles(doublereal * molNum) const { - /* - * First copy in the mole fractions - */ - copy(m_moleFractions.begin(), m_moleFractions.end(), molNum); - index_t ik; - doublereal *dtmp = molNum; - for (index_t ip = 0; ip < m_np; ip++) { - doublereal phasemoles = m_moles[ip]; - phase_t* p = m_phase[ip]; - index_t nsp = p->nSpecies(); - for (ik = 0; ik < nsp; ik++) { - *(dtmp++) *= phasemoles; - } + // Get the mole numbers of all species in the multiphase + // object + void MultiPhase::getMoles(doublereal * molNum) const { + /* + * First copy in the mole fractions + */ + copy(m_moleFractions.begin(), m_moleFractions.end(), molNum); + index_t ik; + doublereal *dtmp = molNum; + for (index_t ip = 0; ip < m_np; ip++) { + doublereal phasemoles = m_moles[ip]; + phase_t* p = m_phase[ip]; + index_t nsp = p->nSpecies(); + for (ik = 0; ik < nsp; ik++) { + *(dtmp++) *= phasemoles; } } + } /// Set the species moles to the values in array \a n. The state /// of each phase object is also updated to have the specified @@ -825,40 +823,41 @@ done: return m_snames[k]; } - //------------------------------------------------------------- - // - // protected methods - // - //------------------------------------------------------------- + //------------------------------------------------------------- + // + // protected methods + // + //------------------------------------------------------------- - /// Update the locally-stored species mole fractions. - void MultiPhase::updateMoleFractions() { - index_t ip, loc = 0; - for (ip = 0; ip < m_np; ip++) { - phase_t* p = m_phase[ip]; - p->getMoleFractions(DATA_PTR(m_moleFractions) + loc); - loc += p->nSpecies(); - } + /// Update the locally-stored species mole fractions. + void MultiPhase::updateMoleFractions() { + index_t ip, loc = 0; + for (ip = 0; ip < m_np; ip++) { + phase_t* p = m_phase[ip]; + p->getMoleFractions(DATA_PTR(m_moleFractions) + loc); + loc += p->nSpecies(); } + calcElemAbundances(); + } - /// synchronize the phase objects with the mixture state. This - /// method sets each phase to the mixture temperature and - /// pressure, and sets the phase mole fractions based on the - /// mixture mole numbers. - void MultiPhase::updatePhases() const { - index_t p, nsp, loc = 0; - for (p = 0; p < m_np; p++) { - nsp = m_phase[p]->nSpecies(); - const doublereal* x = DATA_PTR(m_moleFractions) + loc; - loc += nsp; - m_phase[p]->setState_TPX(m_temp, m_press, x); - m_temp_OK[p] = true; - if (m_temp < m_phase[p]->minTemp() - || m_temp > m_phase[p]->maxTemp()) m_temp_OK[p] = false; - } - } + /// synchronize the phase objects with the mixture state. This + /// method sets each phase to the mixture temperature and + /// pressure, and sets the phase mole fractions based on the + /// mixture mole numbers. + void MultiPhase::updatePhases() const { + index_t p, nsp, loc = 0; + for (p = 0; p < m_np; p++) { + nsp = m_phase[p]->nSpecies(); + const doublereal* x = DATA_PTR(m_moleFractions) + loc; + loc += nsp; + m_phase[p]->setState_TPX(m_temp, m_press, x); + m_temp_OK[p] = true; + if (m_temp < m_phase[p]->minTemp() + || m_temp > m_phase[p]->maxTemp()) m_temp_OK[p] = false; + } + } } diff --git a/Cantera/src/MultiPhase.h b/Cantera/src/MultiPhase.h index 94c3fb07e..715cc6ef6 100644 --- a/Cantera/src/MultiPhase.h +++ b/Cantera/src/MultiPhase.h @@ -35,10 +35,16 @@ namespace Cantera { public: - // some typedefs for convenience + //! Shorthand for an index variable that can't be negative typedef size_t index_t; + + //! Shorthand for a ThermoPhase typedef ThermoPhase phase_t; + + //! shorthand for a 2D matrix typedef DenseMatrix array_t; + + //! Shorthand for a vector of pointers to ThermoPhase's typedef std::vector phase_list; /// Constructor. The constructor takes no arguments, since @@ -50,7 +56,13 @@ namespace Cantera { /// phase objects. virtual ~MultiPhase() {} - + //! Add a vector of phases to the mixture + /*! + * See the single addPhases command. This just does a bunch of phases + * at one time + * @param phases Vector of pointers to phases + * @param phaseMoles Vector of mole numbers in each phase (kmol) + */ void addPhases(phase_list& phases, const vector_fp& phaseMoles); /// Add all phases present in 'mix' to this mixture. @@ -74,12 +86,12 @@ namespace Cantera { int nSpecies() const { return int(m_nsp); } //! Name of species with global index \a k. - std::string speciesName(int k) const; + std::string speciesName(int kGlob) const; /// Number of atoms of element \a m in species \a k. - doublereal nAtoms(int k, int m) { + doublereal nAtoms(int kGlob, int mGlob) { if (!m_init) init(); - return m_atoms(m,k); + return m_atoms(mGlob, kGlob); } /// Species mole fractions. Write the array of species mole @@ -89,31 +101,50 @@ namespace Cantera { std::copy(m_moleFractions.begin(), m_moleFractions.end(), x); } - /// Process phases and build atomic composition array. After - /// init() has been called, no more phases may be added. + //! Process phases and build atomic composition array. + /*!This method + * must be called after all phases are added, before doing + * anything else with the mixture. After init() has been called, + * no more phases may be added. + */ void init(); - /// Moles of phase n. + //! Return the number of moles in phase n. + /*! + * @param n Index of the phase. + */ doublereal phaseMoles(index_t n) const { return m_moles[n]; } - /// Set the number of moles of phase with index n. + //! Set the number of moles of phase with index n. + /*! + * @param n Index of the phase + * @param moles Number of moles in the phase (kmol) + */ void setPhaseMoles(index_t n, doublereal moles) { m_moles[n] = moles; } - /// Return a reference to phase n. The state of phase n is - /// also updated to match the state stored locally in the - /// mixture object. + /// Return a %ThermoPhase reference to phase n. + /*! The state of phase n is + * also updated to match the state stored locally in the + * mixture object. + * + * @param n Phase Index + * + * @return Reference to the %ThermoPhase object for the phase + */ phase_t& phase(index_t n); - //! Moles of species \c k. + //! Returns the moles of global species \c k. /*! * Returns the moles of global species k. * units = kmol + * + * @param kGlob Global species index k */ - doublereal speciesMoles(index_t k) const; + doublereal speciesMoles(index_t kGlob) const; /// Index of the species belonging to phase number \c p /// with index \c k within the phase. @@ -160,17 +191,19 @@ namespace Cantera { /// Temperature [K]. doublereal temperature() const { return m_temp; } - /// Set the mixture to a state of chemical equilibrium. - /// @param XY Integer flag specifying properties to hold fixed. - /// @param err Error tolerance for \f$\Delta \mu/RT \f$ for - /// all reactions. Also used as the relative error tolerance - /// for the outer loop. - /// @param maxsteps Maximum number of steps to take in solving - /// the fixed TP problem. - /// @param maxiter Maximum number of "outer" iterations for - /// problems holding fixed something other than (T,P). - /// @param loglevel Level of diagnostic output, written to a - /// file in HTML format. + //! Set the mixture to a state of chemical equilibrium. + /*! + * @param XY Integer flag specifying properties to hold fixed. + * @param err Error tolerance for \f$\Delta \mu/RT \f$ for + * all reactions. Also used as the relative error tolerance + * for the outer loop. + * @param maxsteps Maximum number of steps to take in solving + * the fixed TP problem. + * @param maxiter Maximum number of "outer" iterations for + * problems holding fixed something other than (T,P). + * @param loglevel Level of diagnostic output, written to a + * file in HTML format. + */ doublereal equilibrate(int XY, doublereal err = 1.0e-9, int maxsteps = 1000, int maxiter = 200, int loglevel = -99); @@ -212,33 +245,62 @@ namespace Cantera { return m_np; } - /// Return true is species \a k is a species in a + /// Return true is species \a kGlob is a species in a /// multicomponent solution phase. - bool solutionSpecies(index_t k) const; + bool solutionSpecies(index_t kGlob) const; //! Returns the phase index of the Kth "global" species /*! - * @param k Global species index. + * @param kGlob Global species index. * * @return * Returns the index of the owning phase. */ - index_t speciesPhaseIndex(index_t k) const { - return m_spphase[k]; + index_t speciesPhaseIndex(index_t kGlob) const { + return m_spphase[kGlob]; } //! Returns the mole fraction of global species k - doublereal moleFraction(index_t k) const{ - return m_moleFractions[k]; + doublereal moleFraction(index_t kGlob) const{ + return m_moleFractions[kGlob]; } void setPhaseMoleFractions(index_t n, doublereal* x); void setMolesByName(compositionMap& xMap); + //! Set the Moles via a string containing their names. + /*! + * The string x is in the form of a composition map + * Species which are not listed by name in the composition + * map are set to zero. + * + * @param x string x in the form of a composition map + * where values are the moles of the species. + */ void setMolesByName(const std::string& x); + + //! Return a vector of global species mole numbers + /*! + * Returns a vector of the number of moles of each species + * in the multiphase object. + * + * @param molNum Vector of doubles of length nSpecies + * containing the global mole numbers + * (kmol). + */ void getMoles(doublereal * molNum) const; + + //! Sets all of the global species mole numbers + /*! + * Sets the number of moles of each species + * in the multiphase object. + * + * @param n Vector of doubles of length nSpecies + * containing the global mole numbers + * (kmol). + */ void setMoles(doublereal* n); //! Retrieves a vector of element abundances @@ -250,13 +312,15 @@ namespace Cantera { */ void getElemAbundances(doublereal * elemAbundances) const; - /// Return true if the phase \a p has valid thermo data for - /// the current temperature. + //! Return true if the phase \a p has valid thermo data for + //! the current temperature. + /*! + * @param p Index of the phase. + */ bool tempOK(index_t p) const { return m_temp_OK[p]; } - protected: // These methods are meant for internal use. @@ -264,6 +328,7 @@ namespace Cantera { /// compositions of the phase objects. void updateMoleFractions(); + protected: /// Set the states of the phase objects to the locally-stored /// state. Note that if individual phases have T and P different /// than that stored locally, the phase T and P will be modified. @@ -297,6 +362,13 @@ namespace Cantera { */ vector_fp m_moleFractions; vector_int m_spphase; + + //! Vector of ints containing of first species index in the global list of species + //! for each phase + /*! + * kfirst = m_spstart[ip], kfirst is the index of the first species in the ip'th + * phase. + */ vector_int m_spstart; std::vector m_enames; vector_int m_atomicNumber; @@ -325,8 +397,27 @@ namespace Cantera { index_t m_nsp; bool m_init; int m_eloc; + + //! Vector of bools indicating whether temperatures are ok for phases. + /*! + * If the current temperature is outside the range of valid temperatures + * for the phase thermodynamics, the phase flag is set to false. + */ mutable std::vector m_temp_OK; - doublereal m_Tmin, m_Tmax; + + //! Minimum temperature for which thermo parameterizations are valid + /*! + * Stoichiometric phases are ignored in this determination. + * units Kelvin + */ + doublereal m_Tmin; + + //! Minimum temperature for which thermo parameterizations are valid + /*! + * Stoichiometric phases are ignored in this determination. + * units Kelvin + */ + doublereal m_Tmax; mutable vector_fp m_elemAbundances; }; diff --git a/Cantera/src/ctexceptions.h b/Cantera/src/ctexceptions.h index bc10d8187..183844fad 100755 --- a/Cantera/src/ctexceptions.h +++ b/Cantera/src/ctexceptions.h @@ -26,7 +26,8 @@ namespace Cantera { /*! * @defgroup errorhandling Error Handling * - * \brief These classes and related functions are used to handle errors and unknown events within Cantera. + * \brief These classes and related functions are used to handle errors and + * unknown events within Cantera. * * The general idea is that exceptions are thrown using the common * base class called CanteraError. Derived types of CanteraError @@ -42,7 +43,23 @@ namespace Cantera { * \include edemo.cpp * * The function showErrors() will print out the fatal error condition to standard output. + * + * A group of defines may be used during debugging to assert conditions which should + * be true. These are named AssertTrace(), AssertThrow(), and AssertThrowMsg(). + * Examples of their usage is given below. + * + * @code + * AssertTrace(p == OneAtm); + * AssertThrow(p == OneAtm, "Kinetics::update"); + * AssertThrowMsg(p == OneAtm, "Kinetics::update", "Algorithm limited to atmospheric pressure"); + * @endcode + * + * Their first argument is a boolean. If the boolean is not true, a CanteraError is thrown, with + * descriptive information indicating where the error occured. These functions may be eliminated + * from the source code, if the -DNDEBUG option is specified to the compiler. + * */ + //! Base class for exceptions thrown by Cantera classes. /*! @@ -141,6 +158,63 @@ namespace Cantera { * @ingroup errorhandling */ void removeAtVersion(std::string func, std::string version); + + //! Provides a line number +#define XSTR_TRACE_LINE(s) STR_TRACE_LINE(s) + + //! Provides a line number +#define STR_TRACE_LINE(s) #s + + //! Provides a std::string variable containing the file and line number + /*! + * This is a std:string containing the file name and the line number + */ +#define STR_TRACE (std::string(__FILE__) + ":" + XSTR_TRACE_LINE(__LINE__)) + +#ifdef NDEBUG +# define AssertTrace(expr) ((void) (0)) +# define AssertThrow(expr, proc) ((void) (0)) +# define AssertThrowMsg(expr,proc, message) ((void) (0)) +#else + + //! Assertion must be true or an error is thrown + /*! + * Assertion must be true or else a CanteraError is thrown. A diagnostic string containing the + * file and line number, indicating where the error + * occured is added to the thrown object. + * + * @param expr Boolean expression that must be true + * + * @ingroup errorhandling + */ +# define AssertTrace(expr) ((expr) ? (void) 0 : throw CanteraError(STR_TRACE, std::string("failed assert: ") + #expr)) + + //! Assertion must be true or an error is thrown + /*! + * Assertion must be true or else a CanteraError is thrown. A diagnostic string indicating where the error + * occured is added to the thrown object. + * + * @param expr Boolean expression that must be true + * @param proc Character string or std:string expression indicating the procedure where the assertion failed + * @ingroup errorhandling + */ +# define AssertThrow(expr, proc) ((expr) ? (void) 0 : throw CanteraError(proc, std::string("failed assert: ") + #expr)) + + //! Assertion must be true or an error is thrown + /*! + * Assertion must be true or else a CanteraError is thrown. A diagnostic string indicating where the error + * occured is added to the thrown object. + * + * @param expr Boolean expression that must be true + * @param proc Character string or std:string expression indicating the procedure where the assertion failed + * @param message Character string or std:string expression contaiing a descriptive + * message is added to the thrown error condition. + * + * @ingroup errorhandling + */ +# define AssertThrowMsg(expr, proc, message) ((expr) ? (void) 0 : throw CanteraError(proc + std::string(": at failed assert: \"") + std::string(#expr) + std::string("\""), message)) +#endif + } #endif diff --git a/test_problems/diamondSurf/runDiamond.cpp b/test_problems/diamondSurf/runDiamond.cpp index 9022b34d3..59f84a410 100644 --- a/test_problems/diamondSurf/runDiamond.cpp +++ b/test_problems/diamondSurf/runDiamond.cpp @@ -25,11 +25,6 @@ int iDebug_HKM = 0; /*****************************************************************/ /*****************************************************************/ -/*****************************************************************/ -static void printUsage() -{ - -} #ifdef SRCDIRTREE #include "ct_defs.h" @@ -118,7 +113,11 @@ int main(int argc, char** argv) { iKin_ptr->advanceCoverages(100.); - + // Throw some asserts in here to test that they compile + AssertTrace(p == p); + AssertThrow(p == p, "main"); + AssertThrowMsg(i == 20, "main", "are you kidding"); + double src[20]; for (i = 0; i < 20; i++) src[i] = 0.0; iKin_ptr->getNetProductionRates(src);