280 lines
8.4 KiB
C++
280 lines
8.4 KiB
C++
/*
|
|
Copyright 2015 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 <stdio.h>
|
|
#include <iostream>
|
|
#include <iterator>
|
|
|
|
#include <boost/lexical_cast.hpp>
|
|
#include <boost/filesystem.hpp>
|
|
|
|
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
|
|
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
|
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
|
|
#include <opm/parser/eclipse/Deck/Section.hpp>
|
|
#include <opm/parser/eclipse/Deck/SCHEDULESection.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
|
|
#include <ert/ecl/ecl_util.h>
|
|
|
|
|
|
|
|
|
|
namespace Opm {
|
|
|
|
namespace {
|
|
const char* default_dir = ".";
|
|
|
|
inline std::string basename( const std::string& path ) {
|
|
return boost::filesystem::path( path ).stem().string();
|
|
}
|
|
|
|
inline std::string outputdir( const std::string& path ) {
|
|
auto dir = boost::filesystem::path( path ).parent_path().string();
|
|
|
|
if( dir.empty() ) return default_dir;
|
|
|
|
return dir;
|
|
}
|
|
}
|
|
|
|
|
|
IOConfig::IOConfig( const Deck& deck ) :
|
|
IOConfig( GRIDSection( deck ),
|
|
RUNSPECSection( deck ),
|
|
SOLUTIONSection( deck ),
|
|
SCHEDULESection( deck ),
|
|
std::make_shared< const TimeMap >( deck ),
|
|
deck.hasKeyword("NOSIM"),
|
|
deck.getDataFile() )
|
|
{}
|
|
|
|
IOConfig::IOConfig( const std::string& input_path ) :
|
|
m_deck_filename( input_path ),
|
|
m_output_dir( outputdir( input_path ) ),
|
|
m_base_name( basename( input_path ) )
|
|
{}
|
|
|
|
static inline bool write_egrid_file( const GRIDSection& grid ) {
|
|
if( grid.hasKeyword( "NOGGF" ) ) return false;
|
|
if( !grid.hasKeyword( "GRIDFILE" ) ) return true;
|
|
|
|
const auto& keyword = grid.getKeyword( "GRIDFILE" );
|
|
|
|
if( keyword.size() == 0 ) return false;
|
|
|
|
const auto& rec = keyword.getRecord( 0 );
|
|
const auto& item1 = rec.getItem( 0 );
|
|
|
|
if( item1.hasValue( 0 ) && item1.get< int >( 0 ) != 0 ) {
|
|
std::cerr << "IOConfig: Reading GRIDFILE keyword from GRID section: "
|
|
<< "Output of GRID file is not supported. "
|
|
<< "Supported format: EGRID"
|
|
<< std::endl;
|
|
return true;
|
|
}
|
|
|
|
if( rec.size() < 1 ) return true;
|
|
|
|
const auto& item2 = rec.getItem( 1 );
|
|
return !item2.hasValue( 0 ) || item2.get< int >( 0 ) != 0;
|
|
}
|
|
|
|
IOConfig::IOConfig( const GRIDSection& grid,
|
|
const RUNSPECSection& runspec,
|
|
const SOLUTIONSection& solution,
|
|
const SCHEDULESection& schedule,
|
|
std::shared_ptr< const TimeMap > timemap,
|
|
bool nosim,
|
|
const std::string& input_path ) :
|
|
m_timemap( timemap ),
|
|
m_write_INIT_file( grid.hasKeyword( "INIT" ) ),
|
|
m_write_EGRID_file( write_egrid_file( grid ) ),
|
|
m_UNIFIN( runspec.hasKeyword( "UNIFIN" ) ),
|
|
m_UNIFOUT( runspec.hasKeyword( "UNIFOUT" ) ),
|
|
m_FMTIN( runspec.hasKeyword( "FMTIN" ) ),
|
|
m_FMTOUT( runspec.hasKeyword( "FMTOUT" ) ),
|
|
m_deck_filename( input_path ),
|
|
m_output_dir( outputdir( input_path ) ),
|
|
m_base_name( basename( input_path ) ),
|
|
m_nosim( nosim ),
|
|
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;
|
|
}
|
|
|
|
bool IOConfig::getWriteINITFile() const {
|
|
return m_write_INIT_file;
|
|
}
|
|
|
|
|
|
/*
|
|
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::initFirstRFTOutput(const Schedule& schedule) {
|
|
m_first_rft_step = -1;
|
|
|
|
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::overrideNOSIM(bool nosim) {
|
|
m_nosim = nosim;
|
|
}
|
|
|
|
|
|
bool IOConfig::getUNIFIN() const {
|
|
return m_UNIFIN;
|
|
}
|
|
|
|
bool IOConfig::getUNIFOUT() const {
|
|
return m_UNIFOUT;
|
|
}
|
|
|
|
bool IOConfig::getFMTIN() const {
|
|
return m_FMTIN;
|
|
}
|
|
|
|
bool IOConfig::getFMTOUT() const {
|
|
return m_FMTOUT;
|
|
}
|
|
|
|
|
|
|
|
boost::gregorian::date IOConfig::getTimestepDate(size_t reportStep) const {
|
|
auto time = (*m_timemap)[reportStep];
|
|
return time.date();
|
|
}
|
|
|
|
|
|
|
|
std::string IOConfig::getRestartFileName(const std::string& restart_base, int report_step, bool output) const {
|
|
bool unified = output ? getUNIFOUT() : getUNIFIN();
|
|
bool fmt_file = output ? getFMTOUT() : getFMTIN();
|
|
|
|
ecl_file_enum file_type = (unified) ? ECL_UNIFIED_RESTART_FILE : ECL_RESTART_FILE;
|
|
char * c_str = ecl_util_alloc_filename( NULL , restart_base.c_str() , file_type, fmt_file , report_step);
|
|
std::string restart_filename = c_str;
|
|
free( c_str );
|
|
|
|
return restart_filename;
|
|
}
|
|
|
|
|
|
int IOConfig::getFirstRFTStep() const {
|
|
return m_first_rft_step;
|
|
}
|
|
|
|
bool IOConfig::getOutputEnabled(){
|
|
return m_output_enabled;
|
|
}
|
|
|
|
void IOConfig::setOutputEnabled(bool enabled){
|
|
m_output_enabled = enabled;
|
|
}
|
|
|
|
std::string IOConfig::getOutputDir() const {
|
|
return m_output_dir;
|
|
}
|
|
|
|
void IOConfig::setOutputDir(const std::string& outputDir) {
|
|
m_output_dir = outputDir;
|
|
}
|
|
|
|
const std::string& IOConfig::getBaseName() const {
|
|
return m_base_name;
|
|
}
|
|
|
|
void IOConfig::setBaseName(std::string baseName) {
|
|
m_base_name = baseName;
|
|
}
|
|
|
|
std::string IOConfig::fullBasePath( ) const {
|
|
namespace fs = boost::filesystem;
|
|
|
|
fs::path dir( m_output_dir );
|
|
fs::path base( m_base_name );
|
|
fs::path full_path = dir.make_preferred() / base.make_preferred();
|
|
|
|
return full_path.string();
|
|
}
|
|
|
|
|
|
bool IOConfig::initOnly( ) const {
|
|
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
|