Merge pull request #72 from joakim-hove/time-vector-reorg
Changed time_vector to start with DATES. Ignore TSTEP
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
8
tests/data/schedule/fragment_date.sch
Normal file
8
tests/data/schedule/fragment_date.sch
Normal file
@@ -0,0 +1,8 @@
|
||||
DATES
|
||||
1 'AUG' 1998 /
|
||||
/
|
||||
|
||||
WCONINJE
|
||||
'C-4H' 'GAS' 1* 'RATE' 2503454.000 1* 600 /
|
||||
/
|
||||
|
||||
8
tests/data/schedule/fragment_dates.sch
Normal file
8
tests/data/schedule/fragment_dates.sch
Normal file
@@ -0,0 +1,8 @@
|
||||
DATES
|
||||
1 'AUG' 1998 /
|
||||
/
|
||||
|
||||
WCONINJE
|
||||
'C-4H' 'GAS' 1* 'RATE' 2503454.000 1* 600 /
|
||||
/
|
||||
|
||||
@@ -171,7 +171,4 @@ WCONINJE
|
||||
/
|
||||
|
||||
-- 56.000000 days from start of simulation ( 6 'NOV' 1997 )
|
||||
DATES
|
||||
1 'JAN' 1998 /
|
||||
/
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
DATES
|
||||
|
||||
1 'JAN' 1998 /
|
||||
|
||||
/
|
||||
|
||||
|
||||
@@ -128,8 +132,3 @@ WRFTPLT
|
||||
/
|
||||
|
||||
WRFTPLT
|
||||
-- 144.000000 days from start of simulation ( 6 'NOV' 1997 )
|
||||
DATES
|
||||
30 'MAR' 1998 /
|
||||
/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user