def test_gasoil_normalization(swl, sgcr, sorg, h, tag): """Check that normalization (sgn and son) is correct for all possible saturation endpoints""" gasoil = GasOil( swirr=0.0, swl=swl, sgcr=sgcr, sorg=sorg, h=h, krgendanchor="sorg", tag=tag ) assert not gasoil.table.empty assert not gasoil.table.isnull().values.any() # Check that son is 1 at sgcr assert float_df_checker(gasoil.table, "sg", gasoil.sgcr, "son", 1) # Check that son is 0 at sorg with this krgendanchor assert float_df_checker(gasoil.table, "sg", 1 - gasoil.sorg - gasoil.swl, "son", 0) # Check that sgn is 0 at sgcr assert float_df_checker(gasoil.table, "sg", gasoil.sgcr, "sgn", 0) # Check that sgn is 1 at sorg assert float_df_checker(gasoil.table, "sg", 1 - gasoil.sorg - gasoil.swl, "sgn", 1) # Redo with different krgendanchor gasoil = GasOil( swirr=0.0, swl=swl, sgcr=sgcr, sorg=sorg, h=h, krgendanchor="", tag=tag ) assert float_df_checker(gasoil.table, "sg", 1 - gasoil.swl, "sgn", 1) assert float_df_checker(gasoil.table, "sg", gasoil.sgcr, "sgn", 0)
def test_go_fromtable_problems(): """Test loading from a table where there should be problems""" df1 = pd.DataFrame(columns=["Sg", "KRG", "KROG", "PCOG"], data=[[0.1, 0, 1, 2], [0.9, 1, 0, 0]]) # Now sgcr and swl is wrong: gasoil = GasOil(h=0.1) with pytest.raises(ValueError): # Should say sg must start at zero. gasoil.add_fromtable(df1, pccolname="PCOG") df2 = pd.DataFrame(columns=["Sg", "KRG", "KROG", "PCOG"], data=[[0.0, 0, 1, 2], [0.9, 0.8, 0, 0]]) with pytest.raises(ValueError): # should say too large swl for pcog interpolation gasoil = GasOil(h=0.1) gasoil.add_fromtable(df2, pccolname="PCOG") gasoil = GasOil(h=0.1, swl=0.1) gasoil.add_fromtable(df2, pccolname="PCOG") assert np.isclose(gasoil.table["pc"].max(), 2.0) assert np.isclose(gasoil.table["pc"].min(), 0.0) assert np.isclose(gasoil.table["sg"].max(), 0.9) gasoil = GasOil(h=0.1) with pytest.raises(ValueError): # sg must start at zero gasoil.add_fromtable(df1, krgcolname="KRG", krogcolname="KROG") # This works fine, but we get warnings on swl not seemingly correct gasoil.add_fromtable(df2, krgcolname="KRG", krogcolname="KROG") # krg will be extrapolated to sg=1 float_df_checker(gasoil.table, "sg", 1.0, "krg", 0.8) float_df_checker(gasoil.table, "sg", 1.0, "krog", 0.0) gasoil = GasOil(h=0.1, swl=0.1) gasoil.add_fromtable(df2, krgcolname="KRG", krogcolname="KROG")
def test_gasoil_krendmax(swl, sgcr, sorg, kroend, kromax, krgend, krgmax, h): try: go = GasOil(swl=swl, sgcr=sgcr, sorg=sorg, h=h, tag="") except AssertionError: return kroend = min(kroend, kromax) krgend = min(krgend, krgmax) go.add_corey_oil(kroend=kroend, kromax=kromax) go.add_corey_gas(krgend=krgend, krgmax=krgmax) check_table(go.table) assert go.selfcheck() check_endpoints(go, krgend, krgmax, kroend, kromax) # Redo with krgendanchor not defaulted go = GasOil(swl=swl, sgcr=sgcr, sorg=sorg, h=h, krgendanchor="", tag="") go.add_corey_oil(kroend=kroend, kromax=kromax) go.add_corey_gas(krgend=krgend, krgmax=krgmax) check_table(go.table) assert go.selfcheck() check_endpoints(go, krgend, krgmax, kroend, kromax) # Redo with LET: go = GasOil(swl=swl, sgcr=sgcr, sorg=sorg, h=h, tag="") go.add_LET_oil(kroend=kroend, kromax=kromax) go.add_LET_gas(krgend=krgend, krgmax=krgmax) check_table(go.table) assert go.selfcheck() check_endpoints(go, krgend, krgmax, kroend, kromax)
def test_go_invalidcurves(): """Test fromtable on invalid gasoil data""" # Sw data not ordered: krg1 = pd.DataFrame(columns=["Sg", "krg"], data=[[0.15, 0], [0.1, 1], [1, 1]]) gasoil = GasOil(h=0.1) with pytest.raises(ValueError): # pchip-interpolator raises this error; # x coordinates are not in increasing order gasoil.add_fromtable(krg1, krgcolname="krg") krg2 = pd.DataFrame(columns=["Sg", "krg"], data=[[0.15, 0], [0.4, 0.6], [0.6, 0.4], [1, 1]]) gasoil = GasOil(h=0.1) with pytest.raises(ValueError): # Should get notified that krg is not monotonous gasoil.add_fromtable(krg2, krgcolname="krg") krog2 = pd.DataFrame(columns=["Sg", "krog"], data=[[0.15, 1], [0.4, 0.4], [0.6, 0.6], [1, 0]]) gasoil = GasOil(h=0.1) with pytest.raises(ValueError): # Should get notified that krog is not monotonous gasoil.add_fromtable(krog2, krogcolname="krog") pc2 = pd.DataFrame(columns=["Sg", "pc"], data=[[0.15, 1], [0.4, 0.4], [0.6, 0.6], [1, 0]]) gasoil = GasOil(h=0.1) with pytest.raises(ValueError): # Should get notified that pc is not monotonous gasoil.add_fromtable(pc2, pccolname="pc")
def test_gasoil_gascond_fails(): """Interpolation between an object for gas condendensate (sgro > 0) and an object with sgro = 0 (regular gas-oil) should fail""" gascond = GasOil(sgro=0.1, sgcr=0.1) gasoil = GasOil(sgro=0.0, sgcr=0.1) gasoil.add_corey_gas() gasoil.add_corey_oil() gascond.add_corey_gas() gascond.add_corey_oil() # interpolation parameter at zero is no interpolation, just lookup, # so it works fine: check_table(interpolate_go(gasoil, gascond, parameter=0.0).table) check_table(interpolate_go(gasoil, gascond, parameter=epsilon).table) check_table(interpolate_go(gasoil, gascond, parameter=10 * epsilon).table) with pytest.raises(ValueError, match="Interpolated sgro"): interpolate_go(gasoil, gascond, parameter=100 * epsilon) with pytest.raises(ValueError, match="Interpolated sgro"): interpolate_go(gasoil, gascond, parameter=0.5) check_table(interpolate_go(gasoil, gascond, parameter=1.0 - epsilon).table) check_table(interpolate_go(gasoil, gascond, parameter=1.0).table)
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, ): """Test many possible combinations of interpolation between two Corey gasoil curves, looking for numerical corner cases""" go_low = GasOil(swl=swl, sgcr=sgcr, sorg=sorg) go_high = GasOil(swl=swl + dswlhigh, sgcr=sgcr + dsgcr, sorg=max(sorg - dsorg, 0)) 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 = utils.interpolate_go(go_low, go_high, t) check_table(go_ip.table) ips.append(go_ip) assert 0 < go_ip.crosspoint() < 1 # 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) from matplotlib import pyplot as plt _, 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
def test_fast(): """Test the fast option""" # First without fast-mode: gasoil = GasOil(h=0.1) gasoil.add_corey_gas() gasoil.add_corey_oil() # This crosspoint computation is only present for fast=False: assert "-- krg = krog @ sg=0.5" in gasoil.SGOF() # Provoke non-strict-monotone krow: gasoil.table.loc[0:2, "krog"] = [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 gasoil.SGOF() assert "0.2000000 0.0400000 0.8099999 0.0000000" in gasoil.SGOF() # monotonocity correction: ^^^^^^ # Now redo with fast option: gasoil = GasOil(h=0.1, fast=True) gasoil.add_corey_gas() gasoil.add_corey_oil() # This crosspoint computation is only present for fast=False: assert "-- krg = krog" not in gasoil.SGOF() # Provoke non-strict-monotone krow, in fast-mode # this slips through: gasoil.table.loc[0:2, "krog"] = [1.00, 0.81, 0.81] assert "0.1000000 0.0100000 0.8100000 0.0000000" in gasoil.SGOF() assert "0.2000000 0.0400000 0.8100000 0.0000000" in gasoil.SGOF() # not corrected: ^^^^^^ gasoil.table.loc[0:2, "krg"] = [0.00, 0.01, 0.01] assert "0.1000000 0.0100000" in gasoil.SGFN() assert "0.2000000 0.0100000" in gasoil.SGFN()
def test_normalize_nonlinpart_go(): """Manual tests for normalize_nonlinpart_go""" gasoil = GasOil(swl=0.1, sgcr=0.12, sorg=0.05, h=0.05) gasoil.add_corey_gas(ng=2.1, krgend=0.9) gasoil.add_corey_oil(nog=3, kroend=0.8) krgn, kron = normalize_nonlinpart_go(gasoil) assert np.isclose(krgn(0), 0) assert np.isclose(krgn(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 gasoil = GasOil(swl=h, sgcr=h, sorg=h, h=h) gasoil.add_corey_gas(ng=2.1, krgend=0.9) gasoil.add_corey_oil(nog=3, kroend=0.8) krgn, kron = normalize_nonlinpart_go(gasoil) assert np.isclose(krgn(0), 0.0) assert np.isclose(krgn(1), 0.9) assert np.isclose(kron(0), 0) assert np.isclose(kron(1), 0.8) # Test again with zero endpoints: gasoil = GasOil(swl=0, sgcr=0, sorg=0, h=0.01) gasoil.add_corey_gas(ng=2.1, krgend=0.9) gasoil.add_corey_oil(nog=3, kroend=0.8) krgn, kron = normalize_nonlinpart_go(gasoil) assert np.isclose(krgn(0), 0.0) assert np.isclose(krgn(1), 0.9) assert np.isclose(kron(0), 0) assert np.isclose(kron(1), 0.8) # Test when endpoints are messed up (cleared) gasoil = GasOil(swl=0.1, sgcr=0.2, sorg=0.1, h=0.1) gasoil.add_corey_gas(ng=2.1, krgend=0.6) gasoil.add_corey_oil(nog=3, kroend=0.8) gasoil.swl = 0 gasoil.sgcr = 0 gasoil.sorg = 0 krgn, kron = normalize_nonlinpart_go(gasoil) # These go well still, since we are at zero assert np.isclose(krgn(0), 0.0) assert np.isclose(kron(0), 0) assert np.isclose(kron(1), 0.8) # These do not match when endpoints are wrong assert not np.isclose(krgn(1), 0.6) # So fix endpoints! gasoil.swl = 1 - gasoil.table["sg"].max() gasoil.sgcr = gasoil.estimate_sgcr() gasoil.sorg = gasoil.estimate_sorg() # Try again krgn, kron = normalize_nonlinpart_go(gasoil) assert np.isclose(krgn(0), 0.0) assert np.isclose(kron(0), 0) assert np.isclose(krgn(1), 0.6) assert np.isclose(kron(1), 0.8)
def test_errors(): """Test some error situations for the constructor""" with pytest.raises(ValueError, match="No saturation range left"): GasOil(swl=0.3, sorg=0.8) with pytest.warns(DeprecationWarning): gasoil = GasOil(tag=dict()) assert gasoil.tag == ""
def test_normalize_nonlinpart_go_hypo( swl, sgcr, dswlhigh, dsgcr, sorg, dsorg, sgrononzero, ng1, krgend1, nog1, kroend1, kromax1, ng2, krgend2, nog2, kroend2, kromax2, ): # 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""" kroend1 = min(kroend1, kromax1) kroend2 = min(kroend2, kromax2) if sgrononzero: sgro_low = sgcr sgro_high = sgcr + dsgcr else: sgro_low = 0.0 sgro_high = 0.0 go_low = GasOil(swl=swl, sgcr=sgcr, sorg=sorg, sgro=sgro_low) go_high = GasOil( swl=swl + dswlhigh, sgcr=sgcr + dsgcr, sgro=sgro_high, sorg=max(sorg - dsorg, 0), ) go_low.add_corey_gas(ng=ng1, krgend=krgend1) go_high.add_corey_gas(ng=ng2, krgend=krgend2) go_low.add_corey_oil(nog=nog1, kroend=kroend1, kromax=kromax1) go_high.add_corey_oil(nog=nog2, kroend=kroend2, kromax=kromax2) krgn1, kron1 = normalize_nonlinpart_go(go_low) assert np.isclose(krgn1(0), 0) assert np.isclose(krgn1(1), krgend1) assert np.isclose(kron1(0), 0) assert np.isclose(kron1(1), kroend1) krgn2, kron2 = normalize_nonlinpart_go(go_high) assert np.isclose(krgn2(0), 0) assert np.isclose(krgn2(1), krgend2) assert np.isclose(kron2(0), 0) assert np.isclose(kron2(1), kroend2)
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_gasoil_krgendanchor(): """Test behaviour of the krgendanchor""" gasoil = GasOil(krgendanchor="sorg", sorg=0.2, h=0.1) assert gasoil.sorg gasoil.add_corey_gas(ng=1) gasoil.add_corey_oil(nog=1) # kg should be 1.0 at 1 - sorg due to krgendanchor == "sorg": assert ( gasoil.table[np.isclose(gasoil.table["sg"], 1 - gasoil.sorg)]["krg"].values[0] == 1.0 ) assert gasoil.table[np.isclose(gasoil.table["sg"], 1.0)]["krg"].values[0] == 1.0 gasoil = GasOil(krgendanchor="", sorg=0.2, h=0.1) assert gasoil.sorg gasoil.add_corey_gas(ng=1) gasoil.add_corey_oil(nog=1) # kg should be < 1 at 1 - sorg due to krgendanchor being "" assert ( gasoil.table[np.isclose(gasoil.table["sg"], 1 - gasoil.sorg)]["krg"].values[0] < 1.0 ) assert gasoil.table[np.isclose(gasoil.table["sg"], 1.0)]["krg"].values[0] == 1.0 assert gasoil.selfcheck() assert gasoil.crosspoint() > 0 # Test once more for LET curves: gasoil = GasOil(krgendanchor="sorg", sorg=0.2, h=0.1) assert gasoil.sorg gasoil.add_LET_gas(1, 1, 1.1) gasoil.add_LET_oil(1, 1, 1.1) check_linear_sections(gasoil) assert 0 < gasoil.crosspoint() < 1 # kg should be 1.0 at 1 - sorg due to krgendanchor == "sorg": assert ( gasoil.table[np.isclose(gasoil.table["sg"], 1 - gasoil.sorg)]["krg"].values[0] == 1.0 ) assert gasoil.table[np.isclose(gasoil.table["sg"], 1.0)]["krg"].values[0] == 1.0 gasoil = GasOil(krgendanchor="", sorg=0.2, h=0.1) assert gasoil.sorg gasoil.add_LET_gas(1, 1, 1.1) gasoil.add_LET_oil(1, 1, 1.1) check_linear_sections(gasoil) assert gasoil.selfcheck() # kg should be < 1 at 1 - sorg due to krgendanchor being "" assert ( gasoil.table[np.isclose(gasoil.table["sg"], 1 - gasoil.sorg)]["krg"].values[0] < 1.0 ) assert gasoil.table[np.isclose(gasoil.table["sg"], 1.0)]["krg"].values[0] == 1.0
def test_errors(): """Test some error situations for the constructor""" with pytest.raises(ValueError, match="No saturation range left"): GasOil(swl=0.3, sorg=0.8) with pytest.raises(ValueError, match="No saturation range left"): GasOil(swl=0.3, sgro=0.88, sgcr=0.88) with pytest.raises(ValueError, match="No saturation range left"): GasOil(swl=0.3, sgcr=0.88) with pytest.raises(ValueError, match="sgro must be zero or equal to sgcr"): GasOil(swl=0.3, sgcr=0.1, sgro=0.2)
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_gasoil_krendmax(swl, sgcr, sorg, sgrononzero, kroend, kromax, krgend, krgmax, h, fast): """Test that relperm curves are valid in all numerical corner cases.""" if sgrononzero: sgro = sgcr else: sgro = 0 try: gasoil = GasOil(swl=swl, sgcr=sgcr, sorg=sorg, sgro=sgro, h=h, tag="", fast=fast) except AssertionError: return krgend = min(krgend, krgmax) kroend = min(kroend, kromax) gasoil.add_corey_oil(kroend=kroend, kromax=kromax) gasoil.add_corey_gas(krgend=krgend, krgmax=krgmax) check_table(gasoil.table) check_linear_sections(gasoil) assert gasoil.selfcheck() check_endpoints(gasoil, krgend, krgmax, kroend, kromax) assert 0 < gasoil.crosspoint() < 1 # Redo with krgendanchor not defaulted gasoil = GasOil(swl=swl, sgcr=sgcr, sorg=sorg, h=h, krgendanchor="", tag="") gasoil.add_corey_oil(kroend=kroend) gasoil.add_corey_gas(krgend=krgend, krgmax=krgmax) check_table(gasoil.table) check_linear_sections(gasoil) assert gasoil.selfcheck() check_endpoints(gasoil, krgend, krgmax, kroend, kromax) assert 0 < gasoil.crosspoint() < 1 # Redo with LET: gasoil = GasOil(swl=swl, sgcr=sgcr, sorg=sorg, h=h, tag="") gasoil.add_LET_oil(t=1.1, kroend=kroend, kromax=kromax) gasoil.add_LET_gas(krgend=krgend, krgmax=krgmax) check_table(gasoil.table) check_linear_sections(gasoil) assert gasoil.selfcheck() check_endpoints(gasoil, krgend, krgmax, kroend, kromax) assert 0 < gasoil.crosspoint() < 1
def test_gascond_interpolation(sgro_low, sgro_high): """sgro is required to be either 0 or sgcr, and interpolations will crash when this is not the case. This test validates that we can let sgro and sgcr go to zero, and that we always are able to interpolate without crashes.""" go_low = GasOil(sgro=sgro_low, sgcr=sgro_low) go_high = GasOil(sgro=sgro_high, sgcr=sgro_high) go_low.add_corey_gas() go_low.add_corey_oil() go_high.add_corey_gas() go_high.add_corey_oil() go_ip = interpolate_go(go_low, go_high, parameter=0.5) check_table(go_ip.table)
def test_gasoil_kromax(): go = GasOil(h=0.1, sgcr=0.1) go.add_corey_oil(2, 0.5) # Default for kromax assert float_df_checker(go.table, "sg", 0.0, "krog", 1.0) assert float_df_checker(go.table, "sg", 0.1, "krog", 0.5) go.add_corey_oil(2, 0.5, 0.7) assert float_df_checker(go.table, "sg", 0.0, "krog", 0.7) assert float_df_checker(go.table, "sg", 0.1, "krog", 0.5) go = GasOil(h=0.1, sgcr=0.0) go.add_corey_oil(2, 0.5) assert float_df_checker(go.table, "sg", 0.0, "krog", 0.5) go.add_corey_oil(2, 0.5, 1) # A warning will be given assert float_df_checker(go.table, "sg", 0.0, "krog", 0.5)
def test_sorg(): """Test estimate_sorg for some manually set up cases""" # sorg, sgcr, h, swl: testtuples = [ (0.3, 0.01, 0.1, 0.1), (0.2, 0, 0.05, 0.0), (0.1, 0.3, 0.01, 0.5), (0.0, 0, 0.1, 0.000001), (0.9, 0.000001, 0.1, 0), (0.4, 0, 0.1, 0.2), ] for testtuple in testtuples: real_sorg = testtuple[0] real_sgcr = testtuple[1] h = testtuple[2] swl = testtuple[3] go = GasOil(sgcr=0.03, sorg=real_sorg, h=h, swl=swl) go.add_corey_oil(nog=2) go.add_corey_gas(ng=2, krgend=0.9) print("Testing sorg={} on h={}, swl={}".format(real_sorg, h, swl)) est_sorg = go.estimate_sorg() mis = abs(est_sorg - real_sorg) if mis > 0.01: print("Missed, estimated was {}".format(est_sorg)) assert mis < h + epsilon # Can't guarantee better than h. # If krgendanchor is not sorg (default), then krg cannot be used # and the GasOil object will resort to using krog. Should work # when now=2 but might not always work for all kinds of LET parameters. go = GasOil(sorg=real_sorg, h=h, swl=swl, krgendanchor="") go.add_corey_oil(nog=2) go.add_corey_gas(ng=2, krgend=0.8) est_sorg = go.estimate_sorg() print("Estimated to {}".format(est_sorg)) mis = abs(est_sorg - real_sorg) assert mis < h + epsilon # Test sgcr: go = GasOil(sorg=real_sorg, sgcr=real_sgcr, h=h, swl=swl, krgendanchor="sorg") go.add_corey_oil(nog=2, kroend=0.8) go.add_corey_gas(ng=2, krgend=0.8) est_sgcr = go.estimate_sgcr() mis = abs(est_sgcr - real_sgcr) assert mis < h + epsilon
def test_gasoil_kromax(): """Manual test of kromax behaviour""" gasoil = GasOil(h=0.1, sgcr=0.1) gasoil.add_corey_oil(2, 0.5) # Default for kromax assert float_df_checker(gasoil.table, "sg", 0.0, "krog", 1.0) assert float_df_checker(gasoil.table, "sg", 0.1, "krog", 0.5) gasoil.add_corey_oil(2, 0.5, 0.7) assert float_df_checker(gasoil.table, "sg", 0.0, "krog", 0.7) assert float_df_checker(gasoil.table, "sg", 0.1, "krog", 0.5) gasoil = GasOil(h=0.1, sgcr=0.0) gasoil.add_corey_oil(2, 0.5) assert float_df_checker(gasoil.table, "sg", 0.0, "krog", 0.5) gasoil.add_corey_oil(2, 0.5, 1) # A warning will be given assert float_df_checker(gasoil.table, "sg", 0.0, "krog", 0.5)
def test_gasoil_kromax_fast(): """Test some code in fast mode""" gasoil = GasOil(h=0.1, sgcr=0.1, fast=True) gasoil.add_corey_oil(2, 0.5) # Default for kromax assert float_df_checker(gasoil.table, "sg", 0.0, "krog", 1.0) assert float_df_checker(gasoil.table, "sg", 0.1, "krog", 0.5) gasoil.add_corey_oil(2, 0.5, 0.7) assert float_df_checker(gasoil.table, "sg", 0.0, "krog", 0.7) assert float_df_checker(gasoil.table, "sg", 0.1, "krog", 0.5) gasoil = GasOil(h=0.1, sgcr=0.0) gasoil.add_corey_oil(2, 0.5) assert float_df_checker(gasoil.table, "sg", 0.0, "krog", 0.5) gasoil.add_corey_oil(2, 0.5, 1) # A warning will be given assert float_df_checker(gasoil.table, "sg", 0.0, "krog", 0.5)
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_sgfn(): """Test that we can call SGFN without oil relperm defined""" gasoil = GasOil() gasoil.add_corey_gas() sgfn_str = gasoil.SGFN() assert "SGFN" in sgfn_str assert len(sgfn_str) > 15
def gen_og(parameters: pd.DataFrame, fast_pyscal: bool = False) -> GasOil: """ Creates a PyScal GasOil 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 GasOil object """ og_relperm = GasOil( swirr=parameters["swirr"], swl=parameters["swl"], sorg=parameters["sorg"], sgcr=parameters["sgcr"], h=H_CONSTANT, fast=fast_pyscal, ) og_relperm.add_corey_gas(ng=parameters["ng"], krgend=parameters["krgend"]) og_relperm.add_corey_oil(nog=parameters["nog"], kroend=parameters["kroend"]) return og_relperm
def test_sgof_generation() -> None: """ Testing if the FlowNet code and pyscal generate the same SGOF table - test tolerance set to 4 decimals """ parameter_dict = {} parameter_dict["swirr"] = 0.01 parameter_dict["swl"] = 0.05 parameter_dict["sgcr"] = 0.055 parameter_dict["sorg"] = 0.15 parameter_dict["krgend"] = 0.95 parameter_dict["kroend"] = 0.95 parameter_dict["ng"] = 2.25 parameter_dict["nog"] = 2.25 gasoil = GasOil( swirr=parameter_dict["swirr"], swl=parameter_dict["swl"], sgcr=parameter_dict["sgcr"], sorg=parameter_dict["sorg"], h=H_CONSTANT, ) gasoil.add_corey_oil(nog=parameter_dict["nog"], kroend=parameter_dict["kroend"]) gasoil.add_corey_gas(ng=parameter_dict["ng"], krgend=parameter_dict["krgend"]) pyscal_sgof_string = gasoil.SGOF(header=False, dataincommentrow=False).splitlines()[ 3:-1 ] numpy_sgof_string = sgof_from_parameters(parameter_dict).splitlines() for i, line in enumerate(pyscal_sgof_string): assert [round(float(elem), 4) for elem in line.split()] == [ round(float(elem), 4) for elem in numpy_sgof_string[i].split() ]
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_linearsegments(): """Made for testing the linear segments during the resolution of issue #163""" gasoil = GasOil(h=0.01, swl=0.1, sgcr=0.3, sorg=0.3) gasoil.add_corey_oil(nog=10, kroend=0.5) gasoil.add_corey_gas(ng=10, krgend=0.5) check_table(gasoil.table) check_linear_sections(gasoil)
def test_gasoil_krendmax(swl, sgcr, sorg, kroend, kromax, krgend, krgmax, h, fast): """Test that krendmax gets correct in all numerical corner cases. The normalized sg-range is allowed to collapse to nothing in this test. (causes AssertionError) """ try: gasoil = GasOil(swl=swl, sgcr=sgcr, sorg=sorg, h=h, tag="", fast=fast) except AssertionError: return kroend = min(kroend, kromax) krgend = min(krgend, krgmax) gasoil.add_corey_oil(kroend=kroend, kromax=kromax) gasoil.add_corey_gas(krgend=krgend, krgmax=krgmax) check_table(gasoil.table) check_linear_sections(gasoil) assert gasoil.selfcheck() check_endpoints(gasoil, krgend, krgmax, kroend, kromax) assert 0 < gasoil.crosspoint() < 1 # Redo with krgendanchor not defaulted gasoil = GasOil(swl=swl, sgcr=sgcr, sorg=sorg, h=h, krgendanchor="", tag="") gasoil.add_corey_oil(kroend=kroend, kromax=kromax) gasoil.add_corey_gas(krgend=krgend, krgmax=krgmax) check_table(gasoil.table) check_linear_sections(gasoil) assert gasoil.selfcheck() check_endpoints(gasoil, krgend, krgmax, kroend, kromax) assert 0 < gasoil.crosspoint() < 1 # Redo with LET: gasoil = GasOil(swl=swl, sgcr=sgcr, sorg=sorg, h=h, tag="") gasoil.add_LET_oil(t=1.1, kroend=kroend, kromax=kromax) gasoil.add_LET_gas(krgend=krgend, krgmax=krgmax) check_table(gasoil.table) check_linear_sections(gasoil) assert gasoil.selfcheck() check_endpoints(gasoil, krgend, krgmax, kroend, kromax) assert 0 < gasoil.crosspoint() < 1
def test_gasoil_tag(tag): """Test tagging of GasOil objects, that we are not able to produce something that can crash Eclipse""" gasoil = GasOil(h=0.5, tag=tag) gasoil.add_corey_gas() gasoil.add_corey_oil() sat_table_str_ok(gasoil.SGOF()) sat_table_str_ok(gasoil.SGFN())
def test_ip_go_kroendmax(): """Test behaviour of kroend/kromax under interpolation, gas condensate modelling""" go_low = GasOil(swl=0, sgro=0.1, sgcr=0.1) go_high = GasOil(swl=0, sgro=0) go_low.add_corey_gas() go_low.add_corey_oil(nog=2, kroend=0.5, kromax=1) go_high.add_corey_gas() go_high.add_corey_oil(nog=2, kroend=1) # Interpolate to midpoint between the curves above go_ip = interpolate_go(go_low, go_high, 0.5) # kro(sg=0) is 1 for all interpolants: assert float_df_checker(go_ip.table, "SG", 0.0, "KROG", 1.0) # kro(sg=mean(sgro)) = mean kroeend assert float_df_checker(go_ip.table, "SG", (0 + 0.1) / 2.0, "KROG", 0.75) assert np.isclose(go_ip.estimate_sgro(), (0 + 0.1) / 2.0)
def test_go_fromtable_simple(): df1 = pd.DataFrame(columns=["SG", "KRG", "KROG", "PC"], data=[[0, 0, 1, 2], [1, 1, 0, 0]]) go = GasOil(h=0.1) go.add_fromtable(df1, sgcolname="SG", krgcolname="KRG", krogcolname="KROG", pccolname="PC") check_go_table(go.table)