コード例 #1
0
ファイル: ctml.cpp プロジェクト: anujg1991/cantera
  /* 
   *  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;
  }
コード例 #2
0
ファイル: ctml.cpp プロジェクト: anujg1991/cantera
  /* 
   *  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;
  }
コード例 #3
0
ファイル: MineralEQ3.cpp プロジェクト: athlonshi/cantera
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");
    }

    std::vector<const XML_Node*> xspecies = speciesData();
    const XML_Node* xsp = xspecies[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;
    string smodel = (*aStandardState)["model"];
    if (smodel != "constantVolume") {
        throw CanteraError("MineralEQ3::initThermoXML",
                           "wrong standard state mode");
    }
    if (aStandardState->hasChild("V0_Pr_Tr")) {
        XML_Node& aV = aStandardState->child("V0_Pr_Tr");
        string Aunits = "";
        double Afactor = toSI("cm3/gmol");
        if (aV.hasAttrib("units")) {
            Aunits = aV.attrib("units");
            Afactor = toSI(Aunits);
        }
        volVal = ctml::getFloat(*aStandardState, "V0_Pr_Tr");
        m_V0_pr_tr= volVal;
        volVal *= Afactor;
        m_speciesSize[0] = volVal;
    } else {
        throw CanteraError("MineralEQ3::initThermoXML",
                           "wrong standard state mode");
    }
    doublereal rho = molecularWeight(0) / volVal;
    setDensity(rho);

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


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

    convertDGFormation();
}
コード例 #4
0
ファイル: MineralEQ3.cpp プロジェクト: arghdos/cantera
void MineralEQ3::convertDGFormation()
{
    // Ok let's get the element compositions and conversion factors.
    doublereal totalSum = 0.0;
    for (size_t m = 0; m < nElements(); m++) {
        double na = nAtoms(0, m);
        if (na > 0.0) {
            totalSum += na * LookupGe(elementName(m));
        }
    }
    // Ok, now do the calculation. Convert to joules kmol-1
    doublereal dg = m_deltaG_formation_pr_tr * toSI("cal/gmol");
    //! Store the result into an internal variable.
    m_Mu0_pr_tr = dg + totalSum;

    double Hcalc = m_Mu0_pr_tr + 298.15 * m_Entrop_pr_tr * toSI("cal/gmol");
    double DHjmol = m_deltaH_formation_pr_tr * toSI("kal/gmol");

    // If the discrepancy is greater than 100 cal gmol-1, print an error
    if (fabs(Hcalc -DHjmol) > 100 * toSI("cal/gmol")) {
        throw CanteraError("installMinEQ3asShomateThermoFromXML()",
                           "DHjmol is not consistent with G and S: {} vs {}",
                           Hcalc, DHjmol);
    }
}
コード例 #5
0
void BtLineEdit::lineChanged(Unit::unitDisplay oldUnit, Unit::unitScale oldScale)
{
   // This is where it gets hard
   double val = -1.0;
   QString amt;
   bool force = Brewtarget::hasUnits(text());
   bool ok = false;
   bool wasChanged = sender() == this;

   // editingFinished happens on focus being lost, regardless of anything
   // being changed. I am hoping this short circuits properly and we do
   // nothing if nothing changed.
   if ( sender() == this && ! isModified() )
   {
      return;
   }

   if (text().isEmpty())
   {
      return;
   }

   // The idea here is we need to first translate the field into a known
   // amount (aka to SI) and then into the unit we want.
   switch( _type )
   {
      case Unit::Mass:
      case Unit::Volume:
      case Unit::Temp:
      case Unit::Time:
      case Unit::Density:
         val = toSI(oldUnit,oldScale,force);
         amt = displayAmount(val,3);
         break;
      case Unit::Color:
         val = toSI(oldUnit,oldScale,force);
         amt = displayAmount(val,0);
         break;
      case Unit::String:
         amt = text();
         break;
      case Unit::None:
      default:
         val = Brewtarget::toDouble(text(),&ok);
         if ( ! ok )
            Brewtarget::logW( QString("%1: failed to convert %2 (%3:%4) to double").arg(Q_FUNC_INFO).arg(text()).arg(_section).arg(_editField) );
         amt = displayAmount(val);
   }
   QLineEdit::setText(amt);

   if ( wasChanged ) {
      emit textModified();
   }
}
コード例 #6
0
ファイル: ctml.cpp プロジェクト: anujg1991/cantera
  /* 
   *  Returns a std::map containing a keyed values for child XML_Nodes
   *  of the current node with the name, "float". 
   *  In the keyed mapping there will be a list of titles vs. values
   *  for all of the XML nodes. 
   *  The float XML_nodes are expected to be in a particular form created
   *  by the function addFloat(). One value per XML_node is expected.
   *  
   *
   *  Example:  
   *
   * Code snipet:
   *       @verbatum
     const XML_Node &State_XMLNode;
     std::map<std::string,double> v;
     bool convert = true;
     getFloats(State_XMLNode, v, convert);
   @endverbatum
   *
   *  reads the corresponding XML file:
   *
   *  @verbatum
   <state>
     <float title="a1" units="m3">   32.4 <\float>
     <float title="a2" units="cm3">   1.  <\float>
     <float title="a3">             100.  <\float>
   <\state>
   @endverbatum
   *
   *  Will produce the mapping:
   *
   *         v["a1"] = 32.4
   *         v["a2"] = 1.0E-6
   *         v["a3"] = 100.
   *
   *
   *   @param node     Current XML node to get the values from
   *   @param v        Output map of the results.
   *   @param convert  Turn on conversion to SI units
   */
  void getFloats(const Cantera::XML_Node& node, std::map<std::string, double>& v,
		 const bool convert) {
    std::vector<XML_Node*> f;
    node.getChildren("float",f);
    int n = static_cast<int>(f.size());
    doublereal x, x0, x1, fctr;
    std::string typ, title, units, vmin, vmax;
    for (int i = 0; i < n; i++) {
      const XML_Node& fi = *(f[i]);
      x = atof(fi().c_str());
      x0 = Undef;
      x1 = Undef;
      typ = fi["type"];
      title = fi["title"];
      units = fi["units"];
      vmin = fi["min"];
      vmax = fi["max"];
      if (vmin != "") {
	x0 = atof(vmin.c_str());
	if (x < x0 - Tiny) {
	  writelog("\nWarning: value "+fi()+" is below lower limit of "
		   +vmin+".\n");
	}
      }
      if (fi["max"] != "") {
	x1 = atof(vmax.c_str());
	if (x > x1 + Tiny) {
	  writelog("\nWarning: value "+fi()+" is above upper limit of "
		   +vmax+".\n");
	}
      }
      fctr = (convert ? toSI(units) : 1.0); // toSI(typ,units);
      v[title] = fctr*x;
    }
  }
