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_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 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_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_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_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_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_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_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_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_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_selfcheck(columnname, errorvalues): """Test the selfcheck feature of a GasOil object""" gasoil = GasOil(h=1) gasoil.add_corey_gas() gasoil.add_corey_oil() assert gasoil.selfcheck() # Punch the internal table directly to trigger error: gasoil.table[columnname] = errorvalues assert not gasoil.selfcheck() assert gasoil.SGOF() == "" if not columnname == "KROG": assert gasoil.SGFN() == ""
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_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 testgascurves(): """test of gas-oil curves""" sgof = GasOil(tag="Testcurve", h=0.02, swirr=0.18, swl=0.31, sorg=0.09, sgcr=0.04) sgof.add_corey_gas(ng=1.5, krgend=0.7) sgof.add_corey_oil(nog=2, kroend=0.4) sgof.add_LET_gas(l=2, e=1, t=1.4, krgend=0.9) sgof.add_LET_oil(l=2, e=3, t=1.4, kroend=0.7) print(sgof.table) _, mpl_ax = plt.subplots() sgof.plotkrgkrog(mpl_ax) # mpl_ax.set_yscale('log') print(sgof.SGOF()) plt.show()
def test_slgof_hypo(swl, sorg, sgcr, h): """Shotgun-testing of slgof""" gasoil = GasOil(swl=swl, sorg=sorg, sgcr=sgcr, h=h) gasoil.add_corey_gas() gasoil.add_corey_oil() assert gasoil.selfcheck() slgof = gasoil.slgof_df() check_table(slgof) # Eclipse 100 requirement from manual: assert np.isclose(slgof["sl"].values[0], gasoil.swl + gasoil.sorg) # Eclipse 100 requirement from manual: assert np.isclose(slgof["sl"].values[-1], 1.0) slgof_str = gasoil.SLGOF() assert isinstance(slgof_str, str) assert slgof_str
def test_gasoil_corey1(ng, nog): go = GasOil() try: go.add_corey_oil(nog=nog) go.add_corey_gas(ng=ng) except AssertionError: # This happens for "invalid" input return assert "krog" in go.table assert "krg" in go.table assert isinstance(go.krgcomment, str) check_table(go.table) sgofstr = go.SGOF() assert len(sgofstr) > 100
def test_kroend(): """Manual testing of kromax and kroend behaviour""" gasoil = GasOil(swirr=0.01, sgcr=0.01, h=0.01, swl=0.1, sorg=0.05) gasoil.add_LET_gas() gasoil.add_LET_oil(2, 2, 2.1) assert gasoil.table["krog"].max() == 1 gasoil.add_LET_oil(2, 2, 2.1, kroend=0.5) check_linear_sections(gasoil) assert gasoil.table["krog"].max() == 0.5 assert 0 < gasoil.crosspoint() < 1 gasoil.add_corey_oil(2) assert gasoil.table["krog"].max() == 1 gasoil.add_corey_oil(nog=2, kroend=0.5) assert gasoil.table["krog"].max() == 0.5
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_kromaxend(): """Manual testing of kromax and kroend behaviour""" gasoil = GasOil(swirr=0.01, sgcr=0.01, h=0.01, swl=0.1, sorg=0.05) gasoil.add_LET_gas() gasoil.add_LET_oil(2, 2, 2) assert gasoil.table["krog"].max() == 1 gasoil.add_LET_oil(2, 2, 2, 0.5, 0.9) assert gasoil.table["krog"].max() == 0.5 # Second krog-value should be kroend, values in between will be linearly # interpolated in Eclipse assert gasoil.table.sort_values("krog")[-2:-1]["krog"].values[0] == 0.5 gasoil.add_corey_oil(2) assert gasoil.table["krog"].max() == 1 gasoil.add_corey_oil(2, 0.5, 0.9) assert gasoil.table["krog"].max() == 0.5 assert gasoil.table.sort_values("krog")[-2:-1]["krog"].values[0] == 0.5
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_init(): """Test features in the constructor""" gasoil = GasOil() assert isinstance(gasoil, GasOil) assert gasoil.swirr == 0.0 assert gasoil.swl == 0.0 assert gasoil.krgendanchor == "" # Because sorg is zero gasoil = GasOil(swl=0.1) assert gasoil.swirr == 0.0 assert gasoil.swl == 0.1 gasoil = GasOil(swirr=0.1) assert gasoil.swirr == 0.1 assert gasoil.swl == 0.1 # This one is zero by default, but will follow swirr. assert gasoil.sorg == 0.0 assert gasoil.sgcr == 0.0 gasoil = GasOil(tag="foobar") assert gasoil.tag == "foobar" # This will print a warning, but will be the same as "" gasoil = GasOil(krgendanchor="bogus") assert isinstance(gasoil, GasOil) assert gasoil.krgendanchor == "" # Test with h=1 gasoil = GasOil(h=1) gasoil.add_corey_gas() gasoil.add_corey_oil() assert np.isclose(gasoil.crosspoint(), 0.5) assert len(gasoil.table) == 2 gasoil = GasOil(swl=0.1, h=1) gasoil.add_corey_gas() gasoil.add_corey_oil() assert len(gasoil.table) == 2 assert np.isclose(gasoil.crosspoint(), 0.45) assert np.isclose(gasoil.table["sg"].min(), 0) assert np.isclose(gasoil.table["sg"].max(), 0.9) # Test too small h: gasoil = GasOil(swl=0.1, h=0.00000000000000000001) # (a warning is printed that h is truncated) assert gasoil.h == 1 / SWINTEGERS
def test_kromaxend(): """Manual testing of kromax and kroend behaviour""" gasoil = GasOil(swirr=0.01, sgcr=0.01, h=0.01, swl=0.1, sorg=0.05) gasoil.add_LET_gas() gasoil.add_LET_oil(2, 2, 2.1) assert gasoil.table["krog"].max() == 1 gasoil.add_LET_oil(2, 2, 2.1, kroend=0.5, kromax=0.9) check_linear_sections(gasoil) assert gasoil.table["krog"].max() == 0.9 # Second krog-value should be kroend, values in between will be linearly # interpolated in Eclipse assert gasoil.table.sort_values("krog")[-2:-1]["krog"].values[0] == 0.5 assert 0 < gasoil.crosspoint() < 1 gasoil.add_corey_oil(2) assert gasoil.table["krog"].max() == 1 gasoil.add_corey_oil(nog=2, kroend=0.5, kromax=0.9) assert gasoil.table["krog"].max() == 0.9 assert gasoil.table.sort_values("krog")[-2:-1]["krog"].values[0] == 0.5
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_gasoil_init(): """Check the __init__ method for GasOil are arguments handled correctly?""" gasoil = GasOil() assert isinstance(gasoil, GasOil) assert gasoil.swirr == 0.0 assert gasoil.swl == 0.0 assert gasoil.krgendanchor == "" # Because sorg is zero gasoil = GasOil(swl=0.1) assert gasoil.swirr == 0.0 assert gasoil.swl == 0.1 gasoil = GasOil(swirr=0.1) assert gasoil.swirr == 0.1 assert gasoil.swl == 0.1 # This one is zero by default, but will follow swirr. assert gasoil.sorg == 0.0 assert gasoil.sgcr == 0.0 gasoil = GasOil(tag="foobar") assert gasoil.tag == "foobar" # This will print a warning, but will be the same as "" gasoil = GasOil(krgendanchor="bogus") assert isinstance(gasoil, GasOil) assert gasoil.krgendanchor == "" # Test with h=1 gasoil = GasOil(h=1) gasoil.add_corey_gas() gasoil.add_corey_oil() assert np.isclose(gasoil.crosspoint(), 0.5) assert len(gasoil.table) == 2 gasoil = GasOil(swl=0.1, h=1) gasoil.add_corey_gas() gasoil.add_corey_oil() assert len(gasoil.table) == 2 assert np.isclose(gasoil.crosspoint(), 0.45) assert np.isclose(gasoil.table["sg"].min(), 0) assert np.isclose(gasoil.table["sg"].max(), 0.9)
def test_nexus(): """Test the Nexus export""" 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) nexus_lines = gasoil.GOTABLE().splitlines() non_comments = [ line for line in nexus_lines if not line.startswith("!") or not len(line) ] assert non_comments[0] == "GOTABLE" assert non_comments[1] == "SG KRG KROG 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_gascondensate(): """Test how sgro works when data is tabulated. Sgro is to be used for gas condensate modelling. sgro is tricky because only 0 and sgcr are valid values for sgro when constructing the objects.""" # When sgro is nonzero, we are doing gas condensate modelling: gascond_orig = GasOil(sgro=0.2, sgcr=0.2, h=0.1) gascond_orig.add_corey_gas() gascond_orig.add_corey_oil(kroend=0.8) # Make a new object without assuming anything about sgro and sgcr: gascond_tabulated = GasOil(h=0.1) gascond_tabulated.add_fromtable(gascond_orig.table) check_table(gascond_tabulated.table) # sgro is estimated correctly in this case: assert np.isclose(gascond_tabulated.sgro, gascond_orig.sgro) # The object constructed from the table has an extra row at SG=0.1, because # we didn't tell it that sgcr was 0.2, otherwise they are numerically # equivalent: assert len(gascond_tabulated.table) == len(gascond_orig.table) + 1 pd.testing.assert_frame_equal( gascond_orig.table.iloc[1:][["SG", "KRG", "KROG"]].reset_index(drop=True), gascond_tabulated.table.iloc[2:][["SG", "KRG", "KROG"]].reset_index(drop=True), ) # Make a tricky gascondensate object which has a linear oil curve. The sgro # estimate will become 1.0, we should still be able to use this as a table. gascond_linear = GasOil(sgro=0.2, sgcr=0.2, h=0.1) gascond_linear.add_corey_gas() gascond_linear.add_corey_oil(kroend=0.8, kromax=1, nog=1) gascond_linear_tabulated = GasOil(h=0.1) gascond_linear_tabulated.add_fromtable(gascond_linear.table) check_table(gascond_linear_tabulated.table) # sgro could not be guessed here, and is reset to zero: assert np.isclose(gascond_linear_tabulated.sgro, 0.0)
def test_numerical_problems(swl, sorg, sgcr): """Test fine-tuned numerics for slgof, this function should trigger the code path in slgof_df() where slgof_sl_mismatch is small. Note: The code path taken may depend on hardware/OS etc. """ # Because we cut away some saturation points due to SWINTEGERS, we easily # end in a situation where the wrong saturation point of to "equal" ones # is removed (because in SLGOF, sg is flipped to sl) # Unrounded, this represents a numerical difficulty, when h is low enough, # but there is special code in slgof_df() to workaround this. gasoil = GasOil(swl=swl, sorg=sorg, sgcr=sgcr, h=0.001) gasoil.add_corey_gas() gasoil.add_corey_oil() assert gasoil.selfcheck() slgof = gasoil.slgof_df() assert np.isclose(slgof["SL"].values[0], gasoil.swl + gasoil.sorg) assert np.isclose(slgof["SL"].values[-1], 1.0) check_table(slgof)
def test_gasoil_slgof(): """Test fine-tuned numerics for slgof""" # Parameter set found by hypothesis swl = 0.029950000000000105 sorg = 0.0 sgcr = 0.01994999999999992 # Because we cut away some saturation points due to SWINTEGERS, we easily # end in a situation where the wrong saturation point of to "equal" ones # is removed (because in SLGOF, sg is flipped to sl) # Unrounded, this represents a numerical difficulty, when h is low enough, # but there is special code in slgof_df() to workaround this. gasoil = GasOil(swl=swl, sorg=sorg, sgcr=sgcr, h=0.001) gasoil.add_corey_gas() gasoil.add_corey_oil() assert gasoil.selfcheck() slgof = gasoil.slgof_df() assert np.isclose(slgof["sl"].values[0], gasoil.swl + gasoil.sorg) assert np.isclose(slgof["sl"].values[-1], 1.0) check_table(slgof)