Merge pull request #242 from rolk/242_callback

Let external objects observe individual timesteps in a simulation
This commit is contained in:
Atgeirr Flø Rasmussen 2013-05-22 03:46:02 -07:00
commit 7ee481a601
6 changed files with 69 additions and 6 deletions

View File

@ -29,7 +29,7 @@ set (${project}_DEPS
"CXX11Features" "CXX11Features"
# various runtime library enhancements # various runtime library enhancements
"Boost 1.39.0 "Boost 1.39.0
COMPONENTS date_time filesystem system unit_test_framework REQUIRED" COMPONENTS date_time filesystem system unit_test_framework signals REQUIRED"
# matrix library # matrix library
"BLAS REQUIRED" "BLAS REQUIRED"
"LAPACK REQUIRED" "LAPACK REQUIRED"

View File

@ -266,6 +266,7 @@ list (APPEND PUBLIC_HEADER_FILES
opm/core/simulator/BlackoilState.hpp opm/core/simulator/BlackoilState.hpp
opm/core/simulator/SimulatorCompressibleTwophase.hpp opm/core/simulator/SimulatorCompressibleTwophase.hpp
opm/core/simulator/SimulatorIncompTwophase.hpp opm/core/simulator/SimulatorIncompTwophase.hpp
opm/core/simulator/SimulatorIncompTwophase_impl.hpp
opm/core/simulator/SimulatorReport.hpp opm/core/simulator/SimulatorReport.hpp
opm/core/simulator/SimulatorTimer.hpp opm/core/simulator/SimulatorTimer.hpp
opm/core/simulator/TwophaseState.hpp opm/core/simulator/TwophaseState.hpp

View File

@ -20,7 +20,7 @@ find_opm_package (
"C99; "C99;
CXX11Features; CXX11Features;
Boost 1.39.0 Boost 1.39.0
COMPONENTS date_time filesystem system unit_test_framework REQUIRED; COMPONENTS date_time filesystem system unit_test_framework signals REQUIRED;
BLAS REQUIRED; BLAS REQUIRED;
LAPACK REQUIRED; LAPACK REQUIRED;
SuiteSparse COMPONENTS umfpack; SuiteSparse COMPONENTS umfpack;

View File

@ -49,6 +49,8 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/function.hpp>
#include <boost/signal.hpp>
#include <numeric> #include <numeric>
#include <fstream> #include <fstream>
@ -57,9 +59,8 @@
namespace Opm namespace Opm
{ {
class SimulatorIncompTwophase::Impl struct SimulatorIncompTwophase::Impl
{ {
public:
Impl(const parameter::ParameterGroup& param, Impl(const parameter::ParameterGroup& param,
const UnstructuredGrid& grid, const UnstructuredGrid& grid,
const IncompPropertiesInterface& props, const IncompPropertiesInterface& props,
@ -74,7 +75,6 @@ namespace Opm
TwophaseState& state, TwophaseState& state,
WellState& well_state); WellState& well_state);
private:
// Data. // Data.
// Parameters for output. // Parameters for output.
bool output_; bool output_;
@ -101,6 +101,9 @@ namespace Opm
boost::scoped_ptr<TransportSolverTwophaseInterface> tsolver_; boost::scoped_ptr<TransportSolverTwophaseInterface> tsolver_;
// Misc. data // Misc. data
std::vector<int> allcells_; std::vector<int> allcells_;
// list of hooks that are notified when a timestep completes
boost::signal0 <void> timestep_completed;
}; };
@ -130,6 +133,11 @@ namespace Opm
return pimpl_->run(timer, state, well_state); return pimpl_->run(timer, state, well_state);
} }
// connect the hook to the signal in the implementation class
void SimulatorIncompTwophase::connect_timestep_impl (boost::function0 <void> hook) {
pimpl_->timestep_completed.connect (hook);
}
static void reportVolumes(std::ostream &os, double satvol[2], double tot_porevol_init, static void reportVolumes(std::ostream &os, double satvol[2], double tot_porevol_init,
double tot_injected[2], double tot_produced[2], double tot_injected[2], double tot_produced[2],
double injected[2], double produced[2], double injected[2], double produced[2],
@ -411,6 +419,8 @@ namespace Opm
double ptime = 0.0; double ptime = 0.0;
Opm::time::StopWatch transport_timer; Opm::time::StopWatch transport_timer;
double ttime = 0.0; double ttime = 0.0;
Opm::time::StopWatch callback_timer;
double time_in_callbacks = 0.0;
Opm::time::StopWatch step_timer; Opm::time::StopWatch step_timer;
Opm::time::StopWatch total_timer; Opm::time::StopWatch total_timer;
total_timer.start(); total_timer.start();
@ -587,6 +597,12 @@ namespace Opm
if (output_) { if (output_) {
sreport.reportParam(tstep_os); sreport.reportParam(tstep_os);
} }
// notify all clients that we are done with the timestep
callback_timer.start ();
timestep_completed ();
callback_timer.stop ();
time_in_callbacks += callback_timer.secsSinceStart ();
} }
if (output_) { if (output_) {
@ -612,7 +628,7 @@ namespace Opm
SimulatorReport report; SimulatorReport report;
report.pressure_time = ptime; report.pressure_time = ptime;
report.transport_time = ttime; report.transport_time = ttime;
report.total_time = total_timer.secsSinceStart(); report.total_time = total_timer.secsSinceStart() - time_in_callbacks;
return report; return report;
} }

View File

@ -21,6 +21,8 @@
#define OPM_SIMULATORINCOMPTWOPHASE_HEADER_INCLUDED #define OPM_SIMULATORINCOMPTWOPHASE_HEADER_INCLUDED
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <functional> // bind
#include <vector> #include <vector>
struct UnstructuredGrid; struct UnstructuredGrid;
@ -88,12 +90,44 @@ namespace Opm
TwophaseState& state, TwophaseState& state,
WellState& well_state); WellState& well_state);
/// Register a callback for notifications about completed timestep.
/// The specified method of the object is called when the simulator
/// has completed a timestep and the state objects are (possibly)
/// changed.
/// If you want to know the current timestep, the callback must
/// also monitor the timer object which was passed to run().
/// \tparam T Type of the callback object.
/// \tparam callback Address of a member function of T which will
/// be invoked when a timestep completes.
/// \param[in] t Object which will receive notifications. The
/// lifetime of the object must span over the
/// duration of the simulation, and it is your
/// responsibility to ensure that.
/// \example
/// \code{.cpp}
/// struct Foo {
/// void bar () { cout << "Called!" << endl; }
/// };
///
/// SimulatorIncompTwophase sim (...);
/// Foo f;
/// sim.connect_timestep <Foo, &Foo::bar> (f);
/// sim.run (...);
/// \endcode
template <typename T, void (T::*callback)()>
void connect_timestep (T& t);
private: private:
class Impl; class Impl;
// Using shared_ptr instead of scoped_ptr since scoped_ptr requires complete type for Impl. // Using shared_ptr instead of scoped_ptr since scoped_ptr requires complete type for Impl.
boost::shared_ptr<Impl> pimpl_; boost::shared_ptr<Impl> pimpl_;
// implementation which is not templated, and can be in library
void connect_timestep_impl (boost::function0<void> hook);
}; };
} // namespace Opm } // namespace Opm
#include "SimulatorIncompTwophase_impl.hpp"
#endif // OPM_SIMULATORINCOMPTWOPHASE_HEADER_INCLUDED #endif // OPM_SIMULATORINCOMPTWOPHASE_HEADER_INCLUDED

View File

@ -0,0 +1,12 @@
#ifndef OPM_SIMULATORINCOMPTWOPHASE_HEADER_INCLUDED
#error Do not include SimulatorIncompTwophase directly!
#endif
namespace Opm {
template <typename T, void (T::*callback)()>
inline void SimulatorIncompTwophase::connect_timestep (T& t) {
connect_timestep_impl (boost::function0<void> (std::bind (callback, t)));
}
} /* namespace Opm */