Ejemplo n.º 1
0
def test_simple_j():
    """Simple test of the simple J function correlation"""
    wateroil = WaterOil(swl=0.01)
    wateroil.add_simple_J()  # swl set to zero will give infinite pc
    check_table(wateroil.table)
    assert wateroil.pccomment

    wateroil = WaterOil(swl=0)
    with pytest.raises(ValueError, match="swl must be larger than zero"):
        wateroil.add_simple_J()

    # Zero gravity:
    wateroil = WaterOil(swl=0.01)
    wateroil.add_simple_J(g=0)
    assert wateroil.table["PC"].unique() == 0.0

    # This should give back Sw:
    # This ensures that density and gravity scaling is correct
    wateroil.add_simple_J(a=1, b=1, poro_ref=1, perm_ref=1, drho=1000, g=100)
    assert (wateroil.table["PC"] - wateroil.table["SW"]).sum() < 0.00001
    # (check_table() will fail on this, when b > 0)

    # Some values seen in real life:
    wateroil.add_simple_J(a=100, b=-1.5, poro_ref=0.12, perm_ref=100, drho=200)
    check_table(wateroil.table)
    assert "Simplified" in wateroil.pccomment
    assert "a=100" in wateroil.pccomment
    assert "b=-1.5" in wateroil.pccomment
    wateroil.add_corey_oil()
    wateroil.add_corey_water()
    swof = wateroil.SWOF()
    assert isinstance(swof, str)
    assert swof
    sat_table_str_ok(swof)
    sat_table_str_ok(wateroil.SWFN())
Ejemplo n.º 2
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 WaterOil (red):\n"
        + wo_low.swcomment
        + wo_low.krwcomment
        + wo_low.krowcomment
        + wo_low.pccomment
    )
    print(
        " ** High curve WaterOil (blue):\n"
        + wo_high.swcomment
        + wo_high.krwcomment
        + wo_high.krowcomment
        + wo_high.pccomment
    )

    _, 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.interpolation.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.interpolation.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.interpolation.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()
Ejemplo n.º 3
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
Ejemplo n.º 4
0
def test_plotting():
    """Test that plotting code pass through (nothing displayed)"""
    wateroil = WaterOil(swl=0.1, h=0.1)
    wateroil.add_corey_water()
    wateroil.add_corey_oil()
    wateroil.plotkrwkrow(mpl_ax=matplotlib.pyplot.subplots()[1])

    wateroil.add_simple_J()
    wateroil.plotpc(mpl_ax=matplotlib.pyplot.subplots()[1])
Ejemplo n.º 5
0
def test_normalize_pc(swirr, dswl):
    """Test that we can normalize a pc curve"""
    wateroil = WaterOil(swirr=swirr, swl=swirr + dswl)
    wateroil.add_simple_J()
    pc_max = wateroil.table["pc"].max()
    pc_min = wateroil.table["pc"].min()

    pc_fn = normalize_pc(wateroil)
    assert np.isclose(pc_fn(0), pc_max)
    assert np.isclose(pc_fn(1), pc_min)
Ejemplo n.º 6
0
def test_simple_J_random(a, b, poro_ref, perm_ref, drho, g):
    """Test different J-function parameters.

    Parameter ranges tested through hypothesis are limited, as not
    every number is realistic. Way outside the tested intervals, you
    can get AssertionErrors or the capillary pressure may not be
    monotonically decreasing within machine precision.
    """
    wo = WaterOil(swl=0.01)
    wo.add_simple_J(a=a, b=b, poro_ref=poro_ref, perm_ref=perm_ref, drho=drho, g=g)
    check_table(wo.table)
Ejemplo n.º 7
0
def test_normalize_emptypc():
    """Test that we can normalize both
    when pc is missing, and when it is all zero"""
    wateroil = WaterOil()
    pc_fn = normalize_pc(wateroil)
    assert np.isclose(pc_fn(0), 0)
    assert np.isclose(pc_fn(1), 0)

    wateroil = WaterOil(swl=0.01)
    wateroil.add_simple_J(g=0)
    pc_fn = normalize_pc(wateroil)
    assert np.isclose(pc_fn(0), 0)
    assert np.isclose(pc_fn(1), 0)
