Added documentation.
Made getFloat() more explicit. Took out the use of "-" for type. Now, have to specify the type of units conversion.
This commit is contained in:
parent
22ba9fd676
commit
75e56cf8d3
4 changed files with 291 additions and 134 deletions
|
|
@ -222,47 +222,97 @@ namespace ctml {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a floating-point value from a child element. Returns a
|
||||
* double value for the child named 'name' of element 'parent'. 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'.
|
||||
*/
|
||||
doublereal getFloat(const XML_Node& parent, string name, string type) {
|
||||
if (!parent.hasChild(name))
|
||||
throw CanteraError("getFloat (called from XML Node \"" +
|
||||
parent.name() + "\"): ",
|
||||
"no child XML element named " + name);
|
||||
const XML_Node& node = parent.child(name);
|
||||
doublereal x, x0, x1, fctr = 1.0;
|
||||
string units, vmin, vmax;
|
||||
x = atof(node().c_str());
|
||||
x0 = Undef;
|
||||
x1 = Undef;
|
||||
units = node["units"];
|
||||
vmin = node["min"];
|
||||
vmax = node["max"];
|
||||
if (vmin != "") {
|
||||
x0 = atof(vmin.c_str());
|
||||
if (x < x0 - Tiny) {
|
||||
writelog("\nWarning: value "+node()+" is below lower limit of "
|
||||
+vmin+".\n");
|
||||
}
|
||||
}
|
||||
if (node["max"] != "") {
|
||||
x1 = atof(vmax.c_str());
|
||||
if (x > x1 + Tiny) {
|
||||
writelog("\nWarning: value "+node()+" is above upper limit of "
|
||||
+vmax+".\n");
|
||||
}
|
||||
}
|
||||
if (type == "actEnergy" && units != "")
|
||||
fctr = actEnergyToSI(units);
|
||||
else if (type != "" && units != "")
|
||||
fctr = toSI(units);
|
||||
return fctr*x;
|
||||
// Get a floating-point value from a child element.
|
||||
/*
|
||||
* Returns a double value for the child named 'name' of element 'parent'. 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:
|
||||
* @verbatum
|
||||
const XML_Node &State_XMLNode;
|
||||
doublereal pres = OneAtm;
|
||||
if (state_XMLNode.hasChild("pressure")) {
|
||||
pres = getFloat(State_XMLNode, "pressure", "toSI");
|
||||
}
|
||||
@endverbatum
|
||||
*
|
||||
* reads the corresponding XML file:
|
||||
* @verbatum
|
||||
<state>
|
||||
<pressure units="Pa"> 101325.0 </pressure>
|
||||
<\state>
|
||||
@endverbatum
|
||||
*
|
||||
* @param parent reference to the XML_Node object of the parent XML element
|
||||
* @param name Name of the XML child element
|
||||
* @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 getFloat(const XML_Node& parent, string name, string type) {
|
||||
if (!parent.hasChild(name))
|
||||
throw CanteraError("getFloat (called from XML Node \"" +
|
||||
parent.name() + "\"): ",
|
||||
"no child XML element named \"" + name + "\" exists");
|
||||
const XML_Node& node = parent.child(name);
|
||||
doublereal x, x0, x1, fctr = 1.0;
|
||||
string units, vmin, vmax;
|
||||
x = atof(node().c_str());
|
||||
x0 = Undef;
|
||||
x1 = Undef;
|
||||
units = node["units"];
|
||||
vmin = node["min"];
|
||||
vmax = node["max"];
|
||||
if (vmin != "") {
|
||||
x0 = atof(vmin.c_str());
|
||||
if (x < x0 - Tiny) {
|
||||
writelog("\nWarning: value "+node()+" is below lower limit of "
|
||||
+vmin+".\n");
|
||||
}
|
||||
}
|
||||
if (node["max"] != "") {
|
||||
x1 = atof(vmax.c_str());
|
||||
if (x > x1 + Tiny) {
|
||||
writelog("\nWarning: value "+node()+" is above upper limit of "
|
||||
+vmax+".\n");
|
||||
}
|
||||
}
|
||||
// Note, most type's of converters default to toSI() type atm.
|
||||
// This may change and become more specific in the future.
|
||||
if (type == "actEnergy" && units != "") {
|
||||
fctr = actEnergyToSI(units);
|
||||
} else if (type == "toSI" && units != "") {
|
||||
fctr = toSI(units);
|
||||
} else if (type == "temperature" && units != "") {
|
||||
fctr = toSI(units);
|
||||
} else if (type == "density" && units != "") {
|
||||
fctr = toSI(units);
|
||||
} else if (type == "pressure" && units != "") {
|
||||
fctr = toSI(units);
|
||||
} else if (type != "" && units != "") {
|
||||
fctr = toSI(units);
|
||||
#ifdef DEBUG_MODE
|
||||
writelog("\nWarning: conversion toSI() was done on node value " + node.name() +
|
||||
"but wasn't explicity requested. Type was \"" + type + "\"\n");
|
||||
#endif
|
||||
}
|
||||
// Note, below currently produces a lot of output due to transport blocks.
|
||||
// This needs to be addressed.
|
||||
#ifdef DEBUG_MODE_MORE
|
||||
else if (type == "" && units != "") {
|
||||
writelog("\nWarning: XML node " + node.name() +
|
||||
"has a units attribute, \"" + units + "\","
|
||||
"but no conversion was done because the getFloat() command didn't have a type\n");
|
||||
}
|
||||
#endif
|
||||
return fctr*x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -416,46 +466,47 @@ namespace ctml {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function interprets the value portion of an XML element
|
||||
* as a series of "Pairs" separated by white space.
|
||||
* Each pair consists of nonwhite-space characters.
|
||||
* The first ":" found in the pair string is used to separate
|
||||
* the string into two parts. The first part is called the "key"
|
||||
* The second part is called the "val".
|
||||
* String vectors of key[i] and val[i] are returned in the
|
||||
* argument list.
|
||||
* Warning: No spaces are allowed in each pair. Quotes are part
|
||||
* of the string.
|
||||
* Example
|
||||
* <xmlNode>
|
||||
* red:112 blue:34
|
||||
* green:banana
|
||||
* </xmlNode>
|
||||
*
|
||||
* Returns:
|
||||
* key val
|
||||
* 0: "red" "112"
|
||||
* 1: "blue" "34"
|
||||
* 2: "green" "banana"
|
||||
*/
|
||||
void getPairs(const XML_Node& node, vector<string>& key,
|
||||
vector<string>& val) {
|
||||
vector<string> v;
|
||||
getStringArray(node, v);
|
||||
int n = static_cast<int>(v.size());
|
||||
string::size_type icolon;
|
||||
for (int i = 0; i < n; i++) {
|
||||
icolon = v[i].find(":");
|
||||
if (icolon == string::npos) {
|
||||
throw CanteraError("getPairs","Missing a colon in the Pair entry ("
|
||||
+v[i]+")");
|
||||
}
|
||||
key.push_back(v[i].substr(0,icolon));
|
||||
val.push_back(v[i].substr(icolon+1, v[i].size()));
|
||||
//cout << "getPairs: " << key.back() << " " << val.back() << endl;
|
||||
}
|
||||
|
||||
//! This function interprets the value portion of an XML element
|
||||
//! as a series of "Pairs" separated by white space.
|
||||
/*!
|
||||
* Each pair consists of nonwhite-space characters.
|
||||
* The first ":" found in the pair string is used to separate
|
||||
* the string into two parts. The first part is called the "key"
|
||||
* The second part is called the "val".
|
||||
* String vectors of key[i] and val[i] are returned in the
|
||||
* argument list.
|
||||
* Warning: No spaces are allowed in each pair. Quotes are part
|
||||
* of the string.
|
||||
* Example: @verbatum
|
||||
* <xmlNode>
|
||||
red:112 blue:34
|
||||
green:banana
|
||||
</xmlNode> @endverbatum
|
||||
*
|
||||
* Returns:
|
||||
* key val
|
||||
* 0: "red" "112"
|
||||
* 1: "blue" "34"
|
||||
* 2: "green" "banana"
|
||||
*/
|
||||
void getPairs(const XML_Node& node, vector<string>& key,
|
||||
vector<string>& val) {
|
||||
vector<string> v;
|
||||
getStringArray(node, v);
|
||||
int n = static_cast<int>(v.size());
|
||||
string::size_type icolon;
|
||||
for (int i = 0; i < n; i++) {
|
||||
icolon = v[i].find(":");
|
||||
if (icolon == string::npos) {
|
||||
throw CanteraError("getPairs","Missing a colon in the Pair entry ("
|
||||
+v[i]+")");
|
||||
}
|
||||
key.push_back(v[i].substr(0,icolon));
|
||||
val.push_back(v[i].substr(icolon+1, v[i].size()));
|
||||
//cout << "getPairs: " << key.back() << " " << val.back() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function interprets the value portion of an XML element
|
||||
|
|
|
|||
|
|
@ -75,21 +75,82 @@ namespace ctml {
|
|||
|
||||
void getStringArray(const Cantera::XML_Node& node, std::vector<std::string>& v);
|
||||
void getStringArray(const std::string& val, std::vector<std::string>& v);
|
||||
void getMap(const Cantera::XML_Node& node, std::map<std::string, std::string>& m);
|
||||
void getPairs(const Cantera::XML_Node& node, std::vector<std::string>& key,
|
||||
std::vector<std::string>& val);
|
||||
void getMatrixValues(const Cantera::XML_Node& node,
|
||||
const std::vector<std::string>& keyString1,
|
||||
const std::vector<std::string>& keyString2,
|
||||
Cantera::Array2D &returnValues, bool convert = true,
|
||||
bool matrixSymmetric = false);
|
||||
void getMap(const Cantera::XML_Node& node, std::map<std::string, std::string>& m);
|
||||
|
||||
//! This function interprets the value portion of an XML element
|
||||
//! as a series of "Pairs" separated by white space.
|
||||
/*!
|
||||
* Each pair consists of nonwhite-space characters.
|
||||
* The first ":" found in the pair string is used to separate
|
||||
* the string into two parts. The first part is called the "key"
|
||||
* The second part is called the "val".
|
||||
* String vectors of key[i] and val[i] are returned in the
|
||||
* argument list.
|
||||
* Warning: No spaces are allowed in each pair. Quotes are part
|
||||
* of the string.
|
||||
* Example: @verbatum
|
||||
* <xmlNode>
|
||||
red:112 blue:34
|
||||
green:banana
|
||||
</xmlNode> @endverbatum
|
||||
*
|
||||
* Returns:
|
||||
* key val
|
||||
* 0: "red" "112"
|
||||
* 1: "blue" "34"
|
||||
* 2: "green" "banana"
|
||||
*/
|
||||
void getPairs(const Cantera::XML_Node& node, std::vector<std::string>& key,
|
||||
std::vector<std::string>& val);
|
||||
|
||||
void getMatrixValues(const Cantera::XML_Node& node,
|
||||
const std::vector<std::string>& keyString1,
|
||||
const std::vector<std::string>& keyString2,
|
||||
Cantera::Array2D &returnValues, bool convert = true,
|
||||
bool matrixSymmetric = false);
|
||||
|
||||
void getIntegers(const Cantera::XML_Node& node, std::map<std::string,int>& v);
|
||||
void getFloats(const Cantera::XML_Node& node, std::map<std::string,double>& v,
|
||||
bool convert=true);
|
||||
doublereal getFloat(const Cantera::XML_Node& parent, std::string name,
|
||||
std::string type="");
|
||||
int getInteger(const Cantera::XML_Node& parent, std::string name);
|
||||
|
||||
|
||||
//! Get a floating-point value from a child element.
|
||||
/*!
|
||||
* Returns a double value for the child named 'name' of element 'parent'. 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:
|
||||
* @verbatum
|
||||
const XML_Node &State_XMLNode;
|
||||
doublereal pres = OneAtm;
|
||||
if (state_XMLNode.hasChild("pressure")) {
|
||||
pres = getFloat(State_XMLNode, "pressure", "toSI");
|
||||
}
|
||||
@endverbatum
|
||||
*
|
||||
* reads the corresponding XML file:
|
||||
* @verbatum
|
||||
<state>
|
||||
<pressure units="Pa"> 101325.0 </pressure>
|
||||
<\state>
|
||||
@endverbatum
|
||||
*
|
||||
* @param parent reference to the XML_Node object of the parent XML element
|
||||
* @param name Name of the XML child element
|
||||
* @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 getFloat(const Cantera::XML_Node& parent, std::string name,
|
||||
std::string type="");
|
||||
|
||||
int getInteger(const Cantera::XML_Node& parent, std::string name);
|
||||
|
||||
void getStrings(const Cantera::XML_Node& node, std::map<std::string,
|
||||
std::string>& v);
|
||||
|
|
|
|||
|
|
@ -352,24 +352,24 @@ namespace Cantera {
|
|||
|
||||
|
||||
|
||||
XML_Node::~XML_Node() {
|
||||
if (m_locked)
|
||||
throw CanteraError("XML_Node::~XML_Node",
|
||||
"attempt to delete locked XML_Node "+name());
|
||||
int n = static_cast<int>(m_children.size());
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (m_children[i]) {
|
||||
if (m_children[i]->parent() == this) {
|
||||
delete m_children[i];
|
||||
m_children[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
XML_Node::~XML_Node() {
|
||||
if (m_locked)
|
||||
throw CanteraError("XML_Node::~XML_Node",
|
||||
"attempt to delete locked XML_Node "+name());
|
||||
int n = static_cast<int>(m_children.size());
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (m_children[i]) {
|
||||
if (m_children[i]->parent() == this) {
|
||||
delete m_children[i];
|
||||
m_children[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XML_Node::addComment(string comment) {
|
||||
addChild("comment",comment);
|
||||
}
|
||||
void XML_Node::addComment(string comment) {
|
||||
addChild("comment",comment);
|
||||
}
|
||||
|
||||
XML_Node& XML_Node::addChild(XML_Node& node) {
|
||||
m_children.push_back(&node);
|
||||
|
|
@ -400,6 +400,45 @@ namespace Cantera {
|
|||
if (hasAttrib("id")) return attrib("id");
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
|
||||
// The operator[] is overloaded to provide a lookup capability
|
||||
// on attributes for the current XML element.
|
||||
/*
|
||||
* For example
|
||||
* xmlNode["id"]
|
||||
* will return the value of the attribute "id" for the current
|
||||
* XML element. It will return the blank std::string if there isn't
|
||||
* an attribute with that name.
|
||||
*
|
||||
* @param attr attribute string to look up
|
||||
*
|
||||
* @return Returns a string representing the value of the attribute
|
||||
* within the XML node. If there is no attribute
|
||||
* with the given name, it returns the null string.
|
||||
*/
|
||||
std::string XML_Node::operator[](std::string attr) const {
|
||||
return attrib(attr);
|
||||
}
|
||||
|
||||
// Function returns the value of an attribute
|
||||
/*
|
||||
* This function searches the attibutes vector for the parameter
|
||||
* std::string attribute. If a match is found, the attribute value
|
||||
* is returned as a string. If no match is found, the empty string
|
||||
* is returned.
|
||||
*
|
||||
* @param attr Std::String containing the attribute to be searched for.
|
||||
*
|
||||
* @return Returns If a match is found, the attribute value
|
||||
* is returned as a string. If no match is found, the empty string
|
||||
* is returned.
|
||||
*/
|
||||
std::string XML_Node::attrib(std::string attr) const {
|
||||
std::map<std::string,std::string>::const_iterator i = m_attribs.find(attr);
|
||||
if (i != m_attribs.end()) return i->second;
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine carries out a search for an XML node based
|
||||
|
|
@ -636,25 +675,25 @@ namespace Cantera {
|
|||
}
|
||||
}
|
||||
|
||||
void XML_Node::copy(XML_Node *node_dest) const {
|
||||
XML_Node *sc, *dc;
|
||||
int ndc;
|
||||
node_dest->addValue(m_value);
|
||||
if (m_name == "") return;
|
||||
map<string,string>::const_iterator b = m_attribs.begin();
|
||||
for (; b != m_attribs.end(); ++b) {
|
||||
node_dest->addAttribute(b->first, b->second);
|
||||
}
|
||||
const vector<XML_Node*> &vsc = node_dest->children();
|
||||
|
||||
for (int n = 0; n < m_nchildren; n++) {
|
||||
sc = m_children[n];
|
||||
ndc = node_dest->nChildren();
|
||||
(void) node_dest->addChild(sc->name());
|
||||
dc = vsc[ndc];
|
||||
sc->copy(dc);
|
||||
}
|
||||
void XML_Node::copy(XML_Node *node_dest) const {
|
||||
XML_Node *sc, *dc;
|
||||
int ndc;
|
||||
node_dest->addValue(m_value);
|
||||
if (m_name == "") return;
|
||||
map<string,string>::const_iterator b = m_attribs.begin();
|
||||
for (; b != m_attribs.end(); ++b) {
|
||||
node_dest->addAttribute(b->first, b->second);
|
||||
}
|
||||
const vector<XML_Node*> &vsc = node_dest->children();
|
||||
|
||||
for (int n = 0; n < m_nchildren; n++) {
|
||||
sc = m_children[n];
|
||||
ndc = node_dest->nChildren();
|
||||
(void) node_dest->addChild(sc->name());
|
||||
dc = vsc[ndc];
|
||||
sc->copy(dc);
|
||||
}
|
||||
}
|
||||
|
||||
void XML_Node::getChildren(string nm,
|
||||
vector<XML_Node*>& children) const {
|
||||
|
|
|
|||
|
|
@ -156,23 +156,22 @@ namespace Cantera {
|
|||
* within the XML node. If there is no attribute
|
||||
* with the given name, it returns the null string.
|
||||
*/
|
||||
std::string operator[](std::string attr) const {
|
||||
return attrib(attr);
|
||||
}
|
||||
std::string operator[](std::string attr) const;
|
||||
|
||||
/**
|
||||
//! Function returns the value of an attribute
|
||||
/*!
|
||||
* This function searches the attibutes vector for the parameter
|
||||
* std::string attribute. If a match is found, the attribute value
|
||||
* is returned as a string. If no match is found, the empty string
|
||||
* is returned.
|
||||
*
|
||||
* @param(attr) Std::String containing the attribute to be searched for.
|
||||
* @param attr Std::String containing the attribute to be searched for.
|
||||
*
|
||||
* @return Returns If a match is found, the attribute value
|
||||
* is returned as a string. If no match is found, the empty string
|
||||
* is returned.
|
||||
*/
|
||||
std::string attrib(std::string attr) const {
|
||||
std::map<std::string,std::string>::const_iterator i = m_attribs.find(attr);
|
||||
if (i != m_attribs.end()) return i->second;
|
||||
return "";
|
||||
}
|
||||
std::string attrib(std::string attr) const;
|
||||
|
||||
std::map<std::string,std::string>& attribs() { return m_attribs; }
|
||||
XML_Node* parent() const { return m_parent; }
|
||||
|
|
@ -187,6 +186,13 @@ namespace Cantera {
|
|||
bool hasChild(const std::string ch) const {
|
||||
return (m_childindex.find(ch) != m_childindex.end());
|
||||
}
|
||||
|
||||
//! Tests whether the current node has an attribute with a particular name
|
||||
/*!
|
||||
* @param a Name of the attribute to test
|
||||
*
|
||||
* @return Returns true if the attribute exists, false otherwise.
|
||||
*/
|
||||
bool hasAttrib(std::string a) const {
|
||||
return (m_attribs.find(a) != m_attribs.end());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue