Beispiel #1
0
def test_interpolate_wo():
    """Discrete test scenarios for wateroil interpolation"""
    swl_l = random.uniform(0, 0.1)
    swcr_l = swl_l + random.uniform(0, 0.1)
    sorw_l = random.uniform(0, 0.2)
    swl_h = random.uniform(0, 0.1)
    swcr_h = swl_h + random.uniform(0, 0.1)
    sorw_h = random.uniform(0, 0.2)
    wo_low = WaterOil(swl=swl_l, swcr=swcr_l, sorw=sorw_l, h=0.001)
    wo_high = WaterOil(swl=swl_h, swcr=swcr_h, sorw=sorw_h, h=0.001)
    wo_low.add_corey_water(nw=random.uniform(1, 3),
                           krwend=random.uniform(0.5, 1))
    wo_high.add_corey_water(nw=random.uniform(1, 3),
                            krwend=random.uniform(0.5, 1))
    wo_low.add_corey_oil(now=random.uniform(1, 3),
                         kroend=random.uniform(0.5, 1))
    wo_high.add_corey_oil(now=random.uniform(1, 3),
                          kroend=random.uniform(0.5, 1))
    wo_low.add_simple_J(a=random.uniform(0.1, 2), b=random.uniform(-2, -1))
    wo_high.add_simple_J(a=random.uniform(0.1, 2), b=random.uniform(-2, 1))
    print(" ** Low curve (red):\n" + wo_low.swcomment + wo_low.krwcomment +
          wo_low.krowcomment + wo_low.pccomment)
    print(" ** High curve (blue):\n" + wo_high.swcomment + wo_high.krwcomment +
          wo_high.krowcomment + wo_high.pccomment)

    from matplotlib import pyplot as plt

    _, mpl_ax = plt.subplots()
    wo_low.plotkrwkrow(mpl_ax, color="red")
    wo_high.plotkrwkrow(mpl_ax, color="blue")
    for tparam in np.arange(0, 1, 0.1):
        wo_ip = utils.interpolate_wo(wo_low, wo_high, tparam, h=0.001)
        wo_ip.plotkrwkrow(mpl_ax, color="green")
    mpl_ax.set_title("WaterOil, random Corey, linear y-scale")
    plt.show()

    # Plot again with log yscale:
    _, mpl_ax = plt.subplots()
    wo_low.plotkrwkrow(mpl_ax, color="red")
    wo_high.plotkrwkrow(mpl_ax, color="blue")
    for tparam in np.arange(0, 1, 0.1):
        wo_ip = utils.interpolate_wo(wo_low, wo_high, tparam, h=0.001)
        wo_ip.plotkrwkrow(mpl_ax, color="green", logyscale=True)
    mpl_ax.set_title("WaterOil, random Corey, log y-scale")
    plt.show()

    # Capillary pressure
    _, mpl_ax = plt.subplots()
    wo_low.plotpc(mpl_ax, color="red", logyscale=True)
    wo_high.plotpc(mpl_ax, color="blue", logyscale=True)
    for tparam in np.arange(0, 1, 0.1):
        wo_ip = utils.interpolate_wo(wo_low, wo_high, tparam, h=0.001)
        wo_ip.plotpc(mpl_ax, color="green", logyscale=True)
    mpl_ax.set_title("WaterOil, capillary pressure")
    plt.show()
