コード例 #1
0
    def test_parser_deckItems(self):

        parser = Parser()

        error_recovery = [("PARSE_RANDOM_SLASH", opm.io.action.ignore),
                          ("PARSE_EXTRA_RECORDS", opm.io.action.ignore)]

        context = ParseContext(error_recovery)

        self.deck_spe1case1 = parser.parse(test_path("data/SPE1CASE1.DATA"),
                                           context)

        dkw_compdate = self.deck_spe1case1["COMPDAT"]

        self.assertTrue(dkw_compdate[0][0].is_string())
        self.assertFalse(dkw_compdate[0][1].is_string())

        self.assertTrue(dkw_compdate[0][1].is_int())
        self.assertFalse(dkw_compdate[0][1].is_double())

        self.assertTrue(dkw_compdate[0][8].is_double())

        self.assertTrue(dkw_compdate[0][0].value == "PROD")

        conI = dkw_compdate[0][1].value
        conJ = dkw_compdate[0][2].value
        conK = dkw_compdate[0][3].value

        self.assertEqual(dkw_compdate[0][5].value, "OPEN")

        self.assertTrue((conI, conJ, conK) == (10, 10, 3))

        self.assertFalse(dkw_compdate[0][7].valid)
        self.assertTrue(dkw_compdate[0][7].defaulted)

        self.assertEqual(dkw_compdate[0][6].value, 0)

        self.assertEqual(dkw_compdate[0][8].value, 0.5)

        dkw_wconprod = self.deck_spe1case1["WCONPROD"]

        welln = dkw_wconprod[0][0].value
        self.assertEqual(dkw_wconprod[0][2].value, "ORAT")
        self.assertEqual(dkw_wconprod[0][3].value, "WUOPRL")
        self.assertEqual(dkw_wconprod[0][5].value, 1.5e5)

        dkw_permx = self.deck_spe1case1["PERMX"]
        permx = dkw_permx.get_raw_array()
        self.assertEqual(len(permx), 300)
        self.assertTrue(isinstance(permx, np.ndarray))
        self.assertEqual(permx.dtype, "float64")

        dkw_eqlnum = self.deck_spe1case1["EQLNUM"]
        eqlnum = dkw_eqlnum.get_int_array()

        self.assertEqual(len(eqlnum), 300)
        self.assertTrue(isinstance(eqlnum, np.ndarray))
        self.assertEqual(eqlnum.dtype, "int32")
コード例 #2
0
ファイル: test_state.py プロジェクト: berland/opm-common
    def setUpClass(cls):
        parser = Parser()
        cls.deck_cpa  = parser.parse(test_path('data/CORNERPOINT_ACTNUM.DATA'))
        cls.cp_state = EclipseState(cls.deck_cpa)

        cls.deck_spe3 = parser.parse(test_path('spe3/SPE3CASE1.DATA'))
        cls.state    = EclipseState(cls.deck_spe3)
        cls.schedule  = Schedule(cls.deck_spe3, cls.state)
        cls.summary_config = SummaryConfig(cls.deck_spe3, cls.state, cls.schedule)
コード例 #3
0
ファイル: test_parse.py プロジェクト: verveerpj/opm-common
    def test_throw_on_invalid_recovery(self):
        recoveries = [("PARSE_RANDOM_SLASH", 3.14)]

        with self.assertRaises(TypeError):
            parse_context = ParseContext(recoveries)
            deck = Parser().parse(self.spe3fn, parse_context)

        with self.assertRaises(TypeError):
            parse_context = ParseContext("PARSE_RANDOM_SLASH")
            deck = Parser().parse(self.spe3fn, parse_context)
コード例 #4
0
 def test_faults(self):
     self.assertEquals([], self.state.faultNames())
     parser = Parser()
     faultdeck = parser.parse_string(self.FAULTS_DECK)
     faultstate = EclipseState(faultdeck)
     self.assertEqual(['F1', 'F2'], faultstate.faultNames())
     # 'F2'  5  5  1  4   1  4  'X-' / \n"
     f2 = faultstate.faultFaces('F2')
     self.assertTrue((4, 0, 0, 'X-') in f2)
     self.assertFalse((3, 0, 0, 'X-') in f2)
