Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Fredrik Gundersen 2015-10-02 10:54:01 +02:00
commit cc66cfff51
40 changed files with 1515 additions and 291 deletions

View File

@ -9,3 +9,7 @@ install(TARGETS opm-eclkw DESTINATION "bin")
add_executable(schedule Schedule.cpp)
target_link_libraries(schedule opmparser)
add_executable(OpmLoadDeck OpmLoadDeck)
target_link_libraries(OpmLoadDeck opmparser)
install(TARGETS OpmLoadDeck DESTINATION "bin")

View File

@ -0,0 +1,54 @@
/*
Copyright 2013 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <memory>
#include <opm/parser/eclipse/OpmLog/CounterLog.hpp>
#include <opm/parser/eclipse/OpmLog/StreamLog.hpp>
#include <opm/parser/eclipse/OpmLog/LogUtil.hpp>
#include <opm/parser/eclipse/OpmLog/OpmLog.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParseMode.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
void loadDeck( const char * deck_file) {
Opm::ParseMode parseMode;
Opm::ParserPtr parser(new Opm::Parser());
std::shared_ptr<const Opm::Deck> deck;
std::shared_ptr<Opm::EclipseState> state;
std::cout << "Loading deck: " << deck_file << " ..... "; std::cout.flush();
deck = parser->parseFile(deck_file, parseMode);
std::cout << "parse complete - creating EclipseState .... "; std::cout.flush();
state = std::make_shared<Opm::EclipseState>( deck , parseMode );
std::cout << "complete." << std::endl;
}
int main(int argc, char** argv) {
for (int iarg = 1; iarg < argc; iarg++)
loadDeck( argv[iarg] );
return 0;
}

View File

@ -5,7 +5,6 @@ add_subdirectory(Parser/tests)
add_subdirectory(Generator/tests)
add_subdirectory(RawDeck/tests)
add_subdirectory(Deck/tests)
add_subdirectory(IntegrationTests)
add_subdirectory(EclipseState/tests)
add_subdirectory(EclipseState/Schedule/tests)
add_subdirectory(EclipseState/SimulationConfig/tests)
@ -15,7 +14,8 @@ add_subdirectory(EclipseState/Util/tests)
add_subdirectory(EclipseState/IOConfig/tests)
add_subdirectory(EclipseState/InitConfig/tests)
add_subdirectory( Applications )
add_subdirectory(Applications)
add_subdirectory(IntegrationTests)
set( log_source
OpmLog/TimerLog.cpp
@ -68,6 +68,7 @@ Generator/KeywordGenerator.cpp
Generator/KeywordLoader.cpp )
set( build_parser_source
Parser/ParseMode.cpp
Parser/ParserEnums.cpp
Parser/ParserKeyword.cpp
Parser/ParserRecord.cpp
@ -77,6 +78,7 @@ Parser/ParserFloatItem.cpp
Parser/ParserDoubleItem.cpp
Parser/ParserStringItem.cpp
${generator_source}
${log_source}
)
set (state_source
@ -193,7 +195,7 @@ EclipseState/Schedule/GroupTree.hpp
EclipseState/Schedule/Tuning.hpp
EclipseState/Schedule/Events.hpp
#
EclipseState/Util/ElasticVector.hpp
EclipseState/Util/RecordVector.hpp
EclipseState/Util/OrderedMap.hpp
EclipseState/Util/Value.hpp
#
@ -278,7 +280,7 @@ Utility/EndscaleWrapper.hpp
Utility/ScalecrsWrapper.hpp)
add_library(buildParser STATIC ${rawdeck_source} ${build_parser_source} ${deck_source} ${unit_source} ${generator_source})
target_link_libraries(buildParser opmjson ${Boost_LIBRARIES})
target_link_libraries(buildParser opmjson ${Boost_LIBRARIES} ${ERT_LIBRARIES})
#-----------------------------------------------------------------
# This section manages the generation of C++ code for the default keywords.

View File

@ -40,13 +40,15 @@ class Section : public Deck
const std::string& name() const;
size_t count(const std::string& keyword) const;
static bool hasSCHEDULE(DeckConstPtr deck) { return hasSection( deck , "SCHEDULE" ); }
static bool hasSOLUTION(DeckConstPtr deck) { return hasSection( deck , "SOLUTION" ); }
static bool hasREGIONS(DeckConstPtr deck) { return hasSection( deck , "REGIONS" ); }
static bool hasPROPS(DeckConstPtr deck) { return hasSection( deck , "PROPS" ); }
static bool hasEDIT(DeckConstPtr deck) { return hasSection( deck , "EDIT" ); }
static bool hasGRID(DeckConstPtr deck) { return hasSection( deck , "GRID" ); }
static bool hasRUNSPEC(DeckConstPtr deck) { return hasSection( deck , "RUNSPEC" ); }
static bool hasGRID(DeckConstPtr deck) { return hasSection( deck , "GRID" ); }
static bool hasEDIT(DeckConstPtr deck) { return hasSection( deck , "EDIT" ); }
static bool hasPROPS(DeckConstPtr deck) { return hasSection( deck , "PROPS" ); }
static bool hasREGIONS(DeckConstPtr deck) { return hasSection( deck , "REGIONS" ); }
static bool hasSOLUTION(DeckConstPtr deck) { return hasSection( deck , "SOLUTION" ); }
static bool hasSUMMARY(DeckConstPtr deck) { return hasSection( deck , "SUMMARY" ); }
static bool hasSCHEDULE(DeckConstPtr deck) { return hasSection( deck , "SCHEDULE" ); }
// returns whether the deck has all mandatory sections and if all sections are in
// the right order
@ -92,6 +94,11 @@ class Section : public Deck
public:
SOLUTIONSection(DeckConstPtr deck) : Section(deck, "SOLUTION") {}
};
class SUMMARYSection : public Section {
public:
SUMMARYSection(DeckConstPtr deck) : Section(deck, "SUMMARY") {}
};
}
#endif // SECTION_HPP

View File

@ -118,10 +118,11 @@ BOOST_AUTO_TEST_CASE(StringsWithSpaceOK) {
ParserStringItemPtr itemString(new ParserStringItem(std::string("STRINGITEM1")));
ParserRecordPtr record1(new ParserRecord());
RawRecordPtr rawRecord(new Opm::RawRecord(" ' VALUE ' /"));
ParseMode parseMode;
record1->addItem( itemString );
DeckRecordConstPtr deckRecord = record1->parse( rawRecord );
DeckRecordConstPtr deckRecord = record1->parse( parseMode , rawRecord );
BOOST_CHECK_EQUAL(" VALUE " , deckRecord->getItem(0)->getString(0));
}

View File

@ -126,7 +126,8 @@ namespace Opm {
EclipseState::EclipseState(DeckConstPtr deck , const ParseMode& parseMode)
: m_defaultRegion("FLUXNUM")
: m_defaultRegion("FLUXNUM"),
m_parseMode( parseMode )
{
m_deckUnitSystem = deck->getActiveUnitSystem();
initPhases(deck);
@ -134,12 +135,12 @@ namespace Opm {
initEclipseGrid(deck);
initGridopts(deck);
initIOConfig(deck);
initSchedule(deck , parseMode);
initSchedule(deck);
initIOConfigPostSchedule(deck);
initTitle(deck);
initProperties(deck);
initInitConfig(deck);
initSimulationConfig(deck, parseMode);
initSimulationConfig(deck);
initTransMult();
initFaults(deck);
initMULTREGT(deck);
@ -165,6 +166,10 @@ namespace Opm {
}
const ParseMode& EclipseState::getParseMode() const {
return m_parseMode;
}
ScheduleConstPtr EclipseState::getSchedule() const {
return schedule;
@ -235,14 +240,14 @@ namespace Opm {
m_initConfig = std::make_shared<const InitConfig>(deck);
}
void EclipseState::initSimulationConfig(DeckConstPtr deck , const ParseMode& parseMode) {
m_simulationConfig = std::make_shared<const SimulationConfig>(parseMode , deck , m_intGridProperties);
void EclipseState::initSimulationConfig(DeckConstPtr deck) {
m_simulationConfig = std::make_shared<const SimulationConfig>(m_parseMode , deck , m_intGridProperties);
}
void EclipseState::initSchedule(DeckConstPtr deck, const ParseMode& parseMode) {
void EclipseState::initSchedule(DeckConstPtr deck) {
EclipseGridConstPtr grid = getEclipseGrid();
schedule = ScheduleConstPtr( new Schedule(parseMode , grid , deck, m_ioConfig) );
schedule = ScheduleConstPtr( new Schedule(m_parseMode , grid , deck, m_ioConfig) );
}
void EclipseState::initNNC(DeckConstPtr deck) {

View File

@ -58,6 +58,7 @@ namespace Opm {
EclipseState(DeckConstPtr deck , const ParseMode& parseMode);
const ParseMode& getParseMode() const;
ScheduleConstPtr getSchedule() const;
IOConfigConstPtr getIOConfigConst() const;
IOConfigPtr getIOConfig() const;
@ -97,10 +98,10 @@ namespace Opm {
void initTabdims(DeckConstPtr deck);
void initTables(DeckConstPtr deck);
void initIOConfig(DeckConstPtr deck);
void initSchedule(DeckConstPtr deck , const ParseMode& parseMode);
void initSchedule(DeckConstPtr deck);
void initIOConfigPostSchedule(DeckConstPtr deck);
void initInitConfig(DeckConstPtr deck);
void initSimulationConfig(DeckConstPtr deck, const ParseMode& parseMode);
void initSimulationConfig(DeckConstPtr deck);
void initEclipseGrid(DeckConstPtr deck);
void initGridopts(DeckConstPtr deck);
void initPhases(DeckConstPtr deck);
@ -154,6 +155,7 @@ namespace Opm {
std::shared_ptr<FaultCollection> m_faults;
std::shared_ptr<NNC> m_nnc;
std::string m_defaultRegion;
const ParseMode& m_parseMode;
};
typedef std::shared_ptr<EclipseState> EclipseStatePtr;

View File

@ -91,33 +91,16 @@ namespace Opm {
bool IOConfig::getWriteRestartFileFrequency(size_t timestep,
size_t start_index,
size_t start_timestep,
size_t frequency,
bool first_timesteps_years,
bool first_timesteps_months) const {
bool years,
bool months) const {
bool write_restart_file = false;
if (!first_timesteps_years && !first_timesteps_months) {
write_restart_file = (((timestep-start_index) % frequency) == 0) ? true : false;
if ((!years && !months) && (timestep >= start_timestep)) {
write_restart_file = ((timestep % frequency) == 0) ? true : false;
} else {
std::vector<size_t> timesteps;
if (first_timesteps_years) {
m_timemap->initFirstTimestepsYears(timesteps, start_index);
} else {
m_timemap->initFirstTimestepsMonths(timesteps, start_index);
}
std::vector<size_t>::const_iterator ci_timestep = std::find(timesteps.begin(), timesteps.end(), timestep);
write_restart_file = m_timemap->isTimestepInFirstOfMonthsYearsSequence(timestep, years, start_timestep, frequency);
if (ci_timestep != timesteps.end()) {
if (1 >= frequency) {
write_restart_file = true;
} else {
std::vector<size_t>::const_iterator ci_start = timesteps.begin();
int dist = std::distance( ci_start, ci_timestep ) + 1;
if( ( (dist > 0) && ((dist % frequency) == 0) ) ) {
write_restart_file = true;
}
}
}
}
return write_restart_file;
}

View File

@ -27,6 +27,87 @@
namespace Opm {
/*The IOConfig class holds data about input / ouput configurations
Amongst these configuration settings, a IOConfig object knows if
a restart file should be written for a specific report step
The write of restart files is governed by several eclipse keywords.
These keywords are all described in the eclipse manual, but some
of them are rather porly described there.
To have equal sets of restart files written from Eclipse and Flow for various
configurations, we have made a qualified guess on the behaviour
for some of the keywords (by running eclipse for different configurations,
and looked at which restart files that have been written).
------ RPTSOL RESTART (solution section) ------
If RPTSOL RESTART > 1 initial restart file is written.
------ RPTRST (solution section) ------
Eclipse manual states that the initial restart file is to be written
if RPTSOL RESTART > 1. But - due to that the initial restart file
is written from Eclipse for data where RPTSOL RESTART is not set, - we
have made a guess that when RPTRST is set in SOLUTION (no basic though...),
it means that the initial restart file should be written.
Running of eclipse with different settings have proven this to be a qualified guess.
------ RPTRST BASIC=0 (solution or schedule section) ------
No restart files are written
------ RPTRST BASIC=1 or RPTRST BASIC=2 (solution or schedule section) ------
Restart files are written for every timestep, from timestep 1 to number of timesteps.
(Write of inital timestep is governed by a separate setting)
Notice! Eclipse simulator RPTRST BASIC=1 writes restart files for every
report step, but only keeps the last one written. This functionality is
not supported in Flow; so to compare Eclipse results with Flow results
for every report step, set RPTRST BASIC=2 for the eclipse run
------ RPTRST BASIC=3 FREQ=n (solution or schedule section) ------
Restart files are created every nth report time. Default frequency is 1 (every report step)
If a frequency higher than 1 is given:
start_rs = report step the setting was given.
write report step rstep if (rstep >= start_rs) && ((rstep % frequency) == 0).
------ RPTRST BASIC=4 FREQ=n or RPTRST BASIC=5 FREQ=n (solution or schedule section) ------
For the settings BASIC 4 or BASIC 5, - first report step of every new year(4) or new month(5),
the first report step is compared with report step 0 (start), and then every report step is
compared with the previous one to see if year/month has changed.
This leaves us with a set of timesteps.
All timesteps in the set that are higher or equal to the timestep the RPTRST keyword was set on is written.
If in addition FREQUENCY is given (higher than 1), every n'the value of this set are to be written.
If the setting BASIC=4 or BASIC=5 is set on a timestep that is a member of the set "first timestep of
each year" / "First timestep of each month", then the timestep that is freq-1 timesteps (within the set) from
this start timestep will be written, and then every n'the timestep (within the set) from this one will be written.
If the setting BASIC=4 or BASIC=5 is set on a timestep that is not a member of the list "first timestep of
each year" / "First timestep of each month", then the list is searched for the closest timestep that are
larger than the timestep that introduced the setting, and then; same as above - the timestep that is freq-1
timesteps from this one (within the set) will be written, and then every n'the timestep (within the set) from
this one will be written.
------ RPTRST BASIC=6 (solution or schedule section) ------
Not supported in Flow
------ Default ------
If no keywords for config of writing restart files have been handled; no restart files are written.
*/
class IOConfig {
public:
@ -66,10 +147,10 @@ namespace Opm {
void assertTimeMap(TimeMapConstPtr timemap);
bool getWriteRestartFileFrequency(size_t timestep,
size_t start_index,
size_t start_timestep,
size_t frequency,
bool first_timesteps_years = false,
bool first_timesteps_months = false) const;
bool years = false,
bool months = false) const;
void handleRPTSOL(DeckKeywordConstPtr keyword);
@ -115,6 +196,7 @@ namespace Opm {
std::shared_ptr<DynamicState<restartConfig>> m_restart_output_config;
};

View File

@ -43,39 +43,93 @@ const std::string& deckStr = "RUNSPEC\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"TSTEP\n"
" 1 2 3 4 5 /\n"
"DATES\n"
" 1 JAN 1982 /\n"
" 1 JAN 1982 13:55:44 /\n"
" 3 JAN 1982 14:56:45.123 /\n"
"/\n"
"TSTEP\n"
" 9 10 /\n"
"\n";
" 22 MAY 1981 /\n" // timestep 1
" 23 MAY 1981 /\n" // timestep 2
" 24 MAY 1981 /\n" // timestep 3
" 25 MAY 1981 /\n" // timestep 4
" 26 MAY 1981 /\n" // timestep 5
" 1 JAN 1982 /\n" // timestep 6
" 1 JAN 1982 13:55:44 /\n" // timestep 7
" 3 JAN 1982 14:56:45.123 /\n" // timestep 8
" 4 JAN 1982 14:56:45.123 /\n" // timestep 9
" 5 JAN 1982 14:56:45.123 /\n" // timestep 10
" 6 JAN 1982 14:56:45.123 /\n" // timestep 11
" 7 JAN 1982 14:56:45.123 /\n" // timestep 12
" 8 JAN 1982 14:56:45.123 /\n" // timestep 13
" 9 JAN 1982 14:56:45.123 /\n" // timestep 14
" 10 JAN 1982 14:56:45.123 /\n" // timestep 15
" 11 JAN 1982 14:56:45.123 /\n" // timestep 16
" 1 JAN 1983 /\n" // timestep 17
" 2 JAN 1983 /\n" // timestep 18
" 3 JAN 1983 /\n" // timestep 19
" 1 JAN 1984 /\n" // timestep 20
" 2 JAN 1984 /\n" // timestep 21
" 1 JAN 1985 /\n" // timestep 22
" 3 JAN 1986 14:56:45.123 /\n" // timestep 23
" 4 JAN 1986 14:56:45.123 /\n" // timestep 24
" 5 JAN 1986 14:56:45.123 /\n" // timestep 25
" 1 JAN 1987 /\n" // timestep 26
" 1 JAN 1988 /\n" // timestep 27
" 2 JAN 1988 /\n" // timestep 28
" 3 JAN 1988 /\n" // timestep 29
" 1 JAN 1989 /\n" // timestep 30
" 2 JAN 1989 /\n" // timestep 31
" 2 JAN 1990 /\n" // timestep 32
" 2 JAN 1991 /\n" // timestep 33
" 3 JAN 1991 /\n" // timestep 34
" 4 JAN 1991 /\n" // timestep 35
" 1 JAN 1992 /\n" // timestep 36
" 1 FEB 1992 /\n" // timestep 37
" 1 MAR 1992 /\n" // timestep 38
" 2 MAR 1992 /\n" // timestep 39
" 3 MAR 1992 /\n" // timestep 40
" 4 MAR 1992 /\n" // timestep 41
" 1 APR 1992 /\n" // timestep 42
" 2 APR 1992 /\n" // timestep 43
" 1 MAY 1992 /\n" // timestep 44
" 2 MAY 1992 /\n" // timestep 45
" 3 MAY 1992 /\n" // timestep 46
" 3 JUN 1992 /\n" // timestep 47
" 3 JUL 1992 /\n" // timestep 48
" 3 AUG 1992 /\n" // timestep 49
" 4 AUG 1992 /\n" // timestep 50
" 5 AUG 1992 /\n" // timestep 51
" 6 AUG 1992 /\n" // timestep 52
" 7 AUG 1992 /\n" // timestep 53
" 8 AUG 1992 /\n" // timestep 54
" 9 AUG 1992 /\n" // timestep 55
" 10 AUG 1992 /\n" // timestep 56
" 11 AUG 1992 /\n" // timestep 57
" 12 AUG 1992 /\n" // timestep 58
" 13 AUG 1992 /\n" // timestep 59
" 14 AUG 1992 /\n" // timestep 60
" 15 AUG 1992 /\n" // timestep 61
"/\n"
"\n";
const std::string& deckStr3 = "RUNSPEC\n"
"UNIFIN\n"
"UNIFOUT\n"
"FMTIN\n"
"FMTOUT\n"
"\n"
"DIMENS\n"
"10 10 10 /\n"
"GRID\n"
"INIT\n"
"NOGGF\n"
"\n";
const std::string& deckStr_NOGGF = "RUNSPEC\n"
"UNIFIN\n"
"UNIFOUT\n"
"FMTIN\n"
"FMTOUT\n"
"\n"
"DIMENS\n"
"10 10 10 /\n"
"GRID\n"
"INIT\n"
"NOGGF\n"
"\n";
const std::string& deckStr4 = "RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"GRIDFILE\n"
" 0 0 /\n"
"\n";
const std::string& deckStr_NO_GRIDFILE = "RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"GRIDFILE\n"
" 0 0 /\n"
"\n";
@ -102,8 +156,15 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
Schedule schedule(ParseMode() , grid , deck, ioConfigPtr);
TimeMapConstPtr timemap = schedule.getTimeMap();
const TimeMap* const_tmap = timemap.get();
TimeMap* writableTimemap = const_cast<TimeMap*>(const_tmap);
writableTimemap->initFirstTimestepsYears();
writableTimemap->initFirstTimestepsMonths();
//If no BASIC keyord has been handled, no restart files should be written
TimeMapConstPtr timemap = schedule.getTimeMap();
for (size_t ts = 0; ts < timemap->numTimesteps(); ++ts) {
BOOST_CHECK_EQUAL(false, ioConfigPtr->getWriteRestartFile(ts));
}
@ -120,24 +181,6 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
}
}
//Add timestep 11, 12, 13, 14, 15, 16
const TimeMap* const_tmap = timemap.get();
TimeMap* writableTimemap = const_cast<TimeMap*>(const_tmap);
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(11));
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(12));
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(13));
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(14));
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(15));
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(16));
/* BASIC=3, restart files are created every nth report time, n=3 */
timestep = 11;
@ -146,24 +189,13 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
ioConfigPtr->handleRPTRSTBasic(schedule.getTimeMap(),timestep, basic, frequency);
for (size_t ts = timestep ; ts < timemap->numTimesteps(); ++ts) {
if (((ts-timestep) % frequency) == 0) {
if ((ts >= timestep) && ((ts % frequency) == 0)) {
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(ts));
} else {
BOOST_CHECK_EQUAL(false, ioConfigPtr->getWriteRestartFile(ts));
}
}
//Add timestep 17, 18, 19, 20, 21, 22, 23, 24, 25, 26
writableTimemap->addTStep(boost::posix_time::hours(8760)); //1983
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(8760)); //1984
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(8760)); //1985
writableTimemap->addTStep(boost::posix_time::hours(8760)); //1986
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(8760)); //1987
/* BASIC=4, restart file is written at the first report step of each year.
Optionally, if the mnemonic FREQ is set >1 the restart is written only every n'th year*/
@ -172,10 +204,11 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
frequency = 0;
ioConfigPtr->handleRPTRSTBasic(schedule.getTimeMap(),timestep, basic, frequency);
/*Expected results: Write timestep for timestep 20, 22, 23, 26*/
for (size_t ts = 17; ts <= 26; ++ts) {
if ((20 == ts) || (22 == ts) || (23 == ts) || (26 == ts)) {
for (size_t ts = timestep; ts < timemap->numTimesteps(); ++ts) {
ioConfigPtr->getWriteRestartFile(ts);
if ((17 == ts) || (20 == ts) || (22 == ts) || (23 == ts) || (26 == ts) ||
(27 == ts) || (30 == ts) || (32 == ts) || (33 == ts) || (36 == ts)) {
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(ts));
} else {
BOOST_CHECK_EQUAL(false, ioConfigPtr->getWriteRestartFile(ts));
@ -183,17 +216,23 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
}
//Add timestep 27, 28, 29, 30, 31, 32, 33, 34, 35, 36
writableTimemap->addTStep(boost::posix_time::hours(8760)); //1988
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(8760)); //1989
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(8760)); //1990
writableTimemap->addTStep(boost::posix_time::hours(8760)); //1991
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(8760)); //1992
/* BASIC=4, restart file is written at the first report step of each year.
Optionally, if the mnemonic FREQ is set >1 the restart is written only every n'th year*/
timestep = 18;
basic = 4;
frequency = 0;
ioConfigPtr->handleRPTRSTBasic(schedule.getTimeMap(),timestep, basic, frequency);
for (size_t ts = timestep; ts < timemap->numTimesteps(); ++ts) {
ioConfigPtr->getWriteRestartFile(ts);
if ((20 == ts) || (22 == ts) || (23 == ts) || (26 == ts) ||
(27 == ts) || (30 == ts) || (32 == ts) || (33 == ts) || (36 == ts)) {
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(ts));
} else {
BOOST_CHECK_EQUAL(false, ioConfigPtr->getWriteRestartFile(ts));
}
}
/* BASIC=4, FREQ = 2 restart file is written at the first report step of each year.
Optionally, if the mnemonic FREQ is set >1 the restart is written only every n'th year*/
@ -202,10 +241,8 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
frequency = 2;
ioConfigPtr->handleRPTRSTBasic(schedule.getTimeMap(), timestep, basic, frequency);
//Expected results: Write timestep for 32 and 36 (30, 32, 33, 36 with frequency 2)
for (size_t ts = 27; ts <= 36; ++ts) {
if ((32 == ts) || (36 == ts)) {
for (size_t ts = timestep; ts < timemap->numTimesteps(); ++ts) {
if ((30 == ts) || (33 == ts)) {
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(ts));
} else {
BOOST_CHECK_EQUAL(false, ioConfigPtr->getWriteRestartFile(ts));
@ -214,18 +251,6 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
//Add timestep 37, 38, 39, 40, 41, 42, 43, 44, 45, 46
writableTimemap->addTStep(boost::posix_time::hours(24)); //february
writableTimemap->addTStep(boost::posix_time::hours(650)); //march
writableTimemap->addTStep(boost::posix_time::hours(24)); //march
writableTimemap->addTStep(boost::posix_time::hours(24)); //march
writableTimemap->addTStep(boost::posix_time::hours(24)); //march
writableTimemap->addTStep(boost::posix_time::hours(650)); //april
writableTimemap->addTStep(boost::posix_time::hours(24)); //april
writableTimemap->addTStep(boost::posix_time::hours(650)); //may
writableTimemap->addTStep(boost::posix_time::hours(24)); //may
writableTimemap->addTStep(boost::posix_time::hours(24)); //may
/* BASIC=5, restart file is written at the first report step of each month.
Optionally, if the mnemonic FREQ is set >1 the restart is written only every n'th month*/
timestep = 37;
@ -233,20 +258,14 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
frequency = 2;
ioConfigPtr->handleRPTRSTBasic(schedule.getTimeMap(), timestep, basic, frequency);
//Expected results: Write timestep for timestep 38, 44 (38, 42, 44 with frequency 2)
for (size_t ts = 37; ts <= 46; ++ts) {
if (42 == ts) {
for (size_t ts = timestep; ts < timemap->numTimesteps(); ++ts) {
if ((38 == ts) || (44 == ts) || (48 == ts)) {
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(ts));
} else {
BOOST_CHECK_EQUAL(false, ioConfigPtr->getWriteRestartFile(ts));
}
}
//Add timestep 47, 48, 49
writableTimemap->addTStep(boost::posix_time::hours(750)); //june
writableTimemap->addTStep(boost::posix_time::hours(750)); //july
writableTimemap->addTStep(boost::posix_time::hours(750)); //august
/* BASIC=0, no restart files are written*/
timestep = 47;
@ -254,17 +273,15 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
frequency = 0;
ioConfigPtr->handleRPTRSTBasic(schedule.getTimeMap(), timestep, basic, frequency);
BOOST_CHECK_EQUAL(false, ioConfigPtr->getWriteRestartFile(47));
BOOST_CHECK_EQUAL(false, ioConfigPtr->getWriteRestartFile(48));
BOOST_CHECK_EQUAL(false, ioConfigPtr->getWriteRestartFile(49));
for (size_t ts = timestep; ts < timemap->numTimesteps(); ++ts) {
BOOST_CHECK_EQUAL(false, ioConfigPtr->getWriteRestartFile(ts));
}
/************************* Test RPTSCHED RESTART *************************/
//Add timestep 50, 51
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
/* RPTSCHED RESTART=1, restart files are written*/
timestep = 50;
size_t restart = 1;
@ -273,10 +290,6 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(50));
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(51));
//Add timestep 52, 53
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
/* RPTSCHED RESTART=0, no restart files are written*/
timestep = 52;
restart = 0;
@ -285,19 +298,12 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
BOOST_CHECK_EQUAL(false, ioConfigPtr->getWriteRestartFile(52));
BOOST_CHECK_EQUAL(false, ioConfigPtr->getWriteRestartFile(53));
//Add timestep 54, 55
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
timestep = 54;
basic = 0;
ioConfigPtr->handleRPTSCHEDRestart(schedule.getTimeMap(), timestep, restart);
/* RPTSCHED RESTART IGNORED IF RPTRST BASIC > 2 */
//Add timestep 56, 57, 58, 59
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
timestep = 56;
basic = 3;
frequency = 1;
@ -313,11 +319,7 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
ioConfigPtr->handleRPTSCHEDRestart(schedule.getTimeMap(), timestep, restart);
BOOST_CHECK_EQUAL(true, ioConfigPtr->getWriteRestartFile(timestep));
/* RPTSCHED RESTART NOT IGNORED IF RPTRST BASIC <= 2 */
//Add timestep 60, 61
writableTimemap->addTStep(boost::posix_time::hours(24));
writableTimemap->addTStep(boost::posix_time::hours(24));
timestep = 60;
basic = 1;
frequency = 0;
@ -367,7 +369,7 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
BOOST_CHECK_EQUAL(false, ioConfigPtr->getFMTOUT());
/*If NOGGF keyword is present, no EGRID file is written*/
DeckPtr deck3 = createDeck(deckStr3);
DeckPtr deck3 = createDeck(deckStr_NOGGF);
IOConfigPtr ioConfigPtr3;
BOOST_CHECK_NO_THROW(ioConfigPtr3 = std::make_shared<IOConfig>());
@ -388,7 +390,7 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
BOOST_CHECK_EQUAL(true, ioConfigPtr3->getFMTOUT());
/*If GRIDFILE 0 0 is specified, no EGRID file is written */
DeckPtr deck4 = createDeck(deckStr4);
DeckPtr deck4 = createDeck(deckStr_NO_GRIDFILE);
IOConfigPtr ioConfigPtr4;
BOOST_CHECK_NO_THROW(ioConfigPtr4 = std::make_shared<IOConfig>());

View File

@ -201,6 +201,9 @@ namespace Opm {
}
}
m_timeMap->initFirstTimestepsYears();
m_timeMap->initFirstTimestepsMonths();
for (auto rftPair = rftProperties.begin(); rftPair != rftProperties.end(); ++rftPair) {
DeckKeywordConstPtr keyword = rftPair->first;
size_t timeStep = rftPair->second;

View File

@ -226,43 +226,130 @@ namespace Opm {
}
void TimeMap::initFirstTimestepsMonths(std::vector<size_t>& timesteps, size_t from_timestep) const {
timesteps.clear();
const boost::posix_time::ptime& ptime_prev = getStartTime(from_timestep);
bool TimeMap::isTimestepInFirstOfMonthsYearsSequence(size_t timestep, bool years, size_t start_timestep, size_t frequency) const {
bool timestep_first_of_month_year = false;
const std::vector<size_t>& timesteps = (years) ? getFirstTimestepYears() : getFirstTimestepMonths();
std::vector<size_t>::const_iterator ci_timestep = std::find(timesteps.begin(), timesteps.end(), timestep);
if (ci_timestep != timesteps.end()) {
if (1 >= frequency) {
timestep_first_of_month_year = true;
} else { //Frequency given
timestep_first_of_month_year = isTimestepInFreqSequence(timestep, start_timestep, frequency, years);
}
}
return timestep_first_of_month_year;
}
// This method returns true for every n'th timestep in the vector of timesteps m_first_timestep_years or m_first_timestep_months,
// starting from one before the position of start_timestep. If the given start_timestep is not a value in the month or year vector,
// set the first timestep that are both within the vector and higher than the initial start_timestep as new start_timestep.
bool TimeMap::isTimestepInFreqSequence (size_t timestep, size_t start_timestep, size_t frequency, bool years) const {
bool timestep_right_frequency = false;
const std::vector<size_t>& timesteps = (years) ? getFirstTimestepYears() : getFirstTimestepMonths();
std::vector<size_t>::const_iterator ci_timestep = std::find(timesteps.begin(), timesteps.end(), timestep);
std::vector<size_t>::const_iterator ci_start_timestep = std::find(timesteps.begin(), timesteps.end(), start_timestep);
//Find new start_timestep if the given one is not a value in the timesteps vector
bool start_ts_in_timesteps = false;
if (ci_start_timestep != timesteps.end()) {
start_ts_in_timesteps = true;
} else if (ci_start_timestep == timesteps.end()) {
size_t new_start = closest(timesteps, start_timestep);
if (0 != new_start) {
ci_start_timestep = std::find(timesteps.begin(), timesteps.end(), new_start);
start_ts_in_timesteps = true;
}
}
if (start_ts_in_timesteps) {
//Pick every n'th element, starting on start_timestep + (n-1), that is, every n'th element from ci_start_timestep - 1 for freq n > 1
if (ci_timestep >= ci_start_timestep) {
int dist = std::distance( ci_start_timestep - 1, ci_timestep );
if ((dist % frequency) == 0) {
timestep_right_frequency = true;
}
}
}
return timestep_right_frequency;
}
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 timestepIndex = from_timestep; timestepIndex < m_timeList.size(); ++timestepIndex) {
const boost::posix_time::ptime& ptime_cur = getStartTime(timestepIndex);
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()) {
timesteps.push_back(timestepIndex);
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() {
void TimeMap::initFirstTimestepsYears(std::vector<size_t>& timesteps, size_t from_timestep) const {
timesteps.clear();
m_first_timestep_years.clear();
const boost::posix_time::ptime& ptime_prev = getStartTime(from_timestep);
const boost::posix_time::ptime& ptime_prev = getStartTime(0);
boost::gregorian::date prev_date = ptime_prev.date();
for (size_t timestepIndex = from_timestep; timestepIndex < m_timeList.size(); ++timestepIndex) {
const boost::posix_time::ptime& ptime_cur = getStartTime(timestepIndex);
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()) {
timesteps.push_back(timestepIndex);
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;
}
// vec is assumed to be sorted
size_t TimeMap::closest(const std::vector<size_t> & vec, size_t value) const
{
std::vector<size_t>::const_iterator ci =
std::lower_bound(vec.begin(), vec.end(), value);
if (ci != vec.end()) {
return *ci;
}
return 0;
}
const boost::posix_time::ptime& TimeMap::operator[] (size_t index) const {
if (index < m_timeList.size())
return m_timeList[index];

View File

@ -39,6 +39,8 @@ namespace Opm {
void addTStep(boost::posix_time::time_duration step);
void addFromDATESKeyword( DeckKeywordConstPtr DATESKeyword );
void addFromTSTEPKeyword( DeckKeywordConstPtr TSTEPKeyword );
void initFirstTimestepsMonths();
void initFirstTimestepsYears();
size_t size() const;
size_t numTimesteps() const;
double getTotalTime() const;
@ -49,10 +51,12 @@ namespace Opm {
double getTimePassedUntil(size_t tLevelIdx) const;
/// Return the length of a given time step in seconds.
double getTimeStepLength(size_t tStepIdx) const;
/// Return a list of the first timesteps of each month
void initFirstTimestepsMonths(std::vector<size_t>& timesteps, size_t from_timestep=1) const;
/// Return a list of the first timesteps of each year
void initFirstTimestepsYears(std::vector<size_t>& timesteps, size_t from_timestep=1) const;
/// Return true if the given timestep is the first one of a new month or year, or if frequency > 1,
/// return true for every n'th timestep of every first new month or first new year timesteps,
/// starting from start_timestep-1.
bool isTimestepInFirstOfMonthsYearsSequence(size_t timestep, bool years = true, size_t start_timestep = 1, size_t frequency = 1) const;
static boost::posix_time::ptime timeFromEclipse(DeckRecordConstPtr dateRecord);
static boost::posix_time::ptime timeFromEclipse(int day , const std::string& month, int year, const std::string& eclipseTimeString = "00:00:00.000");
static boost::posix_time::time_duration dayTimeFromEclipse(const std::string& eclipseTimeString);
@ -60,6 +64,14 @@ namespace Opm {
static const std::map<std::string , boost::gregorian::greg_month>& eclipseMonthNames();
std::vector<boost::posix_time::ptime> m_timeList;
const std::vector<size_t>& getFirstTimestepMonths() const;
const std::vector<size_t>& getFirstTimestepYears() const;
bool isTimestepInFreqSequence (size_t timestep, size_t start_timestep, size_t frequency, bool years) const;
size_t closest(const std::vector<size_t> & vec, size_t value) const;
std::vector<size_t> m_first_timestep_years; // A list of the first timestep of every year
std::vector<size_t> m_first_timestep_months; // A list of the first timestep of every month
};
typedef std::shared_ptr<TimeMap> TimeMapPtr;
typedef std::shared_ptr<const TimeMap> TimeMapConstPtr;

View File

@ -1061,8 +1061,8 @@ BOOST_AUTO_TEST_CASE(createDeckWithRPTSCHEDandRPTRST) {
BOOST_CHECK_EQUAL(false, ioConfig->getWriteRestartFile(0));
BOOST_CHECK_EQUAL(false, ioConfig->getWriteRestartFile(1));
BOOST_CHECK_EQUAL(true, ioConfig->getWriteRestartFile(2));
BOOST_CHECK_EQUAL(false, ioConfig->getWriteRestartFile(3));
BOOST_CHECK_EQUAL(false, ioConfig->getWriteRestartFile(2));
BOOST_CHECK_EQUAL(true, ioConfig->getWriteRestartFile(3));
}

View File

@ -304,9 +304,13 @@ BOOST_AUTO_TEST_CASE(initTimestepsYearsAndMonths) {
"TSTEP\n"
" 6 7 /\n";
Opm::ParserPtr parser(new Opm::Parser(/*addDefault=*/true));
Opm::ParserPtr parser(new Opm::Parser(true));
Opm::DeckPtr deck = parser->parseString(deckData, Opm::ParseMode());
Opm::TimeMap tmap(deck);
const Opm::TimeMap tmap(deck);
Opm::TimeMap* writableTimemap = const_cast<Opm::TimeMap*>(&tmap);
writableTimemap->initFirstTimestepsMonths();
writableTimemap->initFirstTimestepsYears();
/*deckData timesteps:
0 21 may 1981 START
@ -326,29 +330,23 @@ BOOST_AUTO_TEST_CASE(initTimestepsYearsAndMonths) {
14 1 jan 1982
15 3 jan 1982
16 9 jan 1982
17 16 jan 1982
*/
17 16 jan 1982*/
std::vector<size_t> first_timestep_of_each_month;
tmap.initFirstTimestepsMonths(first_timestep_of_each_month);
BOOST_CHECK_EQUAL(8, first_timestep_of_each_month.size());
int expected_results[8] = {5,6,8,9,10,11,12,13};
BOOST_CHECK_EQUAL_COLLECTIONS(expected_results, expected_results+8, first_timestep_of_each_month.begin(), first_timestep_of_each_month.end());
for (size_t timestep = 0; timestep <= 17; ++timestep) {
if ((5 == timestep) || (6 == timestep) || (8 == timestep) || (9 == timestep) ||
(10 == timestep) || (11 == timestep) || (12 == timestep) || (13 == timestep)) {
BOOST_CHECK_EQUAL(true, tmap.isTimestepInFirstOfMonthsYearsSequence(timestep, false, true));
} else {
BOOST_CHECK_EQUAL(false, tmap.isTimestepInFirstOfMonthsYearsSequence(timestep, false, true));
}
}
first_timestep_of_each_month.clear();
tmap.initFirstTimestepsMonths(first_timestep_of_each_month, 6);
BOOST_CHECK_EQUAL(6, first_timestep_of_each_month.size());
int expected_results3[6] = {8,9,10,11,12,13};
BOOST_CHECK_EQUAL_COLLECTIONS(expected_results3, expected_results3+6, first_timestep_of_each_month.begin(), first_timestep_of_each_month.end());
std::vector<size_t> first_timestep_of_each_year;
tmap.initFirstTimestepsYears(first_timestep_of_each_year);
BOOST_CHECK_EQUAL(1, first_timestep_of_each_year.size());
int expected_results_years[1] = {13};
BOOST_CHECK_EQUAL_COLLECTIONS(expected_results_years, expected_results_years+1, first_timestep_of_each_year.begin(), first_timestep_of_each_year.end());
first_timestep_of_each_year.clear();
tmap.initFirstTimestepsYears(first_timestep_of_each_year, 13);
BOOST_CHECK_EQUAL(0, first_timestep_of_each_year.size());
for (size_t timestep = 0; timestep <= 17; ++timestep) {
if (13 == timestep) {
BOOST_CHECK_EQUAL(true, tmap.isTimestepInFirstOfMonthsYearsSequence(timestep, true, false));
} else {
BOOST_CHECK_EQUAL(false, tmap.isTimestepInFirstOfMonthsYearsSequence(timestep, true, false));
}
}
}

View File

@ -24,15 +24,37 @@
/*
The internalization of the CPR keyword has been temporarily
disabled, suddenly decks with 'CPR' in the summary section turned
up. Keywords with section aware keyword semantics is currently not
handled by the parser.
When the CPR is added again the following keyword configuration must
be added:
{"name" : "CPR" , "sections" : ["RUNSPEC"], "size": 1 }
*/
namespace Opm {
SimulationConfig::SimulationConfig(const ParseMode& parseMode , DeckConstPtr deck, std::shared_ptr<GridProperties<int>> gridProperties) {
initThresholdPressure(parseMode , deck, gridProperties);
SimulationConfig::SimulationConfig(const ParseMode& parseMode , DeckConstPtr deck, std::shared_ptr<GridProperties<int>> gridProperties) :
m_useCPR( false )
{
if (Section::hasRUNSPEC(deck)) {
const RUNSPECSection runspec(deck);
if (runspec.hasKeyword<ParserKeywords::CPR>()) {
std::shared_ptr<const DeckKeyword> cpr = runspec.getKeyword<ParserKeywords::CPR>();
if (cpr->size() > 0)
throw std::invalid_argument("ERROR: In the RUNSPEC section the CPR keyword should EXACTLY one empty record.");
m_useCPR = false;
if(deck->hasKeyword<ParserKeywords::CPR>()){
m_useCPR = true;
m_useCPR = true;
}
}
initThresholdPressure(parseMode , deck, gridProperties);
}

View File

@ -27,6 +27,7 @@
#include <opm/core/utility/platform_dependent/reenable_warnings.h>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/Parser/ParseMode.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp>
@ -68,12 +69,29 @@ const std::string& inputStr_noTHPRES = "RUNSPEC\n"
"\n";
const std::string& inputStr_cpr = "RUNSPEC\n"
"CPR\n"
"/\n";
"CPR\n"
"/\n"
"SUMMARY\n";
const std::string& inputStr_cprWithData = "RUNSPEC\n"
const std::string& inputStr_INVALID = "RUNSPEC\n"
"CPR\n"
"WEll 10 10 17/"
"/\n"
"SUMMARY\n";
const std::string& inputStr_cpr_in_SUMMARY = "SUMMARY\n"
"CPR\n"
"data/\n";
"well1 10 27 10/\n/\n";
const std::string& inputStr_cpr_BOTH = "RUNSPEC\n"
"CPR\n"
"/\n"
"SUMMARY\n"
"CPR\n"
"well1 10 20 30/\n/\n";
static DeckPtr createDeck(const ParseMode& parseMode , const std::string& input) {
Opm::Parser parser;
@ -116,16 +134,46 @@ BOOST_AUTO_TEST_CASE(SimulationConfigCPRNotUsed) {
}
BOOST_AUTO_TEST_CASE(SimulationConfigCPRUsed) {
ParseMode parseMode;
DeckPtr deck = createDeck(parseMode , inputStr_cpr);
SimulationConfig simulationConfig(parseMode , deck, getGridProperties());
BOOST_CHECK_EQUAL( true , simulationConfig.useCPR());
ParseMode parseMode;
DeckPtr deck = createDeck(parseMode , inputStr_cpr);
SUMMARYSection summary(deck);
SimulationConfig simulationConfig(parseMode , deck, getGridProperties());
BOOST_CHECK_EQUAL( true , simulationConfig.useCPR());
BOOST_CHECK_EQUAL( false , summary.hasKeyword("CPR"));
}
BOOST_AUTO_TEST_CASE(SimulationConfigCPRUsedWithData) {
ParseMode parseMode;
BOOST_CHECK_THROW(createDeck(parseMode , inputStr_cprWithData), std::invalid_argument);
BOOST_AUTO_TEST_CASE(SimulationConfigCPRInSUMMARYSection) {
ParseMode parseMode;
DeckPtr deck = createDeck(parseMode , inputStr_cpr_in_SUMMARY);
SUMMARYSection summary(deck);
SimulationConfig simulationConfig(parseMode , deck, getGridProperties());
BOOST_CHECK_EQUAL( false , simulationConfig.useCPR());
BOOST_CHECK_EQUAL( true , summary.hasKeyword("CPR"));
}
BOOST_AUTO_TEST_CASE(SimulationConfigCPRBoth) {
ParseMode parseMode;
DeckPtr deck = createDeck(parseMode , inputStr_cpr_BOTH);
SUMMARYSection summary(deck);
SimulationConfig simulationConfig(parseMode , deck, getGridProperties());
BOOST_CHECK_EQUAL( true , simulationConfig.useCPR());
BOOST_CHECK_EQUAL( true , summary.hasKeyword("CPR"));
std::shared_ptr<const DeckKeyword> cpr = summary.getKeyword<ParserKeywords::CPR>();
std::shared_ptr<const DeckRecord> record = cpr->getRecord(0);
BOOST_CHECK_EQUAL( 1 , cpr->size());
BOOST_CHECK_EQUAL( record->getItem<ParserKeywords::CPR::WELL>()->getString(0) , "well1");
BOOST_CHECK_EQUAL( record->getItem<ParserKeywords::CPR::I>()->getInt(0) , 10);
BOOST_CHECK_EQUAL( record->getItem<ParserKeywords::CPR::J>()->getInt(0) , 20);
BOOST_CHECK_EQUAL( record->getItem<ParserKeywords::CPR::K>()->getInt(0) , 30);
}
BOOST_AUTO_TEST_CASE(SimulationConfigCPRRUnspecWithData) {
ParseMode parseMode;
BOOST_CHECK_THROW( createDeck(parseMode , inputStr_INVALID) , std::invalid_argument );
}

View File

@ -29,6 +29,12 @@
namespace Opm {
class Tabdims {
public:
/*
The TABDIMS keyword has a total of 25 items; most of them
are ECLIPSE300 only and quite exotic. Here we only
internalize the most common items.
*/
Tabdims(size_t ntsfun, size_t ntpvt, size_t nssfun , size_t nppvt, size_t ntfip , size_t nrpvt) :
m_ntsfun( ntsfun ),
m_ntpvt( ntpvt ),
@ -61,8 +67,8 @@ namespace Opm {
size_t getNumRSNodes() const {
return m_nrpvt;
}
private:
size_t m_ntsfun,m_ntpvt,m_nssfun,m_nppvt,m_ntfip,m_nrpvt;
};

View File

@ -1124,3 +1124,10 @@ BOOST_AUTO_TEST_CASE( TestPLYMAX ) {
BOOST_AUTO_TEST_CASE( TestParseTABDIMS ) {
const char *data =
"TABDIMS\n"
" 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 /\n";
Opm::ParserPtr parser(new Opm::Parser);
BOOST_CHECK_NO_THROW( parser->parseString(data, Opm::ParseMode()));
}

View File

@ -18,8 +18,8 @@
*/
#ifndef _ELASTIC_VECTOR_
#define _ELASTIC_VECTOR_
#ifndef _RECORD_VECTOR_
#define _RECORD_VECTOR_
#include <vector>
#include <stdexcept>
@ -32,7 +32,7 @@
namespace Opm {
template <typename T>
class ElasticVector {
class RecordVector {
private:
std::vector<T> m_data;
public:
@ -47,7 +47,7 @@ public:
else
return m_data[index];
} else
throw std::invalid_argument("Trying to get from empty ElasticVector");
throw std::invalid_argument("Trying to get from empty RecordVector");
}

View File

@ -1,4 +1,4 @@
foreach(tapp OrderedMapTests ValueTests ElasticVectorTests)
foreach(tapp OrderedMapTests ValueTests RecordVectorTests)
opm_add_test(run${tapp} SOURCES ${tapp}.cpp
LIBRARIES opmparser ${Boost_LIBRARIES})
endforeach()

View File

@ -25,17 +25,17 @@
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/parser/eclipse/EclipseState/Util/ElasticVector.hpp>
#include <opm/parser/eclipse/EclipseState/Util/RecordVector.hpp>
BOOST_AUTO_TEST_CASE( check_empty) {
Opm::ElasticVector<int> vector;
Opm::RecordVector<int> vector;
BOOST_CHECK_EQUAL( 0U , vector.size());
BOOST_CHECK_THROW( vector.get(0) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE( check_add ) {
Opm::ElasticVector<int> vector;
Opm::RecordVector<int> vector;
vector.push_back(10);
BOOST_CHECK_EQUAL( 1U , vector.size());
BOOST_CHECK_EQUAL( 10 , vector.get(0));

View File

@ -492,7 +492,7 @@ BOOST_AUTO_TEST_CASE(TestIOConfigCreationWithSolutionRPTRST) {
BOOST_CHECK_EQUAL(true , ioConfig->getWriteRestartFile(0));
BOOST_CHECK_EQUAL(false , ioConfig->getWriteRestartFile(1));
BOOST_CHECK_EQUAL(false , ioConfig->getWriteRestartFile(2));
BOOST_CHECK_EQUAL(true , ioConfig->getWriteRestartFile(3));
BOOST_CHECK_EQUAL(false , ioConfig->getWriteRestartFile(3));
}
@ -565,6 +565,7 @@ BOOST_AUTO_TEST_CASE(TestIOConfigCreationWithSolutionRPTSOL) {
IOConfigConstPtr ioConfig = state.getIOConfigConst();
BOOST_CHECK_EQUAL(true, ioConfig->getWriteRestartFile(0));
BOOST_CHECK_EQUAL(&parseMode , &(state.getParseMode()));
}
{ //old fashion integer mnemonics

View File

@ -12,3 +12,27 @@ foreach(tapp CheckDeckValidity IntegrationTests ParseWellProbe
opm_add_test(run${tapp} SOURCES ${tapp}.cpp
LIBRARIES opmparser ${Boost_LIBRARIES})
endforeach()
if (HAVE_OPM_DATA)
foreach( test_deck ${OPM_DATA_ROOT}/norne/NORNE_ATW2013.DATA
${OPM_DATA_ROOT}/solvent_test_suite/SPE1CASE2_SOLVENT.DATA
${OPM_DATA_ROOT}/solvent_test_suite/SPE9_CP_SOLVENT_CO2.DATA
${OPM_DATA_ROOT}/polymer_test_suite/simple2D/2D_THREEPHASE_POLY_HETER.DATA
${OPM_DATA_ROOT}/spe1/SPE1CASE1.DATA
${OPM_DATA_ROOT}/spe1/SPE1CASE2.DATA
${OPM_DATA_ROOT}/spe1/SPE1CASE2_FAMII.DATA
${OPM_DATA_ROOT}/spe1/SPE1CASE2_SLGOF.DATA
${OPM_DATA_ROOT}/spe3/SPE3CASE1.DATA
${OPM_DATA_ROOT}/spe3/SPE3CASE2.DATA
${OPM_DATA_ROOT}/spe9/SPE9_CP.DATA
${OPM_DATA_ROOT}/spe9/SPE9.DATA
${OPM_DATA_ROOT}/spe10model1/SPE10_MODEL1.DATA
${OPM_DATA_ROOT}/spe10model2/SPE10_MODEL2.DATA )
get_filename_component( test_name ${test_deck} NAME_WE )
add_test( NAME ${test_name} COMMAND OpmLoadDeck ${test_deck})
endforeach()
set_property(TEST NORNE_ATW2013 PROPERTY ENVIRONMENT "OPM_ERRORS_IGNORE=PARSE_RANDOM_SLASH")
endif()

View File

@ -34,6 +34,22 @@
using namespace Opm;
void verifyRestartConfig(IOConfigConstPtr ioconfig, std::vector<std::tuple<int , bool, boost::gregorian::date>>& rptConfig) {
for (auto rptrst : rptConfig) {
int report_step = std::get<0>(rptrst);
bool save = std::get<1>(rptrst);
boost::gregorian::date report_date = std::get<2>(rptrst);
BOOST_CHECK_EQUAL( save , ioconfig->getWriteRestartFile( report_step ));
if (save) {
BOOST_CHECK_EQUAL( report_date, ioconfig->getTimestepDate( report_step ));
}
std::cout << "step: " << report_step << " date: " << report_date << " : " << save << std::endl;
}
}
BOOST_AUTO_TEST_CASE( NorneResttartConfig ) {
std::vector<std::tuple<int , bool, boost::gregorian::date> > rptConfig;
@ -286,18 +302,7 @@ BOOST_AUTO_TEST_CASE( NorneResttartConfig ) {
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/RPTRST_DECK.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<const IOConfig> ioconfig = state.getIOConfigConst();
for (auto rptrst : rptConfig) {
int report_step = std::get<0>(rptrst);
bool save = std::get<1>(rptrst);
boost::gregorian::date report_date = std::get<2>(rptrst);
BOOST_CHECK_EQUAL( save , ioconfig->getWriteRestartFile( report_step ));
if (save) {
BOOST_CHECK_EQUAL( report_date, ioconfig->getTimestepDate( report_step ));
}
std::cout << "step: " << report_step << " date: " << report_date << " : " << save << std::endl;
}
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}
@ -342,19 +347,653 @@ BOOST_AUTO_TEST_CASE( RestartConfig2 ) {
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/RPT_TEST2.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<const IOConfig> ioconfig = state.getIOConfigConst();
for (auto rptrst : rptConfig) {
int report_step = std::get<0>(rptrst);
bool save = std::get<1>(rptrst);
boost::gregorian::date report_date = std::get<2>(rptrst);
BOOST_CHECK_EQUAL( save , ioconfig->getWriteRestartFile( report_step ));
if (save) {
BOOST_CHECK_EQUAL( report_date, ioconfig->getTimestepDate( report_step ));
}
std::cout << "step: " << report_step << " date: " << report_date << " : " << save << std::endl;
}
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}
//----------------- TESTS on SPE1CASE2 ---------------------------------------------------------------------
void fillRptConfig(std::vector<std::tuple<int, bool, boost::gregorian::date>>& rptConfig) {
rptConfig.push_back( std::make_tuple(0, false, boost::gregorian::date(2015,1,1)));
rptConfig.push_back( std::make_tuple(1, true, boost::gregorian::date(2015,2,1)));
rptConfig.push_back( std::make_tuple(2, true, boost::gregorian::date(2015,3,1)));
rptConfig.push_back( std::make_tuple(3, true, boost::gregorian::date(2015,4,1)));
rptConfig.push_back( std::make_tuple(4, true, boost::gregorian::date(2015,5,1)));
rptConfig.push_back( std::make_tuple(5, true, boost::gregorian::date(2015,6,1)));
rptConfig.push_back( std::make_tuple(6, true, boost::gregorian::date(2015,7,1)));
rptConfig.push_back( std::make_tuple(7, true, boost::gregorian::date(2015,8,1)));
rptConfig.push_back( std::make_tuple(8, true, boost::gregorian::date(2015,9,1)));
rptConfig.push_back( std::make_tuple(9, true, boost::gregorian::date(2015,10,1)));
rptConfig.push_back( std::make_tuple(10, true, boost::gregorian::date(2015,11,1)));
rptConfig.push_back( std::make_tuple(11, true, boost::gregorian::date(2015,12,1)));
rptConfig.push_back( std::make_tuple(12, true, boost::gregorian::date(2016,1,1)));
rptConfig.push_back( std::make_tuple(13, true, boost::gregorian::date(2016,2,1)));
rptConfig.push_back( std::make_tuple(14, false, boost::gregorian::date(2016,2,29)));
rptConfig.push_back( std::make_tuple(15, true, boost::gregorian::date(2016,3,31)));
rptConfig.push_back( std::make_tuple(16, true, boost::gregorian::date(2016,4,30)));
rptConfig.push_back( std::make_tuple(17, true, boost::gregorian::date(2016,5,31)));
rptConfig.push_back( std::make_tuple(18, true, boost::gregorian::date(2016,6,30)));
rptConfig.push_back( std::make_tuple(19, true, boost::gregorian::date(2016,7,31)));
rptConfig.push_back( std::make_tuple(20, true, boost::gregorian::date(2016,8,31)));
rptConfig.push_back( std::make_tuple(21, true, boost::gregorian::date(2016,9,30)));
rptConfig.push_back( std::make_tuple(22, true, boost::gregorian::date(2016,10,31)));
rptConfig.push_back( std::make_tuple(23, true, boost::gregorian::date(2016,11,30)));
rptConfig.push_back( std::make_tuple(24, true, boost::gregorian::date(2016,12,31)));
rptConfig.push_back( std::make_tuple(25, true, boost::gregorian::date(2017,1,31)));
rptConfig.push_back( std::make_tuple(26, true, boost::gregorian::date(2017,2,28)));
rptConfig.push_back( std::make_tuple(27, true, boost::gregorian::date(2017,3,31)));
rptConfig.push_back( std::make_tuple(28, true, boost::gregorian::date(2017,4,30)));
rptConfig.push_back( std::make_tuple(29, true, boost::gregorian::date(2017,5,31)));
rptConfig.push_back( std::make_tuple(30, true, boost::gregorian::date(2017,6,30)));
rptConfig.push_back( std::make_tuple(31, true, boost::gregorian::date(2017,7,31)));
rptConfig.push_back( std::make_tuple(32, true, boost::gregorian::date(2017,8,31)));
rptConfig.push_back( std::make_tuple(33, true, boost::gregorian::date(2017,9,30)));
rptConfig.push_back( std::make_tuple(34, true, boost::gregorian::date(2017,10,31)));
rptConfig.push_back( std::make_tuple(35, true, boost::gregorian::date(2017,11,30)));
rptConfig.push_back( std::make_tuple(36, true, boost::gregorian::date(2017,12,31)));
rptConfig.push_back( std::make_tuple(37, true, boost::gregorian::date(2018,1,31)));
rptConfig.push_back( std::make_tuple(38, true, boost::gregorian::date(2018,2,28)));
rptConfig.push_back( std::make_tuple(39, true, boost::gregorian::date(2018,3,31)));
rptConfig.push_back( std::make_tuple(40, true, boost::gregorian::date(2018,4,30)));
rptConfig.push_back( std::make_tuple(41, true, boost::gregorian::date(2018,5,31)));
rptConfig.push_back( std::make_tuple(42, true, boost::gregorian::date(2018,6,30)));
rptConfig.push_back( std::make_tuple(43, true, boost::gregorian::date(2018,7,31)));
rptConfig.push_back( std::make_tuple(44, true, boost::gregorian::date(2018,8,31)));
rptConfig.push_back( std::make_tuple(45, true, boost::gregorian::date(2018,9,30)));
rptConfig.push_back( std::make_tuple(46, true, boost::gregorian::date(2018,10,31)));
rptConfig.push_back( std::make_tuple(47, true, boost::gregorian::date(2018,11,30)));
rptConfig.push_back( std::make_tuple(48, true, boost::gregorian::date(2018,12,31)));
rptConfig.push_back( std::make_tuple(49, true, boost::gregorian::date(2019,1,31)));
rptConfig.push_back( std::make_tuple(50, true, boost::gregorian::date(2019,2,28)));
rptConfig.push_back( std::make_tuple(51, true, boost::gregorian::date(2019,3,31)));
rptConfig.push_back( std::make_tuple(52, true, boost::gregorian::date(2019,4,30)));
rptConfig.push_back( std::make_tuple(53, true, boost::gregorian::date(2019,5,31)));
rptConfig.push_back( std::make_tuple(54, true, boost::gregorian::date(2019,6,30)));
rptConfig.push_back( std::make_tuple(55, true, boost::gregorian::date(2019,7,31)));
rptConfig.push_back( std::make_tuple(56, true, boost::gregorian::date(2019,8,31)));
rptConfig.push_back( std::make_tuple(57, true, boost::gregorian::date(2019,9,30)));
rptConfig.push_back( std::make_tuple(58, true, boost::gregorian::date(2019,10,31)));
rptConfig.push_back( std::make_tuple(59, true, boost::gregorian::date(2019,11,30)));
rptConfig.push_back( std::make_tuple(60, true, boost::gregorian::date(2019,12,31)));
rptConfig.push_back( std::make_tuple(61, true, boost::gregorian::date(2020,1,31)));
rptConfig.push_back( std::make_tuple(62, true, boost::gregorian::date(2020,2,28)));
rptConfig.push_back( std::make_tuple(63, true, boost::gregorian::date(2020,3,30)));
rptConfig.push_back( std::make_tuple(64, true, boost::gregorian::date(2020,4,29)));
rptConfig.push_back( std::make_tuple(65, true, boost::gregorian::date(2020,5,30)));
rptConfig.push_back( std::make_tuple(66, true, boost::gregorian::date(2020,6,29)));
rptConfig.push_back( std::make_tuple(67, true, boost::gregorian::date(2020,7,30)));
rptConfig.push_back( std::make_tuple(68, true, boost::gregorian::date(2020,8,30)));
rptConfig.push_back( std::make_tuple(69, true, boost::gregorian::date(2020,9,29)));
rptConfig.push_back( std::make_tuple(70, true, boost::gregorian::date(2020,10,30)));
rptConfig.push_back( std::make_tuple(71, true, boost::gregorian::date(2020,11,29)));
rptConfig.push_back( std::make_tuple(72, true, boost::gregorian::date(2020,12,30)));
rptConfig.push_back( std::make_tuple(73, true, boost::gregorian::date(2021,1,30)));
rptConfig.push_back( std::make_tuple(74, true, boost::gregorian::date(2021,2,27)));
rptConfig.push_back( std::make_tuple(75, true, boost::gregorian::date(2021,3,30)));
rptConfig.push_back( std::make_tuple(76, true, boost::gregorian::date(2021,4,29)));
rptConfig.push_back( std::make_tuple(77, true, boost::gregorian::date(2021,5,30)));
rptConfig.push_back( std::make_tuple(78, true, boost::gregorian::date(2021,6,29)));
rptConfig.push_back( std::make_tuple(79, true, boost::gregorian::date(2021,7,30)));
rptConfig.push_back( std::make_tuple(80, true, boost::gregorian::date(2021,8,30)));
rptConfig.push_back( std::make_tuple(81, true, boost::gregorian::date(2021,9,29)));
rptConfig.push_back( std::make_tuple(82, true, boost::gregorian::date(2021,10,30)));
rptConfig.push_back( std::make_tuple(83, true, boost::gregorian::date(2021,11,29)));
rptConfig.push_back( std::make_tuple(84, true, boost::gregorian::date(2021,12,30)));
rptConfig.push_back( std::make_tuple(85, true, boost::gregorian::date(2022,1,30)));
rptConfig.push_back( std::make_tuple(86, true, boost::gregorian::date(2022,2,27)));
rptConfig.push_back( std::make_tuple(87, true, boost::gregorian::date(2022,3,30)));
rptConfig.push_back( std::make_tuple(88, true, boost::gregorian::date(2022,4,29)));
rptConfig.push_back( std::make_tuple(89, true, boost::gregorian::date(2022,5,30)));
rptConfig.push_back( std::make_tuple(90, true, boost::gregorian::date(2022,6,29)));
rptConfig.push_back( std::make_tuple(91, true, boost::gregorian::date(2022,7,30)));
rptConfig.push_back( std::make_tuple(92, true, boost::gregorian::date(2022,8,30)));
rptConfig.push_back( std::make_tuple(93, true, boost::gregorian::date(2022,9,29)));
rptConfig.push_back( std::make_tuple(94, true, boost::gregorian::date(2022,10,30)));
rptConfig.push_back( std::make_tuple(95, true, boost::gregorian::date(2022,11,29)));
rptConfig.push_back( std::make_tuple(96, true, boost::gregorian::date(2022,12,30)));
rptConfig.push_back( std::make_tuple(97, true, boost::gregorian::date(2023,1,30)));
rptConfig.push_back( std::make_tuple(98, true, boost::gregorian::date(2023,2,27)));
rptConfig.push_back( std::make_tuple(99, true, boost::gregorian::date(2023,3,30)));
rptConfig.push_back( std::make_tuple(100, true, boost::gregorian::date(2023,4,29)));
rptConfig.push_back( std::make_tuple(101, true, boost::gregorian::date(2023,5,30)));
rptConfig.push_back( std::make_tuple(102, true, boost::gregorian::date(2023,6,29)));
rptConfig.push_back( std::make_tuple(103, true, boost::gregorian::date(2023,7,30)));
rptConfig.push_back( std::make_tuple(104, true, boost::gregorian::date(2023,8,30)));
rptConfig.push_back( std::make_tuple(105, true, boost::gregorian::date(2023,9,29)));
rptConfig.push_back( std::make_tuple(106, true, boost::gregorian::date(2023,10,30)));
rptConfig.push_back( std::make_tuple(107, true, boost::gregorian::date(2023,11,29)));
rptConfig.push_back( std::make_tuple(108, true, boost::gregorian::date(2023,12,30)));
rptConfig.push_back( std::make_tuple(109, true, boost::gregorian::date(2024,1,30)));
rptConfig.push_back( std::make_tuple(110, true, boost::gregorian::date(2024,2,27)));
rptConfig.push_back( std::make_tuple(111, true, boost::gregorian::date(2024,3,29)));
rptConfig.push_back( std::make_tuple(112, true, boost::gregorian::date(2024,4,28)));
rptConfig.push_back( std::make_tuple(113, true, boost::gregorian::date(2024,5,29)));
rptConfig.push_back( std::make_tuple(114, true, boost::gregorian::date(2024,6,28)));
rptConfig.push_back( std::make_tuple(115, true, boost::gregorian::date(2024,7,29)));
rptConfig.push_back( std::make_tuple(116, true, boost::gregorian::date(2024,8,29)));
rptConfig.push_back( std::make_tuple(117, true, boost::gregorian::date(2024,9,28)));
rptConfig.push_back( std::make_tuple(118, true, boost::gregorian::date(2024,10,29)));
rptConfig.push_back( std::make_tuple(119, true, boost::gregorian::date(2024,11,28)));
rptConfig.push_back( std::make_tuple(120, true, boost::gregorian::date(2024,12,29)));
}
BOOST_AUTO_TEST_CASE( SPE1CASE2_BASIC5_SET_ON_TIMESTEP_1 ) {
//Write reportfile every first day of a month
ParseMode parseMode;
ParserPtr parser(new Parser());
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/SPE1CASE2.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<IOConfig> ioconfig = state.getIOConfig();
int basic = 5;
TimeMapConstPtr timemap = state.getSchedule()->getTimeMap();
ioconfig->handleRPTRSTBasic(timemap,
1,
basic);
std::vector<std::tuple<int, bool, boost::gregorian::date>> rptConfig;
fillRptConfig(rptConfig);
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}
BOOST_AUTO_TEST_CASE( SPE1CASE2_BASIC5_SET_ON_TIMESTEP_13 ) {
//Write reportfile every first day of a month
ParseMode parseMode;
ParserPtr parser(new Parser());
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/SPE1CASE2.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<IOConfig> ioconfig = state.getIOConfig();
int basic = 5;
TimeMapConstPtr timemap = state.getSchedule()->getTimeMap();
ioconfig->handleRPTRSTBasic(timemap,
13,
basic);
// Expecting same results as Eclipse:
// Report steps 13 (1 Feb 2016) - 120 (29 Dec 2024) should be written,
// except for step 14!
std::vector<std::tuple<int, bool, boost::gregorian::date>> rptConfig;
fillRptConfig(rptConfig);
for (size_t reportstep = 1; reportstep <= 12; ++reportstep) {
std::get<1>(rptConfig[reportstep]) = false;
}
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}
BOOST_AUTO_TEST_CASE( SPE1CASE2_BASIC5_SET_ON_TIMESTEP_14 ) {
//Write reportfile every first day of a month
ParseMode parseMode;
ParserPtr parser(new Parser());
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/SPE1CASE2.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<IOConfig> ioconfig = state.getIOConfig();
int basic = 5;
TimeMapConstPtr timemap = state.getSchedule()->getTimeMap();
ioconfig->handleRPTRSTBasic(timemap,
14,
basic);
// Expecting same results as Eclipse:
// Report steps 15 (31 Mars 2016) - 120 (29 Dec 2024) should be written
std::vector<std::tuple<int, bool, boost::gregorian::date>> rptConfig;
fillRptConfig(rptConfig);
for (size_t reportstep = 1; reportstep <= 14; ++reportstep) {
std::get<1>(rptConfig[reportstep]) = false;
}
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}
BOOST_AUTO_TEST_CASE( SPE1CASE2_BASIC5_SET_ON_TIMESTEP_37 ) {
//Write reportfile every first day of a month
ParseMode parseMode;
ParserPtr parser(new Parser());
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/SPE1CASE2.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<IOConfig> ioconfig = state.getIOConfig();
int basic = 5;
TimeMapConstPtr timemap = state.getSchedule()->getTimeMap();
ioconfig->handleRPTRSTBasic(timemap,
37,
basic);
// Expecting same results as Eclipse:
// Report steps 37 (31 Jan 2018) - 120 (29 Dec 2024) should be written
std::vector<std::tuple<int, bool, boost::gregorian::date>> rptConfig;
fillRptConfig(rptConfig);
for (size_t reportstep = 1; reportstep <= 36; ++reportstep) {
std::get<1>(rptConfig[reportstep]) = false;
}
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}
BOOST_AUTO_TEST_CASE( SPE1CASE2_BASIC5_FREQ10_SET_ON_TIMESTEP_10 ) {
//Write reportfile every first day of each month, with frequency 10
std::vector<std::tuple<int, bool, boost::gregorian::date>> rptConfig;
for (size_t reportstep = 0; reportstep <= 120; ++reportstep) {
if (20 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2016,8,31)));
} else if (30 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2017,6,30)));
} else if (40 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2018,4,30)));
} else if (50 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2019,2,28)));
} else if (60 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2019,12,31)));
} else if (70 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2020,10,30)));
} else if (80 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2021,8,30)));
} else if (90 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2022,6,29)));
} else if (100 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2023,4,29)));
} else if (110 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2024,2,27)));
} else if (120 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2024,12,29)));
} else {
rptConfig.push_back( std::make_tuple(reportstep, false, boost::gregorian::date(2015,1,1)));
}
}
ParseMode parseMode;
ParserPtr parser(new Parser());
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/SPE1CASE2.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<IOConfig> ioconfig = state.getIOConfig();
int basic = 5;
int freq = 10;
ioconfig->handleRPTRSTBasic(state.getSchedule()->getTimeMap(),
10,
basic,
freq);
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}
BOOST_AUTO_TEST_CASE( SPE1CASE2_BASIC5_FREQ40_SET_ON_TIMESTEP_1 ) {
std::vector<std::tuple<int, bool, boost::gregorian::date>> rptConfig;
for (size_t reportstep = 0; reportstep <= 120; ++reportstep) {
if (0 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, false, boost::gregorian::date(2015,1,1)));
} else if (41 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2018,5,31)));
} else if (81 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2021,9,29)));
} else {
rptConfig.push_back( std::make_tuple(reportstep, false, boost::gregorian::date(2015,1,1)));
}
}
ParseMode parseMode;
ParserPtr parser(new Parser());
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/SPE1CASE2.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<IOConfig> ioconfig = state.getIOConfig();
int basic = 5;
int freq = 40;
ioconfig->handleRPTRSTBasic(state.getSchedule()->getTimeMap(),
1,
basic,
freq);
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}
BOOST_AUTO_TEST_CASE( SPE1CASE2_BASIC5_FREQ40_SET_ON_TIMESTEP_14 ) {
//Write reportfile every first day of a month, with frequency 40
ParseMode parseMode;
ParserPtr parser(new Parser());
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/SPE1CASE2.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<IOConfig> ioconfig = state.getIOConfig();
int basic = 5;
int freq = 40;
TimeMapConstPtr timemap = state.getSchedule()->getTimeMap();
ioconfig->handleRPTRSTBasic(timemap,
14,
basic,
freq);
// Expecting same results as Eclipse:
// Report steps 54 and 94 should be written
std::vector<std::tuple<int, bool, boost::gregorian::date>> rptConfig;
for (size_t reportstep = 0; reportstep <= 120; ++reportstep) {
if (54 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2019,6,30)));
} else if (94 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2022,10,30)));
} else {
rptConfig.push_back( std::make_tuple(reportstep, false, boost::gregorian::date(2015,1,1)));
}
}
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}
BOOST_AUTO_TEST_CASE( SPE1CASE2_BASIC4_SET_ON_TIMESTEP_1 ) {
//Write reportfile every first day of each year
std::vector<std::tuple<int, bool, boost::gregorian::date>> rptConfig;
for (size_t reportstep = 0; reportstep <= 120; ++reportstep) {
if (12 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2016,1,1)));
} else if (25 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2017,1,31)));
} else if (37 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2018,1,31)));
} else if (49 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2019,1,31)));
} else if (61 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2020,1,31)));
} else if (73 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2021,1,30)));
} else if (85 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2022,1,30)));
} else if (97 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2023,1,30)));
} else if (109 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2024,1,30)));
} else {
rptConfig.push_back( std::make_tuple(reportstep, false, boost::gregorian::date(2015,1,1)));
}
}
ParseMode parseMode;
ParserPtr parser(new Parser());
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/SPE1CASE2.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<IOConfig> ioconfig = state.getIOConfig();
int basic = 4;
ioconfig->handleRPTRSTBasic(state.getSchedule()->getTimeMap(),
1,
basic);
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}
BOOST_AUTO_TEST_CASE( SPE1CASE2_BASIC4_SET_ON_TIMESTEP_12 ) {
//Write reportfile every first day of each year
std::vector<std::tuple<int, bool, boost::gregorian::date>> rptConfig;
for (size_t reportstep = 0; reportstep <= 120; ++reportstep) {
if (12 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2016,1,1)));
} else if (25 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2017,1,31)));
} else if (37 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2018,1,31)));
} else if (49 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2019,1,31)));
} else if (61 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2020,1,31)));
} else if (73 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2021,1,30)));
} else if (85 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2022,1,30)));
} else if (97 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2023,1,30)));
} else if (109 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2024,1,30)));
} else {
rptConfig.push_back( std::make_tuple(reportstep, false, boost::gregorian::date(2015,1,1)));
}
}
ParseMode parseMode;
ParserPtr parser(new Parser());
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/SPE1CASE2.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<IOConfig> ioconfig = state.getIOConfig();
int basic = 4;
ioconfig->handleRPTRSTBasic(state.getSchedule()->getTimeMap(),
12,
basic);
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}
BOOST_AUTO_TEST_CASE( SPE1CASE2_BASIC4_SET_ON_TIMESTEP_13 ) {
//Write reportfile every first day of each year
std::vector<std::tuple<int, bool, boost::gregorian::date>> rptConfig;
for (size_t reportstep = 0; reportstep <= 120; ++reportstep) {
if (25 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2017,1,31)));
} else if (37 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2018,1,31)));
} else if (49 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2019,1,31)));
} else if (61 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2020,1,31)));
} else if (73 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2021,1,30)));
} else if (85 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2022,1,30)));
} else if (97 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2023,1,30)));
} else if (109 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2024,1,30)));
} else {
rptConfig.push_back( std::make_tuple(reportstep, false, boost::gregorian::date(2015,1,1)));
}
}
ParseMode parseMode;
ParserPtr parser(new Parser());
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/SPE1CASE2.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<IOConfig> ioconfig = state.getIOConfig();
int basic = 4;
ioconfig->handleRPTRSTBasic(state.getSchedule()->getTimeMap(),
13,
basic);
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}
BOOST_AUTO_TEST_CASE( SPE1CASE2_BASIC4_FREQ3_SET_ON_TIMESTEP_13 ) {
//Write reportfile every first day of each year
std::vector<std::tuple<int, bool, boost::gregorian::date>> rptConfig;
for (size_t reportstep = 0; reportstep <= 120; ++reportstep) {
if (49 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2019,1,31)));
} else if (85 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2022,1,30)));
} else {
rptConfig.push_back( std::make_tuple(reportstep, false, boost::gregorian::date(2015,1,1)));
}
}
ParseMode parseMode;
ParserPtr parser(new Parser());
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/SPE1CASE2.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<IOConfig> ioconfig = state.getIOConfig();
int basic = 4;
int freq = 3;
ioconfig->handleRPTRSTBasic(state.getSchedule()->getTimeMap(),
13,
basic,
freq);
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}
BOOST_AUTO_TEST_CASE( SPE1CASE2_BASIC3_FREQ5_SET_ON_TIMESTEP_11 ) {
//Write reportfile every first day of each year
std::vector<std::tuple<int, bool, boost::gregorian::date>> rptConfig;
for (size_t reportstep = 0; reportstep <= 120; ++reportstep) {
if (15 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2016,3,31)));
} else if (20 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2016,8,31)));
} else if (25 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2017,1,31)));
} else if (30 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2017,6,30)));
} else if (35 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2017,11,30)));
} else if (40 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2018,4,30)));
} else if (45 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2018,9,30)));
} else if (50 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2019,2,28)));
} else if (55 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2019,7,31)));
} else if (60 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2019,12,31)));
} else if (65 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2020,5,30)));
} else if (70 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2020,10,30)));
} else if (75 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2021,3,30)));
} else if (80 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2021,8,30)));
} else if (85 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2022,1,30)));
} else if (90 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2022,6,29)));
} else if (95 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2022,11,29)));
} else if (100 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2023,4,29)));
} else if (105 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2023,9,29)));
} else if (110 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2024,2,27)));
} else if (115 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2024,7,29)));
} else if (120 == reportstep) {
rptConfig.push_back( std::make_tuple(reportstep, true, boost::gregorian::date(2024,12,29)));
} else {
rptConfig.push_back( std::make_tuple(reportstep, false, boost::gregorian::date(2015,1,1)));
}
}
ParseMode parseMode;
ParserPtr parser(new Parser());
DeckConstPtr deck = parser->parseFile("testdata/integration_tests/IOConfig/SPE1CASE2.DATA", parseMode);
EclipseState state( deck , parseMode );
std::shared_ptr<IOConfig> ioconfig = state.getIOConfig();
int basic = 3;
int freq = 5;
ioconfig->handleRPTRSTBasic(state.getSchedule()->getTimeMap(),
11,
basic,
freq);
verifyRestartConfig(state.getIOConfigConst(), rptConfig);
}

