Пример #1
0
// In this routine we must be sure to only find the water branch of the
// curve and not the gas branch
void PDSS_Water::setPressure(doublereal p) {
    doublereal T = m_temp;
    doublereal dens = m_dens;
    int waterState = WATER_LIQUID;
    if (T > m_sub->Tcrit()) {
        waterState = WATER_SUPERCRIT;
    }


#ifdef DEBUG_HKM
    //printf("waterPDSS: set pres = %g t = %g, waterState = %d\n",
    //      p, T, waterState);
#endif
    doublereal dd = m_sub->density(T, p, waterState, dens);
    if (dd <= 0.0) {
        std::string stateString = "T = " +
                                  fp2str(T) + " K and p = " + fp2str(p) + " Pa";
        throw CanteraError("PDSS_Water:setPressure()",
                           "Failed to set water SS state: " + stateString);
    }
    m_dens = dd;
    m_pres = p;

    // We are only putting the phase check here because of speed considerations.
    m_iState = m_sub->phaseState(true);
    if (! m_allowGasPhase) {
        if (m_iState != WATER_SUPERCRIT && m_iState != WATER_LIQUID && m_iState != WATER_UNSTABLELIQUID) {
            throw CanteraError("PDSS_Water::setPressure",
                               "Water State isn't liquid or crit");
        }
    }
}
Пример #2
0
void WaterPropsIAPWS::corr1(doublereal temperature, doublereal pressure,
    doublereal& densLiq, doublereal& densGas, doublereal& pcorr)
{

    densLiq = density(temperature, pressure, WATER_LIQUID, densLiq);
    if (densLiq <= 0.0) {
        throw CanteraError("WaterPropsIAPWS::corr1",
                           "Error occurred trying to find liquid density at (T,P) = "
                           + fp2str(temperature) + "  " + fp2str(pressure));
    }
    setState_TR(temperature, densLiq);
    doublereal prL = m_phi->phiR();

    densGas = density(temperature, pressure, WATER_GAS, densGas);
    if (densGas <= 0.0) {
        throw CanteraError("WaterPropsIAPWS::corr1",
                           "Error occurred trying to find gas density at (T,P) = "
                           + fp2str(temperature) + "  " + fp2str(pressure));
    }
    setState_TR(temperature, densGas);
    doublereal prG = m_phi->phiR();

    doublereal rhs = (prL - prG) + log(densLiq/densGas);
    rhs /= (1.0/densGas - 1.0/densLiq);

    pcorr = rhs * Rgas * temperature / M_water;
}
Пример #3
0
  double WaterProps::isothermalCompressibility_IAPWS(double temp, double press) {
    double dens = m_waterIAPWS->density(temp, press, WATER_LIQUID);
    if (dens < 0.0) {
      throw CanteraError("WaterProps::isothermalCompressibility_IAPWS", 
			 "Unable to solve for density at T = " + fp2str(temp) + " and P = " + fp2str(press));
    }
    double kappa = m_waterIAPWS->isothermalCompressibility();
    return kappa;
  }
Пример #4
0
  double WaterProps::coeffThermalExp_IAPWS(double temp, double press) {
    double dens = m_waterIAPWS->density(temp, press, WATER_LIQUID);
    if (dens < 0.0) {
      throw CanteraError("WaterProps::coeffThermalExp_IAPWS", 
			 "Unable to solve for density at T = " + fp2str(temp) + " and P = " + fp2str(press));
    }
    double cte = m_waterIAPWS->coeffThermExp();
    return cte;
  }
Пример #5
0
  /**
   * For reactions that transfer charge across a potential difference,
   * the activation energies are modified by the potential difference.
   * (see, for example, ...). This method applies this correction.
   */
  void InterfaceKinetics::applyButlerVolmerCorrection(doublereal* kf) {
    int i;

    int n, nsp, k, ik=0;
    doublereal rt = GasConstant*thermo(0).temperature();
    doublereal rrt = 1.0/rt;
    int np = nPhases();

    // compute the electrical potential energy of each species
    for (n = 0; n < np; n++) {
      nsp = thermo(n).nSpecies();
      for (k = 0; k < nsp; k++) {
	m_pot[ik] = Faraday*thermo(n).charge(k)*m_phi[n];
	ik++;
      }
    }

    // Compute the change in electrical potential energy for each
    // reaction. This will only be non-zero if a potential
    // difference is present.
    m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_pot), 
				 DATA_PTR(m_rwork));

    // Modify the reaction rates. Only modify those with a
    // non-zero activation energy, and do not decrease the
    // activation energy below zero.
    doublereal eamod;