コード例 #5
0
ファイル: test_parser.py プロジェクト: verveerpj/opm-common
    def test_dynamic_parser2(self):
        parser = Parser(add_default=False)
        builtin = Builtin()
        kw_list = [
            "START", "RUNSPEC", "FIELD", "REGIONS", "DIMENS", "GRID", "DX",
            "DY", "DZ", "TOPS", "OPERNUM", "FIPNUM"
        ]
        for kw in kw_list:
            parser.add_keyword(builtin[kw])

        deck = parser.parse_string(self.REGIONDATA)
コード例 #6
0
    def test_jfunc(self):
        # jf["FLAG"]         = WATER; # set in deck
        # jf["DIRECTION"]    = XY;    # default
        # jf["ALPHA_FACTOR"] = 0.5    # default
        # jf["BETA_FACTOR"]  = 0.5    # default
        # jf["OIL_WATER"]    = 21.0   # set in deck
        # jf["GAS_OIL"]      = -1.0   # N/A

        parser = Parser()
        deck = parser.parse(test_path('data/JFUNC.DATA'))
        js = EclipseState(deck)
        self.assertEqual('JFUNC TEST', js.title)
        jf = js.jfunc()
        print(jf)
        self.assertEqual(jf['FLAG'], 'WATER')
        self.assertEqual(jf['DIRECTION'], 'XY')
        self.assertFalse('GAS_OIL' in jf)
        self.assertTrue('OIL_WATER' in jf)
        self.assertEqual(jf['OIL_WATER'], 21.0)
        self.assertEqual(jf["ALPHA_FACTOR"], 0.5)  # default
        self.assertEqual(jf["BETA_FACTOR"], 0.5)  # default

        jfunc_gas = """
DIMENS
 10 10 10 /
ENDSCALE
/
GRID
DX
1000*0.25 /
DY
1000*0.25 /
DZ
1000*0.25 /
TOPS
100*0.25 /
PORO
  1000*0.15 /
JFUNC
  GAS * 13.0 0.6 0.7 Z /
PROPS\nREGIONS
"""
        deck2 = parser.parse_string(jfunc_gas)
        js_gas = EclipseState(deck2)
        jf = js_gas.jfunc()
        self.assertEqual(jf['FLAG'], 'GAS')
        self.assertEqual(jf['DIRECTION'], 'Z')
        self.assertTrue('GAS_OIL' in jf)
        self.assertFalse('OIL_WATER' in jf)
        self.assertEqual(jf['GAS_OIL'], 13.0)
        self.assertEqual(jf["ALPHA_FACTOR"], 0.6)  # default
        self.assertEqual(jf["BETA_FACTOR"], 0.7)  # default
コード例 #7
0
ファイル: test_parse.py プロジェクト: verveerpj/opm-common
    def test_parse_ignore_keyword(self):
        deck_string = """
FIPNUM
  100*1 100*2 /

KEYWORD
  1 2 3 /
        """

        parse_context = ParseContext()
        parser = Parser()
        parse_context.ignore_keyword("KEYWORD")
        deck = parser.parse_string(deck_string, parse_context)
        self.assertEqual(len(deck), 1)
コード例 #8
0
    def test_parser_extension(self):
        error_recovery = [("PARSE_RANDOM_SLASH", opm.io.action.ignore)]

        parse_context = ParseContext(error_recovery)
        parser = Parser()
        for kw in self.KEYWORDS:
            parser.add_keyword(json.dumps(kw))

        deck = parser.parse_string(self.DECK_ADDITIONAL_KEYWORDS,
                                   parse_context)

        self.assertIn('TESTKEY0', deck)
        self.assertIn('TESTKEY1', deck)
        self.assertIn('TESTKEY2', deck)
コード例 #9
0
ファイル: test_connection.py プロジェクト: xyuan/opm-common
 def setUpClass(cls):
     deck = Parser().parse(test_path('spe3/SPE3CASE1.DATA'))
     print("Creating state")
     cls.state = EclipseState(deck)
     print("State OK")
     cls.sch = Schedule(deck, cls.state)
     cls.timesteps = cls.sch.timesteps