コード例 #7
0
ファイル: ctml.cpp プロジェクト: iokto/cantera
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;
}
コード例 #8
0
TEST_F(ConstructFromScratch, RedlichKwongMFTP)
{
    RedlichKwongMFTP p;
    p.addSpecies(sCO2);
    p.addSpecies(sH2O);
    p.addSpecies(sH2);
    double fa = toSI("bar-cm6/mol2");
    double fb = toSI("cm3/mol");
    p.setBinaryCoeffs("H2", "H2O", 4 * fa, 40 * fa);
    p.setSpeciesCoeffs("CO2", 7.54e7 * fa, -4.13e4 * fa, 27.80 * fb);
    p.setBinaryCoeffs("CO2", "H2O", 7.897e7 * fa, 0.0);
    p.setSpeciesCoeffs("H2O", 1.7458e8 * fa, -8e4 * fa, 18.18 * fb);
    p.setSpeciesCoeffs("H2", 30e7 * fa, -330e4 * fa, 31 * fb);
    p.initThermo();
    p.setMoleFractionsByName("CO2:0.9998, H2O:0.0002");
    p.setState_TP(300, 200 * OneAtm);
    EXPECT_NEAR(p.pressure(), 200 * OneAtm, 1e-5);
    // Arbitrary regression test values
    EXPECT_NEAR(p.density(), 892.421, 2e-3);
    EXPECT_NEAR(p.enthalpy_mole(), -404848642.3797, 1e-3);
}
コード例 #9
0
ファイル: stringUtils.cpp プロジェクト: hkmoffat/cantera
  /*
   *   This is similar to atof(). However, the second token
   *   is interpreted as an MKS units string and a conversion
   *   factor to MKS is applied.
   *
   *   Example
   *  " 1.0 atm"
   *
   *   results in the number 1.01325e5 
   *
   *   @param strSI string to be converted. One or two tokens
   *
   *   @return returns a converted double  
   */
  doublereal strSItoDbl(const std::string& strSI) {
    std::vector<std::string> v;
    tokenizeString(strSI, v);
    doublereal fp = 1.0;
    int n = v.size();
    if (n > 2 || n < 1) {
      throw CanteraError("strSItoDbl",
			 "number of tokens is too high");
    } else if (n == 2) {
      fp = toSI(v[1]);
    }
    doublereal val = atofCheck(v[0].c_str());
    return (val * fp);
  }
