remove the EclipseGridParser class
RIP!
This commit is contained in:
parent
3941fbc5f1
commit
720acacad3
@ -39,7 +39,6 @@ list (APPEND MAIN_SOURCE_FILES
|
||||
opm/core/grid/cpgpreprocess/preprocess.c
|
||||
opm/core/grid/cpgpreprocess/uniquepoints.c
|
||||
opm/core/io/eclipse/EclipseGridInspector.cpp
|
||||
opm/core/io/eclipse/EclipseGridParser.cpp
|
||||
opm/core/io/eclipse/EclipseWriter.cpp
|
||||
opm/core/io/eclipse/writeECLData.cpp
|
||||
opm/core/io/OutputWriter.cpp
|
||||
@ -256,11 +255,8 @@ list (APPEND PUBLIC_HEADER_FILES
|
||||
opm/core/grid/cpgpreprocess/uniquepoints.h
|
||||
opm/core/io/eclipse/CornerpointChopper.hpp
|
||||
opm/core/io/eclipse/EclipseGridInspector.hpp
|
||||
opm/core/io/eclipse/EclipseGridParser.hpp
|
||||
opm/core/io/eclipse/EclipseGridParserHelpers.hpp
|
||||
opm/core/io/eclipse/EclipseUnits.hpp
|
||||
opm/core/io/eclipse/EclipseWriter.hpp
|
||||
opm/core/io/eclipse/SpecialEclipseFields.hpp
|
||||
opm/core/io/eclipse/writeECLData.hpp
|
||||
opm/core/io/OutputWriter.hpp
|
||||
opm/core/io/vag/vag.hpp
|
||||
|
@ -48,7 +48,7 @@ creation and destruction of an UnstructuredGrid. The method
|
||||
Opm::GridManager::c_grid() provides access to the underlying
|
||||
UnstructuredGrid structure. This class also provides an easy way
|
||||
to initialize a grid from an ECLIPSE-format input deck, via the
|
||||
constructor taking an Opm::EclipseGridParser.
|
||||
constructor taking an Opm::DeckConstPtr.
|
||||
|
||||
|
||||
<h3>Well handling</h3>
|
||||
@ -109,7 +109,7 @@ There are two simulator programs for two-phase immiscible flow in opm-core:
|
||||
<h3>Various utilities</h3>
|
||||
|
||||
Utilities contained in opm-core include:
|
||||
- IO utilities (Opm::EclipseGridParser, binary I/O via the ERT library, vtk output)
|
||||
- IO utilities (binary output via the ERT library, vtk output)
|
||||
- Interpolation utilities (Opm::MonotCubicInterpolator, Opm::VelocityInterpolationECVI)
|
||||
- Support for SI and non-SI units (Opm::unit and Opm::prefix)
|
||||
- Low-order quadratures for general geometries (Opm::CellQuadrature, Opm::FaceQuadrature)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,289 +0,0 @@
|
||||
//===========================================================================
|
||||
//
|
||||
// File: EclipseGridParser.h
|
||||
//
|
||||
// Created: Wed Dec 5 17:05:13 2007
|
||||
//
|
||||
// Author: Atgeirr F Rasmussen <atgeirr@sintef.no>
|
||||
//
|
||||
// $Date$
|
||||
//
|
||||
// Revision: $Id: EclipseGridParser.h,v 1.3 2008/08/18 14:16:13 atgeirr Exp $
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
/*
|
||||
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
|
||||
Copyright 2009, 2010 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/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_ECLIPSEGRIDPARSER_HEADER
|
||||
#define OPM_ECLIPSEGRIDPARSER_HEADER
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <memory>
|
||||
#include <opm/core/io/eclipse/SpecialEclipseFields.hpp>
|
||||
#include <opm/core/io/eclipse/EclipseUnits.hpp>
|
||||
#include <opm/core/utility/Factory.hpp>
|
||||
|
||||
#include <opm/core/grid/cornerpoint_grid.h>
|
||||
#ifdef HAVE_ERT
|
||||
#include <ert/ecl/ecl_kw.h>
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace Opm
|
||||
{
|
||||
|
||||
/**
|
||||
@brief A class for reading and parsing all fields of an eclipse file.
|
||||
|
||||
This object is constructed using an Eclipse .grdecl-file. All data
|
||||
fields are extracted upon construction and written to vector data
|
||||
structures, which can then be read out afterwards via
|
||||
convenience functions.
|
||||
|
||||
There is also a convenience function to easily check which fields
|
||||
were successfully parsed.
|
||||
|
||||
@author Atgeirr F. Rasmussen <atgeirr@sintef.no>
|
||||
@date 2007/12/06 13:00:03
|
||||
|
||||
*/
|
||||
|
||||
enum FieldType {
|
||||
Integer,
|
||||
FloatingPoint,
|
||||
Timestepping,
|
||||
SpecialField,
|
||||
IgnoreWithData,
|
||||
IgnoreNoData,
|
||||
Include,
|
||||
Import,
|
||||
Unknown
|
||||
};
|
||||
|
||||
|
||||
|
||||
class EclipseGridParser
|
||||
{
|
||||
public:
|
||||
/// Default constructor.
|
||||
EclipseGridParser();
|
||||
/// Constructor taking an eclipse filename. Unless the second
|
||||
/// argument 'convert_to_SI' is false, all fields will be
|
||||
/// converted to SI units.
|
||||
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);
|
||||
|
||||
// temporary measure to get the file name passed to the
|
||||
// constuctor above
|
||||
const std::string &deckFileName() const
|
||||
{ return deckFileName_; };
|
||||
|
||||
|
||||
/// Read the given stream, overwriting any previous data. Unless
|
||||
/// the second argument 'convert_to_SI' is false, all fields will
|
||||
/// be converted to SI units.
|
||||
void read(std::istream& is, bool convert_to_SI = true);
|
||||
|
||||
/// Convert all data to SI units, according to unit category as
|
||||
/// specified in the eclipse file (METRIC, FIELD etc.).
|
||||
/// It is unnecessary to call this if constructed with
|
||||
/// 'convert_to_SI' equal to true, but it is not an error.
|
||||
void convertToSI();
|
||||
|
||||
/// Returns true if the given keyword corresponds to a field that
|
||||
/// was found in the file.
|
||||
bool hasField(const std::string& keyword) const;
|
||||
/// Returns true if all the given keywords correspond to fields
|
||||
/// that were found in the file.
|
||||
bool hasFields(const std::vector<std::string>& keywords) const;
|
||||
/// The keywords/fields found in the file.
|
||||
std::vector<std::string> fieldNames() const;
|
||||
|
||||
/// Returns the number of distinct epochs found in the deck SCHEDULE.
|
||||
int numberOfEpochs() const;
|
||||
|
||||
/// Sets the current epoch.
|
||||
/// Valid arguments are in [0, ..., numberOfEpochs() - 1].
|
||||
/// After reading, current epoch always starts at 0.
|
||||
void setCurrentEpoch(int epoch);
|
||||
|
||||
/// Returns the start_date_
|
||||
boost::gregorian::date getStartDate() const;
|
||||
|
||||
/// Returns a reference to a vector containing the values
|
||||
/// corresponding to the given integer keyword.
|
||||
const std::vector<int>& getIntegerValue(const std::string& keyword) const;
|
||||
|
||||
/// Returns a reference to a vector containing the values
|
||||
/// corresponding to the given floating-point keyword.
|
||||
const std::vector<double>& getFloatingPointValue(const std::string& keyword) const;
|
||||
|
||||
/// Returns a reference to a vector containing the values
|
||||
/// corresponding to the given keyword of a type only known
|
||||
/// indirectly (through a template)
|
||||
///
|
||||
/// \tparam T Type of the keyword's value. Currently only int
|
||||
/// and double are supported.
|
||||
template <typename T>
|
||||
const std::vector<T>& getValue(const std::string& keyword) const;
|
||||
|
||||
typedef std::shared_ptr<SpecialBase> SpecialFieldPtr;
|
||||
|
||||
/// Returns a reference to a vector containing pointers to the values
|
||||
/// corresponding to the given keyword when the values are not only integers
|
||||
/// or floats.
|
||||
const SpecialFieldPtr getSpecialValue(const std::string& keyword) const;
|
||||
|
||||
// This macro implements support for a special field keyword. It requires that a subclass
|
||||
// of SpecialBase exists, that has the same name as the keyword.
|
||||
// After using SPECIAL_FIELD(KEYWORD), the public member getKEYWORD will be available.
|
||||
#define SPECIAL_FIELD(keyword) \
|
||||
private: \
|
||||
struct X##keyword { X##keyword() { Factory<SpecialBase>::addCreator<keyword>(#keyword); } }; \
|
||||
X##keyword x##keyword; \
|
||||
public: \
|
||||
const keyword& get##keyword() const \
|
||||
{ return dynamic_cast<const keyword&>(*getSpecialValue(#keyword)); }
|
||||
|
||||
// Support for special fields.
|
||||
SPECIAL_FIELD(SPECGRID)
|
||||
SPECIAL_FIELD(FAULTS)
|
||||
SPECIAL_FIELD(MULTFLT)
|
||||
SPECIAL_FIELD(TITLE)
|
||||
SPECIAL_FIELD(START)
|
||||
SPECIAL_FIELD(DATES)
|
||||
SPECIAL_FIELD(DENSITY)
|
||||
SPECIAL_FIELD(PVDG)
|
||||
SPECIAL_FIELD(PVDO)
|
||||
SPECIAL_FIELD(PVTG)
|
||||
SPECIAL_FIELD(PVTO)
|
||||
SPECIAL_FIELD(PVTW)
|
||||
SPECIAL_FIELD(SGOF)
|
||||
SPECIAL_FIELD(SWOF)
|
||||
SPECIAL_FIELD(ROCK)
|
||||
SPECIAL_FIELD(ROCKTAB)
|
||||
SPECIAL_FIELD(WELSPECS)
|
||||
SPECIAL_FIELD(COMPDAT)
|
||||
SPECIAL_FIELD(WCONINJE)
|
||||
SPECIAL_FIELD(WCONPROD)
|
||||
SPECIAL_FIELD(WELTARG)
|
||||
SPECIAL_FIELD(WELOPEN)
|
||||
SPECIAL_FIELD(EQUIL)
|
||||
SPECIAL_FIELD(PVCDO)
|
||||
SPECIAL_FIELD(TSTEP)
|
||||
SPECIAL_FIELD(PLYVISC)
|
||||
SPECIAL_FIELD(PLYROCK)
|
||||
SPECIAL_FIELD(PLYADS)
|
||||
SPECIAL_FIELD(PLYMAX)
|
||||
SPECIAL_FIELD(PLYSHEAR)
|
||||
SPECIAL_FIELD(TLMIXPAR)
|
||||
SPECIAL_FIELD(WPOLYMER)
|
||||
SPECIAL_FIELD(GRUPTREE)
|
||||
SPECIAL_FIELD(GCONINJE)
|
||||
SPECIAL_FIELD(GCONPROD)
|
||||
SPECIAL_FIELD(WGRUPCON)
|
||||
SPECIAL_FIELD(ENDSCALE)
|
||||
SPECIAL_FIELD(SCALECRS)
|
||||
SPECIAL_FIELD(ENPTVD)
|
||||
SPECIAL_FIELD(ENKRVD)
|
||||
|
||||
// The following fields only have a dummy implementation
|
||||
// that allows us to ignore them.
|
||||
SPECIAL_FIELD(SWFN)
|
||||
SPECIAL_FIELD(SOF2)
|
||||
SPECIAL_FIELD(TUNING)
|
||||
|
||||
#undef SPECIAL_FIELD
|
||||
|
||||
|
||||
/// Sets an integer field to have a particular value.
|
||||
void setIntegerField(const std::string& keyword, const std::vector<int>& field);
|
||||
|
||||
/// Sets a floating point field to have a particular value.
|
||||
void setFloatingPointField(const std::string& keyword, const std::vector<double>& field);
|
||||
|
||||
/// Sets a special field to have a particular value.
|
||||
void setSpecialField(const std::string& keyword, SpecialFieldPtr field);
|
||||
|
||||
/// Compute the units used by the deck, depending on the presence
|
||||
/// of keywords such as METRIC, FIELD etc. It is an error to call
|
||||
/// this after conversion to SI has taken place.
|
||||
void computeUnits();
|
||||
|
||||
/// The units specified by the eclipse file read.
|
||||
const EclipseUnits& units() const;
|
||||
|
||||
struct grdecl get_grdecl() const;
|
||||
|
||||
/// Save grid parts of deck in EGRID format.
|
||||
void saveEGRID(const std::string & filename, int num_cells , const int * global_cell) const;
|
||||
|
||||
#ifdef HAVE_ERT
|
||||
//void saveEGRID_INIT( const std::string& output_dir , const std::string& basename, bool fmt_file = false);
|
||||
void saveINIT( const std::string & filename , const ecl_grid_type * ecl_grid);
|
||||
void saveEGRID_INIT( const std::string& output_dir , const std::string& basename, bool fmt_file);
|
||||
ecl_grid_type * newGrid( );
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
|
||||
#ifdef HAVE_ERT
|
||||
ecl_kw_type * newEclKW(const std::string &keyword , ecl_type_enum ecl_type) const;
|
||||
void save_kw( fortio_type * fortio , const std::string & kw , ecl_type_enum ecl_type);
|
||||
#endif
|
||||
|
||||
SpecialFieldPtr createSpecialField(std::istream& is, const std::string& fieldname);
|
||||
SpecialFieldPtr cloneSpecialField(const std::string& fieldname,
|
||||
const std::shared_ptr<SpecialBase> original);
|
||||
void readImpl(std::istream& is);
|
||||
void getNumericErtFields(const std::string& filename);
|
||||
|
||||
std::string deckFileName_;
|
||||
std::string directory_;
|
||||
std::map<std::string, std::vector<int> > integer_field_map_;
|
||||
std::map<std::string, std::vector<double> > floating_field_map_;
|
||||
// std::map<std::string, SpecialFieldPtr> special_field_map_;
|
||||
std::set<std::string> ignored_fields_;
|
||||
EclipseUnits units_;
|
||||
|
||||
// For SCHEDULE handling.
|
||||
enum ReadingMode { Regular, Timesteps };
|
||||
ReadingMode current_reading_mode_;
|
||||
boost::gregorian::date start_date_;
|
||||
double current_time_days_;
|
||||
int current_epoch_;
|
||||
typedef std::map<std::string, SpecialFieldPtr> SpecialMap;
|
||||
std::vector<SpecialMap> special_field_by_epoch_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
#endif // OPM_ECLIPSEGRIDPARSER_HEADER
|
@ -1,465 +0,0 @@
|
||||
//===========================================================================
|
||||
//
|
||||
// File: EclipseGridParserHelpers.hpp
|
||||
//
|
||||
// Created: Tue Dec 22 11:35:32 2009
|
||||
//
|
||||
// Author(s): Atgeirr F Rasmussen <atgeirr@sintef.no>
|
||||
// B<>rd Skaflestad <bard.skaflestad@sintef.no>
|
||||
//
|
||||
// $Date$
|
||||
//
|
||||
// $Revision$
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
/*
|
||||
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
|
||||
Copyright 2009, 2010 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/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_ECLIPSEGRIDPARSERHELPERS_HEADER
|
||||
#define OPM_ECLIPSEGRIDPARSERHELPERS_HEADER
|
||||
|
||||
#include <opm/core/utility/ErrorMacros.hpp>
|
||||
#include <opm/core/utility/linearInterpolation.hpp>
|
||||
#include <boost/date_time/gregorian/gregorian.hpp>
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <istream>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
namespace Opm
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
inline std::istream& ignoreLine(std::istream& is)
|
||||
{
|
||||
is.ignore(std::numeric_limits<int>::max(), '\n');
|
||||
return is;
|
||||
}
|
||||
|
||||
inline std::istream& ignoreSlashLine(std::istream& is)
|
||||
{
|
||||
is.ignore(std::numeric_limits<int>::max(), '/');
|
||||
is.ignore(std::numeric_limits<int>::max(), '\n');
|
||||
return is;
|
||||
}
|
||||
|
||||
inline std::istream& ignoreWhitespace(std::istream& is)
|
||||
{
|
||||
// Getting the character type facet for is()
|
||||
// We use the classic (i.e. C) locale.
|
||||
const std::ctype<char>& ct = std::use_facet< std::ctype<char> >(std::locale::classic());
|
||||
char c;
|
||||
while (is.get(c)) {
|
||||
if (!ct.is(std::ctype_base::space, c)) {
|
||||
is.putback(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
inline std::string readString(std::istream& is)
|
||||
{
|
||||
std::string string_candidate;
|
||||
is >> string_candidate;
|
||||
const char quote('\'');
|
||||
int beg = string_candidate[0] == quote ? 1 : 0;
|
||||
int len = string_candidate[0] == quote ? string_candidate.size() - 2 : string_candidate.size();
|
||||
return string_candidate.substr(beg, len);
|
||||
}
|
||||
|
||||
// Reads data until '/' or an error is encountered.
|
||||
template<typename T>
|
||||
inline void readVectorData(std::istream& is, std::vector<T>& data)
|
||||
{
|
||||
data.clear();
|
||||
while (is) {
|
||||
T candidate;
|
||||
is >> candidate;
|
||||
if (is.rdstate() & std::ios::failbit) {
|
||||
is.clear(is.rdstate() & ~std::ios::failbit);
|
||||
is >> ignoreWhitespace;
|
||||
char dummy;
|
||||
is >> dummy;
|
||||
if (dummy == '/') {
|
||||
is >> ignoreLine;
|
||||
break;
|
||||
} else if (dummy == '-') { // "comment test"
|
||||
is >> ignoreLine; // This line is a comment
|
||||
} else {
|
||||
char buffer[1000];
|
||||
is.getline(buffer, sizeof(buffer));
|
||||
std::cout << buffer<<std::endl;
|
||||
OPM_THROW(std::runtime_error, "Encountered format error while reading data values. Value = " << dummy);
|
||||
}
|
||||
} else {
|
||||
if (is.peek() == int('*')) {
|
||||
is.ignore(); // ignore the '*'
|
||||
int multiplier = int(candidate);
|
||||
is >> candidate;
|
||||
data.insert(data.end(), multiplier, candidate);
|
||||
} else {
|
||||
data.push_back(candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is) {
|
||||
OPM_THROW(std::runtime_error, "Encountered error while reading data values.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Reads data items of type T. Not more than 'max_values' items.
|
||||
// Asterisks may be used to signify 'repeat counts'. 5*3.14 will
|
||||
// insert 3.14 five times. Asterisk followed by a space is used to
|
||||
// signify default values. n* will default n consecutive quantities.
|
||||
template<class Vec>
|
||||
inline int readDefaultedVectorData(std::istream& is, Vec& data, int max_values)
|
||||
{
|
||||
assert(int(data.size()) >= max_values);
|
||||
const std::ctype<char>& ct = std::use_facet< std::ctype<char> >(std::locale::classic());
|
||||
int num_values = 0;
|
||||
while (is) {
|
||||
typename Vec::value_type candidate;
|
||||
is >> candidate;
|
||||
if (is.rdstate() & std::ios::failbit) {
|
||||
is.clear(is.rdstate() & ~std::ios::failbit);
|
||||
std::string dummy;
|
||||
is >> dummy;
|
||||
if (dummy == "/") {
|
||||
is >> ignoreLine;
|
||||
break;
|
||||
} else if (dummy[0] == '-') { // "comment test"
|
||||
is >> ignoreLine; // This line is a comment
|
||||
} else {
|
||||
OPM_THROW(std::runtime_error, "Encountered format error while reading data values. Value = " << dummy);
|
||||
}
|
||||
} else {
|
||||
if (is.peek() == int('*')) {
|
||||
is.ignore(); // ignore the '*'
|
||||
int multiplier = (int)candidate;
|
||||
if (ct.is(std::ctype_base::space, is.peek())) {
|
||||
num_values += multiplier; // Use default value(s)
|
||||
} else {
|
||||
is >> candidate; // Use candidate 'multipler' times
|
||||
for (int i=0; i<multiplier; ++i, ++num_values) {
|
||||
data[num_values] = candidate;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
data[num_values] = candidate;
|
||||
++num_values;
|
||||
}
|
||||
}
|
||||
if (num_values >= max_values) {
|
||||
//is >> ignoreLine;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!is) {
|
||||
OPM_THROW(std::runtime_error, "Encountered error while reading data values.");
|
||||
}
|
||||
return num_values;
|
||||
}
|
||||
|
||||
|
||||
// Keywords SGOF and SWOF. Reads data until '/' or an error is encountered.
|
||||
// Default values represented by 1* is replaced by -1. Use linear interpolation
|
||||
// outside this function to replace -1.
|
||||
template<typename T>
|
||||
inline void readRelPermTable(std::istream& is, std::vector<T>& data)
|
||||
{
|
||||
data.clear();
|
||||
while (is) {
|
||||
T candidate;
|
||||
is >> candidate;
|
||||
if (is.rdstate() & std::ios::failbit) {
|
||||
is.clear(is.rdstate() & ~std::ios::failbit);
|
||||
std::string dummy;
|
||||
is >> dummy;
|
||||
if (dummy == "/") {
|
||||
is >> ignoreLine;
|
||||
break;
|
||||
} else if (dummy[0] == '-') { // "comment test"
|
||||
is >> ignoreLine; // This line is a comment
|
||||
} else {
|
||||
OPM_THROW(std::runtime_error, "Encountered format error while reading data values. Value = " << dummy);
|
||||
}
|
||||
} else {
|
||||
if (is.peek() == int('*')) {
|
||||
is.ignore(); // ignore the '*'
|
||||
assert(int(candidate) == 1);
|
||||
data.push_back(-1); // Set new flag for interpolation.
|
||||
} else {
|
||||
data.push_back(candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is) {
|
||||
OPM_THROW(std::runtime_error, "Encountered error while reading data values.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Returns month number 1-12. Returns 0 if illegal month name.
|
||||
inline int getMonthNumber(const std::string& month_name)
|
||||
{
|
||||
const int num_months = 12;
|
||||
std::string months[num_months] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
|
||||
"JLY", "AUG", "SEP", "OCT", "NOV", "DEC"};
|
||||
if (month_name == "JUL") {
|
||||
return 7; // "JUL" is an acceptable alternative to 'JLY'
|
||||
}
|
||||
int m = 0;
|
||||
for (int i=0; i<num_months; ++i) {
|
||||
if (month_name == months[i]) {
|
||||
m = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
inline boost::gregorian::date readDate(std::istream& is)
|
||||
{
|
||||
while (is.peek() == int('-')) {
|
||||
is >> ignoreLine; // This line is a comment
|
||||
}
|
||||
int day, year;
|
||||
std::string month_name;
|
||||
is >> day;
|
||||
month_name = readString(is);
|
||||
is >> year;
|
||||
ignoreSlashLine(is);
|
||||
int month = getMonthNumber(month_name);
|
||||
|
||||
return boost::gregorian::date(boost::gregorian::greg_year(year),
|
||||
boost::gregorian::greg_month(month),
|
||||
boost::gregorian::greg_day(day));
|
||||
}
|
||||
|
||||
// Get first character after whitespace and comments, and decide
|
||||
// next action.
|
||||
// NB! Will fail for negative number in column one.
|
||||
inline int next_action(std::istream& is)
|
||||
{
|
||||
int task(0); // 0:continue 1:return 2:throw
|
||||
const std::ctype<char>& ct =
|
||||
std::use_facet< std::ctype<char> >(std::locale::classic());
|
||||
|
||||
while (!is.eof()) {
|
||||
is >> ignoreWhitespace;
|
||||
char c;
|
||||
is.get(c);
|
||||
if (is.eof()) {
|
||||
return task;
|
||||
}
|
||||
is.putback(c);
|
||||
if (ct.is(std::ctype_base::digit, c) || c== '.') {
|
||||
task = 0; // Decimal digit. Read more data.
|
||||
break;
|
||||
}
|
||||
if (ct.is(std::ctype_base::alpha, c)) {
|
||||
task = 1; // Alphabetic char. Read next keyword.
|
||||
break;
|
||||
}
|
||||
if (c == '-') {
|
||||
is >> ignoreLine; // This line is a comment
|
||||
} else {
|
||||
task = 2; // Read error. Unexpected character.
|
||||
break;
|
||||
}
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
// Reads keywords PVTG, PVTO
|
||||
typedef std::vector<std::vector<std::vector<double> > > table_t;
|
||||
inline void readPvtTable(std::istream& is, table_t& pvt_table,
|
||||
const std::string& field_name)
|
||||
{
|
||||
const std::ctype<char>& ct =
|
||||
std::use_facet< std::ctype<char> >(std::locale::classic());
|
||||
std::vector<double> record;
|
||||
std::vector<std::vector<double> > table;
|
||||
while (!is.eof()) {
|
||||
record.clear();
|
||||
readVectorData(is, record);
|
||||
table.push_back(record);
|
||||
while (!is.eof()) {
|
||||
is >> ignoreWhitespace;
|
||||
char c;
|
||||
is.get(c);
|
||||
if (is.eof()) {
|
||||
// Reached end of file, we should have pushed
|
||||
// the last table, and emptied it. If not,
|
||||
// we have an error.
|
||||
if (!table.empty()) {
|
||||
OPM_THROW(std::runtime_error, "Reached EOF while still building PVT table. Missing end-of-table (slash)?");
|
||||
}
|
||||
return;
|
||||
}
|
||||
is.putback(c);
|
||||
if (ct.is(std::ctype_base::digit, c) || c== '.') {
|
||||
break; // Decimal digit. Read more records.
|
||||
}
|
||||
if (ct.is(std::ctype_base::alpha, c)) {
|
||||
return; // Alphabetic char. Read next keyword.
|
||||
}
|
||||
if (c == '-') {
|
||||
is >> ignoreLine; // This line is a comment
|
||||
continue;
|
||||
}
|
||||
if (c == '/') {
|
||||
is >> ignoreLine;
|
||||
pvt_table.push_back(table);
|
||||
table.clear();
|
||||
} else {
|
||||
std::ostringstream oss;
|
||||
oss << "Error reading " << field_name
|
||||
<< ". Next character is " << (char)is.peek();
|
||||
OPM_THROW(std::runtime_error, oss.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reads keywords PVDG, PVDO, ROCKTAB
|
||||
inline void readPvdTable(std::istream& is, table_t& pvd_table,
|
||||
const std::string& field_name, int ncol)
|
||||
{
|
||||
std::vector<double> record;
|
||||
std::vector<std::vector<double> > table(ncol);
|
||||
while (!is.eof()) {
|
||||
record.clear();
|
||||
readVectorData(is, record);
|
||||
const int rec_size = record.size()/ncol;
|
||||
for (int k=0; k<ncol; ++k) {
|
||||
table[k].resize(rec_size);
|
||||
}
|
||||
for (int i=0, n=-1; i<rec_size; ++i) {
|
||||
for (int k=0; k<ncol; ++k) {
|
||||
table[k][i] = record[++n];
|
||||
}
|
||||
}
|
||||
pvd_table.push_back(table);
|
||||
|
||||
int action = next_action(is); // 0:continue 1:return 2:throw
|
||||
if (action == 1) {
|
||||
return; // Alphabetic char. Read next keyword.
|
||||
} else if (action == 2) {
|
||||
std::ostringstream oss;
|
||||
oss << "Error reading " << field_name
|
||||
<< ". Next character is " << (char)is.peek();
|
||||
OPM_THROW(std::runtime_error, oss.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace default values -1 by linear interpolation
|
||||
inline void insertDefaultValues(std::vector<std::vector<double> >& table,
|
||||
int ncol,
|
||||
double defaultOut = 0.0,
|
||||
bool defaultInterpolation = true)
|
||||
{
|
||||
const int sz = table[0].size();
|
||||
for (int k=1; k<ncol; ++k) {
|
||||
std::vector<int> indx;
|
||||
std::vector<double> x;
|
||||
for (int i=0; i<sz; ++i) {
|
||||
if (table[k][i] == -1) {
|
||||
indx.push_back(i);
|
||||
x.push_back(table[0][i]);
|
||||
}
|
||||
}
|
||||
if (!indx.empty()) {
|
||||
std::vector<double> xv, yv;
|
||||
for (int i=0; i<sz; ++i) {
|
||||
if (table[k][i] != -1) {
|
||||
xv.push_back(table[0][i]);
|
||||
yv.push_back(table[k][i]);
|
||||
}
|
||||
}
|
||||
if (xv.empty()) {
|
||||
// Nothing specified, the entire column is defaulted.
|
||||
// We insert default value.
|
||||
for (int i=0; i<int(indx.size()); ++i) {
|
||||
table[k][indx[i]] = defaultOut;
|
||||
}
|
||||
} else if (defaultInterpolation) {
|
||||
// Interpolate
|
||||
for (int i=0; i<int(indx.size()); ++i) {
|
||||
table[k][indx[i]] = linearInterpolation(xv, yv, x[i]);
|
||||
}
|
||||
} else {
|
||||
// Interpolate
|
||||
for (int i=0; i<int(indx.size()); ++i) {
|
||||
table[k][indx[i]] = linearInterpolation(xv, yv, x[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reads keywords SGOF and SWOF
|
||||
inline void readSGWOF(std::istream& is, table_t& relperm_table,
|
||||
const std::string& field_name, int ncol)
|
||||
{
|
||||
std::vector<double> record;
|
||||
std::vector<std::vector<double> > table(ncol);
|
||||
while (!is.eof()) {
|
||||
record.clear();
|
||||
readRelPermTable(is, record);
|
||||
const int rec_size = record.size()/ncol;
|
||||
for (int k=0; k<ncol; ++k) {
|
||||
table[k].resize(rec_size);
|
||||
}
|
||||
for (int i=0, n=-1; i<rec_size; ++i) {
|
||||
for (int k=0; k<ncol; ++k) {
|
||||
table[k][i] = record[++n];
|
||||
}
|
||||
}
|
||||
insertDefaultValues(table, ncol);
|
||||
relperm_table.push_back(table);
|
||||
|
||||
int action = next_action(is); // 0:continue 1:return 2:throw
|
||||
if (action == 1) {
|
||||
return; // Alphabetic char. Read next keyword.
|
||||
} else if (action == 2) {
|
||||
std::ostringstream oss;
|
||||
oss << "Error reading " << field_name
|
||||
<< ". Next character is " << (char)is.peek();
|
||||
OPM_THROW(std::runtime_error, oss.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
|
||||
#endif // OPM_ECLIPSEGRIDPARSERHELPERS_HEADER
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user