void MixtureFugacityTP::setStateFromXML(const XML_Node& state)
{
    int doTP = 0;
    string comp = ctml::getChildValue(state,"moleFractions");
    if (comp != "") {
        // not overloaded in current object -> phase state is not calculated.
        setMoleFractionsByName(comp);
        doTP = 1;
    } else {
        comp = ctml::getChildValue(state,"massFractions");
        if (comp != "") {
            // not overloaded in current object -> phase state is not calculated.
            setMassFractionsByName(comp);
            doTP = 1;
        }
    }
    double t = temperature();
    if (state.hasChild("temperature")) {
        t = ctml::getFloat(state, "temperature", "temperature");
        doTP = 1;
    }
    if (state.hasChild("pressure")) {
        double p = ctml::getFloat(state, "pressure", "pressure");
        setState_TP(t, p);
    } else if (state.hasChild("density")) {
        double rho = ctml::getFloat(state, "density", "density");
        setState_TR(t, rho);
    } else if (doTP) {
        double rho = Phase::density();
        setState_TR(t, rho);
    }
}
Пример #2
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));
}
Пример #3
0
  void SingleSpeciesTP::setState_HP(doublereal h, doublereal p, 
				    doublereal tol) {
    doublereal dt;
    setPressure(p);
    for (int n = 0; n < 50; n++) {
      dt = (h - enthalpy_mass())/cp_mass();
      if (dt > 100.0) dt = 100.0;
      else if (dt < -100.0) dt = -100.0; 
      setState_TP(temperature() + dt, p);
      if (fabs(dt) < tol) {
	return;
      }
    }
    throw CanteraError("setState_HP","no convergence. dt = " + fp2str(dt));
  }
Пример #4
0
void vcs_VolPhase::setPtrThermoPhase(ThermoPhase* tp_ptr)
{
    TP_ptr = tp_ptr;
    Temp_ = TP_ptr->temperature();
    Pres_ = TP_ptr->pressure();
    setState_TP(Temp_, Pres_);
    p_VCS_UnitsFormat = VCS_UNITS_MKS;
    m_phi = TP_ptr->electricPotential();
    size_t nsp = TP_ptr->nSpecies();
    size_t nelem = TP_ptr->nElements();
    if (nsp !=  m_numSpecies) {
        if (m_numSpecies != 0) {
            plogf("Warning Nsp != NVolSpeces: %d %d \n", nsp, m_numSpecies);
        }
        resize(VP_ID_, nsp, nelem, PhaseName.c_str());
    }
    TP_ptr->getMoleFractions(VCS_DATA_PTR(Xmol_));
    creationMoleNumbers_ = Xmol_;
    _updateMoleFractionDependencies();

    /*
     *  figure out ideal solution tag
     */
    if (nsp == 1) {
        m_isIdealSoln = true;
    } else {
        int eos = TP_ptr->eosType();
        switch (eos) {
        case cIdealGas:
        case cIncompressible:
        case cSurf:
        case cMetal:
        case cStoichSubstance:
        case cSemiconductor:
        case cLatticeSolid:
        case cLattice:
        case cEdge:
        case cIdealSolidSolnPhase:
            m_isIdealSoln = true;
            break;
        default:
            m_isIdealSoln = false;
        };
    }
}
Пример #5
0
void StoichSubstance::initThermo()
{
    ThermoPhase::initThermo();
    if (m_kk > 1) {
        throw CanteraError("initThermo",
                           "stoichiometric substances may only contain one species.");
    }
    doublereal tmin = m_spthermo->minTemp();
    doublereal tmax = m_spthermo->maxTemp();
    m_p0 = refPressure();

    m_h0_RT.resize(m_kk);
    m_cp0_R.resize(m_kk);
    m_s0_R.resize(m_kk);

    // Put the object on a valid temperature point.
    double tnow = 300.;
    if (tnow > tmin && tnow < tmax) {

    } else {
        tnow = 0.1 * (9 * tmin + tmax);
    }
    setState_TP(tnow, m_p0);
}
void ThermoPhase::setState_TPX(doublereal t, doublereal p, const compositionMap& x)
{
    setMoleFractionsByName(x);
    setState_TP(t,p);
}
void ThermoPhase::setState_TPX(doublereal t, doublereal p, const doublereal* x)
{
    setMoleFractions(x);
    setState_TP(t,p);
}
Пример #8
0
/*
 * Set the temperature (K), pressure (Pa), and molalities.
 */
