From 0db0637ef77e556e406104740b2dc75ee3d406ec Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Tue, 28 Jun 2016 22:20:49 +0200 Subject: [PATCH] RPTRST / TimeMap updates - Fixed bug with RPTRST BASIC=4 terminated before a year. - Refactored machinery to keep track of first report step in every month/year. --- .../eclipse/EclipseState/Schedule/TimeMap.cpp | 69 ++----- .../eclipse/EclipseState/Schedule/TimeMap.hpp | 2 - .../Schedule/tests/TimeMapTest.cpp | 4 - .../IOConfigIntegrationTest.cpp | 9 + .../integration_tests/IOConfig/SPE9_END.DATA | 174 ++++++++++++++++++ 5 files changed, 198 insertions(+), 60 deletions(-) create mode 100644 testdata/integration_tests/IOConfig/SPE9_END.DATA diff --git a/opm/parser/eclipse/EclipseState/Schedule/TimeMap.cpp b/opm/parser/eclipse/EclipseState/Schedule/TimeMap.cpp index bc852d8a2..349b6da90 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/TimeMap.cpp +++ b/opm/parser/eclipse/EclipseState/Schedule/TimeMap.cpp @@ -68,9 +68,6 @@ namespace Opm { else if (keyword.name() == "DATES") addFromDATESKeyword(keyword); } - - this->initFirstTimestepsYears(); - this->initFirstTimestepsMonths(); } size_t TimeMap::numTimesteps() const { @@ -91,21 +88,29 @@ namespace Opm { return static_cast(deltaT.total_milliseconds())/1000.0; } + void TimeMap::addTime(boost::posix_time::ptime newTime) { boost::posix_time::ptime lastTime = m_timeList.back(); - if (newTime > lastTime) + size_t step = m_timeList.size(); + if (newTime > lastTime) { + boost::gregorian::date new_date = newTime.date(); + boost::gregorian::date prev_date = lastTime.date(); + + if (new_date.month() != prev_date.month()) + m_first_timestep_months.push_back(step); + + if (new_date.year() != prev_date.year()) + m_first_timestep_years.push_back( step ); + m_timeList.push_back( newTime ); - else + } else throw std::invalid_argument("Times added must be in strictly increasing order."); } void TimeMap::addTStep(boost::posix_time::time_duration step) { - if (step.total_seconds() > 0) { - boost::posix_time::ptime newTime = m_timeList.back() + step; - m_timeList.push_back( newTime ); - } else - throw std::invalid_argument("Can only add positive steps"); + boost::posix_time::ptime newTime = m_timeList.back() + step; + addTime(newTime); } @@ -291,58 +296,14 @@ namespace Opm { - void TimeMap::initFirstTimestepsMonths() { - m_first_timestep_months.clear(); - - const boost::posix_time::ptime& ptime_prev = getStartTime(0); - boost::gregorian::date prev_date = ptime_prev.date(); - - for (size_t rstep = 0; rstep < m_timeList.size(); ++rstep) { - const boost::posix_time::ptime& ptime_cur = getStartTime(rstep); - boost::gregorian::date cur_date = ptime_cur.date(); - - if (cur_date.month() != prev_date.month()) { - m_first_timestep_months.push_back(rstep); - prev_date = cur_date; - } else if (cur_date.year() != prev_date.year()) { //Same month but different year - m_first_timestep_months.push_back(rstep); - prev_date = cur_date; - } - } - } - - - void TimeMap::initFirstTimestepsYears() { - - m_first_timestep_years.clear(); - - const boost::posix_time::ptime& ptime_prev = getStartTime(0); - boost::gregorian::date prev_date = ptime_prev.date(); - - for (size_t rstep = 0; rstep < m_timeList.size(); ++rstep) { - const boost::posix_time::ptime& ptime_cur = getStartTime(rstep); - boost::gregorian::date cur_date = ptime_cur.date(); - - if (cur_date.year() != prev_date.year()) { - m_first_timestep_years.push_back(rstep); - prev_date = cur_date; - } - } - } const std::vector& TimeMap::getFirstTimestepMonths() const { - if (m_first_timestep_months.size() == 0) { - throw std::runtime_error("TimeMap vector m_first_timestep_months not initialized"); - } return m_first_timestep_months; } const std::vector& TimeMap::getFirstTimestepYears() const { - if (m_first_timestep_years.size() == 0) { - throw std::runtime_error("TimeMap vector m_first_timestep_years not initialized"); - } return m_first_timestep_years; } diff --git a/opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp b/opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp index a877264df..7d60b12f3 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp @@ -41,8 +41,6 @@ namespace Opm { void addTStep(boost::posix_time::time_duration step); void addFromDATESKeyword( const DeckKeyword& DATESKeyword ); void addFromTSTEPKeyword( const DeckKeyword& TSTEPKeyword ); - void initFirstTimestepsMonths(); - void initFirstTimestepsYears(); size_t size() const; size_t last() const; size_t numTimesteps() const; diff --git a/opm/parser/eclipse/EclipseState/Schedule/tests/TimeMapTest.cpp b/opm/parser/eclipse/EclipseState/Schedule/tests/TimeMapTest.cpp index b9f7c3293..eb55b4e8a 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/tests/TimeMapTest.cpp +++ b/opm/parser/eclipse/EclipseState/Schedule/tests/TimeMapTest.cpp @@ -308,10 +308,6 @@ BOOST_AUTO_TEST_CASE(initTimestepsYearsAndMonths) { Opm::DeckPtr deck = parser->parseString(deckData, Opm::ParseContext()); const Opm::TimeMap tmap(deck); - Opm::TimeMap* writableTimemap = const_cast(&tmap); - writableTimemap->initFirstTimestepsMonths(); - writableTimemap->initFirstTimestepsYears(); - /*deckData timesteps: 0 21 may 1981 START 1 22 may 1981 diff --git a/opm/parser/eclipse/IntegrationTests/IOConfigIntegrationTest.cpp b/opm/parser/eclipse/IntegrationTests/IOConfigIntegrationTest.cpp index d17a0a2b4..b8b2e18ef 100644 --- a/opm/parser/eclipse/IntegrationTests/IOConfigIntegrationTest.cpp +++ b/opm/parser/eclipse/IntegrationTests/IOConfigIntegrationTest.cpp @@ -347,3 +347,12 @@ BOOST_AUTO_TEST_CASE( RestartConfig2 ) { BOOST_CHECK_EQUAL( ioConfig->getFirstRestartStep() , 0 ); } + + + +BOOST_AUTO_TEST_CASE( SPE9END ) { + ParseContext parseContext; + ParserPtr parser(new Parser()); + DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/SPE9_END.DATA", parseContext); + BOOST_CHECK_NO_THROW( EclipseState state( deck , parseContext ) ); +} diff --git a/testdata/integration_tests/IOConfig/SPE9_END.DATA b/testdata/integration_tests/IOConfig/SPE9_END.DATA new file mode 100644 index 000000000..3534ea0e7 --- /dev/null +++ b/testdata/integration_tests/IOConfig/SPE9_END.DATA @@ -0,0 +1,174 @@ +-- This reservoir simulation deck is a simplified version of SPE1CASE2.DATA +-- found in opm-data: https://github.com/OPM/opm-data/blob/master/spe1/SPE1CASE2.DATA + + +-- This reservoir simulation deck is made available under the Open Database +-- License: http://opendatacommons.org/licenses/odbl/1.0/. Any rights in +-- individual contents of the database are licensed under the Database Contents +-- License: http://opendatacommons.org/licenses/dbcl/1.0/ + +-- Copyright (C) 2015 Statoil + +-- This simulation is based on the data given in +-- 'Comparison of Solutions to a Three-Dimensional +-- Black-Oil Reservoir Simulation Problem' by Aziz S. Odeh, +-- Journal of Petroleum Technology, January 1981 + +--------------------------------------------------------------------------- +------------------------ SPE1 - CASE 2 ------------------------------------ +--------------------------------------------------------------------------- + +RUNSPEC +-- ------------------------------------------------------------------------- + +TITLE + SPE1 - CASE 2 + +DIMENS + 10 10 3 / + +-- The number of equilibration regions is inferred from the EQLDIMS +-- keyword. +EQLDIMS +/ + +-- The number of PVTW tables is inferred from the TABDIMS keyword; +-- when no data is included in the keyword the default values are used. +TABDIMS +/ + + +OIL +GAS +WATER +DISGAS +-- As seen from figure 4 in Odeh, GOR is increasing with time, +-- which means that dissolved gas is present + + +FIELD + +START + 1 'JAN' 2015 / + +GRID +-- ------------------------------------------------------------------------- + + +DX +-- There are in total 300 cells with length 1000ft in x-direction + 300*1000 / +DY +-- There are in total 300 cells with length 1000ft in y-direction + 300*1000 / +DZ +-- The layers are 20, 30 and 50 ft thick, in each layer there are 100 cells + 100*20 100*30 100*50 / + +TOPS +-- The depth of the top of each grid block + 100*8325 / + +PORO +-- Constant porosity of 0.3 throughout all 300 grid cells + 300*0.3 / + +PERMX +-- The layers have perm. 500mD, 50mD and 200mD, respectively. + 100*500 100*50 100*200 / + +PERMY +-- Equal to PERMX + 100*500 100*50 100*200 / + +PERMZ +-- Cannot find perm. in z-direction in Odeh's paper +-- For the time being, we will assume PERMZ equal to PERMX and PERMY: + 100*500 100*50 100*200 / + + + +SCHEDULE + +RPTRST + 'BASIC=4' / +WELSPECS +-- Column 3: I-value of well head or heel +-- Column 4: J-value of well head or heel +-- - these coordinates are listed in Killough's dataset +-- Column 5: ref. depth of BHP (ft) +-- - stated to be 9110ft in Killough +-- Column 6: preferred phase for well +-- - should be water for injector and oil for producers +-- Column 7: drainage radius for calc. of productivity or +-- injectivity indices (ft) +-- - stated to be 60ft in Killough + +-- #: 1 2 3 4 5 6 7 + 'INJE1' 'G' 1 1 9110 'WATER' 60 / + 'PRODU2' 'G' 2 2 9110 'OIL' 60 / + / + +COMPDAT +-- Column 2: I-value of connecting grid block +-- Column 3: J-value of connecting grid block +-- Column 4: K-value of upper connecting grid block +-- Column 5: K-value of lower connecting grid block +-- - these coordinates are listed in Killough's dataset +-- Column 9: well bore diameter +-- - Killough says radius is 0.5ft + +-- #: 1 2 3 4 5 6 7 8 9 + 'INJE1' 1 1 1 1 'OPEN' 1* 1* 1 / + 'PRODU2' 2 2 2 2 'OPEN' 1* 1* 1 / +/ + +WCONINJE +-- Killough says the water injector is set to a max rate of +-- 5000 STBW per D with a max BHP of 4000psia at a reference +-- depth of 9110ft subsea: +-- #: 1 2 3 4 5 7 + 'INJE1' 'WATER' 'OPEN' 'RATE' 5000 1* 4000 / +/ + +WCONPROD +-- Killough says the max oil rate for all producers is set to +-- 1500 STBO per D at time zero and that the min flowing BHP +-- is set to 1000psia (with a ref. depth of 9110ft +-- for this pressure in all wells): +-- #: 1 2 3 4 9 + 'PRODU*' 'OPEN' 'ORAT' 1500 4* 1000 / +-- Here, the wildcard '*' has been used to indicate that this applies +-- to all producers; PRODU1-PRODU25. +/ + +TSTEP +30*10 / + +END + +-- At 300 days, the max oil rate for all producers is lowered +-- to 100 STBO per D: +WCONPROD +-- #: 1 2 3 4 9 + 'PRODU*' 'OPEN' 'ORAT' 100 4* 1000 / +/ + +TSTEP +6*10 / + +-- At 360 days, the max oil rate for all producers is changed +-- back to 1500 STBO per D: +WCONPROD +-- #: 1 2 3 4 9 + 'PRODU*' 'OPEN' 'ORAT' 1500 4* 1000 / +/ + +TSTEP +54*10 / +-- End of simulation at 900 days + +END + + +