Пример #1
0
    def create_water_oil_gas(params=None):
        """Create a WaterOilGas object from a dictionary of parameters

        Parameterization (Corey/LET) is inferred from presence
        of certain parameters in the dictionary.
        """
        if not params:
            params = dict()
        if not isinstance(params, dict):
            raise TypeError(
                "Parameter to create_water_oil_gas must be a dictionary")

        # For case insensitiveness, all keys are converted to lower case:
        params = {key.lower(): value for (key, value) in params.items()}

        wateroil = PyscalFactory.create_water_oil(params)
        gasoil = PyscalFactory.create_gas_oil(params)
        wog_init_params = slicedict(params, WOG_INIT)
        wateroilgas = WaterOilGas(**wog_init_params)
        # The wateroilgas __init__ has already created WaterOil and GasOil objects
        # but we overwrite the references with newly created ones, this factory function
        # must then guarantee that they are compatible.
        wateroilgas.wateroil = wateroil
        wateroilgas.gasoil = gasoil
        if not wateroilgas.selfcheck():
            raise ValueError(("Incomplete WaterOilGas object, "
                              "some parameters missing to factory"))
        return wateroilgas
Пример #2
0
def multiplesatnums():
    """Test of a case where there are multiple satnums"""
    satnums = []
    satnums.append(
        WaterOilGas(swirr=0.01, swl=0.1, sgcr=0.05, sorg=0.1, tag="Good sand")
    )
    satnums[0].wateroil.add_corey_oil(3)
    satnums[0].wateroil.add_corey_water(2.5)
    satnums[0].wateroil.add_simple_J()
    satnums[0].gasoil.add_corey_oil(4)
    satnums[0].gasoil.add_corey_gas(1)

    satnums.append(
        WaterOilGas(swirr=0.35, swl=0.4, sgcr=0.05, sorg=0.1, tag="Bad sand")
    )
    satnums[1].wateroil.add_corey_oil(4)
    satnums[1].wateroil.add_corey_water(5)
    satnums[1].wateroil.add_simple_J()
    satnums[1].gasoil.add_corey_oil(4)
    satnums[1].gasoil.add_corey_gas(1)

    if satnums[0].selfcheck() and satnums[1].selfcheck():
        print(satnums[0].wateroil.SWOF())
        print(satnums[1].wateroil.SWOF(header=False))
        print(satnums[0].gasoil.SGOF())
        print(satnums[1].gasoil.SGOF(header=False))
Пример #3
0
def test_threephasecheck():
    """Test three phase consistency checks"""
    wog = WaterOilGas()
    assert not wog.selfcheck()
    wog.wateroil.add_corey_water(nw=2)
    wog.wateroil.add_corey_oil(now=2, kroend=0.9)
    wog.gasoil.add_corey_gas(ng=2)
    wog.gasoil.add_corey_oil(nog=2, kroend=1)
    assert not wog.threephaseconsistency()
Пример #4
0
def test_not_threephase_consistency():
    wog = WaterOilGas()
    # To trigger this, we need to hack the WaterOilGas object
    # by overriding the effect of its __init__
    wog.wateroil = WaterOil(swl=0.4)
    wog.gasoil = GasOil(swl=0.2)
    wog.wateroil.add_corey_water(nw=2)
    wog.wateroil.add_corey_oil(now=2, kroend=0.9)
    wog.gasoil.add_corey_gas(ng=2)
    wog.gasoil.add_corey_oil(nog=2, kroend=1)
    assert not wog.threephaseconsistency()
Пример #5
0
def gen_wog(parameters: pd.DataFrame, fast_pyscal: bool = False) -> WaterOilGas:
    """
    Creates a PyScal WaterOilGas object based on the input parameters supplied.

    Args:
        parameters: A dataframe consisting of all specified parameters.
        fast_pyscal: Run pyscal in fast-mode skipping checks. Useful for large models/ensemble.

    Returns:
        A PyScal WaterOilGas object

    """
    wog_relperm = WaterOilGas(
        swirr=parameters["swirr"],
        swl=parameters["swl"],
        swcr=parameters["swcr"],
        sorw=parameters["sorw"],
        sorg=parameters["sorg"],
        sgcr=parameters["sgcr"],
        h=H_CONSTANT,
        fast=fast_pyscal,
    )

    wog_relperm.wateroil.add_corey_water(
        nw=parameters["nw"], krwend=parameters["krwend"]
    )
    wog_relperm.wateroil.add_corey_oil(
        now=parameters["now"], kroend=parameters["kroend"]
    )
    wog_relperm.gasoil.add_corey_gas(ng=parameters["ng"], krgend=parameters["krgend"])
    wog_relperm.gasoil.add_corey_oil(nog=parameters["nog"], kroend=parameters["kroend"])

    return wog_relperm
