예제 #1
0
def test_interpolate_go(
    swl,
    sgcr,
    dsgcr,
    dswlhigh,
    sorg,
    dsorg,
    ng_l,
    ng_h,
    nog_l,
    nog_h,
    krgend_l,
    krgend_h,
    kroend_l,
    kroend_h,
):
    """Test many possible combinations of interpolation between two
    Corey gasoil curves, looking for numerical corner cases"""
    go_low = GasOil(swl=swl, sgcr=sgcr, sorg=sorg)
    go_high = GasOil(swl=swl + dswlhigh,
                     sgcr=sgcr + dsgcr,
                     sorg=max(sorg - dsorg, 0))
    go_low.add_corey_gas(ng=ng_l, krgend=krgend_l)
    go_high.add_corey_gas(ng=ng_h, krgend=krgend_h)
    go_low.add_corey_oil(nog=nog_l, kroend=kroend_l)
    go_high.add_corey_oil(nog=nog_h, kroend=kroend_h)
    ips = []
    ip_dist = 0.05
    for t in np.arange(0, 1 + ip_dist, ip_dist):
        go_ip = utils.interpolate_go(go_low, go_high, t)
        check_table(go_ip.table)
        ips.append(go_ip)
        assert 0 < go_ip.crosspoint() < 1

    # Distances between low and interpolants:
    dists = [(go_low.table - interp.table)[["krg", "krog"]].sum().sum()
             for interp in ips]
    print("Interpolation, mean: {}, min: {}, max: {}, std: {} ip-par-dist: {}".
          format(np.mean(dists), min(dists), max(dists),
                 np.std(np.diff(dists[1:])), ip_dist))
    assert np.isclose(dists[0], 0)  # Reproducing go_low
    # All curves that are close in parameter t, should be close in sum().sum().
    # That means that diff of the distances should be similar,
    # that is the std.dev of the distances is low:
    ip_dist_std = np.std(np.diff(
        dists[1:]))  # This number depends on 'h' and 't' range, and
    # by how different the low and high is.
    # (avoiding the first which reproduces go_low
    if ip_dist_std > 1.0:  # number found from trial and error.
        print("ip_dist_std: {}".format(ip_dist_std))
        print(dists)
        from matplotlib import pyplot as plt

        _, mpl_ax = plt.subplots()
        go_low.plotkrgkrog(mpl_ax=mpl_ax, color="red")
        go_high.plotkrgkrog(mpl_ax=mpl_ax, color="blue")
        for interp in ips:
            interp.plotkrgkrog(mpl_ax=mpl_ax, color="green")
        plt.show()
        assert False
예제 #2
0
def test_interpolate_go():
    """Interactive tests for gasoil"""
    swl_l = random.uniform(0, 0.1)
    sgcr_l = random.uniform(0, 0.1)
    swl_h = random.uniform(0, 0.1)
    sgcr_h = random.uniform(0, 0.1)
    sorg_l = random.uniform(0, 0.2)
    sorg_h = random.uniform(0, 0.2)
    if random.uniform(0, 1) > 0.5:
        krgendanchor_l = "sorg"
    else:
        krgendanchor_l = ""
    if random.uniform(0, 1) > 0.5:
        krgendanchor_h = "sorg"
    else:
        krgendanchor_h = ""
    go_low = GasOil(swl=swl_l,
                    sgcr=sgcr_l,
                    sorg=sorg_l,
                    krgendanchor=krgendanchor_l,
                    h=0.001)
    go_high = GasOil(swl=swl_h,
                     sgcr=sgcr_h,
                     sorg=sorg_h,
                     krgendanchor=krgendanchor_h,
                     h=0.001)
    go_low.add_corey_gas(ng=random.uniform(1, 3),
                         krgend=random.uniform(0.5, 1))
    go_high.add_corey_gas(ng=random.uniform(1, 3),
                          krgend=random.uniform(0.5, 1))
    go_low.add_corey_oil(nog=random.uniform(1, 3),
                         kroend=random.uniform(0.5, 1))
    go_high.add_corey_oil(nog=random.uniform(1, 3),
                          kroend=random.uniform(0.5, 1))
    print(" ** Low curve (red):\n" + go_low.sgcomment + go_low.krgcomment +
          go_low.krogcomment)
    print(" ** High curve (blue):\n" + go_high.sgcomment + go_high.krgcomment +
          go_high.krogcomment)

    from matplotlib import pyplot as plt

    _, mpl_ax = plt.subplots()
    go_low.plotkrgkrog(mpl_ax, color="red")
    go_high.plotkrgkrog(mpl_ax, color="blue")

    for tparam in np.arange(0, 1, 0.1):
        go_ip = utils.interpolate_go(go_low, go_high, tparam)
        go_ip.plotkrgkrog(mpl_ax, color="green")
    mpl_ax.set_title("GasOil, random Corey, linear y-scale")
    plt.show()

    _, mpl_ax = plt.subplots()
    go_low.plotkrgkrog(mpl_ax, color="red")
    go_high.plotkrgkrog(mpl_ax, color="blue")
    # Plot again with log yscale:
    for tparam in np.arange(0, 1, 0.1):
        go_ip = utils.interpolate_go(go_low, go_high, tparam)
        go_ip.plotkrgkrog(mpl_ax, color="green", logyscale=True)
    mpl_ax.set_title("GasOil, random Corey, log y-scale")
    plt.show()

    # Capillary pressure - This is barely supported for gasoil
    # so the plotpc() function is missing. Include calculations
    # here so we ensure we don't crash on the all zeros.
    # _, mpl_ax = plt.subplots()
    # go_low.plotpc(mpl_ax, color="red", logyscale=True)
    # go_high.plotpc(mpl_ax, color="blue", logyscale=True)
    for tparam in np.arange(0, 1, 0.1):
        go_ip = utils.interpolate_go(go_low, go_high, tparam, h=0.001)
