Esempio n. 1
0
void MineralEQ3::initThermoXML(XML_Node& phaseNode, const std::string& id_)
{
    // Find the Thermo XML node
    if (!phaseNode.hasChild("thermo")) {
        throw CanteraError("HMWSoln::initThermoXML",
                           "no thermo XML node");
    }

    const XML_Node* xsp = speciesData()[0];

    XML_Node* aStandardState = 0;
    if (xsp->hasChild("standardState")) {
        aStandardState = &xsp->child("standardState");
    } else {
        throw CanteraError("MineralEQ3::initThermoXML",
                           "no standard state mode");
    }
    doublereal volVal = 0.0;
    if (aStandardState->attrib("model") != "constantVolume") {
        throw CanteraError("MineralEQ3::initThermoXML",
                           "wrong standard state mode");
    }
    if (aStandardState->hasChild("V0_Pr_Tr")) {
        XML_Node& aV = aStandardState->child("V0_Pr_Tr");
        double Afactor = toSI("cm3/gmol");
        if (aV.hasAttrib("units")) {
            Afactor = toSI(aV.attrib("units"));
        }
        volVal = getFloat(*aStandardState, "V0_Pr_Tr");
        m_V0_pr_tr= volVal;
        volVal *= Afactor;
    } else {
        throw CanteraError("MineralEQ3::initThermoXML",
                           "wrong standard state mode");
    }
    setDensity(molecularWeight(0) / volVal);

    const XML_Node& MinEQ3node = xsp->child("thermo").child("MinEQ3");

    m_deltaG_formation_pr_tr =
        getFloat(MinEQ3node, "DG0_f_Pr_Tr", "actEnergy") / actEnergyToSI("cal/gmol");
    m_deltaH_formation_pr_tr =
        getFloat(MinEQ3node, "DH0_f_Pr_Tr", "actEnergy") / actEnergyToSI("cal/gmol");
    m_Entrop_pr_tr = getFloat(MinEQ3node, "S0_Pr_Tr", "toSI") / toSI("cal/gmol/K");
    m_a = getFloat(MinEQ3node, "a", "toSI") / toSI("cal/gmol/K");
    m_b = getFloat(MinEQ3node, "b", "toSI") / toSI("cal/gmol/K2");
    m_c = getFloat(MinEQ3node, "c", "toSI") / toSI("cal-K/gmol");

    convertDGFormation();
}
Esempio n. 2
0
  /* 
   *  Returns a doublereal 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'.
   *
   * 
   *
   *  Example:  
   *
   * Code snipet:
   *       @verbatim
   const XML_Node &State_XMLNode;
   doublereal pres = OneAtm;
   bool exists = getOptionalFloat(State_XMLNode, "pressure", pres, "toSI");
   @endverbatim
   *
   *  reads the corresponding XML file:
   *  @verbatim
   <state>
     <pressure units="Pa"> 101325.0 </pressure>
   <\state>
   @endverbatim
   *
   *   @param parent reference to the XML_Node object of the parent XML element
   *   @param name   Name of the XML child element
   *   @param fltRtn Float Return. It will be overridden if the XML 
   *                 element exists.
   *   @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.
   *
   * @return returns true if the child element named "name" exists
   */
  doublereal getFloatDefaultUnits(const Cantera::XML_Node& parent, std::string name,
				  std::string defaultUnits, std::string type) {

    doublereal fctr = 1.0;
    if (defaultUnits == "") {
      throw CanteraError("getFloatDefaultUnits",
			 "need to supply an actual value of defaultUnits"); 
    }
    if (type == "actEnergy") {
      fctr = actEnergyToSI(defaultUnits);
    } else if (type == "toSI") {
      fctr = toSI(defaultUnits);
    } else if (defaultUnits == "temperature") {
      fctr = toSI(defaultUnits);
    } else if (type == "density") {
      fctr = toSI(defaultUnits);
    } else if (type == "pressure") {
      fctr = toSI(defaultUnits);
    } else {
      throw CanteraError("getFloatDefaultUnits",
			 "type of units must be supplied and understood");
    }
    doublereal val = getFloat(parent, name, type);
    val /= fctr;
    return val;
  }
