def test_swfn(): """Test that we can dump SWFN without giving oil relperm""" wateroil = WaterOil(h=0.1) wateroil.add_corey_water() swfnstr = wateroil.SWFN() assert "SWFN" in swfnstr assert len(swfnstr) > 15
def test_wo_fromtable_multiindex(): """Test that we accept multiindex dataframes, (but a warning will be issued)""" # Test an example dataframe that easily gets sent in from ecl2df.satfunc: df1 = pd.DataFrame( columns=["KEYWORD", "SATNUM", "SW", "KRW", "KROW", "PC"], data=[ ["SWOF", 1, 0, 0, 1, 2], ["SWOF", 1, 0.5, 0.5, 0.5, 1], ["SWOF", 1, 1, 1, 0, 0], ], ).set_index(["KEYWORD", "SATNUM"]) # Check that we have a MultiIndex: assert len(df1.index.names) == 2 wateroil = WaterOil(h=0.1) wateroil.add_fromtable(df1, swcolname="SW", krwcolname="KRW", krowcolname="KROW", pccolname="PC") assert "krw" in wateroil.table.columns assert "krow" in wateroil.table.columns assert "pc" in wateroil.table.columns check_table(wateroil.table)
def test_wateroil_dual(param1, param2): """Test combination of 2 floats as parameters""" try: wateroil = WaterOil(swl=param1, sorw=param2) check_table(wateroil.table) # Will fail when swl > 1 - sorw except AssertionError: pass try: wateroil = WaterOil(swl=param1, swirr=param2) check_table(wateroil.table) except AssertionError: pass try: wateroil = WaterOil(swcr=param1, sorw=param2) check_table(wateroil.table) except AssertionError: pass try: wateroil = WaterOil(swirr=param1, sorw=param2) check_table(wateroil.table) except AssertionError: pass
def test_pyscallist_basic(): """Test that the class acts like a list""" p_list = PyscalList() assert isinstance(p_list, PyscalList) assert not p_list p_list.append(None) assert not p_list p_list.append([]) assert not p_list with pytest.raises(ValueError): p_list.append(1) with pytest.raises(ValueError): p_list.append("foo") p_list.append(WaterOil()) assert len(p_list) == 1 assert isinstance(p_list[1], WaterOil) with pytest.raises(IndexError): # pylint: disable=W0104 p_list[0] with pytest.raises(IndexError): # pylint: disable=W0104 p_list[2] with pytest.raises(ValueError): p_list.append(GasOil()) assert len(p_list) == 1 p_list.append(WaterOil()) assert len(p_list) == 2
def test_wateroil_dual(p1, p2): try: wo = WaterOil(swl=p1, sorw=p2) check_table(wo.table) # Will fail when swl > 1 - sorw except AssertionError: pass try: wo = WaterOil(swl=p1, swirr=p2) check_table(wo.table) except AssertionError: pass try: wo = WaterOil(swcr=p1, sorw=p2) check_table(wo.table) except AssertionError: pass try: wo = WaterOil(swirr=p1, sorw=p2) check_table(wo.table) except AssertionError: pass
def test_linear_input(h, sw_mid): """Linear input creates difficulties with sorw, which is used in add_fromtable(). The intention of the test is to avoid crashes when add_fromtable(). estimate_sorw() is unreliable on linear input, and returns 0 or 1 on the given test dataset. Correctness of sorw should not be needed for add_fromtable(). This tests fails in pyscal v0.7.7""" dframe = pd.DataFrame( columns=["SW", "KRW", "KROW", "PC"], data=[[sw, sw, 1 - sw, 1 - sw] for sw in [0, sw_mid, 1.0]], ) wateroil = WaterOil(h=h, swl=0) wateroil.add_fromtable(dframe) assert wateroil.selfcheck() # GasOil did not fail in v0.7.7, but test anyway: gasoil = GasOil(h=h, swl=0) gasoil.add_fromtable(dframe, sgcolname="SW", krgcolname="KRW", krogcolname="KROW", pccolname="PCOW") assert gasoil.selfcheck()
def test_normalized_j(): """Test the normalized J-function correlation for capillary pressure""" wateroil = WaterOil(swirr=0.1, h=0.1) with pytest.raises(ValueError): wateroil.add_normalized_J(a=0.5, b=-0.2, poro=0.2, perm=10, sigma_costau=30) wateroil = WaterOil(swirr=0, swl=0.1, h=0.1) wateroil.add_normalized_J(a=0.5, b=-0.2, poro=0.2, perm=10, sigma_costau=30) check_table(wateroil.table) # Sample numerical tests taken from a prior implementation # NB: Prior implementation created Pc in atm, we create in bar bar_to_atm = 1.0 / 1.01325 wateroil.add_normalized_J(a=0.22, b=-0.5, perm=100, poro=0.2, sigma_costau=30) float_df_checker(wateroil.table, "sw", 0.1, "pc", 2.039969 * bar_to_atm) float_df_checker(wateroil.table, "sw", 0.6, "pc", 0.056666 * bar_to_atm) float_df_checker(wateroil.table, "sw", 1.0, "pc", 0.02040 * bar_to_atm)
def test_ow_fromtable_h(h): df1 = pd.DataFrame( columns=["Sw", "krw", "krow", "pcow"], data=[[0.15, 0, 1, 3], [0.89, 1, 0, 0.1], [1, 1, 0, 0]], ) wo = WaterOil(h=h, swl=0.15, sorw=1 - 0.89) wo.add_fromtable(df1) check_wo_table(wo.table)
def test_wo_fromtable_h(h): """Test making curves from tabular data with random stepsize h""" df1 = pd.DataFrame( columns=["Sw", "krw", "krow", "pcow"], data=[[0.15, 0, 1, 3], [0.89, 1, 0, 0.1], [1, 1, 0, 0]], ) wateroil = WaterOil(h=h, swl=0.15, sorw=1 - 0.89) wateroil.add_fromtable(df1) check_table(wateroil.table)
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)
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)
def test_norm_J_pc_random(swirr, swl, a, b, poro, perm, sigma_costau): """Test many possibilities of Pc-parameters. Outside of the tested range, there are many combination of parameters that can give infinite capillary pressure""" swl = swirr + swl # No point in getting too many AssertionErrors wo = WaterOil(swirr=swirr, swl=swl, h=0.01) try: wo.add_normalized_J(a=a, b=b, perm=perm, poro=poro, sigma_costau=sigma_costau) except (AssertionError, ValueError): # when poro is < 0 f.ex. return check_table(wo.table)
def test_wo_fromtable_simple(): """Test loading a simple curve from a table""" df1 = pd.DataFrame(columns=["SW", "KRW", "KROW", "PC"], data=[[0, 0, 1, 2], [1, 1, 0, 0]]) wateroil = WaterOil(h=0.1) # With wrong names: with pytest.raises(ValueError): # Here we also get a deprecation warning wateroil.add_oilwater_fromtable(df1) # Set names: wateroil.add_fromtable(df1, swcolname="SW") # This didn't do anything, because we did not provide any relperm names assert "krw" not in wateroil.table.columns assert "krow" not in wateroil.table.columns assert "pc" not in wateroil.table.columns # Try again: wateroil.add_fromtable(df1, swcolname="SW", krwcolname="KRW", krowcolname="KROW", pccolname="PC") assert "krw" in wateroil.table.columns assert "krow" in wateroil.table.columns assert "pc" in wateroil.table.columns check_table(wateroil.table)
def test_swcrsorw(): """Test estimate_sorw/swcr for some manually set up cases""" # swcr, sorw, h: testtuples = [ (0, 0.3, 0.1), (0.01, 0.2, 0.1), (0.3, 0.1, 0.1), (0.0, 0.0, 0.1), (0.00001, 0.9, 0.1), (0.0001, 0.99, 0.1), ] for testtuple in testtuples: real_swcr = testtuple[0] real_sorw = testtuple[1] h = testtuple[2] wateroil = WaterOil(swcr=real_swcr, sorw=real_sorw, h=h) wateroil.add_corey_oil(now=2, kroend=0.8) wateroil.add_corey_water(nw=2, krwend=0.9) est_sorw = wateroil.estimate_sorw() mis = abs(est_sorw - real_sorw) print("Testing sorw={}, swcr={} on h={}".format(real_sorw, real_swcr, h)) if mis > 0.01: print("Missed, estimated was {}".format(est_sorw)) assert mis < h + epsilon # Can't guarantee better than h. est_swcr = wateroil.estimate_swcr() mis_swcr = abs(est_swcr - real_swcr) if mis_swcr > 0.0: print("Missed swcr, estimate was {}".format(est_swcr)) assert mis_swcr < h + epsilon
def test_wateroil_tag(tag): """Test that we are unlikely to crash Eclipse by having ugly tag names""" wateroil = WaterOil(h=0.5, tag=tag) wateroil.add_corey_oil() wateroil.add_corey_water() sat_table_str_ok(wateroil.SWOF()) sat_table_str_ok(wateroil.SWFN())
def test_normalized_J(): wo = WaterOil(swirr=0.1, h=0.1) with pytest.raises(ValueError): wo.add_normalized_J(a=0.5, b=-0.2, poro=0.2, perm=10, sigma_costau=30) wo = WaterOil(swirr=0, swl=0.1, h=0.1) wo.add_normalized_J(a=0.5, b=-0.2, poro=0.2, perm=10, sigma_costau=30) check_table(wo.table) # Sample numerical tests taken from a prior implementation # NB: Prior implementation created Pc in atm, we create in bar bar_to_atm = 1.0 / 1.01325 wo.add_normalized_J(a=0.22, b=-0.5, perm=100, poro=0.2, sigma_costau=30) float_df_checker(wo.table, "sw", 0.1, "pc", 2.039969 * bar_to_atm) float_df_checker(wo.table, "sw", 0.6, "pc", 0.056666 * bar_to_atm) float_df_checker(wo.table, "sw", 1.0, "pc", 0.02040 * bar_to_atm)
def test_wateroil_normalization(swirr, swl, swcr, sorw, h, tag): """Shoot with more realistic values and test normalized saturations""" wo = WaterOil(swirr=swirr, swl=swl, swcr=swcr, sorw=sorw, h=h, tag=tag) assert not wo.table.empty assert not wo.table.isnull().values.any() # Check that son is 1 at swcr: assert float_df_checker(wo.table, "sw", wo.swcr, "son", 1) # Check that son is 0 at sorw: if wo.sorw > h: assert float_df_checker(wo.table, "sw", 1 - wo.sorw, "son", 0) # Check that swn is 0 at swcr: assert float_df_checker(wo.table, "sw", wo.swcr, "swn", 0) # Check that swn is 1 at 1 - sorw if wo.sorw > 1 / SWINTEGERS: assert float_df_checker(wo.table, "sw", 1 - wo.sorw, "swn", 1) # Check that swnpc is 0 at swirr and 1 at 1: if wo.swirr >= wo.swl + h: assert float_df_checker(wo.table, "sw", wo.swirr, "swnpc", 0) else: # Let this go, when swirr is too close to swl. We # are not guaranteed to have sw=swirr present pass assert float_df_checker(wo.table, "sw", 1.0, "swnpc", 1)
def test_wateroil_random(swirr, swl, swcr, sorw, h, tag): """Shoot wildly with arguments, the code should throw ValueError or AssertionError when input is invalid, but we don't want other crashes""" try: WaterOil(swirr=swirr, swl=swl, swcr=swcr, sorw=sorw, h=h, tag=tag) except AssertionError: pass
def test_swcr(): wo = WaterOil(swcr=0.3, swl=0.1, sorw=0.1, h=0.05) wo.add_corey_oil(now=2, kroend=0.8) wo.add_corey_water(nw=2, krwend=0.6) est_sorw = wo.estimate_sorw() est_swcr = wo.estimate_swcr() assert np.isclose(est_sorw, 0.1) assert np.isclose(est_swcr, 0.3)
def test_swcr(): """Test that we can locate swcr with a certain accuracy""" wateroil = WaterOil(swcr=0.3, swl=0.1, sorw=0.1, h=0.05) wateroil.add_corey_oil(now=2, kroend=0.8) wateroil.add_corey_water(nw=2, krwend=0.6) est_sorw = wateroil.estimate_sorw() est_swcr = wateroil.estimate_swcr() assert np.isclose(est_sorw, 0.1) assert np.isclose(est_swcr, 0.3)
def test_LET_pc_pd(): wo = WaterOil(swirr=0.1) wo.add_LET_pc_pd(Lp=1, Ep=1, Tp=1, Lt=1, Et=1, Tt=1, Pcmax=10, Pct=5) assert np.isclose(wo.table["pc"].max(), 10) assert np.isclose(wo.table["pc"].min(), 0) # (everything is linear) wo.add_LET_pc_pd(Lp=10, Ep=10, Tp=10, Lt=10, Et=10, Tt=10, Pcmax=10, Pct=5) assert np.isclose(wo.table["pc"].max(), 10) assert np.isclose(wo.table["pc"].min(), 0) # On a plot, you can see a kink at Pc=5. # wo.plotpc() wo = WaterOil(swirr=0.1, sorw=0.4) wo.add_LET_pc_pd(Lp=10, Ep=10, Tp=10, Lt=10, Et=10, Tt=10, Pcmax=5, Pct=2) assert np.isclose(wo.table["pc"].max(), 5) assert np.isclose(wo.table["pc"].min(), 0) # On plot: hard-to-see kink at Pc=2. Linear curve from sw=0.6 to 1 due to sorw. assert len(wo.table[(wo.table["sw"] >= 0.6) & (wo.table["sw"] <= 1)]) == 2
def test_skjaeveland_pc(): """Simple test of Skjæveland capillary pressure correlation""" wateroil = WaterOil(h=0.3, swl=0.2) wateroil.add_skjaeveland_pc(swr=0.1, cw=0.1, co=-0.1, aw=0.1, ao=0.1) check_table(wateroil.table) # Add with wrong numbers wateroil = WaterOil(h=0.3, swl=0.2, sorw=0.3) wateroil.add_skjaeveland_pc(swr=0.8, cw=-0.1, co=0.1, aw=-0.1, ao=-0.1) # (the code returns None when errors occur, no Exception) assert wateroil.pccomment == "" assert "pc" not in wateroil.table
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()
def test_fromtable_types(): """Test loading from a table with incorrect types""" # This frame is valid, but the type was wrong. This # can happen if data is via CSV files, and some other rows # ruin the numerical interpretation of a column. df1 = pd.DataFrame( columns=["SW", "KRW", "KROW", "PC"], data=[["0", "0", "1", "2"], ["1", "1", "0", "0"]], ) wateroil = WaterOil(h=0.1) wateroil.add_fromtable(df1, swcolname="SW", krwcolname="KRW", krowcolname="KROW", pccolname="PC") assert "krw" in wateroil.table.columns assert "krow" in wateroil.table.columns assert "pc" in wateroil.table.columns check_table(wateroil.table) gasoil = GasOil(h=0.1) gasoil.add_fromtable(df1, sgcolname="SW", krgcolname="KRW", krogcolname="KROW", pccolname="PC") assert "krg" in gasoil.table.columns assert "krog" in gasoil.table.columns assert "pc" in gasoil.table.columns check_table(gasoil.table) # But this should not make sense. df2 = pd.DataFrame( columns=["SW", "KRW", "KROW", "PC"], data=[["0", dict(foo="bar"), "1", "2"], ["1", "1", "0", "0"]], ) wateroil = WaterOil(h=0.1) with pytest.raises((ValueError, TypeError)): wateroil.add_fromtable(df2, swcolname="SW", krwcolname="KRW", krowcolname="KROW", pccolname="PC") gasoil = GasOil(h=0.1) with pytest.raises((ValueError, TypeError)): gasoil.add_fromtable(df2, sgcolname="SW", krgcolname="KRW", krogcolname="KROW", pccolname="PC")
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
def gen_wo(parameters: pd.DataFrame, fast_pyscal: bool = False) -> WaterOil: """ Creates a PyScal WaterOil 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/ensembles. Returns: A PyScal WaterOil object """ wo_relperm = WaterOil( swirr=parameters["swirr"], swl=parameters["swl"], swcr=parameters["swcr"], sorw=parameters["sorw"], h=H_CONSTANT, fast=fast_pyscal, ) wo_relperm.add_corey_water(nw=parameters["nw"], krwend=parameters["krwend"]) wo_relperm.add_corey_oil(now=parameters["now"], kroend=parameters["kroend"]) return wo_relperm
def test_linearsegments(): """Made for testing the linear segments during the resolution of issue #163""" wateroil = WaterOil(h=0.01, swl=0.1, swcr=0.3, sorw=0.3) wateroil.add_corey_oil(now=10, kroend=0.5) wateroil.add_corey_water(nw=10, krwend=0.5) check_table(wateroil.table) check_linear_sections(wateroil)
def test_wateroil_let1(l, e, t, krwend, krwmax): wo = WaterOil() try: wo.add_LET_oil(l, e, t, krwend, krwmax) wo.add_LET_water(l, e, t, krwend, krwmax) except AssertionError: # This happens for negative values f.ex. return assert "krow" in wo.table assert "krw" in wo.table assert isinstance(wo.krwcomment, str) check_table(wo.table) swofstr = wo.SWOF() assert len(swofstr) > 100
def test_wateroil_corey1(nw, now): wo = WaterOil() try: wo.add_corey_oil(now=now) wo.add_corey_water(nw=nw) except AssertionError: # This happens for "invalid" input return assert "krow" in wo.table assert "krw" in wo.table assert isinstance(wo.krwcomment, str) check_table(wo.table) swofstr = wo.SWOF() assert len(swofstr) > 100
def test_wateroil_let1(l, e, t, krwend, krwmax): """Test random LET parameters""" wateroil = WaterOil() try: wateroil.add_LET_oil(l, e, t, krwend) wateroil.add_LET_water(l, e, t, krwend, krwmax) except AssertionError: # This happens for negative values f.ex. return assert "KROW" in wateroil.table assert "KRW" in wateroil.table assert isinstance(wateroil.krwcomment, str) check_table(wateroil.table) check_linear_sections(wateroil) swofstr = wateroil.SWOF() assert len(swofstr) > 100