Files
opm-core/opm/core/io/eclipse/EclipseGridParser.hpp
2013-11-25 14:14:46 +01:00

284 lines
9.6 KiB
C++

//===========================================================================
//
// 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);
/// 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(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 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