Beispiel #2
0
def test_interpolate_wo_pc(swl, dswcr, dswlhigh, sorw, a_l, a_h, b_l, b_h):
    """
    Generate two random WaterOil curves, interpolate pc between them
    and check that the difference between each interpolant is small,
    this essentially checks that we can go continously between the
    two functions.
    """
    wo_low = WaterOil(swl=swl, swcr=swl + dswcr, sorw=sorw)
    wo_high = WaterOil(swl=swl + dswlhigh,
                       swcr=swl + dswlhigh + dswcr,
                       sorw=max(sorw - 0.01, 0))
    wo_low.add_corey_water()
    wo_high.add_corey_water()
    wo_low.add_corey_oil()
    wo_high.add_corey_oil()
    wo_low.add_simple_J(a=a_l, b=b_l)
    wo_high.add_simple_J(a=a_h, b=b_h)
    ips = []
    ip_dist = 0.05
    for t in np.arange(0, 1 + ip_dist, ip_dist):
        wo_ip = utils.interpolate_wo(wo_low, wo_high, t)
        check_table(wo_ip.table)
        ips.append(wo_ip)
        assert 0 < wo_ip.crosspoint() < 1

    # Distances between low and interpolants:
    dists = [(wo_low.table - interp.table)[["pc"]].sum().sum()
             for interp in ips]
    assert np.isclose(dists[0], 0)

    # Distance between high and the last interpolant
    assert (wo_high.table - ips[-1].table)[["pc"]].sum().sum() < 0.01

    # Distances between low and interpolants:
    dists = [(wo_low.table - interp.table)[["pc"]].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 wo_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
    # (avoiding the first which reproduces go_low
    if ip_dist_std > 1.0:  # Found by trial and error
        print("ip_dist_std: {}".format(ip_dist_std))
        print(dists)
        from matplotlib import pyplot as plt

        _, mpl_ax = plt.subplots()
        wo_low.plotpc(mpl_ax=mpl_ax, color="red", logyscale=True)
        wo_high.plotpc(mpl_ax=mpl_ax, color="blue", logyscale=True)
        for interp in ips:
            interp.plotpc(mpl_ax=mpl_ax, color="green", logyscale=True)
        plt.show()
        assert False
Beispiel #3
0
def interpolation_art(repeats=50, interpolants=30, curvetype="corey"):
    """This code was used to create the Pyscal logo"""
    from matplotlib import pyplot as plt

    cmap = plt.get_cmap("viridis")
    _, mpl_ax = plt.subplots()
    for _ in range(repeats):
        swl = random.uniform(0, 0.1)
        swcr = swl + random.uniform(0, 0.1)
        sorw = random.uniform(0, 0.2)
        wo_low = WaterOil(swl=swl, swcr=swcr, sorw=sorw)
        wo_high = WaterOil(swl=swl + 0.1, swcr=swcr + 0.1, sorw=sorw + 0.1)
        if curvetype == "corey":
            wo_low.add_corey_water(nw=random.uniform(1, 3),
                                   krwend=random.uniform(0.5, 1))
            wo_high.add_corey_water(nw=random.uniform(1, 3),
                                    krwend=random.uniform(0.5, 1))
            wo_low.add_corey_oil(now=random.uniform(1, 3),
                                 kroend=random.uniform(0.5, 1))
            wo_high.add_corey_oil(now=random.uniform(1, 3),
                                  kroend=random.uniform(0.5, 1))
        elif curvetype == "let":
            wo_low.add_LET_water(
                l=random.uniform(1, 3),
                e=random.uniform(1, 3),
                t=random.uniform(1, 3),
                krwend=random.uniform(0.5, 1),
            )
            wo_high.add_LET_water(
                l=random.uniform(1, 3),
                e=random.uniform(1, 3),
                t=random.uniform(1, 3),
                krwend=random.uniform(0.5, 1),
            )
            wo_low.add_LET_oil(
                l=random.uniform(1, 3),
                e=random.uniform(1, 3),
                t=random.uniform(1, 3),
                kroend=random.uniform(0.5, 1),
            )
            wo_high.add_LET_oil(
                l=random.uniform(1, 3),
                e=random.uniform(1, 3),
                t=random.uniform(1, 3),
                kroend=random.uniform(0.5, 1),
            )
        else:
            print("ERROR, wrong curvetype")
        color = cmap(random.random())
        for tparam in np.arange(0, 1, 1.0 / interpolants):
            wo_ip = utils.interpolate_wo(wo_low, wo_high, tparam)
            wo_ip.plotkrwkrow(mpl_ax, color=color, alpha=0.3)
    plt.show()
Beispiel #4
0
def test_ip_kromax():
    """Test behaviour of kroend/kromax under interpolation"""
    wo_low = WaterOil(swl=0, swcr=0.1, sorw=0.2)
    wo_low.add_corey_water(nw=2, krwend=0.5, krwmax=0.7)
    wo_low.add_corey_oil(now=2, kroend=0.6, kromax=0.9)

    wo_high = WaterOil(swl=0.02, swcr=0.05, sorw=0.1)
    wo_high.add_corey_water(nw=2, krwend=0.5, krwmax=0.72)
    wo_high.add_corey_oil(now=2, kroend=0.6, kromax=0.8)

    # Interpolate to midpoint between the curves above
    wo_ip = utils.interpolate_wo(wo_low, wo_high, 0.5)

    # kromax at mean swl:
    assert float_df_checker(wo_ip.table, "sw", 0.01, "krow", 0.85)
    # kroend is 0.6 in low and high, but swcr has changed:
    assert float_df_checker(wo_ip.table, "sw", 0.075, "krow", 0.6)

    assert float_df_checker(wo_ip.table, "sw", 1, "krw", 0.71)
    assert float_df_checker(wo_ip.table, "sw", 1 - 0.15, "krw", 0.5)
Beispiel #5
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())
Beispiel #6
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