#ifdef DEBUG_MODE
    double ea;
#endif
    int nct = m_beta.size();
    int irxn;
    for (i = 0; i < nct; i++) {
      irxn = m_ctrxn[i];
      eamod = m_beta[i]*m_rwork[irxn];
      if (eamod != 0.0 && m_E[irxn] != 0.0) {
#ifdef DEBUG_MODE
	ea = GasConstant * m_E[irxn];
	if (eamod + ea < 0.0) {
	  writelog("Warning: act energy mod too large!\n");
	  writelog("  Delta phi = "+fp2str(m_rwork[irxn]/Faraday)+"\n");
	  writelog("  Delta Ea = "+fp2str(eamod)+"\n");
	  writelog("  Ea = "+fp2str(ea)+"\n");
	  for (n = 0; n < np; n++) {
	    writelog("Phase "+int2str(n)+": phi = "
		     +fp2str(m_phi[n])+"\n");
	  }
	}
#endif
	kf[irxn] *= exp(-eamod*rrt);
      }
    }
  }
Пример #6
0
void vcs_VolPhase::setMoleFractionsState(const double totalMoles,
        const double* const moleFractions,
        const int vcsStateStatus)
{

    if (totalMoles != 0.0) {
        // There are other ways to set the mole fractions when VCS_STATECALC
        // is set to a normal settting.
        if (vcsStateStatus != VCS_STATECALC_TMP) {
            throw CanteraError("vcs_VolPhase::setMolesFractionsState",
                               "inappropriate usage");
        }
        m_UpToDate = false;
        m_vcsStateStatus = VCS_STATECALC_TMP;
        if (m_existence == VCS_PHASE_EXIST_ZEROEDPHASE) {
            throw CanteraError("vcs_VolPhase::setMolesFractionsState",
                               "inappropriate usage");
        }
        m_existence = VCS_PHASE_EXIST_YES;
    } else {
        m_UpToDate = true;
        m_vcsStateStatus = vcsStateStatus;
        m_existence = std::min(m_existence, VCS_PHASE_EXIST_NO);
    }
    double fractotal = 1.0;
    v_totalMoles = totalMoles;
    if (m_totalMolesInert > 0.0) {
        if (m_totalMolesInert > v_totalMoles) {
            throw CanteraError("vcs_VolPhase::setMolesFractionsState",
                 "inerts greater than total: " + fp2str(v_totalMoles) + " " +
                 fp2str(m_totalMolesInert));
        }
        fractotal = 1.0 - m_totalMolesInert/v_totalMoles;
    }
    double sum = 0.0;
    for (size_t k = 0; k < m_numSpecies; k++) {
        Xmol_[k] = moleFractions[k];
        sum += moleFractions[k];
    }
    if (sum == 0.0) {
        throw CanteraError("vcs_VolPhase::setMolesFractionsState",
                           "inappropriate usage");
    }
    if (sum  != fractotal) {
        for (size_t k = 0; k < m_numSpecies; k++) {
            Xmol_[k] *= (fractotal /sum);
        }
    }
    _updateMoleFractionDependencies();

}
Пример #7
0
 /*!
  * @param c Vector of five doubles: The doubles are the parameters,
  *          a, b, c, d, and e of the SRI parameterization
  */
 virtual void init(const vector_fp& c) {
     if (c[2] < 0.0) {
         throw CanteraError("SRI5::init()",
                            "m_c parameter is less than zero: " + fp2str(c[2]));
     }
     if (c[3] < 0.0) {
         throw CanteraError("SRI5::init()",
                            "m_d parameter is less than zero: " + fp2str(c[3]));
     }
     m_a = c[0];
     m_b = c[1];
     m_c = c[2];
     m_d = c[3];
     m_e = c[4];
 }
