diff --git a/ext/SConscript b/ext/SConscript
index f5bd4f088..2a4832c91 100644
--- a/ext/SConscript
+++ b/ext/SConscript
@@ -3,6 +3,10 @@ from buildutils import *
Import('env', 'build', 'install', 'libraryTargets')
localenv = env.Clone()
+#
+# prep function seem to return the environment
+#
+
def prep_default(env):
return env.Clone()
@@ -19,7 +23,16 @@ def prep_f2c(env):
localenv.Append(CPPDEFINES=['USE_CLOCK'])
if not localenv['HAS_UNISTD_H']:
localenv.Append(CPPDEFINES=['MSDOS'])
+ if env['VERBOSE'] :
+ print "INFO 2: prep_f2c: adding MSDOS to CPPDEFINES"
+ if env['VERBOSE'] :
+ localenv.Append(CPPDEFINES=['added'])
+ print "INFO 2: CPPDEFINES ", localenv['CPPDEFINES']
+ #print "localenv", localenv.Dump()
+ #exit(0)
+
+
# The F2C code generates a lot of warnings designed to catch
# programmer errors, but since this is autogenerated code, those
# warnings are irrelevant.
@@ -52,6 +65,10 @@ def prep_gtest(env):
CPPDEFINES={'GTEST_HAS_PTHREAD': 0})
return localenv
+# libs is a list of length 3
+# 0 subdir for execution
+# 1 file extension
+# 2 function pointer
# (subdir, (file extensions), prepfunction)
libs = [('libexecstream', ['cpp'], prep_default)]
@@ -95,6 +112,10 @@ if env['use_sundials'] == 'n':
for subdir, extensions, prepFunction in libs:
+
+ if env['VERBOSE']:
+ print "INFO 2: Prep the environment for ", subdir, ' with extensions ', extensions, ' by calling func ', prepFunction.__name__
+
localenv = prepFunction(env)
if localenv['single_library']:
@@ -120,6 +141,10 @@ for subdir, extensions, prepFunction in libs:
else:
sharedLibName = libName
+ if env['VERBOSE'] :
+ print "INFO 2:" , subdir , ' with ', extensions
+ print " libName = ", libName, " sharedLibName = ", sharedLibName
+
objects = localenv.SharedObject(mglob(localenv, subdir, *extensions))
# Build the static library
diff --git a/include/cantera/thermo/HMWSoln.h b/include/cantera/thermo/HMWSoln.h
index d0783fe9d..fb9d453cc 100644
--- a/include/cantera/thermo/HMWSoln.h
+++ b/include/cantera/thermo/HMWSoln.h
@@ -1333,6 +1333,46 @@ public:
*/
ThermoPhase* duplMyselfAsThermoPhase() const;
+
+ //! Import, construct, and initialize a HMWSoln phase
+ /*! specification from an XML tree into the current object.
+ *
+ * This routine is a precursor to constructPhaseXML(XML_Node*)
+ * routine, which does most of the work.
+ *
+ * @param inputfile XML file containing the description of the phase
+ *
+ * @param id Optional parameter identifying the name of the
+ * phase. If none is given, the first XML
+ * phase element will be used.
+ */
+ void constructPhaseFile(std::string inputFile, std::string id);
+
+ //! Import and initialize a HMWSoln phase specification in an XML tree into the current object.
+ /*!
+ * Here we read an XML description of the phase.
+ * We import descriptions of the elements that make up the
+ * species in a phase.
+ * We import information about the species, including their
+ * reference state thermodynamic polynomials. We then freeze
+ * the state of the species.
+ *
+ * Then, we read the species molar volumes from the xml
+ * tree to finish the initialization.
+ *
+ * @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.
+ */
+ void constructPhaseXML(XML_Node& phaseNode, std::string id);
+
/**
* @name Utilities
* @{
diff --git a/include/cantera/thermo/IonsFromNeutralVPSSTP.h b/include/cantera/thermo/IonsFromNeutralVPSSTP.h
index 348652724..76e6bcaed 100644
--- a/include/cantera/thermo/IonsFromNeutralVPSSTP.h
+++ b/include/cantera/thermo/IonsFromNeutralVPSSTP.h
@@ -159,6 +159,50 @@ public:
*/
virtual ThermoPhase* duplMyselfAsThermoPhase() const;
+ /// The following methods are used in the process of constructing
+ /// the phase and setting its parameters from a specification in an
+ /// input file.
+
+ //! Initialization of an IonsFromNeutralVPSSTP phase using an xml file
+ /*!
+ * This routine is a precursor to initThermo(XML_Node*)
+ * routine, which does most of the work.
+ *
+ * @param inputFile XML file containing the description of the phase
+ *
+ * @param id Optional parameter identifying the name of the
+ * phase. If none is given, the first XML
+ * phase element will be used.
+ */
+ void constructPhaseFile(std::string inputFile, std::string id);
+
+ //! Import and initialize an IonsFromNeutralVPSSTP phase
+ //! specification in an XML tree into the current object.
+ /*!
+ * Here we read an XML description of the phase.
+ * We import descriptions of the elements that make up the
+ * species in a phase.
+ * We import information about the species, including their
+ * reference state thermodynamic polynomials. We then freeze
+ * the state of the species.
+ *
+ * Then, we read the species molar volumes from the xml
+ * tree to finish the initialization.
+ *
+ * @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.
+ */
+ void constructPhaseXML(XML_Node& phaseNode, std::string id);
+
+
/**
*
* @name Utilities
diff --git a/platform/posix/SConscript b/platform/posix/SConscript
index 66fdee31d..644aaa9d2 100644
--- a/platform/posix/SConscript
+++ b/platform/posix/SConscript
@@ -107,6 +107,9 @@ if not localenv['build_with_f2c']:
else:
localenv['mak_syslibs'] = ''
+# print localenv.Dump()
+# exit(0)
+
mak = build(localenv.SubstFile('Cantera.mak', 'Cantera.mak.in'))
install('$inst_incdir', mak)
diff --git a/src/thermo/HMWSoln_input.cpp b/src/thermo/HMWSoln_input.cpp
index 8c971690f..dd71b5440 100644
--- a/src/thermo/HMWSoln_input.cpp
+++ b/src/thermo/HMWSoln_input.cpp
@@ -1047,6 +1047,206 @@ void HMWSoln::initThermo()
initLengths();
}
+ /*
+ * Import, construct, and initialize a HMWSoln phase
+ * specification from an XML tree into the current object.
+ *
+ * This routine is a precursor to constructPhaseXML(XML_Node*)
+ * routine, which does most of the work.
+ *
+ * @param infile XML file containing the description of the
+ * phase
+ *
+ * @param id Optional parameter identifying the name of the
+ * phase. If none is given, the first XML
+ * phase element will be used.
+ */
+ void HMWSoln::constructPhaseFile(std::string inputFile, std::string id) {
+
+ if (inputFile.size() == 0) {
+ throw CanteraError("HMWSoln:constructPhaseFile",
+ "input file is null");
+ }
+ string path = findInputFile(inputFile);
+ std::ifstream fin(path.c_str());
+ if (!fin) {
+ throw CanteraError("HMWSoln:constructPhaseFile","could not open "
+ +path+" for reading.");
+ }
+ /*
+ * The phase object automatically constructs an XML object.
+ * Use this object to store information.
+ */
+ XML_Node &phaseNode_XML = xml();
+ XML_Node *fxml = new XML_Node();
+ fxml->build(fin);
+ XML_Node *fxml_phase = findXMLPhase(fxml, id);
+ if (!fxml_phase) {
+ throw CanteraError("HMWSoln:constructPhaseFile",
+ "ERROR: Can not find phase named " +
+ id + " in file named " + inputFile);
+ }
+ fxml_phase->copy(&phaseNode_XML);
+ constructPhaseXML(*fxml_phase, id);
+ delete fxml;
+ }
+
+ /*
+ * Import, construct, and initialize a HMWSoln phase
+ * specification from an XML tree into the current object.
+ *
+ * Most of the work is carried out by the cantera base
+ * routine, importPhase(). That routine imports all of the
+ * species and element data, including the standard states
+ * of the species.
+ *
+ * Then, In this routine, we read the information
+ * particular to the specification of the activity
+ * coefficient model for the Pitzer parameterization.
+ *
+ * We also read information about the molar volumes of the
+ * standard states if present in the XML file.
+ *
+ * @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.
+ */
+ void HMWSoln::constructPhaseXML(XML_Node& phaseNode, std::string id) {
+ string stemp;
+ if (id.size() > 0) {
+ string idp = phaseNode.id();
+ if (idp != id) {
+ throw CanteraError("HMWSoln::constructPhaseXML",
+ "phasenode and Id are incompatible");
+ }
+ }
+
+ /*
+ * Find the Thermo XML node
+ */
+ if (!phaseNode.hasChild("thermo")) {
+ throw CanteraError("HMWSoln::constructPhaseXML",
+ "no thermo XML node");
+ }
+ XML_Node& thermoNode = phaseNode.child("thermo");
+
+ /*
+ * Possibly change the form of the standard concentrations
+ */
+ if (thermoNode.hasChild("standardConc")) {
+ XML_Node& scNode = thermoNode.child("standardConc");
+ m_formGC = 2;
+ stemp = scNode.attrib("model");
+ string formString = lowercase(stemp);
+ if (formString != "") {
+ if (formString == "unity") {
+ m_formGC = 0;
+ printf("exit standardConc = unity not done\n");
+ exit(EXIT_FAILURE);
+ } else if (formString == "molar_volume") {
+ m_formGC = 1;
+ printf("exit standardConc = molar_volume not done\n");
+ exit(EXIT_FAILURE);
+ } else if (formString == "solvent_volume") {
+ m_formGC = 2;
+ } else {
+ throw CanteraError("HMWSoln::constructPhaseXML",
+ "Unknown standardConc model: " + formString);
+ }
+ }
+ }
+ /*
+ * Get the Name of the Solvent:
+ * solventName
+ */
+ string solventName = "";
+ if (thermoNode.hasChild("solvent")) {
+ XML_Node& scNode = thermoNode.child("solvent");
+ vector nameSolventa;
+ getStringArray(scNode, nameSolventa);
+ int nsp = static_cast(nameSolventa.size());
+ if (nsp != 1) {
+ throw CanteraError("HMWSoln::constructPhaseXML",
+ "badly formed solvent XML node");
+ }
+ solventName = nameSolventa[0];
+ }
+
+ /*
+ * Determine the form of the Pitzer model,
+ * We will use this information to size arrays below.
+ */
+ if (thermoNode.hasChild("activityCoefficients")) {
+ XML_Node& scNode = thermoNode.child("activityCoefficients");
+ stemp = scNode.attrib("model");
+ string formString = lowercase(stemp);
+ if (formString != "") {
+ if (formString == "pitzer" || formString == "default") {
+ m_formPitzer = PITZERFORM_BASE;
+ } else if (formString == "base") {
+ m_formPitzer = PITZERFORM_BASE;
+ } else {
+ throw CanteraError("HMWSoln::constructPhaseXML",
+ "Unknown Pitzer ActivityCoeff model: "
+ + formString);
+ }
+ }
+ /*
+ * Determine the form of the temperature dependence
+ * of the Pitzer activity coefficient model.
+ */
+ stemp = scNode.attrib("TempModel");
+ formString = lowercase(stemp);
+ if (formString != "") {
+ if (formString == "constant" || formString == "default") {
+ m_formPitzerTemp = PITZER_TEMP_CONSTANT;
+ } else if (formString == "linear") {
+ m_formPitzerTemp = PITZER_TEMP_LINEAR;
+ } else if (formString == "complex" || formString == "complex1") {
+ m_formPitzerTemp = PITZER_TEMP_COMPLEX1;
+ } else {
+ throw CanteraError("HMWSoln::constructPhaseXML",
+ "Unknown Pitzer ActivityCoeff Temp model: "
+ + formString);
+ }
+ }
+
+ /*
+ * Determine the reference temperature
+ * of the Pitzer activity coefficient model's temperature
+ * dependence formulation: defaults to 25C
+ */
+ stemp = scNode.attrib("TempReference");
+ formString = lowercase(stemp);
+ if (formString != "") {
+ m_TempPitzerRef = atofCheck(formString.c_str());
+ } else {
+ m_TempPitzerRef = 273.15 + 25;
+ }
+
+ }
+
+ /*
+ * Call the Cantera importPhase() function. This will import
+ * all of the species into the phase. This will also handle
+ * all of the solvent and solute standard states
+ */
+ bool m_ok = importPhase(phaseNode, this);
+ if (!m_ok) {
+ throw CanteraError("HMWSoln::constructPhaseXML","importPhase failed ");
+ }
+
+ }
+
+
+
/**
* Process the XML file after species are set up.
*
diff --git a/src/thermo/IonsFromNeutralVPSSTP.cpp b/src/thermo/IonsFromNeutralVPSSTP.cpp
index abbc33191..b9ac0c4e4 100644
--- a/src/thermo/IonsFromNeutralVPSSTP.cpp
+++ b/src/thermo/IonsFromNeutralVPSSTP.cpp
@@ -240,6 +240,146 @@ IonsFromNeutralVPSSTP::duplMyselfAsThermoPhase() const
return new IonsFromNeutralVPSSTP(*this);
}
+/*
+ * Import, construct, and initialize a phase
+ * specification from an XML tree into the current object.
+ *
+ * This routine is a precursor to constructPhaseXML(XML_Node*)
+ * routine, which does most of the work.
+ *
+ * @param infile XML file containing the description of the
+ * phase
+ *
+ * @param id Optional parameter identifying the name of the
+ * phase. If none is given, the first XML
+ * phase element will be used.
+ */
+void IonsFromNeutralVPSSTP::constructPhaseFile(std::string inputFile, std::string id) {
+
+ if (inputFile.size() == 0) {
+ throw CanteraError("MargulesVPSSTP:constructPhaseFile",
+ "input file is null");
+ }
+ string path = findInputFile(inputFile);
+ std::ifstream fin(path.c_str());
+ if (!fin) {
+ throw CanteraError("MargulesVPSSTP:constructPhaseFile","could not open "
+ +path+" for reading.");
+ }
+ /*
+ * The phase object automatically constructs an XML object.
+ * Use this object to store information.
+ */
+ XML_Node &phaseNode_XML = xml();
+ XML_Node *fxml = new XML_Node();
+ fxml->build(fin);
+ XML_Node *fxml_phase = findXMLPhase(fxml, id);
+ if (!fxml_phase) {
+ throw CanteraError("MargulesVPSSTP:constructPhaseFile",
+ "ERROR: Can not find phase named " +
+ id + " in file named " + inputFile);
+ }
+ fxml_phase->copy(&phaseNode_XML);
+ constructPhaseXML(*fxml_phase, id);
+ delete fxml;
+}
+
+/*
+ * Import, construct, and initialize a HMWSoln phase
+ * specification from an XML tree into the current object.
+ *
+ * Most of the work is carried out by the cantera base
+ * routine, importPhase(). That routine imports all of the
+ * species and element data, including the standard states
+ * of the species.
+ *
+ * Then, In this routine, we read the information
+ * particular to the specification of the activity
+ * coefficient model for the Pitzer parameterization.
+ *
+ * We also read information about the molar volumes of the
+ * standard states if present in the XML file.
+ *
+ * @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.
+ */
+
+void IonsFromNeutralVPSSTP::constructPhaseXML(XML_Node& phaseNode, std::string id) {
+ string stemp;
+ if (id.size() > 0) {
+ string idp = phaseNode.id();
+ if (idp != id) {
+ throw CanteraError("IonsFromNeutralVPSSTP::constructPhaseXML",
+ "phasenode and Id are incompatible");
+ }
+ }
+
+ /*
+ * Find the thermo XML node
+ */
+ if (!phaseNode.hasChild("thermo")) {
+ throw CanteraError("IonsFromNeutralVPSSTP::constructPhaseXML",
+ "no thermo XML node");
+ }
+ XML_Node& thermoNode = phaseNode.child("thermo");
+
+
+
+ /*
+ * Make sure that the thermo model is IonsFromNeutralMolecule
+ */
+ stemp = thermoNode.attrib("model");
+ string formString = lowercase(stemp);
+ if (formString != "ionsfromneutralmolecule") {
+ throw CanteraError("IonsFromNeutralVPSSTP::constructPhaseXML",
+ "model name isn't IonsFromNeutralMolecule: " + formString);
+ }
+
+ /*
+ * Find the Neutral Molecule Phase
+ */
+ if (!thermoNode.hasChild("neutralMoleculePhase")) {
+ throw CanteraError("IonsFromNeutralVPSSTP::constructPhaseXML",
+ "no neutralMoleculePhase XML node");
+ }
+ XML_Node& neutralMoleculeNode = thermoNode.child("neutralMoleculePhase");
+
+ string nsource = neutralMoleculeNode["datasrc"];
+ XML_Node *neut_ptr = get_XML_Node(nsource, 0);
+ if (!neut_ptr) {
+ throw CanteraError("IonsFromNeutralVPSSTP::constructPhaseXML",
+ "neut_ptr = 0");
+ }
+
+ /*
+ * Create the neutralMolecule ThermoPhase if we haven't already
+ */
+ if (!neutralMoleculePhase_) {
+ neutralMoleculePhase_ = newPhase(*neut_ptr);
+ }
+
+ /*
+ * Call the Cantera importPhase() function. This will import
+ * all of the species into the phase. This will also handle
+ * all of the solvent and solute standard states
+ */
+ bool m_ok = importPhase(phaseNode, this);
+ if (!m_ok) {
+ throw CanteraError("IonsFromNeutralVPSSTP::constructPhaseXML",
+ "importPhase failed ");
+ }
+
+ }
+
+
/*
* -------------- Utilities -------------------------------
*/
diff --git a/src/thermo/ThermoFactory.cpp b/src/thermo/ThermoFactory.cpp
index 2484d0a1a..700479b6a 100644
--- a/src/thermo/ThermoFactory.cpp
+++ b/src/thermo/ThermoFactory.cpp
@@ -247,7 +247,22 @@ ThermoPhase* newPhase(XML_Node& xmlphase)
const XML_Node& th = xmlphase.child("thermo");
string model = th["model"];
ThermoPhase* t = newThermoPhase(model);
- importPhase(xmlphase, t);
+ if (model == "singing cows") {
+ throw CanteraError("ThermoPhase::newPhase", "Cows don't sing");
+ }
+ else if (model == "HMW") {
+ HMWSoln* p = dynamic_cast(t);
+ p->constructPhaseXML(xmlphase,"");
+ }
+ else if (model == "IonsFromNeutralMolecule") {
+ IonsFromNeutralVPSSTP* p = dynamic_cast(t);
+ p->constructPhaseXML(xmlphase,"");
+ }
+ else {
+ importPhase(xmlphase, t);
+ }
+ //return t;
+ //importPhase(xmlphase, t);
return t;
}