예제 #3
0
def test_tag_preservation():
    """Test that we can preserve tags/comments through interpolation"""
    wo_low = WaterOil(swl=0.1)
    wo_high = WaterOil(swl=0.2)
    wo_low.add_corey_water(nw=2)
    wo_high.add_corey_water(nw=3)
    wo_low.add_corey_oil(now=2)
    wo_high.add_corey_oil(now=3)
    interpolant1 = utils.interpolate_wo(wo_low, wo_high, parameter=0.1, h=0.2)
    assert "Interpolated to 0.1" in interpolant1.tag
    sat_table_str_ok(interpolant1.SWOF())

    wo_high.tag = "FOOBAR"
    interpolant2 = utils.interpolate_wo(wo_low, wo_high, parameter=0.1, h=0.2)
    assert "Interpolated to 0.1" in interpolant2.tag
    assert "between" in interpolant2.tag
    assert wo_high.tag in interpolant2.tag
    sat_table_str_ok(interpolant2.SWOF())
    # wo_low.tag was empty deliberately here.

    # When wo_log and wo_high has the same tag:
    wo_low.tag = "FOOBAR"
    interpolant3 = utils.interpolate_wo(wo_low, wo_high, parameter=0.1, h=0.2)
    assert "Interpolated to 0.1" in interpolant3.tag
    assert "between" not in interpolant3.tag
    assert wo_high.tag in interpolant3.tag
    sat_table_str_ok(interpolant3.SWOF())

    # Explicit tag:
    interpolant4 = utils.interpolate_wo(wo_low,
                                        wo_high,
                                        parameter=0.1,
                                        h=0.2,
                                        tag="Explicit tag")
    assert interpolant4.tag == "Explicit tag"

    # Tag with newline
    interpolant6 = utils.interpolate_wo(wo_low,
                                        wo_high,
                                        parameter=0.1,
                                        h=0.2,
                                        tag="Explicit tag\non two lines")
    assert "Explicit tag" in interpolant6.tag
    print(interpolant6.SWOF())
    sat_table_str_ok(interpolant6.SWOF())

    # Empty tag:
    interpolant5 = utils.interpolate_wo(wo_low,
                                        wo_high,
                                        parameter=0.1,
                                        h=0.2,
                                        tag="")
    assert interpolant5.tag == ""

    # Also sample check for GasOil (calls the same code)
    go_low = GasOil()
    go_high = GasOil()
    go_low.add_corey_gas(ng=2)
    go_high.add_corey_gas(ng=3)
    go_low.add_corey_oil(nog=2)
    go_high.add_corey_oil(nog=3)
    interpolant1 = utils.interpolate_go(go_low, go_high, parameter=0.1, h=0.2)
    assert "Interpolated to 0.1" in interpolant1.tag
    sat_table_str_ok(interpolant1.SGOF())
