コード例 #1
0
def test_wateroil_swir(swirr):
    """Check that the saturation values are valid for all swirr"""
    wateroil = WaterOil(swirr=swirr)
    check_table(wateroil.table)
コード例 #2
0
ファイル: test_factory.py プロジェクト: whl19910402/pyscal
def test_factory_wateroil():
    """Test that we can create curves from dictionaries of parameters"""
    pyscal_factory = PyscalFactory()

    # Factory refuses to create incomplete defaulted objects.
    with pytest.raises(ValueError):
        pyscal_factory.create_water_oil()

    with pytest.raises(TypeError):
        # (it must be a dictionary)
        # pylint: disable=unexpected-keyword-arg
        pyscal_factory.create_water_oil(swirr=0.01)  # noqa

    wateroil = pyscal_factory.create_water_oil(
        dict(
            swirr=0.01,
            swl=0.1,
            bogus="foobar",
            tag="Good sand",
            nw=3,
            now=2,
            krwend=0.2,
            krwmax=0.5,
        )
    )
    assert isinstance(wateroil, WaterOil)
    assert wateroil.swirr == 0.01
    assert wateroil.swl == 0.1
    assert wateroil.tag == "Good sand"
    assert "krw" in wateroil.table
    assert "Corey" in wateroil.krwcomment
    assert wateroil.table["krw"].max() == 0.2  # Because sorw==0 by default
    check_table(wateroil.table)
    sat_table_str_ok(wateroil.SWOF())
    sat_table_str_ok(wateroil.SWFN())

    wateroil = pyscal_factory.create_water_oil(
        dict(nw=3, now=2, sorw=0.1, krwend=0.2, krwmax=0.5)
    )
    assert isinstance(wateroil, WaterOil)
    assert "krw" in wateroil.table
    assert "Corey" in wateroil.krwcomment
    assert wateroil.table["krw"].max() == 0.5
    check_table(wateroil.table)
    sat_table_str_ok(wateroil.SWOF())
    sat_table_str_ok(wateroil.SWFN())

    # Ambiguous works, but we don't guarantee that this results
    # in LET or Corey.
    wateroil = pyscal_factory.create_water_oil(dict(nw=3, Lw=2, Ew=2, Tw=2, now=3))
    assert "krw" in wateroil.table
    assert "Corey" in wateroil.krwcomment or "LET" in wateroil.krwcomment
    check_table(wateroil.table)
    sat_table_str_ok(wateroil.SWOF())
    sat_table_str_ok(wateroil.SWFN())

    # Mixing Corey and LET
    wateroil = pyscal_factory.create_water_oil(dict(Lw=2, Ew=2, Tw=2, krwend=1, now=4))
    assert isinstance(wateroil, WaterOil)
    assert "krw" in wateroil.table
    assert wateroil.table["krw"].max() == 1.0
    assert "LET" in wateroil.krwcomment
    check_table(wateroil.table)
    sat_table_str_ok(wateroil.SWOF())
    sat_table_str_ok(wateroil.SWFN())

    wateroil = pyscal_factory.create_water_oil(
        dict(Lw=2, Ew=2, Tw=2, Low=3, Eow=3, Tow=3, krwend=0.5)
    )
    assert isinstance(wateroil, WaterOil)
    assert "krw" in wateroil.table
    assert "krow" in wateroil.table
    assert wateroil.table["krw"].max() == 0.5
    assert wateroil.table["krow"].max() == 1
    assert "LET" in wateroil.krwcomment
    assert "LET" in wateroil.krowcomment
    check_table(wateroil.table)
    sat_table_str_ok(wateroil.SWOF())
    sat_table_str_ok(wateroil.SWFN())

    # Add capillary pressure
    wateroil = pyscal_factory.create_water_oil(
        dict(swl=0.1, nw=1, now=1, a=2, b=-1, poro_ref=0.2, perm_ref=100, drho=200)
    )
    assert "pc" in wateroil.table
    assert wateroil.table["pc"].max() > 0.0
    assert "Simplified J" in wateroil.pccomment
    check_table(wateroil.table)
    sat_table_str_ok(wateroil.SWOF())
    sat_table_str_ok(wateroil.SWFN())

    # Test that the optional gravity g is picked up:
    wateroil = pyscal_factory.create_water_oil(
        dict(swl=0.1, nw=1, now=1, a=2, b=-1, poro_ref=0.2, perm_ref=100, drho=200, g=0)
    )
    assert "pc" in wateroil.table
    assert wateroil.table["pc"].max() == 0.0
    check_table(wateroil.table)
    sat_table_str_ok(wateroil.SWOF())
    sat_table_str_ok(wateroil.SWFN())

    # Test petrophysical simple J:
    wateroil = pyscal_factory.create_water_oil(
        dict(
            swl=0.1,
            nw=1,
            now=1,
            a_petro=2,
            b_petro=-1,
            poro_ref=0.2,
            perm_ref=100,
            drho=200,
        )
    )
    assert "pc" in wateroil.table
    assert wateroil.table["pc"].max() > 0.0
    assert "etrophysic" in wateroil.pccomment
    check_table(wateroil.table)
    sat_table_str_ok(wateroil.SWOF())
    sat_table_str_ok(wateroil.SWFN())

    # One pc param missing:
    wateroil = pyscal_factory.create_water_oil(
        dict(swl=0.1, nw=1, now=1, a=2, b=-1, perm_ref=100, drho=200, g=0)
    )
    assert "pc" not in wateroil.table
