Esempio n. 1
0
    static Evaluation krn(const Params &params,
                          const FluidState &fluidState)
    {
        typedef MathToolbox<Evaluation> Toolbox;
        typedef MathToolbox<typename FluidState::Scalar> FsToolbox;

        Scalar Swco = params.Swl();

        Evaluation Sw =
            Toolbox::max(Evaluation(Swco),
                         FsToolbox::template decay<Evaluation>(fluidState.saturation(waterPhaseIdx)));
        Evaluation Sg = FsToolbox::template decay<Evaluation>(fluidState.saturation(gasPhaseIdx));

        Evaluation Sw_ow = Sg + Sw;
        Evaluation So_go = 1.0 - Sw_ow;
        const Evaluation& kro_ow = OilWaterMaterialLaw::twoPhaseSatKrn(params.oilWaterParams(), Sw_ow);
        const Evaluation& kro_go = GasOilMaterialLaw::twoPhaseSatKrw(params.gasOilParams(), So_go);

        // avoid the division by zero: chose a regularized kro which is used if Sw - Swco
        // < epsilon/2 and interpolate between the oridinary and the regularized kro between
        // epsilon and epsilon/2
        const Scalar epsilon = 1e-5;
        if (Toolbox::scalarValue(Sw_ow) - Swco < epsilon) {
            Evaluation kro2 = (kro_ow + kro_go)/2;;
            if (Toolbox::scalarValue(Sw_ow) - Swco > epsilon/2) {
                Evaluation kro1 = (Sg*kro_go + (Sw - Swco)*kro_ow)/(Sw_ow - Swco);
                Evaluation alpha = (epsilon - (Sw_ow - Swco))/(epsilon/2);
                return kro2*alpha + kro1*(1 - alpha);
            }

            return kro2;
        }
        else
            return (Sg*kro_go + (Sw - Swco)*kro_ow)/(Sw_ow - Swco);
    }
Esempio n. 2
0
    static void updateHysteresis(Params &params, const FluidState &fluidState)
    {
        typedef MathToolbox<typename FluidState::Scalar> FsToolbox;

        Scalar Sw = FsToolbox::scalarValue(fluidState.saturation(waterPhaseIdx));
        Scalar So = FsToolbox::scalarValue(fluidState.saturation(oilPhaseIdx));
        Scalar Sg = FsToolbox::scalarValue(fluidState.saturation(gasPhaseIdx));

        if (params.inconsistentHysteresisUpdate()) {
            Sg = std::min(Scalar(1.0), std::max(Scalar(0.0), Sg));
            // NOTE: the saturations which are passed to update the hysteresis curves are
            // inconsistent with the ones used to calculate the relative permabilities. We do
            // it like this anyway because (a) the saturation functions of opm-core do it
            // this way (b) the simulations seem to converge better (which is not too much
            // surprising actually, because the time step does not start on a kink in the
            // solution) and (c) the Eclipse 100 simulator may do the same.
            //
            // Though be aware that from a physical perspective this is definitively
            // incorrect!
            params.oilWaterParams().update(/*pcSw=*/1 - So, /*krwSw=*/1 - So, /*krn_Sw=*/1 - So);
            params.gasOilParams().update(/*pcSw=*/1 - Sg, /*krwSw=*/1 - Sg, /*krn_Sw=*/1 - Sg);
        }
        else {
            Scalar Swco = params.Swl();
            Sw = std::min(Scalar(1.0), std::max(Scalar(0.0), Sw));
            Sg = std::min(Scalar(1.0), std::max(Scalar(0.0), Sg));

            Scalar Sw_ow = Sg + std::max(Swco, Sw);
            Scalar So_go = 1 + Sw_ow;

            params.oilWaterParams().update(/*pcSw=*/Sw, /*krwSw=*/1 - Sg, /*krnSw=*/Sw_ow);
            params.gasOilParams().update(/*pcSw=*/1 - Sg, /*krwSw=*/So_go, /*krnSw=*/1 - Sg);
        }
    }
Esempio n. 3
0
    static Evaluation krn(const Params &params,
                          const FluidState &fluidState)
    {
        typedef MathToolbox<typename FluidState::Scalar> FsToolbox;

        Scalar Swco = params.Swl();
        const Evaluation& Sw = FsToolbox::template toLhs<Evaluation>(fluidState.saturation(waterPhaseIdx));
        const Evaluation& Sg = FsToolbox::template toLhs<Evaluation>(fluidState.saturation(gasPhaseIdx));

        Scalar krocw = OilWaterMaterialLaw::twoPhaseSatKrn(params.oilWaterParams(), Swco);
        Evaluation krow = OilWaterMaterialLaw::twoPhaseSatKrn(params.oilWaterParams(), Sw);
        Evaluation krw = OilWaterMaterialLaw::twoPhaseSatKrw(params.oilWaterParams(), Sw);
        Evaluation krg = GasOilMaterialLaw::twoPhaseSatKrn(params.gasOilParams(), 1 - Sg);
        Evaluation krog = GasOilMaterialLaw::twoPhaseSatKrw(params.gasOilParams(), 1 - Sg);

        return krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg);
    }
    static Evaluation krn(const Params &params,
                          const FluidState &fluidState)
    {
        typedef MathToolbox<Evaluation> Toolbox;
        typedef MathToolbox<typename FluidState::Scalar> FsToolbox;

        // the Eclipse docu is inconsistent here: In some places the connate water
        // saturation is represented by "Swl", in others "Swco" is used.
        Scalar Swco = params.Swl();

        Scalar Sowcr = params.Sowcr();
        Scalar Sogcr = params.Sogcr();
        Scalar Som = std::min(Sowcr, Sogcr); // minimum residual oil saturation

        Scalar eta = params.eta(); // exponent of the beta term

        const Evaluation& Sw = FsToolbox::template toLhs<Evaluation>(fluidState.saturation(waterPhaseIdx));
        const Evaluation& So = FsToolbox::template toLhs<Evaluation>(fluidState.saturation(oilPhaseIdx));
        const Evaluation& Sg = FsToolbox::template toLhs<Evaluation>(fluidState.saturation(gasPhaseIdx));

        Evaluation SSw;
        if (Sw > Swco)
            SSw = (Sw - Swco)/(1 - Swco - Som);
        else
            SSw = 0.0;

        Evaluation SSo;
        if (So > Som)
            SSo = (So - Som)/(1 - Swco - Som);
        else
            SSo = 0.0;

        Evaluation SSg = Sg/(1 - Swco - Som);

        Scalar krocw = OilWaterMaterialLaw::twoPhaseSatKrn(params.oilWaterParams(), Swco);
        Evaluation krow = OilWaterMaterialLaw::twoPhaseSatKrn(params.oilWaterParams(), Sw);
        Evaluation krog = GasOilMaterialLaw::twoPhaseSatKrw(params.gasOilParams(), 1 - Sg);

        Evaluation beta = Toolbox::pow(SSo/((1 - SSw)*(1 - SSg)), eta);
        return beta*krow*krog/krocw;
    }