1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
import os
import unittest
from contextlib import contextmanager
import datetime as dt
from pathlib import Path
import re
from opm.simulators import BlackOilSimulator
from opm.io.parser import Parser
from opm.io.ecl_state import EclipseState
from opm.io.schedule import Schedule
from opm.io.summary import SummaryConfig
@contextmanager
def pushd(path):
cwd = os.getcwd()
if not os.path.isdir(path):
os.makedirs(path)
os.chdir(path)
yield
os.chdir(cwd)
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)
|