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.
This commit is contained in:
Harry Moffat 2003-09-03 18:29:15 +00:00
parent 35f71ec193
commit 7e6ef23479
3 changed files with 59 additions and 7 deletions

View file

@ -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,

View file

@ -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<XML_Node*> 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) {

View file

@ -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<XML_Node*> nodes);
virtual SpeciesThermo* newSpeciesThermoOpt(vector<XML_Node*> nodes);
private:
static SpeciesThermoFactory* __factory;
@ -78,11 +104,16 @@ namespace Cantera {
}
inline SpeciesThermo* newSpeciesThermoMgr(vector<XML_Node*> 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;
}