void MolalityVPSSTP::setState_TPM(doublereal t, doublereal p, compositionMap& m)
{
    setMolalitiesByName(m);
    setState_TP(t, p);
}
void ThermoPhase::setState_TPY(doublereal t, doublereal p, const compositionMap& y)
{
    setMassFractionsByName(y);
    setState_TP(t,p);
}
Пример #10
0
 void GibbsExcessVPSSTP::setState_TPX(doublereal t, doublereal p, const doublereal* x) {
   State::setMoleFractions(x);
   getMoleFractions(DATA_PTR(moleFractions_));
   setState_TP(t, p);
 }
Пример #11
0
 /*
  * Set the pressure at constant temperature. Units: Pa.
  * This method sets a constant within the object.
  * The mass density is not a function of pressure.
  */
 void GibbsExcessVPSSTP::setPressure(doublereal p) {
   setState_TP(temperature(), p);
 }
doublereal MixtureFugacityTP::calculatePsat(doublereal TKelvin, doublereal& molarVolGas,
        doublereal& molarVolLiquid)
{
    /*
     *  The algorithm for this routine has undergone quite a bit of work. It probably needs more work.
     *  However, it seems now to be fairly robust.
     *  The key requirement is to find an initial pressure where both the liquid and the gas exist. This
     *  is not as easy as it sounds, and it gets exceedingly hard as the critical temperature is approached
     *  from below.
     *  Once we have this initial state, then we seek to equilibrate the gibbs free energies of the
     *  gas and liquid and use the formula
     *
     *    dp = VdG
     *
     *  to create an update condition for deltaP using
     *
     *      - (Gliq  - Ggas) = (Vliq - Vgas) (deltaP)
     *
     *  @TODO Suggestions for the future would be to switch it to an algorithm that uses the gas molar volume
     *        and the liquid molar volumes as the fundamental unknowns.
     */

    // we need this because this is a non-const routine that is public
    setTemperature(TKelvin);
    double densSave = density();
    double tempSave = temperature();
    double pres;
    doublereal mw = meanMolecularWeight();
    if (TKelvin < critTemperature()) {

        pres = psatEst(TKelvin);
        // trial value = Psat from correlation
        doublereal volLiquid = liquidVolEst(TKelvin, pres);
        double RhoLiquidGood = mw / volLiquid;
        double RhoGasGood = pres * mw / (GasConstant * TKelvin);
        doublereal delGRT = 1.0E6;
        doublereal liqGRT, gasGRT;

        /*
         *  First part of the calculation involves finding a pressure at which the
         *  gas and the liquid state coexists.
         */
        doublereal presLiquid = 0.;
        doublereal presGas;
        doublereal  presBase = pres;
        bool foundLiquid = false;
        bool foundGas = false;

        doublereal  densLiquid = densityCalc(TKelvin, presBase, FLUID_LIQUID_0, RhoLiquidGood);
        if (densLiquid > 0.0) {
            foundLiquid = true;
            presLiquid = pres;
            RhoLiquidGood = densLiquid;
        }
        if (!foundLiquid) {
            for (int i = 0; i < 50; i++) {
                pres = 1.1 * pres;
                densLiquid = densityCalc(TKelvin, pres, FLUID_LIQUID_0, RhoLiquidGood);
                if (densLiquid > 0.0) {
                    foundLiquid = true;
                    presLiquid = pres;
                    RhoLiquidGood = densLiquid;
                    break;
                }
            }
        }

        pres = presBase;
        doublereal densGas = densityCalc(TKelvin, pres, FLUID_GAS, RhoGasGood);
        if (densGas <= 0.0) {
            foundGas = false;
        } else {
            foundGas = true;
            presGas = pres;
            RhoGasGood = densGas;
        }
        if (!foundGas) {
            for (int i = 0; i < 50; i++) {
                pres = 0.9 * pres;
                densGas = densityCalc(TKelvin, pres, FLUID_GAS, RhoGasGood);
                if (densGas > 0.0) {
                    foundGas = true;
                    presGas = pres;
                    RhoGasGood = densGas;
                    break;
                }
            }
        }

        if (foundGas && foundLiquid) {
            if (presGas != presLiquid) {
                pres = 0.5 * (presLiquid + presGas);
                bool goodLiq;
                bool goodGas;
                for (int i = 0; i < 50; i++) {
                    densLiquid = densityCalc(TKelvin, pres, FLUID_LIQUID_0, RhoLiquidGood);
                    if (densLiquid <= 0.0) {
                        goodLiq = false;
                    } else {
                        goodLiq = true;
                        RhoLiquidGood = densLiquid;
                        presLiquid = pres;
                    }
                    densGas = densityCalc(TKelvin, pres, FLUID_GAS, RhoGasGood);
                    if (densGas <= 0.0) {
                        goodGas = false;
                    } else {
                        goodGas = true;
                        RhoGasGood = densGas;
                        presGas = pres;
                    }
                    if (goodGas && goodLiq) {
                        break;
                    }
                    if (!goodLiq && !goodGas) {
                        pres = 0.5 * (pres + presLiquid);
                    }
                    if (goodLiq || goodGas) {
                        pres = 0.5 * (presLiquid + presGas);
                    }
                }
            }
        }
        if (!foundGas || !foundLiquid) {
            printf("error coundn't find a starting pressure\n");
            return 0.0;
        }
        if (presGas != presLiquid) {
            printf("error coundn't find a starting pressure\n");
            return 0.0;
        }

        pres = presGas;
        double presLast = pres;
        double RhoGas = RhoGasGood;
        double RhoLiquid = RhoLiquidGood;


        /*
         *  Now that we have found a good pressure we can proceed with the algorithm.
         */

        for (int i = 0; i < 20; i++) {
            int stab = corr0(TKelvin, pres, RhoLiquid, RhoGas, liqGRT, gasGRT);
            if (stab == 0) {
                presLast = pres;
                delGRT = liqGRT - gasGRT;
                doublereal delV = mw * (1.0/RhoLiquid - 1.0/RhoGas);
                doublereal dp = - delGRT * GasConstant * TKelvin / delV;

                if (fabs(dp) > 0.1 * pres) {
                    if (dp > 0.0) {
                        dp = 0.1 * pres;
                    } else {
                        dp = -0.1 * pres;
                    }
                }
                pres += dp;

            } else if (stab == -1) {
                delGRT = 1.0E6;
                if (presLast > pres) {
                    pres = 0.5 * (presLast + pres);
                } else {
                    // we are stuck here - try this
                    pres = 1.1 * pres;
                }
            } else if (stab == -2) {
                if (presLast < pres) {
                    pres = 0.5 * (presLast + pres);
                } else {
                    // we are stuck here - try this
                    pres = 0.9 * pres;
                }
            }
            molarVolGas = mw / RhoGas;
            molarVolLiquid = mw / RhoLiquid;


            if (fabs(delGRT) < 1.0E-8) {
                // converged
                break;
            }
        }

        molarVolGas = mw / RhoGas;
        molarVolLiquid = mw / RhoLiquid;
        // Put the fluid in the desired end condition
        setState_TR(tempSave, densSave);

        return pres;


    } else {
        pres = critPressure();
        setState_TP(TKelvin, pres);
        molarVolGas = mw / density();
        molarVolLiquid =  molarVolGas;
        setState_TR(tempSave, densSave);
    }
    return pres;
}
void MixtureFugacityTP::setState_TPX(doublereal t, doublereal p, const doublereal* x)
{
    setMoleFractions_NoState(x);
    setState_TP(t,p);
}
void MixtureFugacityTP::setPressure(doublereal p)
{
    setState_TP(temperature(), p);
 }
