Another update aimed at getting a SimpleTransport model up and running.

SimpleTransport now can read its XML file.
This commit is contained in:
Harry Moffat 2009-10-13 00:27:48 +00:00
parent 3b4401a77d
commit 9593d2996e
13 changed files with 257 additions and 175 deletions

View file

@ -91,7 +91,7 @@ endif
clean:
@PYTHON_CMD@ setup.py clean
rm -f _build; rm -f _winbuild
(cd build; rm -fR *)
(if test -d build ; then cd build; rm -fR * ; fi )
cd src; rm -f *.o
depends:

View file

@ -630,6 +630,11 @@ namespace ctml {
parent.name() + "\"): ",
"no child XML element named \"" + name + "\" exists");
const XML_Node& node = parent.child(name);
return getFloatCurrent(node, type);
}
doublereal getFloatCurrent(const Cantera::XML_Node& node,
const std::string type) {
doublereal x, x0, x1, fctr = 1.0;
string units, vmin, vmax;
x = atof(node().c_str());
@ -758,6 +763,15 @@ namespace ctml {
return val;
}
bool getOptionalModel(const Cantera::XML_Node& parent, const std::string nodeName,
std::string &modelName) {
if (parent.hasChild(nodeName)) {
const XML_Node& node = parent.child(nodeName);
modelName = node["model"];
return true;
}
return false;
}
// Get an integer value from a child element.
/*

View file

@ -563,6 +563,41 @@ namespace ctml {
doublereal getFloat(const Cantera::XML_Node& parent, const std::string &name,
const std::string type="");
//! Get a floating-point value from the current XML element
/*!
* Returns a doublereal value from the current element. If
* 'type' is supplied and matches a known unit type, unit
* conversion to SI will be done if the child element has an attribute
* 'units'.
*
* Note, it's an error for the child element not to exist.
*
* Example:
*
* Code snipet:
* @verbatim
const XML_Node &State_XMLNode;
doublereal pres = OneAtm;
if (state_XMLNode.hasChild("pressure")) {
XML_Node *pres_XMLNode = State_XMLNode.getChild("pressure");
pres = getFloatCurrent(pres_XMLNode, "toSI");
}
@endverbatim
*
* reads the corresponding XML file:
* @verbatim
<state>
<pressure units="Pa"> 101325.0 </pressure>
<\state>
@endverbatim
*
* @param currXML reference to the current XML_Node object
* @param type String type. Currently known types are "toSI" and "actEnergy",
* and "" , for no conversion. The default value is "",
* which implies that no conversion is allowed.
*/
doublereal getFloatCurrent(const Cantera::XML_Node& currXML, const std::string type="");
//! Get an optional floating-point value from a child element.
/*!
* Returns a doublereal value for the child named 'name' of element 'parent'. If
@ -647,6 +682,34 @@ namespace ctml {
void getFloats(const Cantera::XML_Node& node, std::map<std::string, double>& v,
const bool convert=true);
//! Get an integer value from a child element.
/*!
* Returns an integer value for the child named 'name' of element 'parent'.
*
* Note, it's an error for the child element not to exist.
*
* Example:
*
* Code snipet:
* @verbatim
const XML_Node &State_XMLNode;
int number = 1;
if (state_XMLNode.hasChild("NumProcs")) {
number = getInteger(State_XMLNode, "numProcs");
}
@endverbatim
*
* reads the corresponding XML file:
* @verbatim
<state>
<numProcs> 10 <numProcs/>
<\state>
@endverbatim
*
* @param parent reference to the XML_Node object of the parent XML element
* @param name Name of the XML child element
*/
int getInteger(const Cantera::XML_Node& parent, std::string name);
//! Get a floating-point value from a child element with a defined units field
/*!
@ -685,34 +748,37 @@ namespace ctml {
doublereal getFloatDefaultUnits(const Cantera::XML_Node& parent, std::string name,
std::string defaultUnits, std::string type="toSI");
//! Get an integer value from a child element.
//! Get an optional model name from a named child node.
/*!
* Returns an integer value for the child named 'name' of element 'parent'.
*
* Note, it's an error for the child element not to exist.
* Returns the model name attribute for the child named 'nodeName' of element 'parent'.
* Note, it's optional for the child node to exist
*
* Example:
*
* Code snipet:
* @verbatim
const XML_Node &State_XMLNode;
int number = 1;
if (state_XMLNode.hasChild("NumProcs")) {
number = getInteger(State_XMLNode, "numProcs");
}
std::string modelName = "";
bool exists = getOptionalModel(transportNode, "compositionDependence",
modelName);
@endverbatim
*
* reads the corresponding XML file:
* @verbatim
<state>
<numProcs> 10 <numProcs/>
<\state>
<transport model="Simple">
<compositionDependence model="Solvent_Only"/>
</transport>
@endverbatim
*
* On return modelName is set to "Solvent_Only".
*
* @param parent reference to the XML_Node object of the parent XML element
* @param name Name of the XML child element
* @param nodeName Name of the XML child element
* @param modelName On return this contains the contents of the model attribute
*
* @return True if the nodeName XML node exists. False otherwise
*/
int getInteger(const Cantera::XML_Node& parent, std::string name);
bool getOptionalModel(const Cantera::XML_Node& parent, const std::string nodeName,
std::string &modelName);
//! This function reads a child node with the default name, "floatArray", with a value
//! consisting of a comma separated list of floats

View file

@ -232,6 +232,10 @@ namespace Cantera {
m_u["m-1"] = m_u["m^-1"];
m_u["wavenumbers"] = m_u["cm^-1"];
// viscosity
m_u["poise"] = 0.1;
m_u["centipoise"] = 0.001;
m_act_u["eV"] = m_u["eV"]; // /m_u["molec"];
m_act_u["K"] = GasConstant;
m_act_u["Kelvin"] = GasConstant;

View file

@ -441,6 +441,7 @@ namespace Cantera {
m_nchildren(0),
m_iscomment(false)
{
m_root = this;
right.copy(this);
}
@ -1150,6 +1151,7 @@ namespace Cantera {
XML_Node *sc, *dc;
int ndc;
node_dest->addValue(m_value);
node_dest->setName(m_name);
if (m_name == "") return;
map<string,string>::const_iterator b = m_attribs.begin();
for (; b != m_attribs.end(); ++b) {

View file

@ -443,6 +443,14 @@ namespace Cantera {
*/
std::string name() const { return m_name; }
//! Sets the name of the XML node
/*!
* @param name The name of the XML node
*/
void setName(std::string name) {
m_name = name;
}
//! Return the id attribute, if present
/*!
* Returns the id attribute if present. If not

View file

@ -426,7 +426,7 @@ namespace Cantera {
* be able to resurrect the information later by calling xml().
*/
XML_Node &phaseNode_XML = th->xml();
phaseNode_XML.clear();
//phaseNode_XML.clear();
phase.copy(&phaseNode_XML);
// set the id attribute of the phase to the 'id' attribute

View file

@ -48,8 +48,14 @@ namespace Cantera {
ThermoPhase::~ThermoPhase()
{
for (int k = 0; k < m_kk; k++) {
if (!m_speciesData[k]) {
delete m_speciesData[k];
}
}
delete m_spthermo;
}
/**
* Copy Constructor for the ThermoPhase object.
*
@ -84,6 +90,19 @@ namespace Cantera {
* Check for self assignment.
*/
if (this == &right) return *this;
/*
* We need to destruct first
*/
for (int k = 0; k < m_kk; k++) {
if (!m_speciesData[k]) {
delete m_speciesData[k];
}
}
if (m_spthermo) {
delete m_spthermo;
}
/*
* Call the base class assignment operator
*/
@ -93,13 +112,15 @@ namespace Cantera {
* Pointer to the species thermodynamic property manager
* We own this, so we need to do a deep copy
*/
if (m_spthermo) {
delete m_spthermo;
}
m_spthermo = (right.m_spthermo)->duplMyselfAsSpeciesThermo();
// We don't do a deep copy here, because we don't own this
m_speciesData = right.m_speciesData;
/*
* Do a deep copy of species Data, because we own this
*/
m_speciesData.resize(m_kk);
for (int k = 0; k < m_kk; k++) {
m_speciesData[k] = new XML_Node(*(right.m_speciesData[k]));
}
m_index = right.m_index;
m_phi = right.m_phi;
@ -921,7 +942,7 @@ namespace Cantera {
if ((int) m_speciesData.size() < (k + 1)) {
m_speciesData.resize(k+1, 0);
}
m_speciesData[k] = data;
m_speciesData[k] = new XML_Node(*data);
}
//! Return a pointer to the XML tree containing the species

View file

@ -2029,9 +2029,11 @@ namespace Cantera {
//! Vector of pointers to the species databases.
/*!
* This is used to access data needed to
* This is used to access data needed to
* construct the transport manager and other properties
* later in the initialization process.
* We create a copy of the XML_Node data read in here. Therefore, we own this
* data.
*/
std::vector<const XML_Node *> m_speciesData;

View file

@ -60,7 +60,7 @@ namespace Cantera {
DenseMatrix visc_Sij;
//Hydrodynamic radius of transported molecule
vector_fp hydroRadius;
vector_fp hydroRadius;
//! Coefficients for the limiting conductivity of ions
//! in solution: A_k

View file

@ -151,6 +151,39 @@ namespace Cantera {
m_tmin = m_thermo->minTemp();
m_tmax = m_thermo->maxTemp();
/*
* Read the transport block in the phase XML Node
* It's not an error if this block doesn't exist. Just use the defaults
*/
XML_Node &phaseNode = m_thermo->xml();
if (phaseNode.hasChild("transport")) {
XML_Node& transportNode = phaseNode.child("transport");
string transportModel = transportNode.attrib("model");
if (transportModel == "Simple") {
/*
* <compositionDependence model="Solvent_Only"/>
* or
* <compositionDependence model="Mixture_Averaged"/>
*/
std::string modelName = "";
if (getOptionalModel(transportNode, "compositionDependence",
modelName)) {
modelName = lowercase(modelName);
if (modelName == "solvent_only") {
compositionDepType_ = 0;
} else if (modelName == "mixture_averaged") {
compositionDepType_ = 1;
} else {
throw CanteraError("SimpleTransport::initLiquid", "Unknown compositionDependence Model: " + modelName);
}
}
}
}
// make a local copy of the molecular weights
m_mw.resize(m_nsp);
copy(m_thermo->molecularWeights().begin(),
@ -165,24 +198,29 @@ namespace Cantera {
Cantera::LiquidTransportData &ltd0 = tr.LTData[0];
LiquidTR_Model vm0 = ltd0.model_viscosity;
std::string spName0 = m_thermo->speciesName(0);
std::string spName = m_thermo->speciesName(0);
if (vm0 == LTR_MODEL_CONSTANT) {
tempDepType_ = 0;
} else if (vm0 == LTR_MODEL_ARRHENIUS) {
tempDepType_ = 1;
} else if (vm0 == LTR_MODEL_NOTSET) {
throw CanteraError("SimpleTransport::initLiquid",
"Viscosity Model is not set in the input file");
"Viscosity Model is not set for species " + spName0 + " in the input file");
} else {
throw CanteraError("SimpleTransport::initLiquid",
"Viscosity Model is not handled by this object");
"Viscosity Model for species " + spName0 + " is not handled by this object");
}
for (k = 0; k < m_nsp; k++) {
spName = m_thermo->speciesName(k);
Cantera::LiquidTransportData &ltd = tr.LTData[k];
LiquidTR_Model vm = ltd.model_viscosity;
if (vm != vm0) {
throw CanteraError(" SimpleTransport::initLiquid",
"different viscosity models");
if (compositionDepType_ != 0) {
throw CanteraError(" SimpleTransport::initLiquid",
"different viscosity models for species " + spName + " and " + spName0 );
}
}
vector_fp &kentry = m_coeffVisc_Ns[k];
kentry = ltd.viscCoeffs;
@ -197,15 +235,18 @@ namespace Cantera {
LiquidTR_Model cm0 = ltd0.model_thermalCond;
if (cm0 != vm0) {
throw CanteraError("SimpleTransport::initLiquid",
"Conductivity model is not the same as the viscosity model");
"Conductivity model is not the same as the viscosity model for species " + spName0);
}
for (k = 0; k < m_nsp; k++) {
spName = m_thermo->speciesName(k);
Cantera::LiquidTransportData &ltd = tr.LTData[k];
LiquidTR_Model cm = ltd.model_thermalCond;
if (cm != cm0) {
throw CanteraError(" SimpleTransport::initLiquid",
"different thermal conductivity models");
if (compositionDepType_ != 0) {
throw CanteraError(" SimpleTransport::initLiquid",
"different thermal conductivity models for species " + spName + " and " + spName0);
}
}
vector_fp &kentry = m_coeffLambda_Ns[k];
kentry = ltd.thermalCondCoeffs;
@ -221,42 +262,48 @@ namespace Cantera {
m_coeffDiff_Ns.resize(m_nsp);
LiquidTR_Model dm0 = ltd0.model_speciesDiffusivity;
if (dm0 != vm0) {
if (dm0 == LTR_MODEL_NOTSET) {
if (dm0 == LTR_MODEL_NOTSET) {
LiquidTR_Model rm0 = ltd0.model_hydroradius;
if (rm0 != vm0) {
throw CanteraError("SimpleTransport::initLiquid",
"hydroradius model is not the same as the viscosity model");
"hydroradius model is not the same as the viscosity model for species " + spName0);
} else {
useHydroRadius_ = true;
}
}
for (k = 0; k < m_nsp; k++) {
Cantera::LiquidTransportData &ltd = tr.LTData[k];
LiquidTR_Model dm = ltd.model_speciesDiffusivity;
if (dm == LTR_MODEL_NOTSET) {
LiquidTR_Model rm = ltd.model_hydroradius;
if (rm != vm0) {
throw CanteraError("SimpleTransport::initLiquid",
"hydroradius model is not the same as the viscosity model");
}
if (rm != LTR_MODEL_CONSTANT) {
throw CanteraError("SimpleTransport::initLiquid",
"hydroradius model is not constant");
}
vector_fp &kentry = m_coeffHydroRadius_Ns[k];
kentry.push_back(ltd.hydroradius);
} else {
if (dm != dm0) {
throw CanteraError(" SimpleTransport::initLiquid",
"different thermal conductivity models");
}
vector_fp &kentry = m_coeffDiff_Ns[k];
kentry = ltd.speciesDiffusivityCoeffs;
}
}
}
for (k = 0; k < m_nsp; k++) {
spName = m_thermo->speciesName(k);
Cantera::LiquidTransportData &ltd = tr.LTData[k];
LiquidTR_Model dm = ltd.model_speciesDiffusivity;
if (dm == LTR_MODEL_NOTSET) {
LiquidTR_Model rm = ltd.model_hydroradius;
if (rm == LTR_MODEL_NOTSET) {
throw CanteraError("SimpleTransport::initLiquid",
"Neither diffusivity nor hydroradius is set for species " + spName);
}
if (rm != vm0) {
throw CanteraError("SimpleTransport::initLiquid",
"hydroradius model is not the same as the viscosity model for species " + spName);
}
if (rm != LTR_MODEL_CONSTANT) {
throw CanteraError("SimpleTransport::initLiquid",
"hydroradius model is not constant for species " + spName0);
}
vector_fp &kentry = m_coeffHydroRadius_Ns[k];
kentry.push_back(ltd.hydroradius);
} else {
if (dm != dm0) {
throw CanteraError(" SimpleTransport::initLiquid",
"different diffusivity models for species " + spName + " and " + spName0 );
}
vector_fp &kentry = m_coeffDiff_Ns[k];
kentry = ltd.speciesDiffusivityCoeffs;
}
}
m_molefracs.resize(m_nsp);

View file

@ -531,113 +531,30 @@ namespace Cantera {
trParam.tmin = thermo->minTemp();
trParam.tmax = thermo->maxTemp();
trParam.mw.resize(nsp);
trParam.log_level = log_level;
// Get the molecular weights and load them into trParam
trParam.mw.resize(nsp);
copy(trParam.thermo->molecularWeights().begin(),
trParam.thermo->molecularWeights().end(), trParam.mw.begin());
//trParam.epsilon.resize(nsp, nsp, 0.0);
//trParam.delta.resize(nsp, nsp, 0.0);
//trParam.reducedMass.resize(nsp, nsp, 0.0);
//trParam.dipole.resize(nsp, nsp, 0.0);
//trParam.diam.resize(nsp, nsp, 0.0);
//trParam.polar.resize(nsp, false);
//trParam.poly.resize(nsp);
//trParam.sigma.resize(nsp);
//trParam.eps.resize(nsp);
// Resize all other vectors in trParam
trParam.visc_A.resize(nsp, 0.0);
trParam.visc_n.resize(nsp, 0.0);
trParam.visc_Tact.resize(nsp, 0.0);
trParam.thermCond_A.resize(nsp, 0.0);
trParam.thermCond_n.resize(nsp, 0.0);
trParam.thermCond_Tact.resize(nsp, 0.0);
trParam.visc_Eij.resize(nsp, nsp, 0.0);
trParam.visc_Sij.resize(nsp, nsp, 0.0);
trParam.hydroRadius.resize(nsp, 0.0);
trParam.A_k_cond.resize(nsp, 0.0);
trParam.B_k_cond.resize(nsp, 0.0);
trParam.LTData.resize(nsp);
XML_Node root, log;
getLiquidTransportData(transport_database, log,
trParam.thermo->speciesNames(), trParam);
//int i, j;
//for (i = 0; i < nsp; i++) trParam.poly[i].resize(nsp);
//doublereal ts1, ts2, tstar_min = 1.e8, tstar_max = 0.0;
//doublereal f_eps, f_sigma;
//DenseMatrix& diam = trParam.diam;
//DenseMatrix& epsilon = trParam.epsilon;
//for (i = 0; i < nsp; i++)
// {
// for (j = i; j < nsp; j++)
// {
// // the reduced mass
// trParam.reducedMass(i,j) =
// trParam.mw[i] * trParam.mw[j] / (Avogadro * (trParam.mw[i] + trParam.mw[j]));
//
// // hard-sphere diameter for (i,j) collisions
// diam(i,j) = 0.5*(trParam.sigma[i] + trParam.sigma[j]);
//
// // the effective well depth for (i,j) collisions
// epsilon(i,j) = sqrt(trParam.eps[i]*trParam.eps[j]);
//
// // The polynomial fits of collision integrals vs. T*
// // will be done for the T* from tstar_min to tstar_max
// ts1 = Boltzmann * trParam.tmin/epsilon(i,j);
// ts2 = Boltzmann * trParam.tmax/epsilon(i,j);
// if (ts1 < tstar_min) tstar_min = ts1;
// if (ts2 > tstar_max) tstar_max = ts2;
//
// // the effective dipole moment for (i,j) collisions
// trParam.dipole(i,j) = sqrt(trParam.dipole(i,i)*trParam.dipole(j,j));
//
// // reduced dipole moment delta* (nondimensional)
// doublereal d = diam(i,j);
// trParam.delta(i,j) = 0.5 * trParam.dipole(i,j)*trParam.dipole(i,j)
// / (epsilon(i,j) * d * d * d);
//
// makePolarCorrections(i, j, trParam, f_eps, f_sigma);
// trParam.diam(i,j) *= f_sigma;
// epsilon(i,j) *= f_eps;
//
// // properties are symmetric
// trParam.reducedMass(j,i) = trParam.reducedMass(i,j);
// diam(j,i) = diam(i,j);
// epsilon(j,i) = epsilon(i,j);
// trParam.dipole(j,i) = trParam.dipole(i,j);
// trParam.delta(j,i) = trParam.delta(i,j);
// }
// }
// Chemkin fits the entire T* range in the Monchick and Mason tables,
// so modify tstar_min and tstar_max if in Chemkin compatibility mode
//if (mode == CK_Mode) {
// tstar_min = 0.101;
// tstar_max = 99.9;
//}
// initialize the collision integral calculator for the desired
// T* range
//#ifdef DEBUG_MODE
// if (m_verbose) {
// trParam.xml->XML_open(flog, "collision_integrals");
// }
//#endif
// m_integrals = new MMCollisionInt;
// m_integrals->init(trParam.xml, tstar_min, tstar_max, log_level);
// fitCollisionIntegrals(flog, trParam);
//#ifdef DEBUG_MODE
// if (m_verbose) {
// trParam.xml->XML_close(flog, "collision_integrals");
// }
//#endif
// // make polynomial fits
//#ifdef DEBUG_MODE
// if (m_verbose) {
// trParam.xml->XML_open(flog, "property fits");
// }
//#endif
// fitProperties(trParam, flog);
//#ifdef DEBUG_MODE
// if (m_verbose) {
// trParam.xml->XML_close(flog, "property fits");
// }
//#endif
trParam.thermo->speciesNames(), trParam);
}
@ -1004,7 +921,7 @@ namespace Cantera {
XML_Node& vnode = trNode.child("viscosity");
std::string model = lowercase(vnode["model"]);
if (model == "" || model == "constant") {
A_visc = vnode.fp_value();
A_visc = ctml::getFloatCurrent(vnode, "toSI");
if (A_visc > 0.0) (data.viscCoeffs).push_back(A_visc);
else throw TransportDBError(linenum,
"negative or zero viscosity");
@ -1030,35 +947,35 @@ namespace Cantera {
}
/*
* thermal_conductivity
* thermalConductivity
*
* format:
* <thermal_conductivity model="Constant"> 3.0 </thermal_conductivity>
* <thermal_conductivity> 3.0 </thermal_conductivity>
* <thermal_conductivity model="Arrhenius">
* <thermalConductivity model="Constant"> 3.0 </thermalConductivity>
* <thermalConductivity> 3.0 </thermalConductivity>
* <thermalConductivity model="Arrhenius">
* <A units="Pa S"> 1.0 </A>
* <b> 2.0 </b>
* <E units="kcal/gmol"> 3.0 </E>
* </thermal_conductivity>
* </thermalConductivity>
*
* <thermal_conductivity model="Coeff">
* <thermalConductivity model="Coeff">
* <float_array> 0.0. 1.0, 2.0, 3.0, 4.0 </float_array>
* </thermal_conductivity>
* </thermalConductivity>
*
*/
if (trNode.hasChild("thermal_conductivity")) {
XML_Node& tnode = trNode.child("thermal_conductivity");
if (trNode.hasChild("thermalConductivity")) {
XML_Node& tnode = trNode.child("thermalConductivity");
std::string model = lowercase(tnode["model"]);
if (model == "" || model == "constant") {
A_thcond = tnode.fp_value();
A_thcond = ctml::getFloatCurrent(tnode, "toSI");
if (A_thcond > 0.0) (data.thermalCondCoeffs).push_back(A_thcond);
else throw TransportDBError(linenum,
"negative or zero thermal_conductivity");
"negative or zero thermalConductivity");
data.model_thermalCond = LTR_MODEL_CONSTANT;
} else if (model == "arrhenius") {
getArrhenius(tnode, A_thcond, n_thcond, Tact_thcond);
if (A_thcond <= 0.0) {
throw TransportDBError(linenum, "negative or zero thermal_conductivity");
throw TransportDBError(linenum, "negative or zero thermalConductivity");
}
(data.thermalCondCoeffs).push_back(A_thcond);
(data.thermalCondCoeffs).push_back(n_thcond);
@ -1071,7 +988,7 @@ namespace Cantera {
data.model_thermalCond = LTR_MODEL_COEFF;
} else {
throw CanteraError(" TransportFactory::getLiquidTransportData",
"Unknown model for thermal_conductivity:" + tnode["model"]);
"Unknown model for thermalConductivity:" + tnode["model"]);
}
}
@ -1097,7 +1014,7 @@ namespace Cantera {
XML_Node& dnode = trNode.child("speciesDiffusivity");
std::string model = lowercase(dnode["model"]);
if (model == "" || model == "constant") {
A_spdiff = dnode.fp_value();
A_spdiff = ctml::getFloatCurrent(dnode, "toSI");
if (A_spdiff > 0.0) (data.speciesDiffusivityCoeffs).push_back(A_spdiff);
else throw TransportDBError(linenum,
"negative or zero speciesDiffusivity");
@ -1172,7 +1089,7 @@ namespace Cantera {
// Need to identify a method to obtain interaction matrices.
// This will fill LiquidTransportParams members visc_Eij, visc_Sij
trParam.visc_Eij.resize(trParam.nsp_,trParam.nsp_);
cout << "No support for species viscosity interactions in TransportFactory.cpp" << endl;
//cout << "No support for species viscosity interactions in TransportFactory.cpp" << endl;
}

3
configure vendored

File diff suppressed because one or more lines are too long