コード例 #10
0
 def test_well_names(self):
     deck = Parser().parse(test_path('spe3/SPE3CASE1.DATA'))
     state = EclipseState(deck)
     sch = Schedule(deck, state)
     wnames = sch.well_names("*")
     self.assertTrue("PROD" in wnames)
     self.assertTrue("INJ" in wnames)
     self.assertEqual(len(wnames), 2)
コード例 #11
0
ファイル: test_parse.py プロジェクト: verveerpj/opm-common
    def test_parse_with_multiple_recoveries(self):
        recoveries = [("PARSE_RANDOM_SLASH", opm.io.action.ignore),
                      ("FOO", opm.io.action.warn),
                      ("PARSE_RANDOM_TEXT", opm.io.action.throw)]

        parse_context = ParseContext(recoveries)
        deck = Parser().parse(self.spe3fn, parse_context)
        state = EclipseState(deck)
コード例 #12
0
ファイル: test_parse.py プロジェクト: trinemykk/opm-common
    def test_parse_norne(self):
         parse_context = ParseContext( [('PARSE_RANDOM_SLASH', opm.io.action.ignore)] )
         deck = Parser().parse(self.norne_fname, parse_context)
         es = EclipseState( deck )

         self.assertEqual(46, es.grid().nx)
         self.assertEqual(112, es.grid().ny)
         self.assertEqual(22, es.grid().nz)
コード例 #13
0
ファイル: test_parse.py プロジェクト: trinemykk/opm-common
    def test_raw_string_output(self):
        deck_string = """
UDQ
   DEFINE WUOPR2   WOPR '*' * WOPR '*' /
   DEFINE WUGASRA  3 - WGLIR '*' /
/
        """

        parse_context = ParseContext( )
        parser = Parser()
        parse_context.ignore_keyword("KEYWORD")
        deck = parser.parse_string( deck_string )
        udq = deck[0]
        s = ""
        for rec in udq:
            for item in rec:
                s += item.get_str(0)
コード例 #14
0
    def test_deck_kw_vector(self):
        parser = Parser()
        deck = parser.parse_string(self.REGIONDATA)
        active_unit_system = deck.active_unit_system()
        default_unit_system = deck.default_unit_system()
        self.assertEqual(active_unit_system.name, "Field")

        int_array = np.array([0, 1, 2, 3])
        hbnum_kw = DeckKeyword( parser["HBNUM"], int_array)
        assert( np.array_equal(hbnum_kw.get_int_array(), int_array) )

        raw_array = np.array([1.1, 2.2, 3.3])
        zcorn_kw = DeckKeyword( parser["ZCORN"], raw_array, active_unit_system, default_unit_system)
        assert( np.array_equal(zcorn_kw.get_raw_array(), raw_array) )
        si_array = zcorn_kw.get_SI_array()
        self.assertAlmostEqual( si_array[0], 1.1 * unit_foot )
        self.assertAlmostEqual( si_array[2], 3.3 * unit_foot )
コード例 #15
0
def parse(fname):
    s = dt.now()
    ps = ParseContext([('PARSE_RANDOM_SLASH', opm.io.action.ignore)])
    deck = Parser().parse(fname, ps)
    es = EclipseState(deck)
    e = dt.now()
    print('Parsing took %s sec' % (e - s).seconds)
    return es
