def test_swfn(): """Test that we can dump SWFN without giving gas relperm""" gaswater = GasWater(h=0.1) gaswater.add_corey_water() swfnstr = gaswater.SWFN() assert "SWFN" in swfnstr assert len(swfnstr) > 15
def test_gaswater_tag(tag): """Test that we are unlikely to crash Eclipse by having ugly tag names""" gaswater = GasWater(h=0.5, tag=tag) gaswater.add_corey_gas() gaswater.add_corey_water() sat_table_str_ok(gaswater.SWFN()) sat_table_str_ok(gaswater.SGFN())
def test_fast(): """Test the fast mode, skipping some computations""" gaswater = GasWater(fast=True) assert gaswater.fast gaswater.add_corey_gas() gaswater.add_corey_water() swfn = gaswater.SWFN() assert "krw = krg" not in swfn # Crosspoint should not be present sgfn = gaswater.SGFN() assert "krw = krg" not in sgfn # Crosspoint should not be present
def test_linearsegments(): """Made for testing the linear segments during the resolution of issue #163""" gaswater = GasWater(h=0.01, swl=0.1, swcr=0.3, sgrw=0.3) gaswater.add_corey_gas(ng=10, krgend=0.5) gaswater.add_corey_water(nw=10, krwend=0.5) check_table(gaswater.gasoil.table) check_table(gaswater.wateroil.table) check_linear_sections(gaswater.wateroil) check_linear_sections(gaswater.gasoil)
def test_gaswater_let1(l, e, t, krwend, krwmax): """Test random LET parameters""" gaswater = GasWater() try: gaswater.add_LET_gas(l, e, t, krwend) gaswater.add_LET_water(l, e, t, krwend, krwmax) except AssertionError: # This happens for negative values f.ex. return assert "krg" in gaswater.gasoil.table assert "krw" in gaswater.wateroil.table assert isinstance(gaswater.wateroil.krwcomment, str) check_table(gaswater.wateroil.table) check_table(gaswater.gasoil.table) check_linear_sections(gaswater.wateroil) check_linear_sections(gaswater.gasoil) swfnstr = gaswater.SWFN() assert len(swfnstr) > 100 sgfnstr = gaswater.SGFN() assert len(sgfnstr) > 100
def test_gaswater_corey1(nw, ng): """Test random corey parameters""" gaswater = GasWater() try: gaswater.add_corey_gas(ng=ng) gaswater.add_corey_water(nw=nw) except AssertionError: # This happens for "invalid" input return assert "krg" in gaswater.gasoil.table assert "krw" in gaswater.wateroil.table assert isinstance(gaswater.wateroil.krwcomment, str) check_table(gaswater.wateroil.table) check_table(gaswater.gasoil.table) check_linear_sections(gaswater.wateroil) check_linear_sections(gaswater.gasoil) swfnstr = gaswater.SWFN() assert len(swfnstr) > 100 sgfnstr = gaswater.SGFN() assert len(sgfnstr) > 100
def test_constructor(): """Test that object attributes are set upon intialization""" gaswater = GasWater() gaswater.add_corey_gas() gaswater.add_corey_water() assert "Corey" in gaswater.krwcomment assert "Corey" in gaswater.krgcomment # Trigger tag inconsistency: gaswater.wateroil.tag = "Foo" gaswater.gasoil.tag = "Bar" with pytest.raises(ValueError, match="Internal tag-inconsistency in GasWater"): gaswater.tag
def test_comments(): """Test that the outputters include endpoints in comments""" gaswater = GasWater(h=0.3) gaswater.add_corey_water() gaswater.add_corey_gas() swfn = gaswater.SWFN() assert "--" in swfn assert "pyscal: " in swfn # part of version string assert "swirr=0" in swfn assert "swcr=0" in swfn assert "swl=0" in swfn assert "sgrw=0" in swfn assert "sgcr=0" in swfn assert "nw=2" in swfn assert "krwend=1" in swfn assert "Corey" in swfn assert "krw = krg @ sw=0.5" in swfn assert "Zero capillary pressure" in swfn assert "SW" in swfn assert "KRW" in swfn assert "KRGW" not in swfn assert "PC" in swfn sgfn = gaswater.SGFN() assert "--" in sgfn assert "pyscal: " in sgfn # part of version string assert "swirr=0" in sgfn assert "sgcr=0" in sgfn assert "swl=0" in sgfn assert "ng=2" in sgfn assert "krgend=1" in sgfn assert "Corey" in sgfn assert "krw = krg @ sw=0.5" in sgfn assert "Zero capillary pressure" in sgfn assert "SG" in sgfn assert "KRW" not in sgfn assert "KRG" in sgfn assert "PC" in sgfn
def test_crosspoint(): """Test the crosspoint computation (on edge cases)""" gaswater = GasWater(swl=0.0, sgrw=0.0, sgcr=0.0, h=0.1) gaswater.add_corey_water(nw=1) gaswater.add_corey_gas(ng=1) assert np.isclose(gaswater.crosspoint(), 0.5) assert "-- krw = krg @ sw=0.5" in gaswater.SWFN() gaswater = GasWater(swl=0.5, sgrw=0.0, sgcr=0.0, h=0.1) gaswater.add_corey_water(nw=1) gaswater.add_corey_gas(ng=1) assert np.isclose(gaswater.crosspoint(), 0.75) gaswater = GasWater(swl=0.0, sgrw=0.5, sgcr=0.0, h=0.1) gaswater.add_corey_water(nw=1) gaswater.add_corey_gas(ng=1) assert np.isclose(gaswater.crosspoint(), 0.3333333) gaswater = GasWater(swl=0.0, sgrw=0.5, sgcr=0.5, h=0.1) gaswater.add_corey_water(nw=1) gaswater.add_corey_gas(ng=1) assert np.isclose(gaswater.crosspoint(), 0.25) gaswater = GasWater(swl=0.0, sgrw=0.5, sgcr=0.5, h=0.1) gaswater.add_corey_water(nw=1, krwend=0.5) gaswater.add_corey_gas(ng=1, krgend=0.5) assert np.isclose(gaswater.crosspoint(), 0.25) # Test warning/error situation: del gaswater.wateroil.table["KRW"] assert gaswater.crosspoint() is None
def test_crosspoint(): """Test the crosspoint computation (on edge cases)""" gaswater = GasWater(swl=0.0, sgrw=0.0, sgcr=0.0, h=0.1) gaswater.add_corey_water(nw=1) gaswater.add_corey_gas(ng=1) assert np.isclose(gaswater.crosspoint(), 0.5) gaswater = GasWater(swl=0.5, sgrw=0.0, sgcr=0.0, h=0.1) gaswater.add_corey_water(nw=1) gaswater.add_corey_gas(ng=1) assert np.isclose(gaswater.crosspoint(), 0.75) gaswater = GasWater(swl=0.0, sgrw=0.5, sgcr=0.0, h=0.1) gaswater.add_corey_water(nw=1) gaswater.add_corey_gas(ng=1) assert np.isclose(gaswater.crosspoint(), 0.3333333) gaswater = GasWater(swl=0.0, sgrw=0.5, sgcr=0.5, h=0.1) gaswater.add_corey_water(nw=1) gaswater.add_corey_gas(ng=1) assert np.isclose(gaswater.crosspoint(), 0.25) gaswater = GasWater(swl=0.0, sgrw=0.5, sgcr=0.5, h=0.1) gaswater.add_corey_water(nw=1, krwend=0.5) gaswater.add_corey_gas(ng=1, krgend=0.5) assert np.isclose(gaswater.crosspoint(), 0.25)
def test_gaswater_pc(): """Test that capillary pressure can be added to GasWater. The GasWater object is calling up the code in WaterOil, which is tested more thorougly, in this test function we need to make sure the functionality is in place.""" gaswater = GasWater(swl=0.1, h=0.2) gaswater.add_corey_water() gaswater.add_corey_gas() gaswater.add_simple_J() assert gaswater.wateroil.table["pc"].abs().sum() > 0 swfn = gaswater.SWFN() assert "Simplified J-function" in swfn assert "0.1000000 0.0000000 0.23266" in swfn # this is the first row. sat_table_str_ok(swfn) sgfn = gaswater.SGFN() # Capillary pressure in SGFN must always be zero for GasWater. assert "Zero capillary pressure" in sgfn sat_table_str_ok(sgfn) # Overwrite to zero: gaswater.add_simple_J(drho=0) swfn = gaswater.SWFN() assert "0.1000000 0.0000000 0.0000000" in swfn # first row sat_table_str_ok(sgfn) # Petrophysical pc: gaswater.add_simple_J_petro(a=1, b=-1) swfn = gaswater.SWFN() assert "petrophysical version" in swfn assert "0.1000000 0.0000000 0.014715" in swfn # first row
def interpolate(self, parameter, parameter2=None, h=0.02): """Interpolate between low, base and high Endpoints are located for input curves, and interpolated individually. Interpolation for the nonlinear part is done on a normalized interval between the endpoints Interpolation is linear in relperm-direction, and will thus not be linear in log-relperm-direction This method returns an WaterOilGas object which can be realized into printed tables. No attempt is made to parametrize the interpolant in L,E,T parameter space, or Corey-space. Args: parameter (float): Between -1 and 1, inclusive. -1 reproduces low/ pessimistic curve, 0 gives base, 1 gives high/optimistic. parameter2 (float): If not None, used for the gas-oil interpolation, enables having interpolation uncorrelated for WaterOil and GasOil. Ignored for GasWater (no warning). h (float): Saturation step length in generated tables. Does not need to be the same as the tables interpolation is done from. """ if parameter2 is not None: gasparameter = parameter2 else: gasparameter = parameter # Either wateroil or gasoil can be None in the low, base, high # If they are None, it is a two-phase problem and we # should support this. do_gaswater = False do_wateroil = False do_gasoil = False if self.type == GasWater: do_gaswater = True elif self.type == WaterOilGas: do_wateroil = (self.base.wateroil is not None and self.low.wateroil is not None and self.high.wateroil is not None) do_gasoil = (self.base.gasoil is not None and self.low.gasoil is not None and self.high.gasoil is not None) if not do_gaswater: if not do_wateroil and not do_gasoil: raise ValueError( "Neither WaterOil or GasOil is complete in SCAL recommendation" ) if parameter2 is not None: if not do_gasoil: logger.warning("parameter2 is meaningless for water-oil only") if do_gaswater: logger.warning("parameter2 is meaningless for gas-water") # Initialize wateroil and gasoil curves to be filled with # interpolated curves: tags = set() if do_wateroil or do_gaswater: tags = tags.union( set([ self.base.wateroil.tag, self.low.wateroil.tag, self.high.wateroil.tag, ])) if do_gasoil: tags = tags.union( set([ self.base.gasoil.tag, self.low.gasoil.tag, self.high.gasoil.tag ])) tagstring = "\n".join(tags) if do_gaswater: interpolant = GasWater(h=h, tag=tagstring) if gasparameter != parameter: logger.warning( "Different interpolation parameters for Water and for " "gas in GasWater, this is maybe not what you want") else: interpolant = WaterOilGas(h=h, tag=tagstring) if do_wateroil or do_gaswater: tag = ( "SCAL recommendation interpolation to {}\n".format(parameter) + tagstring) if abs(parameter) > 1.0: logger.error("Interpolation parameter must be in [-1,1]") assert abs(parameter) <= 1.0 elif np.isclose(parameter, 0.0): interpolant.wateroil = copy.deepcopy(self.base.wateroil) interpolant.wateroil.tag = tag elif np.isclose(parameter, -1.0): interpolant.wateroil = copy.deepcopy(self.low.wateroil) interpolant.wateroil.tag = tag elif np.isclose(parameter, 1.0): interpolant.wateroil = copy.deepcopy(self.high.wateroil) interpolant.wateroil.tag = tag elif parameter < 0.0: interpolant.wateroil = interpolate_wo(self.base.wateroil, self.low.wateroil, -parameter, h=h, tag=tag) elif parameter > 0.0: interpolant.wateroil = interpolate_wo(self.base.wateroil, self.high.wateroil, parameter, h=h, tag=tag) else: interpolant.wateroil = None if do_gasoil or do_gaswater: tag = ("SCAL recommendation interpolation to {}\n".format( gasparameter) + tagstring) if abs(gasparameter) > 1.0: logger.error("Interpolation parameter must be in [-1,1]") assert abs(gasparameter) <= 1.0 elif np.isclose(gasparameter, 0.0): interpolant.gasoil = copy.deepcopy(self.base.gasoil) interpolant.gasoil.tag = tag elif np.isclose(gasparameter, -1.0): interpolant.gasoil = copy.deepcopy(self.low.gasoil) interpolant.gasoil.tag = tag elif np.isclose(gasparameter, 1.0): interpolant.gasoil = copy.deepcopy(self.high.gasoil) interpolant.gasoil.tag = tag elif gasparameter < 0.0: interpolant.gasoil = interpolate_go(self.base.gasoil, self.low.gasoil, -1 * gasparameter, h=h, tag=tag) elif gasparameter > 0.0: interpolant.gasoil = interpolate_go(self.base.gasoil, self.high.gasoil, gasparameter, h=h, tag=tag) else: interpolant.gasoil = None return interpolant
def test_gaswater_linear(): """Test linear gaswater curves (linear as in giving only two saturation points to Eclipse)""" gaswater = GasWater(h=1) gaswater.add_corey_water() gaswater.add_corey_gas() swfnstr = gaswater.SWFN(header=False) check_table(gaswater.wateroil.table) check_table(gaswater.gasoil.table) check_linear_sections(gaswater.wateroil) check_linear_sections(gaswater.gasoil) assert isinstance(swfnstr, str) assert swfnstr assert len(gaswater.wateroil.table) == 2 # assert np.isclose(gaswater.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) gaswater = GasWater(swl=0.1, h=1) gaswater.add_corey_water() gaswater.add_corey_gas() check_table(gaswater.wateroil.table) check_table(gaswater.gasoil.table) check_linear_sections(gaswater.wateroil) check_linear_sections(gaswater.gasoil) assert len(gaswater.wateroil.table) == 2 assert len(gaswater.gasoil.table) == 2 assert np.isclose(gaswater.wateroil.table["sw"].min(), 0.1) assert np.isclose(gaswater.wateroil.table["sw"].max(), 1.0)
def test_plotting(): """Test that plotting code pass through (nothing displayed)""" gaswater = GasWater(swl=0.1, h=0.1) gaswater.add_corey_gas() gaswater.add_corey_water() gaswater.plotkrwkrg(mpl_ax=matplotlib.pyplot.subplots()[1])
def test_gaswater_krendmax(swl, swcr, sgrw, krgend, krwend, krwmax, h, fast): """Test endpoints for gaswater using hypothesis testing""" try: gaswater = GasWater(swl=swl, swcr=swcr, sgrw=sgrw, h=h, fast=fast) except AssertionError: return krwend = min(krwend, krwmax) gaswater.add_corey_gas(krgend=krgend) gaswater.add_corey_water(krwend=krwend, krwmax=krwmax) check_table(gaswater.wateroil.table) check_table(gaswater.gasoil.table) assert gaswater.selfcheck() # assert 0 < gaswater.crosspoint() < 1 check_endpoints(gaswater, krwend, krwmax, krgend) #################################### # Do it over again, but with LET: gaswater.add_LET_gas(t=1.1, krgend=krgend) gaswater.add_LET_water(t=1.1, krwend=krwend, krwmax=krwmax) assert gaswater.selfcheck() check_table(gaswater.gasoil.table) check_table(gaswater.wateroil.table) # Check endpoints for oil curve: check_endpoints(gaswater, krwend, krwmax, krgend) check_linear_sections(gaswater.wateroil) check_linear_sections(gaswater.gasoil)
def test_interpolate_gw(): """Discrete test scenarios for gaswater interpolation""" # pylint: disable=too-many-locals swl_l = random.uniform(0, 0.1) swcr_l = swl_l + random.uniform(0, 0.1) sgrw_l = random.uniform(0, 0.2) sgcr_l = random.uniform(0, 0.3) swl_h = random.uniform(0, 0.1) swcr_h = swl_h + random.uniform(0, 0.1) sgrw_h = random.uniform(0, 0.2) sgcr_h = random.uniform(0, 0.3) gw_low = GasWater(swl=swl_l, swcr=swcr_l, sgrw=sgrw_l, sgcr=sgcr_l, h=0.001) gw_high = GasWater(swl=swl_h, swcr=swcr_h, sgrw=sgrw_h, sgcr=sgcr_h, h=0.001) gw_low.add_corey_water(nw=random.uniform(1, 3), krwend=random.uniform(0.5, 1)) gw_high.add_corey_water(nw=random.uniform(1, 3), krwend=random.uniform(0.5, 1)) gw_low.add_corey_gas(ng=random.uniform(1, 3), krgend=random.uniform(0.5, 1)) gw_high.add_corey_gas(ng=random.uniform(1, 3), krgend=random.uniform(0.5, 1)) print(" ** Low curve GasWater (red):\n" + gw_low.swcomment + gw_low.krwcomment + gw_low.krgcomment) print(" ** High curve GasWater (blue):\n" + gw_high.swcomment + gw_high.krwcomment + gw_high.krgcomment) _, mpl_ax = pyplot.subplots() gw_low.plotkrwkrg(mpl_ax, color="red") gw_high.plotkrwkrg(mpl_ax, color="blue") for tparam in np.arange(0, 1, 0.1): gw_wo_ip = utils.interpolation.interpolate_wo(gw_low.wateroil, gw_high.wateroil, tparam, h=0.001) gw_go_ip = utils.interpolation.interpolate_go(gw_low.gasoil, gw_high.gasoil, tparam, h=0.001) gw_ip = GasWater() gw_ip.gasoil = gw_go_ip gw_ip.wateroil = gw_wo_ip gw_ip.plotkrwkrg(mpl_ax, color="green") mpl_ax.set_title("GasWater, random Corey, linear y-scale") _pyplot_show_with_user_message() # Plot again with log yscale: _, mpl_ax = pyplot.subplots() gw_low.plotkrwkrg(mpl_ax, color="red") gw_high.plotkrwkrg(mpl_ax, color="blue") for tparam in np.arange(0, 1, 0.1): gw_wo_ip = utils.interpolation.interpolate_wo(gw_low.wateroil, gw_high.wateroil, tparam, h=0.001) gw_go_ip = utils.interpolation.interpolate_go(gw_low.gasoil, gw_high.gasoil, tparam, h=0.001) gw_ip = GasWater() gw_ip.gasoil = gw_go_ip gw_ip.wateroil = gw_wo_ip gw_ip.plotkrwkrg(mpl_ax, color="green", logyscale=True) mpl_ax.set_title("GasWater, random Corey, log y-scale") _pyplot_show_with_user_message()
def make_gaswater_co2_icd2(show=True): # CO2 trapping plt.xkcd() _, axes = plt.subplots() swl = 0.1 swcr = 0.1 sgcr = 0.3 sgrw = 0.3 krwend = 0.3 krwmax = 1 krgend = 0.8 gaswater = GasWater(swl=swl, swcr=swcr, sgrw=sgrw, sgcr=sgcr, h=0.001) gaswater.add_corey_water(nw=3, krwend=krwend, krwmax=krwmax) gaswater.add_corey_gas(ng=2, krgend=krgend) gaswater.wateroil.table.plot(ax=axes, x="SW", y="KRW", c="blue", alpha=1, label="KRW", linewidth=2) gaswater.gasoil.table.plot(ax=axes, x="SL", y="KRG", c="red", alpha=1, label="KRG", linewidth=2) plt.ylim([-0.02, 1]) plt.xticks([0, 1]) plt.yticks([0, 1]) plt.xlim([-0.02, 1.02]) axes.annotate( "KRGEND", xy=(swl, krgend), arrowprops=dict(arrowstyle="->"), xytext=(swl + 0.1, krgend - 0.1), ) axes.annotate( "KRWEND", xy=(1 - sgrw, krwend), arrowprops=dict(arrowstyle="->"), xytext=(1 - sgrw - 0.23, krwend + 0.1), ) axes.annotate( "KRWMAX", xy=(1, krwmax), arrowprops=dict(arrowstyle="->"), xytext=(1 - 0.23, krwmax - 0.1), ) axes.annotate( "SWL=SWCR", xy=(swl, 0), arrowprops=dict(arrowstyle="->"), xytext=(swl - 0.1, 0 + 0.1), ) plt.xlabel("SW", labelpad=-10) axes.text(1 - sgrw + 0.04, 0.04, "SGRW=SGCR") axes.annotate("", xy=(1 - sgrw, 0.02), xytext=(1, 0.02), arrowprops=dict(arrowstyle="<->")) # Initial state and saturation direction: sw_initial = 0.3 plt.vlines(sw_initial, ymin=0, ymax=1, colors="darkorange", linestyles="dashed") axes.arrow( sw_initial + 0.01, 0.37, 0.08, -0.12, head_width=0.025, fill=True, facecolor="darkorange", ) axes.arrow( sw_initial + 0.01, 0.03, 0.1, 0.03, head_width=0.025, fill=True, facecolor="darkorange", ) axes.legend(loc="upper center") if show: plt.show()
def make_gaswater_endpoints(show=True): """Make a plot explaining the inputs to a WaterOil object""" plt.xkcd() _, axes = plt.subplots() swirr = 0.05 swl = 0.1 swcr = 0.2 sgcr = 0.4 sgrw = 0.2 krwend = 0.65 krwmax = 0.75 krgend = 0.85 gaswater = GasWater(swirr=swirr, swl=swl, swcr=swcr, sgrw=sgrw, sgcr=sgcr, h=0.001) gaswater.add_corey_water(nw=2, krwend=krwend, krwmax=krwmax) gaswater.add_corey_gas(ng=2, krgend=krgend) gaswater.wateroil.table.plot(ax=axes, x="SW", y="KRW", c="blue", alpha=1, label="KRW", linewidth=2) gaswater.gasoil.table.plot(ax=axes, x="SL", y="KRG", c="red", alpha=1, label="KRG", linewidth=2) plt.ylim([-0.02, 1]) plt.xticks([0, 1]) plt.yticks([0, 1]) axes.annotate( "KRGEND", xy=(swl, krgend), arrowprops=dict(arrowstyle="->"), xytext=(swl - 0.1, krgend - 0.3), ) axes.annotate( "KRWEND", xy=(1 - sgrw, krwend), arrowprops=dict(arrowstyle="->"), xytext=(1 - sgrw - 0.23, krwmax - 0.2), ) axes.annotate( "KRWMAX", xy=(1, krwmax), arrowprops=dict(arrowstyle="->"), xytext=(1 - 0.1, krwmax - 0.3), ) axes.annotate( "SWIRR", xy=(swirr, 0), arrowprops=dict(arrowstyle="->"), xytext=(swirr - 0.12, 0 + 0.1), ) axes.annotate( "SWL", xy=(swl, 0), arrowprops=dict(arrowstyle="->"), xytext=(swl - 0.05, 0 + 0.14), ) axes.annotate( "SWCR", xy=(swcr, 0), arrowprops=dict(arrowstyle="->"), xytext=(swcr - 0.06, 0 + 0.21), ) plt.xlabel("SW", labelpad=-10) axes.text(1 - sgrw + 0.04, 0.04, "SGRW") axes.annotate("", xy=(1 - sgrw, 0.02), xytext=(1, 0.02), arrowprops=dict(arrowstyle="<->")) axes.text(1 - sgcr + 0.04, 0.14, "SGCR") axes.annotate("", xy=(1 - sgcr, 0.12), xytext=(1, 0.12), arrowprops=dict(arrowstyle="<->")) if show: plt.show()