20#ifndef OPM_ADAPTIVE_TIME_STEPPING_IMPL_HPP
21#define OPM_ADAPTIVE_TIME_STEPPING_IMPL_HPP
24#ifndef OPM_ADAPTIVE_TIME_STEPPING_HPP
26#include <opm/simulators/timestepping/AdaptiveTimeStepping.hpp>
27#include <opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp>
30#include <dune/common/timer.hh>
31#include <dune/istl/istlexception.hh>
33#include <opm/common/Exceptions.hpp>
34#include <opm/common/ErrorMacros.hpp>
35#include <opm/common/OpmLog/OpmLog.hpp>
37#include <opm/grid/utility/StopWatch.hpp>
39#include <opm/input/eclipse/Schedule/Tuning.hpp>
41#include <opm/input/eclipse/Units/Units.hpp>
42#include <opm/input/eclipse/Units/UnitSystem.hpp>
46#include <opm/simulators/timestepping/EclTimeSteppingParams.hpp>
54#include <boost/date_time/posix_time/posix_time.hpp>
55#include <fmt/format.h>
56#include <fmt/ranges.h>
64template<
class TypeTag>
65AdaptiveTimeStepping<TypeTag>::
66AdaptiveTimeStepping(
const UnitSystem& unit_system,
68 const double max_next_tstep,
69 const bool terminal_output
72 ,
restart_factor_{Parameters::Get<Parameters::SolverRestartFactor<Scalar>>()}
73 ,
growth_factor_{Parameters::Get<Parameters::SolverGrowthFactor<Scalar>>()}
74 ,
max_growth_{Parameters::Get<Parameters::SolverMaxGrowth<Scalar>>()}
76 Parameters::Get<Parameters::SolverMaxTimeStepInDays<Scalar>>() * 24 * 60 * 60}
78 unit_system.to_si(UnitSystem::measure::time,
79 Parameters::Get<Parameters::SolverMinTimeStep<Scalar>>())}
81 Parameters::Get<Parameters::SolverContinueOnConvergenceFailure>()}
83 ,
solver_verbose_{Parameters::Get<Parameters::SolverVerbosity>() > 0 && terminal_output}
84 ,
timestep_verbose_{Parameters::Get<Parameters::TimeStepVerbosity>() > 0 && terminal_output}
86 (max_next_tstep <= 0 ? Parameters::Get<Parameters::InitialTimeStepInDays>()
87 : max_next_tstep) * 24 * 60 * 60}
90 Parameters::Get<Parameters::TimeStepAfterEventInDays<Scalar>>() * 24 * 60 * 60}
93 Parameters::Get<Parameters::MinTimeStepBeforeShuttingProblematicWellsInDays>() * unit::day}
105template<
class TypeTag>
106AdaptiveTimeStepping<TypeTag>::
107AdaptiveTimeStepping(
double max_next_tstep,
108 const Tuning& tuning,
109 const UnitSystem& unit_system,
111 const bool terminal_output
121 ,
solver_verbose_{Parameters::Get<Parameters::SolverVerbosity>() > 0 && terminal_output}
122 ,
timestep_verbose_{Parameters::Get<Parameters::TimeStepVerbosity>() > 0 && terminal_output}
124 max_next_tstep <= 0 ? Parameters::Get<Parameters::InitialTimeStepInDays>() * 24 * 60 * 60
130 Parameters::Get<Parameters::MinTimeStepBeforeShuttingProblematicWellsInDays>() * unit::day}
136template<
class TypeTag>
148 switch (this->time_step_control_type_) {
149 case TimeStepControlType::HardCodedTimeStep:
150 result = castAndComp<HardcodedTimeStepControl>(rhs);
152 case TimeStepControlType::PIDAndIterationCount:
153 result = castAndComp<PIDAndIterationCountTimeStepControl>(rhs);
155 case TimeStepControlType::SimpleIterationCount:
156 result = castAndComp<SimpleIterationCountTimeStepControl>(rhs);
158 case TimeStepControlType::PID:
159 result = castAndComp<PIDTimeStepControl>(rhs);
161 case TimeStepControlType::General3rdOrder:
162 result = castAndComp<General3rdOrderController>(rhs);
178 this->min_time_step_before_shutting_problematic_wells_ ==
182template<
class TypeTag>
187 registerEclTimeSteppingParameters<Scalar>();
188 detail::registerAdaptiveParameters();
199template<
class TypeTag>
200template <
class Solver>
206 const TuningUpdateCallback& tuning_updater)
208 SubStepper<Solver> sub_stepper{
209 *
this, simulator_timer, solver, is_event, tuning_updater,
211 return sub_stepper.run();
214template<
class TypeTag>
215template<
class Serializer>
220 serializer(this->time_step_control_type_);
221 switch (this->time_step_control_type_) {
222 case TimeStepControlType::HardCodedTimeStep:
223 allocAndSerialize<HardcodedTimeStepControl>(serializer);
225 case TimeStepControlType::PIDAndIterationCount:
226 allocAndSerialize<PIDAndIterationCountTimeStepControl>(serializer);
228 case TimeStepControlType::SimpleIterationCount:
229 allocAndSerialize<SimpleIterationCountTimeStepControl>(serializer);
231 case TimeStepControlType::PID:
232 allocAndSerialize<PIDTimeStepControl>(serializer);
234 case TimeStepControlType::General3rdOrder:
235 allocAndSerialize<General3rdOrderController>(serializer);
238 serializer(this->restart_factor_);
239 serializer(this->growth_factor_);
240 serializer(this->max_growth_);
241 serializer(this->max_time_step_);
242 serializer(this->min_time_step_);
243 serializer(this->ignore_convergence_failure_);
244 serializer(this->solver_restart_max_);
245 serializer(this->solver_verbose_);
246 serializer(this->timestep_verbose_);
247 serializer(this->suggested_next_timestep_);
248 serializer(this->full_timestep_initially_);
249 serializer(this->timestep_after_event_);
250 serializer(this->use_newton_iteration_);
251 serializer(this->min_time_step_before_shutting_problematic_wells_);
254template<
class TypeTag>
262template<
class TypeTag>
267 return serializationTestObject_<HardcodedTimeStepControl>();
270template<
class TypeTag>
275 return serializationTestObject_<PIDTimeStepControl>();
278template<
class TypeTag>
283 return serializationTestObject_<PIDAndIterationCountTimeStepControl>();
286template<
class TypeTag>
291 return serializationTestObject_<SimpleIterationCountTimeStepControl>();
294template<
class TypeTag>
299 return serializationTestObject_<General3rdOrderController>();
303template<
class TypeTag>
308 this->suggested_next_timestep_ = x;
311template<
class TypeTag>
316 return this->suggested_next_timestep_;
319template<
class TypeTag>
324 return *this->time_step_control_;
328template<
class TypeTag>
335 if (max_next_tstep > 0) {
336 this->suggested_next_timestep_ = max_next_tstep;
340template<
class TypeTag>
343updateTUNING(
double max_next_tstep,
const Tuning& tuning)
345 this->restart_factor_ = tuning.TSFCNV;
346 this->growth_factor_ = tuning.TFDIFF;
347 this->max_growth_ = tuning.TSFMAX;
348 this->max_time_step_ = tuning.TSMAXZ;
349 updateNEXTSTEP(max_next_tstep);
350 this->timestep_after_event_ = tuning.TMAXWC;
357template<
class TypeTag>
358template<
class T,
class Serializer>
363 if (!serializer.isSerializing()) {
364 this->time_step_control_ = std::make_unique<T>();
366 serializer(*
static_cast<T*
>(this->time_step_control_.get()));
369template<
class TypeTag>
375 const T* lhs =
static_cast<const T*
>(this->time_step_control_.get());
376 const T* rhs =
static_cast<const T*
>(Rhs.time_step_control_.get());
380template<
class TypeTag>
387 if (this->suggested_next_timestep_ < 0) {
388 this->suggested_next_timestep_ = this->restart_factor_ * original_time_step;
391 if (this->full_timestep_initially_) {
392 this->suggested_next_timestep_ = original_time_step;
396 if (is_event && this->timestep_after_event_ > 0) {
397 this->suggested_next_timestep_ = this->timestep_after_event_;
401template<
class TypeTag>
402template<
class Controller>
410 result.growth_factor_ = 2.0;
411 result.max_growth_ = 3.0;
412 result.max_time_step_ = 4.0;
413 result.min_time_step_ = 5.0;
414 result.ignore_convergence_failure_ =
true;
415 result.solver_restart_max_ = 6;
416 result.solver_verbose_ =
true;
417 result.timestep_verbose_ =
true;
418 result.suggested_next_timestep_ = 7.0;
419 result.full_timestep_initially_ =
true;
420 result.use_newton_iteration_ =
true;
421 result.min_time_step_before_shutting_problematic_wells_ = 9.0;
422 result.time_step_control_type_ = Controller::Type;
423 result.time_step_control_ =
424 std::make_unique<Controller>(Controller::serializationTestObject());
433template<
class TypeTag>
435init_(
const UnitSystem& unitSystem)
437 std::tie(time_step_control_type_,
439 use_newton_iteration_) = detail::createController(unitSystem);
441 if (this->growth_factor_ < 1.0) {
442 OPM_THROW(std::runtime_error,
443 "Growth factor cannot be less than 1.");
453template<
class TypeTag>
454template<
class Solver>
460 const TuningUpdateCallback& tuning_updater)
461 : adaptive_time_stepping_{adaptive_time_stepping}
462 , simulator_timer_{simulator_timer}
464 , is_event_{is_event}
465 , tuning_updater_{tuning_updater}
469template<
class TypeTag>
470template<
class Solver>
475 return adaptive_time_stepping_;
478template<
class TypeTag>
479template<
class Solver>
484#ifdef RESERVOIR_COUPLING_ENABLED
485 if (isReservoirCouplingSlave_() && reservoirCouplingSlave_().activated()) {
486 return runStepReservoirCouplingSlave_();
488 else if (isReservoirCouplingMaster_() && reservoirCouplingMaster_().activated()) {
489 return runStepReservoirCouplingMaster_();
492 return runStepOriginal_();
495 return runStepOriginal_();
503#ifdef RESERVOIR_COUPLING_ENABLED
504template<
class TypeTag>
505template<
class Solver>
510 return this->solver_.model().simulator().reservoirCouplingMaster() !=
nullptr;
513template<
class TypeTag>
514template<
class Solver>
519 return this->solver_.model().simulator().reservoirCouplingSlave() !=
nullptr;
523template<
class TypeTag>
524template<
class Solver>
529 this->adaptive_time_stepping_.maybeModifySuggestedTimeStepAtBeginningOfReportStep_(
530 original_time_step, this->is_event_
537template<
class TypeTag>
538template<
class Solver>
543 return this->tuning_updater_(elapsed, dt, sub_step_number);
546template<
class TypeTag>
547template<
class Solver>
555template <
class TypeTag>
556template <
class Solver>
561 const auto elapsed = this->simulator_timer_.simulationTimeElapsed();
562 const auto original_time_step = this->simulator_timer_.currentStepLength();
563 const auto report_step = this->simulator_timer_.reportStepNum();
564 maybeUpdateTuning_(elapsed, original_time_step, report_step);
565 maybeModifySuggestedTimeStepAtBeginningOfReportStep_(original_time_step);
568 this->simulator_timer_.startDateTime(),
571 suggestedNextTimestep_(),
575 SubStepIteration<Solver> substepIteration{*
this, substep_timer, original_time_step,
true};
576 return substepIteration.run();
579#ifdef RESERVOIR_COUPLING_ENABLED
580template <
class TypeTag>
581template <
class Solver>
586 return *(this->solver_.model().simulator().reservoirCouplingMaster());
590#ifdef RESERVOIR_COUPLING_ENABLED
591template <
class TypeTag>
592template <
class Solver>
597 return *(this->solver_.model().simulator().reservoirCouplingSlave());
601#ifdef RESERVOIR_COUPLING_ENABLED
632template <
class TypeTag>
633template <
class Solver>
639 const double original_time_step = this->simulator_timer_.currentStepLength();
640 double current_time{this->simulator_timer_.simulationTimeElapsed()};
641 double step_end_time = current_time + original_time_step;
642 auto current_step_length = original_time_step;
643 auto report_step_idx = this->simulator_timer_.currentStepNum();
644 if (report_step_idx == 0 && iteration == 0) {
645 reservoirCouplingMaster_().initTimeStepping();
649 reservoirCouplingMaster_().maybeReceiveActivationHandshakeFromSlaves(current_time);
651 reservoirCouplingMaster_().sendDontTerminateSignalToSlaves();
652 reservoirCouplingMaster_().receiveNextReportDateFromSlaves();
653 bool start_of_report_step = (iteration == 0);
654 if (start_of_report_step) {
655 reservoirCouplingMaster_().initStartOfReportStep(report_step_idx);
657 current_step_length = reservoirCouplingMaster_().maybeChopSubStep(
658 current_step_length, current_time);
659 auto num_active = reservoirCouplingMaster_().numActivatedSlaves();
660 OpmLog::info(fmt::format(
661 "\nChoosing next sync time between master and {} active slave {}: {:.2f} days",
662 num_active, (num_active == 1 ?
"process" :
"processes"),
663 current_step_length / unit::day
665 reservoirCouplingMaster_().sendNextTimeStepToSlaves(current_step_length);
666 if (start_of_report_step) {
667 maybeUpdateTuning_(current_time, current_step_length, 0);
668 maybeModifySuggestedTimeStepAtBeginningOfReportStep_(current_step_length);
671 this->simulator_timer_.startDateTime(),
674 suggestedNextTimestep_(),
675 this->simulator_timer_.reportStepNum(),
679 current_time + current_step_length, step_end_time
684 reservoirCouplingMaster_().setFirstSubstepOfSyncTimestep(
true);
688 reservoirCouplingMaster_().setNeedsSlaveDataReceive(
true);
689 SubStepIteration<Solver> substepIteration{*
this, substep_timer, current_step_length, final_step};
690 const auto sub_steps_report = substepIteration.run();
691 report += sub_steps_report;
692 current_time += current_step_length;
702#ifdef RESERVOIR_COUPLING_ENABLED
703template <
class TypeTag>
704template <
class Solver>
710 const double original_time_step = this->simulator_timer_.currentStepLength();
711 double current_time{this->simulator_timer_.simulationTimeElapsed()};
712 double step_end_time = current_time + original_time_step;
714 auto report_step_idx = this->simulator_timer_.currentStepNum();
715 if (report_step_idx == 0 && iteration == 0) {
716 reservoirCouplingSlave_().initTimeStepping();
719 bool start_of_report_step = (iteration == 0);
720 if (reservoirCouplingSlave_().maybeReceiveTerminateSignalFromMaster()) {
724 reservoirCouplingSlave_().sendNextReportDateToMasterProcess();
725 const auto timestep = reservoirCouplingSlave_().receiveNextTimeStepFromMaster();
726 if (start_of_report_step) {
727 maybeUpdateTuning_(current_time, original_time_step, 0);
728 maybeModifySuggestedTimeStepAtBeginningOfReportStep_(timestep);
731 this->simulator_timer_.startDateTime(),
734 suggestedNextTimestep_(),
735 this->simulator_timer_.reportStepNum(),
739 current_time + timestep, step_end_time
744 reservoirCouplingSlave_().setFirstSubstepOfSyncTimestep(
true);
745 SubStepIteration<Solver> substepIteration{*
this, substep_timer, timestep, final_step};
746 const auto sub_steps_report = substepIteration.run();
747 report += sub_steps_report;
748 current_time += timestep;
759template <
class TypeTag>
760template <
class Solver>
765 return this->adaptive_time_stepping_.suggestedNextStep();
774template<
class TypeTag>
775template<
class Solver>
779 const double original_time_step,
781 : substepper_{substepper}
782 , substep_timer_{substep_timer}
783 , original_time_step_{original_time_step}
784 , final_step_{final_step}
785 , adaptive_time_stepping_{substepper.getAdaptiveTimerStepper()}
789template <
class TypeTag>
790template <
class Solver>
795 auto& simulator = solver_().model().simulator();
796 auto& problem = simulator.problem();
802 while (!this->substep_timer_.done()) {
806 maybeUpdateTuningAndTimeStep_();
808 const double dt = this->substep_timer_.currentStepLength();
809 if (timeStepVerbose_()) {
810 detail::logTimer(this->substep_timer_);
813 maybeUpdateLastSubstepOfSyncTimestep_(dt);
814 auto substep_report = runSubStep_();
815 markFirstSubStepAsFinished_();
817 if (substep_report.converged || checkContinueOnUnconvergedSolution_(dt)) {
818 Dune::Timer perfTimer;
821 problem.setSubStepReport(substep_report);
822 auto& full_report = adaptive_time_stepping_.report();
823 full_report += substep_report;
824 problem.setSimulationReport(full_report);
825 problem.endTimeStep();
826 substep_report.pre_post_time += perfTimer.stop();
828 report += substep_report;
830 ++this->substep_timer_;
832 const int iterations = getNumIterations_(substep_report);
833 auto dt_estimate = timeStepControlComputeEstimate_(
834 dt, iterations, this->substep_timer_);
836 assert(dt_estimate > 0);
837 dt_estimate = maybeRestrictTimeStepGrowth_(dt, dt_estimate, restarts);
840 maybeReportSubStep_(substep_report);
841 if (this->final_step_ && this->substep_timer_.done()) {
846 report.success.output_write_time += writeOutput_();
850 setTimeStep_(dt_estimate);
852 report.success.converged = this->substep_timer_.done();
853 this->substep_timer_.setLastStepFailed(
false);
856 report += substep_report;
857 this->substep_timer_.setLastStepFailed(
true);
858 checkTimeStepMaxRestartLimit_(restarts);
860 double new_time_step = restartFactor_() * dt;
861 if (substep_report.time_step_rejected) {
864 const double temp_time_step = std::sqrt(safetyFactor * tol / solver_().model().relativeChange()) * dt;
865 if (temp_time_step < dt) {
866 new_time_step = temp_time_step;
869 checkTimeStepMinLimit_(new_time_step);
870 bool wells_shut =
false;
871 if (new_time_step > minTimeStepBeforeClosingWells_()) {
872 chopTimeStep_(new_time_step);
874 wells_shut = chopTimeStepOrCloseFailingWells_(new_time_step);
883 problem.setNextTimeStepSize(this->substep_timer_.currentStepLength());
885 updateSuggestedNextStep_();
895template<
class TypeTag>
896template<
class Solver>
901 const bool continue_on_uncoverged_solution = ignoreConvergenceFailure_() && dt <= minTimeStep_();
902 if (continue_on_uncoverged_solution && solverVerbose_()) {
904 const auto msg = fmt::format(
905 "Solver failed to converge but timestep {} is smaller or equal to {}\n"
906 "which is the minimum threshold given by option --solver-min-time-step\n",
909 OpmLog::problem(msg);
911 return continue_on_uncoverged_solution;
914template<
class TypeTag>
915template<
class Solver>
922 if (restarts >= solverRestartMax_()) {
923 const auto msg = fmt::format(
924 fmt::runtime(
"Solver failed to converge after cutting timestep {} times."), restarts
926 if (solverVerbose_()) {
930 throw TimeSteppingBreakdown{msg};
934template<
class TypeTag>
935template<
class Solver>
940 using Meas = UnitSystem::measure;
943 if (new_time_step < minTimeStep_()) {
944 std::string msg =
"Solver failed to converge after cutting timestep to ";
946 const UnitSystem& unit_system = solver_().model().simulator().vanguard().eclState().getDeckUnitSystem();
948 "{:.3E} {}\nwhich is the minimum threshold given by the TUNING keyword\n",
949 unit_system.from_si(Meas::time, minTimeStep_()),
950 unit_system.name(Meas::time)
955 "{:.3E} DAYS\nwhich is the minimum threshold given by option --solver-min-time-step\n",
956 minTimeStep_() / 86400.0
959 if (solverVerbose_()) {
963 throw TimeSteppingBreakdown{msg};
967template<
class TypeTag>
968template<
class Solver>
973 setTimeStep_(new_time_step);
974 if (solverVerbose_()) {
975 const auto msg = fmt::format(fmt::runtime(
"{}\nTimestep chopped to {} days\n"),
976 this->cause_of_failure_,
977 unit::convert::to(this->substep_timer_.currentStepLength(), unit::day));
978 OpmLog::problem(msg);
982template<
class TypeTag>
983template<
class Solver>
988 bool wells_shut =
false;
995 const bool requireRepeatedFailures =
996 new_time_step > (minTimeStepBeforeClosingWells_() * restartFactor_() * restartFactor_());
997 const std::set<std::string> failing_wells =
998 detail::consistentlyFailingWells(solver_().model().stepReports(), requireRepeatedFailures);
1000 if (failing_wells.empty()) {
1002 chopTimeStep_(new_time_step);
1005 std::vector<std::string> shut_wells;
1006 for (
const auto& well : failing_wells) {
1007 const bool was_shut =
1008 solver_().model().wellModel().forceShutWellByName(well,
1009 this->substep_timer_.simulationTimeElapsed(),
1012 shut_wells.push_back(well);
1016 if (shut_wells.empty()) {
1017 for (
const auto& well : failing_wells) {
1018 const bool was_shut =
1019 solver_().model().wellModel().forceShutWellByName(well,
1020 this->substep_timer_.simulationTimeElapsed(),
1023 shut_wells.push_back(well);
1028 if (shut_wells.empty()) {
1029 chopTimeStep_(new_time_step);
1032 if (solverVerbose_()) {
1033 const std::string msg =
1034 fmt::format(fmt::runtime(
"\nProblematic well(s) were shut: {}"
1035 "(retrying timestep)\n"),
1036 fmt::join(shut_wells,
" "));
1037 OpmLog::problem(msg);
1044template<
class TypeTag>
1045template<
class Solver>
1046boost::posix_time::ptime
1050 return simulatorTimer_().currentDateTime();
1053template<
class TypeTag>
1054template<
class Solver>
1059 if (useNewtonIteration_()) {
1060 return substep_report.total_newton_iterations;
1063 return substep_report.total_linear_iterations;
1067template<
class TypeTag>
1068template<
class Solver>
1076template<
class TypeTag>
1077template<
class Solver>
1085template<
class TypeTag>
1086template<
class Solver>
1091 return this->substepper_.isReservoirCouplingMaster_();
1094template<
class TypeTag>
1095template<
class Solver>
1100 return this->substepper_.isReservoirCouplingSlave_();
1103template<
class TypeTag>
1104template<
class Solver>
1109#ifdef RESERVOIR_COUPLING_ENABLED
1113 if (isReservoirCouplingMaster_()) {
1114 reservoirCouplingMaster_().setFirstSubstepOfSyncTimestep(
false);
1116 else if (isReservoirCouplingSlave_()) {
1117 reservoirCouplingSlave_().setFirstSubstepOfSyncTimestep(
false);
1123template<
class TypeTag>
1124template<
class Solver>
1132template<
class TypeTag>
1133template<
class Solver>
1138 if (timeStepVerbose_()) {
1139 std::ostringstream ss;
1140 substep_report.reportStep(ss);
1141 OpmLog::info(ss.str());
1145template<
class TypeTag>
1146template<
class Solver>
1152 dt_estimate = std::min(dt_estimate,
double(maxGrowth_() * dt));
1153 assert(dt_estimate > 0);
1156 dt_estimate = std::min(growthFactor_() * dt, dt_estimate);
1163template<
class TypeTag>
1164template<
class Solver>
1169#ifdef RESERVOIR_COUPLING_ENABLED
1174 if (isReservoirCouplingSlave_()) {
1176 this->substep_timer_.simulationTimeElapsed() + dt,
1177 this->substep_timer_.totalTime()
1179 reservoirCouplingSlave_().setLastSubstepOfSyncTimestep(is_last);
1187template<
class TypeTag>
1188template<
class Solver>
1199 const auto old_value = suggestedNextTimestep_();
1200 if (this->substepper_.maybeUpdateTuning_(this->substep_timer_.simulationTimeElapsed(),
1201 this->substep_timer_.currentStepLength(),
1202 this->substep_timer_.currentStepNum()))
1209 setTimeStep_(suggestedNextTimestep_());
1210 setSuggestedNextStep_(old_value);
1214template<
class TypeTag>
1215template<
class Solver>
1223template<
class TypeTag>
1224template<
class Solver>
1232#ifdef RESERVOIR_COUPLING_ENABLED
1233template<
class TypeTag>
1234template<
class Solver>
1239 return this->substepper_.reservoirCouplingMaster_();
1242template<
class TypeTag>
1243template<
class Solver>
1248 return this->substepper_.reservoirCouplingSlave_();
1252template<
class TypeTag>
1253template<
class Solver>
1261template<
class TypeTag>
1262template<
class Solver>
1269 auto handleFailure = [
this, &substep_report]
1270 (
const std::string& failure_reason,
const std::exception& e,
bool log_exception =
true)
1272 substep_report = solver_().failureReport();
1273 this->cause_of_failure_ = failure_reason;
1274 if (log_exception && solverVerbose_()) {
1275 OpmLog::debug(std::string(
"Caught Exception: ") + e.what());
1280 substep_report = solver_().step(this->substep_timer_, &this->adaptive_time_stepping_.timeStepControl());
1281 if (solverVerbose_()) {
1283 OpmLog::debug(
"Overall linear iterations used: "
1284 + std::to_string(substep_report.total_linear_iterations));
1287 catch (
const TooManyIterations& e) {
1288 handleFailure(
"Solver convergence failure - Iteration limit reached", e);
1290 catch (
const TimeSteppingBreakdown& e) {
1291 handleFailure(e.what(), e);
1293 catch (
const ConvergenceMonitorFailure& e) {
1294 handleFailure(
"Convergence monitor failure", e,
false);
1296 catch (
const LinearSolverProblem& e) {
1297 handleFailure(
"Linear solver convergence failure", e);
1299 catch (
const NumericalProblem& e) {
1300 handleFailure(
"Solver convergence failure - Numerical problem encountered", e);
1302 catch (
const std::runtime_error& e) {
1303 handleFailure(
"Runtime error encountered", e);
1305 catch (
const Dune::ISTLError& e) {
1306 handleFailure(
"ISTL error - Time step too large", e);
1308 catch (
const Dune::MatrixBlockError& e) {
1309 handleFailure(
"Matrix block error", e);
1312 return substep_report;
1315template<
class TypeTag>
1316template<
class Solver>
1321 this->substep_timer_.provideTimeStepEstimate(dt_estimate);
1324template<
class TypeTag>
1325template<
class Solver>
1330 return this->substepper_.solver_;
1334template<
class TypeTag>
1335template<
class Solver>
1343template<
class TypeTag>
1344template<
class Solver>
1349 this->adaptive_time_stepping_.setSuggestedNextStep(step);
1352template <
class TypeTag>
1353template <
class Solver>
1358 return this->substepper_.simulator_timer_;
1361template <
class TypeTag>
1362template <
class Solver>
1370template<
class TypeTag>
1371template<
class Solver>
1372boost::posix_time::ptime
1376 return simulatorTimer_().startDateTime();
1379template <
class TypeTag>
1380template <
class Solver>
1385 return this->adaptive_time_stepping_.suggestedNextStep();
1388template <
class TypeTag>
1389template <
class Solver>
1396 const SolutionTimeErrorSolverWrapper<Solver> relative_change{solver_()};
1398 dt, iterations, relative_change, substepTimer);
1401template <
class TypeTag>
1402template <
class Solver>
1417template <
class TypeTag>
1418template <
class Solver>
1423 auto suggested_next_step = this->substep_timer_.currentStepLength();
1424 if (! std::isfinite(suggested_next_step)) {
1425 suggested_next_step = this->original_time_step_;
1427 if (timeStepVerbose_()) {
1428 std::ostringstream ss;
1429 this->substep_timer_.report(ss);
1430 ss <<
"Suggested next step size = "
1431 << unit::convert::to(suggested_next_step, unit::day) <<
" (days)" << std::endl;
1432 OpmLog::debug(ss.str());
1434 setSuggestedNextStep_(suggested_next_step);
1437template <
class TypeTag>
1438template <
class Solver>
1446template <
class TypeTag>
1447template <
class Solver>
1452 time::StopWatch perf_timer;
1454 auto& problem = solver_().model().simulator().problem();
1455 problem.writeOutput(
true);
1456 return perf_timer.secsSinceStart();
1463template<
class TypeTag>
1464template<
class Solver>
1471template<
class TypeTag>
1472template<
class Solver>
1473double AdaptiveTimeStepping<TypeTag>::SolutionTimeErrorSolverWrapper<Solver>::relativeChange()
const
1476 return solver_.model().relativeChange();
Simulation timer for adaptive time stepping.
Definition AdaptiveSimulatorTimer.hpp:41
Definition AdaptiveTimeStepping.hpp:76
double max_growth_
factor that limits the maximum growth of a time step
Definition AdaptiveTimeStepping.hpp:258
double max_time_step_
maximal allowed time step size in days
Definition AdaptiveTimeStepping.hpp:259
bool solver_verbose_
solver verbosity
Definition AdaptiveTimeStepping.hpp:263
int solver_restart_max_
how many restart of solver are allowed
Definition AdaptiveTimeStepping.hpp:262
double timestep_after_event_
suggested size of timestep after an event
Definition AdaptiveTimeStepping.hpp:267
bool ignore_convergence_failure_
continue instead of stop when minimum time step is reached
Definition AdaptiveTimeStepping.hpp:261
double suggested_next_timestep_
suggested size of next timestep
Definition AdaptiveTimeStepping.hpp:265
TimeStepControlType time_step_control_type_
type of time step control object
Definition AdaptiveTimeStepping.hpp:254
bool full_timestep_initially_
beginning with the size of the time step from data file
Definition AdaptiveTimeStepping.hpp:266
SimulatorReport step(const SimulatorTimer &simulator_timer, Solver &solver, const bool is_event, const TuningUpdateCallback &tuning_updater)
step method that acts like the solver::step method in a sub cycle of time steps
Definition AdaptiveTimeStepping_impl.hpp:203
double growth_factor_
factor to multiply time step when solver recovered from failed convergence
Definition AdaptiveTimeStepping.hpp:257
double restart_factor_
factor to multiply time step with when solver fails to converge
Definition AdaptiveTimeStepping.hpp:256
double min_time_step_
minimal allowed time step size before throwing
Definition AdaptiveTimeStepping.hpp:260
TimeStepController time_step_control_
time step control object
Definition AdaptiveTimeStepping.hpp:255
double min_time_step_before_shutting_problematic_wells_
< shut problematic wells when time step size in days are less than this
Definition AdaptiveTimeStepping.hpp:271
bool timestep_verbose_
timestep verbosity
Definition AdaptiveTimeStepping.hpp:264
bool use_newton_iteration_
use newton iteration count for adaptive time step control
Definition AdaptiveTimeStepping.hpp:268
Definition ReservoirCouplingMaster.hpp:38
Definition ReservoirCouplingSlave.hpp:40
Definition SimulatorTimer.hpp:39
TimeStepControlInterface.
Definition TimeStepControlInterface.hpp:51
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition blackoilbioeffectsmodules.hh:45
This file provides the infrastructure to retrieve run-time parameters.
auto Get(bool errorIfNotRegistered=true)
Retrieve a runtime parameter.
Definition parametersystem.hpp:187
static bool compare_gt_or_eq(double a, double b)
Determines if a is greater than b within the specified tolerance.
Definition ReservoirCoupling.cpp:179
A struct for returning timing data from a simulator to its caller.
Definition SimulatorReport.hpp:34
Definition SimulatorReport.hpp:122