コード例 #16
0
ファイル: test_parser.py プロジェクト: verveerpj/opm-common
    def test_deck_kw_records_uda(self):
        parser = Parser()
        deck = parser.parse_string(self.REGIONDATA)
        active_unit_system = deck.active_unit_system()
        default_unit_system = deck.default_unit_system()
        oil_target = 30000  # stb/day
        well_name = "PROD"
        well_status = "OPEN"
        control_mode = "ORAT"
        bhp_limit = 1000  # psia

        wconprod = DeckKeyword(parser["WCONPROD"], [[
            well_name, well_status, control_mode, oil_target, "4*", bhp_limit
        ]], active_unit_system, default_unit_system)

        self.assertEqual(len(wconprod), 1)
        record = wconprod[0]
        self.assertEqual(record[0].name(), "WELL")
        self.assertTrue(record[0].is_string())
        self.assertEqual(record[0].get_str(0), "PROD")
        self.assertEqual(record[1].name(), "STATUS")
        self.assertTrue(record[1].is_string())
        self.assertEqual(record[1].get_str(0), "OPEN")
        self.assertEqual(record[2].name(), "CMODE")
        self.assertTrue(record[2].is_string())
        self.assertEqual(record[2].get_str(0), "ORAT")
        self.assertEqual(record[3].name(), "ORAT")
        self.assertTrue(record[3].is_uda())
        self.assertEqual(record[3].value, 30000)
        self.assertEqual(record[4].name(), "WRAT")
        self.assertTrue(record[4].is_uda())
        self.assertEqual(record[4].value, 0)
        self.assertEqual(record[5].name(), "GRAT")
        self.assertTrue(record[5].is_uda())
        self.assertEqual(record[5].value, 0)
        self.assertEqual(record[6].name(), "LRAT")
        self.assertTrue(record[6].is_uda())
        self.assertEqual(record[6].value, 0)
        self.assertEqual(record[7].name(), "RESV")
        self.assertTrue(record[7].is_uda())
        self.assertEqual(record[7].value, 0)
        self.assertEqual(record[8].name(), "BHP")
        self.assertTrue(record[8].is_uda())
        self.assertEqual(record[8].value, 1000)
コード例 #17
0
    def test_no_leading_DATES(self):
        tv = TimeVector(datetime.date(1997, 11, 6),
                        base_file=test_path("data/schedule/part1.sch"))
        s = str(tv)
        d = Parser().parse_string(s)
        kw0 = d[0]
        self.assertEqual(kw0.name, "WELSPECS")

        tv2 = TimeVector(datetime.date(2000, 1, 1))
        self.assertEqual("", str(tv2))
コード例 #18
0
    def test_getitem(self):
        deck = Parser().parse(test_path('spe3/SPE3CASE1.DATA'))
        state = EclipseState(deck)
        sch = Schedule(deck, state)
        self.assertEqual(len(sch), 176)
        with self.assertRaises(IndexError):
            a = sch[200]

        st100 = sch[100]
        nupcol = st100.nupcol
コード例 #19
0
    def test_open_shut(self):
        deck = Parser().parse(test_path('spe3/SPE3CASE1.DATA'))
        state = EclipseState(deck)
        sch = Schedule(deck, state)
        prod = sch.get_well("PROD", 1)
        self.assertEqual(prod.status(), "OPEN")

        sch.shut_well("PROD", 10)
        prod = sch.get_well("PROD", 10)
        self.assertEqual(prod.status(), "SHUT")
