Merge pull request #977 from bska/hookup-rft-writer

Hook New RFT File Writer up to Central ECLIPSE I/O Facility
This commit is contained in:
Joakim Hove
2019-09-20 07:21:35 +02:00
committed by GitHub

View File

@@ -39,129 +39,25 @@
#include <opm/output/eclipse/RestartIO.hpp>
#include <opm/output/eclipse/Summary.hpp>
#include <opm/output/eclipse/WriteInit.hpp>
#include <opm/output/eclipse/WriteRFT.hpp>
#include <opm/io/eclipse/OutputStream.hpp>
#include <algorithm>
#include <cstdlib>
#include <cctype>
#include <memory> // unique_ptr
#include <unordered_map>
#include <utility> // move
#include <ert/ecl/EclKW.hpp>
#include <ert/ecl/EclFilename.hpp>
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/ecl_init_file.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_rft_file.h>
#include <ert/ecl/ecl_rst_file.h>
#include <ert/ecl_well/well_const.h>
#include <ert/ecl/ecl_rsthead.h>
#include <ert/ecl/ecl_util.hpp>
#include <ert/util/util.h>
#include <ert/ecl/fortio.h>
#define OPM_XWEL "OPM_XWEL"
#define OPM_IWEL "OPM_IWEL"
// namespace start here since we don't want the ERT headers in it
namespace Opm {
namespace {
class RFT {
public:
RFT( const std::string& output_dir,
const std::string& basename,
bool format );
void writeTimeStep( const Schedule& schedule,
const EclipseGrid& grid,
std::size_t report_step,
time_t current_time,
double days,
const UnitSystem& units,
data::Wells wellData);
private:
std::string filename;
bool fmt_file;
};
RFT::RFT( const std::string& output_dir,
const std::string& basename,
bool format ) :
filename( ERT::EclFilename( output_dir, basename, ECL_RFT_FILE, format ) ),
fmt_file( format )
{}
void RFT::writeTimeStep( const Schedule& schedule,
const EclipseGrid& grid,
std::size_t report_step,
time_t current_time,
double days,
const UnitSystem& units,
data::Wells wellDatas) {
using rft = ERT::ert_unique_ptr< ecl_rft_node_type, ecl_rft_node_free >;
const auto& rft_config = schedule.rftConfig();
auto well_names = schedule.wellNames(report_step);
if (!rft_config.active(report_step))
return;
fortio_type * fortio;
if (report_step > rft_config.firstRFTOutput())
fortio = fortio_open_append( filename.c_str() , fmt_file , ECL_ENDIAN_FLIP );
else
fortio = fortio_open_writer( filename.c_str() , fmt_file , ECL_ENDIAN_FLIP );
for ( const auto& well_name : well_names ) {
if (!(rft_config.rft(well_name, report_step) || rft_config.plt(well_name, report_step)))
continue;
rft rft_node(ecl_rft_node_alloc_new( well_name.c_str(), "RFT", current_time, days ));
const auto& wellData = wellDatas.at(well_name);
if (wellData.connections.empty())
continue;
const auto& well = schedule.getWell2(well_name, report_step);
for( const auto& connection : well.getConnections() ) {
const size_t i = size_t( connection.getI() );
const size_t j = size_t( connection.getJ() );
const size_t k = size_t( connection.getK() );
if( !grid.cellActive( i, j, k ) ) continue;
const auto index = grid.getGlobalIndex( i, j, k );
const double depth = grid.getCellDepth( i, j, k );
const auto& connectionData = std::find_if( wellData.connections.begin(),
wellData.connections.end(),
[=]( const data::Connection& c ) {
return c.index == index;
} );
const double press = units.from_si(UnitSystem::measure::pressure,connectionData->cell_pressure);
const double satwat = units.from_si(UnitSystem::measure::identity, connectionData->cell_saturation_water);
const double satgas = units.from_si(UnitSystem::measure::identity, connectionData->cell_saturation_gas);
auto* cell = ecl_rft_cell_alloc_RFT(
i, j, k, depth, press, satwat, satgas );
ecl_rft_node_append_cell( rft_node.get(), cell );
}
ecl_rft_node_fwrite( rft_node.get(), fortio, units.getEclType() );
}
fortio_fclose( fortio );
}
inline std::string uppercase( std::string x ) {
std::transform( x.begin(), x.end(), x.begin(),
[]( char c ) { return std::toupper( c ); } );
@@ -183,7 +79,6 @@ class EclipseIO::Impl {
std::string outputDir;
std::string baseName;
out::Summary summary;
RFT rft;
bool output_enabled;
};
@@ -197,7 +92,6 @@ EclipseIO::Impl::Impl( const EclipseState& eclipseState,
, outputDir( eclipseState.getIOConfig().getOutputDir() )
, baseName( uppercase( eclipseState.getIOConfig().getBaseName() ) )
, summary( eclipseState, summary_config, grid , schedule )
, rft( outputDir.c_str(), baseName.c_str(), es.getIOConfig().getFMTOUT() )
, output_enabled( eclipseState.getIOConfig().getOutputEnabled() )
{}
@@ -259,19 +153,14 @@ void EclipseIO::writeTimeStep(const SummaryState& st,
RestartValue value,
const bool write_double)
{
if( !this->impl->output_enabled )
if (! this->impl->output_enabled) {
return;
}
const auto& es = this->impl->es;
const auto& grid = this->impl->grid;
const auto& schedule = this->impl->schedule;
const auto& units = es.getUnits();
const auto& ioConfig = es.getIOConfig();
const auto& restart = es.cfg().restart();
const auto& ioConfig = es.cfg().io();
/*
Summary data is written unconditionally for every timestep except for the
@@ -288,7 +177,7 @@ void EclipseIO::writeTimeStep(const SummaryState& st,
but there is an unsupported option to the RPTSCHED keyword which
will request restart output from every timestep.
*/
if(!isSubstep && restart.getWriteRestartFile(report_step))
if(!isSubstep && es.cfg().restart().getWriteRestartFile(report_step))
{
EclIO::OutputStream::Restart rstFile {
EclIO::OutputStream::ResultSet { this->impl->outputDir,
@@ -298,25 +187,28 @@ void EclipseIO::writeTimeStep(const SummaryState& st,
EclIO::OutputStream::Unified { ioConfig.getUNIFOUT() }
};
RestartIO::save(rstFile, report_step, secs_elapsed, value, es, grid, schedule,
st, write_double);
RestartIO::save(rstFile, report_step, secs_elapsed, value,
es, grid, schedule, st, write_double);
}
// RFT file is not written for substeps
if (! isSubstep) {
// Open existing RFT file if report step is after first RFT event.
const auto openExisting = EclIO::OutputStream::RFT::OpenExisting {
static_cast<std::size_t>(report_step)
> schedule.rftConfig().firstRFTOutput()
};
/*
RFT files are not written for substep.
*/
if( isSubstep )
return;
this->impl->rft.writeTimeStep( schedule,
grid,
report_step,
secs_elapsed + this->impl->schedule.posixStartTime(),
units.from_si( UnitSystem::measure::time, secs_elapsed ),
units,
value.wells );
EclIO::OutputStream::RFT rftFile {
EclIO::OutputStream::ResultSet { this->impl->outputDir,
this->impl->baseName },
EclIO::OutputStream::Formatted { ioConfig.getFMTOUT() },
openExisting
};
RftIO::write(report_step, secs_elapsed, es.getUnits(),
grid, schedule, value.wells, rftFile);
}
}