Esempio n. 1
0
  /** 
   * Install a NASA9 polynomial thermodynamic property
   * parameterization for species k into a SpeciesThermo instance.
   * This is called by method installThermoForSpecies if a NASA9
   * block is found in the XML input.
   */
  static void installNasa9ThermoFromXML(std::string speciesName,
					SpeciesThermo& sp, int k, 
					const std::vector<XML_Node*>& tp)
  { 				
    const XML_Node * fptr = tp[0];
    int nRegTmp = tp.size();
    int nRegions = 0;
    vector_fp cPoly;
    Nasa9Poly1 *np_ptr = 0; 
    std::vector<Nasa9Poly1 *> regionPtrs;
    doublereal tmin, tmax, pref = OneAtm;
    // Loop over all of the possible temperature regions
    for (int i = 0; i < nRegTmp; i++) {
      fptr = tp[i];
      if (fptr) {
	if (fptr->name() == "NASA9") {
	  if (fptr->hasChild("floatArray")) {

	    tmin = fpValue((*fptr)["Tmin"]);
	    tmax = fpValue((*fptr)["Tmax"]);
	    if ((*fptr).hasAttrib("P0")) {
	      pref = fpValue((*fptr)["P0"]);
	    }
	    if ((*fptr).hasAttrib("Pref")) {
	      pref = fpValue((*fptr)["Pref"]);
	    }

	    getFloatArray(fptr->child("floatArray"), cPoly, false);
	    if (cPoly.size() != 9) {
	      throw CanteraError("installNasa9ThermoFromXML",
				 "Expected 9 coeff polynomial");
	    }
	    np_ptr = new Nasa9Poly1(k, tmin, tmax, pref,
				    DATA_PTR(cPoly));
	    regionPtrs.push_back(np_ptr);
	    nRegions++;
	  } 
	}
      }
    }
    if (nRegions == 0) {
      throw UnknownSpeciesThermoModel("installThermoForSpecies", 
				      speciesName, "  " );
    } else if (nRegions == 1)  {
      sp.install_STIT(np_ptr);
    } else {
      Nasa9PolyMultiTempRegion*  npMulti_ptr = new  Nasa9PolyMultiTempRegion(regionPtrs);
      sp.install_STIT(npMulti_ptr);
    }
  }
Esempio n. 2
0
  /** 
   * Install a NASA96 polynomial thermodynamic property
   * parameterization for species k into a SpeciesThermo instance.
   */
  static void installNasa96ThermoFromXML(std::string speciesName,
					 SpeciesThermo& sp, int k, 
					 const XML_Node* f0ptr, const XML_Node* f1ptr) {
    doublereal tmin0, tmax0, tmin1, tmax1, tmin, tmid, tmax;

    const XML_Node& f0 = *f0ptr;
    bool dualRange = false;
    if (f1ptr) {dualRange = true;}
    tmin0 = fpValue(f0["Tmin"]);
    tmax0 = fpValue(f0["Tmax"]);
    tmin1 = tmax0;
    tmax1 = tmin1 + 0.0001;
    if (dualRange) {
      tmin1 = fpValue((*f1ptr)["Tmin"]);
      tmax1 = fpValue((*f1ptr)["Tmax"]);
    }


    doublereal p0 = OneAtm;
    if (f0.hasAttrib("P0")) {
      p0 = fpValue(f0["P0"]);
    }
    if (f0.hasAttrib("Pref")) {
      p0 = fpValue(f0["Pref"]);
    }

    vector_fp c0, c1;
    if (fabs(tmax0 - tmin1) < 0.01) {
      tmin = tmin0;
      tmid = tmax0;
      tmax = tmax1;
      getFloatArray(f0.child("floatArray"), c0, false);
      if (dualRange)
	getFloatArray(f1ptr->child("floatArray"), c1, false);
      else {
	c1.resize(7,0.0);
	copy(c0.begin(), c0.end(), c1.begin());
      }
    }
    else if (fabs(tmax1 - tmin0) < 0.01) {
      tmin = tmin1;
      tmid = tmax1;
      tmax = tmax0;
      getFloatArray(f1ptr->child("floatArray"), c0, false);
      getFloatArray(f0.child("floatArray"), c1, false);
    }
    else {
      throw CanteraError("installNasaThermo",
			 "non-continuous temperature ranges.");
    }
    array_fp c(15);
    c[0] = tmid;
    c[1] = c0[5];
    c[2] = c0[6];
    copy(c0.begin(), c0.begin()+5, c.begin() + 3);
    c[8] = c1[5];
    c[9] = c1[6];
    copy(c1.begin(), c1.begin()+5, c.begin() + 10);
    sp.install(speciesName, k, NASA, &c[0], tmin, tmax, p0);
  }