コード例 #20
0
    def test_parser_section_deckItems(self):

        all_spe1case1 = [
            "RUNSPEC", "TITLE", "DIMENS", "EQLDIMS", "TABDIMS", "REGDIMS",
            "OIL", "GAS", "WATER", "DISGAS", "FIELD", "START", "WELLDIMS",
            "UNIFOUT", "UDQDIMS", "UDADIMS", "GRID", "INIT", "NOECHO", "DX",
            "DY", "DZ", "TOPS", "PORO", "PERMX", "PERMY", "PERMZ", "ECHO",
            "PROPS", "PVTW", "ROCK", "SWOF", "SGOF", "DENSITY", "PVDG", "PVTO",
            "REGIONS", "EQLNUM", "FIPNUM", "SOLUTION", "EQUIL", "RSVD",
            "SUMMARY", "FOPR", "WGOR", "FGOR", "BPR", "BGSAT", "WBHP", "WGIR",
            "WGIT", "WGPR", "WGPT", "WOIR", "WOIT", "WOPR", "WOPT", "WWIR",
            "WWIT", "WWPR", "WWPT", "WUOPRL", "SCHEDULE", "UDQ", "RPTSCHED",
            "RPTRST", "DRSDT", "WELSPECS", "COMPDAT", "WCONPROD", "WCONINJE",
            "TSTEP"
        ]

        # notice that RUNSPEC keywords will always be parsed since these properties from these keyword
        # are needed to parse following sections.

        props_spe1case1 = [
            "RUNSPEC", "TITLE", "DIMENS", "EQLDIMS", "TABDIMS", "REGDIMS",
            "OIL", "GAS", "WATER", "DISGAS", "FIELD", "START", "WELLDIMS",
            "UNIFOUT", "UDQDIMS", "UDADIMS", "GRID", "PVTW", "ROCK", "SWOF",
            "SGOF", "DENSITY", "PVDG", "PVTO"
        ]

        parser = Parser()

        error_recovery = [("PARSE_RANDOM_SLASH", opm.io.action.ignore),
                          ("PARSE_EXTRA_RECORDS", opm.io.action.ignore)]

        context = ParseContext(error_recovery)

        deck1 = parser.parse(test_path("data/SPE1CASE1.DATA"), context)

        self.assertEqual(len(deck1), len(all_spe1case1))

        test_1 = [dkw.name for dkw in deck1]

        for test, ref in zip(test_1, all_spe1case1):
            self.assertEqual(test, ref)

        section_list = [eclSectionType.PROPS]

        deck2 = parser.parse(test_path("data/SPE1CASE1.DATA"), context,
                             section_list)

        self.assertEqual(len(deck2), len(props_spe1case1))

        test_2 = [dkw.name for dkw in deck2]

        for test, ref in zip(test_2, props_spe1case1):
            self.assertEqual(test, ref)

        # props section keyword located in include file for this deck (SPE1CASE1B.DATA)
        # not possible to parse individual sections

        with self.assertRaises(RuntimeError):
            parser.parse(test_path("data/SPE1CASE1B.DATA"), context,
                         section_list)
コード例 #21
0
ファイル: test_schedule.py プロジェクト: trinemykk/opm-common
 def test_injection_properties(self):
     deck = Parser().parse(test_path('spe3/SPE3CASE1.DATA'))
     state = EclipseState(deck)
     sch = Schedule(deck, state)
     report_step = 4
     well_name = 'INJ'
     prop = sch.get_injection_properties(well_name, report_step)
     self.assertEqual(prop['surf_inj_rate'], 4700.0)  # Mscf/day
     self.assertEqual(prop['resv_inj_rate'], 0.0)  # rb/day
     self.assertEqual(prop['bhp_target'], 4000.0)  # psi
     self.assertEqual(prop['thp_target'], 0.0)
     with self.assertRaises(IndexError):
         prop = sch.get_injection_properties("UNDEF", report_step)
     with self.assertRaises(KeyError):
         prop = sch.get_injection_properties("PROD", report_step)
コード例 #22
0
def main():
    deck = Parser().parse('../tests/spe3/SPE3CASE1.DATA')
    es = EclipseState(deck)
    sc = Schedule(deck, es)
    wp = sc.get_wells(0)[0] # producer
    wi = sc.get_wells(0)[1] # injector
    print('state:     %s' % es)
    print('schedule:  %s' % sc)
    print('prod well: %s' % wp)
    print('inj  well: %s' % wi)
    for i in range(len(sc.timesteps)):
        if not sc.get_wells(i)[0].isproducer() or sc.get_wells(i)[0].isinjector():
            print('wp is not producer in step %s' % sc.timesteps[i])
        if not sc.get_wells(i)[1].isinjector() or sc.get_wells(i)[1].isproducer():
            print('wi is not injector in step %s' % sc.timesteps[i])
コード例 #23
0
ファイル: test_schedule.py プロジェクト: OPMUSER/opm-common
 def test_production_properties(self):
     deck = Parser().parse(test_path('spe3/SPE3CASE1.DATA'))
     state = EclipseState(deck)
     sch = Schedule(deck, state)
     report_step = 4
     well_name = 'PROD'
     prop = sch.get_production_properties(well_name, report_step)
     self.assertEqual(prop['alq_value'], 0.0)
     self.assertEqual(prop['bhp_target'], 500.0)
     self.assertEqual(prop['gas_rate'], 6200.0)
     self.assertEqual(prop['liquid_rate'], 0.0)
     self.assertEqual(prop['oil_rate'], 0.0)
     self.assertEqual(prop['resv_rate'], 0.0)
     self.assertEqual(prop['thp_target'], 0.0)
     self.assertEqual(prop['water_rate'], 0.0)
