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 sat_table_str_ok(swof) sat_table_str_ok(wateroil.SWFN())
def check_endpoints(gasoil, krgend, krgmax, kroend, kromax): """Discrete tests that endpoints get numerically correct""" swtol = 1 / SWINTEGERS # Oil curve, from sg = 0 to sg = 1: if gasoil.sgro < swtol: assert float_df_checker(gasoil.table, "SG", 0, "KROG", kroend) assert np.isclose(gasoil.table["KROG"].max(), kroend) else: assert float_df_checker(gasoil.table, "SG", 0, "KROG", kromax) assert float_df_checker(gasoil.table, "SON", 1.0, "KROG", kroend) assert np.isclose(gasoil.table["KROG"].max(), kromax) # son=0 @ 1 - sorg - swl or 1 - swl) should be zero: assert float_df_checker(gasoil.table, "SON", 0.0, "KROG", 0) # sgn=1 @ 1 - swl: assert float_df_checker(gasoil.table, "SGN", 1.0, "KROG", 0) assert np.isclose(gasoil.table["KROG"].min(), 0.0) # Gas curve, from sg=0 to sg=1: assert float_df_checker(gasoil.table, "SG", 0.0, "KRG", 0) assert float_df_checker(gasoil.table, "SGN", 0.0, "KRG", 0) assert float_df_checker(gasoil.table, "SG", gasoil.sgcr, "KRG", 0) # If krgendanchor == "sorg" then krgmax is irrelevant. if gasoil.sorg > swtol and gasoil.sorg > gasoil.h and gasoil.krgendanchor == "sorg": assert float_df_checker(gasoil.table, "SGN", 1.0, "KRG", krgend) assert np.isclose(gasoil.table["KRG"].max(), krgmax) if gasoil.krgendanchor != "sorg": assert np.isclose(gasoil.table["KRG"].max(), krgend) assert np.isclose(gasoil.table["KRG"].min(), 0.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, 0], [0.9, 1, 0, 2]]) # 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, 0], [0.9, 0.8, 0, 2]]) 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", pccolname=None) # 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") df3 = pd.DataFrame(columns=["SG", "KRG", "KROG", "PCOG"], data=[[0, -0.01, 1, 0], [1, 1, 0, 0]]) gasoil = GasOil(h=0.1) with pytest.raises(ValueError): # Should say krg is negative gasoil.add_fromtable(df3, krgcolname="KRG") df4 = pd.DataFrame( columns=["SG", "KRG", "KROG", "PCOG"], data=[[0, 0, 1, 0], [1, 1.0000000001, 0, 0]], ) gasoil = GasOil(h=0.1) with pytest.raises(ValueError): # Should say krg is above 1.0 print(df4) gasoil.add_fromtable(df4, krgcolname="KRG")
def check_endpoints(gaswater, krwend, krwmax, krgend): """Check that the code produces correct endpoints for parametrizations, on discrete cases""" swtol = 1 / SWINTEGERS # Check endpoints for gas curve: # krg at swl should be krgend: assert float_df_checker(gaswater.gasoil.table, "sgn", 1.0, "krg", krgend) assert float_df_checker(gaswater.gasoil.table, "sl", gaswater.swl, "krg", krgend) # krg at sgcr (sgn is zero there) should be zero: assert float_df_checker(gaswater.gasoil.table, "sgn", 0.0, "krg", 0.0) assert float_df_checker(gaswater.gasoil.table, "sl", 1 - gaswater.sgcr, "krg", 0.0) check_linear_sections(gaswater.gasoil) check_linear_sections(gaswater.wateroil) # Check endpoints for water curve: (np.isclose is only reliable around 1) assert float_df_checker(gaswater.wateroil.table, "swn", 0.0, "krw", 0.0) assert float_df_checker(gaswater.wateroil.table, "sw", gaswater.swcr, "krw", 0) if gaswater.sgrw > swtol: # (hard to get it right when sgrw is less than h and close to zero) assert float_df_checker(gaswater.wateroil.table, "sw", 1 - gaswater.sgrw, "krw", krwend) assert np.isclose(gaswater.wateroil.table["krw"].max(), krwmax) else: assert np.isclose(gaswater.wateroil.table["krw"].max(), krwend)
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_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_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 sg=0 assert float_df_checker(gasoil.table, "sg", 0, "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_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 check_endpoints(wateroil, krwend, krwmax, kroend): """Check that the code produces correct endpoints for parametrizations, on discrete cases""" swtol = 1 / SWINTEGERS # Check endpoints for oil curve: # krow at swcr should be kroend: if wateroil.swcr > wateroil.swl + swtol: assert float_df_checker(wateroil.table, "SON", 1.0, "KROW", kroend) # krow at sorw should be zero: assert float_df_checker(wateroil.table, "SON", 0.0, "KROW", 0.0) assert np.isclose(wateroil.table["KROW"].max(), kroend) # Check endpoints for water curve: (np.isclose is only reliable around 1) assert float_df_checker(wateroil.table, "SWN", 0.0, "KRW", 0.0) assert float_df_checker(wateroil.table, "SW", wateroil.swcr, "KRW", 0) if wateroil.sorw > swtol: # (hard to get it right when sorw is less than h and close to zero) assert float_df_checker(wateroil.table, "SW", 1 - wateroil.sorw, "KRW", krwend) assert np.isclose(wateroil.table["KRW"].max(), krwmax) else: assert np.isclose(wateroil.table["KRW"].max(), krwend)
def test_normalized_j(caplog): """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) wateroil = WaterOil(swirr=0.1, swl=0.11, h=0.1) wateroil.add_normalized_J(a=0.5, b=-0.001, poro=0.2, perm=10, sigma_costau=30) assert "b exponent is very small" in caplog.text wateroil = WaterOil(swirr=0.1, swl=0.11, h=0.1) wateroil.add_normalized_J(a=0.001, b=-2, poro=0.2, perm=10, sigma_costau=30) assert "a parameter is very small" in caplog.text wateroil = WaterOil(swirr=0.1, swl=0.11, h=0.1) wateroil.add_normalized_J(a=9, b=-2, poro=0.2, perm=10, sigma_costau=30) assert "a parameter is very high" in caplog.text
def check_endpoints(gasoil, krgend, krgmax, kroend): """Discrete tests that endpoints get numerically correct""" swtol = 1 / SWINTEGERS # Check endpoints for oil curve: # krog at sgcr should be kroend if gasoil.sgcr > swtol: assert float_df_checker(gasoil.table, "son", 1.0, "krog", kroend) # krog at son=0 (1-sorg-swl or 1 - swl) should be zero: assert float_df_checker(gasoil.table, "son", 0.0, "krog", 0) assert float_df_checker(gasoil.table, "sg", 0, "krog", kroend) assert float_df_checker(gasoil.table, "sgn", 0.0, "krg", 0) assert float_df_checker(gasoil.table, "sg", gasoil.sgcr, "krg", 0) # If krgendanchor == "sorg" then krgmax is irrelevant. if gasoil.sorg > swtol and gasoil.sorg > gasoil.h and gasoil.krgendanchor == "sorg": assert float_df_checker(gasoil.table, "sgn", 1.0, "krg", krgend) assert np.isclose(gasoil.table["krg"].max(), krgmax) if gasoil.krgendanchor != "sorg": assert np.isclose(gasoil.table["krg"].max(), krgend)
def test_wateroil_normalization(swirr, swl, swcr, sorw, h, tag): """Shoot with more realistic values and test normalized saturations""" wateroil = WaterOil(swirr=swirr, swl=swl, swcr=swcr, sorw=sorw, h=h, tag=tag) assert not wateroil.table.empty assert not wateroil.table.isnull().values.any() # Check that son is 1 at swl: assert float_df_checker(wateroil.table, "SW", wateroil.swl, "SON", 1) # Check that son is 0 at sorw: if wateroil.sorw > h: assert float_df_checker(wateroil.table, "SW", 1 - wateroil.sorw, "SON", 0) # Check that swn is 0 at swcr: assert float_df_checker(wateroil.table, "SW", wateroil.swcr, "SWN", 0) # Check that swn is 1 at 1 - sorw if wateroil.sorw > 1 / SWINTEGERS: assert float_df_checker(wateroil.table, "SW", 1 - wateroil.sorw, "SWN", 1) # Check that swnpc is 0 at swirr and 1 at 1: if wateroil.swirr >= wateroil.swl + h: assert float_df_checker(wateroil.table, "SW", wateroil.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(wateroil.table, "SW", 1.0, "SWNPC", 1)
def test_ip_go_kroend(): """Test behaviour of kroend under interpolation""" go_low = GasOil(swl=0, sgcr=0.1, sorg=0.2) go_low.add_corey_gas(ng=2, krgend=0.5, krgmax=0.7) go_low.add_corey_oil(nog=2, kroend=0.6) go_high = GasOil(swl=0.02, sgcr=0.05, sorg=0.1) go_high.add_corey_gas(ng=2, krgend=0.5, krgmax=0.72) go_high.add_corey_oil(nog=2, kroend=0.7) # Interpolate to midpoint between the curves above go_ip = interpolate_go(go_low, go_high, 0.5) # kroend at sg zero: assert float_df_checker(go_ip.table, "sg", 0.0, "krog", (0.6 + 0.7) / 2.0) assert np.isclose(go_ip.swl, 0.01) assert np.isclose(go_ip.sorg, 0.15) # krgmax at 1 - swl: assert float_df_checker(go_ip.table, "sg", 1 - go_ip.swl, "krg", 0.71) # krgend at 1 - swl - sorg assert float_df_checker(go_ip.table, "sg", 1 - go_ip.swl - go_ip.sorg, "krg", 0.5) # If krgendanchor is None, then krgmax should be irrelevant go_low = GasOil(swl=0, sgcr=0.1, sorg=0.2, krgendanchor="") go_low.add_corey_gas(ng=5, krgend=0.5, krgmax=0.7) # krgmax will trigger warning message, intended, as the 0.7 # value here will mean nothing. go_low.add_corey_oil(nog=2, kroend=0.6) go_high = GasOil(swl=0.02, sgcr=0.05, sorg=0.1, krgendanchor="") go_high.add_corey_gas(ng=4, krgend=0.5, krgmax=0.72) # krgmax will trigger warning message, intended. go_high.add_corey_oil(nog=2, kroend=0.7) # Interpolate to midpoint between the curves above go_ip = interpolate_go(go_low, go_high, 0.5, h=0.1) assert float_df_checker(go_ip.table, "sg", 0.0, "krog", (0.6 + 0.7) / 2.0) # Activate these line to see a bug, interpolation_go # does not honor krgendanchorA: # _, mpl_ax = plt.subplots() # go_low.plotkrgkrog(mpl_ax=mpl_ax, color="red") # go_high.plotkrgkrog(mpl_ax=mpl_ax, color="blue") # go_ip.plotkrgkrog(mpl_ax=mpl_ax, color="green") # plt.show() # krgmax is irrelevant, krgend is used here: assert float_df_checker(go_ip.table, "sg", 1 - 0.01, "krg", 0.5) # Also check that estimated new sgcr is between the inputs: assert 0.05 <= go_ip.estimate_sgcr() <= 0.1 # Do we get into trouble if krgendanchor is different in low and high? go_low = GasOil(swl=0, sgcr=0.1, sorg=0.2, krgendanchor="sorg") go_low.add_corey_gas(ng=2, krgend=0.5, krgmax=0.7) go_low.add_corey_oil(nog=2, kroend=0.6) go_high = GasOil(swl=0.02, sgcr=0.05, sorg=0.1, krgendanchor="") go_high.add_corey_gas(ng=2, krgend=0.5) go_high.add_corey_oil(nog=2, kroend=0.7) # Interpolate to midpoint between the curves above go_ip = interpolate_go(go_low, go_high, 0.5) assert float_df_checker(go_ip.table, "sg", 0.0, "krog", (0.6 + 0.7) / 2.0) # max(krg) is here avg of krgmax and krgend from the differnt tables: assert float_df_checker(go_ip.table, "sg", 1 - 0.01, "krg", 0.6) # krgend at 1 - swl - sorg, non-trivial expression, so a numerical # value is used here in the test: assert float_df_checker(go_ip.table, "sg", 1 - 0.01 - 0.15, "krg", 0.4491271) # krog-zero at 1 - swl - sorg: assert float_df_checker(go_ip.table, "sg", 1 - 0.01 - 0.15, "krog", 0)