Пример #6
0
def test_empty():
    """Empty object should give empty strings (and logged errors)"""
    wog = WaterOilGas()
    assert wog.SWOF() == ""
    assert wog.SGOF() == ""
    assert wog.SOF3() == ""
    assert wog.SLGOF() == ""
    assert wog.SWFN() == ""
    assert wog.SGFN() == ""
Пример #7
0
    def create_water_oil_gas(params=None):
        """Create a WaterOilGas object from a dictionary of parameters

        Parameterization (Corey/LET) is inferred from presence
        of certain parameters in the dictionary.

        Check create_water_oil() and create_gas_oil() for lists
        of supported parameters (case insensitive)
        """
        if not params:
            params = dict()
        if not isinstance(params, dict):
            raise TypeError(
                "Parameter to create_water_oil_gas must be a dictionary")

        check_deprecated(params)

        # For case insensitiveness, all keys are converted to lower case:
        params = {key.lower(): value for (key, value) in params.items()}

        if sufficient_water_oil_params(params):
            wateroil = PyscalFactory.create_water_oil(params)
        else:
            logger.info(
                "No wateroil parameters. Assuming only gas-oil in wateroilgas")
            wateroil = None

        if sufficient_gas_oil_params(params):
            gasoil = PyscalFactory.create_gas_oil(params)
        else:
            logger.info("No gasoil parameters, assuming two-phase oilwatergas")
            gasoil = None

        wog_init_params = slicedict(params, WOG_INIT)
        wateroilgas = WaterOilGas(**wog_init_params)
        # The wateroilgas __init__ has already created WaterOil and GasOil objects
        # but we overwrite the references with newly created ones, this factory function
        # must then guarantee that they are compatible.
        wateroilgas.wateroil = wateroil  # This might be None
        wateroilgas.gasoil = gasoil  # This might be None
        if not wateroilgas.selfcheck():
            raise ValueError((
                "Incomplete WaterOilGas object, some parameters missing to factory"
            ))
        return wateroilgas
Пример #8
0
def test_slgof(swl, sorg, sgcr):
    wog = WaterOilGas(swl=swl, sorg=sorg, sgcr=sgcr, h=0.05)
    wog.wateroil.add_corey_water()
    wog.wateroil.add_corey_oil()
    wog.gasoil.add_corey_gas(krgmax=1)
    wog.gasoil.add_corey_oil()

    assert wog.selfcheck()

    slgof = wog.gasoil.slgof_df()
    assert "sl" in slgof
    assert "krg" in slgof
    assert "krog" in slgof
    assert len(slgof)

    check_table(slgof)

    # Requirements from E100 manual:
    assert np.isclose(slgof["sl"].values[0], wog.gasoil.swl + wog.gasoil.sorg)
    assert np.isclose(slgof["krg"].values[-1], 0)
    assert np.isclose(slgof["krog"].values[0], 0)
Пример #9
0
def test_wateroilgas_constructor():
    """Test that constructor properties are available as aattributes"""
    wog = WaterOilGas(swirr=0.01, swl=0.02, sorg=0.03, sorw=0.04, tag="Foo")
    assert wog.swirr == 0.01
    assert wog.swl == 0.02
    assert wog.sorg == 0.03
    assert wog.tag == "Foo"
    assert wog.sorw == 0.04

    # Manipulate the tag in the underlying GasOil object:
    wog.gasoil.tag = "Bar"
    assert wog.tag == "Foo Bar"  # Different tags are concatenated.
Пример #10
0
def test_slgof(swl, sorg, sgcr):
    """Test dumping SLGOF records"""
    wog = WaterOilGas(swl=swl, sorg=sorg, sgcr=sgcr, h=0.05)
    wog.wateroil.add_corey_water()
    wog.wateroil.add_corey_oil()
    wog.gasoil.add_corey_gas(krgmax=1)
    wog.gasoil.add_corey_oil()

    assert wog.selfcheck()

    slgof = wog.gasoil.slgof_df()
    assert "SL" in slgof
    assert "KRG" in slgof
    assert "KROG" in slgof
    assert not slgof.empty

    check_table(slgof)
    sat_table_str_ok(wog.SLGOF())

    # Requirements from E100 manual:
    assert np.isclose(slgof["SL"].values[0], wog.gasoil.swl + wog.gasoil.sorg)
    assert np.isclose(slgof["KRG"].values[-1], 0)
    assert np.isclose(slgof["KROG"].values[0], 0)
