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.
This commit is contained in:
Joakim Hove
2016-06-28 22:20:49 +02:00
parent 0c0cc14538
commit 0db0637ef7
5 changed files with 198 additions and 60 deletions

View File

@@ -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<double>(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<size_t>& 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<size_t>& 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;
}

View File

@@ -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;

View File

@@ -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<Opm::TimeMap*>(&tmap);
writableTimemap->initFirstTimestepsMonths();
writableTimemap->initFirstTimestepsYears();
/*deckData timesteps:
0 21 may 1981 START
1 22 may 1981

View File

@@ -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 ) );
}

View File

@@ -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