Пример #8
0
//=================================================================================================
bool SimpleTransport::update_T()
{
    doublereal t = m_thermo->temperature();
    if (t == m_temp) {
        return false;
    }
    if (t < 0.0) {
        throw CanteraError("SimpleTransport::update_T",
                           "negative temperature "+fp2str(t));
    }

    // Compute various functions of temperature
    m_temp = t;

    // temperature has changed, so polynomial temperature
    // interpolations will need to be reevaluated.
    // Set all of these flags to false
    m_visc_mix_ok = false;
    m_visc_temp_ok  = false;

    m_cond_temp_ok = false;
    m_cond_mix_ok = false;

    m_diff_mix_ok = false;
    m_diff_temp_ok = false;

    return true;
}
Пример #9
0
string PlusConstant1::write(const std::string& arg) const
{
    if (m_c == 0.0) {
        return m_f1->write(arg);
    }
    return m_f1->write(arg) + " + " + fp2str(m_c);
}
Пример #10
0
void addFloatArray(XML_Node& node, const std::string& title, const size_t n,
                   const doublereal* const vals, const std::string& units,
                   const std::string& type,
                   const doublereal minval, const doublereal maxval)
{
    std::string v = "";
    for (size_t i = 0; i < n; i++) {
        v += fp2str(vals[i],FP_Format);
        if (i == n-1) {
            v += "\n";
        } else if (i > 0 && (i+1) % 3 == 0) {
            v += ",\n";
        } else {
            v += ", ";
        }
    }
    XML_Node& f = node.addChild("floatArray",v);
    f.addAttribute("title",title);
    if (type != "") {
        f.addAttribute("type",type);
    }
    f.addAttribute("size", double(n));
    if (units != "") {
        f.addAttribute("units",units);
    }
    if (minval != Undef) {
        f.addAttribute("min",minval);
    }
    if (maxval != Undef) {
        f.addAttribute("max",maxval);
    }
}
Пример #11
0
  /*
   *  This is called whenever a transport property is
   *  requested.  
   *  The first task is to check whether the temperature has changed
   *  since the last call to update_temp().
   *  If it hasn't then an immediate return is carried out.
   *
   *     @internal
   */ 
  void LiquidTransport::update_temp()
  {
    // First make a decision about whether we need to recalculate
    doublereal t = m_thermo->temperature();
    if (t == m_temp) return;

    // Next do a reality check on temperature value
    if (t < 0.0) {
      throw CanteraError("LiquidTransport::update_temp()",
			 "negative temperature "+fp2str(t));
    }

    // Compute various direct functions of temperature
    m_temp = t;
    m_logt = log(m_temp);
    m_kbt = Boltzmann * m_temp;

    // temperature has changed so temp flags are flipped
    m_visc_temp_ok  = false;
    m_diff_temp_ok  = false;

    // temperature has changed, so polynomial temperature 
    // interpolations will need to be reevaluated.
    // This means that many concentration 
    m_visc_conc_ok  = false;
    m_cond_temp_ok  = false;

    // Mixture stuff needs to be evaluated 
    m_visc_mix_ok = false;
    m_diff_mix_ok = false;
    //  m_cond_mix_ok = false; (don't need it because a lower lvl flag is set    

  }                 
Пример #12
0
  /*
   *  @internal This is called whenever a transport property is
   *  requested from ThermoSubstance if the temperature has changed
   *  since the last call to update_T.
   */ 
  void MixTransport::update_T() 
  {
    doublereal t = m_thermo->temperature();
    if (t == m_temp) return;
    if (t < 0.0) {
      throw CanteraError("MixTransport::update_T",
			 "negative temperature "+fp2str(t));
    }
    m_temp = t;
    m_logt = log(m_temp);
    m_kbt = Boltzmann * m_temp;
    m_sqrt_t = sqrt(m_temp);
    m_t14 = sqrt(m_sqrt_t);
    m_t32 = m_temp * m_sqrt_t;
    m_sqrt_kbt = sqrt(Boltzmann*m_temp);

    // compute powers of log(T)
    m_polytempvec[0] = 1.0;
    m_polytempvec[1] = m_logt;
    m_polytempvec[2] = m_logt*m_logt;
    m_polytempvec[3] = m_logt*m_logt*m_logt;
    m_polytempvec[4] = m_logt*m_logt*m_logt*m_logt;

    // temperature has changed, so polynomial fits will need to be
    // redone.
    m_viscmix_ok = false;
    m_spvisc_ok = false;
    m_viscwt_ok = false;
    m_spcond_ok = false;
    m_bindiff_ok = false;
    m_condmix_ok = false;                 
  }                 