Пример #11
0
def test_ieee_754():
    """Test difficult values from experienced bugs related to
    IEE754 representation errors"""
    wateroilgas = WaterOilGas(swl=0.18)
    # For this particular swl value, we get:
    # wateroilgas.gasoil.table.sg.max()
    # Out[18]: 0.8200000000000001  # = (1 - 0.18)

    # Can we then interpolate from a table that goes up to 0.82?
    sgof = pd.DataFrame(columns=["Sg", "krg", "krog", "pcog"],
                        data=[[0, 0, 1, 0], [0.82, 1, 0, 0]])
    # Note, replacing 0.82 in the table above with 1-0.18 *is not the same*
    wateroilgas.gasoil.add_fromtable(sgof)
    assert wateroilgas.gasoil.table["krg"].max() == 1.0
    assert wateroilgas.gasoil.table["krog"].min() == 0.0
    assert wateroilgas.gasoil.table["pc"].min() == 0.0
    assert wateroilgas.gasoil.table["pc"].max() == 0.0
Пример #12
0
def test_wateroilgas_simple():
    """Test that default curves will give valid include strings"""
    wog = WaterOilGas()

    # Add default curves:
    wog.wateroil.add_corey_water()
    wog.wateroil.add_corey_oil()
    wog.gasoil.add_corey_gas()
    wog.gasoil.add_corey_oil()

    with pytest.raises(AssertionError):
        # Testing test code:
        sat_table_str_ok("")
    sat_table_str_ok(wog.SWOF())
    sat_table_str_ok(wog.SGOF())
    sat_table_str_ok(wog.SLGOF())
    sat_table_str_ok(wog.SOF3())
    sat_table_str_ok(wog.SGFN())
    sat_table_str_ok(wog.SWFN())
Пример #13
0
def benchme(fast=False, doprint=False):
    """Test function for benchmarking the "fast"-feature

    Pipe the following code snip into "ipython" on the shell:
    > echo "import benchme
      %timeit benchme.benchme()
      %timeit benchme.benchme(fast=True)
      " | ipython

    or run this module directly
    """
    wog = WaterOilGas(swl=0.1, h=0.1, fast=fast)
    wog.wateroil.add_corey_oil(now=3, kroend=0.9)
    wog.wateroil.add_corey_water(nw=2, krwend=0.2)
    wog.gasoil.add_corey_oil()
    wog.gasoil.add_corey_gas()
    if not doprint:
        len(wog.SWOF())
        len(wog.SGOF())
    else:
        print(wog.SWOF())
        print(wog.SGOF())