コード例 #24
0
    def test_create(self):
        parser = Parser()
        deck = parser.parse(self.spe3fn)

        context = ParseContext()
        deck = parser.parse(self.spe3fn, context)

        with open(self.spe3fn) as f:
            string = f.read()
        deck = parser.parse_string(string)
        deck = parser.parse_string(string, context)
コード例 #25
0
ファイル: test_parser.py プロジェクト: verveerpj/opm-common
    def test_create(self):
        parser = Parser()
        deck = parser.parse(self.spe3fn)
        active_unit_system = deck.active_unit_system()
        default_unit_system = deck.default_unit_system()
        self.assertEqual(active_unit_system.name, "Field")

        context = ParseContext()
        deck = parser.parse(self.spe3fn, context)

        with open(self.spe3fn) as f:
            string = f.read()
        deck = parser.parse_string(string)
        deck = parser.parse_string(string, context)
コード例 #26
0
    def load(self, filename, date=None):
        """Will parse a Schedule file and add the keywords to the current TimeVector.

        You can call the load() method repeatedly, the different timesteps will
        be ordered chronologically. If a timestep is already present the
        keywords will be appended.

        The optional date argument can be used to insert schedule file
        fragments which do not have any DATES / TSTEP keywords. Assuming you
        have a base file 'base.sch' and a small fragment 'well.sch' with the
        WELSPECS and COMPDAT keywords to create one well, then the new well can
        be added 1.st of April 2017 as this:

            tv = TimeVector( start )
            tv.load("base.sch")
            tv.load("well.sch", date = datetime.datetime(2017, 4, 1))

        """
        deck = Parser().parse(filename)
        self._add_deck(deck, date)
コード例 #27
0
 def test_all(self):
     with pushd(self.data_dir):
         deck = Parser().parse('SPE1CASE1.DATA')
         state = EclipseState(deck)
         schedule = Schedule(deck, state)
         summary_config = SummaryConfig(deck, state, schedule)
         self.assertTrue('PROD' in schedule)
         self.assertTrue('INJ' in schedule)
         self.assertEqual(dt.datetime(2015, 1, 1), schedule.start)
         self.assertEqual(dt.datetime(2016, 1, 1), schedule.end)
         sim = BlackOilSimulator(deck, state, schedule, summary_config)
         sim.step_init()
         sim.step()
         prod = schedule.get_well("PROD", 2)
         self.assertEqual(prod.status(), "OPEN")
         #schedule.shut_well("PROD", 3)
         #prod = schedule.get_well("PROD", 3)
         #self.assertEqual(prod.status(), "SHUT")
         sim.step()
         sim.step()
コード例 #28
0
 def load_string(self, deck_string, date=None):
     """
     Like load() - but load from a string literal instead of file.
     """
     deck = Parser().parse_string(deck_string)
     self._add_deck(deck, date)
