Extracted configuration of *when* to write restart

The configuration of when to write restart files is quite complex,
involving at least the three keywords RPTSOL, RPTRST and RPTSCHED. This
commit moves that configuration from the IOConfig class to the
RestartConfig class.

At a later stage the RestartConfgig class will be extended with
information of *what* to save in the restart file.
This commit is contained in:
Joakim Hove
2016-07-15 14:15:26 +02:00
parent 4a22657e76
commit 148b9b22ea
8 changed files with 134 additions and 1058 deletions

View File

@@ -130,6 +130,7 @@ EclipseState/InitConfig/Equil.cpp
EclipseState/SimulationConfig/SimulationConfig.cpp
EclipseState/SimulationConfig/ThresholdPressure.cpp
EclipseState/SummaryConfig/SummaryConfig.cpp
EclipseState/IOConfig/RestartConfig.cpp
EclipseState/IOConfig/IOConfig.cpp)
#
@@ -228,6 +229,7 @@ EclipseState/InitConfig/Equil.hpp
EclipseState/SimulationConfig/SimulationConfig.hpp
EclipseState/SimulationConfig/ThresholdPressure.hpp
EclipseState/SummaryConfig/SummaryConfig.hpp
EclipseState/IOConfig/RestartConfig.hpp
EclipseState/IOConfig/IOConfig.hpp
#
EclipseState/Tables/Tabdims.hpp

View File