Пример #14
0
    def interpolate(self, parameter, parameter2=None, h=0.02):
        """Interpolate between low, base and high

        Endpoints are located for input curves, and interpolated
        individually. Interpolation for the nonlinear part
        is done on a normalized interval between the endpoints

        Interpolation is linear in relperm-direction, and will thus not be
        linear in log-relperm-direction

        This method returns an WaterOilGas object which can be
        realized into printed tables. No attempt is made to
        parametrize the interpolant in L,E,T parameter space, or Corey-space.

        Args:
            parameter (float): Between -1 and 1, inclusive. -1 reproduces low/
                pessimistic curve, 0 gives base, 1 gives high/optimistic.
            parameter2 (float): If not None, used for the gas-oil interpolation,
                enables having interpolation uncorrelated for WaterOil and
                GasOil. Ignored for GasWater (no warning).
            h (float): Saturation step length in generated tables. Does not
                need to be the same as the tables interpolation is done from.
        """

        if parameter2 is not None:
            gasparameter = parameter2
        else:
            gasparameter = parameter

        # Either wateroil or gasoil can be None in the low, base, high
        # If they are None, it is a two-phase problem and we
        # should support this.
        do_gaswater = False
        do_wateroil = False
        do_gasoil = False
        if self.type == GasWater:
            do_gaswater = True
        elif self.type == WaterOilGas:
            do_wateroil = (self.base.wateroil is not None
                           and self.low.wateroil is not None
                           and self.high.wateroil is not None)

            do_gasoil = (self.base.gasoil is not None
                         and self.low.gasoil is not None
                         and self.high.gasoil is not None)

        if not do_gaswater:
            if not do_wateroil and not do_gasoil:
                raise ValueError(
                    "Neither WaterOil or GasOil is complete in SCAL recommendation"
                )

        if parameter2 is not None:
            if not do_gasoil:
                logger.warning("parameter2 is meaningless for water-oil only")
            if do_gaswater:
                logger.warning("parameter2 is meaningless for gas-water")

        # Initialize wateroil and gasoil curves to be filled with
        # interpolated curves:

        tags = set()
        if do_wateroil or do_gaswater:
            tags = tags.union(
                set([
                    self.base.wateroil.tag,
                    self.low.wateroil.tag,
                    self.high.wateroil.tag,
                ]))
        if do_gasoil:
            tags = tags.union(
                set([
                    self.base.gasoil.tag, self.low.gasoil.tag,
                    self.high.gasoil.tag
                ]))
        tagstring = "\n".join(tags)
        if do_gaswater:
            interpolant = GasWater(h=h, tag=tagstring)
            if gasparameter != parameter:
                logger.warning(
                    "Different interpolation parameters for Water and for "
                    "gas in GasWater, this is maybe not what you want")
        else:
            interpolant = WaterOilGas(h=h, tag=tagstring)

        if do_wateroil or do_gaswater:
            tag = (
                "SCAL recommendation interpolation to {}\n".format(parameter) +
                tagstring)
            if abs(parameter) > 1.0:
                logger.error("Interpolation parameter must be in [-1,1]")
                assert abs(parameter) <= 1.0
            elif np.isclose(parameter, 0.0):
                interpolant.wateroil = copy.deepcopy(self.base.wateroil)
                interpolant.wateroil.tag = tag
            elif np.isclose(parameter, -1.0):
                interpolant.wateroil = copy.deepcopy(self.low.wateroil)
                interpolant.wateroil.tag = tag
            elif np.isclose(parameter, 1.0):
                interpolant.wateroil = copy.deepcopy(self.high.wateroil)
                interpolant.wateroil.tag = tag
            elif parameter < 0.0:
                interpolant.wateroil = interpolate_wo(self.base.wateroil,
                                                      self.low.wateroil,
                                                      -parameter,
                                                      h=h,
                                                      tag=tag)
            elif parameter > 0.0:
                interpolant.wateroil = interpolate_wo(self.base.wateroil,
                                                      self.high.wateroil,
                                                      parameter,
                                                      h=h,
                                                      tag=tag)
        else:
            interpolant.wateroil = None

        if do_gasoil or do_gaswater:
            tag = ("SCAL recommendation interpolation to {}\n".format(
                gasparameter) + tagstring)
            if abs(gasparameter) > 1.0:
                logger.error("Interpolation parameter must be in [-1,1]")
                assert abs(gasparameter) <= 1.0
            elif np.isclose(gasparameter, 0.0):
                interpolant.gasoil = copy.deepcopy(self.base.gasoil)
                interpolant.gasoil.tag = tag
            elif np.isclose(gasparameter, -1.0):
                interpolant.gasoil = copy.deepcopy(self.low.gasoil)
                interpolant.gasoil.tag = tag
            elif np.isclose(gasparameter, 1.0):
                interpolant.gasoil = copy.deepcopy(self.high.gasoil)
                interpolant.gasoil.tag = tag
            elif gasparameter < 0.0:
                interpolant.gasoil = interpolate_go(self.base.gasoil,
                                                    self.low.gasoil,
                                                    -1 * gasparameter,
                                                    h=h,
                                                    tag=tag)
            elif gasparameter > 0.0:
                interpolant.gasoil = interpolate_go(self.base.gasoil,
                                                    self.high.gasoil,
                                                    gasparameter,
                                                    h=h,
                                                    tag=tag)
        else:
            interpolant.gasoil = None

        return interpolant
Пример #15
0
def test_parse_with_opm(tmpdir):
    """Test that the SWOF+SGOF output from pyscal can be
    injected into a valid Eclipse deck"""
    wog = WaterOilGas()
    wog.wateroil.add_corey_water(nw=2)
    wog.wateroil.add_corey_oil(now=2, kroend=0.9)
    wog.gasoil.add_corey_gas(ng=2)
    wog.gasoil.add_corey_oil(nog=2, kroend=1)

    ecldeck = ("""RUNSPEC
DIMENS
  1 1 1 /
OIL
WATER
GAS
START
  1 'JAN' 2100 /
TABDIMS
   2* 10000 /
EQLDIMS
  1 /
GRID
DX
   10 /
DY
   10 /
DZ
   50 /
TOPS
   1000 /
PORO
   0.3 /
PERMX
   100 /
PERMY
   100 /
PERMZ
   100 /

PROPS

""" + wog.SWOF() + wog.SGOF() + """
DENSITY
  800 1000 1.2 /
PVTW
  1 1 0.0001 0.2 0.00001 /
PVDO
   100 1   1
   150 0.9 1 /
PVDG
   100 1 1
   150 0.9 1 /
ROCK
  100 0.0001 /
SOLUTION
EQUIL
   1000    100     1040    0   1010      0 /""")

    tmpdir.chdir()
    Path("RELPERMTEST.DATA").write_text(ecldeck)
    deck = opm.io.Parser().parse("RELPERMTEST.DATA")
    assert "SWOF" in deck
    assert "SGOF" in deck
