From 5371e19d1924effc530d6f208c65d1a31937f8d0 Mon Sep 17 00:00:00 2001 From: Roland Kaufmann Date: Tue, 1 Apr 2014 14:03:09 +0200 Subject: [PATCH 1/4] Use new parser in common output interface Since EclipseWriter can now take a Deck instead of an EclipseGridParser the interface can be changed to take this type instead. --- opm/core/io/OutputWriter.cpp | 6 +++--- opm/core/io/OutputWriter.hpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/opm/core/io/OutputWriter.cpp b/opm/core/io/OutputWriter.cpp index 5645f420..4b66e2c4 100644 --- a/opm/core/io/OutputWriter.cpp +++ b/opm/core/io/OutputWriter.cpp @@ -48,7 +48,7 @@ private: /// Psuedo-constructor, can appear in template template unique_ptr create (const ParameterGroup& params, - std::shared_ptr parser, + std::shared_ptr parser, std::shared_ptr grid) { return unique_ptr (new Format (params, parser, grid)); } @@ -61,7 +61,7 @@ create (const ParameterGroup& params, /// to the list below! typedef map (*)( const ParameterGroup&, - std::shared_ptr , + std::shared_ptr , std::shared_ptr )> map_t; map_t FORMATS = { { "output_ecl", &create }, @@ -71,7 +71,7 @@ map_t FORMATS = { unique_ptr OutputWriter::create (const ParameterGroup& params, - std::shared_ptr parser, + std::shared_ptr parser, std::shared_ptr grid) { // allocate a list which will be filled with writers. this list // is initially empty (no output). diff --git a/opm/core/io/OutputWriter.hpp b/opm/core/io/OutputWriter.hpp index ea19ea01..46bca77a 100644 --- a/opm/core/io/OutputWriter.hpp +++ b/opm/core/io/OutputWriter.hpp @@ -27,7 +27,7 @@ struct UnstructuredGrid; namespace Opm { // forward declaration -class EclipseGridParser; +class Deck; namespace parameter { class ParameterGroup; } class SimulatorState; class SimulatorTimer; @@ -43,7 +43,7 @@ class WellState; * \example * \code{.cpp} * ParameterGroup params (argc, argv, false); - * auto parser = std::make_shared ( + * auto parser = std::make_shared ( * params.get ("deck_filename")); * * std::unique_ptr writer = @@ -108,7 +108,7 @@ public: */ static std::unique_ptr create (const parameter::ParameterGroup& params, - std::shared_ptr parser, + std::shared_ptr parser, std::shared_ptr grid); }; From a4c168e58ee8550cee290a08afc987bae7abeeec Mon Sep 17 00:00:00 2001 From: Roland Kaufmann Date: Tue, 1 Apr 2014 14:32:30 +0200 Subject: [PATCH 2/4] Use new parser for reading time map and generating output --- opm/core/simulator/SimulatorOutput.cpp | 16 +++++++++++----- opm/core/simulator/SimulatorOutput.hpp | 10 +++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/opm/core/simulator/SimulatorOutput.cpp b/opm/core/simulator/SimulatorOutput.cpp index 2fade1fd..a5d7be95 100644 --- a/opm/core/simulator/SimulatorOutput.cpp +++ b/opm/core/simulator/SimulatorOutput.cpp @@ -20,7 +20,8 @@ #include "SimulatorOutput.hpp" // we need complete definitions for these types -#include +#include +#include #include #include @@ -30,7 +31,7 @@ using namespace Opm; SimulatorOutputBase::SimulatorOutputBase ( const parameter::ParameterGroup& params, - std::shared_ptr parser, + std::shared_ptr parser, std::shared_ptr grid, std::shared_ptr timer, std::shared_ptr state, @@ -53,9 +54,14 @@ SimulatorOutputBase::SimulatorOutputBase ( // timesteps, we make a list of accumulated such to compare with // current time. add an extra zero at the beginning so that the // initial state is also written - const std::vector & tstep = parser->getTSTEP ().tstep_; - times_.resize (tstep.size (), 0.); - std::partial_sum (tstep.begin(), tstep.end(), times_.begin()); + TimeMap tmap(parser); + times_.resize (tmap.size () + 1, 0.); + double sum = 0.; + times_[0] = sum; + for (size_t step = 0; step < tmap.numTimesteps(); ++step) { + sum += tmap.getTimePassedUntil (step); + times_[step + 1] = sum; + } // write the static initialization files, even before simulation starts writer_->writeInit (*timer, *state, *wellState); diff --git a/opm/core/simulator/SimulatorOutput.hpp b/opm/core/simulator/SimulatorOutput.hpp index 22dffeeb..ff44c893 100644 --- a/opm/core/simulator/SimulatorOutput.hpp +++ b/opm/core/simulator/SimulatorOutput.hpp @@ -32,7 +32,7 @@ struct UnstructuredGrid; namespace Opm { // forward definitions -class EclipseGridParser; +class Deck; class OutputWriter; namespace parameter { class ParameterGroup; } class SimulatorState; @@ -53,7 +53,7 @@ protected: * need to pick them up from the object members. */ SimulatorOutputBase (const parameter::ParameterGroup& p, - std::shared_ptr parser, + std::shared_ptr parser, std::shared_ptr grid, std::shared_ptr timer, std::shared_ptr state, @@ -110,7 +110,7 @@ private: * ParameterGroup params (argc, argv, false); * * // input file - * auto deck = make_shared ( ... ); + * auto deck = make_shared ( ... ); * const GridManager manager (*parser); * auto grid = share_obj (*manager.c_grid ()); * @@ -139,7 +139,7 @@ private: template struct SimulatorOutput : public SimulatorOutputBase { SimulatorOutput (const parameter::ParameterGroup& params, - std::shared_ptr parser, + std::shared_ptr parser, std::shared_ptr grid, std::shared_ptr timer, std::shared_ptr state, @@ -161,7 +161,7 @@ struct SimulatorOutput : public SimulatorOutputBase { * the arguments passed exceeds the lifetime of this object. */ SimulatorOutput (const parameter::ParameterGroup& params, - EclipseGridParser& parser, + const Deck& parser, const UnstructuredGrid& grid, const SimulatorTimer& timer, const SimulatorState& state, From acf9f96e4616c2550061b0002164c33d8d402b70 Mon Sep 17 00:00:00 2001 From: Roland Kaufmann Date: Tue, 1 Apr 2014 20:27:53 +0200 Subject: [PATCH 3/4] Use TimeMap directly instead of copying times The simulator object will probably have created a time map anyway to control the timestepping so this can be reused directly by the output writer. (If not, it is easy to create one and pass it). --- opm/core/simulator/SimulatorOutput.cpp | 24 ++++++++---------------- opm/core/simulator/SimulatorOutput.hpp | 12 ++++++++++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/opm/core/simulator/SimulatorOutput.cpp b/opm/core/simulator/SimulatorOutput.cpp index a5d7be95..67092c3f 100644 --- a/opm/core/simulator/SimulatorOutput.cpp +++ b/opm/core/simulator/SimulatorOutput.cpp @@ -32,6 +32,7 @@ using namespace Opm; SimulatorOutputBase::SimulatorOutputBase ( const parameter::ParameterGroup& params, std::shared_ptr parser, + std::shared_ptr timeMap, std::shared_ptr grid, std::shared_ptr timer, std::shared_ptr state, @@ -40,6 +41,7 @@ SimulatorOutputBase::SimulatorOutputBase ( // store all parameters passed into the object, making them curried // parameters to the writeOutput function. : timer_ (timer ) + , timeMap_ (timeMap ) , reservoirState_ (state ) , wellState_ (wellState) @@ -50,19 +52,6 @@ SimulatorOutputBase::SimulatorOutputBase ( // always start from the first timestep , next_ (0) { - // make a list of times to dump. since the original list are relative - // timesteps, we make a list of accumulated such to compare with - // current time. add an extra zero at the beginning so that the - // initial state is also written - TimeMap tmap(parser); - times_.resize (tmap.size () + 1, 0.); - double sum = 0.; - times_[0] = sum; - for (size_t step = 0; step < tmap.numTimesteps(); ++step) { - sum += tmap.getTimePassedUntil (step); - times_[step + 1] = sum; - } - // write the static initialization files, even before simulation starts writer_->writeInit (*timer, *state, *wellState); } @@ -82,15 +71,18 @@ SimulatorOutputBase::writeOutput () { // if the simulator signals for timesteps that aren't reporting // times, then ignore them - if (next_ < times_.size () && times_[next_] <= this_time) { + if (next_ < timeMap_->size () + && timeMap_->getTimePassedUntil (next_) <= this_time) { // uh-oh, the simulator has skipped reporting timesteps that // occurred before this timestep (it doesn't honor the TSTEP setting) - while (next_ < times_.size () && times_[next_] < this_time) { + while (next_ < timeMap_->size () + && timeMap_->getTimePassedUntil (next_) < this_time) { ++next_; } // report this timestep if it matches - if (next_ < times_.size () && times_[next_] == this_time) { + if (next_ < timeMap_->size () + && timeMap_->getTimePassedUntil (next_) == this_time) { // make sure the simulator has spilled all necessary internal // state. notice that this calls *our* sync, which is overridden // in the template companion to call the simulator diff --git a/opm/core/simulator/SimulatorOutput.hpp b/opm/core/simulator/SimulatorOutput.hpp index ff44c893..b276ac57 100644 --- a/opm/core/simulator/SimulatorOutput.hpp +++ b/opm/core/simulator/SimulatorOutput.hpp @@ -37,6 +37,7 @@ class OutputWriter; namespace parameter { class ParameterGroup; } class SimulatorState; class SimulatorTimer; +class TimeMap; class WellState; /** @@ -54,6 +55,7 @@ protected: */ SimulatorOutputBase (const parameter::ParameterGroup& p, std::shared_ptr parser, + std::shared_ptr timeMap, std::shared_ptr grid, std::shared_ptr timer, std::shared_ptr state, @@ -75,6 +77,7 @@ protected: /// Just hold a reference to these objects that are owned elsewhere. std::shared_ptr timer_; + std::shared_ptr timeMap_; std::shared_ptr reservoirState_; std::shared_ptr wellState_; @@ -122,11 +125,12 @@ private: * auto wellState = make_shared (); * * // set up simulation + * auto timeMap = make_shared (deck); * auto sim = make_shared (params, *grid, ... ); * * // use this to dump state to disk * auto output = make_shared ( - * params, deck, grid, timer, state, wellState, sim); + * params, deck, timeMap, grid, timer, state, wellState, sim); * * // start simulation * sim.run (timer, state, ... ) @@ -140,13 +144,15 @@ template struct SimulatorOutput : public SimulatorOutputBase { SimulatorOutput (const parameter::ParameterGroup& params, std::shared_ptr parser, + std::shared_ptr timeMap, std::shared_ptr grid, std::shared_ptr timer, std::shared_ptr state, std::shared_ptr wellState, std::shared_ptr sim) // send all other parameters to base class - : SimulatorOutputBase (params, parser, grid, timer, state, wellState) + : SimulatorOutputBase (params, parser, timeMap, + grid, timer, state, wellState) // store reference to simulator in derived class , sim_ (sim) { @@ -162,6 +168,7 @@ struct SimulatorOutput : public SimulatorOutputBase { */ SimulatorOutput (const parameter::ParameterGroup& params, const Deck& parser, + const TimeMap& timeMap, const UnstructuredGrid& grid, const SimulatorTimer& timer, const SimulatorState& state, @@ -170,6 +177,7 @@ struct SimulatorOutput : public SimulatorOutputBase { // send all other parameters to base class : SimulatorOutputBase (params, share_obj (parser), + share_obj (timeMap), share_obj (grid), share_obj (timer), share_obj (state), From a02f315acef9b45b53f27d03efb00d7d37851a7d Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Mon, 31 Mar 2014 17:38:25 +0200 Subject: [PATCH 4/4] EclipseWriter: remove old parser this patch gets rid of the old-parser-taking methods of EclipseWriter. this avoids quite a few consistency issues and also reduces the amount of duplicate work required. --- opm/core/io/eclipse/EclipseWriter.cpp | 545 +++----------------------- opm/core/io/eclipse/EclipseWriter.hpp | 10 - 2 files changed, 62 insertions(+), 493 deletions(-) diff --git a/opm/core/io/eclipse/EclipseWriter.cpp b/opm/core/io/eclipse/EclipseWriter.cpp index 789503e7..241ab953 100644 --- a/opm/core/io/eclipse/EclipseWriter.cpp +++ b/opm/core/io/eclipse/EclipseWriter.cpp @@ -22,7 +22,6 @@ #include "EclipseWriter.hpp" -#include #include #include #include @@ -296,10 +295,6 @@ struct EclipseKeyword : public EclipseHandle { static_cast (name); } - // constructor to keep compatibility with the old eclipse parser - EclipseKeyword (const std::string& name, - const EclipseGridParser& parser); - // GCC 4.4 doesn't generate these constructors for us; provide the // default implementation explicitly here instead EclipseKeyword (EclipseKeyword&& rhs) @@ -389,24 +384,6 @@ template <> ecl_type_enum EclipseKeyword::type () { return ECL_INT_TYPE template <> ecl_type_enum EclipseKeyword::type () { return ECL_FLOAT_TYPE ; } template <> ecl_type_enum EclipseKeyword::type () { return ECL_DOUBLE_TYPE; } -/// keywords in ERT requires single-precision type, but OPM have them -/// stored as double-precision. this template specialization instantiates -/// a copy function that downcast the data to the required type. -template <> -EclipseKeyword ::EclipseKeyword ( - const std::string& name, - const EclipseGridParser& parser) - // allocate handle and put in smart pointer base class - : EclipseHandle ( - ecl_kw_alloc (name.c_str(), - // we can safely use the *size* of the original - dataSize (parser.getValue (name), 0, 1), - type ()), - ecl_kw_free) { - const std::vector & data = parser.getValue (name); - copyData (data, &noConversion, 0, 1); -} - /** * Pointer to memory that holds the name to an Eclipse output file. */ @@ -432,29 +409,6 @@ private: } }; -/// Get dimensions of the grid from the parse of the input file -std::vector parserDim (const EclipseGridParser& parser) { - std::vector dim(/* n = */ 3); - // dimensions explicitly given - if (parser.hasField("SPECGRID")) { - dim = parser.getSPECGRID ().dimensions; - } - // dimensions implicitly given by number of deltas - else if (parser.hasField("DXV")) { - assert(parser.hasField("DYV")); - assert(parser.hasField("DZV")); - dim[0] = parser.getFloatingPointValue("DXV").size(); - dim[1] = parser.getFloatingPointValue("DYV").size(); - dim[2] = parser.getFloatingPointValue("DZV").size(); - } - else { - OPM_THROW(std::runtime_error, - "Only decks featureing either the SPECGRID or the D[XYZ]V keywords " - "are currently supported"); - } - return dim; -} - /// Get dimensions of the grid from the parse of the input file std::vector parserDim (Opm::DeckConstPtr newParserDeck) { std::vector dim(/* n = */ 3); @@ -501,24 +455,6 @@ struct EclipseRestart : public EclipseHandle { outputStepIdx)), ecl_rst_file_close) { } - void writeHeader (const SimulatorTimer& timer, - int outputStepIdx, - const PhaseUsage uses, - const EclipseGridParser parser, - const int num_active_cells) { - const std::vector dim = parserDim (parser); - ecl_rst_file_fwrite_header (*this, - outputStepIdx, - timer.currentPosixTime(), - Opm::unit::convert::to (timer.simulationTimeElapsed (), - Opm::unit::day), - dim[0], - dim[1], - dim[2], - num_active_cells, - phaseMask (uses)); - } - void writeHeader (const SimulatorTimer& timer, int outputStepIdx, const PhaseUsage uses, @@ -565,49 +501,6 @@ private: * Representation of an Eclipse grid. */ struct EclipseGrid : public EclipseHandle { - /// Create a grid based on the keywords available in input file - static EclipseGrid make (const EclipseGridParser& parser, - const UnstructuredGrid& grid) { - if (parser.hasField("DXV")) { - // make sure that the DYV and DZV keywords are present if the - // DXV keyword is used in the deck... - assert(parser.hasField("DYV")); - assert(parser.hasField("DZV")); - - const auto& dxv = parser.getFloatingPointValue("DXV"); - const auto& dyv = parser.getFloatingPointValue("DYV"); - const auto& dzv = parser.getFloatingPointValue("DZV"); - - return EclipseGrid (dxv, dyv, dzv); - } - else if (parser.hasField("ZCORN")) { - struct grdecl g = parser.get_grdecl (); - - auto coordData = parser.getFloatingPointValue(COORD_KW); - auto zcornData = parser.getFloatingPointValue(ZCORN_KW); - - EclipseKeyword coord_kw (COORD_KW, coordData); - EclipseKeyword zcorn_kw (ZCORN_KW, zcornData); - - // get the actually active cells, after processing - std::vector actnum; - getActiveCells_(grid, actnum); - EclipseKeyword actnum_kw (ACTNUM_KW, actnum); - - EclipseKeyword mapaxes_kw (MAPAXES_KW); - if (g.mapaxes) { - auto mapaxesData = parser.getFloatingPointValue(MAPAXES_KW); - mapaxes_kw = std::move (EclipseKeyword (MAPAXES_KW, mapaxesData)); - } - - return EclipseGrid (g.dims, zcorn_kw, coord_kw, actnum_kw, mapaxes_kw); - } - else { - OPM_THROW(std::runtime_error, - "Can't create an ERT grid (no supported keywords found in deck)"); - } - } - /// Create a grid based on the keywords available in input file static EclipseGrid make (Opm::DeckConstPtr newParserDeck, const UnstructuredGrid& grid) @@ -736,18 +629,6 @@ struct EclipseInit : public EclipseHandle { return EclipseInit (initFileName, fmt_file); } - void writeHeader (const EclipseGrid& grid, - const SimulatorTimer& timer, - const EclipseGridParser& parser, - const PhaseUsage uses) { - EclipseKeyword poro (PORO_KW, parser); - ecl_init_file_fwrite_header (*this, - grid, - poro, - phaseMask (uses), - timer.currentPosixTime()); - } - void writeHeader (const UnstructuredGrid& grid, const SimulatorTimer& timer, Opm::DeckConstPtr newParserDeck, @@ -766,15 +647,6 @@ struct EclipseInit : public EclipseHandle { timer.currentPosixTime ()); } - void writeKeyword (const std::string& keywordName, - const EclipseGridParser& parser, - double (* const transf)(const double&)) { - auto data = parser.getValue (keywordName); - convertUnit_(data, transf); - EclipseKeyword kw (keywordName, data); - ecl_kw_fwrite (kw, *this); - } - void writeKeyword (const std::string& keywordName, const std::vector &data) { EclipseKeyword kw (keywordName, data); @@ -814,14 +686,6 @@ template struct EclipseHandle; struct EclipseWellReport; struct EclipseSummary : public EclipseHandle { - EclipseSummary (const std::string& outputDir, - const std::string& baseName, - const SimulatorTimer& timer, - const EclipseGridParser parser) - : EclipseHandle ( - alloc_writer (outputDir, baseName, timer, parser), - ecl_sum_free) { } - EclipseSummary (const std::string& outputDir, const std::string& baseName, const SimulatorTimer& timer, @@ -845,10 +709,6 @@ struct EclipseSummary : public EclipseHandle { ecl_sum_fwrite (*this); } - // add rate variables for each of the well in the input file - void addWells (const EclipseGridParser& parser, - const PhaseUsage& uses); - // add rate variables for each of the well in the input file void addWells (Opm::DeckConstPtr newParserDeck, const PhaseUsage& uses); @@ -879,27 +739,6 @@ private: return std::unique_ptr (tstep); } - /// Helper routine that lets us use local variables to hold - /// intermediate results while filling out the allocations function's - /// argument list. - static ecl_sum_type* alloc_writer (const std::string& outputDir, - const std::string& baseName, - const SimulatorTimer& timer, - const EclipseGridParser& parser) { - boost::filesystem::path casePath (outputDir); - casePath /= boost::to_upper_copy (baseName); - - const std::vector dim = parserDim (parser); - return ecl_sum_alloc_writer (casePath.string ().c_str (), - false, /* formatted */ - true, /* unified */ - ":", /* join string */ - timer.simulationTimeElapsed (), - dim[0], - dim[1], - dim[2]); - } - /// Helper routine that lets us use local variables to hold /// intermediate results while filling out the allocations function's /// argument list. @@ -928,29 +767,6 @@ private: */ struct EclipseWellReport : public EclipseHandle { protected: - EclipseWellReport (const EclipseSummary& summary, /* section to add to */ - const EclipseGridParser& parser, /* well names */ - int whichWell, /* index of well line */ - PhaseUsage uses, /* phases present */ - BlackoilPhases::PhaseIndex phase, /* oil, water or gas */ - WellType type, /* prod. or inj. */ - char aggregation, /* rate or total or BHP */ - std::string unit) - : EclipseHandle ( - ecl_sum_add_var (summary, - varName (phase, - type, - aggregation).c_str (), - wellName (parser, whichWell).c_str (), - /* num = */ 0, - unit.c_str(), - /* defaultValue = */ 0.)) - // save these for when we update the value in a timestep - , index_ (whichWell * uses.num_phases + uses.phase_pos [phase]) - - // producers can be seen as negative injectors - , sign_ (type == INJECTOR ? +1. : -1.) { } - EclipseWellReport (const EclipseSummary& summary, /* section to add to */ Opm::DeckConstPtr newParserDeck, /* well names */ int whichWell, /* index of well line */ @@ -992,12 +808,6 @@ private: /// natural sign of the rate const double sign_; - /// Get the name associated with this well - std::string wellName (const EclipseGridParser& parser, - int whichWell) { - return parser.getWELSPECS().welspecs[whichWell].name_; - } - /// Get the name associated with this well std::string wellName (Opm::DeckConstPtr newParserDeck, int whichWell) @@ -1053,21 +863,6 @@ protected: /// Monitors the rate given by a well. struct EclipseWellRate : public EclipseWellReport { - EclipseWellRate (const EclipseSummary& summary, - const EclipseGridParser& parser, - int whichWell, - PhaseUsage uses, - BlackoilPhases::PhaseIndex phase, - WellType type) - : EclipseWellReport (summary, - parser, - whichWell, - uses, - phase, - type, - 'R', - "SM3/DAY" /* surf. cub. m. per day */ ) { } - EclipseWellRate (const EclipseSummary& summary, Opm::DeckConstPtr newParserDeck, int whichWell, @@ -1092,24 +887,6 @@ struct EclipseWellRate : public EclipseWellReport { /// Monitors the total production in a well. struct EclipseWellTotal : public EclipseWellReport { - EclipseWellTotal (const EclipseSummary& summary, - const EclipseGridParser& parser, - int whichWell, - PhaseUsage uses, - BlackoilPhases::PhaseIndex phase, - WellType type) - : EclipseWellReport (summary, - parser, - whichWell, - uses, - phase, - type, - 'T', - "SM3" /* surface cubic meter */ ) - - // nothing produced when the reporting starts - , total_ (0.) { } - EclipseWellTotal (const EclipseSummary& summary, Opm::DeckConstPtr newParserDeck, int whichWell, @@ -1152,22 +929,6 @@ private: /// Monitors the bottom hole pressure in a well. struct EclipseWellBhp : public EclipseWellReport { - EclipseWellBhp (const EclipseSummary& summary, - const EclipseGridParser& parser, - int whichWell, - PhaseUsage uses, - BlackoilPhases::PhaseIndex phase, - WellType type) - : EclipseWellReport (summary, - parser, - whichWell, - uses, - phase, - type, - 'B', - "Pascal") - { } - EclipseWellBhp (const EclipseSummary& summary, Opm::DeckConstPtr newParserDeck, int whichWell, @@ -1208,69 +969,6 @@ EclipseSummary::writeTimeStep (const SimulatorTimer& timer, /// so we must have an explicit array. static WellType WELL_TYPES[] = { INJECTOR, PRODUCER }; -inline void -EclipseSummary::addWells (const EclipseGridParser& parser, - const PhaseUsage& uses) -{ - // TODO: Only create report variables that are requested with keywords - // (e.g. "WOPR") in the input files, and only for those wells that are - // mentioned in those keywords - const int numWells = parser.getWELSPECS().welspecs.size(); - for (int phaseCounter = 0; - phaseCounter != BlackoilPhases::MaxNumPhases; - ++phaseCounter) { - const BlackoilPhases::PhaseIndex phase = - static_cast (phaseCounter); - // don't bother with reporting for phases that aren't there - if (!uses.phase_used [phaseCounter]) { - continue; - } - for (size_t typeIndex = 0; - typeIndex < sizeof (WELL_TYPES) / sizeof (WELL_TYPES[0]); - ++typeIndex) { - const WellType type = WELL_TYPES[typeIndex]; - for (int whichWell = 0; whichWell != numWells; ++whichWell) { - // W{O,G,W}{I,P}R - add (std::unique_ptr ( - new EclipseWellRate (*this, - parser, - whichWell, - uses, - phase, - type))); - // W{O,G,W}{I,P}T - add (std::unique_ptr ( - new EclipseWellTotal (*this, - parser, - whichWell, - uses, - phase, - type))); - } - } - } - - // Add BHP monitors - for (int whichWell = 0; whichWell != numWells; ++whichWell) { - // In the call below: uses, phase and the well type arguments - // are not used, except to set up an index that stores the - // well indirectly. For details see the implementation of the - // EclipseWellReport constructor, and the method - // EclipseWellReport::bhp(). - BlackoilPhases::PhaseIndex phase = BlackoilPhases::Liquid; - if (!uses.phase_used[BlackoilPhases::Liquid]) { - phase = BlackoilPhases::Vapour; - } - add (std::unique_ptr ( - new EclipseWellBhp (*this, - parser, - whichWell, - uses, - phase, - WELL_TYPES[0]))); - } -} - inline void EclipseSummary::addWells (Opm::DeckConstPtr newParserDeck, const PhaseUsage& uses) { @@ -1346,70 +1044,45 @@ void EclipseWriter::writeInit(const SimulatorTimer &timer, if (!enableOutput_) { return; } - if (newParserDeck_) { - /* Grid files */ - EclipseGrid eclGrid = EclipseGrid::make (newParserDeck_, *grid_); - eclGrid.write (outputDir_, baseName_, /*stepIdx=*/0); + /* Grid files */ + EclipseGrid eclGrid = EclipseGrid::make (newParserDeck_, *grid_); + eclGrid.write (outputDir_, baseName_, /*stepIdx=*/0); - EclipseInit fortio = EclipseInit::make (outputDir_, baseName_, /*stepIdx=*/0); - fortio.writeHeader (*grid_, - timer, - newParserDeck_, - uses_); + EclipseInit fortio = EclipseInit::make (outputDir_, baseName_, /*stepIdx=*/0); + fortio.writeHeader (*grid_, + timer, + newParserDeck_, + uses_); - if (newParserDeck_->hasKeyword("PERM")) { - auto data = getAllSiDoubles_(newParserDeck_->getKeyword("PERM")); - convertUnit_(data, toMilliDarcy); - fortio.writeKeyword ("PERM", data); - } - - if (newParserDeck_->hasKeyword("PERMX")) { - auto data = getAllSiDoubles_(newParserDeck_->getKeyword("PERMX")); - convertUnit_(data, toMilliDarcy); - fortio.writeKeyword ("PERMX", data); - } - if (newParserDeck_->hasKeyword("PERMY")) { - auto data = getAllSiDoubles_(newParserDeck_->getKeyword("PERMY")); - convertUnit_(data, toMilliDarcy); - fortio.writeKeyword ("PERMY", data); - } - if (newParserDeck_->hasKeyword("PERMZ")) { - auto data = getAllSiDoubles_(newParserDeck_->getKeyword("PERMZ")); - convertUnit_(data, toMilliDarcy); - fortio.writeKeyword ("PERMZ", data); - } - - /* Initial solution (pressure and saturation) */ - writeSolution_(timer, reservoirState); - - /* Create summary object (could not do it at construction time, - since it requires knowledge of the start time). */ - summary_.reset(new EclipseSummary(outputDir_, baseName_, timer, newParserDeck_)); - summary_->addWells (newParserDeck_, uses_); + if (newParserDeck_->hasKeyword("PERM")) { + auto data = getAllSiDoubles_(newParserDeck_->getKeyword("PERM")); + convertUnit_(data, toMilliDarcy); + fortio.writeKeyword ("PERM", data); } - else { - /* Grid files */ - EclipseGrid ecl_grid = EclipseGrid::make (*parser_, *grid_); - ecl_grid.write (outputDir_, baseName_, /*stepIdx=*/0); - EclipseInit fortio = EclipseInit::make (outputDir_, baseName_, /*stepIdx=*/0); - fortio.writeHeader (ecl_grid, - timer, - *parser_, - uses_); - - fortio.writeKeyword ("PERMX", *parser_, &toMilliDarcy); - fortio.writeKeyword ("PERMY", *parser_, &toMilliDarcy); - fortio.writeKeyword ("PERMZ", *parser_, &toMilliDarcy); - - /* Initial solution (pressure and saturation) */ - writeSolution_(timer, reservoirState); - - /* Create summary object (could not do it at construction time, - since it requires knowledge of the start time). */ - summary_.reset(new EclipseSummary(outputDir_, baseName_, timer, *parser_)); - summary_->addWells (*parser_, uses_); + if (newParserDeck_->hasKeyword("PERMX")) { + auto data = getAllSiDoubles_(newParserDeck_->getKeyword("PERMX")); + convertUnit_(data, toMilliDarcy); + fortio.writeKeyword ("PERMX", data); } + if (newParserDeck_->hasKeyword("PERMY")) { + auto data = getAllSiDoubles_(newParserDeck_->getKeyword("PERMY")); + convertUnit_(data, toMilliDarcy); + fortio.writeKeyword ("PERMY", data); + } + if (newParserDeck_->hasKeyword("PERMZ")) { + auto data = getAllSiDoubles_(newParserDeck_->getKeyword("PERMZ")); + convertUnit_(data, toMilliDarcy); + fortio.writeKeyword ("PERMZ", data); + } + + /* Initial solution (pressure and saturation) */ + writeSolution_(timer, reservoirState); + + /* Create summary object (could not do it at construction time, + since it requires knowledge of the start time). */ + summary_.reset(new EclipseSummary(outputDir_, baseName_, timer, newParserDeck_)); + summary_->addWells (newParserDeck_, uses_); } void EclipseWriter::activeToGlobalCellData_(std::vector &globalCellsBuf, @@ -1431,69 +1104,32 @@ void EclipseWriter::activeToGlobalCellData_(std::vector &globalCellsBuf, void EclipseWriter::writeSolution_(const SimulatorTimer& timer, const SimulatorState& reservoirState) { - if (newParserDeck_) { - // start writing to files - EclipseRestart rst(outputDir_, baseName_, timer, outputTimeStepIdx_); - rst.writeHeader (timer, outputTimeStepIdx_, uses_, newParserDeck_, reservoirState.pressure().size ()); - EclipseSolution sol (rst); + // start writing to files + EclipseRestart rst(outputDir_, baseName_, timer, outputTimeStepIdx_); + rst.writeHeader (timer, outputTimeStepIdx_, uses_, newParserDeck_, reservoirState.pressure().size ()); + EclipseSolution sol (rst); - // write out the pressure of the reference phase (whatever - // phase that is...). this is not the most performant solution - // thinkable, but this is also not in the most performance - // critical code path! - std::vector tmp = reservoirState.pressure(); - convertUnit_(tmp, toBar); + // write out the pressure of the reference phase (whatever + // phase that is...). this is not the most performant solution + // thinkable, but this is also not in the most performance + // critical code path! + std::vector tmp = reservoirState.pressure(); + convertUnit_(tmp, toBar); - sol.add(EclipseKeyword("PRESSURE", tmp)); + sol.add(EclipseKeyword("PRESSURE", tmp)); - for (int phase = 0; phase != BlackoilPhases::MaxNumPhases; ++phase) { - // Eclipse never writes the oil saturation, so all post-processors - // must calculate this from the other saturations anyway - if (phase == BlackoilPhases::PhaseIndex::Liquid) { - continue; - } - if (uses_.phase_used [phase]) { - tmp = reservoirState.saturation(); - extractFromStripedData_(tmp, - /*offset=*/uses_.phase_pos[phase], - /*stride=*/uses_.num_phases); - sol.add(EclipseKeyword(SAT_NAMES[phase], tmp)); - } + for (int phase = 0; phase != BlackoilPhases::MaxNumPhases; ++phase) { + // Eclipse never writes the oil saturation, so all post-processors + // must calculate this from the other saturations anyway + if (phase == BlackoilPhases::PhaseIndex::Liquid) { + continue; } - } - else { - // start writing to files - EclipseRestart rst (outputDir_, - baseName_, - timer, - outputTimeStepIdx_); - rst.writeHeader (timer, - outputTimeStepIdx_, - uses_, - *parser_, - reservoirState.pressure ().size ()); - EclipseSolution sol (rst); - - // write pressure and saturation fields (same as DataMap holds) - // convert the pressures from Pascals to bar because Eclipse - // seems to write bars - auto data = reservoirState.pressure(); - convertUnit_(data, toBar); - sol.add(EclipseKeyword("PRESSURE", data)); - - for (int phase = 0; phase != BlackoilPhases::MaxNumPhases; ++phase) { - // Eclipse never writes the oil saturation, so all post-processors - // must calculate this from the other saturations anyway - if (phase == BlackoilPhases::PhaseIndex::Liquid) { - continue; - } - if (uses_.phase_used [phase]) { - auto tmp = reservoirState.saturation(); - extractFromStripedData_(tmp, - /*offset=*/uses_.phase_pos[phase], - /*stride=*/uses_.num_phases); - sol.add (EclipseKeyword(SAT_NAMES[phase], tmp)); - } + if (uses_.phase_used [phase]) { + tmp = reservoirState.saturation(); + extractFromStripedData_(tmp, + /*offset=*/uses_.phase_pos[phase], + /*stride=*/uses_.num_phases); + sol.add(EclipseKeyword(SAT_NAMES[phase], tmp)); } } @@ -1569,69 +1205,12 @@ void EclipseWriter::writeTimeStep( #endif // HAVE_ERT -EclipseWriter::EclipseWriter ( - const ParameterGroup& params, - std::shared_ptr parser, - std::shared_ptr grid) - : parser_ (parser) - , newParserDeck_() - , grid_ (grid) - , uses_ (phaseUsageFromDeck (*parser)) -{ - // set the index of the first time step written to 0... - outputTimeStepIdx_ = 0; - - - // get the base name from the name of the deck - using boost::filesystem::path; - path deck (params.get ("deck_filename")); - if (boost::to_upper_copy (path (deck.extension ()).string ()) == ".DATA") { - baseName_ = path (deck.stem ()).string (); - } - else { - baseName_ = path (deck.filename ()).string (); - } - - // make uppercase of everything (or otherwise we'll get uppercase - // of some of the files (.SMSPEC, .UNSMRY) and not others - baseName_ = boost::to_upper_copy (baseName_); - - // retrieve the value of the "output" parameter - enableOutput_ = params.getDefault("output", /*defaultValue=*/true); - - // retrieve the interval at which something should get written to - // disk (once every N timesteps) - outputInterval_ = params.getDefault("output_interval", /*defaultValue=*/1); - - // store in current directory if not explicitly set - outputDir_ = params.getDefault("output_dir", "."); - - // set the index of the first time step written to 0... - outputTimeStepIdx_ = 0; - - if (enableOutput_) { - // make sure that the output directory exists, if not try to create it - if (!boost::filesystem::exists(outputDir_)) { - std::cout << "Trying to create directory \"" << outputDir_ << "\" for the simulation output\n"; - boost::filesystem::create_directories(outputDir_); - } - - if (!boost::filesystem::is_directory(outputDir_)) { - OPM_THROW(std::runtime_error, - "The path specified as output directory '" << outputDir_ - << "' is not a directory"); - } - } -} - -EclipseWriter::EclipseWriter ( - const ParameterGroup& params, - Opm::DeckConstPtr newParserDeck, - std::shared_ptr grid) - : parser_ () - , newParserDeck_(newParserDeck) - , grid_ (grid) - , uses_ (phaseUsageFromDeck (newParserDeck)) +EclipseWriter::EclipseWriter(const ParameterGroup& params, + Opm::DeckConstPtr newParserDeck, + std::shared_ptr grid) + : newParserDeck_(newParserDeck) + , grid_(grid) + , uses_(phaseUsageFromDeck(newParserDeck)) { // get the base name from the name of the deck using boost::filesystem::path; diff --git a/opm/core/io/eclipse/EclipseWriter.hpp b/opm/core/io/eclipse/EclipseWriter.hpp index 4adfbba6..b2808372 100644 --- a/opm/core/io/eclipse/EclipseWriter.hpp +++ b/opm/core/io/eclipse/EclipseWriter.hpp @@ -36,7 +36,6 @@ struct EclipseSummary; namespace Opm { // forward declarations -class EclipseGridParser; class SimulatorState; class SimulatorTimer; class WellState; @@ -55,14 +54,6 @@ namespace parameter { class ParameterGroup; } class EclipseWriter : public OutputWriter { public: - /*! - * \brief Sets the common attributes required to write eclipse - * binary files using ERT. - */ - EclipseWriter(const parameter::ParameterGroup& params, - std::shared_ptr parser, - std::shared_ptr grid); - /*! * \brief Sets the common attributes required to write eclipse * binary files using ERT. @@ -97,7 +88,6 @@ public: const WellState& wellState); private: - std::shared_ptr parser_; Opm::DeckConstPtr newParserDeck_; std::shared_ptr grid_; bool enableOutput_;