コード例 #29
0
    def __init__(self, start_date, base_string=None, base_file=None):
        """The TimeVector class is a simple vector class with DATES/TSTEP blocks.

         The TimeVector class is a basic building block for tools designed to
         update schedule files. A schedule file consists of a list of keywords
         related to the dynamic properties of the field, like opening and
         closing wells, specifiying rates and so on. The temporal advancement of
         the simulator is controlled by DATES and TSTEP keywords. A typical
         schedule section can look like this:

         --- Step 1 -----------------------

         WELSPECS
            'C1'   'G1'   10 10 10 'OIL' /
         /

         COMPDAT
            'C1' 15 20 10 16 'OPEN' /
            'C1' 15 21 16 16 'OPEN' /
         /

         WCONHIST
            'C1' 'OPEN'  'ORAT' 1000 /
         /

         --- Step 2 ----------------------

         DATES
            10  'MAY' 2016 /
         /

         WCONHIST
            'C1'  'OPEN'  'ORAT' 2000 /
         /

        --- Step 3 ----------------------

         TSTEP
             10 /

         WELSPECS
            'W2'  'G1'  5 5 5 'OIL' /
         /

         COMPDAT
            'W2' 10 10 7 10 'OPEN' /
         /

         WCONHIST
            'C1' 'OPEN' 'ORAT' 3000 /
            'W2' 'OPEN' 'ORAT' 1500 /
         /

         --- Step 4 ----------------------

         DATES
            30 'MAY' 2016 /
         /

         As indicated above the DATES and TSTEP keywords act as delimiters in
         the schedule file. In the TimeVector class the fundamental unit is
         TimeStep instance which consists of a list of keywords, and a
         terminating DATES or TSTEP keyword, the example above would correspond
         to a TimeVector with three TimeStep instances.

         Basic usage example:

            #!/usr/bin/env python
            from opm.tools import TimeVector

            # Create vector and load history.
            tv = TimeVector( start )
            tv.load("history.sch")


            # Load predictions from another file
            tv.load("prediction.sch")


            # Insert the definition of one particular well at
            # a specifed date.
            tv.load("extra_wll.sch", date = datetime.datetime(2018,10,1))


            # Check if we have a certain timestep:
            if datetime.datetime(2017,1,1) in tv:
                print("We have it!")
            else:
                print("No such date")


            # Dump the updated schedule content to a file:
            with open("schedule","w") as f:
                 f.write(str(tv))


        """
        if base_string and base_file:
            raise ValueError(
                "Can only supply one of base_string and base_file arguments")

        self.start_date = datetime.datetime(start_date.year, start_date.month,
                                            start_date.day)
        self.time_steps_dict = {}
        self.time_steps_list = []

        ts = TimeStep.create_first(self.start_date)

        self._add_dates_block(ts)
        start_dt = datetime.datetime(start_date.year, start_date.month,
                                     start_date.day)
        if base_file:
            deck = Parser().parse(base_file)
            self._add_deck(deck, start_dt)

        if base_string:
            deck = Parser().parse_string(base_string)
            self._add_deck(deck, start_dt)