Ejemplo n.º 8
0
def test_simple_J():
    wo = WaterOil(swl=0.01)
    wo.add_simple_J()  # swl set to zero will give infinite pc
    check_table(wo.table)
    assert wo.pccomment

    # Zero gravity:
    wo.add_simple_J(g=0)
    assert wo.table.pc.unique() == 0.0

    # This should give back Sw:
    # This ensures that density and gravity scaling is correct
    wo.add_simple_J(a=1, b=1, poro_ref=1, perm_ref=1, drho=1000, g=100)
    assert (wo.table["pc"] - wo.table["sw"]).sum() < 0.00001
    # (check_table() will fail on this, when b > 0)

    # Some values seen in real life:
    wo.add_simple_J(a=100, b=-1.5, poro_ref=0.12, perm_ref=100, drho=200)
    check_table(wo.table)
    assert "Simplified" in wo.pccomment
    assert "a=100" in wo.pccomment
    assert "b=-1.5" in wo.pccomment
    wo.add_corey_oil()
    wo.add_corey_water()
    swof = wo.SWOF()
    assert isinstance(swof, str)
    assert swof
Ejemplo n.º 9
0
def main():
    """Entry point for interactive tests, will run
    some tests where the intention is that the user will
    look at what is displayed, and potentially see if
    something looks really bad"""
    print("-- **********************************")
    print("-- Manual check of output")
    swof = WaterOil(tag="Good sand, SATNUM 1", h=0.1, swl=0.1)
    swof.add_corey_water()
    swof.add_LET_water()
    swof.add_corey_oil()
    swof.add_simple_J()

    print(swof.SWOF())

    sgof = GasOil(tag="Good sand, SATNUM 1", h=0.1)
    sgof.add_corey_gas()
    sgof.add_corey_oil()
    print(sgof.SGOF())

    print("")
    print("-- ******************************************")
    print("-- Manual visual check of interpolation in LET-space")
    print("--  Check:")
    print("--   * green curves are between red and blue blue line")
    print("-- (close plot window to continue)")
    for _ in range(0, 5):
        test_interpolate_wo()
        test_interpolate_go()
        test_interpolate_gw()
    print("")
    print("-- ******************************************")
    print("-- Manual visual check of interpolation in LET-space")
    print("--  Check:")
    print("--   * Red curves are between dotted and solid blue line")
    print("--   * Green curves are between solid blue and dashed")
    print("-- (close plot window to continue)")
    interpolateplottest()

    print("")
    print("-- ***********************************************")
    print("-- Span of LET curves when LET parameters are varied")
    print("-- within the bounds of the parameters of the red curves")
    print(
        "-- Blue dim curves are allowed to go outside the red boundary curves")
    print("-- (close plot window to continue)")
    letspan()
Ejemplo n.º 10
0
def main():
    print("-- **********************************")
    print("-- Manual check of output")
    swof = WaterOil(tag="Good sand, SATNUM 1", h=0.1, swl=0.1)
    swof.add_corey_water()
    swof.add_LET_water()
    swof.add_corey_oil()
    swof.add_simple_J()

    print(swof.SWOF())

    sgof = GasOil(tag="Good sand, SATNUM 1", h=0.1)
    sgof.add_corey_gas()
    sgof.add_corey_oil()
    print(sgof.SGOF())

    print("")
    print("-- ***************************************")
    print("-- Test of one Corey curve set")
    print("-- Check that all the defined endpoints are correct")
    print("-- (close plot window to continue)")
    testplot()

    print("")
    print("-- ******************************************")
    print("-- Manual visual check of interpolation in LET-space")
    print("--  Check:")
    print("--   * Red curves are between dotted and solid blue line")
    print("--   * Green curves are between solid blue and dashed")
    print("-- (close plot window to continue)")
    interpolateplottest()

    print("")
    print("-- ***********************************************")
    print("-- Span of LET curves when LET parameters are varied")
    print("-- within the bounds of the parameters of the red curves")
    print("-- Blue dim curves are allowed to go outside the red boundary curves")
    print("-- (close plot window to continue)")
    letspan()
Ejemplo n.º 11
0
def test_simple_J():
    wo = WaterOil(swl=0.01)
    wo.add_simple_J()  # swl set to zero will give infinite pc
    check_table(wo.table)
    assert wo.pccomment

    # Zero gravity:
    wo.add_simple_J(g=0)
    assert wo.table.pc.unique() == 0.0

    # This should give back Sw:
    # This ensures that density and gravity scaling is correct
    wo.add_simple_J(a=1, b=1, poro_ref=1, perm_ref=1, drho=1000, g=100)
    assert (wo.table["pc"] - wo.table["sw"]).sum() < 0.00001
