def test_gensatfunc(): """Test how the external tool gen_satfunc could use the factory functionality""" pyscal_factory = PyscalFactory() # Example config line for gen_satfunc: conf_line_pc = "RELPERM 4 2 1 3 2 1 0.15 0.10 0.5 20 100 0.2 0.22 -0.5 30" wateroil = pyscal_factory.create_water_oil(parse_gensatfuncline(conf_line_pc)) swof = wateroil.SWOF() assert "0.17580" in swof # krw at sw=0.65 assert "0.0127" in swof # krow at sw=0.65 assert "Capillary pressure from normalized J-function" in swof assert "2.0669" in swof # pc at swl conf_line_min = "RELPERM 1 2 3 1 2 3 0.1 0.15 0.5 20" wateroil = pyscal_factory.create_water_oil(parse_gensatfuncline(conf_line_min)) swof = wateroil.SWOF() assert "Zero capillary pressure" in swof conf_line_few = "RELPERM 1 2 3 1 2 3" with pytest.raises(ValueError): parse_gensatfuncline(conf_line_few) # sigma_costau is missing here: conf_line_almost_pc = "RELPERM 4 2 1 3 2 1 0.15 0.10 0.5 20 100 0.2 0.22 -0.5" wateroil = pyscal_factory.create_water_oil( parse_gensatfuncline(conf_line_almost_pc) ) swof = wateroil.SWOF() # The factory will not recognize the normalized J-function # when costau is missing. Any error message would be the responsibility # of the parser assert "Zero capillary pressure" in swof
def test_check_deprecated_kromax(caplog): """Up until pyscal 0.5.x, kromax was a parameter to the oil curve parametrization for WaterOil and GasOil, and kro was linear between swl and swcr. From pyscal 0.6, that linear segment is gone, and kromax is not needed as a parameter, only krowend/krogend is used. If kromax is encountered in input data, we should warn it is ignored. """ PyscalFactory.create_water_oil(dict(swl=0.1, nw=2, now=2, kroend=0.4, kromax=0.5)) assert "kromax" in caplog.text assert "deprecated" in caplog.text
def test_ambiguity(): factory = PyscalFactory() wo = factory.create_water_oil( dict(swl=0.1, nw=10, Lw=1, Ew=1, Tw=1, now=2, h=0.1, no=2)) # Corey is picked here. assert "Corey" in wo.krwcomment assert "krw" in wo.table
def test_ambiguity(): """Test how the factory handles ambiguity between Corey and LET parameters""" pyscal_factory = PyscalFactory() wateroil = pyscal_factory.create_water_oil( dict(swl=0.1, nw=10, Lw=1, Ew=1, Tw=1, now=2, h=0.1, no=2)) # Corey is picked here. assert "Corey" in wateroil.krwcomment assert "krw" in wateroil.table
def test_fast_mode(): """Test that the fast-flag is passed on to constructed objects Each object's own test code tests the actual effects of the fast flag""" wateroil = PyscalFactory.create_water_oil({"nw": 2, "now": 2}) assert not wateroil.fast wateroil = PyscalFactory.create_water_oil({"nw": 2, "now": 2}, fast=True) assert wateroil.fast gasoil = PyscalFactory.create_gas_oil({"ng": 2, "nog": 2}) assert not gasoil.fast gasoil = PyscalFactory.create_gas_oil({"ng": 2, "nog": 2}, fast=True) assert gasoil.fast gaswater = PyscalFactory.create_gas_water({"nw": 2, "ng": 2}) assert not gaswater.gasoil.fast assert not gaswater.wateroil.fast gaswater = PyscalFactory.create_gas_water({"nw": 2, "ng": 2}, fast=True) assert gaswater.gasoil.fast assert gaswater.wateroil.fast assert gaswater.fast wateroilgas = PyscalFactory.create_water_oil_gas( {"nw": 2, "now": 2, "ng": 2, "nog": 2}, fast=True ) assert wateroilgas.fast assert wateroilgas.wateroil.fast assert wateroilgas.gasoil.fast scalrec = PyscalFactory.create_scal_recommendation( { "low": {"nw": 2, "now": 2, "ng": 2, "nog": 2}, "base": {"nw": 2, "now": 2, "ng": 2, "nog": 2}, "high": {"nw": 2, "now": 2, "ng": 2, "nog": 2}, }, fast=True, ) assert scalrec.low.fast assert scalrec.base.fast assert scalrec.high.fast interpolant = scalrec.interpolate(-0.5) assert interpolant.fast
def test_check_deprecated_krowgend(caplog): """Up until pyscal 0.5.x, krogend and krowend were parameters to the oil curve parametrization for WaterOil and GasOil. From pyscal 0.6.0, krogend and krowend are merged to kroend. """ wateroil = PyscalFactory.create_water_oil(dict(swl=0.1, nw=2, now=2, krowend=0.4)) assert "krowend" in caplog.text assert "deprecated" in caplog.text assert wateroil.table["krow"].max() == 0.4 gasoil = PyscalFactory.create_gas_oil(dict(swl=0.1, ng=2, nog=2, krogend=0.4)) assert "krogend" in caplog.text assert "deprecated" in caplog.text assert gasoil.table["krog"].max() == 0.4
def test_relative_swcr(): """swcr can be initialized relative to swl Relevant when swl is initialized from swlheight.""" pyscal_factory = PyscalFactory() with pytest.raises(ValueError, match="swl must be provided"): pyscal_factory.create_water_oil(dict(swcr_add=0.1, nw=1, now=1, swirr=0.01)) with pytest.raises(ValueError, match="swcr and swcr_add at the same time"): pyscal_factory.create_water_oil( dict(swcr_add=0.1, swcr=0.1, swl=0.1, nw=1, now=1, swirr=0.01) ) wateroil = pyscal_factory.create_water_oil( dict(swcr_add=0.1, swl=0.1, nw=1, now=1, swirr=0.01) ) assert wateroil.swcr == 0.2 # Test when relative to swlheight: wateroil = pyscal_factory.create_water_oil( dict( swlheight=200, swcr_add=0.01, nw=1, now=1, swirr=0.01, a=1, b=-2, poro_ref=0.2, perm_ref=100, drho=200, ) ) assert np.isclose(wateroil.swl, 0.02480395) assert np.isclose(wateroil.swcr, 0.02480395 + 0.01) gaswater = pyscal_factory.create_gas_water( dict( swlheight=200, nw=1, ng=1, swirr=0.01, swcr_add=0.1, a=1, b=-2, poro_ref=0.2, perm_ref=100, drho=200, ) ) assert np.isclose(gaswater.swl, 0.02480395) assert np.isclose(gaswater.swcr, 0.02480395 + 0.1)
def test_factory_wateroil(): """Test that we can create curves from dictionaries of parameters""" pyscal_factory = PyscalFactory() # Factory refuses to create incomplete defaulted objects. with pytest.raises(ValueError): pyscal_factory.create_water_oil() with pytest.raises(TypeError): # (it must be a dictionary) # pylint: disable=unexpected-keyword-arg pyscal_factory.create_water_oil(swirr=0.01) # noqa wateroil = pyscal_factory.create_water_oil( dict( swirr=0.01, swl=0.1, bogus="foobar", tag="Good sand", nw=3, now=2, krwend=0.2, krwmax=0.5, ) ) assert isinstance(wateroil, WaterOil) assert wateroil.swirr == 0.01 assert wateroil.swl == 0.1 assert wateroil.tag == "Good sand" assert "krw" in wateroil.table assert "Corey" in wateroil.krwcomment assert wateroil.table["krw"].max() == 0.2 # Because sorw==0 by default check_table(wateroil.table) sat_table_str_ok(wateroil.SWOF()) sat_table_str_ok(wateroil.SWFN()) wateroil = pyscal_factory.create_water_oil( dict(nw=3, now=2, sorw=0.1, krwend=0.2, krwmax=0.5) ) assert isinstance(wateroil, WaterOil) assert "krw" in wateroil.table assert "Corey" in wateroil.krwcomment assert wateroil.table["krw"].max() == 0.5 check_table(wateroil.table) sat_table_str_ok(wateroil.SWOF()) sat_table_str_ok(wateroil.SWFN()) # Ambiguous works, but we don't guarantee that this results # in LET or Corey. wateroil = pyscal_factory.create_water_oil(dict(nw=3, Lw=2, Ew=2, Tw=2, now=3)) assert "krw" in wateroil.table assert "Corey" in wateroil.krwcomment or "LET" in wateroil.krwcomment check_table(wateroil.table) sat_table_str_ok(wateroil.SWOF()) sat_table_str_ok(wateroil.SWFN()) # Mixing Corey and LET wateroil = pyscal_factory.create_water_oil(dict(Lw=2, Ew=2, Tw=2, krwend=1, now=4)) assert isinstance(wateroil, WaterOil) assert "krw" in wateroil.table assert wateroil.table["krw"].max() == 1.0 assert "LET" in wateroil.krwcomment check_table(wateroil.table) sat_table_str_ok(wateroil.SWOF()) sat_table_str_ok(wateroil.SWFN()) wateroil = pyscal_factory.create_water_oil( dict(Lw=2, Ew=2, Tw=2, Low=3, Eow=3, Tow=3, krwend=0.5) ) assert isinstance(wateroil, WaterOil) assert "krw" in wateroil.table assert "krow" in wateroil.table assert wateroil.table["krw"].max() == 0.5 assert wateroil.table["krow"].max() == 1 assert "LET" in wateroil.krwcomment assert "LET" in wateroil.krowcomment check_table(wateroil.table) sat_table_str_ok(wateroil.SWOF()) sat_table_str_ok(wateroil.SWFN()) # Add capillary pressure wateroil = pyscal_factory.create_water_oil( dict(swl=0.1, nw=1, now=1, a=2, b=-1, poro_ref=0.2, perm_ref=100, drho=200) ) assert "pc" in wateroil.table assert wateroil.table["pc"].max() > 0.0 assert "Simplified J" in wateroil.pccomment check_table(wateroil.table) sat_table_str_ok(wateroil.SWOF()) sat_table_str_ok(wateroil.SWFN()) # Test that the optional gravity g is picked up: wateroil = pyscal_factory.create_water_oil( dict(swl=0.1, nw=1, now=1, a=2, b=-1, poro_ref=0.2, perm_ref=100, drho=200, g=0) ) assert "pc" in wateroil.table assert wateroil.table["pc"].max() == 0.0 check_table(wateroil.table) sat_table_str_ok(wateroil.SWOF()) sat_table_str_ok(wateroil.SWFN()) # Test petrophysical simple J: wateroil = pyscal_factory.create_water_oil( dict( swl=0.1, nw=1, now=1, a_petro=2, b_petro=-1, poro_ref=0.2, perm_ref=100, drho=200, ) ) assert "pc" in wateroil.table assert wateroil.table["pc"].max() > 0.0 assert "etrophysic" in wateroil.pccomment check_table(wateroil.table) sat_table_str_ok(wateroil.SWOF()) sat_table_str_ok(wateroil.SWFN()) # One pc param missing: wateroil = pyscal_factory.create_water_oil( dict(swl=0.1, nw=1, now=1, a=2, b=-1, perm_ref=100, drho=200, g=0) ) assert "pc" not in wateroil.table
def test_init_with_swlheight(): """With sufficient parameters, swl will be calculated on the fly when initializing the WaterOil object""" pyscal_factory = PyscalFactory() wateroil = pyscal_factory.create_water_oil( dict( swlheight=200, nw=1, now=1, swirr=0.01, a=1, b=-2, poro_ref=0.2, perm_ref=100, drho=200, ) ) assert np.isclose(wateroil.swl, 0.02480395) assert "swl=0.024" in wateroil.SWOF() with pytest.raises( ValueError, match="Can't initialize from SWLHEIGHT without sufficient simple-J parameters", ): # This should fail because capillary pressure parameters are not provided. pyscal_factory.create_water_oil(dict(swlheight=200, nw=1, now=1)) # swcr must be larger than swl: with pytest.raises(ValueError, match="lower than computed swl"): pyscal_factory.create_water_oil( dict( swlheight=200, nw=1, now=1, swirr=0.01, swcr=0.0101, a=1, b=-2, poro_ref=0.2, perm_ref=100, drho=200, ) ) # If swcr is large enough, it will pass: wateroil = pyscal_factory.create_water_oil( dict( swlheight=200, nw=1, now=1, swirr=0.01, swcr=0.3, a=1, b=-2, poro_ref=0.2, perm_ref=100, drho=200, ) ) assert wateroil.swcr > wateroil.swl assert wateroil.swcr == 0.3 assert "swcr=0.3" in wateroil.SWOF() # Test that GasWater also can be initialized with swlheight: gaswater = pyscal_factory.create_gas_water( dict( swlheight=200, nw=1, ng=1, swirr=0.01, swcr=0.3, a=1, b=-2, poro_ref=0.2, perm_ref=100, drho=200, ) ) assert "swl=0.024" in gaswater.SWFN() assert gaswater.swcr > gaswater.swl assert gaswater.swcr == 0.3 assert "swcr=0.3" in gaswater.SWFN()
def test_factory_wateroil(): """Test that we can create curves from dictionaries of parameters""" logging.getLogger().setLevel("INFO") factory = PyscalFactory() # Factory refuses to create incomplete defaulted objects. with pytest.raises(ValueError): factory.create_water_oil() with pytest.raises(TypeError): # (it must be a dictionary) factory.create_water_oil(swirr=0.01) # noqa wo = factory.create_water_oil( dict( swirr=0.01, swl=0.1, bogus="foobar", tag="Good sand", nw=3, now=2, krwend=0.2, krwmax=0.5, )) assert isinstance(wo, WaterOil) assert wo.swirr == 0.01 assert wo.swl == 0.1 assert wo.tag == "Good sand" assert "krw" in wo.table assert "Corey" in wo.krwcomment assert wo.table["krw"].max() == 0.2 # Because sorw==0 by default wo = factory.create_water_oil( dict(nw=3, now=2, sorw=0.1, krwend=0.2, krwmax=0.5)) assert isinstance(wo, WaterOil) assert "krw" in wo.table assert "Corey" in wo.krwcomment assert wo.table["krw"].max() == 0.5 # Ambiguous works, but we don't guarantee that this results # in LET or Corey. wo = factory.create_water_oil(dict(nw=3, Lw=2, Ew=2, Tw=2, now=3)) assert "krw" in wo.table assert "Corey" in wo.krwcomment or "LET" in wo.krwcomment wo = factory.create_water_oil(dict(Lw=2, Ew=2, Tw=2, krwend=1, now=4)) assert isinstance(wo, WaterOil) assert "krw" in wo.table assert wo.table["krw"].max() == 1.0 assert "LET" in wo.krwcomment wo = factory.create_water_oil( dict(Lw=2, Ew=2, Tw=2, Low=3, Eow=3, Tow=3, krwend=0.5)) assert isinstance(wo, WaterOil) assert "krw" in wo.table assert "krow" in wo.table assert wo.table["krw"].max() == 0.5 assert wo.table["krow"].max() == 1 assert "LET" in wo.krwcomment assert "LET" in wo.krowcomment # Add capillary pressure wo = factory.create_water_oil( dict(swl=0.1, nw=1, now=1, a=2, b=-1, poro_ref=0.2, perm_ref=100, drho=200)) assert "pc" in wo.table assert wo.table["pc"].max() > 0.0 assert "Simplified J" in wo.pccomment # Test that the optional gravity g is picked up: wo = factory.create_water_oil( dict(swl=0.1, nw=1, now=1, a=2, b=-1, poro_ref=0.2, perm_ref=100, drho=200, g=0)) assert "pc" in wo.table assert wo.table["pc"].max() == 0.0 # One pc param missing: wo = factory.create_water_oil( dict(swl=0.1, nw=1, now=1, a=2, b=-1, perm_ref=100, drho=200, g=0)) assert "pc" not in wo.table