void Phase::addElement(const XML_Node& e) { warn_deprecated("Phase::addElement(XML_Node&)", "To be removed after Cantera 2.2."); doublereal weight = 0.0; if (e.hasAttrib("atomicWt")) { weight = fpValue(stripws(e["atomicWt"])); } int anum = 0; if (e.hasAttrib("atomicNumber")) { anum = atoi(stripws(e["atomicNumber"]).c_str()); } string symbol = e["name"]; doublereal entropy298 = ENTROPY298_UNKNOWN; if (e.hasChild("entropy298")) { XML_Node& e298Node = e.child("entropy298"); if (e298Node.hasAttrib("value")) { entropy298 = fpValueCheck(stripws(e298Node["value"])); } } if (weight != 0.0) { addElement(symbol, weight, anum, entropy298); } else { addElement(symbol); } }
void installElements(Phase& th, const XML_Node& phaseNode) { // get the declared element names if (!phaseNode.hasChild("elementArray")) { throw CanteraError("installElements", "phase XML node doesn't have \"elementArray\" XML Node"); } XML_Node& elements = phaseNode.child("elementArray"); vector<string> enames; getStringArray(elements, enames); // // element database defaults to elements.xml string element_database = "elements.xml"; if (elements.hasAttrib("datasrc")) { element_database = elements["datasrc"]; } XML_Node* doc = get_XML_File(element_database); XML_Node* dbe = &doc->child("elementData"); XML_Node& root = phaseNode.root(); XML_Node* local_db = 0; if (root.hasChild("elementData")) { local_db = &root.child("elementData"); } for (size_t i = 0; i < enames.size(); i++) { // Find the element data XML_Node* e = 0; if (local_db) { e = local_db->findByAttr("name",enames[i]); } if (!e) { e = dbe->findByAttr("name",enames[i]); } if (!e) { throw CanteraError("addElementsFromXML","no data for element " +enames[i]); } // Add the element doublereal weight = 0.0; if (e->hasAttrib("atomicWt")) { weight = fpValue(e->attrib("atomicWt")); } int anum = 0; if (e->hasAttrib("atomicNumber")) { anum = intValue(e->attrib("atomicNumber")); } string symbol = e->attrib("name"); doublereal entropy298 = ENTROPY298_UNKNOWN; if (e->hasChild("entropy298")) { XML_Node& e298Node = e->child("entropy298"); if (e298Node.hasAttrib("value")) { entropy298 = fpValueCheck(e298Node["value"]); } } th.addElement(symbol, weight, anum, entropy298); } }
static void installAdsorbateThermoFromXML(std::string speciesName, SpeciesThermo& sp, int k, const XML_Node& f) { vector_fp freqs; doublereal tmin, tmax, pref = OneAtm; int nfreq = 0; tmin = fpValue(f["Tmin"]); tmax = fpValue(f["Tmax"]); if (f.hasAttrib("P0")) { pref = fpValue(f["P0"]); } if (f.hasAttrib("Pref")) { pref = fpValue(f["Pref"]); } if (tmax == 0.0) tmax = 1.0e30; if (f.hasChild("floatArray")) { getFloatArray(f.child("floatArray"), freqs, false); nfreq = freqs.size(); } for (int n = 0; n < nfreq; n++) { freqs[n] *= 3.0e10; } vector_fp coeffs(nfreq + 2); coeffs[0] = nfreq; coeffs[1] = getFloat(f, "binding_energy", "toSI"); copy(freqs.begin(), freqs.end(), coeffs.begin() + 2); //posc = new Adsorbate(k, tmin, tmax, pref, // DATA_PTR(coeffs)); (&sp)->install(speciesName, k, ADSORBATE, &coeffs[0], tmin, tmax, pref); }
/* * @todo call addUniqueElement(symbol, weight) instead of * addElement. */ void Elements:: addUniqueElement(const XML_Node& e) { doublereal weight = 0.0; if (e.hasAttrib("atomicWt")) weight = atof(stripws(e["atomicWt"]).c_str()); int anum = 0; if (e.hasAttrib("atomicNumber")) anum = atoi(stripws(e["atomicNumber"]).c_str()); string symbol = e["name"]; doublereal entropy298 = ENTROPY298_UNKNOWN; if (e.hasChild("entropy298")) { XML_Node& e298Node = e.child("entropy298"); if (e298Node.hasAttrib("value")) { entropy298 = atofCheck(stripws(e298Node["value"]).c_str()); } } if (weight != 0.0) { addUniqueElement(symbol, weight, anum, entropy298); } else { addUniqueElement(symbol); } }
void importPhase(XML_Node& phase, ThermoPhase* th) { // Check the the supplied XML node in fact represents a phase. if (phase.name() != "phase") { throw CanteraError("importPhase", "Current const XML_Node named, " + phase.name() + ", is not a phase element."); } // In this section of code, we get the reference to the phase XML tree // within the ThermoPhase object. Then, we clear it and fill it with the // current information that we are about to use to construct the object. We // will then be able to resurrect the information later by calling xml(). th->setXMLdata(phase); // set the id attribute of the phase to the 'id' attribute in the XML tree. th->setID(phase.id()); th->setName(phase.id()); // Number of spatial dimensions. Defaults to 3 (bulk phase) if (phase.hasAttrib("dim")) { int idim = intValue(phase["dim"]); if (idim < 1 || idim > 3) { throw CanteraError("importPhase", "phase, " + th->id() + ", has unphysical number of dimensions: " + phase["dim"]); } th->setNDim(idim); } else { th->setNDim(3); // default } // Set equation of state parameters. The parameters are specific to each // subclass of ThermoPhase, so this is done by method setParametersFromXML // in each subclass. const XML_Node& eos = phase.child("thermo"); if (phase.hasChild("thermo")) { th->setParametersFromXML(eos); } else { throw CanteraError("importPhase", " phase, " + th->id() + ", XML_Node does not have a \"thermo\" XML_Node"); } VPStandardStateTP* vpss_ptr = 0; int ssConvention = th->standardStateConvention(); if (ssConvention == cSS_CONVENTION_VPSS) { vpss_ptr = dynamic_cast <VPStandardStateTP*>(th); if (vpss_ptr == 0) { throw CanteraError("importPhase", "phase, " + th->id() + ", was VPSS, but dynamic cast failed"); } } // Add the elements. if (ssConvention != cSS_CONVENTION_SLAVE) { installElements(*th, phase); } // Add the species. // // Species definitions may be imported from multiple sources. For each one, // a speciesArray element must be present. vector<XML_Node*> sparrays = phase.getChildren("speciesArray"); if (ssConvention != cSS_CONVENTION_SLAVE && sparrays.empty()) { 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"); } vector<XML_Node*> dbases; vector_int sprule(sparrays.size(),0); // Default behavior when importing from CTI/XML is for undefined elements to // be treated as an error th->throwUndefinedElements(); // loop over the speciesArray elements for (size_t jsp = 0; jsp < sparrays.size(); jsp++) { const XML_Node& speciesArray = *sparrays[jsp]; // If the speciesArray element has a child element // // <skip element="undeclared"> // // then set sprule[jsp] to 1, so that any species with an undeclared // element will be quietly skipped when importing species. Additionally, // if the skip node has the following attribute: // // <skip species="duplicate"> // // 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; } string dskip = sk["species"]; if (dskip == "duplicate") { sprule[jsp] += 10; } } // 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. XML_Node* 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<XML_Node*> spDataNodeList; std::vector<std::string> spNamesList; vector_int spRuleList; formSpeciesXMLNodeList(spDataNodeList, spNamesList, spRuleList, sparrays, dbases, sprule); size_t nsp = spDataNodeList.size(); if (ssConvention == cSS_CONVENTION_SLAVE && nsp > 0) { throw CanteraError("importPhase()", "For Slave standard states, " "number of species must be zero: {}", nsp); } for (size_t k = 0; k < nsp; k++) { XML_Node* s = spDataNodeList[k]; AssertTrace(s != 0); if (spRuleList[k]) { th->ignoreUndefinedElements(); } th->addSpecies(newSpecies(*s)); if (vpss_ptr) { const XML_Node* const ss = s->findByName("standardState"); std::string ss_model = (ss) ? ss->attrib("model") : "ideal-gas"; unique_ptr<PDSS> kPDSS(newPDSS(ss_model)); kPDSS->setParametersFromXML(*s); vpss_ptr->installPDSS(k, std::move(kPDSS)); } th->saveSpeciesData(k, s); } // Done adding species. Perform any required subclass-specific // initialization. th->initThermo(); // Perform any required subclass-specific initialization that requires the // XML phase object std::string id = ""; th->initThermoXML(phase, id); }
bool importPhase(XML_Node& phase, ThermoPhase* th, SpeciesThermoFactory* spfactory) { // Check the the supplied XML node in fact represents a phase. if (phase.name() != "phase") { throw CanteraError("importPhase", "Current const XML_Node named, " + phase.name() + ", is not a phase element."); } /* * In this section of code, we get the reference to the * phase xml tree within the ThermoPhase object. Then, * we clear it and fill it with the current information that * we are about to use to construct the object. We will then * be able to resurrect the information later by calling xml(). */ th->setXMLdata(phase); // set the id attribute of the phase to the 'id' attribute in the XML tree. th->setID(phase.id()); th->setName(phase.id()); // Number of spatial dimensions. Defaults to 3 (bulk phase) if (phase.hasAttrib("dim")) { int idim = intValue(phase["dim"]); if (idim < 1 || idim > 3) throw CanteraError("importPhase", "phase, " + th->id() + ", has unphysical number of dimensions: " + phase["dim"]); th->setNDim(idim); } else { th->setNDim(3); // default } // Set equation of state parameters. The parameters are // specific to each subclass of ThermoPhase, so this is done // by method setParametersFromXML in each subclass. const XML_Node& eos = phase.child("thermo"); if (phase.hasChild("thermo")) { th->setParametersFromXML(eos); } else { throw CanteraError("importPhase", " phase, " + th->id() + ", XML_Node does not have a \"thermo\" XML_Node"); } VPStandardStateTP* vpss_ptr = 0; int ssConvention = th->standardStateConvention(); if (ssConvention == cSS_CONVENTION_VPSS) { vpss_ptr = dynamic_cast <VPStandardStateTP*>(th); if (vpss_ptr == 0) { throw CanteraError("importPhase", "phase, " + th->id() + ", was VPSS, but dynamic cast failed"); } } // if no species thermo factory was supplied, use the default one. if (!spfactory) { spfactory = SpeciesThermoFactory::factory(); } /*************************************************************** * Add the elements. ***************************************************************/ if (ssConvention != cSS_CONVENTION_SLAVE) { installElements(*th, phase); } /*************************************************************** * Add the species. * * Species definitions may be imported from multiple * sources. For each one, a speciesArray element must be * present. ***************************************************************/ vector<XML_Node*> sparrays; phase.getChildren("speciesArray", sparrays); if (ssConvention != cSS_CONVENTION_SLAVE) { if (sparrays.empty()) { 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"); } } vector<XML_Node*> dbases; vector_int sprule(sparrays.size(),0); // loop over the speciesArray elements for (size_t jsp = 0; jsp < sparrays.size(); jsp++) { const XML_Node& speciesArray = *sparrays[jsp]; // If the speciesArray element has a child element // // <skip element="undeclared"> // // then set sprule[jsp] to 1, so that any species with an undeclared // element will be quietly skipped when importing species. Additionally, // if the skip node has the following attribute: // // <skip species="duplicate"> // // 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; } string dskip = sk["species"]; if (dskip == "duplicate") { sprule[jsp] += 10; } } // 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. XML_Node* 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<XML_Node*> spDataNodeList; std::vector<std::string> spNamesList; std::vector<int> spRuleList; formSpeciesXMLNodeList(spDataNodeList, spNamesList, spRuleList, sparrays, dbases, sprule); // Decide whether the the phase has a variable pressure ss or not SpeciesThermo* spth = 0; VPSSMgr* vp_spth = 0; if (ssConvention == cSS_CONVENTION_TEMPERATURE) { // Create a new species thermo manager. Function // 'newSpeciesThermoMgr' looks at the species in the database // to see what thermodynamic property parameterizations are // used, and selects a class that can handle the // parameterizations found. spth = newSpeciesThermoMgr(spDataNodeList); // install it in the phase object th->setSpeciesThermo(spth); } else if (ssConvention == cSS_CONVENTION_SLAVE) { /* * No species thermo manager for this type */ } else if (ssConvention == cSS_CONVENTION_VPSS) { vp_spth = newVPSSMgr(vpss_ptr, &phase, spDataNodeList); vpss_ptr->setVPSSMgr(vp_spth); spth = vp_spth->SpeciesThermoMgr(); th->setSpeciesThermo(spth); } else { throw CanteraError("importPhase()", "unknown convention"); } size_t k = 0; size_t nsp = spDataNodeList.size(); if (ssConvention == cSS_CONVENTION_SLAVE) { if (nsp > 0) { throw CanteraError("importPhase()", "For Slave standard states, number of species must be zero: " + int2str(nsp)); } } for (size_t 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) { th->saveSpeciesData(k, s); ++k; } } if (ssConvention == cSS_CONVENTION_SLAVE) { th->installSlavePhases(&phase); } // Done adding species. Perform any required subclass-specific // initialization. th->initThermo(); // Perform any required subclass-specific initialization // that requires the XML phase object std::string id = ""; th->initThermoXML(phase, id); return true; }