From 1f97037f693b410caa4962d2168047839b76fefc Mon Sep 17 00:00:00 2001 From: Harry Moffat Date: Wed, 19 Dec 2007 17:03:17 +0000 Subject: [PATCH] Bug fix for instantiation of these thermo models via the ThermoFactory approach. --- Cantera/src/thermo/DebyeHuckel.cpp | 66 ++++++++++++++++++++-- Cantera/src/thermo/IdealSolidSolnPhase.cpp | 44 +++++++++++++++ Cantera/src/thermo/IdealSolidSolnPhase.h | 2 +- Cantera/src/thermo/ThermoFactory.cpp | 20 ++++--- Cantera/src/thermo/mix_defs.h | 3 + 5 files changed, 123 insertions(+), 12 deletions(-) diff --git a/Cantera/src/thermo/DebyeHuckel.cpp b/Cantera/src/thermo/DebyeHuckel.cpp index 6a0002b69..58e8cbd8e 100644 --- a/Cantera/src/thermo/DebyeHuckel.cpp +++ b/Cantera/src/thermo/DebyeHuckel.cpp @@ -1360,7 +1360,6 @@ namespace Cantera { throw CanteraError("DebyeHuckel::constructPhaseXML", "importPhase failed "); } - } /* @@ -1395,10 +1394,31 @@ namespace Cantera { XML_Node& thermoNode = phaseNode.child("thermo"); /* - * Initialize all of the lengths of arrays in the object - * now that we know what species are in the phase. + * Possibly change the form of the standard concentrations */ - initThermo(); + if (thermoNode.hasChild("standardConc")) { + XML_Node& scNode = thermoNode.child("standardConc"); + m_formGC = 2; + std::string formString = scNode.attrib("model"); + if (formString != "") { + if (formString == "unity") { + m_formGC = 0; + printf("exit standardConc = unity not done\n"); + exit(-1); + } else if (formString == "molar_volume") { + m_formGC = 1; + printf("exit standardConc = molar_volume not done\n"); + exit(-1); + } else if (formString == "solvent_volume") { + m_formGC = 2; + } else { + throw CanteraError("DebyeHuckel::constructPhaseXML", + "Unknown standardConc model: " + formString); + } + } + } + + /* * Reconcile the solvent name and index. @@ -1438,6 +1458,44 @@ namespace Cantera { " should be first species"); } + /* + * Determine the form of the Debye-Huckel model, + * m_formDH. We will use this information to size arrays below. + */ + if (thermoNode.hasChild("activityCoefficients")) { + XML_Node& scNode = thermoNode.child("activityCoefficients"); + m_formDH = DHFORM_DILUTE_LIMIT; + std::string formString = scNode.attrib("model"); + if (formString != "") { + if (formString == "Dilute_limit") { + m_formDH = DHFORM_DILUTE_LIMIT; + } else if (formString == "Bdot_with_variable_a") { + m_formDH = DHFORM_BDOT_AK ; + } else if (formString == "Bdot_with_common_a") { + m_formDH = DHFORM_BDOT_ACOMMON; + } else if (formString == "Beta_ij") { + m_formDH = DHFORM_BETAIJ; + } else if (formString == "Pitzer_with_Beta_ij") { + m_formDH = DHFORM_PITZER_BETAIJ; + } else { + throw CanteraError("DebyeHuckel::constructPhaseXML", + "Unknown standardConc model: " + formString); + } + } + } else { + /* + * If there is no XML node named "activityCoefficients", assume + * that we are doing the extreme dilute limit assumption + */ + m_formDH = DHFORM_DILUTE_LIMIT; + } + + /* + * Initialize all of the lengths of arrays in the object + * now that we know what species are in the phase. + */ + initThermo(); + /* * Now go get the specification of the standard states for * species in the solution. This includes the molar volumes diff --git a/Cantera/src/thermo/IdealSolidSolnPhase.cpp b/Cantera/src/thermo/IdealSolidSolnPhase.cpp index be9f46dbd..70d0e25a5 100644 --- a/Cantera/src/thermo/IdealSolidSolnPhase.cpp +++ b/Cantera/src/thermo/IdealSolidSolnPhase.cpp @@ -1193,6 +1193,50 @@ namespace Cantera { * with the correct id. */ void IdealSolidSolnPhase::initThermoXML(XML_Node& phaseNode, std::string id) { + string subname = "IdealSolidSolnPhase::initThermoXML"; + /* + * Check on the thermo field. Must have: + * + */ + if (phaseNode.hasChild("thermo")) { + XML_Node& thNode = phaseNode.child("thermo"); + string mStringa = thNode.attrib("model"); + string mString = lowercase(mStringa); + if (mString != "idealsolidsolution") { + throw CanteraError(subname.c_str(), + "Unknown thermo model: " + mStringa); + } + } else { + throw CanteraError(subname.c_str(), + "Unspecified thermo model"); + } + + /* + * Form of the standard concentrations. Must have one of: + * + * + * + * + */ + if (phaseNode.hasChild("standardConc")) { + 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(subname.c_str(), + "Unknown standardConc model: " + formStringa); + } + } else { + throw CanteraError(subname.c_str(), + "Unspecified standardConc model"); + } + /* * Initialize all of the lengths now that we know how many species * there are in the phase. diff --git a/Cantera/src/thermo/IdealSolidSolnPhase.h b/Cantera/src/thermo/IdealSolidSolnPhase.h index 14b976c66..cb00b0737 100644 --- a/Cantera/src/thermo/IdealSolidSolnPhase.h +++ b/Cantera/src/thermo/IdealSolidSolnPhase.h @@ -806,7 +806,7 @@ namespace Cantera { * @param g Output vector containing reference Gibbs free energies. * Length: m_kk. */ - virtual void getGibbs_ref(doublereal *g) const; + virtual void getGibbs_ref(doublereal *g) const; /** * Returns the vector of nondimensional diff --git a/Cantera/src/thermo/ThermoFactory.cpp b/Cantera/src/thermo/ThermoFactory.cpp index b0c6a1a8b..c125936ef 100644 --- a/Cantera/src/thermo/ThermoFactory.cpp +++ b/Cantera/src/thermo/ThermoFactory.cpp @@ -24,6 +24,7 @@ #include "speciesThermoTypes.h" #include "SpeciesThermoFactory.h" #include "IdealGasPhase.h" +#include "IdealSolidSolnPhase.h" #ifdef WITH_PURE_FLUIDS #include "PureFluidPhase.h" @@ -72,17 +73,19 @@ namespace Cantera { boost::mutex ThermoFactory::thermo_mutex; #endif - static int ntypes = 10; + static int ntypes = 13; static string _types[] = {"IdealGas", "Incompressible", "Surface", "Edge", "Metal", "StoichSubstance", "PureFluid", "LatticeSolid", "Lattice", - "HMW" + "HMW", "IdealSolidSolution", "DebyeHuckel", + "IdealMolalSolution" }; static int _itypes[] = {cIdealGas, cIncompressible, cSurf, cEdge, cMetal, cStoichSubstance, cPureFluid, cLatticeSolid, cLattice, - cHMW + cHMW, cIdealSolidSolnPhase, cDebyeHuckel, + cIdealMolalSoln }; /* @@ -97,7 +100,6 @@ namespace Cantera { } ThermoPhase* th=0; - // map d; switch (ieos) { case cIdealGas: @@ -116,6 +118,10 @@ namespace Cantera { th = new EdgePhase; break; + case cIdealSolidSolnPhase: + th = new IdealSolidSolnPhase(); + break; + #ifdef WITH_METAL case cMetal: th = new MetalPhase; @@ -187,12 +193,12 @@ namespace Cantera { ThermoPhase* t = newThermoPhase(model); #ifdef WITH_ELECTROLYTES if (model == "HMW") { - HMWSoln* p = (HMWSoln*)t; - p->constructPhaseXML(xmlphase,""); + HMWSoln* p = (HMWSoln*)t; + p->constructPhaseXML(xmlphase,""); } else #endif - importPhase(xmlphase, t); + importPhase(xmlphase, t); return t; } diff --git a/Cantera/src/thermo/mix_defs.h b/Cantera/src/thermo/mix_defs.h index 4c9d020ea..d22596f2a 100755 --- a/Cantera/src/thermo/mix_defs.h +++ b/Cantera/src/thermo/mix_defs.h @@ -52,6 +52,9 @@ namespace Cantera { /// An edge between two 2D surfaces const int cEdge = 6; + /// Constant partial molar volume solution IdealSolidSolnPhase.h + const int cIdealSolidSolnPhase = 5009; + //! HMW - Strong electrolyte using the Pitzer formulation const int cHMW = 40;