From 7e6ef23479bce7d538f76c55b8580dca6c256e0c Mon Sep 17 00:00:00 2001 From: Harry Moffat Date: Wed, 3 Sep 2003 18:29:15 +0000 Subject: [PATCH] Two main changes: The routines will now throw a named error condition when it can't match the species thermo or it can't find the species thermo. This is used in PartSpecPhase.cpp to signal that the thermo functions should be created on the fly from the bulk phase thermo and the bulk species basis for the particle species. The second one is to eliminate a potential fatal error of calling a delete for an object in the object's own destructor function. --- Cantera/src/SpeciesThermo.h | 2 +- Cantera/src/SpeciesThermoFactory.cpp | 21 ++++++++++++++ Cantera/src/SpeciesThermoFactory.h | 43 ++++++++++++++++++++++++---- 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/Cantera/src/SpeciesThermo.h b/Cantera/src/SpeciesThermo.h index 2753da0cb..e4c671170 100755 --- a/Cantera/src/SpeciesThermo.h +++ b/Cantera/src/SpeciesThermo.h @@ -80,7 +80,7 @@ namespace Cantera { doublereal* s_R) const=0; /** - * Like update, but only updates position k. + * Like update, but only updates the species k. */ virtual void update_one(int k, doublereal T, doublereal* cp_R, diff --git a/Cantera/src/SpeciesThermoFactory.cpp b/Cantera/src/SpeciesThermoFactory.cpp index ad7fc8e86..ecba83a63 100755 --- a/Cantera/src/SpeciesThermoFactory.cpp +++ b/Cantera/src/SpeciesThermoFactory.cpp @@ -40,6 +40,8 @@ namespace Cantera { sparray.getChildren("species",sp); int ns = sp.size(); for (int n = 0; n < ns; n++) { + XML_Node* spNode = sp[n]; + if (spNode->hasChild("thermo")) { const XML_Node& th = sp[n]->child("thermo"); if (th.hasChild("NASA")) has_nasa = 1; if (th.hasChild("Shomate")) has_shomate = 1; @@ -49,6 +51,10 @@ namespace Cantera { else throw CanteraError("newSpeciesThermo", "poly with order > 1 not yet supported"); } + } else { + throw UnknownSpeciesThermoModel("getSpeciesThermoTypes:", + spNode->attrib("name"), "missing"); + } } } @@ -75,6 +81,21 @@ namespace Cantera { } + SpeciesThermo* SpeciesThermoFactory::newSpeciesThermoOpt(vector nodes) { + int n = nodes.size(); + int inasa = 0, ishomate = 0, isimple = 0; + for (int j = 0; j < n; j++) { + try { + getSpeciesThermoTypes(nodes[j], inasa, ishomate, isimple); + } catch (UnknownSpeciesThermoModel) { + + } + } + return newSpeciesThermo(NASA*inasa + + SHOMATE*ishomate + SIMPLE*isimple); + } + + SpeciesThermo* SpeciesThermoFactory::newSpeciesThermo(int type) { switch (type) { diff --git a/Cantera/src/SpeciesThermoFactory.h b/Cantera/src/SpeciesThermoFactory.h index 5eec44735..6e52e1b68 100755 --- a/Cantera/src/SpeciesThermoFactory.h +++ b/Cantera/src/SpeciesThermoFactory.h @@ -15,12 +15,27 @@ #define SPECIESTHERMO_FACTORY_H #include "SpeciesThermo.h" -//#include "xml.h" +#include "ctexceptions.h" namespace Cantera { class XML_Node; + /** + * Throw a named error for an unknown or missing species thermo + * model. + */ + class UnknownSpeciesThermoModel: public CanteraError { + public: + UnknownSpeciesThermoModel(string proc, string spName, + string speciesThermoModel) : + CanteraError(proc, "species :" + spName + + ": Specified speciesThermoPhase model " + + speciesThermoModel + + " does not match any known type.") {} + virtual ~UnknownSpeciesThermoModel() {} + }; + /** * Factory to build instances of classes that manage the * standard-state thermodynamic properties of a set of species. @@ -33,10 +48,20 @@ namespace Cantera { if (!__factory) __factory = new SpeciesThermoFactory; return __factory; } - + static void deleteFactory() { + if (__factory) { + delete __factory; + __factory = 0; + } + } + + /** + * Destructor doesn't do anything. We do not delete statically + * created single instance of this class here, because it would + * create an infinite loop if destructor is called for that + * single instance. + */ virtual ~SpeciesThermoFactory() { - delete __factory; - __factory = 0; } /** @@ -46,6 +71,7 @@ namespace Cantera { virtual SpeciesThermo* newSpeciesThermo(int type); virtual SpeciesThermo* newSpeciesThermo(XML_Node* node); virtual SpeciesThermo* newSpeciesThermo(vector nodes); + virtual SpeciesThermo* newSpeciesThermoOpt(vector nodes); private: static SpeciesThermoFactory* __factory; @@ -78,11 +104,16 @@ namespace Cantera { } inline SpeciesThermo* newSpeciesThermoMgr(vector nodes, - SpeciesThermoFactory* f=0) { + SpeciesThermoFactory* f=0, bool opt=false) { if (f == 0) { f = SpeciesThermoFactory::factory(); } - SpeciesThermo* sptherm = f->newSpeciesThermo(nodes); + SpeciesThermo* sptherm; + if (opt) { + sptherm = f->newSpeciesThermoOpt(nodes); + } else { + sptherm = f->newSpeciesThermo(nodes); + } return sptherm; }