Masquerade the actual output format with an interface

Using an interface allows us to code the simulator to just pass the
necessary state variables to something which implements this, and
then the user can select the actual output format with configuration
values. This allows us to set new formats without having to change
the code being compiled (for instance, we can have a special debug
"format" which prints out things of interest in each timestep)
This commit is contained in:
Roland Kaufmann 2013-11-07 13:40:25 +01:00
parent 992572c522
commit 441fd2825b
4 changed files with 197 additions and 5 deletions

View File

@ -37,6 +37,7 @@ list (APPEND MAIN_SOURCE_FILES
opm/core/grid/cpgpreprocess/geometry.c
opm/core/grid/cpgpreprocess/preprocess.c
opm/core/grid/cpgpreprocess/uniquepoints.c
opm/core/io/BlackoilOutputWriter.cpp
opm/core/io/eclipse/BlackoilEclipseOutputWriter.cpp
opm/core/io/eclipse/EclipseGridInspector.cpp
opm/core/io/eclipse/EclipseGridParser.cpp
@ -230,6 +231,7 @@ list (APPEND PUBLIC_HEADER_FILES
opm/core/grid/cpgpreprocess/grdecl.h
opm/core/grid/cpgpreprocess/preprocess.h
opm/core/grid/cpgpreprocess/uniquepoints.h
opm/core/io/BlackoilOutputWriter.hpp
opm/core/io/eclipse/BlackoilEclipseOutputWriter.hpp
opm/core/io/eclipse/CornerpointChopper.hpp
opm/core/io/eclipse/EclipseGridInspector.hpp

View File

@ -0,0 +1,93 @@
#include "BlackoilOutputWriter.hpp"
#include <opm/core/io/eclipse/BlackoilEclipseOutputWriter.hpp>
#include <opm/core/utility/parameters/Parameter.hpp>
#include <opm/core/utility/parameters/ParameterGroup.hpp>
#include <map>
#include <memory> // unique_ptr
#include <vector>
using namespace std;
using namespace Opm;
using namespace Opm::parameter;
namespace {
/// Multiplexer over a list of output writers
struct BlackoilMultiOutputWriter : public BlackoilOutputWriter {
/// Shorthand for a list of owned output writers
typedef vector <unique_ptr <BlackoilOutputWriter> > writers_t;
typedef writers_t::iterator it_t;
typedef unique_ptr <writers_t> ptr_t;
/// Adopt a list of writers
BlackoilMultiOutputWriter (ptr_t writers)
: writers_ (std::move (writers)) { }
/// Forward the call to all writers
virtual void writeInit(const SimulatorTimer &timer) {
for (it_t it = writers_->begin (); it != writers_->end (); ++it) {
(*it)->writeInit (timer);
}
}
virtual void writeTimeStep(const SimulatorTimer& timer,
const BlackoilState& reservoirState,
const WellState& wellState) {
for (it_t it = writers_->begin (); it != writers_->end(); ++it) {
(*it)->writeTimeStep (timer, reservoirState, wellState);
}
}
private:
ptr_t writers_;
};
/// Psuedo-constructor, can appear in template
template <typename Format> unique_ptr <BlackoilOutputWriter>
create (const ParameterGroup& params, const EclipseGridParser& parser) {
return unique_ptr <BlackoilOutputWriter> (new Format (params, parser));
}
/// Map between keyword in configuration and the corresponding
/// constructor function (type) that should be called when detected.
/// The writer must have a constructor which takes params and parser.
///
/// If you want to add more possible writer formats, just add them
/// to the list below!
typedef map <const char*,
unique_ptr <BlackoilOutputWriter> (*)(const ParameterGroup&,
const EclipseGridParser&)> map_t;
map_t FORMATS = {
{ "output_ecl", &create <BlackoilEclipseOutputWriter> },
};
} // anonymous namespace
unique_ptr <BlackoilOutputWriter>
BlackoilOutputWriter::create (const ParameterGroup& params,
const EclipseGridParser& parser) {
// allocate a list which will be filled with writers. this list
// is initially empty (no output).
BlackoilMultiOutputWriter::ptr_t list (
new BlackoilMultiOutputWriter::writers_t ());
// loop through the map and see if we can find the key that is
// specified there
typedef map_t::iterator map_it_t;
for (map_it_t it = FORMATS.begin (); it != FORMATS.end(); ++it) {
// keyword which would indicate that this format should be used
const std::string name (it->first);
// invoke the constructor for the type if we found the keyword
// and put the pointer to this writer onto the list
if (params.getDefault <bool> (name, false)) {
list->push_back (it->second (params, parser));
}
}
// create a multiplexer from the list of formats we found
return unique_ptr <BlackoilOutputWriter> (
new BlackoilMultiOutputWriter (std::move (list)));
}

View File

@ -0,0 +1,95 @@
/*
Copyright (c) 2013 Uni Research AS
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_BLACKOIL_OUTPUT_WRITER_HPP
#define OPM_BLACKOIL_OUTPUT_WRITER_HPP
#include <memory> // unique_ptr
namespace Opm {
// forward declaration
class BlackoilState;
class EclipseGridParser;
namespace parameter { class ParameterGroup; }
class SimulatorTimer;
class WellState;
/*!
* Interface for writing non-compositional (blackoil, two-phase) simulation
* state to files.
*
* Use the create() function to setup a chain of writer based on the
* configuration values, e.g.
*
* \example
* \code{.cpp}
* ParameterGroup params (argc, argv, false);
* EclipseGridParser parser (params.get <string> ("deck_filename");
*
* std::unique_ptr <BlackoilOutputWriter> writer =
* BlackoilOutputWriter::create (params, parser);
*
* // before the first timestep
* writer->writeInit (timer);
*
* // after each timestep
* writer->writeTimeStep (timer, state, wellState);
*
* \endcode
*/
class BlackoilOutputWriter {
public:
/*!
* \brief Write the static eclipse data (grid, PVT curves, etc) to disk
*/
virtual void writeInit(const SimulatorTimer &timer) = 0;
/*!
* \brief Write a blackoil reservoir state to disk for later inspection with
* visualization tools like ResInsight
*
* \param[in] reservoirState The thermodynamic state of the reservoir
* \param[in] wellState The production/injection data for all wells
*/
virtual void writeTimeStep(const SimulatorTimer& timer,
const BlackoilState& reservoirState,
const WellState& wellState) = 0;
/*!
* Create a suitable set of output formats based on configuration.
*
* @param params Configuration properties. This function will setup a
* multiplexer of applicable output formats based on the
* desired configuration values.
*
* @param parser Input deck used to set up the simulation. The lifetime
* of this object must exceed the lifetime of the writer
* that is returned.
*
* @return Pointer to a multiplexer to all applicable output formats.
*/
static std::unique_ptr <BlackoilOutputWriter>
create (const parameter::ParameterGroup& params,
const EclipseGridParser& parser);
};
} // namespace Opm
#endif /* OPM_BLACKOIL_OUTPUT_WRITER_HPP */

View File

@ -21,6 +21,8 @@
#ifndef OPM_BLACKOIL_ECLIPSE_OUTPUT_WRITER_HPP
#define OPM_BLACKOIL_ECLIPSE_OUTPUT_WRITER_HPP
#include <opm/core/io/BlackoilOutputWriter.hpp>
#include <string>
#include <memory> // std::unique_ptr
@ -48,7 +50,7 @@ namespace internal { struct EclipseSummary; }
* 'write_output' parameter is set but ERT is not available, all
* methods throw a std::runtime_error.
*/
class BlackoilEclipseOutputWriter
class BlackoilEclipseOutputWriter : public BlackoilOutputWriter
{
public:
/*!
@ -61,7 +63,7 @@ public:
/*!
* \brief Write the static eclipse data (grid, PVT curves, etc) to disk
*/
void writeInit(const SimulatorTimer &timer);
virtual void writeInit(const SimulatorTimer &timer);
/*!
* \brief Write a blackoil reservoir state to disk for later inspection with
@ -70,7 +72,7 @@ public:
* \param[in] reservoirState The thermodynamic state of the reservoir
* \param[in] wellState The production/injection data for all wells
*/
void writeTimeStep(const SimulatorTimer& timer,
virtual void writeTimeStep(const SimulatorTimer& timer,
const BlackoilState& reservoirState,
const WellState& wellState);