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(); }
static void installMinEQ3asShomateThermoFromXML(std::string speciesName, ThermoPhase *th_ptr, SpeciesThermo& sp, int k, const XML_Node* MinEQ3node) { array_fp coef(15), c0(7, 0.0); std::string astring = (*MinEQ3node)["Tmin"]; doublereal tmin0 = strSItoDbl(astring); astring = (*MinEQ3node)["Tmax"]; doublereal tmax0 = strSItoDbl(astring); astring = (*MinEQ3node)["Pref"]; doublereal p0 = strSItoDbl(astring); doublereal deltaG_formation_pr_tr = getFloatDefaultUnits(*MinEQ3node, "DG0_f_Pr_Tr", "cal/gmol", "actEnergy"); doublereal deltaH_formation_pr_tr = getFloatDefaultUnits(*MinEQ3node, "DH0_f_Pr_Tr", "cal/gmol", "actEnergy"); doublereal Entrop_pr_tr = getFloatDefaultUnits(*MinEQ3node, "S0_Pr_Tr", "cal/gmol/K"); doublereal a = getFloatDefaultUnits(*MinEQ3node, "a", "cal/gmol/K"); doublereal b = getFloatDefaultUnits(*MinEQ3node, "b", "cal/gmol/K2"); doublereal c = getFloatDefaultUnits(*MinEQ3node, "c", "cal-K/gmol"); doublereal dg = deltaG_formation_pr_tr * 4.184 * 1.0E3; doublereal fac = convertDGFormation(k, th_ptr); doublereal Mu0_tr_pr = fac + dg; doublereal e = Entrop_pr_tr * 1.0E3 * 4.184; doublereal Hcalc = Mu0_tr_pr + 298.15 * e; doublereal DHjmol = deltaH_formation_pr_tr * 1.0E3 * 4.184; // If the discrepency is greater than 100 cal gmol-1, print // an error and exit. if (fabs(Hcalc -DHjmol) > 10.* 1.0E6 * 4.184) { throw CanteraError("installMinEQ3asShomateThermoFromXML()", "DHjmol is not consistent with G and S" + fp2str(Hcalc) + " vs " + fp2str(DHjmol)); } /* * Now calculate the shomate polynomials * * Cp first * * Shomate: (Joules / gmol / K) * Cp = As + Bs * t + Cs * t*t + Ds * t*t*t + Es / (t*t) * where * t = temperature(Kelvin) / 1000 */ double As = a * 4.184; double Bs = b * 4.184 * 1000.; double Cs = 0.0; double Ds = 0.0; double Es = c * 4.184 / (1.0E6); double t = 298.15 / 1000.; double H298smFs = As * t + Bs * t * t / 2.0 - Es / t; double HcalcS = Hcalc / 1.0E6; double Fs = HcalcS - H298smFs; double S298smGs = As * log(t) + Bs * t - Es/(2.0*t*t); double ScalcS = e / 1.0E3; double Gs = ScalcS - S298smGs; c0[0] = As; c0[1] = Bs; c0[2] = Cs; c0[3] = Ds; c0[4] = Es; c0[5] = Fs; c0[6] = Gs; coef[0] = tmax0 - 0.001; copy(c0.begin(), c0.begin()+7, coef.begin() + 1); copy(c0.begin(), c0.begin()+7, coef.begin() + 8); sp.install(speciesName, k, SHOMATE, &coef[0], tmin0, tmax0, p0); }