Merge pull request #77 from joakim-hove/IMPORT
Small utility examples/import_rewrite to update ECLIPSE deck to use IMPORT keywords
This commit is contained in:
commit
0efcf9e806
@ -38,6 +38,12 @@ sim_2p_incomp_reorder \
|
|||||||
sim_wateroil \
|
sim_wateroil \
|
||||||
wells_example
|
wells_example
|
||||||
|
|
||||||
|
if HAVE_ERT
|
||||||
|
noinst_PROGRAMS += import_rewrite
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
# Product constituents. Must be specified for every product that's
|
# Product constituents. Must be specified for every product that's
|
||||||
# built from more than a single ".c" file and/or that link to anything
|
# built from more than a single ".c" file and/or that link to anything
|
||||||
@ -47,8 +53,14 @@ wells_example
|
|||||||
|
|
||||||
compute_tof_SOURCES = compute_tof.cpp
|
compute_tof_SOURCES = compute_tof.cpp
|
||||||
compute_tof_LDADD = $(LDADD) $(LINK_BOOST_FILESYSTEM)
|
compute_tof_LDADD = $(LDADD) $(LINK_BOOST_FILESYSTEM)
|
||||||
|
|
||||||
refine_wells_SOURCES = refine_wells.cpp
|
refine_wells_SOURCES = refine_wells.cpp
|
||||||
|
|
||||||
|
if HAVE_ERT
|
||||||
|
import_rewrite_SOURCES = import_rewrite.cpp
|
||||||
|
import_rewrite_LDADD = $(LDADD) $(LINK_BOOST_FILESYSTEM)
|
||||||
|
endif
|
||||||
|
|
||||||
sim_2p_comp_reorder_SOURCES = sim_2p_comp_reorder.cpp
|
sim_2p_comp_reorder_SOURCES = sim_2p_comp_reorder.cpp
|
||||||
sim_2p_comp_reorder_LDADD = $(LDADD) $(LINK_BOOST_FILESYSTEM)
|
sim_2p_comp_reorder_LDADD = $(LDADD) $(LINK_BOOST_FILESYSTEM)
|
||||||
|
|
||||||
|
253
examples/import_rewrite.cpp
Normal file
253
examples/import_rewrite.cpp
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
#if HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif // HAVE_CONFIG_H
|
||||||
|
|
||||||
|
#include <opm/core/eclipse/EclipseGridParser.hpp>
|
||||||
|
|
||||||
|
#include <boost/filesystem/convenience.hpp>
|
||||||
|
|
||||||
|
#ifdef HAVE_ERT
|
||||||
|
#include <opm/core/utility/writeECLData.hpp>
|
||||||
|
#include <util.h>
|
||||||
|
#include <ecl_util.h>
|
||||||
|
#include <ecl_kw.h>
|
||||||
|
#include <ecl_endian_flip.h>
|
||||||
|
#include <fortio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
Small utility to read through an ECLIPSE input deck and replace
|
||||||
|
occurences of (large) numerical fields like COORD and ZCORN with
|
||||||
|
IMPORT statements of a binary versions of the relevant keywords. The
|
||||||
|
program will follow INCLUDE statements.
|
||||||
|
|
||||||
|
Usage: import_rewrite eclipse_case.data
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
The numerical keywords in the ECLIPSE datafile like e.g. PORO and
|
||||||
|
COORD are not annoted with type information; however when read and
|
||||||
|
written in binary form they are of type float. If the updated
|
||||||
|
datafile should be used with ECLIPSE these float values must be
|
||||||
|
exported as float; this is achieved by setting the outputFloatType
|
||||||
|
variable to ECL_FLOAT_TYPE.
|
||||||
|
|
||||||
|
In OPM all numerical fields are treated as double, hence if the OPM
|
||||||
|
EclipseParser meets an import of a float keyword it will be
|
||||||
|
converted to double. If the output from this little utility will
|
||||||
|
only be used from OPM the output can be saved as double directly by
|
||||||
|
setting the outputFloatType to ECL_DOUBLE_TYPE.
|
||||||
|
*/
|
||||||
|
const ecl_type_enum outputFloatType = ECL_DOUBLE_TYPE;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Only keywords which have more >= minImportSize elements are
|
||||||
|
converted to binary form. This is to avoid convertion short keywords
|
||||||
|
like MAPAXES and TABDIMS.
|
||||||
|
*/
|
||||||
|
const int minImportSize = 10;
|
||||||
|
|
||||||
|
|
||||||
|
using namespace Opm;
|
||||||
|
|
||||||
|
|
||||||
|
static void skipKeyword( std::ifstream& is) {
|
||||||
|
std::string keyword;
|
||||||
|
EclipseGridParser::readKeyword( is , keyword );
|
||||||
|
while (true) {
|
||||||
|
std::ios::pos_type pos = is.tellg();
|
||||||
|
|
||||||
|
if (EclipseGridParser::readKeyword( is , keyword )) {
|
||||||
|
is.seekg( pos ); // Repos to start of keyword for next read.
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
is >> ignoreLine;
|
||||||
|
|
||||||
|
if (!is.good()) {
|
||||||
|
is.clear();
|
||||||
|
is.seekg( 0 , std::ios::end );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void copyKeyword( std::ifstream& is , std::ofstream& os) {
|
||||||
|
std::ios::pos_type start_pos = is.tellg();
|
||||||
|
skipKeyword( is );
|
||||||
|
{
|
||||||
|
std::ios::pos_type end_pos = is.tellg();
|
||||||
|
long length = end_pos - start_pos;
|
||||||
|
|
||||||
|
{
|
||||||
|
char * buffer = new char[length];
|
||||||
|
{
|
||||||
|
is.seekg( start_pos );
|
||||||
|
is.read( buffer , length );
|
||||||
|
}
|
||||||
|
os.write( buffer , length );
|
||||||
|
delete[] buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static ecl_kw_type * loadFromcstdio( const std::string& filename , std::ios::pos_type& offset , ecl_type_enum ecl_type) {
|
||||||
|
ecl_kw_type * ecl_kw;
|
||||||
|
|
||||||
|
FILE * cstream = util_fopen( filename.c_str() , "r");
|
||||||
|
fseek( cstream , offset , SEEK_SET);
|
||||||
|
ecl_kw = ecl_kw_fscanf_alloc_current_grdecl( cstream , ecl_type );
|
||||||
|
offset = ftell( cstream );
|
||||||
|
fclose( cstream );
|
||||||
|
|
||||||
|
return ecl_kw;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static bool convertKeyword( const std::string& inputFile , const std::string& outputPath , std::ifstream& is , FieldType fieldType , std::ofstream& os ) {
|
||||||
|
bool convert = true;
|
||||||
|
ecl_type_enum ecl_type;
|
||||||
|
ecl_kw_type * ecl_kw;
|
||||||
|
|
||||||
|
if (fieldType == Integer)
|
||||||
|
ecl_type = ECL_INT_TYPE;
|
||||||
|
else
|
||||||
|
ecl_type = outputFloatType;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::ios::pos_type inputPos = is.tellg();
|
||||||
|
ecl_kw_type * ecl_kw = loadFromcstdio( inputFile , inputPos , ecl_type );
|
||||||
|
|
||||||
|
if (ecl_kw_get_size( ecl_kw ) >= minImportSize) {
|
||||||
|
{
|
||||||
|
std::string outputFile = outputPath + "/" + ecl_kw_get_header( ecl_kw );
|
||||||
|
fortio_type * fortio = fortio_open_writer( outputFile.c_str() , false , ECL_ENDIAN_FLIP );
|
||||||
|
ecl_kw_fwrite( ecl_kw , fortio );
|
||||||
|
fortio_fclose( fortio );
|
||||||
|
|
||||||
|
os << "IMPORT" << std::endl << " '" << outputFile << "' /" << std::endl << std::endl;
|
||||||
|
}
|
||||||
|
is.seekg( inputPos );
|
||||||
|
} else {
|
||||||
|
copyKeyword( is , os );
|
||||||
|
convert = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ecl_kw_free( ecl_kw );
|
||||||
|
}
|
||||||
|
return convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool parseFile(const std::string& inputFile, std::string& outputFile, const std::string& indent = "") {
|
||||||
|
bool updateFile = false;
|
||||||
|
std::cout << indent << "Parsing " << inputFile << "\n";
|
||||||
|
{
|
||||||
|
std::ifstream is(inputFile.c_str());
|
||||||
|
if (is) {
|
||||||
|
std::ofstream os;
|
||||||
|
std::string keyword;
|
||||||
|
std::string path;
|
||||||
|
{
|
||||||
|
boost::filesystem::path inputPath(inputFile);
|
||||||
|
path = inputPath.parent_path().string();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::string basename;
|
||||||
|
std::string extension;
|
||||||
|
|
||||||
|
outputFile = inputFile;
|
||||||
|
size_t ext_pos = inputFile.rfind(".");
|
||||||
|
if (ext_pos == std::string::npos) {
|
||||||
|
basename = outputFile.substr();
|
||||||
|
extension = "";
|
||||||
|
} else {
|
||||||
|
basename = outputFile.substr(0,ext_pos);
|
||||||
|
extension = outputFile.substr(ext_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
outputFile = basename + "_import" + extension;
|
||||||
|
}
|
||||||
|
os.open( outputFile.c_str() );
|
||||||
|
|
||||||
|
while(is.good()) {
|
||||||
|
is >> ignoreWhitespace;
|
||||||
|
{
|
||||||
|
std::ios::pos_type start_pos = is.tellg();
|
||||||
|
if (EclipseGridParser::readKeyword( is , keyword )) {
|
||||||
|
FieldType fieldType = EclipseGridParser::classifyKeyword( keyword );
|
||||||
|
switch (fieldType) {
|
||||||
|
case(Integer):
|
||||||
|
case(FloatingPoint):
|
||||||
|
{
|
||||||
|
is.seekg( start_pos );
|
||||||
|
if (convertKeyword( inputFile , path , is , fieldType , os )) {
|
||||||
|
std::cout << indent + " " << "Writing binary file: " << path << "/" << keyword << std::endl;
|
||||||
|
updateFile = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(Include):
|
||||||
|
{
|
||||||
|
std::string includeFile = readString(is);
|
||||||
|
if (!path.empty()) {
|
||||||
|
includeFile = path + '/' + includeFile;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::string __outputFile;
|
||||||
|
bool updateInclude = parseFile( includeFile , __outputFile , indent + " ");
|
||||||
|
if (updateInclude) {
|
||||||
|
is.seekg( start_pos );
|
||||||
|
skipKeyword( is );
|
||||||
|
os << "INCLUDE" << std::endl << " '" << __outputFile << "' /" << std::endl << std::endl;
|
||||||
|
}
|
||||||
|
updateFile |= updateInclude;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
is.seekg( start_pos );
|
||||||
|
copyKeyword( is , os);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
is >> ignoreLine; // Not at a valid keyword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os.close();
|
||||||
|
is.close();
|
||||||
|
if (updateFile)
|
||||||
|
std::cout << indent << "Written updated include file: " << outputFile << std::endl;
|
||||||
|
else
|
||||||
|
remove( outputFile.c_str() );
|
||||||
|
} else
|
||||||
|
std::cerr << indent << "** WARNING: Failed to open include file: " << inputFile << " for reading **" << std::endl;
|
||||||
|
}
|
||||||
|
return updateFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2)
|
||||||
|
THROW("Need the name of ECLIPSE file on command line");
|
||||||
|
{
|
||||||
|
std::string outputFile;
|
||||||
|
parseFile(argv[1] , outputFile);
|
||||||
|
}
|
||||||
|
}
|
@ -160,19 +160,62 @@ namespace EclipseKeywords
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
enum FieldType {
|
inline std::string upcase(const std::string& s)
|
||||||
Integer,
|
{
|
||||||
FloatingPoint,
|
std::string us(s);
|
||||||
Timestepping,
|
// Getting the character type facet for toupper().
|
||||||
SpecialField,
|
// We use the classic (i.e. C) locale.
|
||||||
IgnoreWithData,
|
const std::ctype<char>& ct = std::use_facet< std::ctype<char> >(std::locale::classic());
|
||||||
IgnoreNoData,
|
for (int i = 0; i < int(s.size()); ++i) {
|
||||||
Include,
|
us[i] = ct.toupper(s[i]);
|
||||||
Import,
|
}
|
||||||
Unknown
|
return us;
|
||||||
};
|
}
|
||||||
|
|
||||||
inline FieldType classifyKeyword(const string& keyword)
|
|
||||||
|
|
||||||
|
} // anon namespace
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ---------- Member functions ----------
|
||||||
|
|
||||||
|
/// Default constructor.
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
EclipseGridParser::EclipseGridParser()
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
: current_reading_mode_(Regular),
|
||||||
|
start_date_(boost::date_time::not_a_date_time),
|
||||||
|
current_time_days_(0.0),
|
||||||
|
current_epoch_(0),
|
||||||
|
special_field_by_epoch_(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Constructor taking an eclipse filename.
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
EclipseGridParser::EclipseGridParser(const string& filename, bool convert_to_SI)
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
: current_reading_mode_(Regular),
|
||||||
|
start_date_(boost::date_time::not_a_date_time),
|
||||||
|
current_time_days_(0.0),
|
||||||
|
current_epoch_(0),
|
||||||
|
special_field_by_epoch_(1)
|
||||||
|
{
|
||||||
|
// Store directory of filename
|
||||||
|
boost::filesystem::path p(filename);
|
||||||
|
directory_ = p.parent_path().string();
|
||||||
|
ifstream is(filename.c_str());
|
||||||
|
if (!is) {
|
||||||
|
cerr << "Unable to open file " << filename << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
read(is, convert_to_SI);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FieldType EclipseGridParser::classifyKeyword(const string& keyword)
|
||||||
{
|
{
|
||||||
using namespace EclipseKeywords;
|
using namespace EclipseKeywords;
|
||||||
if (count(integer_fields, integer_fields + num_integer_fields, keyword)) {
|
if (count(integer_fields, integer_fields + num_integer_fields, keyword)) {
|
||||||
@ -196,20 +239,9 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string upcase(const std::string& s)
|
|
||||||
{
|
|
||||||
std::string us(s);
|
|
||||||
// Getting the character type facet for toupper().
|
|
||||||
// We use the classic (i.e. C) locale.
|
|
||||||
const std::ctype<char>& ct = std::use_facet< std::ctype<char> >(std::locale::classic());
|
|
||||||
for (int i = 0; i < int(s.size()); ++i) {
|
|
||||||
us[i] = ct.toupper(s[i]);
|
|
||||||
}
|
|
||||||
return us;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool readKeyword(std::istream& is, std::string& keyword)
|
bool EclipseGridParser::readKeyword(std::istream& is, std::string& keyword)
|
||||||
{
|
{
|
||||||
char buf[9];
|
char buf[9];
|
||||||
int i, j;
|
int i, j;
|
||||||
char c;
|
char c;
|
||||||
@ -272,46 +304,6 @@ namespace {
|
|||||||
if(end != keyword.npos)
|
if(end != keyword.npos)
|
||||||
keyword = keyword.substr(0, end+1);
|
keyword = keyword.substr(0, end+1);
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
} // anon namespace
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---------- Member functions ----------
|
|
||||||
|
|
||||||
/// Default constructor.
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
EclipseGridParser::EclipseGridParser()
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
: current_reading_mode_(Regular),
|
|
||||||
start_date_(boost::date_time::not_a_date_time),
|
|
||||||
current_time_days_(0.0),
|
|
||||||
current_epoch_(0),
|
|
||||||
special_field_by_epoch_(1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Constructor taking an eclipse filename.
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
EclipseGridParser::EclipseGridParser(const string& filename, bool convert_to_SI)
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
: current_reading_mode_(Regular),
|
|
||||||
start_date_(boost::date_time::not_a_date_time),
|
|
||||||
current_time_days_(0.0),
|
|
||||||
current_epoch_(0),
|
|
||||||
special_field_by_epoch_(1)
|
|
||||||
{
|
|
||||||
// Store directory of filename
|
|
||||||
boost::filesystem::path p(filename);
|
|
||||||
directory_ = p.parent_path().string();
|
|
||||||
ifstream is(filename.c_str());
|
|
||||||
if (!is) {
|
|
||||||
cerr << "Unable to open file " << filename << endl;
|
|
||||||
throw exception();
|
|
||||||
}
|
|
||||||
read(is, convert_to_SI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,9 +71,23 @@ namespace Opm
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EclipseGridParser
|
enum FieldType {
|
||||||
{
|
Integer,
|
||||||
public:
|
FloatingPoint,
|
||||||
|
Timestepping,
|
||||||
|
SpecialField,
|
||||||
|
IgnoreWithData,
|
||||||
|
IgnoreNoData,
|
||||||
|
Include,
|
||||||
|
Import,
|
||||||
|
Unknown
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class EclipseGridParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
/// Default constructor.
|
/// Default constructor.
|
||||||
EclipseGridParser();
|
EclipseGridParser();
|
||||||
/// Constructor taking an eclipse filename. Unless the second
|
/// Constructor taking an eclipse filename. Unless the second
|
||||||
@ -81,6 +95,11 @@ public:
|
|||||||
/// converted to SI units.
|
/// converted to SI units.
|
||||||
explicit EclipseGridParser(const std::string& filename, bool convert_to_SI = true);
|
explicit EclipseGridParser(const std::string& filename, bool convert_to_SI = true);
|
||||||
|
|
||||||
|
|
||||||
|
static FieldType classifyKeyword(const std::string& keyword);
|
||||||
|
static bool readKeyword(std::istream& is, std::string& keyword);
|
||||||
|
|
||||||
|
|
||||||
/// Read the given stream, overwriting any previous data. Unless
|
/// Read the given stream, overwriting any previous data. Unless
|
||||||
/// the second argument 'convert_to_SI' is false, all fields will
|
/// the second argument 'convert_to_SI' is false, all fields will
|
||||||
/// be converted to SI units.
|
/// be converted to SI units.
|
||||||
@ -240,6 +259,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
|
||||||
#endif // SINTEF_ECLIPSEGRIDPARSER_HEADER
|
#endif // SINTEF_ECLIPSEGRIDPARSER_HEADER
|
||||||
|
Loading…
Reference in New Issue
Block a user