コード例 #3
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,
):
    # pylint: disable=too-many-arguments,too-many-locals
    """Test many possible combinations of interpolation between two
    Corey gasoil curves, looking for numerical corner cases"""
    h = 0.01
    go_low = GasOil(swl=swl, sgcr=sgcr, sorg=sorg, h=h)
    go_high = GasOil(
        swl=swl + dswlhigh, sgcr=sgcr + dsgcr, sorg=max(sorg - dsorg, 0), h=h
    )
    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 = interpolate_go(go_low, go_high, t)
        check_table(go_ip.table)
        ips.append(go_ip)
        assert 0 < go_ip.crosspoint() < 1

        # sgcr is non-trivial, if exponents are high, an effective sgcr might
        # be larger than the value used to initialize the curve. Try to be
        # permissive enough here. This can even cause the interpolant to be
        # outside the low-high envelope, but it is the way it is supposed to
        # be when sgcr is interpolated separately.
        sgcr_low = min(
            go_low.sgcr, go_low.estimate_sgcr(), go_high.sgcr, go_high.estimate_sgcr()
        )
        sgcr_high = max(
            go_low.sgcr, go_low.estimate_sgcr(), go_high.sgcr, go_high.estimate_sgcr()
        )

        sgcr_ip = go_ip.estimate_sgcr()

        sgcr_lower_bound_ok = sgcr_low - h - epsilon < sgcr_ip
        sgcr_upper_bound_ok = sgcr_ip < sgcr_high + h + epsilon

        assert sgcr_lower_bound_ok
        assert sgcr_upper_bound_ok

    # 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)
        _, 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
コード例 #4
0
def test_interpolate_wo(
    swl,
    dswcr,
    dswlhigh,
    sorw,
    nw_l,
    nw_h,
    now_l,
    now_h,
    krwend_l,
    krwend_h,
    kroend_l,
    kroend_h,
):
    # pylint: disable=too-many-arguments,too-many-locals
    """
    Generate two random WaterOil curves, interpolate 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(nw=nw_l, krwend=krwend_l)
    wo_high.add_corey_water(nw=nw_h, krwend=krwend_h)
    wo_low.add_corey_oil(now=now_l, kroend=kroend_l)
    wo_high.add_corey_oil(now=now_h, kroend=kroend_h)
    ips = []
    ip_dist = 0.05
    for tparam in np.arange(0, 1 + ip_dist, ip_dist):
        wo_ip = interpolate_wo(wo_low, wo_high, tparam)
        check_table(wo_ip.table)
        assert wo_ip.tag
        ips.append(wo_ip)
        assert 0 < wo_ip.crosspoint() < 1

    # Distances between low and interpolants:
    dists = [
        (wo_low.table - interp.table)[["krw", "krow"]].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)[["krw", "krow"]].sum().sum() < 0.01

    # Distances between low and interpolants:
    dists = [
        (wo_low.table - interp.table)[["krw", "krow"]].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)

        _, mpl_ax = plt.subplots()
        wo_low.plotkrwkrow(mpl_ax=mpl_ax, color="red")
        wo_high.plotkrwkrow(mpl_ax=mpl_ax, color="blue")
        for interp in ips:
            interp.plotkrwkrow(mpl_ax=mpl_ax, color="green")
        plt.show()
        assert False
コード例 #5
0
def test_wateroil_sorw(sorw):
    """Check that the saturation values are valid for all sorw"""
    wateroil = WaterOil(sorw=sorw)
    check_table(wateroil.table)
コード例 #6
0
def test_scalrecommendation():
    """Testing making SCAL rec from dict of dict."""
    pyscal_factory = PyscalFactory()

    scal_input = {
        "low": {
            "nw": 2,
            "now": 4,
            "ng": 1,
            "nog": 2
        },
        "BASE": {
            "nw": 3,
            "NOW": 3,
            "ng": 1,
            "nog": 2
        },
        "high": {
            "nw": 4,
            "now": 2,
            "ng": 1,
            "nog": 3
        },
    }
    scal = pyscal_factory.create_scal_recommendation(scal_input)

    with pytest.raises(ValueError, match="Input must be a dict"):
        pyscal_factory.create_scal_recommendation("low")

    # (not supported yet to make WaterOil only..)
    interp = scal.interpolate(-0.5)
    sat_table_str_ok(interp.SWOF())
    sat_table_str_ok(interp.SGOF())
    sat_table_str_ok(interp.SLGOF())
    sat_table_str_ok(interp.SOF3())
    check_table(interp.wateroil.table)
    check_table(interp.gasoil.table)

    # Check that we error if any of the parameters above is missing:
    for case in ["low", "BASE", "high"]:
        copy1 = scal_input.copy()
        del copy1[case]
        with pytest.raises(ValueError):
            pyscal_factory.create_scal_recommendation(copy1)

    go_only = scal_input.copy()
    del go_only["low"]["now"]
    del go_only["low"]["nw"]
    gasoil = pyscal_factory.create_scal_recommendation(go_only)
    assert gasoil.low.wateroil is None
    assert gasoil.base.wateroil is not None
    assert gasoil.high.wateroil is not None
    # SCALrecommendation of gasoil only works as long as you
    # don't try to ask for water data:
    assert "SGFN" in gasoil.interpolate(-0.4).SGFN()
    assert "SWOF" not in gasoil.interpolate(-0.2).SWOF()

    basehigh = scal_input.copy()
    del basehigh["low"]
    with pytest.raises(ValueError, match='"low" case not supplied'):
        pyscal_factory.create_scal_recommendation(basehigh)

    baselow = scal_input.copy()
    del baselow["high"]
    with pytest.raises(ValueError, match='"high" case not supplied'):
        pyscal_factory.create_scal_recommendation(baselow)

    with pytest.raises(
            ValueError,
            match="All values in parameter dict must be dictionaries"):

        pyscal_factory.create_scal_recommendation({
            "low": [1, 2],
            "base": {
                "swl": 0.1
            },
            "high": {
                "swl": 0.1
            }
        })