void SpeciesThermoFactory::installThermoForSpecies
(size_t k, const XML_Node& speciesNode, ThermoPhase* th_ptr,
 SpeciesThermo& spthermo, const XML_Node* phaseNode_ptr) const
{
    SpeciesThermoInterpType* stit = newSpeciesThermoInterpType(speciesNode);
    stit->validate(speciesNode["name"]);
    stit->setIndex(k);
    spthermo.install_STIT(stit);
}
void SpeciesThermoFactory::installThermoForSpecies
(size_t k, const XML_Node& speciesNode, ThermoPhase* th_ptr,
 SpeciesThermo& spthermo, const XML_Node* phaseNode_ptr) const
{
    shared_ptr<SpeciesThermoInterpType> stit(
        newSpeciesThermoInterpType(speciesNode.child("thermo")));
    stit->validate(speciesNode["name"]);
    spthermo.install_STIT(k, stit);
}
Esempio n. 5
0
  /** 
   * Install a Shomate polynomial thermodynamic property
   * parameterization for species k.
   */
  static void installShomateThermoFromXML(std::string speciesName, 
					  SpeciesThermo& sp, int k, 
					  const XML_Node* f0ptr, const XML_Node* f1ptr) {
    doublereal tmin0, tmax0, tmin1, tmax1, tmin, tmid, tmax;

    const XML_Node& f0 = *f0ptr;
    bool dualRange = false;
    if (f1ptr) {dualRange = true;}
    tmin0 = fpValue(f0["Tmin"]);
    tmax0 = fpValue(f0["Tmax"]);
    tmin1 = tmax0;
    tmax1 = tmin1 + 0.0001;
    if (dualRange) {
      tmin1 = fpValue((*f1ptr)["Tmin"]);
      tmax1 = fpValue((*f1ptr)["Tmax"]);
    }

    vector_fp c0, c1;
    if (fabs(tmax0 - tmin1) < 0.01) {
      tmin = tmin0;
      tmid = tmax0;
      tmax = tmax1;
      getFloatArray(f0.child("floatArray"), c0, false);
      if (dualRange)
	getFloatArray(f1ptr->child("floatArray"), c1, false);
      else {
	c1.resize(7,0.0);
	copy(c0.begin(), c0.begin()+7, c1.begin());
      }
    }
    else if (fabs(tmax1 - tmin0) < 0.01) {
      tmin = tmin1;
      tmid = tmax1;
      tmax = tmax0;
      getFloatArray(f1ptr->child("floatArray"), c0, false);
      getFloatArray(f0.child("floatArray"), c1, false);
    }
    else {
      throw CanteraError("installShomateThermoFromXML",
			 "non-continuous temperature ranges.");
    }
    array_fp c(15);
    c[0] = tmid;
    doublereal p0 = OneAtm;
    copy(c0.begin(), c0.begin()+7, c.begin() + 1);
    copy(c1.begin(), c1.begin()+7, c.begin() + 8);
    sp.install(speciesName, k, SHOMATE, &c[0], tmin, tmax, p0);
  }
Esempio n. 6
0
  /** 
   * Install a constant-cp thermodynamic property
   * parameterization for species k.
   */
  static void installSimpleThermoFromXML(std::string speciesName, 
					 SpeciesThermo& sp, int k, 
					 const XML_Node& f) {
    doublereal tmin, tmax;
    tmin = fpValue(f["Tmin"]);
    tmax = fpValue(f["Tmax"]);
    if (tmax == 0.0) tmax = 1.0e30;

    vector_fp c(4);
    c[0] = getFloat(f, "t0", "toSI");
    c[1] = getFloat(f, "h0", "toSI");
    c[2] = getFloat(f, "s0", "toSI");
    c[3] = getFloat(f, "cp0", "toSI");
    doublereal p0 = OneAtm;
    sp.install(speciesName, k, SIMPLE, &c[0], tmin, tmax, p0);
  }
