Merge pull request #557 from andlaus/EclipseWriter_remove_old_parser
Eclipse writer remove old parser
This commit is contained in:
@@ -48,7 +48,7 @@ private:
|
||||
/// Psuedo-constructor, can appear in template
|
||||
template <typename Format> unique_ptr <OutputWriter>
|
||||
create (const ParameterGroup& params,
|
||||
std::shared_ptr <EclipseGridParser> parser,
|
||||
std::shared_ptr <const Deck> parser,
|
||||
std::shared_ptr <const UnstructuredGrid> grid) {
|
||||
return unique_ptr <OutputWriter> (new Format (params, parser, grid));
|
||||
}
|
||||
@@ -61,7 +61,7 @@ create (const ParameterGroup& params,
|
||||
/// to the list below!
|
||||
typedef map <const char*, unique_ptr <OutputWriter> (*)(
|
||||
const ParameterGroup&,
|
||||
std::shared_ptr <EclipseGridParser>,
|
||||
std::shared_ptr <const Deck>,
|
||||
std::shared_ptr <const UnstructuredGrid>)> map_t;
|
||||
map_t FORMATS = {
|
||||
{ "output_ecl", &create <EclipseWriter> },
|
||||
@@ -71,7 +71,7 @@ map_t FORMATS = {
|
||||
|
||||
unique_ptr <OutputWriter>
|
||||
OutputWriter::create (const ParameterGroup& params,
|
||||
std::shared_ptr <EclipseGridParser> parser,
|
||||
std::shared_ptr <const Deck> parser,
|
||||
std::shared_ptr <const UnstructuredGrid> grid) {
|
||||
// allocate a list which will be filled with writers. this list
|
||||
// is initially empty (no output).
|
||||
|
||||
@@ -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 <EclipseGridParser> (
|
||||
* auto parser = std::make_shared <const Deck> (
|
||||
* params.get <string> ("deck_filename"));
|
||||
*
|
||||
* std::unique_ptr <OutputWriter> writer =
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
*/
|
||||
static std::unique_ptr <OutputWriter>
|
||||
create (const parameter::ParameterGroup& params,
|
||||
std::shared_ptr <EclipseGridParser> parser,
|
||||
std::shared_ptr <const Deck> parser,
|
||||
std::shared_ptr <const UnstructuredGrid> grid);
|
||||
};
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include "EclipseWriter.hpp"
|
||||
|
||||
#include <opm/core/io/eclipse/EclipseGridParser.hpp>
|
||||
#include <opm/core/props/BlackoilPhases.hpp>
|
||||
#include <opm/core/grid/GridManager.hpp>
|
||||
#include <opm/core/props/phaseUsageFromDeck.hpp>
|
||||
@@ -296,10 +295,6 @@ struct EclipseKeyword : public EclipseHandle <ecl_kw_type> {
|
||||
static_cast<void> (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<int >::type () { return ECL_INT_TYPE
|
||||
template <> ecl_type_enum EclipseKeyword<float >::type () { return ECL_FLOAT_TYPE ; }
|
||||
template <> ecl_type_enum EclipseKeyword<double>::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 <float>::EclipseKeyword (
|
||||
const std::string& name,
|
||||
const EclipseGridParser& parser)
|
||||
// allocate handle and put in smart pointer base class
|
||||
: EclipseHandle <ecl_kw_type> (
|
||||
ecl_kw_alloc (name.c_str(),
|
||||
// we can safely use the *size* of the original
|
||||
dataSize (parser.getValue <double> (name), 0, 1),
|
||||
type ()),
|
||||
ecl_kw_free) {
|
||||
const std::vector <double>& data = parser.getValue <double> (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 <int> parserDim (const EclipseGridParser& parser) {
|
||||
std::vector<int> 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 <int> parserDim (Opm::DeckConstPtr newParserDeck) {
|
||||
std::vector<int> dim(/* n = */ 3);
|
||||
@@ -501,24 +455,6 @@ struct EclipseRestart : public EclipseHandle <ecl_rst_file_type> {
|
||||
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 <int> 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 <ecl_grid_type> {
|
||||
/// 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<float> coord_kw (COORD_KW, coordData);
|
||||
EclipseKeyword<float> zcorn_kw (ZCORN_KW, zcornData);
|
||||
|
||||
// get the actually active cells, after processing
|
||||
std::vector <int> actnum;
|
||||
getActiveCells_(grid, actnum);
|
||||
EclipseKeyword<int> actnum_kw (ACTNUM_KW, actnum);
|
||||
|
||||
EclipseKeyword<float> mapaxes_kw (MAPAXES_KW);
|
||||
if (g.mapaxes) {
|
||||
auto mapaxesData = parser.getFloatingPointValue(MAPAXES_KW);
|
||||
mapaxes_kw = std::move (EclipseKeyword<float> (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 <fortio_type> {
|
||||
return EclipseInit (initFileName, fmt_file);
|
||||
}
|
||||
|
||||
void writeHeader (const EclipseGrid& grid,
|
||||
const SimulatorTimer& timer,
|
||||
const EclipseGridParser& parser,
|
||||
const PhaseUsage uses) {
|
||||
EclipseKeyword<float> 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 <fortio_type> {
|
||||
timer.currentPosixTime ());
|
||||
}
|
||||
|
||||
void writeKeyword (const std::string& keywordName,
|
||||
const EclipseGridParser& parser,
|
||||
double (* const transf)(const double&)) {
|
||||
auto data = parser.getValue <double> (keywordName);
|
||||
convertUnit_(data, transf);
|
||||
EclipseKeyword <float> kw (keywordName, data);
|
||||
ecl_kw_fwrite (kw, *this);
|
||||
}
|
||||
|
||||
void writeKeyword (const std::string& keywordName, const std::vector<double> &data)
|
||||
{
|
||||
EclipseKeyword <float> kw (keywordName, data);
|
||||
@@ -814,14 +686,6 @@ template struct EclipseHandle<ecl_sum_tstep_struct>;
|
||||
struct EclipseWellReport;
|
||||
|
||||
struct EclipseSummary : public EclipseHandle <ecl_sum_type> {
|
||||
EclipseSummary (const std::string& outputDir,
|
||||
const std::string& baseName,
|
||||
const SimulatorTimer& timer,
|
||||
const EclipseGridParser parser)
|
||||
: EclipseHandle <ecl_sum_type> (
|
||||
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_type> {
|
||||
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 <EclipseTimeStep> (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 <int> 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 <smspec_node_type> {
|
||||
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 <smspec_node_type> (
|
||||
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 <BlackoilPhases::PhaseIndex> (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 <EclipseWellReport> (
|
||||
new EclipseWellRate (*this,
|
||||
parser,
|
||||
whichWell,
|
||||
uses,
|
||||
phase,
|
||||
type)));
|
||||
// W{O,G,W}{I,P}T
|
||||
add (std::unique_ptr <EclipseWellReport> (
|
||||
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 <EclipseWellReport> (
|
||||
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<double> &globalCellsBuf,
|
||||
@@ -1431,69 +1104,32 @@ void EclipseWriter::activeToGlobalCellData_(std::vector<double> &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<double> 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<double> tmp = reservoirState.pressure();
|
||||
convertUnit_(tmp, toBar);
|
||||
|
||||
sol.add(EclipseKeyword<float>("PRESSURE", tmp));
|
||||
sol.add(EclipseKeyword<float>("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<float>(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<float>("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<float>(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<float>(SAT_NAMES[phase], tmp));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1569,69 +1205,12 @@ void EclipseWriter::writeTimeStep(
|
||||
|
||||
#endif // HAVE_ERT
|
||||
|
||||
EclipseWriter::EclipseWriter (
|
||||
const ParameterGroup& params,
|
||||
std::shared_ptr <EclipseGridParser> parser,
|
||||
std::shared_ptr <const UnstructuredGrid> 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 <std::string> ("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<bool>("output", /*defaultValue=*/true);
|
||||
|
||||
// retrieve the interval at which something should get written to
|
||||
// disk (once every N timesteps)
|
||||
outputInterval_ = params.getDefault<int>("output_interval", /*defaultValue=*/1);
|
||||
|
||||
// store in current directory if not explicitly set
|
||||
outputDir_ = params.getDefault<std::string>("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 <const UnstructuredGrid> grid)
|
||||
: parser_ ()
|
||||
, newParserDeck_(newParserDeck)
|
||||
, grid_ (grid)
|
||||
, uses_ (phaseUsageFromDeck (newParserDeck))
|
||||
EclipseWriter::EclipseWriter(const ParameterGroup& params,
|
||||
Opm::DeckConstPtr newParserDeck,
|
||||
std::shared_ptr<const UnstructuredGrid> grid)
|
||||
: newParserDeck_(newParserDeck)
|
||||
, grid_(grid)
|
||||
, uses_(phaseUsageFromDeck(newParserDeck))
|
||||
{
|
||||
// get the base name from the name of the deck
|
||||
using boost::filesystem::path;
|
||||
|
||||
@@ -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 <EclipseGridParser> parser,
|
||||
std::shared_ptr <const UnstructuredGrid> 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 <const EclipseGridParser> parser_;
|
||||
Opm::DeckConstPtr newParserDeck_;
|
||||
std::shared_ptr <const UnstructuredGrid> grid_;
|
||||
bool enableOutput_;
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
#include "SimulatorOutput.hpp"
|
||||
|
||||
// we need complete definitions for these types
|
||||
#include <opm/core/io/eclipse/EclipseGridParser.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
|
||||
#include <opm/core/io/OutputWriter.hpp>
|
||||
#include <opm/core/simulator/SimulatorTimer.hpp>
|
||||
|
||||
@@ -30,7 +31,8 @@ using namespace Opm;
|
||||
|
||||
SimulatorOutputBase::SimulatorOutputBase (
|
||||
const parameter::ParameterGroup& params,
|
||||
std::shared_ptr <EclipseGridParser> parser,
|
||||
std::shared_ptr <const Deck> parser,
|
||||
std::shared_ptr <const TimeMap> timeMap,
|
||||
std::shared_ptr <const UnstructuredGrid> grid,
|
||||
std::shared_ptr <const SimulatorTimer> timer,
|
||||
std::shared_ptr <const SimulatorState> state,
|
||||
@@ -39,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)
|
||||
|
||||
@@ -49,14 +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
|
||||
const std::vector <double>& tstep = parser->getTSTEP ().tstep_;
|
||||
times_.resize (tstep.size (), 0.);
|
||||
std::partial_sum (tstep.begin(), tstep.end(), times_.begin());
|
||||
|
||||
// write the static initialization files, even before simulation starts
|
||||
writer_->writeInit (*timer, *state, *wellState);
|
||||
}
|
||||
@@ -76,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
|
||||
|
||||
@@ -32,11 +32,12 @@ struct UnstructuredGrid;
|
||||
namespace Opm {
|
||||
|
||||
// forward definitions
|
||||
class EclipseGridParser;
|
||||
class Deck;
|
||||
class OutputWriter;
|
||||
namespace parameter { class ParameterGroup; }
|
||||
class SimulatorState;
|
||||
class SimulatorTimer;
|
||||
class TimeMap;
|
||||
class WellState;
|
||||
|
||||
/**
|
||||
@@ -53,7 +54,8 @@ protected:
|
||||
* need to pick them up from the object members.
|
||||
*/
|
||||
SimulatorOutputBase (const parameter::ParameterGroup& p,
|
||||
std::shared_ptr <EclipseGridParser> parser,
|
||||
std::shared_ptr <const Deck> parser,
|
||||
std::shared_ptr <const TimeMap> timeMap,
|
||||
std::shared_ptr <const UnstructuredGrid> grid,
|
||||
std::shared_ptr <const SimulatorTimer> timer,
|
||||
std::shared_ptr <const SimulatorState> state,
|
||||
@@ -75,6 +77,7 @@ protected:
|
||||
|
||||
/// Just hold a reference to these objects that are owned elsewhere.
|
||||
std::shared_ptr <const SimulatorTimer> timer_;
|
||||
std::shared_ptr <const TimeMap> timeMap_;
|
||||
std::shared_ptr <const SimulatorState> reservoirState_;
|
||||
std::shared_ptr <const WellState> wellState_;
|
||||
|
||||
@@ -110,7 +113,7 @@ private:
|
||||
* ParameterGroup params (argc, argv, false);
|
||||
*
|
||||
* // input file
|
||||
* auto deck = make_shared <EclipseGridParser> ( ... );
|
||||
* auto deck = make_shared <const Deck> ( ... );
|
||||
* const GridManager manager (*parser);
|
||||
* auto grid = share_obj (*manager.c_grid ());
|
||||
*
|
||||
@@ -122,11 +125,12 @@ private:
|
||||
* auto wellState = make_shared <WellState> ();
|
||||
*
|
||||
* // set up simulation
|
||||
* auto timeMap = make_shared <const TimeMap> (deck);
|
||||
* auto sim = make_shared <SimulatorIncompTwophase> (params, *grid, ... );
|
||||
*
|
||||
* // use this to dump state to disk
|
||||
* auto output = make_shared <SimulatorOutput> (
|
||||
* params, deck, grid, timer, state, wellState, sim);
|
||||
* params, deck, timeMap, grid, timer, state, wellState, sim);
|
||||
*
|
||||
* // start simulation
|
||||
* sim.run (timer, state, ... )
|
||||
@@ -139,14 +143,16 @@ private:
|
||||
template <typename Simulator>
|
||||
struct SimulatorOutput : public SimulatorOutputBase {
|
||||
SimulatorOutput (const parameter::ParameterGroup& params,
|
||||
std::shared_ptr <EclipseGridParser> parser,
|
||||
std::shared_ptr <const Deck> parser,
|
||||
std::shared_ptr <const TimeMap> timeMap,
|
||||
std::shared_ptr <const UnstructuredGrid> grid,
|
||||
std::shared_ptr <const SimulatorTimer> timer,
|
||||
std::shared_ptr <const SimulatorState> state,
|
||||
std::shared_ptr <const WellState> wellState,
|
||||
std::shared_ptr <Simulator> 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) {
|
||||
@@ -161,7 +167,8 @@ struct SimulatorOutput : public SimulatorOutputBase {
|
||||
* the arguments passed exceeds the lifetime of this object.
|
||||
*/
|
||||
SimulatorOutput (const parameter::ParameterGroup& params,
|
||||
EclipseGridParser& parser,
|
||||
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),
|
||||
|
||||
Reference in New Issue
Block a user