From 2252a7bd3304e02a9db3efcb6bf3c228ab25a508 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 22 Mar 2018 10:06:53 +0100 Subject: [PATCH] Changed time_vector to start with DATES. Ignore TSTEP --- python/sunbeam/tools/time_vector.py | 93 +++++++++++++------------- tests/CMakeLists.txt | 1 + tests/data/schedule/fragment_date.sch | 8 +++ tests/data/schedule/fragment_dates.sch | 8 +++ tests/data/schedule/part1.sch | 5 +- tests/data/schedule/part2.sch | 9 ++- tests/data/schedule/part3.sch | 7 +- tests/time_vector.py | 47 +++++++------ 8 files changed, 102 insertions(+), 76 deletions(-) create mode 100644 tests/data/schedule/fragment_date.sch create mode 100644 tests/data/schedule/fragment_dates.sch diff --git a/python/sunbeam/tools/time_vector.py b/python/sunbeam/tools/time_vector.py index 554ca1f33..0d770403a 100644 --- a/python/sunbeam/tools/time_vector.py +++ b/python/sunbeam/tools/time_vector.py @@ -61,7 +61,6 @@ class TimeStep(object): """ self.dt = dt self.keywords = keywords - self.is_tstep = False self.tstep = None @@ -69,34 +68,25 @@ class TimeStep(object): self.keywords.append(kw) - @classmethod - def create_tstep(cls, tstep, dt, keywords): - ts = cls(dt, keywords) - ts.is_tstep = True - ts.tstep = tstep - return ts - def __str__(self): string = StringIO() + + day = self.dt.day + month = self.dt.month + year = self.dt.year + string.write("DATES\n {day} '{month}' {year}/\n/\n\n".format( day=day, month = inv_ecl_month[month], year=year)) + for kw in self.keywords: string.write(str(kw)) string.write("\n") - if self.is_tstep: - string.write("TSTEP\n {}/\n\n".format( self.tstep )) - else: - day = self.dt.day - month = self.dt.month - year = self.dt.year - string.write("DATES\n {day} '{month}' {year}/\n/\n\n".format( day=day, month = inv_ecl_month[month], year=year)) - return string.getvalue() class TimeVector(object): - def __init__(self, start_date): + 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 @@ -121,21 +111,21 @@ class TimeVector(object): 'C1' 'OPEN' 'ORAT' 1000 / / + --- Step 2 ---------------------- + DATES 10 'MAY' 2016 / / - --- Step 2 ---------------------- - WCONHIST 'C1' 'OPEN' 'ORAT' 2000 / / + --- Step 3 ---------------------- + TSTEP 10 / - --- Step 3 ---------------------- - WELSPECS 'W2' 'G1' 5 5 5 'OIL' / / @@ -149,6 +139,8 @@ class TimeVector(object): 'W2' 'OPEN' 'ORAT' 1500 / / + --- Step 4 ---------------------- + DATES 30 'MAY' 2016 / / @@ -191,10 +183,23 @@ class TimeVector(object): """ + 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_list = [] self.time_steps_dict = {} + ts = TimeStep(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 = sunbeam.deck.parse(base_file) + self._add_deck(deck, start_dt) + + if base_string: + deck = sunbeam.deck.parse_string(base_string) + self._add_deck(deck, start_dt) def __len__(self): @@ -233,8 +238,8 @@ class TimeVector(object): def add_keywords(self, dt, keywords): - if dt <= self.start_date: - raise ValueError("Invalid datetime argument") + if dt < self.start_date: + raise ValueError("Invalid datetime argument: {}".format(dt)) if dt in self.time_steps_dict: ts = self[dt] @@ -246,40 +251,38 @@ class TimeVector(object): self.time_steps_list.sort( key = attrgetter("dt")) - def append_tstep(self, tstep, keywords): - if len(self) == 0: - last_dt = self.start_data + def _add_deck(self, deck, start_date): + first_kw = deck[0] + if start_date is None: + if first_kw.name != "DATES": + raise ValueError("When loading you must *either* specify date - or file must start with DATES keyword") else: - last_dt = self[-1].dt + if first_kw.name == "DATES": + raise ValueError("When loading you must *either* specify date - or file must start with DATES keyword") - new_dt = last_dt + datetime.timedelta(days = tstep) - ts = TimeStep.create_tstep(tstep, new_dt, keywords) - self._add_dates_block(ts) - - - def _add_deck(self, deck, last_date): keywords = [] + dt = start_date for kw in deck: if kw.name == "DATES": - for record in kw: - dt = _make_datetime(record) + if keywords: self.add_keywords(dt, keywords) - keywords = [] + + for index in range(len(kw)-1): + dt = _make_datetime(kw[index]) + self.add_keywords(dt, []) + + dt = _make_datetime(kw[len(kw)-1]) + + keywords = [] continue - if kw.name == "TSTEP": - record = kw[0] - for tstep in record[0]: - self.append_tstep(tstep, keywords) - keywords = [] - continue + #if kw.name == "TSTEP": + #raise ValueError("Must block the ranges with active TSTEP - getting a DATES in there is ERROR") keywords.append(kw) - if last_date: - if keywords: - self.add_keywords(last_date, keywords) + self.add_keywords(dt, keywords) def load(self, filename, date = None): diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2f37e8d8c..2ed803058 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,6 +5,7 @@ configure_file(data/schedule/part1.sch data/schedule/part1.sch COPYONLY) configure_file(data/schedule/part2.sch data/schedule/part2.sch COPYONLY) configure_file(data/schedule/part3.sch data/schedule/part3.sch COPYONLY) configure_file(data/schedule/fragment.sch data/schedule/fragment.sch COPYONLY) +configure_file(data/schedule/fragment_dates.sch data/schedule/fragment_dates.sch COPYONLY) foreach(prog time_vector completions deck group_tree grupnet parse_deck parse state props schedule wells) diff --git a/tests/data/schedule/fragment_date.sch b/tests/data/schedule/fragment_date.sch new file mode 100644 index 000000000..e96653270 --- /dev/null +++ b/tests/data/schedule/fragment_date.sch @@ -0,0 +1,8 @@ +DATES + 1 'AUG' 1998 / +/ + +WCONINJE +'C-4H' 'GAS' 1* 'RATE' 2503454.000 1* 600 / +/ + diff --git a/tests/data/schedule/fragment_dates.sch b/tests/data/schedule/fragment_dates.sch new file mode 100644 index 000000000..e96653270 --- /dev/null +++ b/tests/data/schedule/fragment_dates.sch @@ -0,0 +1,8 @@ +DATES + 1 'AUG' 1998 / +/ + +WCONINJE +'C-4H' 'GAS' 1* 'RATE' 2503454.000 1* 600 / +/ + diff --git a/tests/data/schedule/part1.sch b/tests/data/schedule/part1.sch index 315b24772..dc422a9ff 100644 --- a/tests/data/schedule/part1.sch +++ b/tests/data/schedule/part1.sch @@ -171,7 +171,4 @@ WCONINJE / -- 56.000000 days from start of simulation ( 6 'NOV' 1997 ) -DATES - 1 'JAN' 1998 / -/ - + diff --git a/tests/data/schedule/part2.sch b/tests/data/schedule/part2.sch index 81d7db386..e0e143d90 100644 --- a/tests/data/schedule/part2.sch +++ b/tests/data/schedule/part2.sch @@ -1,3 +1,7 @@ +DATES +1 'JAN' 1998 / +/ + WCONHIST 'B-2H' 'OPEN' 'RESV' 5194.690 0.000 576611.282 5* / 'D-1H' 'OPEN' 'RESV' 5169.755 0.000 703808.288 5* / @@ -128,8 +132,3 @@ WRFTPLT 'B-4H' 'YES' 'YES' 1* / / --- 144.000000 days from start of simulation ( 6 'NOV' 1997 ) -DATES - 30 'MAR' 1998 / -/ - diff --git a/tests/data/schedule/part3.sch b/tests/data/schedule/part3.sch index bd6c68364..45cc15cad 100644 --- a/tests/data/schedule/part3.sch +++ b/tests/data/schedule/part3.sch @@ -1,3 +1,8 @@ +-- 144.000000 days from start of simulation ( 6 'NOV' 1997 ) +DATES +30 'MAR' 1998 / +/ + WCONHIST 'B-2H' 'OPEN' 'RESV' 6174.300 0.000 685348.969 5* / 'D-1H' 'OPEN' 'RESV' 5427.250 0.000 906735.000 5* / @@ -178,8 +183,6 @@ DATES 27 'MAY' 1998 / / -TSTEP -1 1 / -- : D-4H Squeeze Top: 2715.00 Bot: 3038.00 -- : >> --for RFT pressure points diff --git a/tests/time_vector.py b/tests/time_vector.py index d37651b63..b1eeb0b18 100644 --- a/tests/time_vector.py +++ b/tests/time_vector.py @@ -10,8 +10,12 @@ class TestTimeVector(unittest.TestCase): def test_create(self): start_date = datetime.date(2018,1,1) + start_datetime = datetime.datetime(2018,1,1) + with self.assertRaises(ValueError): + tv = TimeVector(start_date, base_string = "string", base_file="XYZ") + tv = TimeVector( start_date ) - self.assertEqual(len(tv), 0) + self.assertEqual(len(tv), 1) with self.assertRaises(IndexError): tv[1] @@ -21,27 +25,23 @@ class TestTimeVector(unittest.TestCase): next_date = datetime.datetime(2018,2,1) tv.add_keywords(next_date, ["KEY1"]) - self.assertEqual(len(tv), 1) + self.assertEqual(len(tv), 2) middle_date = datetime.datetime(2018,1,15) tv.add_keywords(middle_date,[]) - self.assertEqual(len(tv) ,2) + self.assertEqual(len(tv) ,3) ts1 = tv[0] - self.assertEqual(ts1.dt, middle_date) + self.assertEqual(ts1.dt, start_datetime) tv.add_keywords(next_date, ["KEY2"]) - self.assertEqual(len(tv),2) + self.assertEqual(len(tv),3) ts = tv[-1] self.assertEqual(ts.keywords, ["KEY1", "KEY2"]) self.assertIn(middle_date, tv) - self.assertEqual(tv.dates, [middle_date, next_date]) - - tv.append_tstep(10, []) - ts = tv[-1] - self.assertTrue(ts.is_tstep) + self.assertEqual(tv.dates, [start_datetime, middle_date, next_date]) with self.assertRaises(KeyError): @@ -54,12 +54,13 @@ class TestTimeVector(unittest.TestCase): def test_load(self): - tv = TimeVector(datetime.date(1997, 11, 6)) - tv.load("data/schedule/part1.sch") + tv = TimeVector(datetime.date(1997, 11, 6), base_file = "data/schedule/part1.sch") tv.load("data/schedule/part3.sch") + tv.load("data/schedule/fragment_dates.sch") tv.load("data/schedule/part2.sch") - self.assertEqual(tv.dates, [datetime.datetime(1997, 11, 14), + self.assertEqual(tv.dates, [datetime.datetime(1997, 11, 6), + datetime.datetime(1997, 11, 14), datetime.datetime(1997, 12, 1), datetime.datetime(1997, 12, 17), datetime.datetime(1998, 1, 1), @@ -72,13 +73,11 @@ class TestTimeVector(unittest.TestCase): datetime.datetime(1998, 5, 1), datetime.datetime(1998, 5, 26), datetime.datetime(1998, 5, 27), - datetime.datetime(1998, 5, 28), - datetime.datetime(1998, 5, 29), - datetime.datetime(1998, 6, 1)]) + datetime.datetime(1998, 6, 1), + datetime.datetime(1998, 8, 1)]) def test_str(self): - tv = TimeVector(datetime.date(1997, 11, 6)) - tv.load("data/schedule/part1.sch") + tv = TimeVector(datetime.date(1997, 11, 6), base_string = open("data/schedule/part1.sch").read()) tv.load("data/schedule/part3.sch") tv.load("data/schedule/part2.sch") @@ -91,8 +90,16 @@ class TestTimeVector(unittest.TestCase): def test_optional(self): - tv = TimeVector(datetime.date(1997, 11, 6)) - tv.load("data/schedule/part1.sch") + tv = TimeVector(datetime.date(1997, 11, 6), base_file = "data/schedule/part1.sch") + + # Must have a starting date, either as first keyword in loaded file, + # or alternatively as the optional date argument. + with self.assertRaises(ValueError): + tv.load("data/schedule/fragment.sch") + + with self.assertRaises(ValueError): + tv.load("data/schedule/fragment_dates.sch", date = datetime.datetime(1998, 1,1)) + tv.load("data/schedule/fragment.sch", date = datetime.datetime(1998, 1, 10)) ts = tv[-1] self.assertEqual(ts.dt, datetime.datetime(1998, 1 , 10))