@@ -43,12 +43,6 @@ namespace Opm {
m_simulationConfig(std::make_shared<const SimulationConfig>(deck, eclipse3DProperties)),
m_summaryConfig( deck, schedule, eclipse3DProperties, parseContext , inputGrid.getNXYZ())
{
// Hmmm - would have thought this should iterate through the SCHEDULE section as well?
if (Section::hasSOLUTION(deck)) {
std::shared_ptr<const SOLUTIONSection> solutionSection = std::make_shared<const SOLUTIONSection>(deck);
m_ioConfig->handleSolutionSection(schedule.getTimeMap(), solutionSection);
}
m_ioConfig->initFirstOutput(schedule);
}
const SummaryConfig& EclipseConfig::getSummaryConfig() const {

View File

@@ -64,170 +64,11 @@ namespace Opm {
}
}
IOConfig::restartConfig IOConfig::rptrst( const DeckKeyword& kw, size_t step ) {
const auto& items = kw.getStringData();
/* if any of the values are pure integers we assume this is meant to be
* the slash-terminated list of integers way of configuring. If
* integers and non-integers are mixed, this is an error.
*/
const auto ints = std::any_of( items.begin(), items.end(), is_int );
const auto strs = !std::all_of( items.begin(), items.end(), is_int );
if( ints && strs ) throw std::runtime_error(
"RPTRST does not support mixed mnemonics and integer list."
);
size_t basic = 1;
size_t freq = 0;
bool found_basic = false;
for( const auto& mnemonic : items ) {
const auto freq_pos = mnemonic.find( "FREQ=" );
if( freq_pos != std::string::npos ) {
freq = std::stoul( mnemonic.substr( freq_pos + 5 ) );
}
const auto basic_pos = mnemonic.find( "BASIC=" );
if( basic_pos != std::string::npos ) {
basic = std::stoul( mnemonic.substr( basic_pos + 6 ) );
found_basic = true;
}
}
if( found_basic ) return restartConfig( step, basic, freq );
/* If no BASIC mnemonic is found, either it is not present or we might
* have an old data set containing integer controls instead of mnemonics.
* BASIC integer switch is integer control nr 1, FREQUENCY is integer
* control nr 6.
*/
/* mnemonics, but without basic and freq. Effectively ignored */
if( !ints ) return {};
const int BASIC_index = 0;
const int FREQ_index = 5;
if( items.size() > BASIC_index )
basic = std::stoul( items[ BASIC_index ] );
// Peculiar special case in eclipse, - not documented
// This ignore of basic = 0 for the integer mnemonics case
// is done to make flow write restart file at the same intervals
// as eclipse for the Norne data set. There might be some rules
// we are missing here.
if( 0 == basic ) return {};
if( items.size() > FREQ_index ) // if frequency is set
freq = std::stoul( items[ FREQ_index ] );
return restartConfig( step, basic, freq );
}
IOConfig::restartConfig IOConfig::rptsched( const DeckKeyword& keyword ) {
size_t restart = 0;
bool restart_found = false;
const auto& items = keyword.getStringData();
const auto ints = std::any_of( items.begin(), items.end(), is_int );
const auto strs = !std::all_of( items.begin(), items.end(), is_int );
if( ints && strs ) throw std::runtime_error(
"RPTSCHED does not support mixed mnemonics and integer list."
);
for( const auto& mnemonic : items ) {
const auto restart_pos = mnemonic.find( "RESTART=" );
if( restart_pos != std::string::npos ) {
restart = std::stoul( mnemonic.substr( restart_pos + 8 ) );
restart_found = true;
}
const auto nothing_pos = mnemonic.find( "NOTHING" );
if( nothing_pos != std::string::npos ) {
restart = 0;
restart_found = true;
}
}
if( restart_found ) return restartConfig( restart );
/* No RESTART or NOTHING found, but it is not an integer list */
if( strs ) return {};
/* We might have an old data set containing integer controls instead of
* mnemonics. Restart integer switch is integer control nr 7
*/
const int RESTART_index = 6;
if( items.size() <= RESTART_index ) return {};
return restartConfig( std::stoul( items[ RESTART_index ] ) );
}
DynamicState< IOConfig::restartConfig > IOConfig::rstconf(
const SCHEDULESection& schedule,
std::shared_ptr< const TimeMap > timemap ) {
size_t current_step = 1;
bool ignore_RPTSCHED_restart = false;
restartConfig unset;
DynamicState< IOConfig::restartConfig >
restart_config( timemap, restartConfig( 0, 0, 1 ) );
for( const auto& keyword : schedule ) {
const auto& name = keyword.name();
if( name == "DATES" ) {
current_step += keyword.size();
continue;
}
if( name == "TSTEP" ) {
current_step += keyword.getRecord( 0 ).getItem( 0 ).size();
continue;
}
if( !( name == "RPTRST" || name == "RPTSCHED" ) ) continue;
if( timemap->size() <= current_step ) continue;
const bool is_RPTRST = name == "RPTRST";
if( !is_RPTRST && ignore_RPTSCHED_restart ) continue;
const auto rs = is_RPTRST
? rptrst( keyword, current_step - 1 )
: rptsched( keyword );
if( is_RPTRST ) ignore_RPTSCHED_restart = rs.basic > 2;
/* we're using the default state of restartConfig to signal "no
* update". The default state is non-sensical
*/
if( rs == unset ) continue;
if( 6 == rs.rptsched_restart || 6 == rs.basic )
throw std::runtime_error(
"OPM does not support the RESTART=6 setting"
"(write restart file every timestep)"
);
restart_config.update( current_step, rs );
}
return restart_config;
}
IOConfig::IOConfig( const Deck& deck ) :
IOConfig( GRIDSection( deck ),
RUNSPECSection( deck ),
SOLUTIONSection( deck ),
SCHEDULESection( deck ),
std::make_shared< const TimeMap >( deck ),
deck.hasKeyword("NOSIM"),
@@ -267,6 +108,7 @@ namespace Opm {
IOConfig::IOConfig( const GRIDSection& grid,
const RUNSPECSection& runspec,
const SOLUTIONSection& solution,
const SCHEDULESection& schedule,
std::shared_ptr< const TimeMap > timemap,
bool nosim,
@@ -282,10 +124,15 @@ namespace Opm {
m_output_dir( outputdir( input_path ) ),
m_base_name( basename( input_path ) ),
m_nosim( nosim ),
m_restart_output_config( std::make_shared< DynamicState< restartConfig > >(
rstconf( schedule, timemap ) ) )
m_restart_config( RestartConfig( schedule , solution , timemap))
{}
const RestartConfig& IOConfig::restartConfig() const {
return m_restart_config;
}
bool IOConfig::getWriteEGRIDFile() const {
return m_write_EGRID_file;
}
@@ -294,153 +141,29 @@ namespace Opm {
return m_write_INIT_file;
}
bool IOConfig::getWriteRestartFile(size_t timestep) const {
bool write_restart_ts = false;
if (0 == timestep) {
write_restart_ts = m_write_initial_RST_file;
} else if (m_restart_output_config) {
restartConfig ts_restart_config = m_restart_output_config->get(timestep);
//Look at rptsched restart setting
if (ts_restart_config.rptsched_restart_set) {
if (ts_restart_config.rptsched_restart > 0) {
write_restart_ts = true;
}
} else { //Look at rptrst basic setting
switch (ts_restart_config.basic) {
case 0: //Do not write restart files
write_restart_ts = false;
break;
case 1: //Write restart file every report time
write_restart_ts = true;
break;
case 2: //Write restart file every report time
write_restart_ts = true;
break;
case 3: //Every n'th report time
write_restart_ts = getWriteRestartFileFrequency(timestep, ts_restart_config.timestep, ts_restart_config.frequency);
break;
case 4: //First reportstep of every year, or if n > 1, n'th years
write_restart_ts = getWriteRestartFileFrequency(timestep, ts_restart_config.timestep, ts_restart_config.frequency, true);
break;
case 5: //First reportstep of every month, or if n > 1, n'th months
write_restart_ts = getWriteRestartFileFrequency(timestep, ts_restart_config.timestep, ts_restart_config.frequency, false, true);
break;
default:
// do nothing
break;
}
}
}
return write_restart_ts;
}
bool IOConfig::getWriteRestartFileFrequency(size_t timestep,
size_t start_timestep,
size_t frequency,
bool years,
bool months) const {
bool write_restart_file = false;
if ((!years && !months) && (timestep >= start_timestep)) {
write_restart_file = ((timestep % frequency) == 0) ? true : false;
} else {
write_restart_file = m_timemap->isTimestepInFirstOfMonthsYearsSequence(timestep, years, start_timestep, frequency);
}
return write_restart_file;
}
void IOConfig::assertTimeMap(TimeMapConstPtr timemap) {
if (!m_timemap) {
restartConfig rs;
rs.timestep = 0;
rs.basic = 0;
rs.frequency = 1;
rs.rptsched_restart_set = false;
rs.rptsched_restart = 0;
m_timemap = timemap;
m_restart_output_config = std::make_shared<DynamicState<restartConfig>>(timemap, rs);
}
}
/*
Will initialize the two internal variables holding the first
report step when restart and rft output is queried.
The reason we are interested in this report step is that when we
reach this step the output files should be opened with mode 'w'
- whereas for subsequent steps they should be opened with mode
'a'.
Will initialize an internal variable holding the first report
step when rft output is queried. The reason we are interested in
this report step is that when we reach this step the output
files should be opened with mode 'w' - whereas for subsequent
steps it should be opened with mode 'a'.
*/
void IOConfig::initFirstOutput(const Schedule& schedule) {
m_first_restart_step = -1;
void IOConfig::initFirstRFTOutput(const Schedule& schedule) {
m_first_rft_step = -1;
assertTimeMap( this->m_timemap );
{
size_t report_step = 0;
while (true) {
if (getWriteRestartFile(report_step)) {
m_first_restart_step = report_step;
break;
}
report_step++;
if (report_step == m_timemap->size())
break;
}
}
{
for (const auto& well : schedule.getWells( )) {
int well_output = well->firstRFTOutput();
if (well_output >= 0) {
if ((m_first_rft_step < 0) || (well_output < m_first_rft_step))
m_first_rft_step = well_output;
}
for (const auto& well : schedule.getWells( )) {
int well_output = well->firstRFTOutput();
if (well_output >= 0) {
if ((m_first_rft_step < 0) || (well_output < m_first_rft_step))
m_first_rft_step = well_output;
}
}
}
void IOConfig::handleSolutionSection(TimeMapConstPtr timemap, std::shared_ptr<const SOLUTIONSection> solutionSection) {
if (solutionSection->hasKeyword("RPTRST")) {
const auto& rptrstkeyword = solutionSection->getKeyword("RPTRST");
auto rs = rptrst( rptrstkeyword, 0 );
if( rs != restartConfig() )
m_restart_output_config->updateInitial( rs );
setWriteInitialRestartFile(true); // Guessing on eclipse rules for write of initial RESTART file (at time 0):
// Write of initial restart file is (due to the eclipse reference manual)
// governed by RPTSOL RESTART in solution section,
// if RPTSOL RESTART > 1 initial restart file is written.
// but - due to initial restart file written from Eclipse
// for data where RPTSOL RESTART not set - guessing that
// when RPTRST is set in SOLUTION (no basic though...) -> write inital restart.
} //RPTRST
if (solutionSection->hasKeyword("RPTSOL") && (timemap->size() > 0)) {
handleRPTSOL(solutionSection->getKeyword("RPTSOL"));
} //RPTSOL
}
void IOConfig::overrideRestartWriteInterval(size_t interval) {
size_t step = 0;
/* write restart files if the interval is non-zero. The restart
* mnemonic (setting) that governs restart-on-interval is BASIC=3
*/
size_t basic = interval > 0 ? 3 : 0;
restartConfig rs( step, basic, interval );
m_restart_output_config->globalReset( rs );
setWriteInitialRestartFile( interval > 0 );
}
void IOConfig::overrideNOSIM(bool nosim) {
m_nosim = nosim;
@@ -463,57 +186,6 @@ namespace Opm {
return m_FMTOUT;
}
void IOConfig::setWriteInitialRestartFile(bool writeInitialRestartFile) {
m_write_initial_RST_file = writeInitialRestartFile;
}
void IOConfig::handleRPTSOL( const DeckKeyword& keyword) {
const auto& record = keyword.getRecord(0);
size_t restart = 0;
size_t found_mnemonic_RESTART = 0;
bool handle_RPTSOL_RESTART = false;
const auto& item = record.getItem(0);
for (size_t index = 0; index < item.size(); ++index) {
const std::string& mnemonic = item.get< std::string >(index);
found_mnemonic_RESTART = mnemonic.find("RESTART=");
if (found_mnemonic_RESTART != std::string::npos) {
std::string restart_no = mnemonic.substr(found_mnemonic_RESTART+8, mnemonic.size());
restart = boost::lexical_cast<size_t>(restart_no);
handle_RPTSOL_RESTART = true;
}
}
/* If no RESTART mnemonic is found, either it is not present or we might
have an old data set containing integer controls instead of mnemonics.
Restart integer switch is integer control nr 7 */
if (found_mnemonic_RESTART == std::string::npos) {
if (item.size() >= 7) {
const std::string& integer_control = item.get< std::string >(6);
try {
restart = boost::lexical_cast<size_t>(integer_control);
handle_RPTSOL_RESTART = true;
} catch (boost::bad_lexical_cast &) {
//do nothing
}
}
}
if (handle_RPTSOL_RESTART) {
if (restart > 1) {
setWriteInitialRestartFile(true);
} else {
setWriteInitialRestartFile(false);
}
}
}
boost::gregorian::date IOConfig::getTimestepDate(size_t reportStep) const {
@@ -522,17 +194,6 @@ namespace Opm {
}
void IOConfig::dumpRestartConfig() const {
for (size_t reportStep = 0; reportStep < m_timemap->size(); reportStep++) {
if (getWriteRestartFile(reportStep)) {
auto time = (*m_timemap)[reportStep];
boost::gregorian::date date = time.date();
printf("%04zu : %02hu/%02hu/%hu \n" , reportStep ,
date.day().as_number() , date.month().as_number() , static_cast<unsigned short>(date.year()));
}
}
}
std::string IOConfig::getRestartFileName(const std::string& restart_base, int report_step, bool output) const {
bool unified = output ? getUNIFOUT() : getUNIFIN();
@@ -547,11 +208,6 @@ namespace Opm {
}
int IOConfig::getFirstRestartStep() const {
return m_first_restart_step;
}
int IOConfig::getFirstRFTStep() const {
return m_first_rft_step;
}
@@ -595,4 +251,37 @@ namespace Opm {
return m_nosim;
}
/*****************************************************************/
/* Here at the bottom are some forwarding proxy methods which just
forward to the appropriate RestartConfig method. They are
retained here as a temporary convenience method to prevent
downstream breakage.
Currently the EclipseState object can return a mutable IOConfig
object, which application code can alter to override settings
from the deck - this is quite ugly. When the API is reworked to
remove the ability modify IOConfig objects we should also
remove these forwarding methods.
*/
void IOConfig::overrideRestartWriteInterval(size_t interval) {
m_restart_config.overrideRestartWriteInterval(interval);
}
bool IOConfig::getWriteRestartFile(size_t timestep) const {
return m_restart_config.getWriteRestartFile( timestep );
}
int IOConfig::getFirstRestartStep() const {
return m_restart_config.getFirstRestartStep();
}
void IOConfig::setWriteInitialRestartFile(bool writeInitialRestartFile) {
m_restart_config.setWriteInitialRestartFile( writeInitialRestartFile );
}
} //namespace Opm

View File

@@ -22,6 +22,8 @@
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp>
namespace Opm {
template< typename > class DynamicState;
@@ -124,9 +126,8 @@ namespace Opm {
explicit IOConfig( const Deck& );
explicit IOConfig( const std::string& input_path );
int getFirstRestartStep() const;
int getFirstRFTStep() const;
bool getWriteRestartFile(size_t timestep) const;
bool getWriteEGRIDFile() const;
bool getWriteINITFile() const;
bool getUNIFOUT() const;
@@ -135,20 +136,11 @@ namespace Opm {
bool getFMTOUT() const;
const std::string& getEclipseInputPath() const;
void overrideRestartWriteInterval(size_t interval);
void overrideNOSIM(bool nosim);
void handleSolutionSection(std::shared_ptr< const TimeMap > timemap, std::shared_ptr<const SOLUTIONSection> solutionSection);
void setWriteInitialRestartFile(bool writeInitialRestartFile);
/// This method will internalize variables with information of
/// the first report step with restart and rft output
/// respectively. This information is important because right
/// at the first output step we must reset the files to size
/// zero, for subsequent output steps we should append.
void initFirstOutput(const Schedule& schedule);
boost::gregorian::date getTimestepDate(size_t timestep) const;
void dumpRestartConfig() const;
std::string getRestartFileName(const std::string& restart_base, int report_step, bool output) const;
@@ -166,27 +158,17 @@ namespace Opm {
std::string fullBasePath( ) const;
bool initOnly() const;
const RestartConfig& restartConfig() const;
// Proxy methods forwarding directly to corresponding RestartConfig
bool getWriteRestartFile(size_t timestep) const;
int getFirstRestartStep() const;
void overrideRestartWriteInterval(size_t interval);
void setWriteInitialRestartFile(bool writeInitialRestartFile);
private:
IOConfig( const GRIDSection&,
const RUNSPECSection&,
const SCHEDULESection&,
std::shared_ptr< const TimeMap >,
bool nosim,
const std::string& input_path );
void assertTimeMap(std::shared_ptr< const TimeMap > timemap);
bool getWriteRestartFileFrequency(size_t timestep,
size_t start_timestep,
size_t frequency,
bool years = false,
bool months = false) const;
void handleRPTSOL( const DeckKeyword& keyword);
std::shared_ptr< const TimeMap > m_timemap;
bool m_write_INIT_file = false;
bool m_write_EGRID_file = true;
bool m_write_initial_RST_file = false;
bool m_UNIFIN = false;
bool m_UNIFOUT = false;
bool m_FMTIN = false;
@@ -198,58 +180,18 @@ namespace Opm {
std::string m_output_dir;
std::string m_base_name;
bool m_nosim;
struct restartConfig {
/*
The content of this struct is logically divided in two; either the
restart behaviour is governed by { timestep , basic , frequency }, or
alternatively by { rptshec_restart_set , rptsched_restart }.
The former triplet is mainly governed by the RPTRST keyword and the
latter pair by the RPTSCHED keyword.
*/
size_t timestep = 0;
size_t basic = 0;
size_t frequency = 0;
bool rptsched_restart_set = false;
size_t rptsched_restart = 0;
restartConfig() = default;
restartConfig( size_t sched_restart ) :
rptsched_restart_set( true ),
rptsched_restart( sched_restart )
{}
restartConfig( size_t step, size_t b, size_t freq ) :
timestep( step ),
basic( b ),
frequency( freq )
{}
bool operator!=(const restartConfig& rhs) const {
return !( *this == rhs );
}
bool operator==( const restartConfig& rhs ) const {
if( this->rptsched_restart_set ) {
return rhs.rptsched_restart_set
&& this->rptsched_restart == rhs.rptsched_restart;
}
return this->timestep == rhs.timestep &&
this->basic == rhs.basic &&
this->frequency == rhs.frequency;
}
};
static DynamicState< restartConfig > rstconf( const SCHEDULESection&,
std::shared_ptr< const TimeMap > );
static restartConfig rptrst( const DeckKeyword&, size_t );
static restartConfig rptsched( const DeckKeyword& );
std::shared_ptr<DynamicState<restartConfig>> m_restart_output_config;
RestartConfig m_restart_config;
IOConfig( const GRIDSection&,
const RUNSPECSection&,
const SOLUTIONSection&,
const SCHEDULESection&,
std::shared_ptr< const TimeMap >,
bool nosim,
const std::string& input_path );
void initFirstRFTOutput(const Schedule& schedule);
};

View File

@@ -1,2 +1,5 @@
opm_add_test(runIOConfigTests SOURCES IOConfigTest.cpp
LIBRARIES opmparser ${Boost_LIBRARIES})
opm_add_test(runRestartConfigTests SOURCES RestartConfigTests.cpp
LIBRARIES opmparser ${Boost_LIBRARIES})

View File

@@ -197,604 +197,7 @@ BOOST_AUTO_TEST_CASE(RPTRST_mixed_mnemonics_int_list) {
BOOST_CHECK_THROW( IOConfig c( *deck ), std::runtime_error );
}
BOOST_AUTO_TEST_CASE(RPTRST) {
const char *deckData1 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=1\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n";
const char *deckData2 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=2 RUBBISH=5\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 JAN 2011 / \n"
"/\n";
const char *deckData3 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"3 0 0 0 0 2\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 JAN 2011 / \n"
"/\n";
Opm::Parser parser;
ParseContext ctx;
auto deck1 = parser.parseString( deckData1, ctx );
IOConfig ioConfig1( *deck1 );
BOOST_CHECK( !ioConfig1.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig1.getWriteRestartFile( 1 ) );
BOOST_CHECK( ioConfig1.getWriteRestartFile( 2 ) );
auto deck2 = parser.parseString( deckData2, ctx );
IOConfig ioConfig2( *deck2 );
BOOST_CHECK( !ioConfig2.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig2.getWriteRestartFile( 1 ) );
BOOST_CHECK( ioConfig2.getWriteRestartFile( 2 ) );
BOOST_CHECK( !ioConfig2.getWriteRestartFile( 3 ) );
auto deck3 = parser.parseString( deckData3, ctx );
IOConfig ioConfig3( *deck3 );
BOOST_CHECK( !ioConfig3.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig3.getWriteRestartFile( 1 ) );
BOOST_CHECK( ioConfig3.getWriteRestartFile( 2 ) );
BOOST_CHECK( !ioConfig3.getWriteRestartFile( 3 ) );
}
BOOST_AUTO_TEST_CASE(RPTSCHED) {
const char *deckData1 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=1\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=0\n"
"/\n";
const char *deckData2 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=1\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"NOTHING RUBBISH\n"
"/\n";
const char *deckData3 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=1 RUBBISH=5\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"0 0 0 0 0 0 0 0\n"
"/\n";
Parser parser;
ParseContext ctx;
auto deck1 = parser.parseString( deckData1, ctx );
IOConfig ioConfig1( *deck1 );
BOOST_CHECK( !ioConfig1.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig1.getWriteRestartFile( 1 ) );
BOOST_CHECK( ioConfig1.getWriteRestartFile( 2 ) );
BOOST_CHECK( ioConfig1.getWriteRestartFile( 3 ) );
auto deck2 = parser.parseString( deckData2, ctx );
IOConfig ioConfig2( *deck2 );
BOOST_CHECK( !ioConfig2.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig2.getWriteRestartFile( 1 ) );
BOOST_CHECK( ioConfig2.getWriteRestartFile( 2 ) );
BOOST_CHECK( ioConfig2.getWriteRestartFile( 3 ) );
auto deck3 = parser.parseString( deckData3, ctx );
IOConfig ioConfig3( *deck3 );
//Older ECLIPSE 100 data set may use integer controls instead of mnemonics
BOOST_CHECK( !ioConfig3.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig3.getWriteRestartFile( 1 ) );
BOOST_CHECK( ioConfig3.getWriteRestartFile( 2 ) );
BOOST_CHECK( ioConfig3.getWriteRestartFile( 3 ) );
}
BOOST_AUTO_TEST_CASE(RPTSCHED_and_RPTRST) {
const char *deckData =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=3\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=1\n"
"/\n";
Opm::Parser parser;
ParseContext ctx;
auto deck = parser.parseString( deckData, ctx );
IOConfig ioConfig( *deck );
BOOST_CHECK( !ioConfig.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig.getWriteRestartFile( 1 ) );
BOOST_CHECK( !ioConfig.getWriteRestartFile( 2 ) );
BOOST_CHECK( ioConfig.getWriteRestartFile( 3 ) );
}
BOOST_AUTO_TEST_CASE(NO_BASIC) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
for( size_t ts = 0; ts < 4; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_1) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=3\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"BASIC=1\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
for( size_t ts = 0; ts < 3; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
BOOST_CHECK( ioConfig.getWriteRestartFile( 3 ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_3) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=3 FREQ=3\n"
"/\n"
"DATES\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
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
const size_t freq = 3;
/* BASIC=3, restart files are created every nth report time, n=3 */
for( size_t ts = 1; ts < 12; ++ts )
BOOST_CHECK_EQUAL( ts % freq == 0, ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_4) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=4\n"
"/\n"
"DATES\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
" 6 JAN 1983 14:56:45.123 /\n" // timestep 12
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
/* BASIC=4, restart file is written at the first report step of each year.
*/
for( size_t ts : { 1, 2, 3, 4, 5, 7, 8, 9, 10, 11 } )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
for( size_t ts : { 6, 12 } )
BOOST_CHECK( ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_4_FREQ_2) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=4 FREQ=2\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 23 MAY 1982 /\n"
" 24 MAY 1982 /\n"
" 24 MAY 1983 /\n" // write
" 25 MAY 1984 /\n"
" 26 MAY 1984 /\n"
" 26 MAY 1985 /\n" // write
" 27 MAY 1985 /\n"
" 1 JAN 1986 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
/* 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.
*
* FREQ=2
*/
for( size_t ts : { 1, 2, 3, 4, 5, 7, 8, 10, 11 } )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
for( size_t ts : { 6, 9 } )
BOOST_CHECK( ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_5) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=5 FREQ=2\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 1 JUN 1981 /\n"
" 1 JUL 1981 /\n" // write
" 1 JAN 1982 /\n"
" 2 JAN 1982 /\n"
" 1 FEB 1982 /\n" // write
" 1 MAR 1982 /\n"
" 1 APR 1983 /\n" //write
" 2 JUN 1983 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
/* BASIC=5, restart file is written at the first report step of each month.
*/
for( size_t ts : { 1, 2, 3, 4, 6, 7, 9, 11 } )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
for( size_t ts : { 5, 8, 10 } )
BOOST_CHECK( ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_0) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=0 FREQ=2\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 1 JUN 1981 /\n"
" 1 JUL 1981 /\n"
" 1 JAN 1982 /\n"
" 2 JAN 1982 /\n"
" 1 FEB 1982 /\n"
" 1 MAR 1982 /\n"
" 1 APR 1983 /\n"
" 2 JUN 1983 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
/* RESTART=0, no restart file is written
*/
for( size_t ts = 0; ts < 11; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(RESTART_EQ_0) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTSCHED\n"
"RESTART=0\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 1 JUN 1981 /\n"
" 1 JUL 1981 /\n"
" 1 JAN 1982 /\n"
" 2 JAN 1982 /\n"
" 1 FEB 1982 /\n"
" 1 MAR 1982 /\n"
" 1 APR 1983 /\n"
" 2 JUN 1983 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
/* RESTART=0, no restart file is written
*/
for( size_t ts = 0; ts < 11; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(RESTART_BASIC_GT_2) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=4 FREQ=2\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
"/\n"
"RPTSCHED\n" // BASIC >2, ignore RPTSCHED RESTART
"RESTART=3, FREQ=1\n"
"/\n"
"DATES\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 23 MAY 1982 /\n"
" 24 MAY 1982 /\n"
" 24 MAY 1983 /\n" // write
" 25 MAY 1984 /\n"
" 26 MAY 1984 /\n"
" 26 MAY 1985 /\n" // write
" 27 MAY 1985 /\n"
" 1 JAN 1986 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
for( size_t ts : { 1, 2, 3, 4, 5, 7, 8, 10, 11 } )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
for( size_t ts : { 6, 9 } )
BOOST_CHECK( ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(RESTART_BASIC_LEQ_2) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=1"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
"/\n"
"RPTSCHED\n"
"RESTART=0\n"
"/\n"
"DATES\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 23 MAY 1982 /\n"
" 24 MAY 1982 /\n"
" 24 MAY 1983 /\n"
" 25 MAY 1984 /\n"
" 26 MAY 1984 /\n"
" 26 MAY 1985 /\n"
" 27 MAY 1985 /\n"
" 1 JAN 1986 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
BOOST_CHECK( ioConfig.getWriteRestartFile( 1 ) );
for( size_t ts = 2; ts < 11; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(DefaultProperties) {
const char* data = "RUNSPEC\n"
@@ -914,3 +317,42 @@ BOOST_AUTO_TEST_CASE(OutputPaths) {
BOOST_CHECK_EQUAL( "testString", config3.getBaseName() );
BOOST_CHECK_EQUAL( testpath, config3.fullBasePath() );
}
BOOST_AUTO_TEST_CASE(RPTSCHED_and_RPTRST) {
const char *deckData =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=3\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=1\n"
"/\n";
Opm::Parser parser;
ParseContext ctx;
auto deck = parser.parseString( deckData, ctx );
IOConfig ioConfig( *deck );
BOOST_CHECK( !ioConfig.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig.getWriteRestartFile( 1 ) );
BOOST_CHECK( !ioConfig.getWriteRestartFile( 2 ) );
BOOST_CHECK( ioConfig.getWriteRestartFile( 3 ) );
}

View File

@@ -498,11 +498,12 @@ BOOST_AUTO_TEST_CASE(TestIOConfigCreation) {
EclipseState state(deck , ParseContext());
IOConfigConstPtr ioConfig = state.getIOConfigConst();
const RestartConfig& rstConfig = ioConfig->restartConfig();
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, rstConfig.getWriteRestartFile(0));
BOOST_CHECK_EQUAL(false, rstConfig.getWriteRestartFile(1));
BOOST_CHECK_EQUAL(true, rstConfig.getWriteRestartFile(2));
BOOST_CHECK_EQUAL(false, rstConfig.getWriteRestartFile(3));
}
@@ -549,11 +550,12 @@ BOOST_AUTO_TEST_CASE(TestIOConfigCreationWithSolutionRPTRST) {
EclipseState state(deck, parseContext);
IOConfigConstPtr ioConfig = state.getIOConfigConst();
const RestartConfig& rstConfig = ioConfig->restartConfig();
BOOST_CHECK_EQUAL(true , ioConfig->getWriteRestartFile(0));
BOOST_CHECK_EQUAL(false , ioConfig->getWriteRestartFile(1));
BOOST_CHECK_EQUAL(false , ioConfig->getWriteRestartFile(2));
BOOST_CHECK_EQUAL(false , ioConfig->getWriteRestartFile(3));
BOOST_CHECK_EQUAL(true , rstConfig.getWriteRestartFile(0));
BOOST_CHECK_EQUAL(false , rstConfig.getWriteRestartFile(1));
BOOST_CHECK_EQUAL(false , rstConfig.getWriteRestartFile(2));
BOOST_CHECK_EQUAL(false , rstConfig.getWriteRestartFile(3));
}
@@ -640,8 +642,9 @@ BOOST_AUTO_TEST_CASE(TestIOConfigCreationWithSolutionRPTSOL) {
EclipseState state(deck, parseContext);
IOConfigConstPtr ioConfig = state.getIOConfigConst();
const RestartConfig& rstConfig = ioConfig->restartConfig();
BOOST_CHECK_EQUAL(true, ioConfig->getWriteRestartFile(0));
BOOST_CHECK_EQUAL(true, rstConfig.getWriteRestartFile(0));
}
{ //old fashion integer mnemonics
@@ -649,7 +652,8 @@ BOOST_AUTO_TEST_CASE(TestIOConfigCreationWithSolutionRPTSOL) {
EclipseState state(deck, parseContext);
IOConfigConstPtr ioConfig = state.getIOConfigConst();
const RestartConfig& rstConfig = ioConfig->restartConfig();
BOOST_CHECK_EQUAL(true, ioConfig->getWriteRestartFile(0));
BOOST_CHECK_EQUAL(true, rstConfig.getWriteRestartFile(0));
}
}

View File

@@ -44,7 +44,7 @@ void verifyRestartConfig(IOConfigConstPtr ioconfig, std::vector<std::tuple<int ,
bool save = std::get<1>(rptrst);
boost::gregorian::date report_date = std::get<2>(rptrst);
BOOST_CHECK_EQUAL( save , ioconfig->getWriteRestartFile( report_step ));
BOOST_CHECK_EQUAL( save , ioconfig->restartConfig().getWriteRestartFile( report_step ));
if (save) {
BOOST_CHECK_EQUAL( report_date, ioconfig->getTimestepDate( report_step ));
}