Implementing the expanded species name idea, where we can guarantee

a unique name, when dealing with a bunch of phases.
Working on the LatticePhase
This commit is contained in:
Harry Moffat 2010-06-06 02:57:02 +00:00
parent 60f5f31c3b
commit e911aa1309
6 changed files with 253 additions and 11 deletions

View file

@ -280,12 +280,13 @@ namespace Cantera {
doublereal charge = 0.0,
doublereal size = 1.0);
//! Returns the index of a species named 'name' within the ThermoPhase
//! Returns the index of a species named 'name' within the Constituents object
/*!
* The first species added will have index 0, and the last one index nSpecies() - 1.
* The first species in the phase will have an index 0, and the last one in the
* phase will have an index of nSpecies() - 1.
*
* @param name String name of the species
* @return Returns the index of the species. If the name is not found
* @return Returns the index of the species. If the name is not found,
* the value of -1 is returned.
*/
int speciesIndex(std::string name) const;

View file

@ -23,8 +23,10 @@
#include "mix_defs.h"
#include "LatticePhase.h"
#include "SpeciesThermo.h"
#include "ThermoFactory.h"
#include <cmath>
#include <string>
namespace Cantera {
@ -70,7 +72,27 @@ namespace Cantera {
// Destructor
LatticePhase::~LatticePhase() {
}
// Full constructor for a lattice phase
/*
* @param inputFile String name of the input file
* @param id string id of the phase name
*/
LatticePhase::LatticePhase(std::string inputFile, std::string id) {
constructPhaseFile(inputFile, id);
}
// Full constructor for a water phase
/*
* @param phaseRef XML node referencing the lattice phase.
* @param id string id of the phase name
*/
LatticePhase::LatticePhase(XML_Node& phaseRef, std::string id) {
constructPhaseXML(phaseRef, id);
}
// Duplication function
/*
* This virtual function is used to create a duplicate of the
@ -84,6 +106,75 @@ namespace Cantera {
return (ThermoPhase *) igp;
}
/*
* @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 LatticePhase::constructPhaseXML(XML_Node& phaseNode, std::string idTarget) {
std::string idattrib = phaseNode.id();
if (idTarget != idattrib) {
throw CanteraError("LatticePhase::constructPhaseXML","ids don't match");
}
/*
* 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("LatticePhase::constructPhaseXML","importPhase failed ");
}
}
/*
* constructPhaseFile
*
*
* 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 LatticePhase::constructPhaseFile(std::string inputFile, std::string id) {
if (inputFile.size() == 0) {
throw CanteraError("LatticePhase::constructPhaseFile",
"input file is null");
}
std::string path = findInputFile(inputFile);
std::ifstream fin(path.c_str());
if (!fin) {
throw CanteraError("LatticePhase::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("LatticePhase::constructPhaseFile",
"ERROR: Can not find phase named " +
id + " in file named " + inputFile);
}
fxml_phase->copy(&phaseNode_XML);
constructPhaseXML(*fxml_phase, id);
delete fxml;
}
doublereal LatticePhase::
enthalpy_mole() const {
@ -247,7 +338,7 @@ namespace Cantera {
}
void LatticePhase::setParametersFromXML(const XML_Node& eosdata) {
eosdata._require("model","Lattice");
eosdata._require("model", "Lattice");
m_molar_density = getFloat(eosdata, "site_density", "toSI");
m_vacancy = getChildValue(eosdata, "vacancy_species");
}

View file

@ -274,6 +274,20 @@ namespace Cantera {
*/
LatticePhase& operator=(const LatticePhase& right);
//! Full constructor for a lattice phase
/*!
* @param inputFile String name of the input file
* @param id string id of the phase name
*/
LatticePhase(std::string inputFile, std::string id = "");
//! Full constructor for a water phase
/*!
* @param phaseRef XML node referencing the lattice phase.
* @param id string id of the phase name
*/
LatticePhase(XML_Node& phaseRef, std::string id = "");
//! Destructor
virtual ~LatticePhase();
@ -287,6 +301,31 @@ namespace Cantera {
*/
ThermoPhase *duplMyselfAsThermoPhase() const;
/*
* @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 constructPhaseXML(XML_Node& phaseNode, std::string idTarget);
/*
* constructPhaseFile
*
*
* 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);
//! Equation of state flag. Returns the value cLattice
virtual int eosType() const { return cLattice; }
@ -814,6 +853,8 @@ namespace Cantera {
//! Molar density of the lattice solid
/*!
* Currently, this does not change as a function of T, P or composition
*
* units are kmol m-3
*/
doublereal m_molar_density;

View file

@ -137,6 +137,41 @@ namespace Cantera {
m_index = m;
}
// Returns the index of a species named 'name' within the Phase object
/*
* The first species in the phase will have an index 0, and the last one in the
* phase will have an index of nSpecies() - 1.
*
*
* A species name may be referred to via three methods:
*
* - "speciesName"
* - "PhaseId:speciesName"
* - "phaseName:speciesName"
* .
*
* The first two methods of naming may not yield a unique species within
* complicated assemblies of Cantera Phases.
*
* @param nameStr String name of the species. It may also be the phase name
* species name combination, separated by a colon.
* @return Returns the index of the species. If the name is not found,
* the value of -1 is returned.
*/
int Phase::speciesIndex(std::string nameStr) const {
std::string pn;
std::string sn = parseSpeciesName(nameStr, pn);
if (pn == "" || pn == m_name || pn == m_id) {
return Constituents::speciesIndex(sn);
}
return -1;
}
std::string Phase::speciesSPName(int k) const {
std::string sn = Constituents::speciesName(k);
return(m_name + ":" + sn);
}
void Phase::saveState(vector_fp& state) const {
state.resize(nSpecies() + 2);
saveState(state.size(),&(state[0]));
@ -315,8 +350,8 @@ namespace Cantera {
return State::moleFraction(k);
}
doublereal Phase::moleFraction(std::string name) const {
int iloc = speciesIndex(name);
doublereal Phase::moleFraction(std::string nameSpec) const {
int iloc = speciesIndex(nameSpec);
if (iloc >= 0) return State::moleFraction(iloc);
else return 0.0;
}
@ -325,8 +360,8 @@ namespace Cantera {
return State::massFraction(k);
}
doublereal Phase::massFraction(std::string name) const {
int iloc = speciesIndex(name);
doublereal Phase::massFraction(std::string nameSpec) const {
int iloc = speciesIndex(nameSpec);
if (iloc >= 0) return massFractions()[iloc];
else return 0.0;
}

View file

@ -138,6 +138,37 @@ namespace Cantera {
* vector, which is in general of length (2 + nSpecies()). The first
* two entries of the state vector is temperature and density.
*
* The class Phase contains two strings that identify a phase.
* The string id() is the value of the ID attribute of the XML phase node
* that is used to initialize a phase when it is read it.
* The id() field will stay that way even if the name is changed.
* The name field is also set to the value of the ID attribute of
* the XML phase node.
*
* However, the name field may be changed to another value during the course of a calculation.
* For example, if a phase is located in two places, but has the same
* constituitive input, the id's of the two phases will be the same,
* but the names of the two phases may be different.
*
* The name of a phase can be the same as the id of that same phase.
* Actually, this is the default and normal condition to have the name and
* the id for each phase to be the same. However, it is expected that
* it's an error to have two phases in a single problem with the same name.
* or the same id (or the name from one phase being the same as the id
* of another phase).
* Thus, it is expected that there is a 1-1 correspondence between
* names and unique phases within a Cantera problem.
*
* A species name may be referred to via three methods:
*
* - "speciesName"
* - "PhaseId:speciesName"
* - "phaseName:speciesName"
* .
*
* The first two methods of naming may not yield a unique species within
* complicated assemblies of Cantera Phases.
*
*
* @todo
* Make the concept of saving state vectors more general, so that
@ -237,6 +268,39 @@ namespace Cantera {
*/
void setIndex(int m);
//! Returns the index of a species named 'name' within the Phase object
/*!
* The first species in the phase will have an index 0, and the last one in the
* phase will have an index of nSpecies() - 1.
*
* A species name may be referred to via three methods:
*
* - "speciesName"
* - "PhaseId:speciesName"
* - "phaseName:speciesName"
* .
*
* The first two methods of naming may not yield a unique species within
* complicated assemblies of Cantera phases. The last method is guarranteed
* to be unique within a collection of Cantera phases.
*
* @param name String name of the species. It may also be the phase name
* species name combination, separated by a colon.
* @return Returns the index of the species. If the name is not found,
* the value of -1 is returned.
*/
int speciesIndex(std::string name) const;
//! Returns the expanded species name of a species, including the phase name
/*!
* Returns the expanded phase name species name string.
* This is guarranteed to be unique within a Cantera problem.
*
* @param k Species index within the phase
* @return Returns the "phaseName:speciesName" string
*/
std::string speciesSPName(int k) const;
//! Save the current internal state of the phase
/*!
* Write to vector 'state' the current internal state.
@ -530,12 +594,22 @@ namespace Cantera {
//! ID of the phase.
/*!
* This is the value of the ID attribute of the XML phase node.
* The field will stay that way even if the name is changed.
*/
std::string m_id;
//! Name of the phase.
/*!
* Initially, this is the value of the ID attribute of the XML phase node.
*
* It may be changed to another value during the course of a calculation.
* for example, if a phase is located in two places, but has the same
* constituitive input, the id's of the two phases will be the same,
* but the names of the two phases may be different.
*
* The name can be the same as the id, within a phase. However, besides
* that case, it is expected that there is a 1-1 correspondence between
* names and unique phases within a Cantera problem.
*/
std::string m_name;
};

View file

@ -162,13 +162,13 @@ namespace Cantera {
void WaterSSTP::constructPhaseFile(std::string inputFile, std::string id) {
if (inputFile.size() == 0) {
throw CanteraError("WaterTp::initThermo",
throw CanteraError("WaterSSTP::constructPhaseFile",
"input file is null");
}
std::string path = findInputFile(inputFile);
std::ifstream fin(path.c_str());
if (!fin) {
throw CanteraError("WaterSSTP::initThermo","could not open "
throw CanteraError("WaterSSTP::constructPhaseFile","could not open "
+path+" for reading.");
}
/*
@ -180,7 +180,7 @@ namespace Cantera {
fxml->build(fin);
XML_Node *fxml_phase = findXMLPhase(fxml, id);
if (!fxml_phase) {
throw CanteraError("WaterSSTP::initThermo",
throw CanteraError("WaterSSTP::constructPhaseFile",
"ERROR: Can not find phase named " +
id + " in file named " + inputFile);
}