Пример #16
0
    def __init__(self, low, base, high, tag=None, h=0.01):
        """Set up a SCAL recommendation curve set from WaterOilGas objects

        Arguments:
            low (WaterOilGas): low case
            base (WaterOilGas): base case
            high (WaterOilGas): high case
            tag (str): Describes the recommendation. This string will be used
                as tag strings for the interpolants.
        """

        self.h = h
        self.tag = tag

        if isinstance(low, dict) and isinstance(base, dict) and isinstance(
                high, dict):

            logger.warning(
                ("Making SCALrecommendation from dicts is deprecated "
                 "and will not be supported in future versions\n"))

            self.defaultshandling("swirr", 0.0, [low, base, high])
            self.defaultshandling("swcr", 0.0, [low, base, high])
            self.defaultshandling("sorg", 0.0, [low, base, high])
            self.defaultshandling("sgcr", 0.0, [low, base, high])

            # Special treatment for backwards compatibility:
            if "krowend" in low:
                logger.error("krowend is deprecated, use kroend")
                krowend = "krowend"
            else:
                krowend = "kroend"

            if "krogend" in low:
                logger.error("krogend is deprecated, use kroend")
                krogend = "krogend"
            else:
                krogend = "kroend"

            self.defaultshandling("kroend", 1.0, [low, base, high])
            self.defaultshandling("krwmax", 1.0, [low, base, high])
            self.defaultshandling("krgend", 1.0, [low, base, high])
            self.defaultshandling("krgmax", 1.0, [low, base, high])

            # Initialize saturation ranges for all curves
            self.low = WaterOilGas(
                swirr=low["swirr"],
                swl=low["swl"],
                sorw=low["sorw"],
                sorg=low["sorg"],
                sgcr=low["sgcr"],
                swcr=low["swcr"],
                h=h,
                tag=tag,
            )
            self.base = WaterOilGas(
                swirr=base["swirr"],
                swl=base["swl"],
                sorw=base["sorw"],
                sorg=base["sorg"],
                sgcr=base["sgcr"],
                swcr=base["swcr"],
                h=h,
                tag=tag,
            )
            self.high = WaterOilGas(
                swirr=high["swirr"],
                swl=high["swl"],
                sorw=high["sorw"],
                sorg=high["sorg"],
                sgcr=high["sgcr"],
                swcr=high["swcr"],
                h=h,
                tag=tag,
            )

            # Add water and oil curves
            self.low.wateroil.add_LET_water(
                l=low["Lw"],
                e=low["Ew"],
                t=low["Tw"],
                krwend=low["krwend"],
                krwmax=low["krwmax"],
            )
            self.base.wateroil.add_LET_water(
                l=base["Lw"],
                e=base["Ew"],
                t=base["Tw"],
                krwend=base["krwend"],
                krwmax=base["krwmax"],
            )
            self.high.wateroil.add_LET_water(
                l=high["Lw"],
                e=high["Ew"],
                t=high["Tw"],
                krwend=high["krwend"],
                krwmax=high["krwmax"],
            )

            self.low.wateroil.add_LET_oil(l=low["Lo"],
                                          e=low["Eo"],
                                          t=low["To"],
                                          kroend=low[krowend])
            self.base.wateroil.add_LET_oil(l=base["Lo"],
                                           e=base["Eo"],
                                           t=base["To"],
                                           kroend=base[krowend])
            self.high.wateroil.add_LET_oil(l=high["Lo"],
                                           e=high["Eo"],
                                           t=high["To"],
                                           kroend=high[krowend])

            # Add gas and oil curves:
            self.low.gasoil.add_LET_gas(
                l=low["Lg"],
                e=low["Eg"],
                t=low["Tg"],
                krgend=low["krgend"],
                krgmax=low["krgmax"],
            )
            self.base.gasoil.add_LET_gas(
                l=base["Lg"],
                e=base["Eg"],
                t=base["Tg"],
                krgend=base["krgend"],
                krgmax=base["krgmax"],
            )
            self.high.gasoil.add_LET_gas(
                l=high["Lg"],
                e=high["Eg"],
                t=high["Tg"],
                krgend=high["krgend"],
                krgmax=high["krgmax"],
            )
            self.low.gasoil.add_LET_oil(l=low["Log"],
                                        e=low["Eog"],
                                        t=low["Tog"],
                                        kroend=low[krogend])
            self.base.gasoil.add_LET_oil(l=base["Log"],
                                         e=base["Eog"],
                                         t=base["Tog"],
                                         kroend=base[krogend])
            self.high.gasoil.add_LET_oil(l=high["Log"],
                                         e=high["Eog"],
                                         t=high["Tog"],
                                         kroend=high[krogend])
            self.type = WaterOilGas
        elif (isinstance(low, WaterOilGas) and isinstance(base, WaterOilGas)
              and isinstance(high, WaterOilGas)):

            self.low = low
            self.base = base
            self.high = high
            self.type = WaterOilGas
        elif (isinstance(low, GasWater) and isinstance(base, GasWater)
              and isinstance(high, GasWater)):

            self.low = low
            self.base = base
            self.high = high
            self.type = GasWater
        else:
            raise ValueError("Wrong arguments to SCALrecommendation")
