Provide wrapper which connect simulator and writer
This wrapper class aggregate all the result objects (state, timer etc.) and register itself for notification with the simulator. At every timestep the simulator should provide a notification. The wrapper will receive this and pass all the state objects to the writer(s) which creates a new timestep. Currently this doesn't work out-of-the-box because only the two-phase simulator sends notifications and the writer only understand the state of blackoil simulators, but these two concepts should be unified.
This commit is contained in:
1 parent
ede84e6cc8
commit
f710ff71d1
3 files changed
+246
No files matched your search
@@ -99,6 +99,7 @@ list (APPEND MAIN_SOURCE_FILES
|
||||
opm/core/simulator/BlackoilState.cpp
|
||||
opm/core/simulator/SimulatorCompressibleTwophase.cpp
|
||||
opm/core/simulator/SimulatorIncompTwophase.cpp
|
||||
opm/core/simulator/SimulatorOutput.cpp
|
||||
opm/core/simulator/SimulatorReport.cpp
|
||||
opm/core/simulator/SimulatorState.cpp
|
||||
opm/core/simulator/SimulatorTimer.cpp
|
||||
@@ -307,6 +308,7 @@ list (APPEND PUBLIC_HEADER_FILES
|
||||
opm/core/simulator/BlackoilState.hpp
|
||||
opm/core/simulator/SimulatorCompressibleTwophase.hpp
|
||||
opm/core/simulator/SimulatorIncompTwophase.hpp
|
||||
opm/core/simulator/SimulatorOutput.hpp
|
||||
opm/core/simulator/SimulatorReport.hpp
|
||||
opm/core/simulator/SimulatorState.hpp
|
||||
opm/core/simulator/SimulatorTimer.hpp
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include "SimulatorOutput.hpp"
|
||||
|
||||
// we need complete definitions for these types
|
||||
#include <opm/core/io/eclipse/EclipseGridParser.hpp>
|
||||
#include <opm/core/io/OutputWriter.hpp>
|
||||
#include <opm/core/simulator/SimulatorTimer.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
|
||||
SimulatorOutputBase::SimulatorOutputBase (
|
||||
const parameter::ParameterGroup& params,
|
||||
std::shared_ptr <EclipseGridParser> parser,
|
||||
std::shared_ptr <SimulatorTimer> timer,
|
||||
std::shared_ptr <BlackoilState> state,
|
||||
std::shared_ptr <WellState> wellState)
|
||||
|
||||
// store all parameters passed into the object, making them curried
|
||||
// parameters to the writeOutput function.
|
||||
: parser_ (parser )
|
||||
, timer_ (timer )
|
||||
, reservoirState_ (state )
|
||||
, wellState_ (wellState)
|
||||
|
||||
// process parameters into a writer. we don't setup a new chain in
|
||||
// every timestep!
|
||||
, writer_ (std::move (OutputWriter::create (params, parser_)))
|
||||
|
||||
// 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.
|
||||
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);
|
||||
}
|
||||
|
||||
SimulatorOutputBase::operator std::function <void ()> () {
|
||||
// return (a pointer to) the writeOutput() function as an object
|
||||
// which can be passed to the event available from the simulator
|
||||
return std::bind (&SimulatorOutputBase::writeOutput, std::ref (*this));
|
||||
}
|
||||
|
||||
void
|
||||
SimulatorOutputBase::writeOutput () {
|
||||
// write output for all timesteps that have passed (usually only
|
||||
// one, unless you have entered the same time twice, or the simulator
|
||||
// doesn't honor the TSTEP settings)
|
||||
for (;
|
||||
next_ < times_.size () && times_[next_] <= timer_->currentTime ();
|
||||
++next_) {
|
||||
|
||||
// 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
|
||||
sync ();
|
||||
|
||||
// relay the request to the handlers (setup in the constructor
|
||||
// from parameters)
|
||||
writer_->writeTimeStep (*timer_, *reservoirState_, *wellState_);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimulatorOutputBase::sync () {
|
||||
// no-op in base class (overridden by simulator-specific template)
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
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_SIMULATOR_OUTPUT_HPP
|
||||
#define OPM_SIMULATOR_OUTPUT_HPP
|
||||
|
||||
#include <memory> // unique_ptr, shared_ptr
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
// forward definitions
|
||||
class BlackoilState;
|
||||
class EclipseGridParser;
|
||||
class OutputWriter;
|
||||
namespace parameter { class ParameterGroup; }
|
||||
class SimulatorTimer;
|
||||
class WellState;
|
||||
|
||||
/**
|
||||
* Encapsulate output writing from simulators. This is essentially
|
||||
* a function object holding curried arguments to the writing backend
|
||||
* which is used when invoked through the event handler (which passes
|
||||
* on no arguments on it own).
|
||||
*/
|
||||
class SimulatorOutputBase {
|
||||
protected:
|
||||
/**
|
||||
* Curry arguments for the output writer. These arguments are passed
|
||||
* to the simulator, but is not passed on to the event handler so it
|
||||
* need to pick them up from the object members.
|
||||
*/
|
||||
SimulatorOutputBase (const parameter::ParameterGroup& p,
|
||||
std::shared_ptr <EclipseGridParser> parser,
|
||||
std::shared_ptr <SimulatorTimer> timer,
|
||||
std::shared_ptr <BlackoilState> state,
|
||||
std::shared_ptr <WellState> wellState);
|
||||
|
||||
/**
|
||||
* Conversion operator which allows the object to be directly passed
|
||||
* into an Event and used as a handler.
|
||||
*
|
||||
* @see Opm::SimulatorIncompTwophase::timestep_completed
|
||||
*/
|
||||
operator std::function <void ()> ();
|
||||
|
||||
/// Just hold a reference to these objects that are owned elsewhere.
|
||||
std::shared_ptr <EclipseGridParser> parser_;
|
||||
std::shared_ptr <SimulatorTimer> timer_;
|
||||
std::shared_ptr <BlackoilState> reservoirState_;
|
||||
std::shared_ptr <WellState> wellState_;
|
||||
|
||||
/// Created locally and destructed together with us
|
||||
std::unique_ptr <OutputWriter> writer_;
|
||||
|
||||
/// Call the writers that were created based on the parameters
|
||||
virtual void writeOutput ();
|
||||
|
||||
/// Make sure that the simulator state is up to date before writing
|
||||
virtual void sync ();
|
||||
|
||||
private:
|
||||
/// Index of the upcoming reporting time
|
||||
std::vector <double>::size_type next_;
|
||||
|
||||
/// Array of times when to write report
|
||||
std::vector <double> times_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an output writer that is coupled to a simulator capable
|
||||
* of reading Eclipse deck files. Output will be written only when
|
||||
* specified in the deck file.
|
||||
*
|
||||
* @note
|
||||
* This class is a template since there is no fixed interface for
|
||||
* simulators, only an implied type class of common method signatures.
|
||||
*
|
||||
* @example
|
||||
* @code{.cpp}
|
||||
* // configuration
|
||||
* ParameterGroup params (argc, argv, false);
|
||||
*
|
||||
* // input file
|
||||
* auto deck = make_shared <EclipseGridParser> ( ... );
|
||||
*
|
||||
* // timestep ends up here
|
||||
* auto timer = make_shared <SimulatorTimer> ();
|
||||
*
|
||||
* // state ends up here
|
||||
* auto state = make_shared <TwophaseState> ();
|
||||
* auto wellState = make_shared <WellState> ();
|
||||
*
|
||||
* // set up simulation
|
||||
* auto sim = make_shared <SimulatorIncompTwophase> (params, grid, ... );
|
||||
*
|
||||
* // use this to dump state to disk
|
||||
* auto output = make_shared <SimulatorOutput> (
|
||||
* params, deck, timer, state, wellState, sim);
|
||||
*
|
||||
* // start simulation
|
||||
* sim.run (timer, state, ... )
|
||||
* @endcode
|
||||
*
|
||||
* @todo
|
||||
* This functionality could be incorporated directly into a simulator
|
||||
* object.
|
||||
*/
|
||||
template <typename Simulator>
|
||||
struct SimulatorOutput : public SimulatorOutputBase {
|
||||
SimulatorOutput (const parameter::ParameterGroup& params,
|
||||
std::shared_ptr <EclipseGridParser> parser,
|
||||
std::shared_ptr <SimulatorTimer> timer,
|
||||
std::shared_ptr <BlackoilState> state,
|
||||
std::shared_ptr <WellState> wellState,
|
||||
std::shared_ptr <Simulator> sim)
|
||||
// send all other parameters to base class
|
||||
: SimulatorOutputBase (params, parser, timer, state, wellState)
|
||||
|
||||
// store reference to simulator in derived class
|
||||
, sim_ (sim) {
|
||||
|
||||
// connect simulation with output writer
|
||||
sim.timestep_completed ().add (*this);
|
||||
}
|
||||
|
||||
protected:
|
||||
// forward this request to the simulator
|
||||
virtual void sync () { sim_->sync (); }
|
||||
|
||||
private:
|
||||
/// Reference to the simulator class; needed to ask it to synchronize
|
||||
std::shared_ptr <Simulator> sim_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* OPM_SIMULATOR_OUTPUT_HPP */
|
||||
Reference in new issue
Block a user