Add opm_formatted property to the IOConfig

This commit is contained in:
Joakim Hove 2018-09-10 23:47:43 +02:00
parent 2ea1b7860f
commit 71d92c3dc8
4 changed files with 123 additions and 7 deletions

View File

@ -105,6 +105,41 @@ namespace Opm {
------ Default ------
If no keywords for config of writing restart files have been handled; no restart files are written.
ECL compatible restart
======================
Unfortunately flow & eclipse are not compatible across restarts. The
RestartIO implementation can write restart files for flow -> flow restart
or alternatively for flow -> eclipse restart. This is regulated by the
boolean flag ecl_compatible_restart in the IOConfig class. The difference
between the two are as follows:
ecl_compatible_restart = false:
1. The 'extra' fields in the RestartValue structure are actually
written to disk.
2. You can optionally ask the RestartIO::save() function to save the
solution in double precision.
3. The RestartIO::save() function will save opm specific vector OPM_IWEL
and OPM_XWEL.
ecl_compatible_restart = true:
1. The 'extra' fields in the RestartValue are silently ignored.
2. If request double precision solution data that is silently ignored,
it will be float.
3. The OPM_IWEL and OPM_XWEL vectors will not be written.
Observe that the solution data in the RestartValue is passed
unconditionally to the solution section in the restart file, so if you
pass a field in the solution section which Eclipse does not recognize you
will end up with a restart file which Eclipse can not read, even if you
have set ecl_compatible_restart to true.
*/
@ -117,7 +152,8 @@ namespace Opm {
explicit IOConfig( const Deck& );
explicit IOConfig( const std::string& input_path );
void setEclCompatibleRST(bool ecl_rst);
bool getEclCompatibleRST() const;
bool getWriteEGRIDFile() const;
bool getWriteINITFile() const;
bool getUNIFOUT() const;
@ -165,6 +201,7 @@ namespace Opm {
std::string m_output_dir;
std::string m_base_name;
bool m_nosim;
bool ecl_compatible_rst = false;
IOConfig( const GRIDSection&,
const RUNSPECSection&,

View File

@ -253,6 +253,10 @@ RestartValue load( const std::string& filename,
} else
file_view = ecl_file_get_global_view( file.get() );
if (!ecl_file_view_has_kw(file_view, "OPM_XWEL"))
throw std::runtime_error("Sorry - this file is missing the OPM_XWEL keyword - required for flow based restart\n");
const ecl_kw_type * intehead = ecl_file_view_iget_named_kw( file_view , "INTEHEAD", 0 );
const ecl_kw_type * opm_xwel = ecl_file_view_iget_named_kw( file_view , "OPM_XWEL", 0 );
const ecl_kw_type * opm_iwel = ecl_file_view_iget_named_kw( file_view, "OPM_IWEL", 0 );
@ -554,16 +558,20 @@ void writeWell(ecl_rst_file_type* rst_file, int sim_step, const EclipseState& es
const auto& phases = es.runspec().phases();
const size_t ncwmax = schedule.getMaxNumConnectionsForWells(sim_step);
const auto opm_xwel = serialize_OPM_XWEL( wells, sim_step, sched_wells, phases, grid );
const auto opm_iwel = serialize_OPM_IWEL( wells, sched_wells );
const auto iwel_data = serialize_IWEL(sim_step, sched_wells, grid);
const auto icon_data = serialize_ICON(sim_step , ncwmax, sched_wells, grid);
const auto zwel_data = serialize_ZWEL( sched_wells );
write_kw( rst_file, ERT::EclKW< int >( IWEL_KW, iwel_data) );
write_kw( rst_file, ERT::EclKW< const char* >(ZWEL_KW, zwel_data ) );
write_kw( rst_file, ERT::EclKW< double >( OPM_XWEL, opm_xwel ) );
write_kw( rst_file, ERT::EclKW< int >( OPM_IWEL, opm_iwel ) );
if (!es.getIOConfig().getEclCompatibleRST()) {
const auto opm_xwel = serialize_OPM_XWEL( wells, sim_step, sched_wells, phases, grid );
const auto opm_iwel = serialize_OPM_IWEL( wells, sched_wells );
write_kw( rst_file, ERT::EclKW< double >( OPM_XWEL, opm_xwel ) );
write_kw( rst_file, ERT::EclKW< int >( OPM_IWEL, opm_iwel ) );
}
write_kw( rst_file, ERT::EclKW< int >( ICON_KW, icon_data ) );
}
@ -605,6 +613,7 @@ void save(const std::string& filename,
{
checkSaveArguments(es, value, grid);
{
bool ecl_compatible_rst = es.getIOConfig().getEclCompatibleRST();
int sim_step = std::max(report_step - 1, 0);
int ert_phase_mask = es.runspec().eclPhaseMask( );
const auto& units = es.getUnits();
@ -617,6 +626,9 @@ void save(const std::string& filename,
else
rst_file.reset( ecl_rst_file_open_write( filename.c_str() ) );
if (ecl_compatible_rst)
write_double = false;
// Convert solution fields and extra values from SI to user units.
value.solution.convertFromSI(units);
for (auto & extra_value : value.extra) {
@ -628,8 +640,9 @@ void save(const std::string& filename,
writeHeader( rst_file.get(), sim_step, report_step, posix_time , sim_time, ert_phase_mask, units, schedule , grid );
writeWell( rst_file.get(), sim_step, es , grid, schedule, value.wells);
writeSolution( rst_file.get(), value, write_double );
writeExtraData( rst_file.get(), value.extra );
writeSolution( rst_file.get(), value, write_double);
if (!ecl_compatible_rst)
writeExtraData( rst_file.get(), value.extra );
}
}
}

View File

@ -122,6 +122,14 @@ namespace Opm {
}
bool IOConfig::getEclCompatibleRST() const {
return this->ecl_compatible_rst;
}
void IOConfig::setEclCompatibleRST(bool ecl_rst) {
this->ecl_compatible_rst = ecl_rst;
}
void IOConfig::overrideNOSIM(bool nosim) {

View File

@ -407,6 +407,8 @@ struct Setup {
schedule( deck, grid, es.get3DProperties(), es.runspec().phases(), parseContext),
summary_config( deck, schedule, es.getTableManager( ), parseContext)
{
auto& io_config = es.getIOConfig();
io_config.setEclCompatibleRST(false);
}
};
@ -433,6 +435,62 @@ BOOST_AUTO_TEST_CASE(EclipseReadWriteWellStateData) {
}
BOOST_AUTO_TEST_CASE(ECL_FORMATTED) {
Setup setup("FIRST_SIM.DATA");
test_work_area_type * test_area = test_work_area_alloc("test_Restart");
auto& io_config = setup.es.getIOConfig();
{
auto num_cells = setup.grid.getNumActive( );
auto cells = mkSolution( num_cells );
auto wells = mkWells();
{
RestartValue restart_value(cells, wells);
io_config.setEclCompatibleRST( false );
restart_value.addExtra("EXTRA", UnitSystem::measure::pressure, {10,1,2,3});
RestartIO::save("OPM_FILE.UNRST", 1 ,
100,
restart_value,
setup.es,
setup.grid,
setup.schedule,
true);
{
ecl_file_type * rst_file = ecl_file_open( "OPM_FILE.UNRST" , 0 );
ecl_kw_type * swat = ecl_file_iget_named_kw(rst_file, "SWAT", 0);
BOOST_CHECK_EQUAL( ECL_DOUBLE_TYPE, ecl_kw_get_type(swat));
BOOST_CHECK( ecl_file_has_kw(rst_file, "EXTRA"));
ecl_file_close(rst_file);
}
io_config.setEclCompatibleRST( true );
RestartIO::save("ECL_FILE.UNRST", 1 ,
100,
restart_value,
setup.es,
setup.grid,
setup.schedule,
true);
{
ecl_file_type * rst_file = ecl_file_open( "ECL_FILE.UNRST" , 0 );
ecl_kw_type * swat = ecl_file_iget_named_kw(rst_file, "SWAT", 0);
BOOST_CHECK_EQUAL( ECL_FLOAT_TYPE, ecl_kw_get_type(swat));
BOOST_CHECK( !ecl_file_has_kw(rst_file, "EXTRA"));
BOOST_CHECK( !ecl_file_has_kw(rst_file, "OPM_XWEL"));
BOOST_CHECK( !ecl_file_has_kw(rst_file, "OPM_IWEL"));
ecl_file_close(rst_file);
}
}
}
test_work_area_free(test_area);
}
void compare_equal( const RestartValue& fst,
const RestartValue& snd ,