コード例 #30
0
class TestBasic(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        # NOTE: See comment in test_basic.py for the reason why we are
        #   only using a single test_all() function instead of splitting
        #   it up in multiple test functions
        test_dir = Path(os.path.dirname(__file__))
        cls.data_dir = test_dir.parent.joinpath("test_data/SPE1CASE1b")

    def test_all(self):
        with pushd(self.data_dir):
            self.deck = Parser().parse('SPE1CASE1.DATA')
            state = EclipseState(self.deck)
            self.schedule = Schedule(self.deck, state)
            summary_config = SummaryConfig(self.deck, state, self.schedule)
            self.unit_system = self.deck.active_unit_system()

            self.assertTrue('PROD' in self.schedule)
            self.assertTrue('INJ' in self.schedule)
            self.assertEqual(dt.datetime(2015, 1, 1), self.schedule.start)
            self.assertEqual(dt.datetime(2016, 1, 1), self.schedule.end)
            self.sim = BlackOilSimulator(self.deck, state, self.schedule,
                                         summary_config)
            tsteps = self.schedule.timesteps
            self.assertEqual(dt.datetime(2015, 1, 1), tsteps[0])
            last_step = len(tsteps) - 1
            self.assertEqual(dt.datetime(2016, 1, 1), tsteps[last_step])
            self.sim.step_init()
            report_step = 4
            self.sim.advance(report_step=report_step)
            well_name = "PROD"
            prod = self.schedule.get_well(well_name, 2)
            self.assertEqual(prod.status(), "OPEN")
            #schedule.shut_well("PROD", 3)
            #prod = schedule.get_well("PROD", 3)
            #self.assertEqual(prod.status(), "SHUT")
            self.subtest_modify_prod_weltarg_dynamically(
                well_name, report_step)
            self.sim.step()
            report_step = self.sim.current_step()
            well_name = "INJ"
            self.subtest_modify_inj_weltarg_dynamically(well_name, report_step)
            self.sim.advance(report_step=last_step)
            self.sim.step_cleanup()

    def subtest_modify_inj_weltarg_dynamically(self, well_name, report_step):
        prop = self.schedule.get_injection_properties(well_name, report_step)
        self.assertEqual(prop['surf_inj_rate'], 100000.0)  # Mscf/day
        self.assertEqual(prop['resv_inj_rate'], 0.0)  # rb/day
        self.assertEqual(prop['bhp_target'], 9014.0)  # psi
        self.assertEqual(prop['thp_target'], 0.0)
        new_grat_target = prop['surf_inj_rate'] - 100  # stb/day
        self.update_inj_grat_target_wconinje(well_name, new_grat_target)
        self.sim.step()
        prop2 = self.schedule.get_injection_properties(well_name,
                                                       report_step + 1)
        self.assertEqual(prop2['surf_inj_rate'], new_grat_target)
        new_grat_target += 200
        self.update_inj_grat_target_weltarg(well_name, new_grat_target)
        self.sim.step()
        prop3 = self.schedule.get_injection_properties(well_name,
                                                       report_step + 2)
        self.assertEqual(prop3['surf_inj_rate'], new_grat_target)

    def subtest_modify_prod_weltarg_dynamically(self, well_name, report_step):
        prop = self.schedule.get_production_properties(well_name, report_step)
        self.assertEqual(prop['alq_value'], 0.0)
        self.assertEqual(prop['bhp_target'], 1000.0)
        self.assertEqual(prop['gas_rate'], 0.0)
        self.assertEqual(prop['liquid_rate'], 0.0)
        self.assertEqual(prop['oil_rate'], 20000.0)
        self.assertEqual(prop['resv_rate'], 0.0)
        self.assertEqual(prop['thp_target'], 0.0)
        self.assertEqual(prop['water_rate'], 0.0)
        new_oil_target = prop['oil_rate'] + 10000  # stb/day
        self.update_prod_orat_target_wconprod(well_name, new_oil_target)
        self.sim.step()
        prop2 = self.schedule.get_production_properties(
            well_name, report_step + 1)
        self.assertEqual(prop2['oil_rate'], new_oil_target)
        new_oil_target += 1000
        self.update_prod_orat_target_weltarg(well_name, new_oil_target)
        self.sim.step()
        prop3 = self.schedule.get_production_properties(
            well_name, report_step + 2)
        self.assertEqual(prop3['oil_rate'], new_oil_target)

    # This is an alternative to using WELTARG
    def update_inj_grat_target_wconinje(self, well_name, new_surf_flow_rate):
        data = self.deck["WCONINJE"]
        # assumes data looks like this:
        #  WCONINJE
        #  	'INJ'	'GAS'	'OPEN'	'RATE'	100000 1* 9014 /
        #  /
        # The initial rate can also be obtained from data[0][4].get_uda(0).get_double()
        data = re.sub(pattern='100000',
                      repl=str(new_surf_flow_rate),
                      string=str(data),
                      count=1)
        report_step = self.sim.current_step()
        self.schedule.insert_keywords(data,
                                      step=report_step,
                                      unit_system=self.unit_system)

    # This is an alternative to using WCONINJE to modify injection properties
    def update_inj_grat_target_weltarg(self, well_name, net_surf_flow_rate):
        data = """
WELTARG
    '{}'  GRAT {} /
/
        """.format(well_name, net_surf_flow_rate)
        report_step = self.sim.current_step()
        self.schedule.insert_keywords(data,
                                      step=report_step,
                                      unit_system=self.unit_system)

    # This is an alternative to using WCONPROD to modify production properties
    def update_prod_orat_target_weltarg(self, well_name, oil_target):
        data = """
WELTARG
    '{}'  ORAT {} /
/
        """.format(well_name, oil_target)
        report_step = self.sim.current_step()
        self.schedule.insert_keywords(data,
                                      step=report_step,
                                      unit_system=self.unit_system)

    # This is an alternative to using WELTARG to modify production properties
    def update_prod_orat_target_wconprod(self, well_name, oil_target):
        well_status = "OPEN"
        control_mode = "ORAT"
        bhp_limit = 1000  # psia
        data = """
WCONPROD
	'{}' '{}' '{}' {} 4* {} /
/
        """.format(well_name, well_status, control_mode, oil_target, bhp_limit)
        report_step = self.sim.current_step()
        self.schedule.insert_keywords(data,
                                      step=report_step,
                                      unit_system=self.unit_system)