Пример #13
0
  void LatticePhase::_updateThermo() const {
    doublereal tnow = temperature();
    if (fabs(molarDensity() - m_molar_density)/m_molar_density > 0.0001) {
      throw CanteraError("_updateThermo","molar density changed from "
			 +fp2str(m_molar_density)+" to "+fp2str(molarDensity()));
    }
    if (m_tlast != tnow) {
      m_spthermo->update(tnow, &m_cp0_R[0], &m_h0_RT[0], 
			 &m_s0_R[0]);
      m_tlast = tnow;
      for (size_t k = 0; k < m_kk; k++) {
	m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
      }
      m_tlast = tnow;
    }
  }
Пример #14
0
std::string Exp1::write(const std::string& arg) const
{
    string c  = "";
    if (m_c != 1.0) {
        c = fp2str(m_c);
    }
    return "\\exp("+c+arg+")";
}
Пример #15
0
  double GibbsExcessVPSSTP::checkMFSum(const doublereal * const x) const {
    doublereal norm = accumulate(x, x + m_kk, 0.0);
    if (fabs(norm - 1.0) > 1.0E-9) {
      throw CanteraError("GibbsExcessVPSSTP::checkMFSum",
			 "(MF sum - 1) exceeded tolerance of 1.0E-9:" + fp2str(norm));
    }
    return norm;
  }
Пример #16
0
string Sin1::write(const string& arg) const
{
    string c  = "";
    if (m_c != 1.0) {
        c = fp2str(m_c);
    }
    return "\\sin(" + c + arg + ")";
}
Пример #17
0
  void SingleSpeciesTP::setState_UV(doublereal u, doublereal v, 
				    doublereal tol) {
    doublereal dt;
    setDensity(1.0/v);
    for (int n = 0; n < 50; n++) {
      dt = (u - intEnergy_mass())/cv_mass();
      if (dt > 100.0) dt = 100.0;
      else if (dt < -100.0) dt = -100.0;
      setTemperature(temperature() + dt);
      if (fabs(dt) < tol) {
	return;
      }
    }
    throw CanteraError("setState_UV",
		       "no convergence. dt = " + fp2str(dt)+"\n"
		       +"u = "+fp2str(u)+" v = "+fp2str(v)+"\n");
  }