Ejemplo n.º 12
0
    def create_water_oil(params=None):
        """Create a WaterOil object from a dictionary of parameters.

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

        Don't rely on behaviour of you supply both Corey and LET at
        the same time.

        Parameter names in the dictionary are case insensitive. You
        can use Swirr, swirr, sWirR, swiRR etc.

        NB: the add_LET_* methods have the names 'l', 'e' and 't'
        in their signatures, which is not precise enough in this
        context, so we require e.g. 'Lw' and 'Low' (which both will be
        translated to 'l')

        Recognized parameters:
          swirr, swl, swcr, sorw, h, tag, nw, now, krwmax, krwend,
          lw, ew, tw, low, eow, tow, lo, eo, to, kromax, krowend,
          a, a_petro, b, b_petro, poro_ref, perm_ref, drho,
          a, b, poro, perm, sigma_costau

        Args:
            params (dict): Dictionary with parameters describing
                the WaterOil object.
        """
        if not params:
            params = dict()
        if not isinstance(params, dict):
            raise TypeError(
                "Parameter to create_water_oil 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()}

        # Allowing sending in NaN values, delete those keys.
        params = filter_nan_from_dict(params)

        usedparams = set()
        # No requirements to the base objects, defaults are ok.
        wateroil = WaterOil(**slicedict(params, WO_INIT))
        usedparams = usedparams.union(set(slicedict(params, WO_INIT).keys()))
        logger.info("Initialized WaterOil object from parameters %s",
                    str(list(usedparams)))

        # Water curve
        params_corey_water = slicedict(params,
                                       WO_COREY_WATER + WO_WATER_ENDPOINTS)
        params_let_water = slicedict(params, WO_LET_WATER + WO_WATER_ENDPOINTS)
        if set(WO_COREY_WATER).issubset(set(params_corey_water)):
            wateroil.add_corey_water(**params_corey_water)
            usedparams = usedparams.union(set(params_corey_water.keys()))
            logger.info(
                "Added Corey water to WaterOil object from parameters %s",
                str(params_corey_water.keys()),
            )
        elif set(WO_LET_WATER).issubset(set(params_let_water)):
            params_let_water["l"] = params_let_water.pop("lw")
            params_let_water["e"] = params_let_water.pop("ew")
            params_let_water["t"] = params_let_water.pop("tw")
            wateroil.add_LET_water(**params_let_water)
            usedparams = usedparams.union(set(params_let_water.keys()))
            logger.info(
                "Added LET water to WaterOil object from parameters %s",
                str(params_let_water.keys()),
            )
        else:
            logger.warning(
                "Missing or ambiguous parameters for water curve in WaterOil object"
            )

        # Oil curve:
        params_corey_oil = slicedict(params, WO_COREY_OIL + WO_OIL_ENDPOINTS)
        params_let_oil = slicedict(
            params, WO_LET_OIL + WO_LET_OIL_ALT + WO_OIL_ENDPOINTS)
        if set(WO_COREY_OIL).issubset(set(params_corey_oil)):
            if "krowend" in params_corey_oil:
                params_corey_oil["kroend"] = params_corey_oil.pop("krowend")
            wateroil.add_corey_oil(**params_corey_oil)
            logger.info(
                "Added Corey water to WaterOil object from parameters %s",
                str(params_corey_oil.keys()),
            )
        elif set(WO_LET_OIL).issubset(set(params_let_oil)):
            params_let_oil["l"] = params_let_oil.pop("low")
            params_let_oil["e"] = params_let_oil.pop("eow")
            params_let_oil["t"] = params_let_oil.pop("tow")
            if "krowend" in params_let_oil:
                params_let_oil["kroend"] = params_let_oil.pop("krowend")
            wateroil.add_LET_oil(**params_let_oil)
            logger.info(
                "Added LET water to WaterOil object from parameters %s",
                str(params_let_oil.keys()),
            )
        elif set(WO_LET_OIL_ALT).issubset(set(params_let_oil)):
            params_let_oil["l"] = params_let_oil.pop("lo")
            params_let_oil["e"] = params_let_oil.pop("eo")
            params_let_oil["t"] = params_let_oil.pop("to")
            if "krowend" in params_let_oil:
                params_let_oil["kroend"] = params_let_oil.pop("krowend")
            wateroil.add_LET_oil(**params_let_oil)
            logger.info(
                "Added LET water to WaterOil object from parameters %s",
                str(params_let_oil.keys()),
            )
        else:
            logger.warning(
                "Missing or ambiguous parameters for oil curve in WaterOil object"
            )

        # Capillary pressure:
        params_simple_j = slicedict(params, WO_SIMPLE_J + ["g"])
        params_norm_j = slicedict(params, WO_NORM_J)
        params_simple_j_petro = slicedict(params, WO_SIMPLE_J_PETRO + ["g"])
        if set(WO_SIMPLE_J).issubset(set(params_simple_j)):
            wateroil.add_simple_J(**params_simple_j)
        elif set(WO_SIMPLE_J_PETRO).issubset(set(params_simple_j_petro)):
            params_simple_j_petro["a"] = params_simple_j_petro.pop("a_petro")
            params_simple_j_petro["b"] = params_simple_j_petro.pop("b_petro")
            wateroil.add_simple_J_petro(**params_simple_j_petro)
        elif set(WO_NORM_J).issubset(set(params_norm_j)):
            wateroil.add_normalized_J(**params_norm_j)
        else:
            logger.warning(
                ("Missing or ambiguous parameters for capillary pressure in "
                 "WaterOil object. Using zero."))
        if not wateroil.selfcheck():
            raise ValueError((
                "Incomplete WaterOil object, some parameters missing to factory"
            ))
        return wateroil
Ejemplo n.º 13
0
    def create_water_oil(params=None):
        """Create a WaterOil object from a dictionary of parameters.

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

        Don't rely on behaviour of you supply both Corey and LET at
        the same time.

        Parameter names in the dictionary are case insensitive. You
        can use Swirr, swirr, sWirR, swiRR etc.

        NB: the add_LET_* methods have the names 'l', 'e' and 't'
        in their signatures, which is not precise enough in this
        context, so we require e.g. 'Lw' and 'Low' (which both will be
        translated to 'l')
        """
        if not params:
            params = dict()
        if not isinstance(params, dict):
            raise TypeError(
                "Parameter to create_water_oil must be a dictionary")

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

        usedparams = set()
        # No requirements to the base objects, defaults are ok.
        wateroil = WaterOil(**slicedict(params, WO_INIT))
        usedparams = usedparams.union(set(slicedict(params, WO_INIT).keys()))
        logging.info("Initialized WaterOil object from parameters %s",
                     str(list(usedparams)))

        # Water curve
        params_corey_water = slicedict(params,
                                       WO_COREY_WATER + WO_WATER_ENDPOINTS)
        params_let_water = slicedict(params, WO_LET_WATER + WO_WATER_ENDPOINTS)
        if set(WO_COREY_WATER).issubset(set(params_corey_water)):
            wateroil.add_corey_water(**params_corey_water)
            usedparams = usedparams.union(set(params_corey_water.keys()))
            logging.info(
                "Added Corey water to WaterOil object from parameters %s",
                str(params_corey_water.keys()),
            )
        elif set(WO_LET_WATER).issubset(set(params_let_water)):
            params_let_water["l"] = params_let_water.pop("lw")
            params_let_water["e"] = params_let_water.pop("ew")
            params_let_water["t"] = params_let_water.pop("tw")
            wateroil.add_LET_water(**params_let_water)
            usedparams = usedparams.union(set(params_let_water.keys()))
            logging.info(
                "Added LET water to WaterOil object from parameters %s",
                str(params_let_water.keys()),
            )
        else:
            logging.warning(
                "Missing or ambiguous parameters for water curve in WaterOil object"
            )

        # Oil curve:
        params_corey_oil = slicedict(params, WO_COREY_OIL + WO_OIL_ENDPOINTS)
        params_let_oil = slicedict(
            params, WO_LET_OIL + WO_LET_OIL_ALT + WO_OIL_ENDPOINTS)
        if set(WO_COREY_OIL).issubset(set(params_corey_oil)):
            wateroil.add_corey_oil(**params_corey_oil)
            logging.info(
                "Added Corey water to WaterOil object from parameters %s",
                str(params_corey_oil.keys()),
            )
        elif set(WO_LET_OIL).issubset(set(params_let_oil)):
            params_let_oil["l"] = params_let_oil.pop("low")
            params_let_oil["e"] = params_let_oil.pop("eow")
            params_let_oil["t"] = params_let_oil.pop("tow")
            wateroil.add_LET_oil(**params_let_oil)
            logging.info(
                "Added LET water to WaterOil object from parameters %s",
                str(params_let_oil.keys()),
            )
        elif set(WO_LET_OIL_ALT).issubset(set(params_let_oil)):
            params_let_oil["l"] = params_let_oil.pop("lo")
            params_let_oil["e"] = params_let_oil.pop("eo")
            params_let_oil["t"] = params_let_oil.pop("to")
            wateroil.add_LET_oil(**params_let_oil)
            logging.info(
                "Added LET water to WaterOil object from parameters %s",
                str(params_let_oil.keys()),
            )
        else:
            logging.warning(
                "Missing or ambiguous parameters for oil curve in WaterOil object"
            )

        # Capillary pressure:
        params_simple_j = slicedict(params, WO_SIMPLE_J + ["g"])
        params_norm_j = slicedict(params, WO_NORM_J)
        if set(WO_SIMPLE_J).issubset(set(params_simple_j)):
            wateroil.add_simple_J(**params_simple_j)
        elif set(WO_NORM_J).issubset(set(params_norm_j)):
            wateroil.add_normalized_J(**params_norm_j)
        else:
            logging.warning(
                "Missing or ambiguous parameters for capillary pressure in WaterOil object. Using zero."
            )
        if not wateroil.selfcheck():
            raise ValueError(("Incomplete WaterOil object, some parameters "
                              "missing to factory"))
        return wateroil