Esempio n. 7
0
void installMu0ThermoFromXML(const std::string& speciesName, SpeciesThermo<ValAndDerivType>& sp, size_t k,
                             const XML_Node* Mu0Node_ptr)
{

    doublereal tmin, tmax;
    bool dimensionlessMu0Values = false;
    const XML_Node& Mu0Node = *Mu0Node_ptr;

    tmin = fpValue(Mu0Node["Tmin"]);
    tmax = fpValue(Mu0Node["Tmax"]);
    doublereal pref = fpValue(Mu0Node["Pref"]);

    doublereal h298 = 0.0;
    if (Mu0Node.hasChild("H298")) {
        h298 = getFloat(Mu0Node, "H298", "actEnergy");
    }

    size_t numPoints = 1;
    if (Mu0Node.hasChild("numPoints")) {
        numPoints = getInteger(Mu0Node, "numPoints");
    }

    vector_fp cValues(numPoints);
    const XML_Node* valNode_ptr = getByTitle(const_cast<XML_Node&>(Mu0Node), "Mu0Values");
    if (!valNode_ptr) {
        throw CanteraError("installMu0ThermoFromXML", "missing required while processing " + speciesName);
    }
    getFloatArray(*valNode_ptr, cValues, true, "actEnergy");
    /*
     * Check to see whether the Mu0's were input in a dimensionless
     * form. If they were, then the assumed temperature needs to be
     * adjusted from the assumed T = 273.15
     */
    string uuu = (*valNode_ptr)["units"];
    if (uuu == "Dimensionless") {
        dimensionlessMu0Values = true;
    }
    size_t ns = cValues.size();
    if (ns != numPoints) {
        throw CanteraError("installMu0ThermoFromXML", "numPoints inconsistent while processing " + speciesName);
    }

    vector_fp cTemperatures(numPoints);
    const XML_Node* tempNode_ptr = getByTitle(const_cast<XML_Node&>(Mu0Node), "Mu0Temperatures");
    if (!tempNode_ptr) {
        throw CanteraError("installMu0ThermoFromXML", "missing required while processing + " + speciesName);
    }
    getFloatArray(*tempNode_ptr, cTemperatures, false);
    ns = cTemperatures.size();
    if (ns != numPoints) {
        throw CanteraError("installMu0ThermoFromXML", "numPoints inconsistent while processing " + speciesName);
    }

    /*
     * Fix up dimensionless Mu0 values if input
     */
    if (dimensionlessMu0Values) {
        for (size_t i = 0; i < numPoints; i++) {
            cValues[i] *= cTemperatures[i] / 273.15;
        }
    }

    vector_fp c(2 + 2 * numPoints);

    c[0] = static_cast<double>(numPoints);
    c[1] = h298;
    for (size_t i = 0; i < numPoints; i++) {
        c[2 + i * 2] = cTemperatures[i];
        c[2 + i * 2 + 1] = cValues[i];
    }

    sp.install(speciesName, k, MU0_INTERP, &c[0], tmin, tmax, pref);
}
Esempio n. 8
0
  static void installMinEQ3asShomateThermoFromXML(std::string speciesName, 
						  ThermoPhase *th_ptr,
						  SpeciesThermo& sp, int k, 
						  const XML_Node* MinEQ3node) {

    array_fp coef(15), c0(7, 0.0);
    std::string astring = (*MinEQ3node)["Tmin"];
    doublereal tmin0 = strSItoDbl(astring);
    astring = (*MinEQ3node)["Tmax"];
    doublereal tmax0 = strSItoDbl(astring);
    astring = (*MinEQ3node)["Pref"];
    doublereal p0 = strSItoDbl(astring);
 
    doublereal deltaG_formation_pr_tr =
      getFloatDefaultUnits(*MinEQ3node, "DG0_f_Pr_Tr", "cal/gmol", "actEnergy");
    doublereal deltaH_formation_pr_tr =
      getFloatDefaultUnits(*MinEQ3node, "DH0_f_Pr_Tr", "cal/gmol", "actEnergy");
    doublereal Entrop_pr_tr = getFloatDefaultUnits(*MinEQ3node, "S0_Pr_Tr", "cal/gmol/K");
    doublereal a = getFloatDefaultUnits(*MinEQ3node, "a", "cal/gmol/K");
    doublereal b = getFloatDefaultUnits(*MinEQ3node, "b", "cal/gmol/K2");
    doublereal c = getFloatDefaultUnits(*MinEQ3node, "c", "cal-K/gmol");
    doublereal dg = deltaG_formation_pr_tr * 4.184 * 1.0E3;
    doublereal fac =  convertDGFormation(k, th_ptr);
    doublereal Mu0_tr_pr = fac + dg;
    doublereal e = Entrop_pr_tr * 1.0E3 * 4.184;
    doublereal Hcalc = Mu0_tr_pr + 298.15 * e;
    doublereal DHjmol = deltaH_formation_pr_tr * 1.0E3 * 4.184;

    // If the discrepency is greater than 100 cal gmol-1, print
    // an error and exit.
    if (fabs(Hcalc -DHjmol) > 10.* 1.0E6 * 4.184) {
      throw CanteraError("installMinEQ3asShomateThermoFromXML()",
                         "DHjmol is not consistent with G and S" +
                         fp2str(Hcalc) + " vs " + fp2str(DHjmol));
    }

    /*
     * Now calculate the shomate polynomials
     *
     * Cp first
     * 
     *  Shomate: (Joules / gmol / K)
     *    Cp = As + Bs * t + Cs * t*t + Ds * t*t*t + Es / (t*t)
     *     where
     *          t = temperature(Kelvin) / 1000
     */
    double As = a * 4.184;
    double Bs = b * 4.184 * 1000.;
    double Cs = 0.0;
    double Ds = 0.0;
    double Es = c * 4.184 / (1.0E6);
    
    double t = 298.15 / 1000.;
    double H298smFs = As * t + Bs * t * t / 2.0 - Es / t; 
    
    double HcalcS = Hcalc / 1.0E6;
    double Fs = HcalcS - H298smFs;

    double S298smGs = As * log(t) + Bs * t - Es/(2.0*t*t);
    double ScalcS = e / 1.0E3;
    double Gs = ScalcS - S298smGs;

    c0[0] = As;
    c0[1] = Bs;
    c0[2] = Cs;
    c0[3] = Ds;
    c0[4] = Es;
    c0[5] = Fs;
    c0[6] = Gs;

    coef[0] = tmax0 - 0.001;
    copy(c0.begin(), c0.begin()+7, coef.begin() + 1);
    copy(c0.begin(), c0.begin()+7, coef.begin() + 8);
    sp.install(speciesName, k, SHOMATE, &coef[0], tmin0, tmax0, p0);
  }