Пример #18
0
void vcs_VolPhase::setMolesFromVCSCheck(const int vcsStateStatus,
                                        const double* molesSpeciesVCS,
                                        const double* const TPhMoles)
{
    setMolesFromVCS(vcsStateStatus, molesSpeciesVCS);
    /*
     * Check for consistency with TPhMoles[]
     */
    double Tcheck = TPhMoles[VP_ID_];
    if (Tcheck != v_totalMoles) {
        if (vcs_doubleEqual(Tcheck, v_totalMoles)) {
            Tcheck = v_totalMoles;
        } else {
            throw CanteraError("vcs_VolPhase::setMolesFromVCSCheck",
                  "We have a consistency problem: " + fp2str(Tcheck) + " " +
                  fp2str(v_totalMoles));
        }
    }
}
Пример #19
0
void SingleSpeciesTP::setState_UV(doublereal u, doublereal v,
                                  doublereal tol)
{
    doublereal dt;
    if (v == 0.0) {
        setDensity(1.0E100);
    } else {
        setDensity(1.0/v);
    }
    for (int n = 0; n < 50; n++) {
        dt = clip((u - intEnergy_mass())/cv_mass(), -100.0, 100.0);
        setTemperature(temperature() + dt);
        if (fabs(dt) < tol) {
            return;
        }
    }
    throw CanteraError("setState_UV",
                       "no convergence. dt = " + fp2str(dt)+"\n"
                       +"u = "+fp2str(u)+" v = "+fp2str(v)+"\n");
}
Пример #20
0
double HFC134a::ldens()
{
    if ((T < Tmn) || (T > Tc)) {
        throw TPX_Error("HFC134a::ldens",
                        "Temperature out of range. T = " + fp2str(T));
    }
    double x1 = T/Tc;
    double x2 = 1.0 - x1;
    return 518.2 + 884.13*pow(x2,1.0/3.0) + 485.84*pow(x2,2.0/3.0)
           + 193.29*pow(x2,10.0/3.0);
}
Пример #21
0
double hydrogen::Psat()
{
    double x = (1.0 - Tt/T)/(1.0 - Tt/Tc);
    double result;
    if ((T < Tmn) || (T > Tc)) {
        throw TPX_Error("hydrogen::Psat",
                        "Temperature out of range. T = " + fp2str(T));
    }
    result = Fhydro[0]*x + Fhydro[1]*x*x + Fhydro[2]*x*x*x +
             Fhydro[3]*x*pow(1-x, alpha);
    return exp(result)*Pt;
}
Пример #22
0
void vcs_VolPhase::setTotalMoles(const double totalMols)
{
    v_totalMoles = totalMols;
    if (m_totalMolesInert > 0.0) {
        m_existence = VCS_PHASE_EXIST_ALWAYS;
        AssertThrowMsg(totalMols >= m_totalMolesInert,
                       "vcs_VolPhase::setTotalMoles",
                       "totalMoles less than inert moles: " +
                       fp2str(totalMols) + " " + fp2str(m_totalMolesInert));
    } else {
        if (m_singleSpecies && (m_phiVarIndex == 0)) {
            m_existence =  VCS_PHASE_EXIST_ALWAYS;
        } else {
            if (totalMols > 0.0) {
                m_existence = VCS_PHASE_EXIST_YES;
            } else {
                m_existence = VCS_PHASE_EXIST_NO;
            }
        }
    }
}
Пример #23
0
double HFC134a::Psat()
{
    if ((T < Tmn) || (T > Tc)) {
        throw TPX_Error("HFC134a::Psat",
                        "Temperature out of range. T = " + fp2str(T));
    }
    double x1 = T/Tc;
    double x2 = 1.0 - x1;
    double f = -7.686556*x2 + 2.311791*pow(x2,1.5)
               - 2.039554*x2*x2 - 3.583758*pow(x2,4);
    return Pc*exp(f/x1);
}
Пример #24
0
double oxygen::ldens()
{
    double xx=1-T/Tc, sum=0;
    if ((T < Tmn) || (T > Tc)) {
        throw TPX_Error("oxygen::ldens",
                        "Temperature out of range. T = " + fp2str(T));
    }
    for (int i=0; i<=5; i++) {
        sum+=Doxy[i]*pow(xx,double(i)/3.0);
    }
    return sum;
}
Пример #25
0
  /*
   * Check the continuity of properties at the midpoint
   * temperature.
   */
  void NasaThermo::checkContinuity(std::string name, double tmid, const doublereal* clow,
				   doublereal* chigh) {
    // heat capacity
    doublereal cplow = poly4(tmid, clow);
    doublereal cphigh = poly4(tmid, chigh);
    doublereal delta = cplow - cphigh;
    if (fabs(delta/(fabs(cplow)+1.0E-4)) > 0.001) {
      writelog("\n\n**** WARNING ****\nFor species "+name+
	       ", discontinuity in cp/R detected at Tmid = "
	       +fp2str(tmid)+"\n");
      writelog("\tValue computed using low-temperature polynomial:  "
	       +fp2str(cplow)+".\n");
      writelog("\tValue computed using high-temperature polynomial: "
	       +fp2str(cphigh)+".\n");
    }

    // enthalpy
    doublereal hrtlow = enthalpy_RT(tmid, clow);
    doublereal hrthigh = enthalpy_RT(tmid, chigh);
    delta = hrtlow - hrthigh;
    if (fabs(delta/(fabs(hrtlow)+cplow*tmid)) > 0.001) {
      writelog("\n\n**** WARNING ****\nFor species "+name+
	       ", discontinuity in h/RT detected at Tmid = "
	       +fp2str(tmid)+"\n");
      writelog("\tValue computed using low-temperature polynomial:  "
	       +fp2str(hrtlow)+".\n");
      writelog("\tValue computed using high-temperature polynomial: "
	       +fp2str(hrthigh)+".\n");
    }

    // entropy
    doublereal srlow = entropy_R(tmid, clow);
    doublereal srhigh = entropy_R(tmid, chigh);
    delta = srlow - srhigh;
    if (fabs(delta/(fabs(srlow)+cplow)) > 0.001) {
      writelog("\n\n**** WARNING ****\nFor species "+name+
	       ", discontinuity in s/R detected at Tmid = "
	       +fp2str(tmid)+"\n");
      writelog("\tValue computed using low-temperature polynomial:  "
	       +fp2str(srlow)+".\n");
      writelog("\tValue computed using high-temperature polynomial: "
	       +fp2str(srhigh)+".\n");
    }
  }
