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 # Zero gravity: 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 assert sat_table_str_ok(swof) assert sat_table_str_ok(wateroil.SWFN())
def test_wateroil_krendmax(swl, swcr, sorw, kroend, kromax, krwend, krwmax, h, fast): """Test endpoints for wateroil using hypothesis testing""" try: wateroil = WaterOil(swl=swl, swcr=swcr, sorw=sorw, h=h, fast=fast) except AssertionError: return kroend = min(kroend, kromax) krwend = min(krwend, krwmax) wateroil.add_corey_oil(kroend=kroend, kromax=kromax) wateroil.add_corey_water(krwend=krwend, krwmax=krwmax) check_table(wateroil.table) assert wateroil.selfcheck() assert 0 < wateroil.crosspoint() < 1 check_endpoints(wateroil, krwend, krwmax, kroend, kromax) #################################### # Do it over again, but with LET: wateroil.add_LET_oil(t=1.1, kroend=kroend, kromax=kromax) wateroil.add_LET_water(t=1.1, krwend=krwend, krwmax=krwmax) assert wateroil.selfcheck() check_table(wateroil.table) # Check endpoints for oil curve: check_endpoints(wateroil, krwend, krwmax, kroend, kromax) check_linear_sections(wateroil) assert 0 < wateroil.crosspoint() < 1
def test_let_pc_pd(): """Test LET formulation for primary drainage capillary pressure""" wateroil = WaterOil(swirr=0.1) wateroil.add_LET_pc_pd(Lp=1, Ep=1, Tp=1, Lt=1, Et=1, Tt=1, Pcmax=10, Pct=5) assert np.isclose(wateroil.table["pc"].max(), 10) assert np.isclose(wateroil.table["pc"].min(), 0) # (everything is linear) wateroil.add_LET_pc_pd(Lp=10, Ep=10, Tp=10, Lt=10, Et=10, Tt=10, Pcmax=10, Pct=5) assert np.isclose(wateroil.table["pc"].max(), 10) assert np.isclose(wateroil.table["pc"].min(), 0) # On a plot, you can see a kink at Pc=5. # wateroil.plotpc() wateroil = WaterOil(swirr=0.1, sorw=0.4) wateroil.add_LET_pc_pd(Lp=10, Ep=10, Tp=10, Lt=10, Et=10, Tt=10, Pcmax=5, Pct=2) assert np.isclose(wateroil.table["pc"].max(), 5) assert np.isclose(wateroil.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(wateroil.table[(wateroil.table["sw"] >= 0.6) & (wateroil.table["sw"] <= 1)]) == 2 ) wateroil.add_corey_water() wateroil.add_corey_oil() assert sat_table_str_ok(wateroil.SWOF())
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_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_fast(): """Test the fast option""" # First without fast: wateroil = WaterOil(h=0.1) wateroil.add_corey_water() wateroil.add_corey_oil() # This crosspoint computation is only present for fast=False: assert "-- krw = krow @ sw=0.5" in wateroil.SWOF() # Provoke non-strict-monotone krow: wateroil.table.loc[0:2, "KROW"] = [1.00, 0.81, 0.81] # (this is valid in non-imbibition, but pyscal will correct it for all # curves) assert "0.1000000 0.0100000 0.8100000 0.0000000" in wateroil.SWOF() assert "0.2000000 0.0400000 0.8099999 0.0000000" in wateroil.SWOF() # monotonicity correction: ^^^^^^ # Now redo with fast option: wateroil = WaterOil(h=0.1, fast=True) wateroil.add_corey_water() wateroil.add_corey_oil() # This crosspoint computation is only present for fast=False: assert "-- krw = krow" not in wateroil.SWOF() # Provoke non-strict-monotone krow, in fast-mode # this slips through: wateroil.table.loc[0:2, "KROW"] = [1.00, 0.81, 0.81] assert "0.1000000 0.0100000 0.8100000 0.0000000" in wateroil.SWOF() assert "0.2000000 0.0400000 0.8100000 0.0000000" in wateroil.SWOF() # not corrected: ^^^^^^ wateroil.table.loc[0:2, "KRW"] = [0.00, 0.01, 0.01] assert "0.1000000 0.0100000" in wateroil.SWFN() assert "0.2000000 0.0100000" in wateroil.SWFN()
def test_wateroil_linear(): """Test linear wateroil curves""" wateroil = WaterOil(h=1) wateroil.add_corey_water() wateroil.add_corey_oil() swofstr = wateroil.SWOF(header=False) check_table(wateroil.table) check_linear_sections(wateroil) assert isinstance(swofstr, str) assert swofstr assert len(wateroil.table) == 2 assert np.isclose(wateroil.crosspoint(), 0.5) # What if there is no space for our choice of h? # We should be able to initialize nonetheless # (a warning could be given) wateroil = WaterOil(swl=0.1, h=1) wateroil.add_corey_water() wateroil.add_corey_oil() check_table(wateroil.table) check_linear_sections(wateroil) assert len(wateroil.table) == 2 assert np.isclose(wateroil.table["SW"].min(), 0.1) assert np.isclose(wateroil.table["SW"].max(), 1.0) assert np.isclose(wateroil.crosspoint(), 0.55)
def test_normalize_nonlinpart_wo_hypo( swl, dswcr, dswlhigh, sorw, nw1, krwend1, now1, kroend1, nw2, krwend2, now2, kroend2 ): # pylint: disable=too-many-arguments,too-many-locals """Test the normalization code in utils. In particular the fill_value argument to scipy has been tuned to fulfill this code""" 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=nw1, krwend=krwend1) wo_high.add_corey_water(nw=nw2, krwend=krwend2) wo_low.add_corey_oil(now=now1, kroend=kroend1) wo_high.add_corey_oil(now=now2, kroend=kroend2) krwn1, kron1 = normalize_nonlinpart_wo(wo_low) assert np.isclose(krwn1(0), 0) assert np.isclose(krwn1(1), krwend1) assert np.isclose(kron1(0), 0) assert np.isclose(kron1(1), kroend1) krwn2, kron2 = normalize_nonlinpart_wo(wo_high) assert np.isclose(krwn2(0), 0) assert np.isclose(krwn2(1), krwend2) assert np.isclose(kron2(0), 0) assert np.isclose(kron2(1), kroend2)
def test_simple_j_petro(): """Simple test of the simple J petrophysical function correlation""" wateroil = WaterOil(swl=0.01) wateroil.add_simple_J_petro(a=1, b=-2) check_table(wateroil.table) assert wateroil.pccomment assert "etrophysic" in wateroil.pccomment # Zero gravity: wateroil.add_simple_J_petro(a=1, b=-2, g=0) assert wateroil.table.pc.unique() == 0.0 # Numerical test from sample numbers calculated independently in different tool: wateroil = WaterOil(swl=0.05, h=0.025) wateroil.add_simple_J_petro( a=1.45, b=-0.285, drho=143, g=9.81, perm_ref=15, poro_ref=0.27 ) float_df_checker(wateroil.table, "sw", 0.1, "pc", 22.36746) assert "Simplified" in wateroil.pccomment assert "etrophysic" in wateroil.pccomment wateroil.add_corey_oil() wateroil.add_corey_water() swof = wateroil.SWOF() assert isinstance(swof, str) assert swof assert sat_table_str_ok(swof) assert sat_table_str_ok(wateroil.SWFN())
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()
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_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_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
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_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])
def test_interpolation_art(): """This code was used to create the Pyscal logo (50 repeats and 30 interpolants)""" repeats = 15 interpolants = 30 curvetype = "corey" cmap = pyplot.get_cmap("viridis") _, mpl_ax = pyplot.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.interpolation.interpolate_wo(wo_low, wo_high, tparam) wo_ip.plotkrwkrow(mpl_ax, color=color, alpha=0.3) pyplot.title("Pyscal art") pyplot.show()
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 = 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 = 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 = 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 = interpolate_wo( wo_low, wo_high, parameter=0.1, h=0.2, tag="Explicit tag" ) assert interpolant4.tag == "Explicit tag" # Tag with newline interpolant6 = 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 = 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 = 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())
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_selfcheck(columnname, errorvalues): """Test the selfcheck feature of a WaterOil object""" wateroil = WaterOil(h=1) wateroil.add_corey_water() wateroil.add_corey_oil() assert wateroil.selfcheck() # Punch the internal table directly to trigger error: wateroil.table[columnname] = errorvalues assert not wateroil.selfcheck() assert wateroil.SWOF() == "" if not columnname == "KROW": assert wateroil.SWFN() == ""
def test_normalize_nonlinpart_wo(): """Manual tests for utils.normalize_nonlinpart_wo""" wateroil = WaterOil(swl=0.1, swcr=0.12, sorw=0.05, h=0.05) wateroil.add_corey_water(nw=2.1, krwend=0.9) wateroil.add_corey_oil(now=3, kroend=0.8) krwn, kron = utils.normalize_nonlinpart_wo(wateroil) assert np.isclose(krwn(0), 0) assert np.isclose(krwn(1), 0.9) # kron is normalized on son assert np.isclose(kron(0), 0) assert np.isclose(kron(1), 0.8) # Test with tricky endpoints h = 0.01 wateroil = WaterOil(swl=h, swcr=h, sorw=h, h=h) wateroil.add_corey_water(nw=2.1, krwend=0.9) wateroil.add_corey_oil(now=3, kroend=0.8) krwn, kron = utils.normalize_nonlinpart_wo(wateroil) assert np.isclose(krwn(0), 0.0) assert np.isclose(krwn(1), 0.9) assert np.isclose(kron(0), 0) assert np.isclose(kron(1), 0.8) # Test again with zero endpoints: wateroil = WaterOil(swl=0, swcr=0, sorw=0, h=0.01) wateroil.add_corey_water(nw=2.1, krwend=0.9) wateroil.add_corey_oil(now=3, kroend=0.8) krwn, kron = utils.normalize_nonlinpart_wo(wateroil) assert np.isclose(krwn(0), 0.0) assert np.isclose(krwn(1), 0.9) assert np.isclose(kron(0), 0) assert np.isclose(kron(1), 0.8) # Test when endpoints are messed up: wateroil = WaterOil(swl=0.1, swcr=0.2, sorw=0.1, h=0.1) wateroil.add_corey_water(nw=2.1, krwend=0.6) wateroil.add_corey_oil(now=3, kroend=0.8) wateroil.swl = 0 wateroil.swcr = 0 wateroil.sorw = 0 krwn, kron = utils.normalize_nonlinpart_wo(wateroil) # These go well still, since we are at zero assert np.isclose(krwn(0), 0.0) assert np.isclose(kron(0), 0) # These do not match when endpoints are wrong assert not np.isclose(krwn(1), 0.6) assert not np.isclose(kron(1), 0.8) # So fix endpoints! wateroil.swl = wateroil.table["sw"].min() wateroil.swcr = wateroil.estimate_swcr() wateroil.sorw = wateroil.estimate_sorw() # Try again krwn, kron = utils.normalize_nonlinpart_wo(wateroil) assert np.isclose(krwn(0), 0.0) assert np.isclose(kron(0), 0) assert np.isclose(krwn(1), 0.6) assert np.isclose(kron(1), 0.8)
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 testplot(): """Generate and plot relperm curves Use this as a template function. """ swof = WaterOil(tag="Testcurve", h=0.01, swirr=0.2, swl=0.2, sorw=0.1) swof.add_corey_water(nw=5, krwend=0.7, krwmax=0.9) swof.add_corey_oil(now=2, kroend=0.95) swof.add_LET_water(l=2, e=1, t=1.4, krwend=0.7, krwmax=0.9) swof.add_LET_oil(l=2, e=1, t=1.4, kroend=0.9) # Print the first 7 lines of SWOF: print("\n".join(swof.SWOF().split("\n")[0:8])) _, mpl_ax = plt.subplots() swof.plotkrwkrow(mpl_ax) plt.show()
def test_wateroil_corey1(nw, now): """Test random corey parameters""" wateroil = WaterOil() try: wateroil.add_corey_oil(now=now) wateroil.add_corey_water(nw=nw) except AssertionError: # This happens for "invalid" input return assert "krow" in wateroil.table assert "krw" in wateroil.table assert isinstance(wateroil.krwcomment, str) check_table(wateroil.table) swofstr = wateroil.SWOF() assert len(swofstr) > 100
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()
def test_norm_j_pc_random(swirr, swl, a_pc, b_pc, 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 wateroil = WaterOil(swirr=swirr, swl=swl, h=0.01) try: wateroil.add_normalized_J( a=a_pc, b=b_pc, perm=perm, poro=poro, sigma_costau=sigma_costau ) except (AssertionError, ValueError): # when poro is < 0 f.ex. return check_table(wateroil.table) wateroil.add_corey_water() wateroil.add_corey_oil() assert sat_table_str_ok(wateroil.SWOF())
def test_ip_wo_kroend(): """Test behaviour of kroend 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) 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.7) # Interpolate to midpoint between the curves above wo_ip = interpolate_wo(wo_low, wo_high, 0.5) # kroend at mean swl: assert float_df_checker(wo_ip.table, "sw", 0.01, "krow", (0.6 + 0.7) / 2.0) 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)
def test_let_pc_imb(): """Test the LET formulation for imbibition capillary pressures""" wateroil = WaterOil(swirr=0.1) wateroil.add_LET_pc_imb(Ls=1, Es=1, Ts=1, Lf=1, Ef=1, Tf=1, Pcmax=10, Pcmin=-10, Pct=3) assert np.isclose(wateroil.table["pc"].max(), 10) assert np.isclose(wateroil.table["pc"].min(), -10) wateroil = WaterOil(swirr=0.1) wateroil.add_LET_pc_imb(Ls=5, Es=5, Ts=5, Lf=5, Ef=5, Tf=5, Pcmax=5, Pcmin=1, Pct=4) assert np.isclose(wateroil.table["pc"].max(), 5) assert np.isclose(wateroil.table["pc"].min(), 1) wateroil = WaterOil(swirr=0.1, sorw=0.3) wateroil.add_LET_pc_imb(Ls=5, Es=5, Ts=5, Lf=5, Ef=5, Tf=5, Pcmax=5, Pcmin=1, Pct=4) assert np.isclose(wateroil.table["pc"].max(), 5) assert np.isclose(wateroil.table["pc"].min(), 1) wateroil.add_corey_water() wateroil.add_corey_oil() sat_table_str_ok(wateroil.SWOF())
def test_nexus(): """Test the Nexus export""" 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) nexus_lines = wateroil.WOTABLE().splitlines() non_comments = [ line for line in nexus_lines if not line.startswith("!") or not len(line) ] assert non_comments[0] == "WOTABLE" assert non_comments[1] == "SW KRW KROW PC" df = pd.read_table( io.StringIO("\n".join(non_comments[2:])), engine="python", sep=r"\s+", header=None, ) assert (df.values <= 1.0).all() assert (df.values >= 0.0).all()
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)
def test_sorw_hypo(h, sorw, nw): """Test estimate_sorw extensively""" wateroil = WaterOil(sorw=sorw, h=h) wateroil.add_corey_oil(now=2) wateroil.add_corey_water(nw=nw) est_sorw = wateroil.estimate_sorw() est_error = abs(sorw - est_sorw) assert not np.isnan(est_sorw) error_requirement = h + 10000 * epsilon if abs(1 - nw) < 0.1: # When the Corey curve is almost linear, we don't # expect sorw estimation to be robust error_requirement = 3 * h if est_error > error_requirement: print("h = {}, sorw = {}".format(h, sorw)) print("estimated sorw = {}".format(est_sorw)) print(wateroil.table) # We don't bother to tune the code better than this: assert est_error <= error_requirement