Esempio n. 9
0
  /** 
   * Install a NASA polynomial thermodynamic property
   * parameterization for species k into a SpeciesThermo instance.
   * This is called by method installThermoForSpecies if a NASA
   * block is found in the XML input.
   */
  static void installNasaThermoFromXML(std::string speciesName,
				       SpeciesThermo& sp, int k, 
				       const XML_Node* f0ptr, const XML_Node* f1ptr) {
    doublereal tmin0, tmax0, tmin1, tmax1, tmin, tmid, tmax;

    const XML_Node& f0 = *f0ptr;

    // default to a single temperature range
    bool dualRange = false;

    // but if f1ptr is suppled, then it is a two-range
    // parameterization
    if (f1ptr) {dualRange = true;}

    tmin0 = fpValue(f0["Tmin"]);
    tmax0 = fpValue(f0["Tmax"]);

    doublereal p0 = OneAtm;
    if (f0.hasAttrib("P0")) {
      p0 = fpValue(f0["P0"]);
    }
    if (f0.hasAttrib("Pref")) {
      p0 = fpValue(f0["Pref"]);
    }
    p0 = OneAtm;

    tmin1 = tmax0;
    tmax1 = tmin1 + 0.0001;
    if (dualRange) {
      tmin1 = fpValue((*f1ptr)["Tmin"]);
      tmax1 = fpValue((*f1ptr)["Tmax"]);
    }

    vector_fp c0, c1;
    if (fabs(tmax0 - tmin1) < 0.01) {
      // f0 has the lower T data, and f1 the higher T data
      tmin = tmin0;
      tmid = tmax0;
      tmax = tmax1;
      getFloatArray(f0.child("floatArray"), c0, false);
      if (dualRange)
	getFloatArray(f1ptr->child("floatArray"), c1, false);
      else {
	// if there is no higher range data, then copy c0 to c1.
	c1.resize(7,0.0);
	copy(c0.begin(), c0.end(), c1.begin());
      }
    }
    else if (fabs(tmax1 - tmin0) < 0.01) {
      // f1 has the lower T data, and f0 the higher T data
      tmin = tmin1;
      tmid = tmax1;
      tmax = tmax0;
      getFloatArray(f1ptr->child("floatArray"), c0, false);
      getFloatArray(f0.child("floatArray"), c1, false);
    }
    else {
      throw CanteraError("installNasaThermo",
			 "non-continuous temperature ranges.");
    }

    // The NasaThermo species property manager expects the
    // coefficients in a different order, so rearrange them.
    array_fp c(15);
    c[0] = tmid;
   
    c[1] = c0[5];
    c[2] = c0[6];
    copy(c0.begin(), c0.begin()+5, c.begin() + 3);
    c[8] = c1[5];
    c[9] = c1[6];
    copy(c1.begin(), c1.begin()+5, c.begin() + 10);
    sp.install(speciesName, k, NASA, &c[0], tmin, tmax, p0);
  }