View File

@ -63,6 +63,7 @@ namespace Opm {
addKey(PARSE_RANDOM_TEXT);
addKey(PARSE_RANDOM_SLASH);
addKey(PARSE_MISSING_DIMS_KEYWORD);
addKey(PARSE_EXTRA_DATA);
addKey(UNSUPPORTED_SCHEDULE_GEO_MODIFIER);
addKey(UNSUPPORTED_COMPORD_TYPE);
addKey(UNSUPPORTED_INITIAL_THPRES);
@ -207,11 +208,12 @@ namespace Opm {
const std::string ParseMode::PARSE_RANDOM_TEXT = "PARSE_RANDOM_TEXT";
const std::string ParseMode::PARSE_RANDOM_SLASH = "PARSE_RANDOM_SLASH";
const std::string ParseMode::PARSE_MISSING_DIMS_KEYWORD = "PARSE_MISSING_DIMS_KEYWORD";
const std::string ParseMode::PARSE_EXTRA_DATA = "PARSE_EXTRA_DATA";
const std::string ParseMode::UNSUPPORTED_SCHEDULE_GEO_MODIFIER = "UNSUPPORTED_SCHEDULE_GEO_MODIFIER";
const std::string ParseMode::UNSUPPORTED_COMPORD_TYPE = "UNSUPPORTED_COMPORD_TYPE";
const std::string ParseMode::UNSUPPORTED_INITIAL_THPRES = "UNSUPPORTED_INITIAL_THPRES";
const std::string ParseMode::INTERNAL_ERROR_UNINITIALIZED_THPRES = "INTERNAL_ERROR_UNINITIALIZED_THPRES";
}

View File

@ -148,6 +148,16 @@ namespace Opm {
*/
const static std::string PARSE_MISSING_DIMS_KEYWORD;
/*
If the number of elements in the input record exceeds the
number of items in the keyword configuration this error
situation will be triggered. Many keywords end with several
ECLIPSE300 only items - in some cases we have omitted those
items in the Json configuration; that will typically trigger
this error situation when encountering an ECLIPSE300 deck.
*/
const static std::string PARSE_EXTRA_DATA;
/*
Some property modfiers can be modified in the Schedule
section; this effectively means that Eclipse supports time

View File

@ -376,7 +376,7 @@ namespace Opm {
if (isRecognizedKeyword(parserState->rawKeyword->getKeywordName())) {
ParserKeywordConstPtr parserKeyword = getParserKeywordFromDeckName(parserState->rawKeyword->getKeywordName());
DeckKeywordPtr deckKeyword = parserKeyword->parse(parserState->rawKeyword);
DeckKeywordPtr deckKeyword = parserKeyword->parse(parserState->parseMode , parserState->rawKeyword);
deckKeyword->setParserKeyword(parserKeyword);
parserState->deck->addKeyword(deckKeyword);
} else {

View File

@ -524,7 +524,7 @@ namespace Opm {
return m_deckNames.end();
}
DeckKeywordPtr ParserKeyword::parse(RawKeywordConstPtr rawKeyword) const {
DeckKeywordPtr ParserKeyword::parse(const ParseMode& parseMode , RawKeywordConstPtr rawKeyword) const {
if (rawKeyword->isFinished()) {
DeckKeywordPtr keyword(new DeckKeyword(rawKeyword->getKeywordName()));
keyword->setLocation(rawKeyword->getFilename(), rawKeyword->getLineNR());
@ -534,7 +534,7 @@ namespace Opm {
auto rawRecord = rawKeyword->getRecord(i);
if(m_records.size() > 0) {
std::shared_ptr <ParserRecord> record = getRecord(i);
DeckRecordConstPtr deckRecord = record->parse(rawRecord);
DeckRecordConstPtr deckRecord = record->parse(parseMode , rawRecord);
keyword->addRecord(deckRecord);
}
else {

View File

@ -36,11 +36,12 @@
#include <opm/parser/eclipse/Parser/ParserDoubleItem.hpp>
#include <opm/parser/eclipse/Parser/ParserFloatItem.hpp>
#include <opm/parser/eclipse/Parser/ParserEnums.hpp>
#include <opm/parser/eclipse/Parser/ParseMode.hpp>
#include <opm/parser/eclipse/RawDeck/RawKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/Util/ElasticVector.hpp>
#include <opm/parser/eclipse/EclipseState/Util/RecordVector.hpp>
namespace Opm {
@ -99,7 +100,7 @@ namespace Opm {
SectionNameSet::const_iterator validSectionNamesBegin() const;
SectionNameSet::const_iterator validSectionNamesEnd() const;
DeckKeywordPtr parse(RawKeywordConstPtr rawKeyword) const;
DeckKeywordPtr parse(const ParseMode& parseMode , RawKeywordConstPtr rawKeyword) const;
enum ParserKeywordSizeEnum getSizeType() const;
const std::pair<std::string,std::string>& getSizeDefinitionPair() const;
bool isDataKeyword() const;
@ -120,7 +121,7 @@ namespace Opm {
#else
boost::regex m_matchRegex;
#endif
ElasticVector<ParserRecordPtr> m_records;
RecordVector<ParserRecordPtr> m_records;
enum ParserKeywordSizeEnum m_keywordSizeType;
size_t m_fixedSize;
bool m_isTableCollection;

View File

@ -18,6 +18,7 @@
*/
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/ParseMode.hpp>
#include <opm/parser/eclipse/Parser/ParserRecord.hpp>
#include <opm/parser/eclipse/Parser/ParserItem.hpp>
@ -113,7 +114,7 @@ namespace Opm {
}
}
DeckRecordConstPtr ParserRecord::parse(RawRecordPtr rawRecord) const {
DeckRecordConstPtr ParserRecord::parse(const ParseMode& parseMode , RawRecordPtr rawRecord) const {
std::string recordBeforeParsing = rawRecord->getRecordString();
DeckRecordPtr deckRecord(new DeckRecord());
for (size_t i = 0; i < size(); i++) {
@ -121,11 +122,13 @@ namespace Opm {
DeckItemPtr deckItem = parserItem->scan(rawRecord);
deckRecord->addItem(deckItem);
}
const size_t recordSize = rawRecord->size();
if (recordSize > 0)
throw std::invalid_argument("The RawRecord for keyword \"" + rawRecord->getKeywordName() + "\" in file\"" + rawRecord->getFileName() + "\" contained " +
boost::lexical_cast<std::string>(recordSize) +
" too many items according to the spec. RawRecord was: " + recordBeforeParsing);
if (rawRecord->size() > 0) {
std::string msg = "The RawRecord for keyword \"" + rawRecord->getKeywordName() + "\" in file\"" + rawRecord->getFileName() + "\" contained " +
std::to_string(rawRecord->size()) +
" too many items according to the spec. RawRecord was: " + recordBeforeParsing;
parseMode.handleError(ParseMode::PARSE_EXTRA_DATA , msg);
}
return deckRecord;
}

View File

@ -26,6 +26,7 @@
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/ParserItem.hpp>
#include <opm/parser/eclipse/Parser/ParseMode.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
@ -39,7 +40,7 @@ namespace Opm {
void addDataItem(ParserItemConstPtr item);
ParserItemConstPtr get(size_t index) const;
ParserItemConstPtr get(const std::string& itemName) const;
DeckRecordConstPtr parse(RawRecordPtr rawRecord) const;
DeckRecordConstPtr parse(const ParseMode& parseMode , RawRecordPtr rawRecord) const;
bool isDataRecord() const;
bool equal(const ParserRecord& other) const;
bool hasDimension() const;

View File

@ -249,3 +249,23 @@ BOOST_AUTO_TEST_CASE( test_constructor_with_values) {
BOOST_CHECK_EQUAL( parseMode.get(ParseMode::UNSUPPORTED_INITIAL_THPRES) , InputError::WARN );
BOOST_CHECK_EQUAL( parseMode.get(ParseMode::UNSUPPORTED_COMPORD_TYPE) , InputError::WARN );
}
BOOST_AUTO_TEST_CASE( test_too_much_data ) {
const char * deckString =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 10 /n"
"\n";
ParseMode parseMode;
Parser parser;
parseMode.update(ParseMode::PARSE_EXTRA_DATA , InputError::THROW_EXCEPTION );
BOOST_CHECK_THROW( parser.parseString( deckString , parseMode ) , std::invalid_argument);
parseMode.update(ParseMode::PARSE_EXTRA_DATA , InputError::IGNORE );
auto deck = parser.parseString( deckString , parseMode );
}

View File

@ -393,13 +393,14 @@ BOOST_AUTO_TEST_CASE(ParseEmptyRecord) {
std::shared_ptr<ParserRecord> record = std::make_shared<ParserRecord>();
ParserIntItemConstPtr item(new ParserIntItem(std::string("ITEM") , ALL));
RawKeywordPtr rawkeyword(new RawKeyword( tabdimsKeyword->getName() , "FILE" , 10U , 1));
ParseMode parseMode;
BOOST_CHECK_EQUAL( Raw::FIXED , rawkeyword->getSizeType());
rawkeyword->addRawRecordString("/");
record->addItem(item);
tabdimsKeyword->addRecord( record );
DeckKeywordConstPtr deckKeyword = tabdimsKeyword->parse( rawkeyword );
DeckKeywordConstPtr deckKeyword = tabdimsKeyword->parse( parseMode , rawkeyword );
BOOST_REQUIRE_EQUAL( 1U , deckKeyword->size());
DeckRecordConstPtr deckRecord = deckKeyword->getRecord(0);

View File

@ -21,6 +21,7 @@
#define BOOST_TEST_MODULE ParserTests
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/Parser/ParseMode.hpp>
#include <opm/parser/eclipse/Parser/ParserEnums.hpp>
#include <opm/parser/eclipse/Parser/ParserRecord.hpp>
#include <opm/parser/eclipse/Parser/ParserItem.hpp>
@ -126,14 +127,16 @@ static ParserRecordPtr createSimpleParserRecord() {
BOOST_AUTO_TEST_CASE(parse_validRecord_noThrow) {
ParserRecordPtr record = createSimpleParserRecord();
RawRecordPtr rawRecord(new RawRecord("100 443 /"));
ParseMode parseMode;
rawRecord->dump();
BOOST_CHECK_NO_THROW(record->parse(rawRecord));
BOOST_CHECK_NO_THROW(record->parse(parseMode , rawRecord));
}
BOOST_AUTO_TEST_CASE(parse_validRecord_deckRecordCreated) {
ParserRecordPtr record = createSimpleParserRecord();
RawRecordPtr rawRecord(new RawRecord("100 443 /"));
DeckRecordConstPtr deckRecord = record->parse(rawRecord);
ParseMode parseMode;
DeckRecordConstPtr deckRecord = record->parse(parseMode , rawRecord);
BOOST_CHECK_EQUAL(2U, deckRecord->size());
}
@ -165,7 +168,8 @@ static ParserRecordPtr createMixedParserRecord() {
BOOST_AUTO_TEST_CASE(parse_validMixedRecord_noThrow) {
ParserRecordPtr record = createMixedParserRecord();
RawRecordPtr rawRecord(new RawRecord("1 2 10.0 20.0 4 90.0 /"));
BOOST_CHECK_NO_THROW(record->parse(rawRecord));
ParseMode parseMode;
BOOST_CHECK_NO_THROW(record->parse(parseMode , rawRecord));
}
BOOST_AUTO_TEST_CASE(Equal_Equal_ReturnsTrue) {
@ -297,6 +301,7 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooManyItems_Throws) {
ParserIntItemConstPtr itemI(new ParserIntItem("I", SINGLE));
ParserIntItemConstPtr itemJ(new ParserIntItem("J", SINGLE));
ParserIntItemConstPtr itemK(new ParserIntItem("K", SINGLE));
ParseMode parseMode;
parserRecord->addItem(itemI);
parserRecord->addItem(itemJ);
@ -304,13 +309,13 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooManyItems_Throws) {
RawRecordPtr rawRecord(new RawRecord("3 3 3 /"));
BOOST_CHECK_NO_THROW(parserRecord->parse(rawRecord));
BOOST_CHECK_NO_THROW(parserRecord->parse(parseMode , rawRecord));
RawRecordPtr rawRecordOneExtra(new RawRecord("3 3 3 4 /"));
BOOST_CHECK_THROW(parserRecord->parse(rawRecordOneExtra), std::invalid_argument);
BOOST_CHECK_THROW(parserRecord->parse(parseMode , rawRecordOneExtra), std::invalid_argument);
RawRecordPtr rawRecordForgotRecordTerminator(new RawRecord("3 3 3 \n 4 4 4 /"));
BOOST_CHECK_THROW(parserRecord->parse(rawRecordForgotRecordTerminator), std::invalid_argument);
BOOST_CHECK_THROW(parserRecord->parse(parseMode , rawRecordForgotRecordTerminator), std::invalid_argument);
}
@ -325,11 +330,13 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooFewItems) {
parserRecord->addItem(itemJ);
parserRecord->addItem(itemK);
ParseMode parseMode;
RawRecordPtr rawRecord(new RawRecord("3 3 /"));
// no default specified for the third item, record can be parsed just fine but trying
// to access the data will raise an exception...
DeckRecordConstPtr record;
BOOST_CHECK_NO_THROW(record = parserRecord->parse(rawRecord));
BOOST_CHECK_NO_THROW(record = parserRecord->parse(parseMode , rawRecord));
BOOST_CHECK_NO_THROW(record->getItem(2));
BOOST_CHECK_THROW(record->getItem(2)->getInt(0), std::out_of_range);
}

View File

@ -1,9 +1,9 @@
{
"name" : "CONNECTION_PROBE",
"sections" : ["SUMMARY"],
"comment": "E100 only",
"deck_names" : [
"comment" : "See comment in CPR keyword file - there is some serious special casing involved here",
"deck_names" : [
"COFR",
"COFRF",
"COFRS",
@ -72,7 +72,6 @@
"CWGRL",
"CGLR",
"CGLRL",
"CPR",
"CPI",
"CTFAC",
"CDBF",
@ -127,7 +126,11 @@
"comment":"Some keywords need to be suffixed by a tracer name...",
"deck_name_regex":"CU.+|CTFR.+|CTPR.+|CTPT.+|CTPC.+|CTIR.+|CTIT.+|CTIC.+|CTFR.+|CTPR.+|CTPT.+|CTPC.+|CTIR.+|CTIT.+|CTIC.+|CTIRF.+|CTIRS.+|CTPRF.+|CTPRS.+|CTITF.+|CTITS.+|CTPTF.+|CTPTS.+|CTICF.+|CTICS.+|CTPCF.+|CTPCS",
"items" : [{
"name" : "MNEMONIC_LIST" , "size_type" : "ALL" , "value_type" : "STRING"
}]
"items" : [
{"name" : "WELL" , "value_type" : "STRING"},
{"name" : "I" , "value_type" : "INT"},
{"name" : "J" , "value_type" : "INT"},
{"name" : "K" , "value_type" : "INT"}
]
}

View File

@ -1,2 +1,14 @@
{"name" : "CPR" , "sections" : ["RUNSPEC"], "size": 1 }
{"name" : "CPR" ,
"items" : [
{"name" : "WELL" , "value_type" : "STRING"},
{"name" : "I" , "value_type" : "INT"},
{"name" : "J" , "value_type" : "INT"},
{"name" : "K" , "value_type" : "INT"}],
"sections" : ["RUNSPEC" , "SUMMARY"],
"comment" : "The CPR keyword can occur both in the RUNSPEC section and in the SUMMARY section",
"comment" : "the meaning of the keyword is completely different in the sections, but we just barely",
"comment" : "manage to get away by using the same configuration for both sections. When occuring",
"comment" : "in the RUNSPEC section the keyword should have exactly one-empty-record - that is enforced",
"comment" : "in the SimulationConfig() constructor"}

View File

@ -0,0 +1 @@
{"name" : "OLDTRAN", "sections" : ["GRID"]}

View File

@ -5,6 +5,24 @@
{"name" : "NPPVT" , "value_type" : "INT" , "default" : 20},
{"name" : "NTFIP" , "value_type" : "INT" , "default" : 1},
{"name" : "NRPVT" , "value_type" : "INT" , "default" : 20},
{"name" : "MAX_RV_NODES" , "value_type" : "INT"},
{"name" : "NTENDP" , "value_type" : "INT" , "default" : 1, "comment" : "This item is ECLIPSE300 specific"},
{"name" : "NUM_STATE_EQ" , "value_type" : "INT" , "default" : 1, "comment" : "This item is ECLIPSE300 specific"}
{"name" : "NUM_STATE_EQ" , "value_type" : "INT" , "default" : 1, "comment" : "This item is ECLIPSE300 specific"},
{"name" : "NUM_EOS_RES" , "value_type" : "INT" , "default" : 1},
{"name" : "NUM_EOS_SURFACE" , "value_type" : "INT"},
{"name" : "MAX_FLUX_REGIONS" , "value_type" : "INT" , "default" : 10},
{"name" : "MAX_THERMAL_REGIONS" , "value_type" : "INT" , "default" : 1},
{"name" : "NTROCC" , "value_type" : "INT"},
{"name" : "MAX_PRESSURE_MAINTAINANCE_REGIONS" , "value_type" : "INT" , "default" : 0},
{"name" : "MAX_KVALUE_TABLES" , "value_type" : "INT" , "default" : 0},
{"name" : "NTALPHA" , "value_type" : "INT"},
{"name" : "ASPHALTENE_ASPKDAM_MAX_ROWS" , "value_type" : "INT" , "default" : 10},
{"name" : "ASPHALTENE_ASPREWG_MAX_ROWS" , "value_type" : "INT" , "default" : 10},
{"name" : "ASPHALTENE_ASPVISO_MAX_ROWS" , "value_type" : "INT" , "default" : 10},
{"name" : "ITEM20_NOT_USED" , "value_type" : "STRING"},
{"name" : "ASPHALTENE_ASPPW2D_MAX_COLUMNS" , "value_type" : "INT" , "default" : 5},
{"name" : "ASPHALTENE_ASPPW2D_MAX_ROWS" , "value_type" : "INT" , "default" : 5},
{"name" : "ASPHALTENE_ASPWETF_MAX_ROWS" , "value_type" : "INT" , "default" : 5},
{"name" : "NUM_KVALUE_TABLES" , "value_type" : "INT" , "default" : 0},
{"name" : "RESERVED" , "value_type" : "STRING" }
]}

View File

@ -0,0 +1,156 @@
-- 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
-- -------------------------------------------------------------------------
RPTSCHED
'PRES' 'SGAS' 'RS' 'WELLS' /
-- If no resolution (i.e. case 1), the two following lines must be added:
--DRSDT
-- 0 /
-- Since this is Case 2, the two lines above have been commented out.
-- if DRSDT is set to 0, GOR cannot rise and free gas does not
-- dissolve in undersaturated oil -> constant bubble point pressure
WELSPECS
-- Item #: 1 2 3 4 5 6
'PROD' 'G1' 10 10 8400 'OIL' /
'INJ' 'G1' 1 1 8335 'GAS' /
/
-- Coordinates in item 3-4 are retrieved from Odeh's figure 1 and 2
-- Note that the depth at the midpoint of the well grid blocks
-- has been used as reference depth for bottom hole pressure in item 5
COMPDAT
-- Item #: 1 2 3 4 5 6 7 8 9
'PROD' 10 10 3 3 'OPEN' 1* 1* 0.5 /
'INJ' 1 1 1 1 'OPEN' 1* 1* 0.5 /
/
-- Coordinates in item 2-5 are retreived from Odeh's figure 1 and 2
-- Item 9 is the well bore internal diameter,
-- the radius is given to be 0.25ft in Odeh's paper
WCONPROD
-- Item #:1 2 3 4 5 9
'PROD' 'OPEN' 'ORAT' 20000 4* 1000 /
/
-- It is stated in Odeh's paper that the maximum oil prod. rate
-- is 20 000stb per day which explains the choice of value in item 4.
-- The items > 4 are defaulted with the exception of item 9,
-- the BHP lower limit, which is given to be 1000psia in Odeh's paper
WCONINJE
-- Item #:1 2 3 4 5 6 7
'INJ' 'GAS' 'OPEN' 'RATE' 100000 1* 9014 /
/
-- Stated in Odeh that gas inj. rate (item 5) is 100MMscf per day
-- BHP upper limit (item 7) should not be exceeding the highest
-- pressure in the PVT table=9014.7psia (default is 100 000psia)
TSTEP
--Advance the simulater once a month for TEN years:
31 28 31 30 31 30 31 31 30 31 30 31
31 28 31 30 31 30 31 31 30 31 30 31
31 28 31 30 31 30 31 31 30 31 30 31
31 28 31 30 31 30 31 31 30 31 30 31
31 28 31 30 31 30 31 31 30 31 30 31
31 28 31 30 31 30 31 31 30 31 30 31
31 28 31 30 31 30 31 31 30 31 30 31
31 28 31 30 31 30 31 31 30 31 30 31
31 28 31 30 31 30 31 31 30 31 30 31
31 28 31 30 31 30 31 31 30 31 30 31 /
--Advance the simulator once a year for TEN years:
--10*365 /
END