From a313dd86d6d540995c542e1825c6bf68e6546e63 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Fri, 11 Apr 2014 17:13:28 +0200 Subject: [PATCH 1/5] convert the EclipseGridInspector to opm-parser that one is completely unused in opm-core (*booo*!), but used quite a bit in dune-cornerpoint and dune-porsol, so let's keep it for now... --- opm/core/io/eclipse/EclipseGridInspector.cpp | 74 +++++++++++++------- opm/core/io/eclipse/EclipseGridInspector.hpp | 13 ++-- opm/core/io/eclipse/EclipseGridParser.cpp | 3 +- opm/core/io/eclipse/EclipseGridParser.hpp | 7 +- 4 files changed, 64 insertions(+), 33 deletions(-) diff --git a/opm/core/io/eclipse/EclipseGridInspector.cpp b/opm/core/io/eclipse/EclipseGridInspector.cpp index 613e14d0..77ac712f 100644 --- a/opm/core/io/eclipse/EclipseGridInspector.cpp +++ b/opm/core/io/eclipse/EclipseGridInspector.cpp @@ -38,8 +38,9 @@ #include "config.h" #endif #include -#include -#include +#include +#include +#include #include #include #include @@ -51,27 +52,42 @@ namespace Opm { -EclipseGridInspector::EclipseGridInspector(const EclipseGridParser& parser) - : parser_(parser) +EclipseGridInspector::EclipseGridInspector(const EclipseGridParser& oldParser) { - std::vector keywords; - keywords.push_back("COORD"); - keywords.push_back("ZCORN"); + Opm::ParserConstPtr parser(new Opm::Parser()); + newParserDeck_ = parser->parseFile(oldParser.deckFileName()); - if (!parser_.hasFields(keywords)) { - OPM_THROW(std::runtime_error, "Needed field is missing in file"); + init_(); +} + + +EclipseGridInspector::EclipseGridInspector(Opm::DeckConstPtr newParserDeck) + : newParserDeck_(newParserDeck) +{ + init_(); +} + +void EclipseGridInspector::init_() +{ + if (!newParserDeck_->hasKeyword("COORD")) { + OPM_THROW(std::runtime_error, "Needed field \"COORD\" is missing in file"); + } + if (!newParserDeck_->hasKeyword("ZCORN")) { + OPM_THROW(std::runtime_error, "Needed field \"ZCORN\" is missing in file"); } - if (parser_.hasField("SPECGRID")) { - const SPECGRID& sgr = parser.getSPECGRID(); - logical_gridsize_[0] = sgr.dimensions[0]; - logical_gridsize_[1] = sgr.dimensions[1]; - logical_gridsize_[2] = sgr.dimensions[2]; - } else if (parser_.hasField("DIMENS")) { - const std::vector& dim = parser.getIntegerValue("DIMENS"); - logical_gridsize_[0] = dim[0]; - logical_gridsize_[1] = dim[1]; - logical_gridsize_[2] = dim[2]; + if (newParserDeck_->hasKeyword("SPECGRID")) { + Opm::DeckRecordConstPtr specgridRecord = + newParserDeck_->getKeyword("SPECGRID")->getRecord(0); + logical_gridsize_[0] = specgridRecord->getItem("NX")->getInt(0); + logical_gridsize_[1] = specgridRecord->getItem("NY")->getInt(0); + logical_gridsize_[2] = specgridRecord->getItem("NZ")->getInt(0); + } else if (newParserDeck_->hasKeyword("DIMENS")) { + Opm::DeckRecordConstPtr dimensRecord = + newParserDeck_->getKeyword("DIMENS")->getRecord(0); + logical_gridsize_[0] = dimensRecord->getItem("NX")->getInt(0); + logical_gridsize_[1] = dimensRecord->getItem("NY")->getInt(0); + logical_gridsize_[2] = dimensRecord->getItem("NZ")->getInt(0); } else { OPM_THROW(std::runtime_error, "Found neither SPECGRID nor DIMENS in file. At least one is needed."); } @@ -90,12 +106,14 @@ EclipseGridInspector::EclipseGridInspector(const EclipseGridParser& parser) std::pair EclipseGridInspector::cellDips(int i, int j, int k) const { checkLogicalCoords(i, j, k); - const std::vector& pillc = parser_.getFloatingPointValue("COORD"); + const std::vector& pillc = + newParserDeck_->getKeyword("COORD")->getSIDoubleData(); int num_pillars = (logical_gridsize_[0] + 1)*(logical_gridsize_[1] + 1); if (6*num_pillars != int(pillc.size())) { throw std::runtime_error("Wrong size of COORD field."); } - const std::vector& z = parser_.getFloatingPointValue("ZCORN"); + const std::vector& z = + newParserDeck_->getKeyword("ZCORN")->getSIDoubleData(); int num_cells = logical_gridsize_[0]*logical_gridsize_[1]*logical_gridsize_[2]; if (8*num_cells != int(z.size())) { throw std::runtime_error("Wrong size of ZCORN field"); @@ -198,12 +216,14 @@ double EclipseGridInspector::cellVolumeVerticalPillars(int i, int j, int k) cons { // Checking parameters and obtaining values from parser. checkLogicalCoords(i, j, k); - const std::vector& pillc = parser_.getFloatingPointValue("COORD"); + const std::vector& pillc = + newParserDeck_->getKeyword("COORD")->getSIDoubleData(); int num_pillars = (logical_gridsize_[0] + 1)*(logical_gridsize_[1] + 1); if (6*num_pillars != int(pillc.size())) { throw std::runtime_error("Wrong size of COORD field."); } - const std::vector& z = parser_.getFloatingPointValue("ZCORN"); + const std::vector& z = + newParserDeck_->getKeyword("ZCORN")->getSIDoubleData(); int num_cells = logical_gridsize_[0]*logical_gridsize_[1]*logical_gridsize_[2]; if (8*num_cells != int(z.size())) { throw std::runtime_error("Wrong size of ZCORN field"); @@ -261,12 +281,12 @@ void EclipseGridInspector::checkLogicalCoords(int i, int j, int k) const std::array EclipseGridInspector::getGridLimits() const { - if (! (parser_.hasField("COORD") && parser_.hasField("ZCORN") && parser_.hasField("SPECGRID")) ) { + if (! (newParserDeck_->hasKeyword("COORD") && newParserDeck_->hasKeyword("ZCORN") && newParserDeck_->hasKeyword("SPECGRID")) ) { throw std::runtime_error("EclipseGridInspector: Grid does not have SPECGRID, COORD, and ZCORN, can't find dimensions."); } - std::vector coord = parser_.getFloatingPointValue("COORD"); - std::vector zcorn = parser_.getFloatingPointValue("ZCORN"); + std::vector coord = newParserDeck_->getKeyword("COORD")->getSIDoubleData(); + std::vector zcorn = newParserDeck_->getKeyword("ZCORN")->getSIDoubleData(); double xmin = +DBL_MAX; double xmax = -DBL_MAX; @@ -315,7 +335,7 @@ std::array EclipseGridInspector::gridSize() const std::array EclipseGridInspector::cellZvals(int i, int j, int k) const { // Get the zcorn field. - const std::vector& z = parser_.getFloatingPointValue("ZCORN"); + const std::vector& z = newParserDeck_->getKeyword("ZCORN")->getSIDoubleData(); int num_cells = logical_gridsize_[0]*logical_gridsize_[1]*logical_gridsize_[2]; if (8*num_cells != int(z.size())) { throw std::runtime_error("Wrong size of ZCORN field"); diff --git a/opm/core/io/eclipse/EclipseGridInspector.hpp b/opm/core/io/eclipse/EclipseGridInspector.hpp index 82bc18b3..e0ee3f70 100644 --- a/opm/core/io/eclipse/EclipseGridInspector.hpp +++ b/opm/core/io/eclipse/EclipseGridInspector.hpp @@ -38,6 +38,9 @@ #include #include +#include +#include +#include namespace Opm { @@ -52,9 +55,6 @@ namespace Opm @author Atgeirr F. Rasmussen @date 2008/06/02 09:46:08 */ - -class EclipseGridParser; - class EclipseGridInspector { public: @@ -62,6 +62,10 @@ public: /// The parser must already have read an Eclipse file. EclipseGridInspector(const EclipseGridParser& parser); + /// Constructor taking a parser as argument. + /// The parser must already have read an Eclipse file. + EclipseGridInspector(Opm::DeckConstPtr newParserDeck); + /// Assuming that the pillars are vertical, compute the /// volume of the cell given by logical coordinates (i, j, k). double cellVolumeVerticalPillars(int i, int j, int k) const; @@ -94,8 +98,9 @@ public: std::array cellZvals(int i, int j, int k) const; private: - const EclipseGridParser& parser_; + Opm::DeckConstPtr newParserDeck_; int logical_gridsize_[3]; + void init_(); void checkLogicalCoords(int i, int j, int k) const; }; diff --git a/opm/core/io/eclipse/EclipseGridParser.cpp b/opm/core/io/eclipse/EclipseGridParser.cpp index e90ad00a..e05534f2 100644 --- a/opm/core/io/eclipse/EclipseGridParser.cpp +++ b/opm/core/io/eclipse/EclipseGridParser.cpp @@ -221,7 +221,8 @@ EclipseGridParser::EclipseGridParser(const string& filename, bool convert_to_SI) // Store directory of filename boost::filesystem::path p(filename); directory_ = p.parent_path().string(); - ifstream is(filename.c_str()); + deckFileName_ = p.string(); + ifstream is(deckFileName_.c_str()); if (!is) { cerr << "Unable to open file " << filename << endl; throw exception(); diff --git a/opm/core/io/eclipse/EclipseGridParser.hpp b/opm/core/io/eclipse/EclipseGridParser.hpp index bdc9749d..bdcbf0f7 100644 --- a/opm/core/io/eclipse/EclipseGridParser.hpp +++ b/opm/core/io/eclipse/EclipseGridParser.hpp @@ -98,6 +98,11 @@ namespace Opm 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 @@ -259,7 +264,7 @@ private: void readImpl(std::istream& is); void getNumericErtFields(const std::string& filename); - + std::string deckFileName_; std::string directory_; std::map > integer_field_map_; std::map > floating_field_map_; From 6a90aa086a1f7d422849325e6f5d9dc630b0ea03 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Fri, 11 Apr 2014 17:28:49 +0200 Subject: [PATCH 2/5] CornerPointChopper: add methods opm-parser'y methods --- opm/core/io/eclipse/CornerpointChopper.hpp | 124 +++++++++++++++++++-- 1 file changed, 113 insertions(+), 11 deletions(-) diff --git a/opm/core/io/eclipse/CornerpointChopper.hpp b/opm/core/io/eclipse/CornerpointChopper.hpp index 0441b781..9c6ec743 100644 --- a/opm/core/io/eclipse/CornerpointChopper.hpp +++ b/opm/core/io/eclipse/CornerpointChopper.hpp @@ -22,6 +22,14 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -38,12 +46,18 @@ namespace Opm CornerPointChopper(const std::string& file) : parser_(file, false) { - for (int dd = 0; dd < 3; ++dd) { - dims_[dd] = parser_.getSPECGRID().dimensions[dd]; - } + Opm::ParserPtr parser(new Opm::Parser()); + deck_ = parser->parseFile(file); + + metricUnits_.reset(Opm::UnitSystem::newMETRIC()); + + Opm::DeckRecordConstPtr specgridRecord = deck_->getKeyword("SPECGRID")->getRecord(0); + dims_[0] = specgridRecord->getItem("NX")->getInt(0); + dims_[1] = specgridRecord->getItem("NY")->getInt(0); + dims_[2] = specgridRecord->getItem("NZ")->getInt(0); int layersz = 8*dims_[0]*dims_[1]; - const std::vector& ZCORN = parser_.getFloatingPointValue("ZCORN"); + const std::vector& ZCORN = deck_->getKeyword("ZCORN")->getRawDoubleData(); botmax_ = *std::max_element(ZCORN.begin(), ZCORN.begin() + layersz/2); topmin_ = *std::min_element(ZCORN.begin() + dims_[2]*layersz - layersz/2, ZCORN.begin() + dims_[2]*layersz); @@ -133,7 +147,7 @@ namespace Opm new_dims_[1] = jmax - jmin; // Filter the coord field - const std::vector& COORD = parser_.getFloatingPointValue("COORD"); + const std::vector& COORD = deck_->getKeyword("COORD")->getRawDoubleData(); int num_coord = COORD.size(); if (num_coord != 6*(dims_[0] + 1)*(dims_[1] + 1)) { std::cerr << "Error! COORD size (" << COORD.size() << ") not consistent with SPECGRID\n"; @@ -166,7 +180,7 @@ namespace Opm // coordinate of the bottom surface, while zmax must be less than or // equal to the lowest coordinate of the top surface. int layersz = 8*dims_[0]*dims_[1]; - const std::vector& ZCORN = parser_.getFloatingPointValue("ZCORN"); + const std::vector& ZCORN = deck_->getKeyword("ZCORN")->getRawDoubleData(); int num_zcorn = ZCORN.size(); if (num_zcorn != layersz*dims_[2]) { std::cerr << "Error! ZCORN size (" << ZCORN.size() << ") not consistent with SPECGRID\n"; @@ -276,8 +290,50 @@ namespace Opm return sp; } + /// Return a sub-deck with fields corresponding to the selected subset. + Opm::DeckConstPtr subDeck() + { + Opm::DeckPtr subDeck(new Opm::Deck); + Opm::DeckKeywordPtr specGridKw(new Opm::DeckKeyword("SPECGRID")); + Opm::DeckRecordPtr specGridRecord(new Opm::DeckRecord()); + Opm::DeckIntItemPtr nxItem(new Opm::DeckIntItem("NX")); + Opm::DeckIntItemPtr nyItem(new Opm::DeckIntItem("NY")); + Opm::DeckIntItemPtr nzItem(new Opm::DeckIntItem("NZ")); + Opm::DeckIntItemPtr numresItem(new Opm::DeckIntItem("NUMRES")); + Opm::DeckStringItemPtr coordTypeItem(new Opm::DeckStringItem("COORD_TYPE")); + + nxItem->push_back(new_dims_[0]); + nyItem->push_back(new_dims_[1]); + nzItem->push_back(new_dims_[2]); + numresItem->push_back(1); + coordTypeItem->push_back("F"); + + specGridRecord->addItem(nxItem); + specGridRecord->addItem(nyItem); + specGridRecord->addItem(nzItem); + specGridRecord->addItem(numresItem); + specGridRecord->addItem(coordTypeItem); + + specGridKw->addRecord(specGridRecord); + + subDeck->addKeyword(specGridKw); + + addDoubleKeyword_(subDeck, "COORD", /*dimension=*/"Length", new_COORD_); + addDoubleKeyword_(subDeck, "ZCORN", /*dimension=*/"Length", new_ZCORN_); + addIntKeyword_(subDeck, "ACTNUM", new_ACTNUM_); + addDoubleKeyword_(subDeck, "PORO", /*dimension=*/"1", new_PORO_); + addDoubleKeyword_(subDeck, "NTG", /*dimension=*/"1", new_NTG_); + addDoubleKeyword_(subDeck, "SWCR", /*dimension=*/"1", new_SWCR_); + addDoubleKeyword_(subDeck, "SOWCR", /*dimension=*/"1", new_SOWCR_); + addDoubleKeyword_(subDeck, "PERMX", /*dimension=*/"Permeability", new_PERMX_); + addDoubleKeyword_(subDeck, "PERMY", /*dimension=*/"Permeability", new_PERMY_); + addDoubleKeyword_(subDeck, "PERMZ", /*dimension=*/"Permeability", new_PERMZ_); + addIntKeyword_(subDeck, "SATNUM", new_SATNUM_); + + return subDeck; + } void writeGrdecl(const std::string& filename) { @@ -307,7 +363,10 @@ namespace Opm bool hasSOWCR() const {return !new_SOWCR_.empty(); } private: - EclipseGridParser parser_; + Opm::EclipseGridParser parser_; + Opm::DeckConstPtr deck_; + std::shared_ptr metricUnits_; + double botmax_; double topmin_; double abszmin_; @@ -327,6 +386,49 @@ namespace Opm int new_dims_[3]; std::vector new_to_old_cell_; + void addDoubleKeyword_(Opm::DeckPtr subDeck, + const std::string& keywordName, + const std::string& dimensionString, + const std::vector& data) + { + if (data.empty()) + return; + + Opm::DeckKeywordPtr dataKw(new Opm::DeckKeyword(keywordName)); + Opm::DeckRecordPtr dataRecord(new Opm::DeckRecord()); + Opm::DeckDoubleItemPtr dataItem(new Opm::DeckDoubleItem("DATA")); + + for (size_t i = 0; i < data.size(); ++i) { + dataItem->push_back(data[i]); + } + + std::shared_ptr dimension = metricUnits_->parse(dimensionString); + dataItem->push_backDimension(/*active=*/dimension, /*default=*/dimension); + + dataRecord->addItem(dataItem); + dataKw->addRecord(dataRecord); + subDeck->addKeyword(dataKw); + } + + void addIntKeyword_(Opm::DeckPtr subDeck, + const std::string& keywordName, + const std::vector& data) + { + if (data.empty()) + return; + + Opm::DeckKeywordPtr dataKw(new Opm::DeckKeyword(keywordName)); + Opm::DeckRecordPtr dataRecord(new Opm::DeckRecord()); + Opm::DeckIntItemPtr dataItem(new Opm::DeckIntItem("DATA")); + + for (size_t i = 0; i < data.size(); ++i) { + dataItem->push_back(data[i]); + } + + dataRecord->addItem(dataItem); + dataKw->addRecord(dataRecord); + subDeck->addKeyword(dataKw); + } template void outputField(std::ostream& os, @@ -366,16 +468,16 @@ namespace Opm void filterDoubleField(const std::string& keyword, std::vector& output_field) { - if (parser_.hasField(keyword)) { - const std::vector& field = parser_.getFloatingPointValue(keyword); + if (deck_->hasKeyword(keyword)) { + const std::vector& field = deck_->getKeyword(keyword)->getRawDoubleData(); filterField(field, output_field); } } void filterIntegerField(const std::string& keyword, std::vector& output_field) { - if (parser_.hasField(keyword)) { - const std::vector& field = parser_.getIntegerValue(keyword); + if (deck_->hasKeyword(keyword)) { + const std::vector& field = deck_->getKeyword(keyword)->getIntData(); filterField(field, output_field); } } From 7917295923e782524093c4f7c7d524c7198401ff Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Thu, 17 Apr 2014 11:50:23 +0200 Subject: [PATCH 3/5] add opm-parser variants for the incompressible property classes --- opm/core/props/IncompPropertiesFromDeck.cpp | 13 ++++- opm/core/props/IncompPropertiesFromDeck.hpp | 10 +++- .../props/pvt/PvtPropertiesIncompFromDeck.cpp | 55 +++++++++++++++++++ .../props/pvt/PvtPropertiesIncompFromDeck.hpp | 5 +- .../props/satfunc/SaturationPropsFromDeck.hpp | 28 ++++------ .../satfunc/SaturationPropsFromDeck_impl.hpp | 24 ++++---- 6 files changed, 104 insertions(+), 31 deletions(-) diff --git a/opm/core/props/IncompPropertiesFromDeck.cpp b/opm/core/props/IncompPropertiesFromDeck.cpp index 3296df64..04306b28 100644 --- a/opm/core/props/IncompPropertiesFromDeck.cpp +++ b/opm/core/props/IncompPropertiesFromDeck.cpp @@ -26,7 +26,6 @@ namespace Opm { - IncompPropertiesFromDeck::IncompPropertiesFromDeck(const EclipseGridParser& deck, const UnstructuredGrid& grid) { @@ -39,6 +38,18 @@ namespace Opm } } + IncompPropertiesFromDeck::IncompPropertiesFromDeck(Opm::DeckConstPtr newParserDeck, + const UnstructuredGrid& grid) + { + rock_.init(newParserDeck, grid.number_of_cells, grid.global_cell, grid.cartdims); + pvt_.init(newParserDeck); + satprops_.init(newParserDeck, grid, 200); + if (pvt_.numPhases() != satprops_.numPhases()) { + OPM_THROW(std::runtime_error, "IncompPropertiesFromDeck::IncompPropertiesFromDeck() - Inconsistent number of phases in pvt data (" + << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_.numPhases() << ")."); + } + } + IncompPropertiesFromDeck::~IncompPropertiesFromDeck() { } diff --git a/opm/core/props/IncompPropertiesFromDeck.hpp b/opm/core/props/IncompPropertiesFromDeck.hpp index 0ca78b95..83718aac 100644 --- a/opm/core/props/IncompPropertiesFromDeck.hpp +++ b/opm/core/props/IncompPropertiesFromDeck.hpp @@ -20,11 +20,11 @@ #ifndef OPM_INCOMPPROPERTIESFROMDECK_HEADER_INCLUDED #define OPM_INCOMPPROPERTIESFROMDECK_HEADER_INCLUDED +#include #include #include #include #include -#include struct UnstructuredGrid; @@ -53,6 +53,14 @@ namespace Opm IncompPropertiesFromDeck(const EclipseGridParser& deck, const UnstructuredGrid& grid); + /// Initialize from deck and grid. + /// \param deck Deck input parser + /// \param grid Grid to which property object applies, needed for the + /// mapping from cell indices (typically from a processed grid) + /// to logical cartesian indices consistent with the deck. + IncompPropertiesFromDeck(Opm::DeckConstPtr newParserDeck, + const UnstructuredGrid& grid); + /// Destructor. virtual ~IncompPropertiesFromDeck(); diff --git a/opm/core/props/pvt/PvtPropertiesIncompFromDeck.cpp b/opm/core/props/pvt/PvtPropertiesIncompFromDeck.cpp index a1fa2aff..33094126 100644 --- a/opm/core/props/pvt/PvtPropertiesIncompFromDeck.cpp +++ b/opm/core/props/pvt/PvtPropertiesIncompFromDeck.cpp @@ -88,6 +88,61 @@ namespace Opm } } + void PvtPropertiesIncompFromDeck::init(Opm::DeckConstPtr newParserDeck ) + { + // If we need multiple regions, this class and the SinglePvt* classes must change. + int region_number = 0; + + PhaseUsage phase_usage = phaseUsageFromDeck(newParserDeck); + if (phase_usage.phase_used[PhaseUsage::Vapour] || + !phase_usage.phase_used[PhaseUsage::Aqua] || + !phase_usage.phase_used[PhaseUsage::Liquid]) { + OPM_THROW(std::runtime_error, "PvtPropertiesIncompFromDeck::init() -- must have gas and oil phases (only) in deck input.\n"); + } + + // Surface densities. Accounting for different orders in eclipse and our code. + if (newParserDeck->hasKeyword("DENSITY")) { + Opm::DeckRecordConstPtr densityRecord = newParserDeck->getKeyword("DENSITY")->getRecord(region_number); + surface_density_[phase_usage.phase_pos[PhaseUsage::Aqua]] = densityRecord->getItem("OIL")->getSIDouble(0); + surface_density_[phase_usage.phase_pos[PhaseUsage::Liquid]] = densityRecord->getItem("WATER")->getSIDouble(0); + } else { + OPM_THROW(std::runtime_error, "Input is missing DENSITY\n"); + } + + // Make reservoir densities the same as surface densities initially. + // We will modify them with formation volume factors if found. + reservoir_density_ = surface_density_; + + // Water viscosity. + if (newParserDeck->hasKeyword("PVTW")) { + Opm::DeckRecordConstPtr pvtwRecord = newParserDeck->getKeyword("PVTW")->getRecord(region_number); + if (pvtwRecord->getItem("WATER_COMPRESSIBILITY")->getSIDouble(0) != 0.0 || + pvtwRecord->getItem("WATER_VISCOSIBILITY")->getSIDouble(0) != 0.0) { + OPM_MESSAGE("Compressibility effects in PVTW are ignored."); + } + reservoir_density_[phase_usage.phase_pos[PhaseUsage::Aqua]] /= pvtwRecord->getItem("WATER_VOL_FACTOR")->getSIDouble(0); + viscosity_[phase_usage.phase_pos[PhaseUsage::Aqua]] = pvtwRecord->getItem("WATER_VISCOSITY")->getSIDouble(0); + } else { + // Eclipse 100 default. + // viscosity_[phase_usage.phase_pos[PhaseUsage::Aqua]] = 0.5*Opm::prefix::centi*Opm::unit::Poise; + OPM_THROW(std::runtime_error, "Input is missing PVTW\n"); + } + + // Oil viscosity. + if (newParserDeck->hasKeyword("PVCDO")) { + Opm::DeckRecordConstPtr pvcdoRecord = newParserDeck->getKeyword("PVCDO")->getRecord(region_number); + + if (pvcdoRecord->getItem("OIL_COMPRESSIBILITY")->getSIDouble(0) != 0.0 || + pvcdoRecord->getItem("OIL_VISCOSIBILITY")->getSIDouble(0) != 0.0) { + OPM_MESSAGE("Compressibility effects in PVCDO are ignored."); + } + reservoir_density_[phase_usage.phase_pos[PhaseUsage::Liquid]] /= pvcdoRecord->getItem("OIL_VOL_FACTOR")->getSIDouble(0); + viscosity_[phase_usage.phase_pos[PhaseUsage::Liquid]] = pvcdoRecord->getItem("OIL_VISCOSITY")->getSIDouble(0); + } else { + OPM_THROW(std::runtime_error, "Input is missing PVCDO\n"); + } + } + const double* PvtPropertiesIncompFromDeck::surfaceDensities() const { return surface_density_.data(); diff --git a/opm/core/props/pvt/PvtPropertiesIncompFromDeck.hpp b/opm/core/props/pvt/PvtPropertiesIncompFromDeck.hpp index 9bc75e8e..4ffe9864 100644 --- a/opm/core/props/pvt/PvtPropertiesIncompFromDeck.hpp +++ b/opm/core/props/pvt/PvtPropertiesIncompFromDeck.hpp @@ -20,8 +20,8 @@ #ifndef OPM_PVTPROPERTIESINCOMPFROMDECK_HEADER_INCLUDED #define OPM_PVTPROPERTIESINCOMPFROMDECK_HEADER_INCLUDED - #include +#include #include namespace Opm @@ -41,6 +41,9 @@ namespace Opm /// Initialize from deck. void init(const EclipseGridParser& deck); + /// Initialize from deck. + void init(Opm::DeckConstPtr newParserDeck); + /// Number of active phases. int numPhases() const; diff --git a/opm/core/props/satfunc/SaturationPropsFromDeck.hpp b/opm/core/props/satfunc/SaturationPropsFromDeck.hpp index bf52b306..8f662b68 100644 --- a/opm/core/props/satfunc/SaturationPropsFromDeck.hpp +++ b/opm/core/props/satfunc/SaturationPropsFromDeck.hpp @@ -63,6 +63,18 @@ namespace Opm const UnstructuredGrid& grid, const int samples); + /// Initialize from deck and grid. + /// \param[in] deck Deck input parser + /// \param[in] grid Grid to which property object applies, needed for the + /// mapping from cell indices (typically from a processed grid) + /// to logical cartesian indices consistent with the deck. + /// \param[in] samples Number of uniform sample points for saturation tables. + /// NOTE: samples will only be used with the SatFuncSetUniform template argument. + void init(Opm::DeckConstPtr newParserDeck, + const UnstructuredGrid& grid, + const int samples); + + /// Initialize from deck and grid. /// \param[in] deck Deck input parser /// \param[in] number_of_cells The number of cells of the grid to which property @@ -84,23 +96,7 @@ namespace Opm const T& begin_cell_centroids, int dimensions, const int samples); - - /// Initialize from deck and grid. - /// \param[in] newParserDeck Deck input parser - /// \param[in] grid Grid to which property object applies, needed for the - /// mapping from cell indices (typically from a processed grid) - /// to logical cartesian indices consistent with the deck. - /// \param[in] samples Number of uniform sample points for saturation tables. - /// NOTE: samples will only be used with the SatFuncSetUniform template argument. - void init(Opm::DeckConstPtr newParserDeck, - const UnstructuredGrid& grid, - const int samples); - /// Initialize from deck and grid. - /// \param[in] newParserDeck Deck input parser - /// \param[in] number_of_cells The number of cells of the grid to which property - /// object applies, needed for the - /// mapping from cell indices (typically from a processed /// grid) to logical cartesian indices consistent with the /// deck. /// \param[in] global_cell The mapping from local cell indices of the grid to diff --git a/opm/core/props/satfunc/SaturationPropsFromDeck_impl.hpp b/opm/core/props/satfunc/SaturationPropsFromDeck_impl.hpp index cf340e7e..e9901ba9 100644 --- a/opm/core/props/satfunc/SaturationPropsFromDeck_impl.hpp +++ b/opm/core/props/satfunc/SaturationPropsFromDeck_impl.hpp @@ -57,6 +57,18 @@ namespace Opm grid.dimensions, samples); } + + /// Initialize from deck. + template + void SaturationPropsFromDeck::init(Opm::DeckConstPtr newParserDeck, + const UnstructuredGrid& grid, + const int samples) + { + init(newParserDeck, grid.number_of_cells, + grid.global_cell, grid.cell_centroids, + grid.dimensions, samples); + } + /// Initialize from deck. template template< class T> @@ -157,18 +169,6 @@ namespace Opm } } - - /// Initialize from deck. - template - void SaturationPropsFromDeck::init(Opm::DeckConstPtr newParserDeck, - const UnstructuredGrid& grid, - const int samples) - { - this->template init(newParserDeck, grid.number_of_cells, - grid.global_cell, grid.cell_centroids, - grid.dimensions, samples); - } - /// Initialize from deck. template template From 3b2aa175d56afb66ad7c6c38545b2ccbd0fc86d5 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Thu, 10 Apr 2014 19:12:48 +0200 Subject: [PATCH 4/5] remove the import_rewrite example that one was quite specific to the old parser and would thus require more work to convert to the opm-parser than what it is worth the effort. If you _really_ want to keep this tool, ping me and I'll port it... --- CMakeLists_files.cmake | 1 - examples/import_rewrite.cpp | 265 ------------------------------------ 2 files changed, 266 deletions(-) delete mode 100644 examples/import_rewrite.cpp diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 5b0c682d..5ab278db 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -211,7 +211,6 @@ list (APPEND EXAMPLE_SOURCE_FILES examples/compute_initial_state.cpp examples/compute_tof.cpp examples/compute_tof_from_files.cpp - examples/import_rewrite.cpp examples/sim_2p_comp_reorder.cpp examples/sim_2p_incomp.cpp examples/wells_example.cpp diff --git a/examples/import_rewrite.cpp b/examples/import_rewrite.cpp deleted file mode 100644 index 37fe1004..00000000 --- a/examples/import_rewrite.cpp +++ /dev/null @@ -1,265 +0,0 @@ -#if HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#include - -#include - -#ifdef HAVE_ERT -#include -#include -#include -#include -#include -#include -#endif - -#include - -/* - 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 version of the same keyword. 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 conversion of 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::string& outputFile , std::ifstream& is , FieldType fieldType , std::ofstream& os ) { - bool convert = true; - ecl_type_enum ecl_type; - - 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) { - { - if (outputPath.empty()) - outputFile = ecl_kw_get_header( ecl_kw ); - else - 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; -} - - - - - -static 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): - { - std::string keywordFile; - is.seekg( start_pos ); - if (convertKeyword( inputFile , path , keywordFile , is , fieldType , os )) { - std::cout << indent + " " << "Writing binary file: " << keywordFile << 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) -try -{ - if (argc != 2) - OPM_THROW(std::runtime_error, "Need the name of ECLIPSE file on command line"); - { - std::string outputFile; - parseFile(argv[1] , outputFile); - } -} -catch (const std::exception &e) { - std::cerr << "Program threw an exception: " << e.what() << "\n"; - throw; -} From 1d7ed184191f93c839a58923dc97c5f75cb70d3e Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Thu, 17 Apr 2014 11:47:50 +0200 Subject: [PATCH 5/5] convert the examples and the tests to opm-parser --- examples/compute_initial_state.cpp | 1 - examples/compute_tof.cpp | 14 +++---- examples/sim_2p_comp_reorder.cpp | 54 ++++++++++-------------- examples/sim_2p_incomp.cpp | 52 ++++++++++------------- examples/wells_example.cpp | 21 +++++----- tests/test_blackoilfluid.cpp | 67 +++++++++++++++++++----------- tests/test_blackoilstate.cpp | 25 ++++++----- tests/test_column_extract.cpp | 11 ++--- tests/test_wellsmanager.cpp | 37 ++++++++--------- 9 files changed, 142 insertions(+), 140 deletions(-) diff --git a/examples/compute_initial_state.cpp b/examples/compute_initial_state.cpp index 3193c9fa..b59a9a40 100644 --- a/examples/compute_initial_state.cpp +++ b/examples/compute_initial_state.cpp @@ -87,7 +87,6 @@ try Opm::ParserPtr parser(new Opm::Parser() ); Opm::DeckConstPtr deck = parser->parseFile(deck_filename); const double grav = param.getDefault("gravity", unit::gravity); - //EclipseGridParser deck(deck_filename); GridManager gm(deck); const UnstructuredGrid& grid = *gm.c_grid(); BlackoilPropertiesFromDeck props(deck, grid, param); diff --git a/examples/compute_tof.cpp b/examples/compute_tof.cpp index c325e070..95d6cfe6 100644 --- a/examples/compute_tof.cpp +++ b/examples/compute_tof.cpp @@ -104,7 +104,7 @@ try // If we have a "deck_filename", grid and props will be read from that. bool use_deck = param.has("deck_filename"); - std::unique_ptr deck; + Opm::DeckConstPtr newParserDeck; std::unique_ptr grid; std::unique_ptr props; std::unique_ptr wells; @@ -115,22 +115,22 @@ try if (use_deck) { std::string deck_filename = param.get("deck_filename"); Opm::ParserPtr parser(new Opm::Parser()); - Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(parser->parseFile(deck_filename))); + newParserDeck = parser->parseFile(deck_filename); + Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(newParserDeck)); - deck.reset(new EclipseGridParser(deck_filename)); // Grid init - grid.reset(new GridManager(*deck)); + grid.reset(new GridManager(newParserDeck)); // Rock and fluid init - props.reset(new IncompPropertiesFromDeck(*deck, *grid->c_grid())); + props.reset(new IncompPropertiesFromDeck(newParserDeck, *grid->c_grid())); // Wells init. wells.reset(new Opm::WellsManager(eclipseState , 0 , *grid->c_grid(), props->permeability())); // Gravity. - gravity[2] = deck->hasField("NOGRAV") ? 0.0 : unit::gravity; + gravity[2] = newParserDeck->hasKeyword("NOGRAV") ? 0.0 : unit::gravity; // Init state variables (saturation and pressure). if (param.has("init_saturation")) { initStateBasic(*grid->c_grid(), *props, param, gravity[2], state); } else { - initStateFromDeck(*grid->c_grid(), *props, *deck, gravity[2], state); + initStateFromDeck(*grid->c_grid(), *props, newParserDeck, gravity[2], state); } } else { // Grid init. diff --git a/examples/sim_2p_comp_reorder.cpp b/examples/sim_2p_comp_reorder.cpp index aaddefe2..9ce2270e 100644 --- a/examples/sim_2p_comp_reorder.cpp +++ b/examples/sim_2p_comp_reorder.cpp @@ -85,35 +85,37 @@ try // If we have a "deck_filename", grid and props will be read from that. bool use_deck = param.has("deck_filename"); EclipseStateConstPtr eclipseState; - std::unique_ptr deck; std::unique_ptr grid; std::unique_ptr props; std::unique_ptr rock_comp; + + ParserPtr parser(new Opm::Parser()); + Opm::DeckConstPtr newParserDeck; + BlackoilState state; // bool check_well_controls = false; // int max_well_control_iterations = 0; double gravity[3] = { 0.0 }; if (use_deck) { - ParserPtr parser(new Opm::Parser()); std::string deck_filename = param.get("deck_filename"); + newParserDeck = parser->parseFile(deck_filename); - eclipseState.reset( new EclipseState(parser->parseFile(deck_filename))); - deck.reset(new EclipseGridParser(deck_filename)); + eclipseState.reset(new EclipseState(newParserDeck)); // Grid init - grid.reset(new GridManager(*deck)); + grid.reset(new GridManager(newParserDeck)); // Rock and fluid init - props.reset(new BlackoilPropertiesFromDeck(*deck, *grid->c_grid(), param)); + props.reset(new BlackoilPropertiesFromDeck(newParserDeck, *grid->c_grid(), param)); // check_well_controls = param.getDefault("check_well_controls", false); // max_well_control_iterations = param.getDefault("max_well_control_iterations", 10); // Rock compressibility. - rock_comp.reset(new RockCompressibility(*deck)); + rock_comp.reset(new RockCompressibility(newParserDeck)); // Gravity. - gravity[2] = deck->hasField("NOGRAV") ? 0.0 : unit::gravity; + gravity[2] = newParserDeck->hasKeyword("NOGRAV") ? 0.0 : unit::gravity; // Init state variables (saturation and pressure). if (param.has("init_saturation")) { initStateBasic(*grid->c_grid(), *props, param, gravity[2], state); } else { - initStateFromDeck(*grid->c_grid(), *props, *deck, gravity[2], state); + initStateFromDeck(*grid->c_grid(), *props, newParserDeck, gravity[2], state); } initBlackoilSurfvol(*grid->c_grid(), *props, state); } else { @@ -196,9 +198,7 @@ try } - std::cout << "\n\n================ Starting main simulation loop ===============\n" - << " (number of epochs: " - << (use_deck ? deck->numberOfEpochs() : 1) << ")\n\n" << std::flush; + std::cout << "\n\n================ Starting main simulation loop ===============\n"; SimulatorReport rep; if (!use_deck) { @@ -225,36 +225,24 @@ try int step = 0; SimulatorTimer simtimer; // Use timer for last epoch to obtain total time. - deck->setCurrentEpoch(deck->numberOfEpochs() - 1); - simtimer.init(*deck); + Opm::TimeMapPtr timeMap(new Opm::TimeMap(newParserDeck)); + simtimer.init(timeMap); const double total_time = simtimer.totalTime(); - for (int epoch = 0; epoch < deck->numberOfEpochs(); ++epoch) { - // Set epoch index. - deck->setCurrentEpoch(epoch); - - // Update the timer. - if (deck->hasField("TSTEP")) { - simtimer.init(*deck); - } else { - if (epoch != 0) { - OPM_THROW(std::runtime_error, "No TSTEP in deck for epoch " << epoch); - } - simtimer.init(param); - } + for (size_t reportStepIdx = 0; reportStepIdx < timeMap->numTimesteps(); ++reportStepIdx) { simtimer.setCurrentStepNum(step); simtimer.setTotalTime(total_time); - // Report on start of epoch. - std::cout << "\n\n-------------- Starting epoch " << epoch << " --------------" + // Report on start of report step. + std::cout << "\n\n-------------- Starting report step " << reportStepIdx << " --------------" << "\n (number of steps: " << simtimer.numSteps() - step << ")\n\n" << std::flush; // Create new wells, well_state - WellsManager wells(eclipseState , epoch , *grid->c_grid(), props->permeability()); + WellsManager wells(eclipseState , reportStepIdx , *grid->c_grid(), props->permeability()); // @@@ HACK: we should really make a new well state and - // properly transfer old well state to it every epoch, + // properly transfer old well state to it every report step, // since number of wells may change etc. - if (epoch == 0) { + if (reportStepIdx == 0) { well_state.init(wells.c_wells(), state); } @@ -268,7 +256,7 @@ try bcs.c_bcs(), linsolver, grav); - if (epoch == 0) { + if (reportStepIdx == 0) { warnIfUnusedParams(param); } SimulatorReport epoch_rep = simulator.run(simtimer, state, well_state); diff --git a/examples/sim_2p_incomp.cpp b/examples/sim_2p_incomp.cpp index e28f90f4..cf1efe99 100644 --- a/examples/sim_2p_incomp.cpp +++ b/examples/sim_2p_incomp.cpp @@ -100,7 +100,7 @@ try bool use_deck = param.has("deck_filename"); EclipseStateConstPtr eclipseState; - std::unique_ptr deck; + Opm::DeckConstPtr newParserDeck; std::unique_ptr grid; std::unique_ptr props; std::unique_ptr rock_comp; @@ -110,24 +110,25 @@ try double gravity[3] = { 0.0 }; if (use_deck) { ParserPtr parser(new Opm::Parser()); + std::string deck_filename = param.get("deck_filename"); - deck.reset(new EclipseGridParser(deck_filename)); - eclipseState.reset( new EclipseState(parser->parseFile(deck_filename))); + newParserDeck = parser->parseFile(deck_filename); + eclipseState.reset( new EclipseState(newParserDeck)); // Grid init - grid.reset(new GridManager(*deck)); + grid.reset(new GridManager(newParserDeck)); // Rock and fluid init - props.reset(new IncompPropertiesFromDeck(*deck, *grid->c_grid())); + props.reset(new IncompPropertiesFromDeck(newParserDeck, *grid->c_grid())); // check_well_controls = param.getDefault("check_well_controls", false); // max_well_control_iterations = param.getDefault("max_well_control_iterations", 10); // Rock compressibility. - rock_comp.reset(new RockCompressibility(*deck)); + rock_comp.reset(new RockCompressibility(newParserDeck)); // Gravity. - gravity[2] = deck->hasField("NOGRAV") ? 0.0 : unit::gravity; + gravity[2] = newParserDeck->hasKeyword("NOGRAV") ? 0.0 : unit::gravity; // Init state variables (saturation and pressure). if (param.has("init_saturation")) { initStateBasic(*grid->c_grid(), *props, param, gravity[2], state); } else { - initStateFromDeck(*grid->c_grid(), *props, *deck, gravity[2], state); + initStateFromDeck(*grid->c_grid(), *props, newParserDeck, gravity[2], state); } } else { // Grid init. @@ -213,10 +214,11 @@ try param.writeParam(output_dir + "/simulation.param"); } + Opm::TimeMapPtr timeMap(new Opm::TimeMap(newParserDeck)); std::cout << "\n\n================ Starting main simulation loop ===============\n" - << " (number of epochs: " - << (use_deck ? deck->numberOfEpochs() : 1) << ")\n\n" << std::flush; + << " (number of report steps: " + << (use_deck ? timeMap->numTimesteps() : 1) << ")\n\n" << std::flush; SimulatorReport rep; if (!use_deck) { @@ -243,36 +245,24 @@ try int step = 0; SimulatorTimer simtimer; // Use timer for last epoch to obtain total time. - deck->setCurrentEpoch(deck->numberOfEpochs() - 1); - simtimer.init(*deck); + simtimer.init(timeMap); const double total_time = simtimer.totalTime(); - for (int epoch = 0; epoch < deck->numberOfEpochs(); ++epoch) { - // Set epoch index. - deck->setCurrentEpoch(epoch); - + for (size_t reportStepIdx = 0; reportStepIdx < timeMap->numTimesteps(); ++reportStepIdx) { // Update the timer. - if (deck->hasField("TSTEP")) { - simtimer.init(*deck); - } else { - if (epoch != 0) { - OPM_THROW(std::runtime_error, "No TSTEP in deck for epoch " << epoch); - } - simtimer.init(param); - } simtimer.setCurrentStepNum(step); simtimer.setTotalTime(total_time); - // Report on start of epoch. - std::cout << "\n\n-------------- Starting epoch " << epoch << " --------------" - << "\n (number of steps: " + // Report on start of report step. + std::cout << "\n\n-------------- Starting report step " << reportStepIdx << " --------------" + << "\n (number of time steps: " << simtimer.numSteps() - step << ")\n\n" << std::flush; // Create new wells, well_state - WellsManager wells(eclipseState , epoch , *grid->c_grid(), props->permeability()); + WellsManager wells(eclipseState , reportStepIdx , *grid->c_grid(), props->permeability()); // @@@ HACK: we should really make a new well state and - // properly transfer old well state to it every epoch, + // properly transfer old well state to it every report step, // since number of wells may change etc. - if (epoch == 0) { + if (reportStepIdx == 0) { well_state.init(wells.c_wells(), state); } @@ -286,7 +276,7 @@ try bcs.c_bcs(), linsolver, grav); - if (epoch == 0) { + if (reportStepIdx == 0) { warnIfUnusedParams(param); } SimulatorReport epoch_rep = simulator.run(simtimer, state, well_state); diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index d0b91531..ea8db46f 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -1,8 +1,7 @@ #include "config.h" -#include -#include -#include +#include +#include #include #include @@ -20,6 +19,7 @@ #include #include +#include #include int main(int argc, char** argv) @@ -34,16 +34,17 @@ try simtimer.init(parameters); // Read input file - EclipseGridParser parser(file_name); + Opm::ParserPtr parser(new Opm::Parser()); + Opm::DeckConstPtr newParserDeck = parser->parseFile(file_name); std::cout << "Done!" << std::endl; + // Setup grid - GridManager grid(parser); + GridManager grid(newParserDeck); // Define rock and fluid properties - IncompPropertiesFromDeck incomp_properties(parser, *grid.c_grid()); - RockCompressibility rock_comp(parser); - ParserPtr newParser(new Opm::Parser()); - EclipseStateConstPtr eclipseState(new Opm::EclipseState(newParser->parseFile(file_name))); + IncompPropertiesFromDeck incomp_properties(newParserDeck, *grid.c_grid()); + RockCompressibility rock_comp(newParserDeck); + EclipseStateConstPtr eclipseState(new Opm::EclipseState(newParserDeck)); // Finally handle the wells WellsManager wells(eclipseState , 0 , *grid.c_grid(), incomp_properties.permeability()); @@ -75,7 +76,7 @@ try Opm::TwophaseState state; - initStateFromDeck(*grid.c_grid(), incomp_properties, parser, gravity[2], state); + initStateFromDeck(*grid.c_grid(), incomp_properties, newParserDeck, gravity[2], state); Opm::WellState well_state; well_state.init(wells.c_wells(), state); diff --git a/tests/test_blackoilfluid.cpp b/tests/test_blackoilfluid.cpp index a1491f13..2bd26751 100644 --- a/tests/test_blackoilfluid.cpp +++ b/tests/test_blackoilfluid.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -12,6 +11,14 @@ #include #include +#include +#include +#include +#include +#include +#include +#include + #if HAVE_DYNAMIC_BOOST_TEST #define BOOST_TEST_DYN_LINK #endif @@ -29,7 +36,7 @@ using namespace Opm; using namespace std; -std::vector > getProps(const EclipseGridParser deck,PhaseUsage phase_usage_){ +std::vector > getProps(Opm::DeckConstPtr newParserDeck,PhaseUsage phase_usage_){ enum PhaseIndex { Aqua = 0, Liquid = 1, Vapour = 2 }; @@ -42,8 +49,9 @@ std::vector > getProps(const EclipseGridPars // Water PVT if (phase_usage_.phase_used[Aqua]) { - if (deck.hasField("PVTW")) { - props_[phase_usage_.phase_pos[Aqua]].reset(new SinglePvtConstCompr(deck.getPVTW().pvtw_)); + if (newParserDeck->hasKeyword("PVTW")) { + Opm::PvtwTable pvtwTable(newParserDeck->getKeyword("PVTW")); + props_[phase_usage_.phase_pos[Aqua]].reset(new SinglePvtConstCompr(pvtwTable)); } else { // Eclipse 100 default. props_[phase_usage_.phase_pos[Aqua]].reset(new SinglePvtConstCompr(0.5*Opm::prefix::centi*Opm::unit::Poise)); @@ -52,31 +60,39 @@ std::vector > getProps(const EclipseGridPars // Oil PVT if (phase_usage_.phase_used[Liquid]) { - if (deck.hasField("PVDO")) { + if (newParserDeck->hasKeyword("PVDO")) { + Opm::PvdoTable pvdoTable(newParserDeck->getKeyword("PVDO")); if (samples > 0) { - props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDeadSpline(deck.getPVDO().pvdo_, samples)); + props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDeadSpline(pvdoTable, samples)); } else { - props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDead(deck.getPVDO().pvdo_)); + props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDead(pvdoTable)); } - } else if (deck.hasField("PVTO")) { + } else if (newParserDeck->hasKeyword("PVTO")) { + Opm::PvtoTable pvtoTable(newParserDeck->getKeyword("PVTO"), /*tableIdx=*/0); - props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtLiveOil(deck.getPVTO().pvto_)); - } else if (deck.hasField("PVCDO")) { - props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtConstCompr(deck.getPVCDO().pvcdo_)); + props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtLiveOil(pvtoTable)); + } else if (newParserDeck->hasKeyword("PVCDO")) { + Opm::PvcdoTable pvcdoTable(newParserDeck->getKeyword("PVCDO"), /*tableIdx=*/0); + + props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtConstCompr(pvcdoTable)); } else { OPM_THROW(std::runtime_error, "Input is missing PVDO or PVTO\n"); } } // Gas PVT if (phase_usage_.phase_used[Vapour]) { - if (deck.hasField("PVDG")) { + if (newParserDeck->hasKeyword("PVDG")) { + Opm::PvdgTable pvdgTable(newParserDeck->getKeyword("PVDG")); + if (samples > 0) { - props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDeadSpline(deck.getPVDG().pvdg_, samples)); + props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDeadSpline(pvdgTable, samples)); } else { - props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDead(deck.getPVDG().pvdg_)); + props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDead(pvdgTable)); } - } else if (deck.hasField("PVTG")) { - props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtLiveGas(deck.getPVTG().pvtg_)); + } else if (newParserDeck->hasKeyword("PVTG")) { + Opm::PvtgTable pvtgTable(newParserDeck->getKeyword("PVTG"), /*tableIdx=*/0); + + props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtLiveGas(pvtgTable)); } else { OPM_THROW(std::runtime_error, "Input is missing PVDG or PVTG\n"); } @@ -213,13 +229,14 @@ BOOST_AUTO_TEST_CASE(test_liveoil) // read eclipse deck - const string filename = "liveoil.DATA"; + const std::string filename = "liveoil.DATA"; cout << "Reading deck: " << filename << endl; - const EclipseGridParser deck (filename); + Opm::ParserPtr parser(new Opm::Parser()); + Opm::DeckConstPtr newParserDeck(parser->parseFile(filename)); // setup pvt interface - PhaseUsage phase_usage_ = phaseUsageFromDeck(deck); - std::vector > props_ = getProps(deck,phase_usage_); + PhaseUsage phase_usage_ = phaseUsageFromDeck(newParserDeck); + std::vector > props_ = getProps(newParserDeck,phase_usage_); // setup a test case. We will check 6 [p,r] pairs and compare them to both the [p,z] interface and a finite difference @@ -286,13 +303,15 @@ BOOST_AUTO_TEST_CASE(test_wetgas) // read eclipse deck - const string filename = "wetgas.DATA"; + + const std::string filename = "wetgas.DATA"; cout << "Reading deck: " << filename << endl; - const EclipseGridParser deck (filename); + Opm::ParserPtr parser(new Opm::Parser()); + Opm::DeckConstPtr newParserDeck(parser->parseFile(filename)); // setup pvt interface - PhaseUsage phase_usage_ = phaseUsageFromDeck(deck); - std::vector > props_ = getProps(deck,phase_usage_); + PhaseUsage phase_usage_ = phaseUsageFromDeck(newParserDeck); + std::vector > props_ = getProps(newParserDeck,phase_usage_); // setup a test case. We will check 6 [p,r] pairs and compare them to both the [p,z] interface and a finite difference diff --git a/tests/test_blackoilstate.cpp b/tests/test_blackoilstate.cpp index 255229a5..095f224a 100644 --- a/tests/test_blackoilstate.cpp +++ b/tests/test_blackoilstate.cpp @@ -1,9 +1,11 @@ #include -#include #include - #include + +#include +#include + #if HAVE_DYNAMIC_BOOST_TEST #define BOOST_TEST_DYN_LINK #endif @@ -29,12 +31,13 @@ BOOST_AUTO_TEST_CASE(EqualsDifferentDeckReturnFalse) { const string filename1 = "testBlackoilState1.DATA"; const string filename2 = "testBlackoilState2.DATA"; - const EclipseGridParser deck1 (filename1); - const EclipseGridParser deck2 (filename2); + Opm::ParserPtr parser(new Opm::Parser()); + Opm::DeckConstPtr newParserDeck1(parser->parseFile(filename1)); + Opm::DeckConstPtr newParserDeck2(parser->parseFile(filename2)); - GridManager gridManager1(deck1); + GridManager gridManager1(newParserDeck1); const UnstructuredGrid* grid1 = gridManager1.c_grid(); - GridManager gridManager2(deck2); + GridManager gridManager2(newParserDeck2); const UnstructuredGrid* grid2 = gridManager2.c_grid(); BlackoilState state1; @@ -51,9 +54,10 @@ BOOST_AUTO_TEST_CASE(EqualsDifferentDeckReturnFalse) { BOOST_AUTO_TEST_CASE(EqualsDifferentNumPhasesReturnFalse) { const string filename = "testBlackoilState1.DATA"; - const EclipseGridParser deck (filename); + Opm::ParserPtr parser(new Opm::Parser()); + Opm::DeckConstPtr newParserDeck(parser->parseFile(filename)); - GridManager gridManager(deck); + GridManager gridManager(newParserDeck); const UnstructuredGrid* grid = gridManager.c_grid(); BlackoilState state1; @@ -70,9 +74,10 @@ BOOST_AUTO_TEST_CASE(EqualsDifferentNumPhasesReturnFalse) { BOOST_AUTO_TEST_CASE(EqualsNumericalDifferenceReturnFalse) { const string filename = "testBlackoilState1.DATA"; - const EclipseGridParser deck (filename); + Opm::ParserPtr parser(new Opm::Parser()); + Opm::DeckConstPtr newParserDeck(parser->parseFile(filename)); - GridManager gridManager(deck); + GridManager gridManager(newParserDeck); const UnstructuredGrid* grid = gridManager.c_grid(); BlackoilState state1; diff --git a/tests/test_column_extract.cpp b/tests/test_column_extract.cpp index c07124b8..ba810027 100644 --- a/tests/test_column_extract.cpp +++ b/tests/test_column_extract.cpp @@ -10,7 +10,9 @@ #include #include #include -#include + +#include +#include #include #include @@ -128,11 +130,10 @@ BOOST_AUTO_TEST_CASE(DisjointColumn) correct_answer[4].resize(1); correct_answer[9].resize(1); - std::istringstream is(grdecl); + Opm::ParserPtr parser(new Opm::Parser()); + Opm::DeckConstPtr newParserDeck(parser->parseString(grdecl)); - Opm::EclipseGridParser deck; - deck.read(is); - Opm::GridManager manager(deck); + Opm::GridManager manager(newParserDeck); VVI columns; Opm::extractColumn(*manager.c_grid(), columns); diff --git a/tests/test_wellsmanager.cpp b/tests/test_wellsmanager.cpp index 2141e4bf..b652aafc 100644 --- a/tests/test_wellsmanager.cpp +++ b/tests/test_wellsmanager.cpp @@ -35,7 +35,6 @@ #include #include -#include #include @@ -175,11 +174,12 @@ void check_controls_epoch1( struct WellControls ** ctrls) { BOOST_AUTO_TEST_CASE(New_Constructor_Works) { + const std::string filename = "wells_manager_data.data"; Opm::ParserPtr parser(new Opm::Parser()); - Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(parser->parseFile("wells_manager_data.data"))); + Opm::DeckConstPtr newParserDeck(parser->parseFile(filename)); - Opm::EclipseGridParser Deck("wells_manager_data.data"); - Opm::GridManager gridManager(Deck); + Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(newParserDeck)); + Opm::GridManager gridManager(newParserDeck); { Opm::WellsManager wellsManager(eclipseState, 0, *gridManager.c_grid(), NULL); @@ -197,10 +197,12 @@ BOOST_AUTO_TEST_CASE(New_Constructor_Works) { BOOST_AUTO_TEST_CASE(WellsEqual) { - Opm::EclipseGridParser Deck("wells_manager_data.data"); - Opm::GridManager gridManager(Deck); + const std::string filename = "wells_manager_data.data"; Opm::ParserPtr parser(new Opm::Parser()); - Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(parser->parseFile("wells_manager_data.data"))); + Opm::DeckConstPtr newParserDeck(parser->parseFile(filename)); + + Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(newParserDeck)); + Opm::GridManager gridManager(newParserDeck); Opm::WellsManager wellsManager0(eclipseState , 0 , *gridManager.c_grid(), NULL); Opm::WellsManager wellsManager1(eclipseState , 1 , *gridManager.c_grid(), NULL); @@ -211,11 +213,12 @@ BOOST_AUTO_TEST_CASE(WellsEqual) { BOOST_AUTO_TEST_CASE(ControlsEqual) { - Opm::EclipseGridParser Deck("wells_manager_data.data"); - Opm::GridManager gridManager(Deck); - + const std::string filename = "wells_manager_data.data"; Opm::ParserPtr parser(new Opm::Parser()); - Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(parser->parseFile("wells_manager_data.data"))); + Opm::DeckConstPtr newParserDeck(parser->parseFile(filename)); + + Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(newParserDeck)); + Opm::GridManager gridManager(newParserDeck); Opm::WellsManager wellsManager0(eclipseState , 0 , *gridManager.c_grid(), NULL); Opm::WellsManager wellsManager1(eclipseState , 1 , *gridManager.c_grid(), NULL); @@ -234,16 +237,12 @@ BOOST_AUTO_TEST_CASE(ControlsEqual) { BOOST_AUTO_TEST_CASE(WellHasSTOP_ExceptionIsThrown) { - Opm::EclipseGridParser Deck("wells_manager_data_wellSTOP.data"); - Opm::GridManager gridManager(Deck); - + const std::string filename = "wells_manager_data_wellSTOP.data"; Opm::ParserPtr parser(new Opm::Parser()); - Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(parser->parseFile("wells_manager_data_wellSTOP.data"))); + Opm::DeckConstPtr newParserDeck(parser->parseFile(filename)); - Deck.setCurrentEpoch(0); + Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(newParserDeck)); + Opm::GridManager gridManager(newParserDeck); BOOST_CHECK_THROW( new Opm::WellsManager(eclipseState, 0, *gridManager.c_grid(), NULL), std::runtime_error ); } - - -