opm-simulators
AdaptiveTimeStepping.hpp
1 /*
2 */
3 #ifndef OPM_ADAPTIVE_TIME_STEPPING_HPP
4 #define OPM_ADAPTIVE_TIME_STEPPING_HPP
5 
8 
9 #include <opm/simulators/flow/rescoup/ReservoirCouplingEnabled.hpp>
10 #include <opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp>
11 #include <opm/simulators/timestepping/SimulatorReport.hpp>
12 #include <opm/simulators/timestepping/SimulatorTimer.hpp>
13 #include <opm/simulators/timestepping/TimeStepControl.hpp>
14 #include <opm/simulators/timestepping/TimeStepControlInterface.hpp>
15 
16 #ifdef RESERVOIR_COUPLING_ENABLED
17 #include <opm/simulators/flow/rescoup/ReservoirCoupling.hpp>
18 #include <opm/simulators/flow/rescoup/ReservoirCouplingMaster.hpp>
19 #include <opm/simulators/flow/rescoup/ReservoirCouplingSlave.hpp>
20 #endif
21 
22 #include <functional>
23 #include <memory>
24 #include <set>
25 #include <string>
26 #include <tuple>
27 #include <vector>
28 
29 namespace Opm::Parameters {
30 
31 struct SolverContinueOnConvergenceFailure { static constexpr bool value = false; };
32 struct SolverMaxRestarts { static constexpr int value = 10; };
33 struct SolverVerbosity { static constexpr int value = 1; };
34 struct TimeStepVerbosity { static constexpr int value = 1; };
35 struct InitialTimeStepInDays { static constexpr double value = 1.0; };
36 struct FullTimeStepInitially { static constexpr bool value = false; };
37 struct TimeStepControl { static constexpr auto value = "pid+newtoniteration"; };
38 struct TimeStepControlTolerance { static constexpr double value = 1e-1; };
39 struct TimeStepControlTargetIterations { static constexpr int value = 30; };
40 struct TimeStepControlTargetNewtonIterations { static constexpr int value = 8; };
41 struct TimeStepControlDecayRate { static constexpr double value = 0.75; };
42 struct TimeStepControlGrowthRate { static constexpr double value = 1.25; };
43 struct TimeStepControlDecayDampingFactor { static constexpr double value = 1.0; };
44 struct TimeStepControlGrowthDampingFactor { static constexpr double value = 3.2; };
45 struct TimeStepControlFileName { static constexpr auto value = "timesteps"; };
46 struct MinTimeStepBeforeShuttingProblematicWellsInDays { static constexpr double value = 0.01; };
47 struct MinTimeStepBasedOnNewtonIterations { static constexpr double value = 0.0; };
48 struct TimeStepControlSafetyFactor { static constexpr double value = 0.8; };
49 struct TimeStepControlRejectCompletedStep { static constexpr bool value = false; };
50 struct TimeStepControlToleranceTestVersion { static constexpr auto value = "standard"; };
51 struct TimeStepControlMaxReductionTimeStep { static constexpr double value = 0.1; };
52 struct TimeStepControlParameters { static constexpr auto value = "0.125;0.25;0.125;0.75;0.25"; };
53 
54 } // namespace Opm::Parameters
55 
56 namespace Opm {
57 
58 struct Tuning;
59 class UnitSystem;
60 struct StepReport;
61 
62 namespace detail {
63  void logTimer(const AdaptiveSimulatorTimer& substep_timer);
64 
65  std::set<std::string>
66  consistentlyFailingWells(const std::vector<StepReport>& sr,
67  bool requireRepeatedFailures);
68  void registerAdaptiveParameters();
69 
70  std::tuple<TimeStepControlType, std::unique_ptr<TimeStepControlInterface>, bool>
71  createController(const UnitSystem& unitSystem);
72 }
73 
91 template<class TypeTag>
93 {
94 public:
117  using TuningUpdateCallback = std::function<bool(double elapsed,
118  double substep_length,
119  int sub_step_number)>;
120 
121 private:
123 
124  template <class Solver>
125  class SolutionTimeErrorSolverWrapper : public RelativeChangeInterface
126  {
127  public:
128  explicit SolutionTimeErrorSolverWrapper(const Solver& solver);
129  double relativeChange() const;
130 
131  private:
132  const Solver& solver_;
133  };
134 
135  // Forward declaration of SubStepIteration
136  template <class Solver> class SubStepIteration;
137 
152  template <class Solver>
153  class SubStepper {
154  public:
155  SubStepper(AdaptiveTimeStepping<TypeTag>& adaptive_time_stepping,
156  const SimulatorTimer& simulator_timer,
157  Solver& solver,
158  const bool is_event,
159  const TuningUpdateCallback& tuning_updater);
160 
161  AdaptiveTimeStepping<TypeTag>& getAdaptiveTimerStepper();
162 
166  SimulatorReport run();
167  friend class SubStepIteration<Solver>;
168 
169  private:
170  bool isReservoirCouplingMaster_() const;
171  bool isReservoirCouplingSlave_() const;
172 
187  void maybeModifySuggestedTimeStepAtBeginningOfReportStep_(const double originalTimeStep);
188 
191  bool maybeUpdateTuning_(double elapsed, double substep_length, int sub_step_number) const;
192 
193  double maxTimeStep_() const;
194 
197  SimulatorReport runStepOriginal_();
198 #ifdef RESERVOIR_COUPLING_ENABLED
199  void checkIfSlaveIsTerminated_();
204 
205  // Reservoir coupling master: pick the sync-step length for the next outer-loop
206  // iteration of `runStepReservoirCouplingMaster_()`, including the chop
207  // against slave-report boundaries. See the helper's own comment for
208  // details.
209  double getRcMasterSyncStepLength_(double prev_step, double current_time, double step_end_time);
210  ReservoirCouplingMaster<Scalar>& reservoirCouplingMaster_();
211  ReservoirCouplingSlave<Scalar>& reservoirCouplingSlave_();
212 
217  SimulatorReport runStepReservoirCouplingMaster_();
218 
222  SimulatorReport runStepReservoirCouplingSlave_();
223 #endif
224  double suggestedNextTimestep_() const;
225 
226  AdaptiveTimeStepping<TypeTag>& adaptive_time_stepping_;
227  const SimulatorTimer& simulator_timer_;
228  Solver& solver_;
229  const bool is_event_;
230  const TuningUpdateCallback& tuning_updater_;
231  };
232 
245  template <class Solver>
246  class SubStepIteration {
247  public:
248  SubStepIteration(SubStepper<Solver>& substepper,
249  AdaptiveSimulatorTimer& substep_timer,
250  const double original_time_step,
251  const bool final_step);
252 
255  SimulatorReport run();
256 
257  private:
258  bool checkContinueOnUnconvergedSolution_(double dt) const;
259  void checkTimeStepMaxRestartLimit_(const int restarts) const;
260  void checkTimeStepMinLimit_(const double new_time_step) const;
261  void chopTimeStep_(const double new_time_step);
262  bool chopTimeStepOrCloseFailingWells_(const double new_time_step);
263  boost::posix_time::ptime currentDateTime_() const;
264  int getNumIterations_(const SimulatorReportSingle& substep_report) const;
265  double growthFactor_() const;
266  bool ignoreConvergenceFailure_() const;
267  bool isReservoirCouplingMaster_() const;
268  bool isReservoirCouplingSlave_() const;
269  void markFirstSubStepAsFinished_() const;
270  void maybeReportSubStep_(SimulatorReportSingle substep_report) const;
271  double maybeRestrictTimeStepGrowth_(const double dt,
272  double dt_estimate,
273  const int restarts) const;
274  void maybeUpdateLastSubstepOfSyncTimestep_(double dt);
275 
293  void maybeUpdateTuningAndTimeStep_();
294  double maxGrowth_() const;
295  double minTimeStepBeforeClosingWells_() const;
296  double minTimeStep_() const;
297  double restartFactor_() const;
298  SimulatorReportSingle runSubStep_();
299  int solverRestartMax_() const;
300  double suggestedNextTimestep_() const;
301  void setSuggestedNextStep_(double step);
302  void setTimeStep_(double dt_estimate);
303  Solver& solver_() const;
304  bool solverVerbose_() const;
305  const SimulatorTimer& simulatorTimer_() const;
306  boost::posix_time::ptime startDateTime_() const;
307 #ifdef RESERVOIR_COUPLING_ENABLED
308  ReservoirCouplingMaster<Scalar>& reservoirCouplingMaster_() const;
309  ReservoirCouplingSlave<Scalar>& reservoirCouplingSlave_() const;
310 #endif
311  double timeStepControlComputeEstimate_(const double dt,
312  const int iterations,
313  const AdaptiveSimulatorTimer& substepTimer) const;
314  bool timeStepVerbose_() const;
315  void updateSuggestedNextStep_();
316  bool useNewtonIteration_() const;
317  double writeOutput_() const;
318 
319  SubStepper<Solver>& substepper_;
320  AdaptiveSimulatorTimer& substep_timer_;
321  const double original_time_step_;
322  const bool final_step_;
323  std::string cause_of_failure_;
324  AdaptiveTimeStepping<TypeTag>& adaptive_time_stepping_;
325  };
326 
327 public:
328  AdaptiveTimeStepping() = default;
329 
330  AdaptiveTimeStepping(const UnitSystem& unitSystem,
331  const SimulatorReport& full_report,
332  const double max_next_tstep = -1.0,
333  const bool terminalOutput = true);
334 
335  AdaptiveTimeStepping(double max_next_tstep,
336  const Tuning& tuning,
337  const UnitSystem& unitSystem,
338  const SimulatorReport& full_report,
339  const bool terminalOutput = true);
340 
341  bool operator==(const AdaptiveTimeStepping<TypeTag>& rhs) const;
342 
343  static void registerParameters();
344 
346  void setSuggestedNextStep(const double x);
347 
351  double suggestedNextStep() const;
352 
353  const TimeStepControlInterface& timeStepControl() const;
354 
373  template <class Solver>
374  SimulatorReport step(const SimulatorTimer& simulator_timer,
375  Solver& solver,
376  const bool is_event,
377  const TuningUpdateCallback& tuning_updater);
378 
388  void updateTUNING(double max_next_tstep, const Tuning& tuning);
389 
397  void updateNEXTSTEP(double max_next_tstep);
398 
399  template<class Serializer>
400  void serializeOp(Serializer& serializer);
401 
402  SimulatorReport& report();
403 
404  static AdaptiveTimeStepping<TypeTag> serializationTestObjectHardcoded();
405  static AdaptiveTimeStepping<TypeTag> serializationTestObjectPID();
406  static AdaptiveTimeStepping<TypeTag> serializationTestObjectPIDIt();
407  static AdaptiveTimeStepping<TypeTag> serializationTestObjectSimple();
408  static AdaptiveTimeStepping<TypeTag> serializationTestObject3rdOrder();
409 
410 private:
411  void maybeModifySuggestedTimeStepAtBeginningOfReportStep_(const double original_time_step,
412  const bool is_event);
413 
414  template<class Controller>
415  static AdaptiveTimeStepping<TypeTag> serializationTestObject_();
416 
417  template<class T, class Serializer>
418  void allocAndSerialize(Serializer& serializer);
419 
420  template<class T>
421  bool castAndComp(const AdaptiveTimeStepping<TypeTag>& Rhs) const;
422 
423 protected:
424  void init_(const UnitSystem& unitSystem);
425 
426  using TimeStepController = std::unique_ptr<TimeStepControlInterface>;
427 
429  TimeStepControlType time_step_control_type_{TimeStepControlType::PIDAndIterationCount};
430  TimeStepController time_step_control_{};
431  double restart_factor_{};
432  double growth_factor_{};
433  double max_growth_{};
434  double max_time_step_{};
435  double min_time_step_{};
438  bool solver_verbose_{false};
439  bool timestep_verbose_{false};
443  bool use_newton_iteration_{false};
444 
447  // We store a copy of the full simulator run report for output purposes,
448  // so it can be updated and passed to the summary writing code every
449  // substep (not just every report step).
450  SimulatorReport report_{};
451 };
452 
453 } // namespace Opm
454 
455 #include <opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp>
456 
457 #endif // OPM_ADAPTIVE_TIME_STEPPING_HPP
Definition: AdaptiveTimeStepping.hpp:32
Definition: AdaptiveTimeStepping.hpp:36
Definition: AdaptiveTimeStepping.hpp:50
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
Simulation timer for adaptive time stepping.
Definition: AdaptiveSimulatorTimer.hpp:41
double growth_factor_
factor to multiply time step when solver recovered from failed convergence
Definition: AdaptiveTimeStepping.hpp:432
Definition: AdaptiveTimeStepping.hpp:52
Definition: AdaptiveTimeStepping.hpp:43
Definition: ConvergenceReport.hpp:460
double suggested_next_timestep_
suggested size of next timestep
Definition: AdaptiveTimeStepping.hpp:440
Definition: AdaptiveTimeStepping.hpp:37
void setSuggestedNextStep(const double x)
Set the suggested length for the next substep [s].
Definition: AdaptiveTimeStepping_impl.hpp:300
Definition: AdaptiveTimeStepping.hpp:42
double max_growth_
factor that limits the maximum growth of a time step
Definition: AdaptiveTimeStepping.hpp:433
Definition: AdaptiveTimeStepping.hpp:34
Definition: AdaptiveTimeStepping.hpp:49
Adaptive time-stepping coordinator for the black-oil simulator.
Definition: AdaptiveTimeStepping.hpp:92
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Definition: AdaptiveTimeStepping.hpp:38
Definition: AdaptiveTimeStepping.hpp:39
Definition: AdaptiveTimeStepping.hpp:44
Definition: blackoilnewtonmethodparams.hpp:31
void updateNEXTSTEP(double max_next_tstep)
Set suggested_next_timestep_ to max_next_tstep iff max_next_tstep > 0.
Definition: AdaptiveTimeStepping_impl.hpp:325
double min_time_step_before_shutting_problematic_wells_
< shut problematic wells when time step size in days are less than this
Definition: AdaptiveTimeStepping.hpp:446
bool ignore_convergence_failure_
continue instead of stop when minimum time step is reached
Definition: AdaptiveTimeStepping.hpp:436
int solver_restart_max_
how many restart of solver are allowed
Definition: AdaptiveTimeStepping.hpp:437
Definition: AdaptiveTimeStepping.hpp:51
Definition: AdaptiveTimeStepping.hpp:33
TimeStepController time_step_control_
time step control object
Definition: AdaptiveTimeStepping.hpp:430
Definition: AdaptiveTimeStepping.hpp:41
double max_time_step_
maximal allowed time step size in days
Definition: AdaptiveTimeStepping.hpp:434
TimeStepControlType time_step_control_type_
type of time step control object
Definition: AdaptiveTimeStepping.hpp:429
Definition: ReservoirCouplingMaster.hpp:38
SimulatorReport step(const SimulatorTimer &simulator_timer, Solver &solver, const bool is_event, const TuningUpdateCallback &tuning_updater)
Run one report step by orchestrating adaptive substepping.
Definition: AdaptiveTimeStepping_impl.hpp:197
The Opm property system, traits with inheritance.
Definition: AdaptiveTimeStepping.hpp:35
Definition: ReservoirCouplingSlave.hpp:40
RelativeChangeInterface.
Definition: TimeStepControlInterface.hpp:33
Definition: AdaptiveTimeStepping.hpp:31
bool full_timestep_initially_
beginning with the size of the time step from data file
Definition: AdaptiveTimeStepping.hpp:441
void updateTUNING(double max_next_tstep, const Tuning &tuning)
Apply TUNING keyword parameters.
Definition: AdaptiveTimeStepping_impl.hpp:337
bool solver_verbose_
solver verbosity
Definition: AdaptiveTimeStepping.hpp:438
bool timestep_verbose_
timestep verbosity
Definition: AdaptiveTimeStepping.hpp:439
double suggestedNextStep() const
Current suggested length for the next substep [s].
Definition: AdaptiveTimeStepping_impl.hpp:308
Definition: SimulatorReport.hpp:121
double timestep_after_event_
suggested size of timestep after an event
Definition: AdaptiveTimeStepping.hpp:442
bool use_newton_iteration_
use newton iteration count for adaptive time step control
Definition: AdaptiveTimeStepping.hpp:443
Definition: AdaptiveTimeStepping.hpp:48
Definition: SimulatorTimer.hpp:38
Defines a type tags and some fundamental properties all models.
Definition: AdaptiveTimeStepping.hpp:45
std::function< bool(double elapsed, double substep_length, int sub_step_number)> TuningUpdateCallback
Callback invoked at the start of each substep to apply TUNING, NEXTSTEP (via ACTIONX), and WCYCLE updates.
Definition: AdaptiveTimeStepping.hpp:119
Definition: AdaptiveTimeStepping.hpp:40
double restart_factor_
factor to multiply time step with when solver fails to converge
Definition: AdaptiveTimeStepping.hpp:431
double min_time_step_
minimal allowed time step size before throwing
Definition: AdaptiveTimeStepping.hpp:435
Definition: AdaptiveTimeStepping.hpp:47