예제 #4
0
def test_ip_krogmax():
    """Test behaviour of kroend/kromax under interpolation"""
    go_low = GasOil(swl=0, sgcr=0.1, sorg=0.2)
    go_low.add_corey_gas(ng=2, krgend=0.5, krgmax=0.7)
    go_low.add_corey_oil(nog=2, kroend=0.6, kromax=0.9)

    go_high = GasOil(swl=0.02, sgcr=0.05, sorg=0.1)
    go_high.add_corey_gas(ng=2, krgend=0.5, krgmax=0.72)
    go_high.add_corey_oil(nog=2, kroend=0.6, kromax=0.8)

    # Interpolate to midpoint between the curves above
    go_ip = utils.interpolate_go(go_low, go_high, 0.5)

    # kromax at sg zero, should be kromax:
    assert float_df_checker(go_ip.table, "sg", 0.0, "krog", 0.85)
    # kroend is 0.6 in low and high, but sgcr has changed:
    assert float_df_checker(go_ip.table, "sg", 0.075, "krog", 0.6)
    assert np.isclose(go_ip.swl, 0.01)
    assert np.isclose(go_ip.sorg, 0.15)

    # krgmax at 1 - swl:
    assert float_df_checker(go_ip.table, "sg", 1 - go_ip.swl, "krg", 0.71)
    # krgend at 1 - swl - sorg
    assert float_df_checker(go_ip.table, "sg", 1 - go_ip.swl - go_ip.sorg,
                            "krg", 0.5)

    # If krgendanchor is None, then krgmax should be irrelevant
    go_low = GasOil(swl=0, sgcr=0.1, sorg=0.2, krgendanchor="")
    go_low.add_corey_gas(ng=5, krgend=0.5, krgmax=0.7)
    # krgmax will trigger warning message, intended, as the 0.7
    # value here will mean nothing.
    go_low.add_corey_oil(nog=2, kroend=0.6, kromax=0.9)

    go_high = GasOil(swl=0.02, sgcr=0.05, sorg=0.1, krgendanchor="")
    go_high.add_corey_gas(ng=4, krgend=0.5, krgmax=0.72)
    # krgmax will trigger warning message, intended.
    go_high.add_corey_oil(nog=2, kroend=0.6, kromax=0.8)

    # Interpolate to midpoint between the curves above
    go_ip = utils.interpolate_go(go_low, go_high, 0.5, h=0.1)

    assert float_df_checker(go_ip.table, "sg", 0.0, "krog", 0.85)
    # kroend is 0.6 in low and high, but swcr has changed:
    assert float_df_checker(go_ip.table, "sg", 0.075, "krog", 0.6)

    # Activate these line to see a bug, interpolation_go
    # does not honor krgendanchorA:
    # from matplotlib import pyplot as plt
    # _, mpl_ax = plt.subplots()
    # go_low.plotkrgkrog(mpl_ax=mpl_ax, color="red")
    # go_high.plotkrgkrog(mpl_ax=mpl_ax, color="blue")
    # go_ip.plotkrgkrog(mpl_ax=mpl_ax, color="green")
    # plt.show()

    # krgmax is irrelevant, krgend is used here:
    assert float_df_checker(go_ip.table, "sg", 1 - 0.01, "krg", 0.5)

    # Do we get into trouble if krgendanchor is different in low and high?
    go_low = GasOil(swl=0, sgcr=0.1, sorg=0.2, krgendanchor="sorg")
    go_low.add_corey_gas(ng=2, krgend=0.5, krgmax=0.7)
    go_low.add_corey_oil(nog=2, kroend=0.6, kromax=0.9)

    go_high = GasOil(swl=0.02, sgcr=0.05, sorg=0.1, krgendanchor="")
    go_high.add_corey_gas(ng=2, krgend=0.5)
    go_high.add_corey_oil(nog=2, kroend=0.6, kromax=0.8)

    # Interpolate to midpoint between the curves above
    go_ip = utils.interpolate_go(go_low, go_high, 0.5)

    assert float_df_checker(go_ip.table, "sg", 0.0, "krog", 0.85)
    # kroend is 0.6 in low and high, but swcr has changed:
    assert float_df_checker(go_ip.table, "sg", 0.075, "krog", 0.6)

    # max(krg) is here avg of krgmax and krgend from the differnt tables:
    assert float_df_checker(go_ip.table, "sg", 1 - 0.01, "krg", 0.6)

    # krgend at 1 - swl - sorg, non-trivial expression, so a numerical
    # value is used here in the test:
    assert float_df_checker(go_ip.table, "sg", 1 - 0.01 - 0.15, "krg",
                            0.4491271)

    # krog-zero at 1 - swl - sorg:
    assert float_df_checker(go_ip.table, "sg", 1 - 0.01 - 0.15, "krog", 0)
예제 #5
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