From b03e238d458e873eb12789aedec763eb3e9a53d7 Mon Sep 17 00:00:00 2001 From: Roland Kaufmann Date: Thu, 22 Aug 2013 13:06:46 +0200 Subject: [PATCH] Provide protocol for exchanging state with client The state that is passed to the simulator object is directly accessible without any encapsulation towards the client. After the notification callback was introduced, this allows the client to observe the state in the middle of a simulation. However, it may be that the simulator has some internal state which is not reflected in the state object because there is a cost associated by flushing it into the TwophaseState format. The notification is called back on every timestep, not just the ones that will do reporting. It may even be that reporting is done dynamically and is not known at the time of setup. (It is more like a condition variable). Consequently, flushing the state in every timestep is a bad idea. This patch sets up a new method sync() which it is expected that the notification will call if it needs the state for reporting purposes. Currently it is a no-op. It just establishes a protocol that other, compatible implementations can also use. --- opm/simulators/SimulatorIncompTwophase.cpp | 5 +++++ opm/simulators/SimulatorIncompTwophase.hpp | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/opm/simulators/SimulatorIncompTwophase.cpp b/opm/simulators/SimulatorIncompTwophase.cpp index 5005c586d..0c55c8838 100644 --- a/opm/simulators/SimulatorIncompTwophase.cpp +++ b/opm/simulators/SimulatorIncompTwophase.cpp @@ -136,6 +136,11 @@ namespace Opm return pimpl_->timestep_completed_; } + // empty default implementation, but provided in module; it is dangerous ta have + // this inlined in clients from the header, because then it can't be updated! + void SimulatorIncompTwophase::sync () { + } + static void reportVolumes(std::ostream &os, double satvol[2], double tot_porevol_init, double tot_injected[2], double tot_produced[2], double injected[2], double produced[2], diff --git a/opm/simulators/SimulatorIncompTwophase.hpp b/opm/simulators/SimulatorIncompTwophase.hpp index 09ea2b93a..cba56a286 100644 --- a/opm/simulators/SimulatorIncompTwophase.hpp +++ b/opm/simulators/SimulatorIncompTwophase.hpp @@ -110,8 +110,28 @@ namespace Opm /// sim.timestep_completed ().add (f); /// sim.run (...); /// \endcode + /// + /// \note + /// Registered callbacks should call the sync() method before + /// accessing the state that was passed into the run() method. + /// + /// \see Opm::SimulatorIncompTwophase::sync Event& timestep_completed (); + /// Notify the simulator that a callback has an interest in reading + /// for reporting purposes the contents of the state argument that + /// was passed to the run() method. The simulator will then flush + /// any internal state which is currently not reflected in it. + /// + /// \note + /// This should only be called from within a notification which has + /// been setup with timestep_completed(). Avoid calling this method + /// outside of run(). + /// + /// \see Opm::SimulatorIncompTwophase::run, + /// Opm::SimulatorIncompTwophase::timestep_completed + void sync (); + private: struct Impl; // Using shared_ptr instead of unique_ptr since unique_ptr requires complete type for Impl.