コード例 #1
0
ファイル: WaterPropsIAPWS.cpp プロジェクト: hkmoffat/cantera
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 Cantera::CanteraError("WaterPropsIAPWS::corr1",
                                    "Error occurred trying to find liquid density at (T,P) = "
                                    + Cantera::fp2str(temperature) + "  " + Cantera::fp2str(pressure));
    }
    setState_TR(temperature, densLiq);
    doublereal prL = m_phi->phiR();

    densGas = density(temperature, pressure, WATER_GAS, densGas);
    if (densGas <= 0.0) {
        throw Cantera::CanteraError("WaterPropsIAPWS::corr1",
                                    "Error occurred trying to find gas density at (T,P) = "
                                    + Cantera::fp2str(temperature) + "  " + Cantera::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;
}
コード例 #2
0
int MixtureFugacityTP::corr0(doublereal TKelvin, doublereal pres, doublereal& densLiqGuess,
                             doublereal& densGasGuess, doublereal& liqGRT,  doublereal& gasGRT)
{

    int retn = 0;
    doublereal densLiq = densityCalc(TKelvin, pres, FLUID_LIQUID_0, densLiqGuess);
    if (densLiq <= 0.0) {
        retn = -1;
    } else {
        densLiqGuess = densLiq;
        setState_TR(TKelvin, densLiq);
        liqGRT = gibbs_mole() / _RT();
    }

    doublereal  densGas = densityCalc(TKelvin, pres, FLUID_GAS, densGasGuess);
    if (densGas <= 0.0) {
        if (retn == -1) {
            throw Cantera::CanteraError("MixtureFugacityTP::corr0",
                                        "Error occurred trying to find gas density at (T,P) = "
                                        + Cantera::fp2str(TKelvin) + "  " + Cantera::fp2str(pres));
        }
        retn = -2;
    } else {
        densGasGuess = densGas;
        setState_TR(TKelvin, densGas);
        gasGRT = gibbs_mole() / _RT();
    }
    return retn;
}
コード例 #3
0
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);
    }
}
コード例 #4
0
ファイル: WaterPropsIAPWS.cpp プロジェクト: hkmoffat/cantera
/*
 * Calculates the density given the temperature and the pressure,
 * and a guess at the density. Note, below T_c, this is a
 * multivalued function.
 *
 * parameters:
 *    temperature: Kelvin
 *    pressure   : Pressure in Pascals (Newton/m**2)
 *    phase      : guessed phase of water
 *               : -1: no guessed phase
 *    rhoguess   : guessed density of the water
 *               : -1.0 no guessed density
 *
 * If a problem is encountered, a negative 1 is returned.
 */
doublereal WaterPropsIAPWS::density(doublereal temperature, doublereal pressure,
                                    int phase, doublereal rhoguess) {

    doublereal deltaGuess = 0.0;
    if (rhoguess == -1.0) {
        if (phase != -1) {
            if (temperature > T_c) {
                rhoguess = pressure * M_water / (Rgas * temperature);
            } else {
                if (phase == WATER_GAS || phase == WATER_SUPERCRIT) {
                    rhoguess = pressure * M_water / (Rgas * temperature);
                } else if (phase == WATER_LIQUID) {
                    /*
                     * Provide a guess about the liquid density that is
                     * relatively high -> convergnce from above seems robust.
                     */
                    rhoguess = 1000.;
                } else if (phase == WATER_UNSTABLELIQUID || phase == WATER_UNSTABLEGAS) {
                    throw Cantera::CanteraError("WaterPropsIAPWS::density",
                                                "Unstable Branch finder is untested");
                } else {
                    throw Cantera::CanteraError("WaterPropsIAPWS::density",
                                                "unknown state: " + Cantera::int2str(phase));
                }
            }
        } else {
            /*
             * Assume the Gas phase initial guess, if nothing is
             * specified to the routine
             */
            rhoguess = pressure * M_water / (Rgas * temperature);
        }

    }
    doublereal p_red = pressure * M_water / (Rgas * temperature * Rho_c);
    deltaGuess = rhoguess / Rho_c;
    setState_TR(temperature, rhoguess);
    doublereal delta_retn = m_phi->dfind(p_red, tau, deltaGuess);
    doublereal density_retn;
    if (delta_retn >0.0) {
        delta = delta_retn;

        /*
         * Dimensionalize the density before returning
         */
        density_retn = delta_retn * Rho_c;
        /*
         * Set the internal state -> this may be
         * a duplication. However, let's just be sure.
         */
        setState_TR(temperature, density_retn);


    } else {
        density_retn = -1.0;
    }
    return density_retn;
}
コード例 #5
0
ファイル: WaterPropsIAPWS.cpp プロジェクト: hkmoffat/cantera
doublereal WaterPropsIAPWS::psat(doublereal temperature, int waterState) {
    doublereal densLiq = -1.0, densGas = -1.0, delGRT = 0.0;
    doublereal dp, pcorr;
    if (temperature >= T_c) {
        densGas = density(temperature, P_c, WATER_SUPERCRIT);
        setState_TR(temperature, densGas);
        return P_c;
    }
    doublereal p = psat_est(temperature);
    bool conv = false;
    for (int i = 0; i < 30; i++) {
        if (method == 1) {
            corr(temperature, p, densLiq, densGas, delGRT);
            doublereal delV = M_water * (1.0/densLiq - 1.0/densGas);
            dp = - delGRT * Rgas * temperature / delV;
        } else {
            corr1(temperature, p, densLiq, densGas, pcorr);
            dp = pcorr - p;
        }
        p += dp;

        if ((method == 1) && delGRT < 1.0E-8) {
            conv = true;
            break;
        } else {
            if (fabs(dp/p) < 1.0E-9) {
                conv = true;
                break;
            }
        }
    }
    // Put the fluid in the desired end condition
    if (waterState == WATER_LIQUID) {
        setState_TR(temperature, densLiq);
    } else if (waterState == WATER_GAS) {
        setState_TR(temperature, densGas);
    } else {
        throw Cantera::CanteraError("WaterPropsIAPWS::psat",
                                    "unknown water state input: " + Cantera::int2str(waterState));
    }
    return p;
}
コード例 #6
0
void WaterPropsIAPWS::corr(doublereal temperature, doublereal pressure,
    doublereal& densLiq, doublereal& densGas, doublereal& delGRT)
{
    densLiq = density(temperature, pressure, WATER_LIQUID, densLiq);
    if (densLiq <= 0.0) {
        throw CanteraError("WaterPropsIAPWS::corr",
            "Error occurred trying to find liquid density at (T,P) = {}  {}",
            temperature, pressure);
    }
    setState_TR(temperature, densLiq);
    doublereal gibbsLiqRT = m_phi.gibbs_RT();

    densGas = density(temperature, pressure, WATER_GAS, densGas);
    if (densGas <= 0.0) {
        throw CanteraError("WaterPropsIAPWS::corr",
            "Error occurred trying to find gas density at (T,P) = {}  {}",
            temperature, pressure);
    }
    setState_TR(temperature, densGas);
    doublereal gibbsGasRT = m_phi.gibbs_RT();

    delGRT = gibbsLiqRT - gibbsGasRT;
}
コード例 #7
0
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;
}
コード例 #8
0
void MixtureFugacityTP::setTemperature(const doublereal temp)
{
    _updateReferenceStateThermo();
    setState_TR(temperature(), density());
}