Пример #26
0
void Plog::validate(const ReactionData& rdata)
{
    double T[] = {200.0, 500.0, 1000.0, 2000.0, 5000.0, 10000.0};
    for (pressureIter iter = pressures_.begin();
            iter->first < 1000;
            iter++) {
        update_C(&iter->first);
        for (size_t i=0; i < 6; i++) {
            double k = updateRC(log(T[i]), 1.0/T[i]);
            if (!(k >= 0)) {
                // k is NaN. Increment the iterator so that the error
                // message will correctly indicate that the problematic rate
                // expression is at the higher of the adjacent pressures.
                throw CanteraError("Plog::validate",
                        "Invalid rate coefficient for reaction #" +
                        int2str(rdata.number) + ":\n" + rdata.equation + "\n" +
                        "at P = " + fp2str(std::exp((++iter)->first)) +
                        ", T = " + fp2str(T[i]));
            }
        }
    }
}
Пример #27
0
double water::ldens()
{
    double sum=0;
    int i;
    if ((T < Tmn) || (T >= Tc)) {
        throw TPX_Error("water::ldens",
                        "Temperature out of range. T = " + fp2str(T));
    }
    for (i=0; i<8; i++) {
        sum+=D[i]*pow(1.0 - T/Tc, double(i+1)/3.0);
    }
    double density = Roc*(1+sum);
    return density;
}
Пример #28
0
void SingleSpeciesTP::setState_SP(doublereal s, doublereal p,
                                  doublereal tol)
{
    doublereal dt;
    setPressure(p);
    for (int n = 0; n < 50; n++) {
        dt = clip((s - entropy_mass())*temperature()/cp_mass(), -100.0, 100.0);
        setState_TP(temperature() + dt, p);
        if (fabs(dt) < tol) {
            return;
        }
    }
    throw CanteraError("setState_SP","no convergence. dt = " + fp2str(dt));
}
Пример #29
0
double hydrogen::ldens()
{
    if ((T < Tmn) || (T > Tc)) {
        throw TPX_Error("hydrogen::ldens",
                        "Temperature out of range. T = " + fp2str(T));
    }
    double x=1-T/Tc;
    double sum;
    int i;
    for (i=1, sum=0; i<=6; i++) {
        sum+=Dhydro[i]*pow(x, 1+double(i-1)/3.0);
    }
    return sum+Roc+Dhydro[0]*pow(x,alpha1);
}
Пример #30
0
double water::Psat()
{
    double log, sum=0,P;
    if ((T < Tmn) || (T > Tc)) {
        throw TPX_Error("water::Psat",
                        "Temperature out of range. T = " + fp2str(T));
    }
    for (int i=1; i<=8; i++) {
        sum += F[i-1]*pow(aww*(T-Tp),double(i-1));    // DGG mod
    }
    log = (Tc/T-1)*sum;
    P=exp(log)*Pc;
    return P;
}