28#ifndef EWOMS_SIMULATOR_HH
29#define EWOMS_SIMULATOR_HH
41#include <dune/common/parallel/mpihelper.hh>
56 return Dune::MPIHelper::getCommunication();
61#define EWOMS_CATCH_PARALLEL_EXCEPTIONS_FATAL(code) \
63 const auto& comm = ::Opm::detail::getMPIHelperCommunication(); \
64 bool exceptionThrown = false; \
66 catch (const Dune::Exception& e) { \
67 exceptionThrown = true; \
68 std::cerr << "Process " << comm.rank() << " threw a fatal exception: " \
69 << e.what() << ". Abort!" << std::endl; \
71 catch (const std::exception& e) { \
72 exceptionThrown = true; \
73 std::cerr << "Process " << comm.rank() << " threw a fatal exception: " \
74 << e.what() << ". Abort!" << std::endl; \
77 exceptionThrown = true; \
78 std::cerr << "Process " << comm.rank() << " threw a fatal exception. " \
79 <<" Abort!" << std::endl; \
82 if (comm.max(exceptionThrown)) \
100template <
class TypeTag>
109 using MPIComm =
typename Dune::MPIHelper::MPICommunicator;
110 using Communication = Dune::Communication<MPIComm>;
127 verbose_ = verbose && comm.rank() == 0;
132 endTime_ = Parameters::Get<Parameters::EndTime<Scalar>>();
133 timeStepSize_ = Parameters::Get<Parameters::InitialTimeStepSize<Scalar>>();
134 assert(timeStepSize_ > 0);
135 const std::string& predetTimeStepFile =
136 Parameters::Get<Parameters::PredeterminedTimeStepsFile>();
137 if (!predetTimeStepFile.empty()) {
138 std::ifstream is(predetTimeStepFile);
142 forcedTimeSteps_.push_back(dt);
147 episodeStartTime_ = 0;
148 episodeLength_ = std::numeric_limits<Scalar>::max();
153 std::cout <<
"Allocating the simulation vanguard\n" << std::flush;
155 int exceptionThrown = 0;
159 [&exceptionThrown, &what, comm](
const std::exception& e,
163 if (comm.size() > 1) {
164 what +=
" (on rank " + std::to_string(comm.rank()) +
")";
167 std::cerr <<
"Rank " << comm.rank() <<
" threw an exception: " << e.what() << std::endl;
170 auto checkParallelException =
171 [comm](
const std::string& prefix,
172 int exceptionThrown_,
173 const std::string& what_)
175 if (comm.max(exceptionThrown_)) {
177 assert(!all_what.empty());
178 throw std::runtime_error(prefix + all_what.front());
183 { vanguard_.reset(
new Vanguard(*
this)); }
184 catch (
const std::exception& e) {
185 catchAction(e, verbose_);
187 checkParallelException(
"Allocating the simulation vanguard failed: ",
188 exceptionThrown, what);
191 std::cout <<
"Distributing the vanguard's data\n" << std::flush;
194 { vanguard_->loadBalance(); }
195 catch (
const std::exception& e) {
196 catchAction(e, verbose_);
198 checkParallelException(
"Could not distribute the vanguard data: ",
199 exceptionThrown, what);
202 std::cout <<
"Allocating the model\n" << std::flush;
204 model_.reset(
new Model(*
this));
206 catch (
const std::exception& e) {
207 catchAction(e, verbose_);
209 checkParallelException(
"Could not allocate model: ",
210 exceptionThrown, what);
213 std::cout <<
"Allocating the problem\n" << std::flush;
216 problem_.reset(
new Problem(*
this));
218 catch (
const std::exception& e) {
219 catchAction(e, verbose_);
221 checkParallelException(
"Could not allocate the problem: ",
222 exceptionThrown, what);
225 std::cout <<
"Initializing the model\n" << std::flush;
228 { model_->finishInit(); }
229 catch (
const std::exception& e) {
230 catchAction(e, verbose_);
232 checkParallelException(
"Could not initialize the model: ",
233 exceptionThrown, what);
236 std::cout <<
"Initializing the problem\n" << std::flush;
239 { problem_->finishInit(); }
240 catch (
const std::exception& e) {
241 catchAction(e, verbose_);
243 checkParallelException(
"Could not initialize the problem: ",
244 exceptionThrown, what);
249 std::cout <<
"Simulator successfully set up\n" << std::flush;
257 Parameters::Register<Parameters::EndTime<Scalar>>
258 (
"The simulation time at which the simulation is finished [s]");
259 Parameters::Register<Parameters::InitialTimeStepSize<Scalar>>
260 (
"The size of the initial time step [s]");
261 Parameters::Register<Parameters::RestartTime<Scalar>>
262 (
"The simulation time at which a restart should be attempted [s]");
263 Parameters::Register<Parameters::PredeterminedTimeStepsFile>
264 (
"A file with a list of predetermined time step sizes (one "
265 "time step per line)");
267 Vanguard::registerParameters();
268 Model::registerParameters();
269 Problem::registerParameters();
276 {
return *vanguard_; }
282 {
return *vanguard_; }
288 {
return vanguard_->gridView(); }
307 {
return *problem_; }
314 {
return *problem_; }
328 {
return startTime_; }
348 timeStepIdx_ = stepIdx;
381 {
return setupTimer_; }
388 {
return executionTimer_; }
390 {
return executionTimer_; }
397 {
return prePostProcessTimer_; }
404 {
return linearizeTimer_; }
411 {
return solveTimer_; }
418 {
return updateTimer_; }
425 {
return writeTimer_; }
439 timeStepSize_ = value;
448 { timeStepIdx_ = value; }
456 {
return timeStepSize_; }
463 {
return timeStepIdx_; }
473 { finished_ = yesno; }
483 assert(timeStepSize_ >= 0.0);
486 *std::numeric_limits<Scalar>::epsilon()*1e3;
487 return finished_ || (this->
time()*(1.0 + eps) >=
endTime());
496 static const Scalar eps = std::numeric_limits<Scalar>::epsilon()*1e3;
498 return finished_ || (this->
time() + timeStepSize_)*(1.0 + eps) >=
endTime();
537 episodeStartTime_ = startTime_ + time_;
538 episodeLength_ = len;
547 { episodeIdx_ = episodeIdx; }
555 {
return episodeIdx_; }
562 {
return episodeStartTime_; }
570 { episodeLength_ = dt; }
577 {
return episodeLength_; }
585 static const Scalar eps = std::numeric_limits<Scalar>::epsilon()*1e3;
587 return this->
time() <= (episodeStartTime_ -
startTime())*(1 + eps);
596 static const Scalar eps = std::numeric_limits<Scalar>::epsilon()*1e3;
607 static const Scalar eps = std::numeric_limits<Scalar>::epsilon()*1e3;
628 return std::max<Scalar>(0.0,
647 TimerGuard executionTimerGuard(executionTimer_);
648 TimerGuard prePostProcessTimerGuard(prePostProcessTimer_);
652 Scalar restartTime = Parameters::Get<Parameters::RestartTime<Scalar>>();
653 if (restartTime > -1e30) {
660 std::cout <<
"Deserialize from file '" << res.
fileName() <<
"'\n" << std::flush;
666 std::cout <<
"Deserialization done."
670 <<
"\n" << std::flush;
675 std::cout <<
"Applying the initial solution of the \"" << problem_->name()
676 <<
"\" problem\n" << std::flush;
678 Scalar oldTimeStepSize = timeStepSize_;
679 int oldTimeStepIdx = timeStepIdx_;
686 if (problem_->shouldWriteOutput())
689 timeStepSize_ = oldTimeStepSize;
690 timeStepIdx_ = oldTimeStepIdx;
694 executionTimer_.
start();
698 prePostProcessTimer_.
start();
708 prePostProcessTimer_.
stop();
713 episodeBegins =
false;
716 std::cout <<
"Begin time step " <<
timeStepIndex() + 1 <<
". "
730 prePostProcessTimer_.
stop();
734 prePostProcessTimer_.
stop();
738 problem_->timeIntegration();
743 const auto&
model = problem_->model();
744 prePostProcessTimer_ +=
model.prePostProcessTimer();
745 linearizeTimer_ +=
model.linearizeTimer();
746 solveTimer_ +=
model.solveTimer();
747 updateTimer_ +=
model.updateTimer();
752 const auto&
model = problem_->model();
753 prePostProcessTimer_ +=
model.prePostProcessTimer();
754 linearizeTimer_ +=
model.linearizeTimer();
755 solveTimer_ +=
model.solveTimer();
756 updateTimer_ +=
model.updateTimer();
759 prePostProcessTimer_.
start();
761 prePostProcessTimer_.
stop();
765 if (problem_->shouldWriteOutput())
774 std::cout <<
"Time step " <<
timeStepIndex() + 1 <<
" done. "
778 <<
"\n" << std::flush;
785 prePostProcessTimer_.
start();
790 episodeBegins =
true;
794 if (timeStepIdx_ <
static_cast<int>(forcedTimeSteps_.size()))
796 dt = forcedTimeSteps_[timeStepIdx_];
803 prePostProcessTimer_.
stop();
807 if (problem_->shouldWriteRestartFile())
811 executionTimer_.
stop();
824 std::ostringstream oss;
825 oss << std::setprecision(4);
828 if (timeInSeconds >= 365.25*24*60*60) {
829 int years =
static_cast<int>(timeInSeconds/(365.25*24*60*60));
830 int days =
static_cast<int>((timeInSeconds - years*(365.25*24*60*60))/(24*60*60));
832 double accuracy = 1e-2;
834 std::round(1.0/accuracy*
836 - years*(365.25*24*60*60)
837 - days*(24*60*60))/(60*60))
840 oss << years <<
" years, " << days <<
" days, " << hours <<
" hours";
842 else if (timeInSeconds >= 24.0*60*60) {
843 int days =
static_cast<int>(timeInSeconds/(24*60*60));
844 int hours =
static_cast<int>((timeInSeconds - days*(24*60*60))/(60*60));
846 double accuracy = 1e-2;
848 std::round(1.0/accuracy*
854 oss << days <<
" days, " << hours <<
" hours, " << minutes <<
" minutes";
856 else if (timeInSeconds >= 60.0*60) {
857 int hours =
static_cast<int>(timeInSeconds/(60*60));
858 int minutes =
static_cast<int>((timeInSeconds - hours*(60*60))/60);
860 double accuracy = 1e-2;
862 std::round(1.0/accuracy*
868 oss << hours <<
" hours, " << minutes <<
" minutes, " << seconds <<
" seconds";
870 else if (timeInSeconds >= 60.0) {
871 int minutes =
static_cast<int>(timeInSeconds/60);
873 double accuracy = 1e-3;
875 std::round(1.0/accuracy*
880 oss << minutes <<
" minutes, " << seconds <<
" seconds";
882 else if (!isAmendment)
883 oss << timeInSeconds <<
" seconds";
912 std::cout <<
"Serialize to file '" << res.fileName() <<
"'"
914 <<
"\n" << std::flush;
917 problem_->serialize(res);
918 model_->serialize(res);
929 template <
class Restarter>
932 restarter.serializeSectionBegin(
"Simulator");
933 restarter.serializeStream()
934 << episodeIdx_ <<
" "
935 << episodeStartTime_ <<
" "
936 << episodeLength_ <<
" "
939 << timeStepIdx_ <<
" ";
940 restarter.serializeSectionEnd();
950 template <
class Restarter>
953 restarter.deserializeSectionBegin(
"Simulator");
954 restarter.deserializeStream()
961 restarter.deserializeSectionEnd();
964 template<
class Serializer>
967 serializer(*vanguard_);
969 serializer(*problem_);
970 serializer(episodeIdx_);
971 serializer(episodeStartTime_);
972 serializer(episodeLength_);
973 serializer(startTime_);
975 serializer(timeStepIdx_);
979 std::unique_ptr<Vanguard> vanguard_;
980 std::unique_ptr<Model> model_;
981 std::unique_ptr<Problem> problem_;
984 Scalar episodeStartTime_;
985 Scalar episodeLength_;
988 Timer executionTimer_;
989 Timer prePostProcessTimer_;
990 Timer linearizeTimer_;
995 std::vector<Scalar> forcedTimeSteps_;
1000 Scalar timeStepSize_;
1007namespace Properties {
1008template<
class TypeTag>
Defines a type tags and some fundamental properties all models.
Load or save a state of a problem to/from the harddisk.
Definition: restart.hh:41
void serializeBegin(Simulator &simulator)
Write the current state of the model to disk.
Definition: restart.hh:101
const std::string & fileName() const
Returns the name of the file which is (de-)serialized.
Definition: restart.hh:94
void deserializeBegin(Simulator &simulator, Scalar t)
Start reading a restart file at a certain simulated time.
Definition: restart.hh:172
void deserializeEnd()
Stop reading the restart file.
Definition: restart.hh:265
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:102
const Timer & writeTimer() const
Returns a reference to the timer object which measures the time needed to write the visualization out...
Definition: simulator.hh:424
Scalar timeStepSize() const
Returns the time step length so that we don't miss the beginning of the next episode or cross the en...
Definition: simulator.hh:455
Scalar startTime() const
Return the time of the start of the simulation.
Definition: simulator.hh:327
int timeStepIndex() const
Returns number of time steps which have been executed since the beginning of the simulation.
Definition: simulator.hh:462
void serialize()
This method writes the complete state of the simulation to the harddisk.
Definition: simulator.hh:906
Timer & executionTimer()
Definition: simulator.hh:389
Scalar episodeLength() const
Returns the length of the current episode in simulated time .
Definition: simulator.hh:576
const Timer & prePostProcessTimer() const
Returns a reference to the timer object which measures the time needed for pre- and postprocessing of...
Definition: simulator.hh:396
const Timer & solveTimer() const
Returns a reference to the timer object which measures the time needed by the solver.
Definition: simulator.hh:410
void startNextEpisode(Scalar len=std::numeric_limits< Scalar >::max())
Start the next episode, but don't change the episode identifier.
Definition: simulator.hh:534
void serializeOp(Serializer &serializer)
Definition: simulator.hh:965
const Vanguard & vanguard() const
Return a reference to the grid manager of simulation.
Definition: simulator.hh:281
void serialize(Restarter &restarter)
Write the time manager's state to a restart file.
Definition: simulator.hh:930
const Timer & updateTimer() const
Returns a reference to the timer object which measures the time needed to the solutions of the non-li...
Definition: simulator.hh:417
const Timer & executionTimer() const
Returns a reference to the timer object which measures the time needed to run the simulation.
Definition: simulator.hh:387
void startNextEpisode(Scalar episodeStartTime, Scalar episodeLength)
Change the current episode of the simulation.
Definition: simulator.hh:520
void setEndTime(Scalar t)
Set the time of simulated seconds at which the simulation runs.
Definition: simulator.hh:366
const Timer & linearizeTimer() const
Returns a reference to the timer object which measures the time needed for linarizing the solutions.
Definition: simulator.hh:403
void setStartTime(Scalar t)
Set the time of the start of the simulation.
Definition: simulator.hh:321
void deserialize(Restarter &restarter)
Read the time manager's state from a restart file.
Definition: simulator.hh:951
Simulator(Communication comm, bool verbose=true)
Definition: simulator.hh:121
void setTimeStepSize(Scalar value)
Set the current time step size to a given value.
Definition: simulator.hh:437
bool episodeStarts() const
Returns true if the current episode has just been started at the current time.
Definition: simulator.hh:583
void run()
Runs the simulation using a given problem class.
Definition: simulator.hh:643
Vanguard & vanguard()
Return a reference to the grid manager of simulation.
Definition: simulator.hh:275
int episodeIndex() const
Returns the index of the current episode.
Definition: simulator.hh:554
void setTimeStepIndex(unsigned value)
Set the current time step index to a given value.
Definition: simulator.hh:447
void setFinished(bool yesno=true)
Specify whether the simulation is finished.
Definition: simulator.hh:472
Problem & problem()
Return the object which specifies the pysical setup of the simulation.
Definition: simulator.hh:306
static void registerParameters()
Registers all runtime parameters used by the simulation.
Definition: simulator.hh:255
void setTime(Scalar t)
Set the current simulated time, don't change the current time step index.
Definition: simulator.hh:336
bool willBeFinished() const
Returns true if the simulation is finished after the time level is incremented by the current time st...
Definition: simulator.hh:494
bool finished() const
Returns true if the simulation is finished.
Definition: simulator.hh:481
Scalar maxTimeStepSize() const
Aligns the time step size to the episode boundary and to the end time of the simulation.
Definition: simulator.hh:505
const Model & model() const
Return the physical model used in the simulation.
Definition: simulator.hh:299
Simulator(bool verbose=true)
Definition: simulator.hh:116
void setTime(Scalar t, unsigned stepIdx)
Set the current simulated time and the time step index.
Definition: simulator.hh:345
bool episodeIsOver() const
Returns true if the current episode is finished at the current time.
Definition: simulator.hh:594
Scalar endTime() const
Returns the number of (simulated) seconds which the simulation runs.
Definition: simulator.hh:373
Simulator(const Simulator &)=delete
bool episodeWillBeOver() const
Returns true if the current episode will be finished after the current time step.
Definition: simulator.hh:605
const GridView & gridView() const
Return the grid view for which the simulation is done.
Definition: simulator.hh:287
static std::string humanReadableTime(Scalar timeInSeconds, bool isAmendment=true)
Given a time step size in seconds, return it in a format which is more easily parsable by humans.
Definition: simulator.hh:822
void setEpisodeIndex(int episodeIdx)
Sets the index of the current episode.
Definition: simulator.hh:546
Scalar time() const
Return the number of seconds of simulated time which have elapsed since the start time.
Definition: simulator.hh:358
void setEpisodeLength(Scalar dt)
Sets the length in seconds of the current episode.
Definition: simulator.hh:569
const Problem & problem() const
Return the object which specifies the pysical setup of the simulation.
Definition: simulator.hh:313
Model & model()
Return the physical model used in the simulation.
Definition: simulator.hh:293
Scalar episodeMaxTimeStepSize() const
Aligns the time step size to the episode boundary if the current time step crosses the boundary of th...
Definition: simulator.hh:617
Scalar episodeStartTime() const
Returns the absolute time when the current episode started .
Definition: simulator.hh:561
const Timer & setupTimer() const
Returns a reference to the timer object which measures the time needed to set up and initialize the s...
Definition: simulator.hh:380
A simple class which makes sure that a timer gets stopped if an exception is thrown.
Definition: timerguard.hh:41
Provides an encapsulation to measure the system time.
Definition: timer.hh:49
void start()
Start counting the time resources used by the simulation.
Definition: timer.hh:62
double realTimeElapsed() const
Return the real time [s] elapsed during the periods the timer was active since the last reset.
Definition: timer.hh:121
double stop()
Stop counting the time resources.
Definition: timer.hh:73
Declare the properties used by the infrastructure code of the finite volume discretizations.
auto getMPIHelperCommunication()
Definition: simulator.hh:54
Definition: blackoilboundaryratevector.hh:37
std::vector< std::string > gatherStrings(const std::string &local_string)
From each rank, gather its string (if not empty) into a vector.
Definition: mpiutil.hh:153
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:235
This file provides the infrastructure to retrieve run-time parameters.
The Opm property system, traits with inheritance.
#define EWOMS_CATCH_PARALLEL_EXCEPTIONS_FATAL(code)
Definition: simulator.hh:61
Manages the simulation time.
Definition: basicproperties.hh:116