コード例 #10
0
ファイル: MineralEQ3.cpp プロジェクト: arghdos/cantera
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();
}
コード例 #11
0
ファイル: ctml.cpp プロジェクト: anujg1991/cantera
  /*
   *   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;
    }
  }
コード例 #12
0
ファイル: ctml.cpp プロジェクト: anujg1991/cantera
  /*
   * 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
   *    <xmlNode>
   *        red:green:112
   *        blue:black:3.3E-23
   *
   *    </xmlNode>
   *
   * Returns:
   *     retnValues(0, 3) = 112
   *     retnValues(1, 2) = 3.3E-23
   *
   *
   *  @param node          XML Node containing the information for the matrix
   *  @param keyStringRow  Key string for the row
   *  @param keyStringCol  Key string for the column entries
   *  @param returnValues  Return Matrix.
   *  @param convert       If this is true, and if the node has a units 
   *                       attribute, then conversion to si units is carried
   *                       out. Default is true.
   *  @param matrixSymmetric  If true entries are made so that the matrix
   *                       is always symmetric. Default is false.
   */
  void getMatrixValues(const Cantera::XML_Node& node,
		       const std::vector<std::string>& keyStringRow,
		       const std::vector<std::string>& keyStringCol,
		       Cantera::Array2D &retnValues, const bool convert,
		       const bool matrixSymmetric) {
    int szKey1 = keyStringRow.size();
    int szKey2 = keyStringCol.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<string> v;
    getStringArray(node, v);
    int icol, irow;
    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("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 == keyStringRow[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 == keyStringCol[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;
      }
    }
  }