Пример #17
0
    def interpolate(self, parameter, parameter2=None, h=0.02):
        """Interpolate between low, base and high
        parameter = -1 reproduces low curve
        parameter = 0 reproduces base curve
        parameter = 1 reproduces high curve

        Endpoints are located for input curves, and interpolated
        individually. Interpolation for the nonlinear part
        is done on a normalized interval between the endpoints

        Interpolation is linear in relperm-direction, and will thus not be
        linear in log-relperm-direction

        This method returns an WaterOilGas object which can be
        realized into printed tables. No attempt is made to
        parametrize the interpolant in L,E,T parameter space, or Corey-space.

        If a second parameter is supplied ("parameter2") this is used
        for the gas-oil interpolation. This enables the gas-oil
        interpolant to be fully uncorrelated to the water-oil
        interpolant. CHECK how this affects endpoints and Eclipse
        consistency!!

        """

        if parameter2 is not None:
            gasparameter = parameter2
        else:
            gasparameter = parameter

        # Either wateroil or gasoil can be None in the low, base, high
        # If they are None, it is a two-phase problem and we
        # should support this.
        do_wateroil = (self.base.wateroil is not None
                       and self.low.wateroil is not None
                       and self.high.wateroil is not None)

        do_gasoil = (self.base.gasoil is not None
                     and self.low.gasoil is not None
                     and self.high.gasoil is not None)

        if not do_wateroil and not do_gasoil:
            raise ValueError(
                "Neither wateroil or gasoil is complete in SCAL recommendation"
            )

        if parameter2 is not None and not do_gasoil:
            logger.warning("parameter2 is meaningless for water-oil only")

        # Initialize wateroil and gasoil curves to be filled with
        # interpolated curves:

        tags = set()
        if do_wateroil:
            tags = tags.union(
                set([
                    self.base.wateroil.tag,
                    self.low.wateroil.tag,
                    self.high.wateroil.tag,
                ]))
        if do_gasoil:
            tags = tags.union(
                set([
                    self.base.gasoil.tag, self.low.gasoil.tag,
                    self.high.gasoil.tag
                ]))
        tagstring = "\n".join(tags)

        interpolant = WaterOilGas(h=h, tag=tagstring)

        if do_wateroil:
            tag = (
                "SCAL recommendation interpolation to {}\n".format(parameter) +
                tagstring)
            if abs(parameter) > 1.0:
                logger.error("Interpolation parameter must be in [-1,1]")
                assert abs(parameter) <= 1.0
            elif np.isclose(parameter, 0.0):
                interpolant.wateroil = self.base.wateroil
                interpolant.wateroil.tag = tag
            elif np.isclose(parameter, -1.0):
                interpolant.wateroil = self.low.wateroil
                interpolant.wateroil.tag = tag
            elif np.isclose(parameter, 1.0):
                interpolant.wateroil = self.high.wateroil
                interpolant.wateroil.tag = tag
            elif parameter < 0.0:
                interpolant.wateroil = utils.interpolate_wo(self.base.wateroil,
                                                            self.low.wateroil,
                                                            -parameter,
                                                            h=h,
                                                            tag=tag)
            elif parameter > 0.0:
                interpolant.wateroil = utils.interpolate_wo(self.base.wateroil,
                                                            self.high.wateroil,
                                                            parameter,
                                                            h=h,
                                                            tag=tag)
        else:
            interpolant.wateroil = None

        if do_gasoil:
            tag = ("SCAL recommendation interpolation to {}\n".format(
                gasparameter) + tagstring)
            if abs(gasparameter) > 1.0:
                logger.error("Interpolation parameter must be in [-1,1]")
                assert abs(gasparameter) <= 1.0
            elif np.isclose(gasparameter, 0.0):
                interpolant.gasoil = self.base.gasoil
                interpolant.gasoil.tag = tag
            elif np.isclose(gasparameter, -1.0):
                interpolant.gasoil = self.low.gasoil
                interpolant.gasoil.tag = tag
            elif np.isclose(gasparameter, 1.0):
                interpolant.gasoil = self.high.gasoil
                interpolant.gasoil.tag = tag
            elif gasparameter < 0.0:
                interpolant.gasoil = utils.interpolate_go(self.base.gasoil,
                                                          self.low.gasoil,
                                                          -1 * gasparameter,
                                                          h=h,
                                                          tag=tag)
            elif gasparameter > 0.0:
                interpolant.gasoil = utils.interpolate_go(self.base.gasoil,
                                                          self.high.gasoil,
                                                          gasparameter,
                                                          h=h,
                                                          tag=tag)
        else:
            interpolant.gasoil = None

        return interpolant
