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); } }
void MixtureFugacityTP::setStateFromXML(const XML_Node& state) { int doTP = 0; string comp = ctml::getChildValue(state,"moleFractions"); if (comp != "") { // not overloaded in current object -> phase state is not calculated. setMoleFractionsByName(comp); doTP = 1; } else { comp = ctml::getChildValue(state,"massFractions"); if (comp != "") { // not overloaded in current object -> phase state is not calculated. setMassFractionsByName(comp); doTP = 1; } } double t = temperature(); if (state.hasChild("temperature")) { t = ctml::getFloat(state, "temperature", "temperature"); doTP = 1; } if (state.hasChild("pressure")) { double p = ctml::getFloat(state, "pressure", "pressure"); setState_TP(t, p); } else if (state.hasChild("density")) { double rho = ctml::getFloat(state, "density", "density"); setState_TR(t, rho); } else if (doTP) { double rho = Phase::density(); setState_TR(t, rho); } }
void MineralEQ3::initThermoXML(XML_Node& phaseNode, const std::string& id_) { /* * Find the Thermo XML node */ if (!phaseNode.hasChild("thermo")) { throw CanteraError("HMWSoln::initThermoXML", "no thermo XML node"); } std::vector<const XML_Node*> xspecies = speciesData(); const XML_Node* xsp = xspecies[0]; XML_Node* aStandardState = 0; if (xsp->hasChild("standardState")) { aStandardState = &xsp->child("standardState"); } else { throw CanteraError("MineralEQ3::initThermoXML", "no standard state mode"); } doublereal volVal = 0.0; string smodel = (*aStandardState)["model"]; if (smodel != "constantVolume") { throw CanteraError("MineralEQ3::initThermoXML", "wrong standard state mode"); } if (aStandardState->hasChild("V0_Pr_Tr")) { XML_Node& aV = aStandardState->child("V0_Pr_Tr"); string Aunits = ""; double Afactor = toSI("cm3/gmol"); if (aV.hasAttrib("units")) { Aunits = aV.attrib("units"); Afactor = toSI(Aunits); } volVal = ctml::getFloat(*aStandardState, "V0_Pr_Tr"); m_V0_pr_tr= volVal; volVal *= Afactor; m_speciesSize[0] = volVal; } else { throw CanteraError("MineralEQ3::initThermoXML", "wrong standard state mode"); } doublereal rho = molecularWeight(0) / volVal; setDensity(rho); const XML_Node& sThermo = xsp->child("thermo"); const XML_Node& MinEQ3node = sThermo.child("MinEQ3"); m_deltaG_formation_pr_tr = ctml::getFloatDefaultUnits(MinEQ3node, "DG0_f_Pr_Tr", "cal/gmol", "actEnergy"); m_deltaH_formation_pr_tr = ctml::getFloatDefaultUnits(MinEQ3node, "DH0_f_Pr_Tr", "cal/gmol", "actEnergy"); m_Entrop_pr_tr = ctml::getFloatDefaultUnits(MinEQ3node, "S0_Pr_Tr", "cal/gmol/K"); m_a = ctml::getFloatDefaultUnits(MinEQ3node, "a", "cal/gmol/K"); m_b = ctml::getFloatDefaultUnits(MinEQ3node, "b", "cal/gmol/K2"); m_c = ctml::getFloatDefaultUnits(MinEQ3node, "c", "cal-K/gmol"); convertDGFormation(); }
void MineralEQ3::initThermoXML(XML_Node& phaseNode, const std::string& id_) { // Find the Thermo XML node if (!phaseNode.hasChild("thermo")) { throw CanteraError("HMWSoln::initThermoXML", "no thermo XML node"); } const XML_Node* xsp = speciesData()[0]; XML_Node* aStandardState = 0; if (xsp->hasChild("standardState")) { aStandardState = &xsp->child("standardState"); } else { throw CanteraError("MineralEQ3::initThermoXML", "no standard state mode"); } doublereal volVal = 0.0; if (aStandardState->attrib("model") != "constantVolume") { throw CanteraError("MineralEQ3::initThermoXML", "wrong standard state mode"); } if (aStandardState->hasChild("V0_Pr_Tr")) { XML_Node& aV = aStandardState->child("V0_Pr_Tr"); double Afactor = toSI("cm3/gmol"); if (aV.hasAttrib("units")) { Afactor = toSI(aV.attrib("units")); } volVal = getFloat(*aStandardState, "V0_Pr_Tr"); m_V0_pr_tr= volVal; volVal *= Afactor; } else { throw CanteraError("MineralEQ3::initThermoXML", "wrong standard state mode"); } setDensity(molecularWeight(0) / volVal); const XML_Node& MinEQ3node = xsp->child("thermo").child("MinEQ3"); m_deltaG_formation_pr_tr = getFloat(MinEQ3node, "DG0_f_Pr_Tr", "actEnergy") / actEnergyToSI("cal/gmol"); m_deltaH_formation_pr_tr = getFloat(MinEQ3node, "DH0_f_Pr_Tr", "actEnergy") / actEnergyToSI("cal/gmol"); m_Entrop_pr_tr = getFloat(MinEQ3node, "S0_Pr_Tr", "toSI") / toSI("cal/gmol/K"); m_a = getFloat(MinEQ3node, "a", "toSI") / toSI("cal/gmol/K"); m_b = getFloat(MinEQ3node, "b", "toSI") / toSI("cal/gmol/K2"); m_c = getFloat(MinEQ3node, "c", "toSI") / toSI("cal-K/gmol"); convertDGFormation(); }
/* * Import and initialize a ThermoPhase object * * param phaseNode This object must be the phase node of a * complete XML tree * description of the phase, including all of the * species data. In other words while "phase" must * point to an XML phase object, it must have * sibling nodes "speciesData" that describe * the species in the phase. * param id ID of the phase. If nonnull, a check is done * to see if phaseNode is pointing to the phase * with the correct id. * * This routine initializes the lengths in the current object and * then calls the parent routine. */ void IdealSolnGasVPSS::initThermoXML(XML_Node& phaseNode, std::string id) { IdealSolnGasVPSS::initLengths(); if (phaseNode.hasChild("thermo")) { XML_Node& thermoNode = phaseNode.child("thermo"); std::string model = thermoNode["model"]; if (model == "IdealGasVPSS") { m_idealGas = 1; } else if (model == "IdealSolnVPSS") { m_idealGas = 0; } else { throw CanteraError("IdealSolnGasVPSS::initThermoXML", "Unknown thermo model : " + model); } } /* * Form of the standard concentrations. Must have one of: * * <standardConc model="unity" /> * <standardConc model="molar_volume" /> * <standardConc model="solvent_volume" /> */ if (phaseNode.hasChild("standardConc")) { if (m_idealGas) { throw CanteraError("IdealSolnGasVPSS::initThermoXML", "standardConc node for ideal gas"); } XML_Node& scNode = phaseNode.child("standardConc"); string formStringa = scNode.attrib("model"); string formString = lowercase(formStringa); if (formString == "unity") { m_formGC = 0; } else if (formString == "molar_volume") { m_formGC = 1; } else if (formString == "solvent_volume") { m_formGC = 2; } else { throw CanteraError("initThermoXML", "Unknown standardConc model: " + formStringa); } } else { if (!m_idealGas) { throw CanteraError("initThermoXML", "Unspecified standardConc model"); } } VPStandardStateTP::initThermoXML(phaseNode, id); }
/*! * * @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(std::vector<XML_Node *> & spDataNodeList, int& has_nasa, int& has_shomate, int& has_simple, int &has_other) { size_t ns = spDataNodeList.size(); for (size_t n = 0; n < ns; n++) { XML_Node* spNode = spDataNodeList[n]; if (spNode->hasChild("standardState")) { const XML_Node& ss = spNode->child("standardState"); string mname = ss["model"]; if (mname == "water" || mname == "waterIAPWS") { has_other = 1; continue; } } if (spNode->hasChild("thermo")) { 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("MinEQ3")) { 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"); } 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 CanteraError("getSpeciesThermoTypes:", spNode->attrib("name") + " is missing the thermo XML node"); } } }
std::string getChildValue(const XML_Node& parent, const std::string& nameString) { if (!parent.hasChild(nameString)) { return ""; } return parent(nameString); }
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); }
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); } }
/********************************************************************* * Utility Functions *********************************************************************/ void MaskellSolidSolnPhase::initThermoXML(XML_Node& phaseNode, const std::string& id_) { if (id_.size() > 0 && phaseNode.id() != id_) { throw CanteraError("MaskellSolidSolnPhase::initThermoXML", "phasenode and Id are incompatible"); } /* * Check on the thermo field. Must have: * <thermo model="MaskellSolidSolution" /> */ if (phaseNode.hasChild("thermo")) { XML_Node& thNode = phaseNode.child("thermo"); std::string mString = thNode.attrib("model"); if (lowercase(mString) != "maskellsolidsolnphase") { throw CanteraError("MaskellSolidSolnPhase::initThermoXML", "Unknown thermo model: " + mString); } /* * Parse the enthalpy of mixing constant */ if (thNode.hasChild("h_mix")) { set_h_mix(fpValue(thNode.child("h_mix").value())); } else { throw CanteraError("MaskellSolidSolnPhase::initThermoXML", "Mixing enthalpy parameter not specified."); } if (thNode.hasChild("product_species")) { std::string product_species_name = thNode.child("product_species").value(); product_species_index = speciesIndex(product_species_name); if (product_species_index == static_cast<int>(npos)) { throw CanteraError("MaskellSolidSolnPhase::initThermoXML", "Species " + product_species_name + " not found."); } if (product_species_index == 0) { reactant_species_index = 1; } else { reactant_species_index = 0; } } } else { throw CanteraError("MaskellSolidSolnPhase::initThermoXML", "Unspecified thermo model"); } // Confirm that the phase only contains 2 species if (m_kk != 2) { throw CanteraError("MaskellSolidSolnPhase::initThermoXML", "MaskellSolidSolution model requires exactly 2 species."); } /* * Call the base initThermo, which handles setting the initial * state. */ VPStandardStateTP::initThermoXML(phaseNode, id_); }
void ThermoPhase::initThermoXML(XML_Node& phaseNode, const std::string& id) { if (phaseNode.hasChild("state")) { setStateFromXML(phaseNode.child("state")); } xMol_Ref.resize(m_kk); getMoleFractions(&xMol_Ref[0]); }
void IdealMolalSoln::initThermoXML(XML_Node& phaseNode, const std::string& id_) { MolalityVPSSTP::initThermoXML(phaseNode, id_); if (id_.size() > 0 && phaseNode.id() != id_) { throw CanteraError("IdealMolalSoln::initThermo", "phasenode and Id are incompatible"); } // Find the Thermo XML node if (!phaseNode.hasChild("thermo")) { throw CanteraError("IdealMolalSoln::initThermo", "no thermo XML node"); } XML_Node& thermoNode = phaseNode.child("thermo"); // Possible change the form of the standard concentrations if (thermoNode.hasChild("standardConc")) { XML_Node& scNode = thermoNode.child("standardConc"); setStandardConcentrationModel(scNode["model"]); } if (thermoNode.hasChild("activityCoefficients")) { XML_Node& acNode = thermoNode.child("activityCoefficients"); std::string modelString = acNode.attrib("model"); if (modelString != "IdealMolalSoln") { throw CanteraError("IdealMolalSoln::initThermoXML", "unknown ActivityCoefficient model: " + modelString); } if (acNode.hasChild("idealMolalSolnCutoff")) { XML_Node& ccNode = acNode.child("idealMolalSolnCutoff"); modelString = ccNode.attrib("model"); if (modelString != "") { setCutoffModel(modelString); if (ccNode.hasChild("gamma_o_limit")) { IMS_gamma_o_min_ = getFloat(ccNode, "gamma_o_limit"); } if (ccNode.hasChild("gamma_k_limit")) { IMS_gamma_k_min_ = getFloat(ccNode, "gamma_k_limit"); } if (ccNode.hasChild("X_o_cutoff")) { IMS_X_o_cutoff_ = getFloat(ccNode, "X_o_cutoff"); } if (ccNode.hasChild("c_0_param")) { IMS_cCut_ = getFloat(ccNode, "c_0_param"); } if (ccNode.hasChild("slope_f_limit")) { IMS_slopefCut_ = getFloat(ccNode, "slope_f_limit"); } if (ccNode.hasChild("slope_g_limit")) { IMS_slopegCut_ = getFloat(ccNode, "slope_g_limit"); } } } else { setCutoffModel("none"); } } }
bool getOptionalModel(const XML_Node& parent, const std::string& nodeName, std::string& modelName) { if (parent.hasChild(nodeName)) { modelName = parent.child(nodeName)["model"]; return true; } return false; }
bool getOptionalFloat(const XML_Node& parent, const std::string& name, doublereal& fltRtn, const std::string& type) { if (parent.hasChild(name)) { fltRtn = getFloat(parent, name, type); return true; } return false; }
doublereal getFloat(const XML_Node& parent, const std::string& name, const std::string& type) { if (!parent.hasChild(name)) throw CanteraError("getFloat (called from XML Node \"" + parent.name() + "\"): ", "no child XML element named \"" + name + "\" exists"); const XML_Node& node = parent.child(name); return getFloatCurrent(node, type); }
void MixedSolventElectrolyte::initThermoXML(XML_Node& phaseNode, const std::string& id_) { if ((int) id_.size() > 0 && phaseNode.id() != id_) { throw CanteraError("MixedSolventElectrolyte::initThermoXML", "phasenode and Id are incompatible"); } /* * Check on the thermo field. Must have: * <thermo model="MixedSolventElectrolyte" /> */ if (!phaseNode.hasChild("thermo")) { throw CanteraError("MixedSolventElectrolyte::initThermoXML", "no thermo XML node"); } XML_Node& thermoNode = phaseNode.child("thermo"); string mString = thermoNode.attrib("model"); if (lowercase(mString) != "mixedsolventelectrolyte") { throw CanteraError("MixedSolventElectrolyte::initThermoXML", "Unknown thermo model: " + mString); } /* * Go get all of the coefficients and factors in the * activityCoefficients XML block */ if (thermoNode.hasChild("activityCoefficients")) { XML_Node& acNode = thermoNode.child("activityCoefficients"); mString = acNode.attrib("model"); if (lowercase(mString) != "margules") { throw CanteraError("MixedSolventElectrolyte::initThermoXML", "Unknown activity coefficient model: " + mString); } for (size_t i = 0; i < acNode.nChildren(); i++) { XML_Node& xmlACChild = acNode.child(i); /* * Process a binary salt field, or any of the other XML fields * that make up the Pitzer Database. Entries will be ignored * if any of the species in the entry isn't in the solution. */ if (lowercase(xmlACChild.name()) == "binaryneutralspeciesparameters") { readXMLBinarySpecies(xmlACChild); } } } /* * Go down the chain */ MolarityIonicVPSSTP::initThermoXML(phaseNode, id_); }
void MetalSHEelectrons::setParametersFromXML(const XML_Node& eosdata) { if ( eosdata["model"] != "MetalSHEelectrons") { throw CanteraError("MetalSHEelectrons::setParametersFromXML", "thermo model attribute must be MetalSHEelectrons"); } doublereal rho = 2.65E3; if (eosdata.hasChild("density")) { rho = getFloat(eosdata, "density", "toSI"); } setDensity(rho); }
/* * Set the thermodynamic state. */ void MolalityVPSSTP::setStateFromXML(const XML_Node& state) { VPStandardStateTP::setStateFromXML(state); string comp = ctml::getChildValue(state,"soluteMolalities"); if (comp != "") { setMolalitiesByName(comp); } if (state.hasChild("pressure")) { double p = ctml::getFloat(state, "pressure", "pressure"); setPressure(p); } }
void SurfPhase::setStateFromXML(const XML_Node& state) { double t; if (getOptionalFloat(state, "temperature", t, "temperature")) { setTemperature(t); } if (state.hasChild("coverages")) { string comp = getChildValue(state,"coverages"); setCoveragesByName(comp); } }
void StoichSubstanceSSTP::initThermoXML(XML_Node& phaseNode, std::string id) { /* * Find the Thermo XML node */ if (!phaseNode.hasChild("thermo")) { throw CanteraError("StoichSubstanceSSTP::initThermoXML", "no thermo XML node"); } XML_Node &tnode = phaseNode.child("thermo"); double dens = getFloatDefaultUnits(tnode, "density", "kg/m3"); setDensity(dens); SingleSpeciesTP::initThermoXML(phaseNode, id); }
void Phase::addElementsFromXML(const XML_Node& phase) { // get the declared element names if (! phase.hasChild("elementArray")) { throw CanteraError("Elements::addElementsFromXML", "phase xml node doesn't have \"elementArray\" XML Node"); } XML_Node& elements = phase.child("elementArray"); vector<string> enames; ctml::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("ctml/elementData"); XML_Node& root = phase.root(); XML_Node* local_db = 0; if (root.hasChild("ctml")) { if (root.child("ctml").hasChild("elementData")) { local_db = &root.child("ctml/elementData"); } } int nel = static_cast<int>(enames.size()); int i; string enm; XML_Node* e = 0; for (i = 0; i < nel; i++) { e = 0; if (local_db) { //writelog("looking in local database."); e = local_db->findByAttr("name",enames[i]); //if (!e) writelog(enames[i]+" not found."); } if (!e) { e = dbe->findByAttr("name",enames[i]); } if (e) { addUniqueElement(*e); } else { throw CanteraError("addElementsFromXML","no data for element " +enames[i]); } } }
void MetalSHEelectrons::initThermoXML(XML_Node& phaseNode, const std::string& id_) { // Find the Thermo XML node if (!phaseNode.hasChild("thermo")) { throw CanteraError("MetalSHEelectrons::initThermoXML", "no thermo XML node"); } XML_Node& tnode = phaseNode.child("thermo"); doublereal dens = 2.65E3; if (tnode.hasChild("density")) { dens = getFloat(tnode, "density", "toSI"); } setDensity(dens); SingleSpeciesTP::initThermoXML(phaseNode, id_); }
void ThermoPhase::setStateFromXML(const XML_Node& state) { string comp = getChildValue(state,"moleFractions"); if (comp != "") { setMoleFractionsByName(comp); } else { comp = getChildValue(state,"massFractions"); if (comp != "") { setMassFractionsByName(comp); } } if (state.hasChild("temperature")) { double t = getFloat(state, "temperature", "temperature"); setTemperature(t); } if (state.hasChild("pressure")) { double p = getFloat(state, "pressure", "pressure"); setPressure(p); } if (state.hasChild("density")) { double rho = getFloat(state, "density", "density"); setDensity(rho); } }
void StoichSubstance::initThermoXML(XML_Node& phaseNode, const std::string& id_) { // Find the Thermo XML node if (!phaseNode.hasChild("thermo")) { throw CanteraError("StoichSubstance::initThermoXML", "no thermo XML node"); } XML_Node& tnode = phaseNode.child("thermo"); std::string model = tnode["model"]; if (model != "StoichSubstance" && model != "StoichSubstanceSSTP") { throw CanteraError("StoichSubstance::initThermoXML", "thermo model attribute must be StoichSubstance"); } double dens = getFloat(tnode, "density", "toSI"); setDensity(dens); SingleSpeciesTP::initThermoXML(phaseNode, id_); }
void MargulesVPSSTP::initThermoXML(XML_Node& phaseNode, const std::string& id_) { if ((int) id_.size() > 0) { string idp = phaseNode.id(); if (idp != id_) { throw CanteraError("MargulesVPSSTP::initThermoXML", "phasenode and Id are incompatible"); } } // Find the Thermo XML node if (!phaseNode.hasChild("thermo")) { throw CanteraError("MargulesVPSSTP::initThermoXML", "no thermo XML node"); } XML_Node& thermoNode = phaseNode.child("thermo"); // Make sure that the thermo model is Margules if (!caseInsensitiveEquals(thermoNode["model"], "margules")) { throw CanteraError("MargulesVPSSTP::initThermoXML", "model name isn't Margules: " + thermoNode["model"]); } // Go get all of the coefficients and factors in the activityCoefficients // XML block if (thermoNode.hasChild("activityCoefficients")) { XML_Node& acNode = thermoNode.child("activityCoefficients"); if (!caseInsensitiveEquals(acNode["model"], "margules")) { throw CanteraError("MargulesVPSSTP::initThermoXML", "Unknown activity coefficient model: " + acNode["model"]); } for (size_t i = 0; i < acNode.nChildren(); i++) { XML_Node& xmlACChild = acNode.child(i); // Process a binary salt field, or any of the other XML fields that // make up the Pitzer Database. Entries will be ignored if any of // the species in the entry isn't in the solution. if (caseInsensitiveEquals(xmlACChild.name(), "binaryneutralspeciesparameters")) { readXMLBinarySpecies(xmlACChild); } } } // Go down the chain GibbsExcessVPSSTP::initThermoXML(phaseNode, id_); }
void RedlichKisterVPSSTP::initThermoXML(XML_Node& phaseNode, const std::string& id_) { if ((int) id_.size() > 0 && phaseNode.id() != id_) { throw CanteraError("RedlichKisterVPSSTP::initThermoXML", "phasenode and Id are incompatible"); } // Check on the thermo field. Must have: // <thermo model="Redlich-Kister" /> if (!phaseNode.hasChild("thermo")) { throw CanteraError("RedlichKisterVPSSTP::initThermoXML", "no thermo XML node"); } XML_Node& thermoNode = phaseNode.child("thermo"); std::string mString = thermoNode.attrib("model"); if (lowercase(mString) != "redlich-kister") { throw CanteraError("RedlichKisterVPSSTP::initThermoXML", "Unknown thermo model: " + mString + " - This object only knows \"Redlich-Kister\" "); } // Go get all of the coefficients and factors in the activityCoefficients // XML block if (thermoNode.hasChild("activityCoefficients")) { XML_Node& acNode = thermoNode.child("activityCoefficients"); mString = acNode.attrib("model"); if (lowercase(mString) != "redlich-kister") { throw CanteraError("RedlichKisterVPSSTP::initThermoXML", "Unknown activity coefficient model: " + mString); } for (size_t i = 0; i < acNode.nChildren(); i++) { XML_Node& xmlACChild = acNode.child(i); // Process a binary salt field, or any of the other XML fields that // make up the Pitzer Database. Entries will be ignored if any of // the species in the entry isn't in the solution. if (lowercase(xmlACChild.name()) == "binaryneutralspeciesparameters") { readXMLBinarySpecies(xmlACChild); } } } // Go down the chain GibbsExcessVPSSTP::initThermoXML(phaseNode, id_); }
void MaskellSolidSolnPhase::initThermoXML(XML_Node& phaseNode, const std::string& id_) { if (id_.size() > 0 && phaseNode.id() != id_) { throw CanteraError("MaskellSolidSolnPhase::initThermoXML", "phasenode and Id are incompatible"); } // Check on the thermo field. Must have: // <thermo model="MaskellSolidSolution" /> if (phaseNode.hasChild("thermo")) { XML_Node& thNode = phaseNode.child("thermo"); if (!ba::iequals(thNode["model"], "maskellsolidsolnphase")) { throw CanteraError("MaskellSolidSolnPhase::initThermoXML", "Unknown thermo model: " + thNode["model"]); } // Parse the enthalpy of mixing constant if (thNode.hasChild("h_mix")) { set_h_mix(fpValue(thNode.child("h_mix").value())); } else { throw CanteraError("MaskellSolidSolnPhase::initThermoXML", "Mixing enthalpy parameter not specified."); } if (thNode.hasChild("product_species")) { setProductSpecies(thNode.child("product_species").value()); } else { setProductSpecies(speciesName(0)); // default } } else { throw CanteraError("MaskellSolidSolnPhase::initThermoXML", "Unspecified thermo model"); } // Confirm that the phase only contains 2 species if (m_kk != 2) { throw CanteraError("MaskellSolidSolnPhase::initThermoXML", "MaskellSolidSolution model requires exactly 2 species."); } // Call the base initThermo, which handles setting the initial state. VPStandardStateTP::initThermoXML(phaseNode, id_); }
void FixedChemPotSSTP::initThermoXML(XML_Node& phaseNode, const std::string& id_) { /* * Find the Thermo XML node */ if (!phaseNode.hasChild("thermo")) { throw CanteraError("FixedChemPotSSTP::initThermoXML", "no thermo XML node"); } XML_Node& tnode = phaseNode.child("thermo"); std::string model = tnode["model"]; if (model != "StoichSubstance" && model != "FixedChemPot" && model != "StoichSubstanceSSTP") { throw CanteraError("FixedChemPotSSTP::initThermoXML()", "thermo model attribute must be FixedChemPot or StoichSubstance or StoichSubstanceSSTP"); } if (model == "FixedChemPot") { double val = ctml::getFloatDefaultUnits(tnode, "chemicalPotential", "J/kmol"); chemPot_ = val; } SingleSpeciesTP::initThermoXML(phaseNode, id_); }
int getInteger(const XML_Node& parent, const std::string& name) { if (!parent.hasChild(name)) { throw CanteraError("getInteger (called from XML Node \"" + parent.name() + "\"): ", "no child XML element named " + name); } const XML_Node& node = parent.child(name); int x = node.int_value(); const string& vmin = node["min"]; const string& vmax = node["max"]; if (vmin != "" && x < intValue(vmin)) { writelog("\nWarning: value "+node.value()+" is below lower limit of " +vmin+".\n"); } if (node["max"] != "" && x > intValue(vmax)) { writelog("\nWarning: value "+node.value()+" is above upper limit of " +vmax+".\n"); } return x; }
void LatticePhase::initThermoXML(XML_Node& phaseNode, const std::string& id_) { if (!id_.empty() && id_ != phaseNode.id()) { throw CanteraError("LatticePhase::initThermoXML", "ids don't match"); } // Check on the thermo field. Must have: // <thermo model="Lattice" /> if (phaseNode.hasChild("thermo")) { XML_Node& thNode = phaseNode.child("thermo"); std::string mString = thNode.attrib("model"); if (lowercase(mString) != "lattice") { throw CanteraError("LatticePhase::initThermoXML", "Unknown thermo model: " + mString); } } else { throw CanteraError("LatticePhase::initThermoXML", "Unspecified thermo model"); } // Now go get the molar volumes. use the default if not found XML_Node& speciesList = phaseNode.child("speciesArray"); XML_Node* speciesDB = get_XML_NameID("speciesData", speciesList["datasrc"], &phaseNode.root()); for (size_t k = 0; k < m_kk; k++) { m_speciesMolarVolume[k] = m_site_density; XML_Node* s = speciesDB->findByAttr("name", speciesName(k)); if (!s) { throw CanteraError(" LatticePhase::initThermoXML", "database problems"); } XML_Node* ss = s->findByName("standardState"); if (ss && ss->findByName("molarVolume")) { m_speciesMolarVolume[k] = getFloat(*ss, "molarVolume", "toSI"); } } // Call the base initThermo, which handles setting the initial state. ThermoPhase::initThermoXML(phaseNode, id_); }