コード例 #13
0
ファイル: BtLineEdit.cpp プロジェクト: f1oki/brewtarget
void BtLineEdit::lineChanged(Unit::unitDisplay oldUnit, Unit::unitScale oldScale)
{
   // This is where it gets hard
   double val = -1.0;
   QString amt;
   bool force = false;
   bool ok = false;

   // editingFinished happens on focus being lost, regardless of anything
   // being changed. I am hoping this short circuits properly and we do
   // nothing if nothing changed.
   if ( sender() == this && ! isModified() )
   {
      return;
   }

   // If we are here because somebody else sent the signal (ie, a label) or we
   // generated the signal but nothing has changed then don't try to guess the
   // units.
   if ( sender() != this )
   {
      force = true;
   }

   if ( _section.isEmpty() )
      initializeSection();

   if ( _property.isEmpty() )
      initializeProperties();

   if (text().isEmpty())
   {
      return;
   }

   // The idea here is we need to first translate the field into a known
   // amount (aka to SI) and then into the unit we want.
   switch( _type )
   {
      case MASS:
      case VOLUME:
      case TEMPERATURE:
      case TIME:
         val = toSI(oldUnit,oldScale,force);
         amt = displayAmount(val,3);
         break;
      case DENSITY:
      case COLOR:
         val = toSI(oldUnit,oldScale,force);
         amt = displayAmount(val,0);
         break;
      case STRING:
         amt = text();
         break;
      case GENERIC:
      default:
         val = Brewtarget::toDouble(text(),&ok);
         if ( ! ok )
            Brewtarget::logW( QString("BtLineEdit::lineChanged: failed to convert %1 toDouble").arg(text()) );
         amt = displayAmount(val);
   }
   QLineEdit::setText(amt);

   if ( ! force )
   {
      emit textModified();
   }
}
コード例 #14
0
ファイル: ctml.cpp プロジェクト: iokto/cantera
void getMatrixValues(const XML_Node& node,
                     const std::vector<std::string>& keyStringRow,
                     const std::vector<std::string>& keyStringCol,
                     Array2D& retnValues, const bool convert,
                     const bool matrixSymmetric)
{
    if (keyStringRow.size() > retnValues.nRows()) {
        throw CanteraError("getMatrixValues",
                           "size of key1 greater than numrows");
    } else if (keyStringCol.size() > retnValues.nColumns()) {
        throw CanteraError("getMatrixValues",
                           "size of key2 greater than num cols");
    } else if (matrixSymmetric && retnValues.nRows() != retnValues.nColumns()) {
        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;
    if (convert && node["units"] != "") {
        funit = toSI(node["units"]);
    }

    vector<string> v;
    getStringArray(node, v);
    for (size_t i = 0; i < v.size(); i++) {
        size_t icolon = v[i].find(":");
        if (icolon == string::npos) {
            throw CanteraError("getMatrixValues","Missing two colons ("
                               +v[i]+")");
        }
        string key1 = v[i].substr(0,icolon);
        string rmm = v[i].substr(icolon+1, v[i].size());

        icolon = rmm.find(":");
        if (icolon == string::npos) {
            throw CanteraError("getMatrixValues","Missing one colon ("
                               +v[i]+")");
        }

        size_t irow = find(keyStringRow.begin(), keyStringRow.end(), key1)
                      - keyStringRow.begin();
        if (irow == keyStringRow.size()) {
            throw CanteraError("getMatrixValues","Row not matched by string: "
                               + key1);
        }

        string key2 = rmm.substr(0,icolon);
        size_t icol = find(keyStringCol.begin(), keyStringCol.end(), key2)
                      - keyStringCol.begin();
        if (icol == keyStringCol.size()) {
            throw CanteraError("getMatrixValues","Col not matched by string: "
                               + key2);
        }
        double dval = fpValueCheck(rmm.substr(icolon+1, rmm.size())) * funit;
        /*
         * Finally, insert the value;
         */
        retnValues(irow, icol) = dval;
        if (matrixSymmetric) {
            retnValues(icol, irow) = dval;
        }
    }
}
コード例 #15
0
ファイル: ctml.cpp プロジェクト: iokto/cantera
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();
}
コード例 #16
0
TEST(HMWSoln, fromScratch_HKFT)
{
    HMWSoln p;
    auto sH2O = make_species("H2O(l)", "H:2, O:1", h2oliq_nasa_coeffs);
    auto sNa = make_species("Na+", "Na:1, E:-1", 0.0,
                            298.15, -125.5213, 333.15, -125.5213, 1e5);
    sNa->charge = 1;
    auto sCl = make_species("Cl-", "Cl:1, E:1", 0.0,
                            298.15, -52.8716, 333.15, -52.8716, 1e5);
    sCl->charge = -1;
    auto sH = make_species("H+", "H:1, E:-1", 0.0, 298.15, 0.0, 333.15, 0.0, 1e5);
    sH->charge = 1;
    auto sOH = make_species("OH-", "O:1, H:1, E:1", 0.0,
                            298.15, -91.523, 333.15, -91.523, 1e5);
    sOH->charge = -1;
    for (auto& s : {sH2O, sNa, sCl, sH, sOH}) {
        p.addSpecies(s);
    }
    double h0[] = {-57433, Undef, 0.0, -54977};
    double g0[] = {Undef, -31379, 0.0, -37595};
    double s0[] = {13.96, 13.56, Undef, -2.56};
    double a[][4] = {{0.1839, -228.5, 3.256, -27260},
                     {0.4032, 480.1, 5.563, -28470},
                     {0.0, 0.0, 0.0, 0.0},
                     {0.12527, 7.38, 1.8423, -27821}};
    double c[][2] = {{18.18, -29810}, {-4.4, -57140}, {0.0, 0.0}, {4.15, -103460}};
    double omega[] = {33060, 145600, 0.0, 172460};

    std::unique_ptr<PDSS_Water> ss(new PDSS_Water());
    p.installPDSS(0, std::move(ss));
    for (size_t k = 0; k < 4; k++) {
        std::unique_ptr<PDSS_HKFT> ss(new PDSS_HKFT());
        if (h0[k] != Undef) {
            ss->setDeltaH0(h0[k] * toSI("cal/gmol"));
        }
        if (g0[k] != Undef) {
            ss->setDeltaG0(g0[k] * toSI("cal/gmol"));
        }
        if (s0[k] != Undef) {
            ss->setS0(s0[k] * toSI("cal/gmol/K"));
        }
        a[k][0] *= toSI("cal/gmol/bar");
        a[k][1] *= toSI("cal/gmol");
        a[k][2] *= toSI("cal-K/gmol/bar");
        a[k][3] *= toSI("cal-K/gmol");
        c[k][0] *= toSI("cal/gmol/K");
        c[k][1] *= toSI("cal-K/gmol");
        ss->set_a(a[k]);
        ss->set_c(c[k]);
        ss->setOmega(omega[k] * toSI("cal/gmol"));
        p.installPDSS(k+1, std::move(ss));
    }
    p.setPitzerTempModel("complex");
    p.setA_Debye(-1);
    p.initThermo();

    set_hmw_interactions(p);
    p.setMolalitiesByName("Na+:6.0954 Cl-:6.0954 H+:2.1628E-9 OH-:1.3977E-6");
    p.setState_TP(50 + 273.15, 101325);

    size_t N = p.nSpecies();
    vector_fp mv(N), h(N), mu(N), ac(N), acoeff(N);
    p.getPartialMolarVolumes(mv.data());
    p.getPartialMolarEnthalpies(h.data());
    p.getChemPotentials(mu.data());
    p.getActivities(ac.data());
    p.getActivityCoefficients(acoeff.data());

    double mvRef[] = {0.01815224, 0.00157182, 0.01954605, 0.00173137, -0.0020266};

    for (size_t k = 0; k < N; k++) {
        EXPECT_NEAR(mv[k], mvRef[k], 2e-8);
    }
}