diff --git a/Cantera/src/ctml.cpp b/Cantera/src/ctml.cpp
index 283037843..f5fbc3c78 100755
--- a/Cantera/src/ctml.cpp
+++ b/Cantera/src/ctml.cpp
@@ -287,8 +287,18 @@ namespace ctml {
return x;
}
-
- void getFloatArray(const XML_Node& node, vector_fp& v, bool convert) {
+ /*
+ * getFloatArray():
+ *
+ * Get an array of floats from the XML Node. The argument field
+ * is assumed to consist of an arbitrary number of comma
+ * separated floats, with an arbitrary amount of white space
+ * separating each field.
+ * If the node array has an units attribute field, then
+ * the units are used to convert the floats, iff convert is true.
+ */
+ void getFloatArray(const XML_Node& node, vector_fp& v, bool convert,
+ string type) {
string::size_type icom;
string numstr;
if (node.name() != "floatArray")
@@ -299,16 +309,24 @@ namespace ctml {
doublereal vmin = Undef, vmax = Undef;
doublereal funit = 1.0;
- if (node["units"] != "" && convert) {
- funit = toSI(node["units"]);
- }
+ /*
+ * Get the attributes field, units, from the XML node
+ */
+ string units = node["units"];
+ if (units != "" && convert) {
+ if (type == "actEnergy" && units != "") {
+ funit = actEnergyToSI(units);
+ } else if (type != "" && units != "") {
+ funit = toSI(units);
+ }
+ }
- if (node["min"] != "")
- vmin = atof(node["min"].c_str());
- if (node["max"] != "")
- vmax = atof(node["max"].c_str());
+ if (node["min"] != "")
+ vmin = atof(node["min"].c_str());
+ if (node["max"] != "")
+ vmax = atof(node["max"].c_str());
- doublereal vv;
+ doublereal vv;
string val = node.value();
while (1 > 0) {
icom = val.find(',');
@@ -368,16 +386,39 @@ 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
+ *
+ * red:112 blue:34
+ * green:banana
+ *
+ *
+ * Returns:
+ * key val
+ * 0: "red" "112"
+ * 1: "blue" "34"
+ * 2: "green" "banana"
+ */
void getPairs(const XML_Node& node, vector& key,
vector& val) {
vector v;
getStringArray(node, v);
int n = static_cast(v.size());
- string::size_type icolon;
+ string::size_type icolon;
for (int i = 0; i < n; i++) {
icolon = v[i].find(":");
if (icolon == string::npos) {
- throw CanteraError("getMap","missing colon in map entry ("
+ throw CanteraError("getPairs","Missing a colon in the Pair entry ("
+v[i]+")");
}
key.push_back(v[i].substr(0,icolon));
@@ -385,6 +426,128 @@ namespace ctml {
}
}
+ /**
+ * This function interprets the value portion of an XML element
+ * as a series of "Matrix ids and entries" separated by white space.
+ * Each pair consists of nonwhite-space characters.
+ * The first two ":" found in the pair string is used to separate
+ * the string into three parts. The first part is called the first
+ * key. The second part is the second key. Both parts must match
+ * an entry in the keyString1 and keyString2, respectively,
+ * in order to provide a location to
+ * place the object in the matrix.
+ * The third part is called the value. It is expected to be
+ * a double. It is translated into a double and placed into the
+ * correct location in the matrix.
+ *
+ * Warning: No spaces are allowed in each triplet. Quotes are part
+ * of the string.
+ * Example
+ * keyString = red, blue, black, green
+ *
+ * red:green:112
+ * blue:black:3.3E-23
+ *
+ *
+ *
+ * Returns:
+ * retnValues(0, 3) = 112
+ * retnValues(1, 2) = 3.3E-23
+ */
+ void getMatrixValues(const XML_Node& node,
+ const vector& keyString1,
+ const vector& keyString2,
+ Array2D &retnValues, bool convert,
+ bool matrixSymmetric) {
+ int szKey1 = keyString1.size();
+ int szKey2 = keyString2.size();
+ int nrow = retnValues.nRows();
+ int ncol = retnValues.nColumns();
+ if (szKey1 > nrow) {
+ throw CanteraError("getMatrixValues",
+ "size of key1 greater than numrows");
+ }
+ if (szKey2 > ncol) {
+ throw CanteraError("getMatrixValues",
+ "size of key2 greater than num cols");
+ }
+ if (matrixSymmetric) {
+ if (nrow != ncol) {
+ throw CanteraError("getMatrixValues",
+ "nrow != ncol for a symmetric matrix");
+ }
+ }
+
+ /*
+ * Get the attributes field, units, from the XML node
+ * and determine the conversion factor, funit.
+ */
+ doublereal funit = 1.0;
+ string units = node["units"];
+ if (units != "" && convert) {
+ funit = toSI(units);
+ }
+
+ string key1;
+ string key2;
+ string rmm;
+ string val;
+ vector v;
+ getStringArray(node, v);
+ int icol, irow;
+ int n = static_cast(v.size());
+ string::size_type icolon;
+ for (int i = 0; i < n; i++) {
+ icolon = v[i].find(":");
+ if (icolon == string::npos) {
+ throw CanteraError("getMatrixValues","Missing two colons ("
+ +v[i]+")");
+ }
+ key1 = v[i].substr(0,icolon);
+ rmm = v[i].substr(icolon+1, v[i].size());
+ icolon = rmm.find(":");
+ if (icolon == string::npos) {
+ throw CanteraError("getMatrixValues","Missing one colon ("
+ +v[i]+")");
+ }
+ key2 = rmm.substr(0,icolon);
+ val = rmm.substr(icolon+1, rmm.size());
+ icol = -1;
+ irow = -1;
+ for (int j = 0; j < szKey1; j++) {
+ if (key1 == keyString1[j]) {
+ irow = j;
+ break;
+ }
+ }
+ if (irow == -1) {
+ throw CanteraError("getMatrixValues","Row not matched by string: "
+ + key1);
+ }
+ for (int j = 0; j < szKey2; j++) {
+ if (key2 == keyString2[j]) {
+ icol = j;
+ break;
+ }
+ }
+ if (icol == -1) {
+ throw CanteraError("getMatrixValues","Col not matched by string: "
+ + key2);
+ }
+ double dval = atofCheck(val.c_str());
+ dval *= funit;
+ /*
+ * Finally, insert the value;
+ */
+ retnValues(irow, icol) = dval;
+ if (matrixSymmetric) {
+ retnValues(icol, irow) = dval;
+ }
+ }
+
+ }
+
+
/**
* This function interprets the value portion of an XML element
* as a string. It then separates the string up into tokens
diff --git a/Cantera/src/ctml.h b/Cantera/src/ctml.h
index ad73d1a58..62821d753 100755
--- a/Cantera/src/ctml.h
+++ b/Cantera/src/ctml.h
@@ -22,6 +22,7 @@
#include "ct_defs.h"
#include "xml.h"
+#include "Array.h"
using namespace Cantera;
namespace ctml {
@@ -71,15 +72,22 @@ namespace ctml {
string val,
string type="");
- void getFloatArray(const XML_Node& node,
- vector_fp& v, bool convert=true);
+ void getFloatArray(const XML_Node& node, vector_fp& v,
+ bool convert=true, string type="");
void getStringArray(const XML_Node& node, vector& v);
void getMap(const XML_Node& node, map& m);
- void getPairs(const XML_Node& node, vector& key, vector& val);
+ void getPairs(const XML_Node& node, vector& key,
+ vector& val);
+ void getMatrixValues(const XML_Node& node,
+ const vector& keyString1,
+ const vector& keyString2,
+ Array2D &returnValues, bool convert = true,
+ bool matrixSymmetric = false);
void getIntegers(const XML_Node& node, map& v);
- void getFloats(const XML_Node& node, map& v, bool convert=true);
+ void getFloats(const XML_Node& node, map& v,
+ bool convert=true);
doublereal getFloat(const XML_Node& parent, string name, string type="");
int getInteger(const XML_Node& parent, string name);