Added back constructPhaseFile() and constructPhaseXML().

All molten salt problems were broken and some brine problems were broken.
This commit is contained in:
Harry Moffat
2012-11-07 23:51:30 +00:00
parent 6e7b14c468
commit 08a41f191c
7 changed files with 468 additions and 1 deletions

View File

@@ -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

View File

@@ -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
* @{

View File

@@ -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

View File

@@ -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)

View File

@@ -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:
* <solvent> solventName </solvent>
*/
string solventName = "";
if (thermoNode.hasChild("solvent")) {
XML_Node& scNode = thermoNode.child("solvent");
vector<string> nameSolventa;
getStringArray(scNode, nameSolventa);
int nsp = static_cast<int>(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.
*

View File

@@ -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 -------------------------------
*/

View File

@@ -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<HMWSoln*>(t);
p->constructPhaseXML(xmlphase,"");
}
else if (model == "IonsFromNeutralMolecule") {
IonsFromNeutralVPSSTP* p = dynamic_cast<IonsFromNeutralVPSSTP*>(t);
p->constructPhaseXML(xmlphase,"");
}
else {
importPhase(xmlphase, t);
}
//return t;
//importPhase(xmlphase, t);
return t;
}