28 #ifndef EWOMS_SIMULATOR_HH 29 #define EWOMS_SIMULATOR_HH 32 #define RESERVOIR_COUPLING_ENABLED 34 #ifdef RESERVOIR_COUPLING_ENABLED 35 #include <opm/simulators/flow/rescoup/ReservoirCouplingMaster.hpp> 36 #include <opm/simulators/flow/rescoup/ReservoirCouplingSlave.hpp> 39 #include <dune/common/parallel/mpihelper.hh> 48 #include <opm/models/utils/simulatorutils.hpp> 52 #include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp> 66 static constexpr T constexpr_max(T a, T b) {
67 return (a > b) ? a : b;
82 template <
class TypeTag>
91 using MPIComm =
typename Dune::MPIHelper::MPICommunicator;
92 using Communication = Dune::Communication<MPIComm>;
95 static constexpr Scalar eps =
96 constexpr_max(std::numeric_limits<Scalar>::epsilon(), static_cast<Scalar>(1.0e-9));
107 explicit Simulator(Communication comm,
bool verbose =
true)
113 verbose_ = verbose && comm.rank() == 0;
118 endTime_ = Parameters::Get<Parameters::EndTime<Scalar>>();
119 timeStepSize_ = Parameters::Get<Parameters::InitialTimeStepSize<Scalar>>();
120 assert(timeStepSize_ > 0);
121 const std::string& predetTimeStepFile =
122 Parameters::Get<Parameters::PredeterminedTimeStepsFile>();
123 if (!predetTimeStepFile.empty()) {
124 forcedTimeSteps_ = readTimeStepFile<Scalar>(predetTimeStepFile);
126 truncateTimeStepToFloat_ = Parameters::Get<Parameters::TruncateTimeStepToFloat>();
129 episodeStartTime_ = 0;
130 episodeLength_ = std::numeric_limits<Scalar>::max();
135 std::cout <<
"Allocating the simulation vanguard\n" << std::flush;
139 OPM_BEGIN_PARALLEL_TRY_CATCH();
140 vanguard_ = std::make_unique<Vanguard>(*this);
141 OPM_END_PARALLEL_TRY_CATCH(
"Allocating the simulation vanguard failed: ", comm);
145 std::cout <<
"Distributing the vanguard's data\n" << std::flush;
149 OPM_BEGIN_PARALLEL_TRY_CATCH();
150 vanguard_->loadBalance();
151 OPM_END_PARALLEL_TRY_CATCH(
"Could not distribute the vanguard data: ", comm);
156 std::cout <<
"Adding LGRs, if any, in serial run\n" << std::flush;
160 OPM_BEGIN_PARALLEL_TRY_CATCH();
161 vanguard_->addLgrs();
162 OPM_END_PARALLEL_TRY_CATCH(
"Adding LGRs to the simulation vanguard in serial run failed: ", comm);
166 std::cout <<
"Allocating the model\n" << std::flush;
170 OPM_BEGIN_PARALLEL_TRY_CATCH();
171 model_ = std::make_unique<Model>(*this);
172 OPM_END_PARALLEL_TRY_CATCH(
"Could not allocate model: ", comm);
176 std::cout <<
"Allocating the problem\n" << std::flush;
180 OPM_BEGIN_PARALLEL_TRY_CATCH();
181 problem_ = std::make_unique<Problem>(*this);
182 OPM_END_PARALLEL_TRY_CATCH(
"Could not allocate the problem: ", comm);
186 std::cout <<
"Initializing the model\n" << std::flush;
190 OPM_BEGIN_PARALLEL_TRY_CATCH();
191 model_->finishInit();
192 OPM_END_PARALLEL_TRY_CATCH(
"Could not initialize the model: ", comm);
196 std::cout <<
"Initializing the problem\n" << std::flush;
200 OPM_BEGIN_PARALLEL_TRY_CATCH();
201 problem_->finishInit();
202 OPM_END_PARALLEL_TRY_CATCH(
"Could not initialize the problem: ", comm);
208 std::cout <<
"Simulator successfully set up\n" << std::flush;
217 Parameters::Register<Parameters::EndTime<Scalar>>
218 (
"The simulation time at which the simulation is finished [s]");
219 Parameters::Register<Parameters::InitialTimeStepSize<Scalar>>
220 (
"The size of the initial time step [s]");
221 Parameters::Register<Parameters::RestartTime<Scalar>>
222 (
"The simulation time at which a restart should be attempted [s]");
223 Parameters::Register<Parameters::PredeterminedTimeStepsFile>
224 (
"A file with a list of predetermined time step sizes " 225 "(one time step per line)");
226 Parameters::Register<Parameters::TruncateTimeStepToFloat>
227 (
"Truncate the time step size to float precision. Only used to make " 228 "time steps reproducible for the timestep-replay regression test; " 229 "do not enable for production runs.");
231 Vanguard::registerParameters();
232 Model::registerParameters();
233 Problem::registerParameters();
240 {
return *vanguard_; }
246 {
return *vanguard_; }
252 {
return vanguard_->gridView(); }
271 {
return *problem_; }
278 {
return *problem_; }
292 {
return startTime_; }
312 timeStepIdx_ = stepIdx;
345 {
return setupTimer_; }
352 {
return executionTimer_; }
355 {
return executionTimer_; }
362 {
return prePostProcessTimer_; }
369 {
return linearizeTimer_; }
376 {
return solveTimer_; }
383 {
return updateTimer_; }
390 {
return writeTimer_; }
403 { timeStepSize_ = truncateTimeStepToFloat_ ?
static_cast<Scalar
>(float(value)) : value; }
411 { timeStepIdx_ = value; }
419 {
return timeStepSize_; }
426 {
return timeStepIdx_; }
436 { finished_ = yesno; }
446 assert(timeStepSize_ >= 0.0);
447 return finished_ || (this->
time() * (1.0 + eps) >=
endTime());
456 return finished_ || (this->
time() + timeStepSize_) * (1.0 + eps) >=
endTime();
496 episodeStartTime_ = startTime_ + time_;
497 episodeLength_ = len;
506 { episodeIdx_ = episodeIdx; }
514 {
return episodeIdx_; }
521 {
return episodeStartTime_; }
529 { episodeLength_ = dt; }
536 {
return episodeLength_; }
544 return this->
time() <= (episodeStartTime_ -
startTime()) * (1 + eps);
582 return std::max<Scalar>(0.0,
601 TimerGuard executionTimerGuard(executionTimer_);
602 TimerGuard prePostProcessTimerGuard(prePostProcessTimer_);
606 const Scalar restartTime = Parameters::Get<Parameters::RestartTime<Scalar>>();
607 if (restartTime > -1e30) {
611 OPM_BEGIN_PARALLEL_TRY_CATCH();
616 std::cout <<
"Deserialize from file '" << res.
fileName() <<
"'\n" << std::flush;
620 problem_->deserialize(res);
621 model_->deserialize(res);
623 OPM_END_PARALLEL_TRY_CATCH(
"Deserialization failed: ",
624 Dune::MPIHelper::getCommunication());
626 std::cout <<
"Deserialization done." 630 <<
"\n" << std::flush;
636 std::cout <<
"Applying the initial solution of the \"" << problem_->name()
637 <<
"\" problem\n" << std::flush;
640 const Scalar oldTimeStepSize = timeStepSize_;
641 const int oldTimeStepIdx = timeStepIdx_;
646 OPM_BEGIN_PARALLEL_TRY_CATCH();
647 model_->applyInitialSolution();
648 OPM_END_PARALLEL_TRY_CATCH(
"Apply initial solution failed: ",
649 Dune::MPIHelper::getCommunication());
653 if (problem_->shouldWriteOutput()) {
654 OPM_BEGIN_PARALLEL_TRY_CATCH();
655 problem_->writeOutput(
true);
656 OPM_END_PARALLEL_TRY_CATCH(
"Write output failed: ",
657 Dune::MPIHelper::getCommunication());
660 timeStepSize_ = oldTimeStepSize;
661 timeStepIdx_ = oldTimeStepIdx;
665 executionTimer_.
start();
669 prePostProcessTimer_.
start();
674 OPM_BEGIN_PARALLEL_TRY_CATCH();
675 problem_->beginEpisode();
676 OPM_END_PARALLEL_TRY_CATCH(
"Begin episode failed: ",
677 Dune::MPIHelper::getCommunication());
683 OPM_BEGIN_PARALLEL_TRY_CATCH();
684 problem_->endEpisode();
685 OPM_END_PARALLEL_TRY_CATCH(
"End episode failed: ",
686 Dune::MPIHelper::getCommunication());
687 prePostProcessTimer_.
stop();
692 episodeBegins =
false;
695 std::cout <<
"Begin time step " <<
timeStepIndex() + 1 <<
". " 703 OPM_BEGIN_PARALLEL_TRY_CATCH();
704 problem_->beginTimeStep();
705 OPM_END_PARALLEL_TRY_CATCH(
"Begin timestep failed: ",
706 Dune::MPIHelper::getCommunication());
712 OPM_BEGIN_PARALLEL_TRY_CATCH();
713 problem_->endTimeStep();
714 problem_->endEpisode();
715 OPM_END_PARALLEL_TRY_CATCH(
"Finish failed: ",
716 Dune::MPIHelper::getCommunication());
717 prePostProcessTimer_.
stop();
721 prePostProcessTimer_.
stop();
725 problem_->timeIntegration();
730 const auto& pmodel = problem_->model();
731 prePostProcessTimer_ += pmodel.prePostProcessTimer();
732 linearizeTimer_ += pmodel.linearizeTimer();
733 solveTimer_ += pmodel.solveTimer();
734 updateTimer_ += pmodel.updateTimer();
739 const auto& pmodel = problem_->model();
740 prePostProcessTimer_ += pmodel.prePostProcessTimer();
741 linearizeTimer_ += pmodel.linearizeTimer();
742 solveTimer_ += pmodel.solveTimer();
743 updateTimer_ += pmodel.updateTimer();
746 prePostProcessTimer_.
start();
748 OPM_BEGIN_PARALLEL_TRY_CATCH();
749 problem_->endTimeStep();
750 OPM_END_PARALLEL_TRY_CATCH(
"End timestep failed: ",
751 Dune::MPIHelper::getCommunication());
753 prePostProcessTimer_.
stop();
757 if (problem_->shouldWriteOutput()) {
758 OPM_BEGIN_PARALLEL_TRY_CATCH();
759 problem_->writeOutput(
true);
760 OPM_END_PARALLEL_TRY_CATCH(
"Write output failed: ",
761 Dune::MPIHelper::getCommunication());
768 OPM_BEGIN_PARALLEL_TRY_CATCH();
769 problem_->advanceTimeLevel();
770 OPM_END_PARALLEL_TRY_CATCH(
"Advance time level failed: ",
771 Dune::MPIHelper::getCommunication());
775 std::cout <<
"Time step " <<
timeStepIndex() + 1 <<
" done. " 778 <<
", end time: " << this->
time() + oldDt <<
" seconds" 781 <<
"\n" << std::flush;
788 prePostProcessTimer_.
start();
792 OPM_BEGIN_PARALLEL_TRY_CATCH();
793 problem_->endEpisode();
794 OPM_END_PARALLEL_TRY_CATCH(
"End episode failed: ",
795 Dune::MPIHelper::getCommunication());
796 episodeBegins =
true;
800 if (timeStepIdx_ < static_cast<int>(forcedTimeSteps_.size())) {
802 dt = forcedTimeSteps_[timeStepIdx_];
811 prePostProcessTimer_.
stop();
815 if (problem_->shouldWriteRestartFile()) {
816 OPM_BEGIN_PARALLEL_TRY_CATCH();
818 OPM_END_PARALLEL_TRY_CATCH(
"Serialize failed: ",
819 Dune::MPIHelper::getCommunication());
823 executionTimer_.
stop();
826 OPM_BEGIN_PARALLEL_TRY_CATCH();
827 problem_->finalize();
828 OPM_END_PARALLEL_TRY_CATCH(
"Finalize failed: ",
829 Dune::MPIHelper::getCommunication());
833 #ifdef RESERVOIR_COUPLING_ENABLED 836 return reservoirCouplingMaster_;
838 ReservoirCouplingSlave<Scalar>* reservoirCouplingSlave()
const 840 return reservoirCouplingSlave_;
842 void setReservoirCouplingMaster(ReservoirCouplingMaster<Scalar> *reservoirCouplingMaster)
844 this->reservoirCouplingMaster_ = reservoirCouplingMaster;
846 void setReservoirCouplingSlave(ReservoirCouplingSlave<Scalar> *reservoirCouplingSlave)
848 this->reservoirCouplingSlave_ = reservoirCouplingSlave;
871 if (
gridView().comm().rank() == 0) {
872 std::cout <<
"Serialize to file '" << res.fileName() <<
"'" 874 <<
"\n" << std::flush;
878 problem_->serialize(res);
879 model_->serialize(res);
890 template <
class Restarter>
893 restarter.serializeSectionBegin(
"Simulator");
894 restarter.serializeStream()
895 << episodeIdx_ <<
" " 896 << episodeStartTime_ <<
" " 897 << episodeLength_ <<
" " 900 << timeStepIdx_ <<
" ";
901 restarter.serializeSectionEnd();
911 template <
class Restarter>
914 restarter.deserializeSectionBegin(
"Simulator");
915 restarter.deserializeStream()
922 restarter.deserializeSectionEnd();
925 template<
class Serializer>
926 void serializeOp(Serializer& serializer)
928 serializer(*vanguard_);
930 serializer(*problem_);
931 serializer(episodeIdx_);
932 serializer(episodeStartTime_);
933 serializer(episodeLength_);
934 serializer(startTime_);
936 serializer(timeStepIdx_);
940 std::unique_ptr<Vanguard> vanguard_;
941 std::unique_ptr<Model> model_;
942 std::unique_ptr<Problem> problem_;
945 Scalar episodeStartTime_;
946 Scalar episodeLength_;
949 Timer executionTimer_;
950 Timer prePostProcessTimer_;
951 Timer linearizeTimer_;
956 std::vector<Scalar> forcedTimeSteps_;
961 Scalar timeStepSize_;
966 bool truncateTimeStepToFloat_ =
false;
968 #ifdef RESERVOIR_COUPLING_ENABLED 969 ReservoirCouplingMaster<Scalar> *reservoirCouplingMaster_ =
nullptr;
970 ReservoirCouplingSlave<Scalar> *reservoirCouplingSlave_ =
nullptr;
975 namespace Properties {
976 template<
class TypeTag>
const Vanguard & vanguard() const
Return a reference to the grid manager of simulation.
Definition: simulator.hh:245
const Timer & solveTimer() const
Returns a reference to the timer object which measures the time needed by the solver.
Definition: simulator.hh:375
void startNextEpisode(Scalar len=std::numeric_limits< Scalar >::max())
Start the next episode, but don't change the episode identifier.
Definition: simulator.hh:493
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:233
Scalar endTime() const
Returns the number of (simulated) seconds which the simulation runs.
Definition: simulator.hh:337
const GridView & gridView() const
Return the grid view for which the simulation is done.
Definition: simulator.hh:251
Scalar startTime() const
Return the time of the start of the simulation.
Definition: simulator.hh:291
Model & model()
Return the physical model used in the simulation.
Definition: simulator.hh:257
void serialize()
This method writes the complete state of the simulation to the harddisk.
Definition: simulator.hh:866
Problem & problem()
Return the object which specifies the pysical setup of the simulation.
Definition: simulator.hh:270
void run()
Runs the simulation using a given problem class.
Definition: simulator.hh:597
void start()
Start counting the time resources used by the simulation.
Definition: timer.cpp:46
bool finished() const
Returns true if the simulation is finished.
Definition: simulator.hh:444
This file provides the infrastructure to retrieve run-time parameters.
const Timer & prePostProcessTimer() const
Returns a reference to the timer object which measures the time needed for pre- and postprocessing of...
Definition: simulator.hh:361
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:570
void deserializeEnd()
Stop reading the restart file.
Definition: restart.cpp:80
bool episodeStarts() const
Returns true if the current episode has just been started at the current time.
Definition: simulator.hh:542
Scalar maxTimeStepSize() const
Aligns the time step size to the episode boundary and to the end time of the simulation.
Definition: simulator.hh:463
int episodeIndex() const
Returns the index of the current episode.
Definition: simulator.hh:513
Load or save a state of a problem to/from the harddisk.
Load or save a state of a problem to/from the harddisk.
Definition: restart.hpp:44
static void registerParameters()
Registers all runtime parameters used by the simulation.
Definition: simulator.hh:215
void setTime(Scalar t)
Set the current simulated time, don't change the current time step index.
Definition: simulator.hh:300
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
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:418
const Timer & executionTimer() const
Returns a reference to the timer object which measures the time needed to run the simulation...
Definition: simulator.hh:351
void setStartTime(Scalar t)
Set the time of the start of the simulation.
Definition: simulator.hh:285
Declare the properties used by the infrastructure code of the finite volume discretizations.
void serialize(Restarter &restarter)
Write the time manager's state to a restart file.
Definition: simulator.hh:891
int timeStepIndex() const
Returns number of time steps which have been executed since the beginning of the simulation.
Definition: simulator.hh:425
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:382
const Model & model() const
Return the physical model used in the simulation.
Definition: simulator.hh:263
std::string humanReadableTime(double timeInSeconds, bool isAmendment)
Given a time step size in seconds, return it in a format which is more easily parsable by humans...
Definition: simulatorutils.cpp:45
void setEndTime(Scalar t)
Set the time of simulated seconds at which the simulation runs.
Definition: simulator.hh:330
bool episodeWillBeOver() const
Returns true if the current episode will be finished after the current time step. ...
Definition: simulator.hh:560
const std::string & fileName() const
Returns the name of the file which is (de-)serialized.
Definition: restart.hpp:85
double realTimeElapsed() const
Return the real time [s] elapsed during the periods the timer was active since the last reset...
Definition: timer.cpp:90
void setFinished(bool yesno=true)
Specify whether the simulation is finished.
Definition: simulator.hh:435
void setEpisodeIndex(int episodeIdx)
Sets the index of the current episode.
Definition: simulator.hh:505
void deserializeBegin(Simulator &simulator, Scalar t)
Start reading a restart file at a certain simulated time.
Definition: restart.hpp:147
Scalar episodeStartTime() const
Returns the absolute time when the current episode started .
Definition: simulator.hh:520
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.hpp:45
const Problem & problem() const
Return the object which specifies the pysical setup of the simulation.
Definition: simulator.hh:277
bool willBeFinished() const
Returns true if the simulation is finished after the time level is incremented by the current time st...
Definition: simulator.hh:454
bool episodeIsOver() const
Returns true if the current episode is finished at the current time.
Definition: simulator.hh:551
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:344
Provides an encapsulation to measure the system time.
Definition: ReservoirCouplingMaster.hpp:38
The Opm property system, traits with inheritance.
void setTime(Scalar t, unsigned stepIdx)
Set the current simulated time and the time step index.
Definition: simulator.hh:309
A simple class which makes sure that a timer gets stopped if an exception is thrown.
const Timer & linearizeTimer() const
Returns a reference to the timer object which measures the time needed for linarizing the solutions...
Definition: simulator.hh:368
Manages the simulation time.
Definition: basicproperties.hh:120
void deserialize(Restarter &restarter)
Read the time manager's state from a restart file.
Definition: simulator.hh:912
void setTimeStepIndex(unsigned value)
Set the current time step index to a given value.
Definition: simulator.hh:410
void serializeBegin(Simulator &simulator)
Write the current state of the model to disk.
Definition: restart.hpp:92
void setEpisodeLength(Scalar dt)
Sets the length in seconds of the current episode.
Definition: simulator.hh:528
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:83
double stop()
Stop counting the time resources.
Definition: timer.cpp:52
Scalar episodeLength() const
Returns the length of the current episode in simulated time .
Definition: simulator.hh:535
Defines a type tags and some fundamental properties all models.
void startNextEpisode(Scalar episodeStartTime, Scalar episodeLength)
Change the current episode of the simulation.
Definition: simulator.hh:479
const Timer & writeTimer() const
Returns a reference to the timer object which measures the time needed to write the visualization out...
Definition: simulator.hh:389
Scalar time() const
Return the number of seconds of simulated time which have elapsed since the start time...
Definition: simulator.hh:322
void setTimeStepSize(Scalar value)
Set the current time step size to a given value.
Definition: simulator.hh:402
Vanguard & vanguard()
Return a reference to the grid manager of simulation.
Definition: simulator.hh:239