Decouple Most of OPM-Common From LibECL
This commit takes a pass at the implementation files in opm-common and removes references to libecl functions where practical. In particular we switch to using types from C++'s standard library (and Boost.Filesystem) to achieve the effects of the interfaces being replaced. We also insert direct calls to Posix function fnmatch() to preserve existing pattern matching behaviour (well lists and well templates).
This commit is contained in:
@@ -49,15 +49,14 @@
|
||||
#include <cstdlib>
|
||||
#include <cctype>
|
||||
#include <memory> // unique_ptr
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
#include <utility> // move
|
||||
|
||||
#include <ert/ecl/EclFilename.hpp>
|
||||
#include <ert/ecl/ecl_util.hpp>
|
||||
#include <ert/util/util.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
// namespace start here since we don't want the ERT headers in it
|
||||
namespace Opm {
|
||||
namespace {
|
||||
|
||||
inline std::string uppercase( std::string x ) {
|
||||
@@ -67,8 +66,34 @@ inline std::string uppercase( std::string x ) {
|
||||
return x;
|
||||
}
|
||||
|
||||
void ensure_directory_exists( const boost::filesystem::path& odir )
|
||||
{
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
if (fs::exists( odir ) && !fs::is_directory( odir ))
|
||||
throw std::runtime_error {
|
||||
"Filesystem element '" + odir.generic_string()
|
||||
+ "' already exists but is not a directory"
|
||||
};
|
||||
|
||||
boost::system::error_code ec{};
|
||||
if (! fs::exists( odir ))
|
||||
fs::create_directories( odir, ec );
|
||||
|
||||
if (ec != boost::system::errc::success) {
|
||||
std::ostringstream msg;
|
||||
|
||||
msg << "Failed to create output directory '"
|
||||
<< odir.generic_string()
|
||||
<< "\nSystem reports: " << ec << '\n';
|
||||
|
||||
throw std::runtime_error { msg.str() };
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Opm {
|
||||
class EclipseIO::Impl {
|
||||
public:
|
||||
Impl( const EclipseState&, EclipseGrid, const Schedule&, const SummaryConfig& );
|
||||
@@ -113,14 +138,16 @@ void EclipseIO::Impl::writeINITFile(const data::Solution& simP
|
||||
|
||||
|
||||
void EclipseIO::Impl::writeEGRIDFile( const NNC& nnc ) {
|
||||
const auto& ioConfig = this->es.getIOConfig();
|
||||
const auto formatted = this->es.cfg().io().getFMTOUT();
|
||||
|
||||
std::string egridFile( ERT::EclFilename( this->outputDir,
|
||||
this->baseName,
|
||||
ECL_EGRID_FILE,
|
||||
ioConfig.getFMTOUT() ));
|
||||
const auto ext = '.'
|
||||
+ (formatted ? std::string{"F"} : std::string{})
|
||||
+ "EGRID";
|
||||
|
||||
this->grid.save( egridFile, ioConfig.getFMTOUT(), nnc, this->es.getDeckUnitSystem());
|
||||
const auto egridFile = (boost::filesystem::path{ this->outputDir }
|
||||
/ (this->baseName + ext)).generic_string();
|
||||
|
||||
this->grid.save( egridFile, formatted, nnc, this->es.getDeckUnitSystem());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -236,19 +263,8 @@ EclipseIO::EclipseIO( const EclipseState& es,
|
||||
{
|
||||
if( !this->impl->output_enabled )
|
||||
return;
|
||||
{
|
||||
const auto& outputDir = this->impl->outputDir;
|
||||
|
||||
// make sure that the output directory exists, if not try to create it
|
||||
if ( !util_entry_exists( outputDir.c_str() ) ) {
|
||||
util_make_path( outputDir.c_str() );
|
||||
}
|
||||
|
||||
if( !util_is_directory( outputDir.c_str() ) ) {
|
||||
throw std::runtime_error( "The path specified as output directory '"
|
||||
+ outputDir + "' is not a directory");
|
||||
}
|
||||
}
|
||||
ensure_directory_exists( this->impl->outputDir );
|
||||
}
|
||||
|
||||
const out::Summary& EclipseIO::summary() {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#include <ert/ecl/ecl_grid_dims.hpp>
|
||||
#include <opm/io/eclipse/EGrid.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
@@ -140,15 +140,11 @@ namespace Opm {
|
||||
void GridDims::binary_init(const Deck& deck) {
|
||||
const DeckKeyword& gdfile_kw = deck.getKeyword("GDFILE");
|
||||
const std::string& gdfile_arg = gdfile_kw.getRecord(0).getItem("filename").get<std::string>(0);
|
||||
std::string filename = deck.makeDeckPath(gdfile_arg);
|
||||
ecl_grid_dims_type * grid_dims = ecl_grid_dims_alloc( filename.c_str(), nullptr );
|
||||
if (grid_dims) {
|
||||
const auto& dims = ecl_grid_dims_iget_dims(grid_dims, 0);
|
||||
m_nx = dims->nx;
|
||||
m_ny = dims->ny;
|
||||
m_nz = dims->nz;
|
||||
} else
|
||||
throw std::invalid_argument("Could not determine grid dimensions from: " + filename);
|
||||
const EclIO::EGrid egrid( deck.makeDeckPath(gdfile_arg) );
|
||||
const auto& dimens = egrid.dimension();
|
||||
m_nx = dimens[0];
|
||||
m_ny = dimens[1];
|
||||
m_nz = dimens[2];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
@@ -32,9 +33,6 @@
|
||||
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
|
||||
|
||||
#include <ert/ecl/EclFilename.hpp>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
namespace {
|
||||
@@ -190,9 +188,28 @@ namespace Opm {
|
||||
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;
|
||||
|
||||
return ERT::EclFilename( restart_base , file_type , report_step , fmt_file );
|
||||
auto ext = std::string{};
|
||||
if (unified) {
|
||||
ext = fmt_file ? "FUNRST" : "UNRST";
|
||||
}
|
||||
else {
|
||||
std::ostringstream os;
|
||||
|
||||
const char* fmt_prefix = "FGH";
|
||||
const char* unfmt_prefix = "XYZ";
|
||||
|
||||
const int cycle = 10 * 1000;
|
||||
const int p_ix = report_step / cycle;
|
||||
const int n = report_step % cycle;
|
||||
|
||||
os << (fmt_file ? fmt_prefix[p_ix] : unfmt_prefix[p_ix])
|
||||
<< std::setw(4) << std::setfill('0') << n;
|
||||
|
||||
ext = os.str();
|
||||
}
|
||||
|
||||
return restart_base + '.' + ext;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Utility/Functional.hpp>
|
||||
|
||||
#include <ert/ecl/ecl_util.h>
|
||||
|
||||
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
|
||||
@@ -708,12 +708,27 @@ void RestartConfig::handleScheduleSection(const SCHEDULESection& schedule, const
|
||||
|
||||
std::string RestartConfig::getRestartFileName(const std::string& restart_base, int report_step, bool unified , bool fmt_file) {
|
||||
|
||||
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 );
|
||||
auto ext = std::string{};
|
||||
if (unified) {
|
||||
ext = fmt_file ? "FUNRST" : "UNRST";
|
||||
}
|
||||
else {
|
||||
std::ostringstream os;
|
||||
|
||||
return restart_filename;
|
||||
const char* fmt_prefix = "FGH";
|
||||
const char* unfmt_prefix = "XYZ";
|
||||
|
||||
const int cycle = 10 * 1000;
|
||||
const int p_ix = report_step / cycle;
|
||||
const int n = report_step % cycle;
|
||||
|
||||
os << (fmt_file ? fmt_prefix[p_ix] : unfmt_prefix[p_ix])
|
||||
<< std::setw(4) << std::setfill('0') << n;
|
||||
|
||||
ext = os.str();
|
||||
}
|
||||
|
||||
return restart_base + '.' + ext;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
#include <ostream>
|
||||
#include <type_traits>
|
||||
|
||||
#include <ert/ecl/ecl_util.h>
|
||||
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/W.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||
@@ -249,9 +247,13 @@ const EclHysterConfig& Runspec::hysterPar() const noexcept
|
||||
available phases in Eclipse restart and init files.
|
||||
*/
|
||||
int Runspec::eclPhaseMask( ) const noexcept {
|
||||
return ( active_phases.active( Phase::WATER ) ? ECL_WATER_PHASE : 0 )
|
||||
| ( active_phases.active( Phase::OIL ) ? ECL_OIL_PHASE : 0 )
|
||||
| ( active_phases.active( Phase::GAS ) ? ECL_GAS_PHASE : 0 );
|
||||
const int water = 1 << 2;
|
||||
const int oil = 1 << 0;
|
||||
const int gas = 1 << 1;
|
||||
|
||||
return ( active_phases.active( Phase::WATER ) ? water : 0 )
|
||||
| ( active_phases.active( Phase::OIL ) ? oil : 0 )
|
||||
| ( active_phases.active( Phase::GAS ) ? gas : 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
|
||||
|
||||
#include <ert/util/util.h>
|
||||
#include <fnmatch.h>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
@@ -728,7 +728,7 @@ double Well2::injection_rate(const SummaryState& st, Phase phase_arg) const {
|
||||
|
||||
bool Well2::wellNameInWellNamePattern(const std::string& wellName, const std::string& wellNamePattern) {
|
||||
bool wellNameInPattern = false;
|
||||
if (util_fnmatch( wellNamePattern.c_str() , wellName.c_str()) == 0) {
|
||||
if (fnmatch( wellNamePattern.c_str() , wellName.c_str() , 0 ) == 0) {
|
||||
wellNameInPattern = true;
|
||||
}
|
||||
return wellNameInPattern;
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <ert/util/util.h>
|
||||
|
||||
#include <fnmatch.h>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/parser/eclipse/Parser/InputErrorAction.hpp>
|
||||
@@ -266,7 +267,7 @@ namespace Opm {
|
||||
const char * c_pattern = pattern.c_str();
|
||||
for (const auto& pair : m_errorContexts) {
|
||||
const std::string& key = pair.first;
|
||||
if (util_fnmatch( c_pattern , key.c_str()) == 0)
|
||||
if (fnmatch( c_pattern , key.c_str() , 0 ) == 0)
|
||||
updateKey( key , action );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,13 +143,14 @@ namespace Opm {
|
||||
m_count = 1;
|
||||
}
|
||||
else {
|
||||
m_count = std::stoi( m_countString );
|
||||
const auto cnt = std::stoi( m_countString );
|
||||
|
||||
if (m_count == 0)
|
||||
if (cnt < 1)
|
||||
// TODO: decorate the deck with a warning instead?
|
||||
throw std::invalid_argument("Specifing zero repetitions is not allowed. Token: \'" + token + "\'.");
|
||||
|
||||
m_count = static_cast<std::size_t>(cnt);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
#ifndef STAR_TOKEN_HPP
|
||||
#define STAR_TOKEN_HPP
|
||||
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
|
||||
#include <opm/parser/eclipse/Utility/Stringview.hpp>
|
||||
#include <ert/util/ssize_t.h>
|
||||
|
||||
namespace Opm {
|
||||
bool isStarToken(const string_view& token,
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
init_(token);
|
||||
}
|
||||
|
||||
size_t count() const {
|
||||
std::size_t count() const {
|
||||
return m_count;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ private:
|
||||
// must be set before calling this method.
|
||||
void init_(const string_view& token);
|
||||
|
||||
ssize_t m_count;
|
||||
std::size_t m_count;
|
||||
std::string m_countString;
|
||||
std::string m_valueString;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user