Esempio n. 3
0
  /* 
   *  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,
		      const std::string &name,
		      const std::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;
  }
Esempio n. 4
0
doublereal getFloatCurrent(const XML_Node& node, const std::string& type)
{
    doublereal fctr = 1.0;
    doublereal x = node.fp_value();
    const string& units = node["units"];
    const string& vmin = node["min"];
    const string& vmax = node["max"];
    if (vmin != "" && x < fpValue(vmin) - Tiny) {
        writelog("\nWarning: value "+node.value()+" is below lower limit of "
                 +vmin+".\n");
    }
    if (node["max"] != "" && x > fpValue(vmax) + Tiny) {
        writelog("\nWarning: value "+node.value()+" is above upper limit of "
                 +vmax+".\n");
    }
    // Note, most types 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 explicitly 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;
}
Esempio n. 5
0
  /*
   *   This function will read a child node to the current XML node, with the
   *   name "floatArray". It will have a title attribute, and the body
   *   of the XML node will be filled out with a comma separated list of
   *   doublereals.
   *     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.
   *
   *  Example:  
   *
   * Code snipet:
   *       @verbatum
     const XML_Node &State_XMLNode;
     vector_fp v;
     bool convert = true;
     unitsString = "";
     nodeName="floatArray";
     getFloatArray(State_XMLNode, v, convert, unitsString, nodeName);
   @endverbatum
   *
   *  reads the corresponding XML file:
   *
   *  @verbatum
   <state>
     <floatArray  units="m3">   32.4, 1, 100. <\floatArray>
   <\state>
   @endverbatum
   *
   *  Will produce the vector
   *
   *         v[0] = 32.4
   *         v[1] = 1.0
   *         v[2] = 100.
   *
   *
   *   @param  node         XML parent node of the floatArray
   *   @param  v            Output vector of floats containing the floatArray information.
   *   @param  convert      Conversion to SI is carried out if this boolean is
   *                        True. The default is true.
   *   @param  typeString   String name of the type attribute. This is an optional 
   *                        parameter. The default is to have an empty string.
   *                        The only string that is recognized is actEnergy. 
   *                        Anything else has no effect. This affects what
   *                        units converter is used.
   *   @param  nodeName     XML Name of the XML node to read. 
   *                        The default value for the node name is floatArray
   */
  void getFloatArray(const Cantera::XML_Node& node, vector_fp& v, const bool convert,
		     const std::string unitsString, const std::string nodeName) {
    string::size_type icom;
    string numstr;
    doublereal dtmp;
    string nn = node.name();
    if (nn != nodeName) 
      throw CanteraError("getFloatArray",
			 "wrong xml element type/name: was expecting "
			 + nodeName + "but accessed " + node.name());

    v.clear();
    doublereal vmin = Undef, vmax = Undef;

    doublereal funit = 1.0;
    /*
     * Get the attributes field, units, from the XML node
     */
    std::string units = node["units"];
    if (units != "" && convert) {
      if (unitsString == "actEnergy" && units != "") {
	funit = actEnergyToSI(units);
      } else if (unitsString != "" && units != "") {
	funit = toSI(units);
      }
    }

    if (node["min"] != "") 
      vmin = atofCheck(node["min"].c_str());
    if (node["max"] != "") 
      vmax = atofCheck(node["max"].c_str());

    doublereal vv;
    std::string val = node.value();
    while (1 > 0) {
      icom = val.find(',');
      if (icom != string::npos) {
	numstr = val.substr(0,icom);
	val = val.substr(icom+1,val.size());
	dtmp = atofCheck(numstr.c_str());
	v.push_back(dtmp);
      }
      else {
	/*
	 * This little bit of code is to allow for the
	 * possibility of a comma being the last 
	 * item in the value text. This was allowed in
	 * previous versions of Cantera, even though it
	 * would appear to be odd. So, we keep the
	 * possibilty in for backwards compatibility.
	 */
	int nlen = strlen(val.c_str());
	if (nlen > 0) {
	  dtmp = atofCheck(val.c_str());
	  v.push_back(dtmp);
	}
	break;
      }
      vv = v.back();
      if (vmin != Undef && vv < vmin - Tiny) {
	writelog("\nWarning: value "+fp2str(vv)+
		 " is below lower limit of " +fp2str(vmin)+".\n");
      }
      if (vmax != Undef && vv > vmax + Tiny) {
	writelog("\nWarning: value "+fp2str(vv)+
		 " is above upper limit of " +fp2str(vmin)+".\n");
      }
    }
    int nv = v.size();
    for (int n = 0; n < nv; n++) {
      v[n] *= funit;
    }
  }
Esempio n. 6
0
size_t getFloatArray(const XML_Node& node, std::vector<doublereal> & v,
                     const bool convert, const std::string& unitsString,
                     const std::string& nodeName)
{
    const XML_Node* readNode = &node;
    if (node.name() != nodeName) {
        vector<XML_Node*> ll = node.getChildren(nodeName);
        if (ll.size() == 0) {
            throw CanteraError("getFloatArray",
                               "wrong XML element type/name: was expecting "
                               + nodeName + "but accessed " + node.name());
        } else {
            readNode = ll[0];
            ll = readNode->getChildren("floatArray");
            if (ll.size() > 0) {
                readNode = ll[0];
            }
        }
    }

    v.clear();
    doublereal vmin = Undef, vmax = Undef;

    doublereal funit = 1.0;
    /*
     * Get the attributes field, units, from the XML node
     */
    std::string units = readNode->attrib("units");
    if (units != "" && convert) {
        if (unitsString == "actEnergy" && units != "") {
            funit = actEnergyToSI(units);
        } else if (unitsString != "" && units != "") {
            funit = toSI(units);
        }
    }

    if (readNode->attrib("min") != "") {
        vmin = fpValueCheck(readNode->attrib("min"));
    }
    if (readNode->attrib("max") != "") {
        vmax = fpValueCheck(readNode->attrib("max"));
    }

    std::string val = readNode->value();
    while (true) {
        size_t icom = val.find(',');
        if (icom != string::npos) {
            string numstr = val.substr(0,icom);
            val = val.substr(icom+1,val.size());
            v.push_back(fpValueCheck(numstr));
        } else {
            /*
             * This little bit of code is to allow for the
             * possibility of a comma being the last
             * item in the value text. This was allowed in
             * previous versions of Cantera, even though it
             * would appear to be odd. So, we keep the
             * possibility in for backwards compatibility.
             */
            if (!val.empty()) {
                v.push_back(fpValueCheck(val));
            }
            break;
        }
        doublereal vv = v.back();
        if (vmin != Undef && vv < vmin - Tiny) {
            writelog("\nWarning: value "+fp2str(vv)+
                     " is below lower limit of " +fp2str(vmin)+".\n");
        }
        if (vmax != Undef && vv > vmax + Tiny) {
            writelog("\nWarning: value "+fp2str(vv)+
                     " is above upper limit of " +fp2str(vmin)+".\n");
        }
    }
    for (size_t n = 0; n < v.size(); n++) {
        v[n] *= funit;
    }
    return v.size();
}