Пример #18
0
    def interpolate(self, parameter, parameter2=None, h=0.02):
        """Interpolate between low, base and high
        parameter = -1 reproduces low curve
        parameter = 0 reproduces base curve
        parameter = 1 reproduces high curve

        Interpolation is performed pointwise in the "relperm" direction
        for each saturation point. During interpolation, endpoints are
        hard to handle, and only swirr is attempted preserved.

        Interpolation is linear in relperm-direction, and will thus not be
        linear in log-relperm-direction

        This method returns an WaterOilGasTable object which can be
        realized into printed tables. No attempt is made to
        parametrize the interpolant in L,E,T parameter space.

        If a second parameter is supplied ("parameter2") this is used
        for the gas-oil interpolation. This enables the gas-oil
        interpolant to be fully uncorrelated to the water-oil
        interpolant. CHECK how this affects endpoints and Eclipse
        consistency!!

        """

        if parameter2 is not None:
            gasparameter = parameter2
        else:
            gasparameter = parameter

        # Initialize wateroil and gasoil curves to be filled with
        # interpolated curves:
        interpolant = WaterOilGas()

        if abs(parameter) > 1.0:
            logging.error("Interpolation parameter must be in [-1,1]")
            interpolant.wateroil = None
            raise AssertionError
        elif np.isclose(parameter, 0.0):
            interpolant.wateroil = self.base.wateroil
        elif np.isclose(parameter, -1.0):
            interpolant.wateroil = self.low.wateroil
        elif np.isclose(parameter, 1.0):
            interpolant.wateroil = self.high.wateroil
        elif parameter < 0.0:
            curve1 = copy.deepcopy(self.base.wateroil)
            curve2 = copy.deepcopy(self.low.wateroil)
            param_transf = -parameter  # 0 gives base, 1 gives low.
            swl = (curve1.table["sw"][0] * (1 - param_transf) +
                   curve2.table["sw"][0] * param_transf)
            interpolant.wateroil = WaterOil(
                swirr=swl,
                swl=swl,
                sorw=0.0,
                h=h,
                tag=self.tag + " interpolant at %g" % parameter,
            )
            interpolator(
                interpolant.wateroil,
                curve1,
                curve2,
                param_transf,
                "sw",
                "krw",
                "krow",
                "pc",
            )
        elif parameter > 0.0:
            curve1 = copy.deepcopy(self.base.wateroil)
            curve2 = copy.deepcopy(self.high.wateroil)
            param_transf = parameter  # 0 gives base, 1 gives high
            swl = (curve1.table["sw"][0] * (1 - param_transf) +
                   curve2.table["sw"][0] * param_transf)
            interpolant.wateroil = WaterOil(
                swirr=swl,
                swl=swl,
                sorw=0.0,
                h=h,
                tag=self.tag + " interpolant at %g" % parameter,
            )
            interpolator(
                interpolant.wateroil,
                curve1,
                curve2,
                param_transf,
                "sw",
                "krw",
                "krow",
                "pc",
            )

        # Gas-oil interpolation
        # We need swl from the interpolated WaterOil object.
        swl = interpolant.wateroil.swl
        if abs(gasparameter) > 1.0:
            logging.error("Interpolation parameter must be in [-1,1]")
            interpolant.gasoil = None
            raise AssertionError
        elif np.isclose(gasparameter, 0.0):
            interpolant.gasoil = self.base.gasoil
        elif np.isclose(gasparameter, -1.0):
            interpolant.gasoil = self.low.gasoil
        elif np.isclose(gasparameter, 1.0):
            interpolant.gasoil = self.high.gasoil
        elif gasparameter < 0.0:
            curve1 = copy.deepcopy(self.base.gasoil)
            curve2 = copy.deepcopy(self.low.gasoil)
            gas_param_transf = -1 * gasparameter  # 0 gives base, 1 gives low.
            # We have to use the extreme, not interpolated sgcr.
            sgcr = min(curve1.sgcr, curve2.sgcr)
            interpolant.gasoil = GasOil(
                sgcr=sgcr,
                swl=swl,
                sorg=0.0,
                h=h,
                tag=self.tag + " interpolant at %g" % gasparameter,
            )
            interpolator(
                interpolant.gasoil,
                curve1,
                curve2,
                gas_param_transf,
                "sg",
                "krg",
                "krog",
                "pc",
            )
            interpolant.gasoil.resetsorg()
        elif gasparameter > 0.0:
            curve1 = copy.deepcopy(self.base.gasoil)
            curve2 = copy.deepcopy(self.high.gasoil)
            gas_param_transf = gasparameter  # 0 gives base, 1 gives high
            # We have to use the extreme, not interpolated sgcr.
            sgcr = min(curve1.sgcr, curve2.sgcr)
            interpolant.gasoil = GasOil(
                sgcr=sgcr,
                swl=swl,
                sorg=0.0,
                h=h,
                tag=self.tag + " interpolant at %g" % gasparameter,
            )
            interpolator(
                interpolant.gasoil,
                curve1,
                curve2,
                gas_param_transf,
                "sg",
                "krg",
                "krog",
                "pc",
            )
            interpolant.gasoil.resetsorg()

        return interpolant
