diff --git a/Cantera/src/thermo/SpeciesThermoFactory.cpp b/Cantera/src/thermo/SpeciesThermoFactory.cpp index 02933b6e3..4c7fe6106 100755 --- a/Cantera/src/thermo/SpeciesThermoFactory.cpp +++ b/Cantera/src/thermo/SpeciesThermoFactory.cpp @@ -50,44 +50,52 @@ namespace Cantera { #endif - /** - * Examine the types of species thermo parameterizations, - * and return a flag indicating the type of parameterization - * needed by the species. + + //! Examine the types of species thermo parameterizations, + //! and return a flag indicating the type of reference state thermo manager + //! that will be needed in order to evaluate them all. + /*! * - * @param spData_node Species Data XML node. This node contains a list - * of species XML nodes underneath it. + * @param spDataNodeList, This vector contains a list + * of species XML nodes that will be in the phase * * @todo Make sure that spDadta_node is species Data XML node by checking its name is speciesData */ - static void getSpeciesThermoTypes(XML_Node* spData_node, + static void getSpeciesThermoTypes(std::vector & spDataNodeList, int& has_nasa, int& has_shomate, int& has_simple, int &has_other) { - const XML_Node& sparray = *spData_node; - std::vector sp; - - // get all of the species nodes - sparray.getChildren("species",sp); - size_t n, ns = sp.size(); - for (n = 0; n < ns; n++) { - XML_Node* spNode = sp[n]; + size_t ns = spDataNodeList.size(); + for (size_t n = 0; n < ns; n++) { + XML_Node* spNode = spDataNodeList[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; - if (th.hasChild("const_cp")) has_simple = 1; - if (th.hasChild("poly")) { + const XML_Node& th = spNode->child("thermo"); + if (th.hasChild("NASA")) { + has_nasa = 1; + } else if (th.hasChild("Shomate")) { + has_shomate = 1; + } else if (th.hasChild("const_cp")) { + has_simple = 1; + } else if (th.hasChild("poly")) { if (th.child("poly")["order"] == "1") has_simple = 1; else throw CanteraError("newSpeciesThermo", "poly with order > 1 not yet supported"); } - if (th.hasChild("Mu0")) has_other = 1; - if (th.hasChild("NASA9")) has_other = 1; - if (th.hasChild("NASA9MULTITEMP")) has_other = 1; - if (th.hasChild("adsorbate")) has_other = 1; + else if (th.hasChild("Mu0")) { + has_other = 1; + } else if (th.hasChild("NASA9")) { + has_other = 1; + } else if (th.hasChild("NASA9MULTITEMP")) { + has_other = 1; + } else if (th.hasChild("adsorbate")) { + has_other = 1; + } else { + has_other = 1; + //throw UnknownSpeciesThermoModel("getSpeciesThermoTypes:", + // spNode->attrib("name"), "missing"); + } } else { - throw UnknownSpeciesThermoModel("getSpeciesThermoTypes:", - spNode->attrib("name"), "missing"); + throw CanteraError("getSpeciesThermoTypes:", + spNode->attrib("name") + " is missing the thermo XML node"); } } } @@ -97,35 +105,16 @@ namespace Cantera { * Return a species thermo manager to handle the parameterizations * specified in a CTML phase specification. */ - SpeciesThermo* SpeciesThermoFactory::newSpeciesThermo(XML_Node* spData_node) { + SpeciesThermo* SpeciesThermoFactory::newSpeciesThermo(std::vector & spDataNodeList) { int inasa = 0, ishomate = 0, isimple = 0, iother = 0; try { - getSpeciesThermoTypes(spData_node, inasa, ishomate, isimple, iother); + getSpeciesThermoTypes(spDataNodeList, inasa, ishomate, isimple, iother); } catch (UnknownSpeciesThermoModel) { iother = 1; popError(); } if (iother) { - writelog("returning new GeneralSpeciesThermo"); - return new GeneralSpeciesThermo(); - } - return newSpeciesThermo(NASA*inasa - + SHOMATE*ishomate + SIMPLE*isimple); - } - - SpeciesThermo* SpeciesThermoFactory:: - newSpeciesThermo(std::vector spData_nodes) { - int n = static_cast(spData_nodes.size()); - int inasa = 0, ishomate = 0, isimple = 0, iother = 0; - for (int j = 0; j < n; j++) { - try { - getSpeciesThermoTypes(spData_nodes[j], inasa, ishomate, isimple, iother); - } catch (UnknownSpeciesThermoModel) { - iother = 1; - popError(); - } - } - if (iother) { + //writelog("returning new GeneralSpeciesThermo"); return new GeneralSpeciesThermo(); } return newSpeciesThermo(NASA*inasa @@ -137,17 +126,15 @@ namespace Cantera { * @todo is this used? */ SpeciesThermo* SpeciesThermoFactory:: - newSpeciesThermoOpt(std::vector nodes) { - int n = static_cast(nodes.size()); + newSpeciesThermoOpt(std::vector & spDataNodeList) { int inasa = 0, ishomate = 0, isimple = 0, iother = 0; - for (int j = 0; j < n; j++) { - try { - getSpeciesThermoTypes(nodes[j], inasa, ishomate, isimple, iother); - } catch (UnknownSpeciesThermoModel) { - iother = 1; - popError(); - } + try { + getSpeciesThermoTypes(spDataNodeList, inasa, ishomate, isimple, iother); + } catch (UnknownSpeciesThermoModel) { + iother = 1; + popError(); } + if (iother) { return new GeneralSpeciesThermo(); } @@ -655,6 +642,80 @@ namespace Cantera { vp_ptr->createInstallPDSS(k, speciesNode, phaseNode_ptr); } + // Create a new species thermo manager instance, by specifying + // the type and (optionally) a pointer to the factory to use to create it. + /* + * This utility program will look through species nodes. It will discover what + * each species needs for its species property managers. Then, + * it will malloc and return the proper species property manager to use. + * + * These functions allow using a different factory class that + * derives from SpeciesThermoFactory. + * + * @param type Species thermo type. + * @param f Pointer to a SpeciesThermoFactory. optional parameter. + * Defautls to NULL. + */ + SpeciesThermo* newSpeciesThermoMgr(int type, SpeciesThermoFactory* f) { + if (f == 0) { + f = SpeciesThermoFactory::factory(); + } + SpeciesThermo* sptherm = f->newSpeciesThermo(type); + return sptherm; + } + // Function to return SpeciesThermo manager + /* + * This utility program will look through species nodes. It will discover what + * each species needs for its species property managers. Then, + * it will malloc and return the proper species property manager to use. + * + * These functions allow using a different factory class that + * derives from SpeciesThermoFactory. + * + * @param spData_node Vector of XML_Nodes, each of which is a speciesData XML Node. + * Each %speciesData node contains a list of XML species elements + * e.g., \ + * @param f Pointer to a SpeciesThermoFactory. optional parameter. + * Defautls to NULL. + */ + // SpeciesThermo* newSpeciesThermoMgr(XML_Node* spData_node, + // SpeciesThermoFactory* f) { + //if (f == 0) { + // f = SpeciesThermoFactory::factory(); + //} + //SpeciesThermo* sptherm = f->newSpeciesThermo(spData_node); + //return sptherm; + //} + + //! Function to return SpeciesThermo manager + /*! + * This utility program will look through species nodes. It will discover what + * each species needs for its species property managers. Then, + * it will malloc and return the proper species property manager to use. + * + * These functions allow using a different factory class that + * derives from SpeciesThermoFactory. + * + * @param spData_nodes Vector of XML_Nodes, each of which is a speciesData XML Node. + * Each %speciesData node contains a list of XML species elements + * e.g., \ + * @param f Pointer to a SpeciesThermoFactory. optional parameter. + * Defautls to NULL. + * @param opt Boolean defaults to false. + */ + SpeciesThermo* newSpeciesThermoMgr(std::vector spData_nodes, + SpeciesThermoFactory* f, bool opt) { + if (f == 0) { + f = SpeciesThermoFactory::factory(); + } + SpeciesThermo* sptherm; + if (opt) { + sptherm = f->newSpeciesThermoOpt(spData_nodes); + } else { + sptherm = f->newSpeciesThermo(spData_nodes); + } + return sptherm; + } } diff --git a/Cantera/src/thermo/SpeciesThermoFactory.h b/Cantera/src/thermo/SpeciesThermoFactory.h index 32a11d8f8..d7c404bd8 100755 --- a/Cantera/src/thermo/SpeciesThermoFactory.h +++ b/Cantera/src/thermo/SpeciesThermoFactory.h @@ -130,7 +130,6 @@ namespace Cantera { */ SpeciesThermo* newSpeciesThermo(int type); - //! Create a new species thermo property manager given a string /*! * Create a new species thermo property manager, given a @@ -140,29 +139,16 @@ namespace Cantera { */ SpeciesThermo* newSpeciesThermoManager(std::string &stype); - //! Create a new species property manager. - /*! - * This routine will look through species nodes. It will discover what - * each species needs for its species property managers. Then, - * it will malloc and return the proper species property manager to use. - * - * @param spData_node Pointer to a speciesData XML Node. - * Each speciesData node contains a list of XML species elements - * e.g., \ - */ - SpeciesThermo* newSpeciesThermo(XML_Node* spData_node); - //! Create a new species property manager for a group of species /*! * This routine will look through species nodes. It will discover what * each species needs for its species property managers. Then, * it will malloc and return the proper species property manager to use. - * - * @param spData_nodes Vector of XML_Nodes, each of which is a speciesData XML Node. - * Each speciesData node contains a list of XML species elements - * e.g., \ + * + * @param spDataNodeList, This vector contains a list + * of species XML nodes that will be in the phase */ - SpeciesThermo* newSpeciesThermo(std::vector spData_nodes); + SpeciesThermo* newSpeciesThermo(std::vector & spDataNodeList); //! Create a new species property manager. /*! @@ -171,13 +157,11 @@ namespace Cantera { * it will malloc and return the proper species property manager to use. * * - * @param spData_nodes Vector of XML_Nodes, each of which is a speciesData XML Node. - * Each %speciesData node contains a list of XML species elements - * e.g., \ - * + * @param spDataNodeList This vector contains a list + * of species XML nodes that will be in the phase * @todo is this used? */ - SpeciesThermo* newSpeciesThermoOpt(std::vector spData_nodes); + SpeciesThermo* newSpeciesThermoOpt(std::vector & spDataNodeList); //! Install a species thermodynamic property parameterization //! for the reference state for one species into a species thermo manager. @@ -258,14 +242,7 @@ namespace Cantera { * @param f Pointer to a SpeciesThermoFactory. optional parameter. * Defautls to NULL. */ - inline SpeciesThermo* newSpeciesThermoMgr(int type, - SpeciesThermoFactory* f=0) { - if (f == 0) { - f = SpeciesThermoFactory::factory(); - } - SpeciesThermo* sptherm = f->newSpeciesThermo(type); - return sptherm; - } + SpeciesThermo* newSpeciesThermoMgr(int type, SpeciesThermoFactory* f=0); //! Create a new species thermo manager instance, by specifying //!the type and (optionally) a pointer to the factory to use to create it. @@ -305,44 +282,27 @@ namespace Cantera { * @param f Pointer to a SpeciesThermoFactory. optional parameter. * Defautls to NULL. */ - inline SpeciesThermo* newSpeciesThermoMgr(XML_Node* spData_node, - SpeciesThermoFactory* f=0) { - if (f == 0) { - f = SpeciesThermoFactory::factory(); - } - SpeciesThermo* sptherm = f->newSpeciesThermo(spData_node); - return sptherm; - } + // SpeciesThermo* newSpeciesThermoMgr(XML_Node* spData_node, + // SpeciesThermoFactory* f=0); //! Function to return SpeciesThermo manager /*! * This utility program will look through species nodes. It will discover what * each species needs for its species property managers. Then, - * it will malloc and return the proper species property manager to use. + * it will malloc and return the proper species reference state manager to use. * * These functions allow using a different factory class that * derives from SpeciesThermoFactory. * - * @param spData_nodes Vector of XML_Nodes, each of which is a speciesData XML Node. - * Each %speciesData node contains a list of XML species elements - * e.g., \ + * @param spDataNodeList This vector contains a list + * of species XML nodes that will be in the phase + * * @param f Pointer to a SpeciesThermoFactory. optional parameter. * Defautls to NULL. * @param opt Boolean defaults to false. */ - inline SpeciesThermo* newSpeciesThermoMgr(std::vector spData_nodes, - SpeciesThermoFactory* f=0, bool opt=false) { - if (f == 0) { - f = SpeciesThermoFactory::factory(); - } - SpeciesThermo* sptherm; - if (opt) { - sptherm = f->newSpeciesThermoOpt(spData_nodes); - } else { - sptherm = f->newSpeciesThermo(spData_nodes); - } - return sptherm; - } + SpeciesThermo* newSpeciesThermoMgr(std::vector spDataNodeList, + SpeciesThermoFactory* f=0, bool opt=false); } diff --git a/Cantera/src/thermo/ThermoFactory.cpp b/Cantera/src/thermo/ThermoFactory.cpp index e6c6faba2..2628a5e07 100644 --- a/Cantera/src/thermo/ThermoFactory.cpp +++ b/Cantera/src/thermo/ThermoFactory.cpp @@ -229,6 +229,117 @@ namespace Cantera { return (ThermoPhase *) 0; } + + static void formSpeciesXMLNodeList(std::vector &spDataNodeList, + std::vector &spNamesList, + std::vector &spRuleList, + const std::vector spArray_names, + const std::vector spArray_dbases, + const vector_int sprule) { + + // used to check that each species is declared only once + std::map declared; + + int nspa = spArray_dbases.size(); + int nSpecies = 0; + bool skip; + + for (int jsp = 0; jsp < nspa; jsp++) { + const XML_Node& speciesArray = *spArray_names[jsp]; + + // Get the top XML for the database + const XML_Node *db = spArray_dbases[jsp]; + + // Get the array of species name strings and the count them + std::vector spnames; + getStringArray(speciesArray, spnames); + int nsp = static_cast(spnames.size()); + + // if 'all' is specified as the one and only species in the + // spArray_names field, then add all species + // defined in the corresponding database to the phase + if (nsp == 1 && spnames[0] == "all") { + std::vector allsp; + db->getChildren("species", allsp); + nsp = static_cast(allsp.size()); + spnames.resize(nsp); + for (int nn = 0; nn < nsp; nn++) { + string stemp = (*allsp[nn])["name"]; + bool skip = false; + if (declared[stemp]) { + if (sprule[jsp] >= 10) { + skip = true; + } else { + throw CanteraError("ThermoFactory::formSpeciesXMLNodeList()", + "duplicate species: \"" + stemp + "\""); + } + } + if (!skip) { + declared[stemp] = true; + nSpecies++; + spNamesList.resize(nSpecies); + spDataNodeList.resize(nSpecies, 0); + spRuleList.resize(nSpecies, 0); + spNamesList[nSpecies-1] = stemp; + spDataNodeList[nSpecies-1] = allsp[nn]; + spRuleList[nSpecies-1] = sprule[jsp]; + } + } + } + else if (nsp == 1 && spnames[0] == "unique") { + std::vector allsp; + db->getChildren("species", allsp); + nsp = static_cast(allsp.size()); + spnames.resize(nsp); + for (int nn = 0; nn < nsp; nn++) { + string stemp = (*allsp[nn])["name"]; + bool skip = false; + if (declared[stemp]) { + skip = true; + } + if (!skip) { + declared[stemp] = true; + nSpecies++; + spNamesList.resize(nSpecies); + spDataNodeList.resize(nSpecies, 0); + spRuleList.resize(nSpecies, 0); + spNamesList[nSpecies-1] = stemp; + spDataNodeList[nSpecies-1] = allsp[nn]; + spRuleList[nSpecies-1] = sprule[jsp]; + } + } + } else { + for (int k = 0; k < nsp; k++) { + string stemp = spnames[k]; + skip = false; + if (declared[stemp]) { + if (sprule[jsp] >= 10) { + skip = true; + } else { + throw CanteraError("ThermoFactory::formSpeciesXMLNodeList()", + "duplicate species: \"" + stemp + "\""); + } + } + if (!skip) { + declared[stemp] = true; + // Find the species in the database by name. + XML_Node* s = db->findByAttr("name", stemp); + if (!s) { + throw CanteraError("importPhase","no data for species, \"" + + stemp + "\""); + } + nSpecies++; + spNamesList.resize(nSpecies); + spDataNodeList.resize(nSpecies, 0); + spRuleList.resize(nSpecies, 0); + spNamesList[nSpecies-1] = stemp; + spDataNodeList[nSpecies-1] = s; + spRuleList[nSpecies-1] = sprule[jsp]; + } + } + } + } + } /* * Import a phase specification. @@ -262,7 +373,8 @@ namespace Cantera { // phase. if (phase.name() != "phase") { throw CanteraError("importPhase", - "Current const XML_Node named, " + phase.name() + ", is not a phase element."); + "Current const XML_Node named, " + phase.name() + + ", is not a phase element."); } // set the id attribute of the phase to the 'id' attribute @@ -275,7 +387,8 @@ namespace Cantera { int idim = intValue(phase["dim"]); if (idim < 1 || idim > 3) throw CanteraError("importPhase", - "phase, " + th->id() + ", has unphysical number of dimensions: " + phase["dim"]); + "phase, " + th->id() + + ", has unphysical number of dimensions: " + phase["dim"]); th->setNDim(idim); } else { @@ -290,7 +403,8 @@ namespace Cantera { th->setParametersFromXML(eos); } else { throw CanteraError("importPhase", - " phase, " + th->id() + ", XML_Node does not have a \"thermo\" XML_Node"); + " phase, " + th->id() + + ", XML_Node does not have a \"thermo\" XML_Node"); } VPStandardStateTP *vpss_ptr = 0; @@ -328,7 +442,8 @@ namespace Cantera { if (nspa == 0) { throw CanteraError("importPhase", "phase, " + th->id() + ", has zero \"speciesArray\" XML nodes.\n" - + " There must be at least one speciesArray nodes with one or more species"); + + " There must be at least one speciesArray nodes " + "with one or more species"); } vector dbases; vector_int sprule(nspa,0); @@ -336,15 +451,24 @@ namespace Cantera { // loop over the speciesArray elements for (jsp = 0; jsp < nspa; jsp++) { - const XML_Node& species = *sparrays[jsp]; + const XML_Node& speciesArray = *sparrays[jsp]; // If the speciesArray element has a child element + // // + // // then set sprule[jsp] to 1, so // that any species with an undeclared element will be // quietly skipped when importing species. - if (species.hasChild("skip")) { - const XML_Node& sk = species.child("skip"); + // Additionally, if the skip node has the following attribute: + // + // + // + // then duplicate species names will not cause Cantera to + // throw an exception. Instead, the duplicate entry will + // be discarded. + if (speciesArray.hasChild("skip")) { + const XML_Node& sk = speciesArray.child("skip"); string eskip = sk["element"]; if (eskip == "undeclared") { sprule[jsp] = 1; @@ -357,19 +481,33 @@ namespace Cantera { string fname, idstr; - // get a pointer to the node containing the species + // Get a pointer to the node containing the species // definitions for the species declared in this // speciesArray element. This may be in the local file // containing the phase element, or may be in another // file. - db = get_XML_Node(species["datasrc"], &phase.root()); + db = get_XML_Node(speciesArray["datasrc"], &phase.root()); + if (db == 0) { + throw CanteraError("importPhase", + " Can not find XML node for species database: " + + speciesArray["datasrc"]); + } // add this node to the list of species database nodes. dbases.push_back(db); } + // Now, collect all the species names and all the XML_Node * pointers + // for those species in a single vector. This is where we decide what + // species are to be included in the phase. + // The logic is complicated enough that we put it in a separate routine. + std::vector spDataNodeList; + std::vector spNamesList; + std::vector spRuleList; + formSpeciesXMLNodeList(spDataNodeList, spNamesList, spRuleList, + sparrays, dbases, sprule); - // if the phase has a species thermo manager already installed, + // If the phase has a species thermo manager already installed, // delete it since we are adding new species. delete &th->speciesThermo(); @@ -382,88 +520,28 @@ namespace Cantera { // to see what thermodynamic property parameterizations are // used, and selects a class that can handle the // parameterizations found. - spth = newSpeciesThermoMgr(dbases); + spth = newSpeciesThermoMgr(spDataNodeList); // install it in the phase object th->setSpeciesThermo(spth); - // SpeciesThermo& spthermo = th->speciesThermo(); } else { - vp_spth = newVPSSMgr(vpss_ptr, &phase, dbases); + vp_spth = newVPSSMgr(vpss_ptr, &phase, spDataNodeList); vpss_ptr->setVPSSMgr(vp_spth); spth = vp_spth->SpeciesThermoMgr(); th->setSpeciesThermo(spth); } - // used to check that each species is declared only once - map declared; + int k = 0; - int i, k = 0; - - // loop over the species arrays - for (jsp = 0; jsp < nspa; jsp++) { - - const XML_Node& species = *sparrays[jsp]; - db = dbases[jsp]; - - // Get the array of species name strings. - vector spnames; - getStringArray(species, spnames); - int nsp = static_cast(spnames.size()); - - // if 'all' is specified, then add all species - // defined in this database to the phase - if (nsp == 1 && spnames[0] == "all") { - vector allsp; - db->getChildren("species",allsp); - nsp = static_cast(allsp.size()); - spnames.resize(nsp); - for (int nn = 0; nn < nsp; nn++) { - spnames[nn] = (*allsp[nn])["name"]; - } - } - else if (nsp == 1 && spnames[0] == "unique") { - vector uniquesp; - db->getChildren("species",uniquesp); - nsp = static_cast(uniquesp.size()); - spnames.clear(); - spnames.resize(nsp); - string spnm; - for (int nn = 0; nn < nsp; nn++) { - spnm = (*uniquesp[nn])["name"]; - if (!declared[spnm]) spnames[nn] = spnm; - } - } - - string name; - bool skip; - for (i = 0; i < nsp; i++) { - name = spnames[i]; - skip = false; - if (name == "") skip = true; - // Check that every species is only declared once - if (declared[name]) { - if (sprule[jsp] >= 10) - skip = true; - else - throw CanteraError("importPhase", - "duplicate species: \"" + name + "\""); - } - if (!skip) { - declared[name] = true; - - // Find the species in the database by name. - XML_Node* s = db->findByAttr("name",spnames[i]); - if (s) { - if (installSpecies(k, *s, *th, spth, sprule[jsp], - &phase, vp_spth, spfactory)) - ++k; - } - else { - throw CanteraError("importPhase","no data for species, \"" - + name + "\""); - } - } + int nsp = spDataNodeList.size(); + for (int i = 0; i < nsp; i++) { + XML_Node *s = spDataNodeList[i]; + AssertTrace(s != 0); + bool ok = installSpecies(k, *s, *th, spth, spRuleList[i], + &phase, vp_spth, spfactory); + if (ok) { + ++k; } } @@ -474,6 +552,9 @@ namespace Cantera { // Perform any required subclass-specific initialization. th->initThermo(); + + // Perform any required subclass-specific initialization + // that requires the XML phase object string id = ""; th->initThermoXML(phase, id); diff --git a/Cantera/src/thermo/VPSSMgrFactory.cpp b/Cantera/src/thermo/VPSSMgrFactory.cpp index 964323a01..9a5fea73c 100644 --- a/Cantera/src/thermo/VPSSMgrFactory.cpp +++ b/Cantera/src/thermo/VPSSMgrFactory.cpp @@ -70,24 +70,21 @@ namespace Cantera { * * @todo Make sure that spDadta_node is species Data XML node by checking its name is speciesData */ - static void getVPSSMgrTypes(XML_Node* spData_node, - int& has_nasa, int& has_shomate, int& has_simple, + static void getVPSSMgrTypes(std::vector & spDataNodeList, + int &has_nasa, + int& has_shomate, + int& has_simple, int &has_water, int &has_tpx, int &has_hptx, int &has_other) { - - const XML_Node& sparray = *spData_node; - std::vector sp; - - // get all of the species nodes - sparray.getChildren("species",sp); - size_t n, ns = sp.size(); - for (n = 0; n < ns; n++) { + + size_t ns = spDataNodeList.size(); + for (size_t n = 0; n < ns; n++) { bool ifound = false; - XML_Node* spNode = sp[n]; + XML_Node* spNode = spDataNodeList[n]; if (spNode->hasChild("standardState")) { - const XML_Node& ssN = sp[n]->child("standardState"); + const XML_Node& ssN = spNode->child("standardState"); string mm = ssN["model"]; if (mm == "waterIAPWS" || mm == "waterPDSS") { has_water++; @@ -100,7 +97,7 @@ namespace Cantera { } if (!ifound) { if (spNode->hasChild("thermo")) { - const XML_Node& th = sp[n]->child("thermo"); + const XML_Node& th = spNode->child("thermo"); if (th.hasChild("NASA")) { has_nasa++; ifound = true; @@ -169,25 +166,13 @@ namespace Cantera { } return type; } - - // Chose the variable pressure standard state manager - // and the reference standard state manager - VPSSMgr* - VPSSMgrFactory::newVPSSMgr(VPStandardStateTP *vp_ptr, - XML_Node* phaseNode_ptr, - XML_Node* spData_node) { - std::vector spData_nodes; - spData_nodes.push_back(spData_node); - VPSSMgr *vv = newVPSSMgr(vp_ptr, phaseNode_ptr, spData_nodes); - return vv; - } // Chose the variable pressure standard state manager // and the reference standard state manager VPSSMgr* VPSSMgrFactory::newVPSSMgr(VPStandardStateTP *vp_ptr, XML_Node* phaseNode_ptr, - std::vector spData_nodes) { + std::vector & spDataNodeList) { std::string ssManager=""; std::string vpssManager=""; @@ -216,7 +201,7 @@ namespace Cantera { if (ssManager != "") { spth = newSpeciesThermoMgr(ssManager); } else { - spth = newSpeciesThermoMgr(spData_nodes); + spth = newSpeciesThermoMgr(spDataNodeList); } vp_ptr->setSpeciesThermo(spth); @@ -247,18 +232,17 @@ namespace Cantera { } - int n = static_cast(spData_nodes.size()); int inasa = 0, ishomate = 0, isimple = 0, iwater = 0, itpx = 0, iother = 0; int ihptx = 0; - for (int j = 0; j < n; j++) { - try { - getVPSSMgrTypes(spData_nodes[j], inasa, ishomate, isimple, iwater, - itpx, ihptx, iother); - } catch (UnknownSpeciesThermoModel) { - iother = 1; - popError(); - } + + try { + getVPSSMgrTypes(spDataNodeList, inasa, ishomate, isimple, iwater, + itpx, ihptx, iother); + } catch (UnknownSpeciesThermoModel) { + iother = 1; + popError(); } + if (iwater == 1) { if (ihptx == 0) { vpss = new VPSSMgr_Water_ConstVol(vp_ptr, spth); @@ -315,25 +299,15 @@ namespace Cantera { return vpsssptherm; } - VPSSMgr* newVPSSMgr(VPStandardStateTP *tp_ptr, - XML_Node* phaseNode_ptr, - XML_Node* spData_node, - VPSSMgrFactory* f) { - if (f == 0) { - f = VPSSMgrFactory::factory(); - } - VPSSMgr* vpsssptherm = f->newVPSSMgr(tp_ptr, phaseNode_ptr, spData_node); - return vpsssptherm; - } VPSSMgr* newVPSSMgr(VPStandardStateTP *tp_ptr, XML_Node* phaseNode_ptr, - std::vector spData_nodes, + std::vector & spDataNodeList, VPSSMgrFactory* f) { if (f == 0) { f = VPSSMgrFactory::factory(); } - VPSSMgr* vpsssptherm = f->newVPSSMgr(tp_ptr, phaseNode_ptr, spData_nodes); + VPSSMgr* vpsssptherm = f->newVPSSMgr(tp_ptr, phaseNode_ptr, spDataNodeList); return vpsssptherm; } diff --git a/Cantera/src/thermo/VPSSMgrFactory.h b/Cantera/src/thermo/VPSSMgrFactory.h index 32011fe79..acd9ffb6b 100644 --- a/Cantera/src/thermo/VPSSMgrFactory.h +++ b/Cantera/src/thermo/VPSSMgrFactory.h @@ -157,9 +157,9 @@ namespace Cantera { * Each speciesData node contains a list of XML species elements * e.g., \ */ - virtual VPSSMgr* newVPSSMgr(VPStandardStateTP *vp_ptr, - XML_Node* phaseNode_ptr, - XML_Node* spData_node); + // virtual VPSSMgr* newVPSSMgr(VPStandardStateTP *vp_ptr, + // XML_Node* phaseNode_ptr, + // XML_Node* spData_node); //! Create a new species property manager for a group of species /*! @@ -175,9 +175,8 @@ namespace Cantera { * e.g., \ */ virtual VPSSMgr* newVPSSMgr(VPStandardStateTP *vp_ptr, - XML_Node* phaseNode_ptr, - std::vector spData_nodes); - + XML_Node* phaseNode_ptr, + std::vector & spDataNodeList); private: @@ -223,29 +222,6 @@ namespace Cantera { VPSSMgr* newVPSSMgr(VPSSMgr_enumType type, VPStandardStateTP *vp_ptr, VPSSMgrFactory* f=0); - //! Function to return VPSSMgr manager - /*! - * This utility program will look through species nodes. It will discover what - * each species needs for its species property managers. Then, - * it will malloc and return the proper species property manager to use. - * - * These functions allow using a different factory class that - * derives from VPSSMgrFactory. - * - * @param vp_ptr Variable pressure standard state ThermoPhase object - * that will be the owner. - * @param phaseNode_ptr Pointer to the ThermoPhase phase XML Node - * @param spData_node Vector of XML_Nodes, each of which is a speciesData XML Node. - * Each %speciesData node contains a list of XML species elements - * e.g., \ - * @param f Pointer to a SpeciesThermoFactory. optional parameter. - * Defautls to NULL. - */ - VPSSMgr* newVPSSMgr(VPStandardStateTP *vp_ptr, - XML_Node* phaseNode_ptr, - XML_Node* spData_node, - VPSSMgrFactory* f=0); - //! Function to return VPSSMgr manager /*! * This utility program will look through species nodes. It will discover what @@ -258,15 +234,16 @@ namespace Cantera { * @param vp_ptr Variable pressure standard state ThermoPhase object * that will be the owner. * @param phaseNode_ptr Pointer to the ThermoPhase phase XML Node - * @param spData_nodes Vector of XML_Nodes, each of which is a speciesData XML Node. - * Each %speciesData node contains a list of XML species elements - * e.g., \ + * + * @param spDataNodeList This vector contains a list + * of species XML nodes that will be in the phase + * * @param f Pointer to a SpeciesThermoFactory. optional parameter. * Defautls to NULL. */ VPSSMgr* newVPSSMgr(VPStandardStateTP *vp_ptr, XML_Node* phaseNode_ptr, - std::vector spData_nodes, + std::vector & spDataNodeList, VPSSMgrFactory* f=0); } diff --git a/Cantera/src/thermo/VPSSMgr_Water_HKFT.cpp b/Cantera/src/thermo/VPSSMgr_Water_HKFT.cpp index c13cfdc50..d5038c10d 100644 --- a/Cantera/src/thermo/VPSSMgr_Water_HKFT.cpp +++ b/Cantera/src/thermo/VPSSMgr_Water_HKFT.cpp @@ -29,6 +29,7 @@ #include "VPStandardStateTP.h" #include "PDSS_Water.h" #include "PDSS_HKFT.h" +#include "GeneralSpeciesThermo.h" using namespace std; @@ -255,9 +256,17 @@ namespace Cantera { throw CanteraError("VPSSMgr_Water_HKFT::installSpecies", "wrong SS mode: " + model); } - VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr); + //VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr); if (m_waterSS) delete m_waterSS; m_waterSS = new PDSS_Water(m_vptp_ptr, 0); + + GeneralSpeciesThermo *genSpthermo = dynamic_cast(m_spthermo); + if (!genSpthermo) { + throw CanteraError("VPSSMgr_Water_HKFT::installSpecies", + "failed dynamic cast"); + } + genSpthermo->installPDSShandler(k, m_waterSS, this); + kPDSS = m_waterSS; } else { std::string model = (*ss)["model"]; @@ -269,6 +278,12 @@ namespace Cantera { kPDSS = new PDSS_HKFT(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true); + GeneralSpeciesThermo *genSpthermo = dynamic_cast(m_spthermo); + if (!genSpthermo) { + throw CanteraError("VPSSMgr_Water_HKFT::installSpecies", + "failed dynamic cast"); + } + genSpthermo->installPDSShandler(k, kPDSS, this); } return kPDSS; }