void ThermoPhase::setState_TPX(doublereal t, doublereal p, const std::string& x)
{
    setMoleFractionsByName(x);
    setState_TP(t,p);
}
void ThermoPhase::setState_TPY(doublereal t, doublereal p, const doublereal* y)
{
    setMassFractions(y);
    setState_TP(t,p);
}
Пример #17
0
 void VPStandardStateTP::setTemperature(const doublereal temp) {
   setState_TP(temp, m_Pcurrent);
   updateStandardStateThermo();
 }
void ThermoPhase::setState_TPY(doublereal t, doublereal p, const std::string& y)
{
    setMassFractionsByName(y);
    setState_TP(t,p);
}
Пример #19
0
 void VPStandardStateTP::setPressure(doublereal p) {
   setState_TP(temperature(), p);
   updateStandardStateThermo();
 }
Пример #20
0
/*
 * Set the temperature (K), pressure (Pa), and molalities
 * (gmol kg-1) of the solutes
 */
void MolalityVPSSTP::setState_TPM(doublereal t, doublereal p,
                                  const doublereal* const molalities)
{
    setMolalities(molalities);
    setState_TP(t, p);
}
Пример #21
0
vcs_VolPhase& vcs_VolPhase::operator=(const vcs_VolPhase& b)
{
    if (&b != this) {
        size_t old_num = m_numSpecies;

        //  Note: we comment this out for the assignment operator
        //        specifically, because it isn't true for the assignment
        //        operator but is true for a copy constructor
        // m_owningSolverObject = b.m_owningSolverObject;

        VP_ID_               = b.VP_ID_;
        m_singleSpecies     = b.m_singleSpecies;
        m_gasPhase            = b.m_gasPhase;
        m_eqnState            = b.m_eqnState;
        ChargeNeutralityElement = b.ChargeNeutralityElement;
        p_VCS_UnitsFormat   = b.p_VCS_UnitsFormat;
        p_activityConvention= b.p_activityConvention;
        m_numSpecies = b.m_numSpecies;
        m_numElemConstraints    = b.m_numElemConstraints;
        m_elementNames.resize(b.m_numElemConstraints);
        for (size_t e = 0; e < b.m_numElemConstraints; e++) {
            m_elementNames[e] = b.m_elementNames[e];
        }
        m_elementActive = b.m_elementActive;
        m_elementType = b.m_elementType;
        m_formulaMatrix = b.m_formulaMatrix;
        m_speciesUnknownType = b.m_speciesUnknownType;
        m_elemGlobalIndex    = b.m_elemGlobalIndex;
        PhaseName           = b.PhaseName;
        m_totalMolesInert   = b.m_totalMolesInert;
        m_isIdealSoln       = b.m_isIdealSoln;
        m_existence         = b.m_existence;
        m_MFStartIndex      = b.m_MFStartIndex;
        /*
         * Do a shallow copy because we haven' figured this out.
         */
        IndSpecies = b.IndSpecies;

        for (size_t k = 0; k < old_num; k++) {
            if (ListSpeciesPtr[k]) {
                delete  ListSpeciesPtr[k];
                ListSpeciesPtr[k] = 0;
            }
        }
        ListSpeciesPtr.resize(m_numSpecies, 0);
        for (size_t k = 0; k < m_numSpecies; k++) {
            ListSpeciesPtr[k] =
                new vcs_SpeciesProperties(*(b.ListSpeciesPtr[k]));
        }
        /*
         * Do a shallow copy of the ThermoPhase object pointer.
         * We don't duplicate the object.
         *  Um, there is no reason we couldn't do a
         *  duplicateMyselfAsThermoPhase() call here. This will
         *  have to be looked into.
         */
        TP_ptr              = b.TP_ptr;
        v_totalMoles              = b.v_totalMoles;
        Xmol_ = b.Xmol_;
        creationMoleNumbers_ = b.creationMoleNumbers_;
        creationGlobalRxnNumbers_ = b.creationGlobalRxnNumbers_;
        m_phiVarIndex       = b.m_phiVarIndex;
        m_totalVol          = b.m_totalVol;
        SS0ChemicalPotential = b.SS0ChemicalPotential;
        StarChemicalPotential = b.StarChemicalPotential;
        StarMolarVol = b.StarMolarVol;
        PartialMolarVol = b.PartialMolarVol;
        ActCoeff = b.ActCoeff;
        np_dLnActCoeffdMolNumber = b.np_dLnActCoeffdMolNumber;
        m_vcsStateStatus      = b.m_vcsStateStatus;
        m_phi               = b.m_phi;
        m_UpToDate            = false;
        m_UpToDate_AC         = false;
        m_UpToDate_VolStar    = false;
        m_UpToDate_VolPM      = false;
        m_UpToDate_GStar      = false;
        m_UpToDate_G0         = false;
        Temp_                = b.Temp_;
        Pres_                = b.Pres_;

        setState_TP(Temp_, Pres_);
        _updateMoleFractionDependencies();
    }
    return *this;
}
Пример #22
0
/*
 * Set the temperature (K), pressure (Pa), and molality.
 */
void MolalityVPSSTP::setState_TPM(doublereal t, doublereal p, const std::string& m)
{
    setMolalitiesByName(m);
    setState_TP(t, p);
}
Пример #23
0
void vcs_VolPhase::setState_T(const double temp)
{
    setState_TP(temp, Pres_);
}