Пример #19
0
    def __init__(self, low, base, high, tag, h=0.01):
        """Set up a SCAL recommendation curve set from WaterOilGas objects

        Arguments:
            low (WaterOilGas): low case
            base (WaterOilGas): base case
            high (WaterOilGas): high case
        """

        self.h = h
        self.tag = tag

        if isinstance(low, dict) and isinstance(base, dict) and isinstance(
                high, dict):

            logging.warning(
                ("Making SCALrecommendation from dicts is deprecated "
                 "and will not be supported in future versions\n"
                 "Use WaterOilGas objects instead"))

            self.defaultshandling("swirr", 0.0, [low, base, high])
            self.defaultshandling("swcr", 0.0, [low, base, high])
            self.defaultshandling("sorg", 0.0, [low, base, high])
            self.defaultshandling("sgcr", 0.0, [low, base, high])
            self.defaultshandling("kroend", 1.0, [low, base, high])
            self.defaultshandling("krwmax", 1.0, [low, base, high])
            self.defaultshandling("krgend", 1.0, [low, base, high])
            self.defaultshandling("krgmax", 1.0, [low, base, high])

            # Initialize saturation ranges for all curves
            self.low = WaterOilGas(
                swirr=low["swirr"],
                swl=low["swl"],
                sorw=low["sorw"],
                sorg=low["sorg"],
                sgcr=low["sgcr"],
                swcr=low["swcr"],
                h=h,
                tag=tag,
            )
            self.base = WaterOilGas(
                swirr=base["swirr"],
                swl=base["swl"],
                sorw=base["sorw"],
                sorg=base["sorg"],
                sgcr=base["sgcr"],
                swcr=base["swcr"],
                h=h,
                tag=tag,
            )
            self.high = WaterOilGas(
                swirr=high["swirr"],
                swl=high["swl"],
                sorw=high["sorw"],
                sorg=high["sorg"],
                sgcr=high["sgcr"],
                swcr=high["swcr"],
                h=h,
                tag=tag,
            )

            # Add water and oil curves
            self.low.wateroil.add_LET_water(
                l=low["Lw"],
                e=low["Ew"],
                t=low["Tw"],
                krwend=low["krwend"],
                krwmax=low["krwmax"],
            )
            self.base.wateroil.add_LET_water(
                l=base["Lw"],
                e=base["Ew"],
                t=base["Tw"],
                krwend=base["krwend"],
                krwmax=base["krwmax"],
            )
            self.high.wateroil.add_LET_water(
                l=high["Lw"],
                e=high["Ew"],
                t=high["Tw"],
                krwend=high["krwend"],
                krwmax=high["krwmax"],
            )

            self.low.wateroil.add_LET_oil(l=low["Lo"],
                                          e=low["Eo"],
                                          t=low["To"],
                                          kroend=low["kroend"])
            self.base.wateroil.add_LET_oil(l=base["Lo"],
                                           e=base["Eo"],
                                           t=base["To"],
                                           kroend=base["kroend"])
            self.high.wateroil.add_LET_oil(l=high["Lo"],
                                           e=high["Eo"],
                                           t=high["To"],
                                           kroend=high["kroend"])

            # Add gas and oil curves:
            self.low.gasoil.add_LET_gas(
                l=low["Lg"],
                e=low["Eg"],
                t=low["Tg"],
                krgend=low["krgend"],
                krgmax=low["krgmax"],
            )
            self.base.gasoil.add_LET_gas(
                l=base["Lg"],
                e=base["Eg"],
                t=base["Tg"],
                krgend=base["krgend"],
                krgmax=base["krgmax"],
            )
            self.high.gasoil.add_LET_gas(
                l=high["Lg"],
                e=high["Eg"],
                t=high["Tg"],
                krgend=high["krgend"],
                krgmax=high["krgmax"],
            )
            self.low.gasoil.add_LET_oil(l=low["Log"],
                                        e=low["Eog"],
                                        t=low["Tog"],
                                        kroend=low["kroend"])
            self.base.gasoil.add_LET_oil(l=base["Log"],
                                         e=base["Eog"],
                                         t=base["Tog"],
                                         kroend=base["kroend"])
            self.high.gasoil.add_LET_oil(l=high["Log"],
                                         e=high["Eog"],
                                         t=high["Tog"],
                                         kroend=high["kroend"])
        elif (isinstance(low, WaterOilGas) and isinstance(base, WaterOilGas)
              and isinstance(high, WaterOilGas)):

            self.low = low
            self.base = base
            self.high = high
        else:
            raise ValueError("Wrong arguments to SCALrecommendation")