version 3.10-dev
common/timeloop.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_TIME_LOOP_HH
13#define DUMUX_TIME_LOOP_HH
14
15#include <algorithm>
16#include <queue>
17#include <iomanip>
18#include <chrono>
19#include <type_traits>
20#include <initializer_list>
21#include <optional>
22
23#include <dune/common/float_cmp.hh>
24#include <dune/common/timer.hh>
25
26#include <dune/common/parallel/communication.hh>
27
28#include <dune/common/parallel/mpihelper.hh>
29#include <dune/common/exceptions.hh>
30
33#include <dumux/io/format.hh>
34
35namespace Dumux {
36
37
38#ifndef DOXYGEN
39namespace Detail::TimeLoop {
40
41template<typename Scalar, typename R, typename P>
42Scalar toSeconds(std::chrono::duration<R, P> duration)
43{
44 using Second = std::chrono::duration<Scalar, std::ratio<1>>;
45 return std::chrono::duration_cast<Second>(duration).count();
46}
47
48template<typename Scalar, typename T, std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
49Scalar toSeconds(T duration)
50{ return static_cast<Scalar>(duration); }
51
52// overload for nice static_assert message in case of unuspported type
53template<typename Scalar, typename T, std::enable_if_t<!std::is_floating_point_v<T>, bool> = true>
54Scalar toSeconds(T duration)
55{ static_assert(AlwaysFalse<T>::value, "Given type not supported for representation of time values"); }
56
57} // namespace Detail::TimeLoop
58#endif // DOXYGEN
59
82template<class S>
84{
85public:
86 using Scalar = S;
87
89 virtual ~TimeLoopBase() {};
90
96 virtual Scalar time() const = 0;
97
101 virtual Scalar timeStepSize() const = 0;
102
106 virtual Scalar maxTimeStepSize() const = 0;
107
111 virtual void advanceTimeStep() = 0;
112
117 virtual void setTimeStepSize(Scalar dt) = 0;
118
123 template<class Rep, class Period>
124 void setTimeStepSize(std::chrono::duration<Rep, Period> dt)
125 { setTimeStepSize(Detail::TimeLoop::toSeconds<Scalar>(dt)); }
126
130 virtual bool finished() const = 0;
131};
132
137template <class Scalar>
138class TimeLoop : public TimeLoopBase<Scalar>
139{
140public:
141 TimeLoop(Scalar startTime, Scalar dt, Scalar tEnd, bool verbose = true)
142 : timer_(false)
143 {
144 reset(startTime, dt, tEnd, verbose);
145 }
146
147 template<class Rep1, class Period1,
148 class Rep2, class Period2,
149 class Rep3, class Period3>
150 TimeLoop(std::chrono::duration<Rep1, Period1> startTime,
151 std::chrono::duration<Rep2, Period2> dt,
152 std::chrono::duration<Rep3, Period3> tEnd,
153 bool verbose = true)
154 : TimeLoop(
155 Detail::TimeLoop::toSeconds<Scalar>(startTime),
156 Detail::TimeLoop::toSeconds<Scalar>(dt),
157 Detail::TimeLoop::toSeconds<Scalar>(tEnd),
158 verbose
159 ){}
160
169 void start()
170 {
171 timer_.start();
172 }
173
178 double stop()
179 {
180 return timer_.stop();
181 }
182
187 {
188 timer_.reset();
189 }
190
194 template<class Rep1, class Period1,
195 class Rep2, class Period2,
196 class Rep3, class Period3>
197 void reset(std::chrono::duration<Rep1, Period1> startTime,
198 std::chrono::duration<Rep2, Period2> dt,
199 std::chrono::duration<Rep3, Period3> tEnd,
200 bool verbose = true)
201 {
202 reset(
203 Detail::TimeLoop::toSeconds<Scalar>(startTime),
204 Detail::TimeLoop::toSeconds<Scalar>(dt),
205 Detail::TimeLoop::toSeconds<Scalar>(tEnd)
206 );
207 }
208
212 void reset(Scalar startTime, Scalar dt, Scalar tEnd, bool verbose = true)
213 {
214 verbose_ =
215 verbose &&
216 Dune::MPIHelper::getCommunication().rank() == 0;
217
218 startTime_ = startTime;
219 time_ = startTime;
220 endTime_ = tEnd;
221
223 userSetMaxTimeStepSize_ = std::numeric_limits<Scalar>::max();
224 timeStepIdx_ = 0;
225 finished_ = false;
228
229 // ensure that dt is not greater than tEnd-startTime
230 setTimeStepSize(dt);
231
232 timer_.stop();
233 timer_.reset();
234 }
235
239 void advanceTimeStep() override
240 {
241 timeStepIdx_++;
244
245 // compute how long the last time step took
246 const auto cpuTime = wallClockTime();
248 timeAfterLastTimeStep_ = cpuTime;
249
250 // ensure that using current dt we don't exceed tEnd in next time step
252 }
253
260 template<class ScalarOrDuration>
261 void setTime(ScalarOrDuration t)
262 { time_ = Detail::TimeLoop::toSeconds<Scalar>(t); }
263
270 template<class ScalarOrDuration>
271 void setTime(ScalarOrDuration t, int stepIdx)
272 {
273 time_ = Detail::TimeLoop::toSeconds<Scalar>(t);
274 timeStepIdx_ = stepIdx;
275 }
276
282 Scalar time() const final
283 { return time_; }
284
289 { return endTime_; }
290
297 {
298 endTime_ = t;
299 if (verbose_)
300 std::cout << Fmt::format("Set new end time to t = {:.5g} seconds.\n", t);
301 }
302
306 double wallClockTime() const
307 { return timer_.elapsed(); }
308
320 void setTimeStepSize(Scalar dt) final
321 {
322 using std::min;
323 timeStepSize_ = min(dt, maxTimeStepSize());
324 // Warn if dt is so small w.r.t. current time that it renders float addition meaningless
325 // For instance, consider (may depend on architecture):
326 // double cien = 100;
327 // double mil = 1000;
328 // if (cien + 1e-14 == cien) std::cout << "Will not be printed" << std::endl;
329 // if (mil + 1e-14 == mil) std::cout << "Will be printed" << std::endl;
330 if (!finished() && (time_ + timeStepSize_ == time_))
331 std::cerr << Fmt::format("You have set a very small timestep size (dt = {:.5g}).", timeStepSize_)
332 << " This might lead to numerical problems!\n";
333 }
334
341 template<class ScalarOrDuration>
342 void setMaxTimeStepSize(ScalarOrDuration maxDt)
343 {
344 userSetMaxTimeStepSize_ = Detail::TimeLoop::toSeconds<Scalar>(maxDt);
346 }
347
353 Scalar timeStepSize() const final
354 { return timeStepSize_; }
355
360 int timeStepIndex() const
361 { return timeStepIdx_; }
362
367 { return previousTimeStepSize_; }
368
376 void setFinished(bool finished = true)
377 { finished_ = finished; }
378
385 bool finished() const override
386 {
387 return finished_ || (endTime_ - time_) < baseEps_*(time_ - startTime_);
388 }
389
394 bool willBeFinished() const
395 {
397 }
398
404 Scalar maxTimeStepSize() const override
405 {
406 if (finished())
407 return 0.0;
408
409 using std::min; using std::max;
410 return min(userSetMaxTimeStepSize_, max<Scalar>(0.0, endTime_ - time_));
411 }
412
417 void reportTimeStep() const
418 {
419 if (verbose_)
420 {
421 const auto cpuTime = wallClockTime();
422 using std::round;
423 const auto percent = round( (time_ - startTime_) / (endTime_ - startTime_) * 100 );
424 std::cout << Fmt::format("[{:3.0f}%] ", percent)
425 << Fmt::format("Time step {} done in {:.2g} seconds. ", timeStepIdx_, timeStepWallClockTime_)
426 << Fmt::format("Wall clock time: {:.5g}, time: {:.5g}, time step size: {:.5g}\n", cpuTime, time_, previousTimeStepSize_);
427 }
428 }
429
433 template< class Communicator = Dune::Communication<typename Dune::MPIHelper::MPICommunicator> >
434 void finalize(const Communicator& comm = Dune::MPIHelper::getCommunication())
435 {
436 auto cpuTime = timer_.stop();
437
438 if (verbose_)
439 std::cout << Fmt::format("Simulation took {:.5g} seconds on {} processes.\n", cpuTime, comm.size());
440
441 if (comm.size() > 1)
442 cpuTime = comm.sum(cpuTime);
443
444 if (verbose_)
445 std::cout << Fmt::format("The cumulative CPU time was {:.5g} seconds.\n", cpuTime);
446 }
447
449 bool verbose() const
450 { return verbose_; }
451
453 void setVerbose(bool verbose = true)
454 { verbose_ = verbose; }
455
456 /*
457 * @}
458 */
459
460protected:
461 static constexpr Scalar baseEps_ = 1e-10;
462
463 Dune::Timer timer_;
467
475};
476
477// always fall back to floating-point representation
478template<class Rep1, class Period1,
479 class Rep2, class Period2,
480 class Rep3, class Period3>
481TimeLoop(std::chrono::duration<Rep1, Period1>,
482 std::chrono::duration<Rep2, Period2>,
483 std::chrono::duration<Rep3, Period3>,
484 bool verbose = true) -> TimeLoop<std::conditional_t<
485 std::is_floating_point_v<std::common_type_t<Rep1, Rep2, Rep3>>,
486 std::common_type_t<Rep1, Rep2, Rep3>,
487 double
488>>;
489
494template <class Scalar>
495class CheckPointTimeLoop : public TimeLoop<Scalar>
496{
497 class CheckPointType {
498 static constexpr std::size_t manualIdx = 0;
499 static constexpr std::size_t periodicIdx = 1;
500
501 public:
502 bool isPeriodic() const { return set_[periodicIdx]; }
503 bool isManual() const { return set_[manualIdx]; }
504 bool isAny() const { return set_.any(); }
505
506 CheckPointType& withPeriodic(bool value) { set_[periodicIdx] = value; return *this; }
507 CheckPointType& withManual(bool value) { set_[manualIdx] = value; return *this; }
508
509 private:
510 std::bitset<2> set_;
511 };
512
513public:
514 template<class... Args>
515 CheckPointTimeLoop(Args&&... args)
516 : TimeLoop<Scalar>(std::forward<Args>(args)...)
517 {
518 periodicCheckPoints_ = false;
519 deltaPeriodicCheckPoint_ = 0.0;
520 lastPeriodicCheckPoint_ = this->startTime_;
521 isCheckPoint_ = false;
522 }
523
527 void advanceTimeStep() override
528 {
529 const auto dt = this->timeStepSize();
530 const auto newTime = this->time()+dt;
531
533 const auto cpType = nextCheckPointType_(newTime);
534 if (cpType.isManual()) checkPoints_.pop();
535 if (cpType.isPeriodic()) lastPeriodicCheckPoint_ += deltaPeriodicCheckPoint_;
536 isCheckPoint_ = cpType.isAny();
537
538 const auto previousTimeStepSize = this->previousTimeStepSize();
539
540 // advance the time step like in the parent class
542
543 // if this is a check point we might have reduced the time step to reach this check point
544 // reset the time step size to the time step size before this time step
545 if (!this->willBeFinished())
546 {
547 using std::max;
548 if (isCheckPoint_)
550
551 // if there is a check point soon check if the time step after the next time step would be smaller
552 // than 20% of the next time step, if yes increase the suggested next time step to exactly reach the check point
553 // (in the limits of the maximum time step size)
554 auto nextDt = this->timeStepSize();
555 const auto threshold = 0.2*nextDt;
556 const auto nextTime = this->time() + nextDt;
557
558 const auto nextDtToCheckPoint = maxDtToCheckPoint_(nextTime);
559 if (nextDtToCheckPoint > Scalar{0} && Dune::FloatCmp::le(nextDtToCheckPoint, threshold))
560 nextDt += nextDtToCheckPoint;
561
562 assert(nextDt > 0.0);
563 this->setTimeStepSize(nextDt);
564 }
565 }
566
572 Scalar maxTimeStepSize() const override
573 {
574 using std::min;
575 const auto maxCheckPointDt = timeStepSizeToNextCheckPoint();
576 const auto maxDtParent = TimeLoop<Scalar>::maxTimeStepSize();
577 return min(maxDtParent, maxCheckPointDt);
578 }
579
590 template<class ScalarOrDuration1, class ScalarOrDuration2 = Scalar>
591 void setPeriodicCheckPoint(ScalarOrDuration1 interval, ScalarOrDuration2 offset = 0.0)
592 {
593 setPeriodicCheckPoint_(
594 Detail::TimeLoop::toSeconds<Scalar>(interval),
595 Detail::TimeLoop::toSeconds<Scalar>(offset)
596 );
597 }
598
601 { periodicCheckPoints_ = false; }
602
605 {
606 periodicCheckPoints_ = false;
607 while (!checkPoints_.empty())
608 checkPoints_.pop();
609 }
610
615 bool isCheckPoint() const
616 { return isCheckPoint_; }
617
624 template<class ScalarOrDuration>
625 void setCheckPoint(ScalarOrDuration t)
626 {
627 // set the check point
628 setCheckPoint_(Detail::TimeLoop::toSeconds<Scalar>(t));
629
630 // make sure we respect this check point on the next time step
631 this->setTimeStepSize(this->timeStepSize());
632 }
633
640 template<class ScalarOrDuration>
641 void setCheckPoint(const std::initializer_list<ScalarOrDuration>& checkPoints)
642 { setCheckPoint(checkPoints.begin(), checkPoints.end()); }
643
644 template<class ScalarOrDuration>
645 [[deprecated("Use setCheckpoint(begin, end) instead. Will be removed after release 3.9.")]]
646 void setCheckPoint(const std::vector<ScalarOrDuration>& checkPoints)
647 { setCheckPoint(checkPoints.begin(), checkPoints.end()); }
648
656 template<class ForwardIterator>
657 void setCheckPoint(ForwardIterator first, ForwardIterator last)
658 {
659 // set the check points
660 for (; first != last; ++first)
661 setCheckPoint_(Detail::TimeLoop::toSeconds<Scalar>(*first));
662
663 // make sure we respect this check point on the next time step
664 this->setTimeStepSize(this->timeStepSize());
665 }
666
672 { return maxDtToCheckPoint_(this->time()); }
673
674private:
675 bool fuzzyEqual_(const Scalar t0, const Scalar t1) const
676 { return Dune::FloatCmp::eq(t0, t1, this->baseEps_*this->timeStepSize()); }
677
678 void setPeriodicCheckPoint_(Scalar interval, Scalar offset = 0.0)
679 {
680 using std::signbit;
681 if (signbit(interval))
682 DUNE_THROW(Dune::InvalidStateException, "Interval has to be positive!");
683
684 periodicCheckPoints_ = true;
685 deltaPeriodicCheckPoint_ = interval;
686 lastPeriodicCheckPoint_ = offset;
687 while (lastPeriodicCheckPoint_ + interval - this->time() < 1e-14*interval)
688 lastPeriodicCheckPoint_ += interval;
689
690 if (this->verbose())
691 std::cout << Fmt::format("Enabled periodic check points every {:.5g} seconds ", interval)
692 << Fmt::format("with the next check point at {:.5g} seconds.\n", lastPeriodicCheckPoint_ + interval);
693
694 // check if the current time point is a periodic check point
695 if (nextCheckPointType_(this->time() + deltaPeriodicCheckPoint_).isPeriodic())
696 isCheckPoint_ = true;
697
698 // make sure we respect this check point on the next time step
699 this->setTimeStepSize(this->timeStepSize());
700 }
701
703 void setCheckPoint_(Scalar t)
704 {
705 if (Dune::FloatCmp::le(t - this->time(), 0.0, this->timeStepSize()*this->baseEps_))
706 {
707 if (this->verbose())
708 std::cerr << Fmt::format("Couldn't insert checkpoint at t = {:.5g} ", t)
709 << Fmt::format("because that's not in the future! (current simulation time is {:.5g})\n", this->time());
710 return;
711 }
712
713 if (!checkPoints_.empty())
714 {
715 if (t <= checkPoints_.back())
716 {
717 if (this->verbose())
718 std::cerr << Fmt::format("Couldn't insert checkpoint at t = {:.5g} ", t)
719 << Fmt::format("because it's earlier than or equal to the last check point (t = {:.5g}) in the queue.\n", checkPoints_.back())
720 << "Checkpoints can only be inserted in ascending order." << std::endl;
721 return;
722 }
723 }
724
725 checkPoints_.push(t);
726 if (this->verbose())
727 std::cout << Fmt::format("Set check point at t = {:.5g} seconds.\n", t);
728 }
729
733 CheckPointType nextCheckPointType_(Scalar t)
734 {
735 return CheckPointType{}
736 .withPeriodic(periodicCheckPoints_ && fuzzyEqual_(t - lastPeriodicCheckPoint_, deltaPeriodicCheckPoint_))
737 .withManual(!checkPoints_.empty() && fuzzyEqual_(t - checkPoints_.front(), 0.0));
738 }
739
743 Scalar maxDtToCheckPoint_(Scalar t) const
744 {
745 static constexpr auto unset = std::numeric_limits<Scalar>::max();
746 const auto dtToPeriodic = dtToNextPeriodicCheckPoint_(t);
747 const auto dtToManual = dtToNextManualCheckPoint_(t);
748
749 using std::min;
750 return min(
751 dtToPeriodic.value_or(unset),
752 dtToManual.value_or(unset)
753 );
754 }
755
759 std::optional<Scalar> dtToNextPeriodicCheckPoint_(Scalar t) const
760 {
761 if (periodicCheckPoints_)
762 return lastPeriodicCheckPoint_ + deltaPeriodicCheckPoint_ - t;
763 return {};
764 }
765
769 std::optional<Scalar> dtToNextManualCheckPoint_(Scalar t) const
770 {
771 if (!checkPoints_.empty())
772 return checkPoints_.front() - t;
773 return {};
774 }
775
776 bool periodicCheckPoints_;
777 Scalar deltaPeriodicCheckPoint_;
778 Scalar lastPeriodicCheckPoint_;
779 std::queue<Scalar> checkPoints_;
780 bool isCheckPoint_;
781};
782
783template<class... Args>
785 typename decltype(TimeLoop{std::forward<Args>(args)...})::Scalar
786>;
787
788} // end namespace Dumux
789
790#endif
A time loop with a check point mechanism.
Definition: common/timeloop.hh:496
bool isCheckPoint() const
Whether now is a time checkpoint.
Definition: common/timeloop.hh:615
CheckPointTimeLoop(Args &&... args)
Definition: common/timeloop.hh:515
void advanceTimeStep() override
Advance time step.
Definition: common/timeloop.hh:527
void removeAllCheckPoints()
remove all check points
Definition: common/timeloop.hh:604
void setPeriodicCheckPoint(ScalarOrDuration1 interval, ScalarOrDuration2 offset=0.0)
Set a periodic check point.
Definition: common/timeloop.hh:591
void setCheckPoint(const std::vector< ScalarOrDuration > &checkPoints)
Definition: common/timeloop.hh:646
Scalar timeStepSizeToNextCheckPoint() const
Return the time step size to exactly reach the next check point In case there is no check point in th...
Definition: common/timeloop.hh:671
void setCheckPoint(ScalarOrDuration t)
add a checkpoint to the queue
Definition: common/timeloop.hh:625
Scalar maxTimeStepSize() const override
The current maximum time step size.
Definition: common/timeloop.hh:572
void setCheckPoint(ForwardIterator first, ForwardIterator last)
add checkpoints to the queue from a container from the first iterator to the last iterator
Definition: common/timeloop.hh:657
void setCheckPoint(const std::initializer_list< ScalarOrDuration > &checkPoints)
add checkpoints to the queue from a list of time points
Definition: common/timeloop.hh:641
void disablePeriodicCheckPoints()
disable periodic check points
Definition: common/timeloop.hh:600
Manages the handling of time dependent problems.
Definition: common/timeloop.hh:84
virtual Scalar time() const =0
Return the time before the time integration. To get the time after the time integration you have to ...
virtual void setTimeStepSize(Scalar dt)=0
Set the current time step size to a given value.
virtual Scalar timeStepSize() const =0
Returns the suggested time step length .
S Scalar
Definition: common/timeloop.hh:86
virtual void advanceTimeStep()=0
Advance to the next time step.
void setTimeStepSize(std::chrono::duration< Rep, Period > dt)
Set the current time step size to a given value.
Definition: common/timeloop.hh:124
virtual bool finished() const =0
Returns true if the simulation is finished.
virtual Scalar maxTimeStepSize() const =0
Get the maximum possible time step size .
virtual ~TimeLoopBase()
Abstract base class needs virtual constructor.
Definition: common/timeloop.hh:89
The default time loop for instationary simulations.
Definition: common/timeloop.hh:139
void setMaxTimeStepSize(ScalarOrDuration maxDt)
Set the maximum time step size to a given value.
Definition: common/timeloop.hh:342
Scalar maxTimeStepSize() const override
The current maximum time step size.
Definition: common/timeloop.hh:404
void resetTimer()
Reset the timer.
Definition: common/timeloop.hh:186
TimeLoop(Scalar startTime, Scalar dt, Scalar tEnd, bool verbose=true)
Definition: common/timeloop.hh:141
void setVerbose(bool verbose=true)
Sets time loop verbosity.
Definition: common/timeloop.hh:453
Scalar time_
Definition: common/timeloop.hh:464
int timeStepIndex() const
Returns number of time steps which have been executed since the beginning of the simulation.
Definition: common/timeloop.hh:360
double stop()
Tells the time loop to stop tracking the time.
Definition: common/timeloop.hh:178
Scalar endTime_
Definition: common/timeloop.hh:465
TimeLoop(std::chrono::duration< Rep1, Period1 > startTime, std::chrono::duration< Rep2, Period2 > dt, std::chrono::duration< Rep3, Period3 > tEnd, bool verbose=true)
Definition: common/timeloop.hh:150
Scalar previousTimeStepSize_
Definition: common/timeloop.hh:469
void advanceTimeStep() override
Advance time step.
Definition: common/timeloop.hh:239
int timeStepIdx_
Definition: common/timeloop.hh:472
void start()
Tells the time loop to start tracking the time.
Definition: common/timeloop.hh:169
Scalar userSetMaxTimeStepSize_
Definition: common/timeloop.hh:470
void setFinished(bool finished=true)
Specify whether the simulation is finished.
Definition: common/timeloop.hh:376
bool verbose() const
If the time loop has verbose output.
Definition: common/timeloop.hh:449
void finalize(const Communicator &comm=Dune::MPIHelper::getCommunication())
Print final status and stops tracking the time.
Definition: common/timeloop.hh:434
bool verbose_
Definition: common/timeloop.hh:474
bool willBeFinished() const
Returns true if the simulation is finished after the time level is incremented by the current time st...
Definition: common/timeloop.hh:394
Scalar previousTimeStepSize() const
The previous time step size.
Definition: common/timeloop.hh:366
void reset(Scalar startTime, Scalar dt, Scalar tEnd, bool verbose=true)
Reset the time loop.
Definition: common/timeloop.hh:212
Scalar endTime() const
Returns the number of (simulated) seconds which the simulation runs.
Definition: common/timeloop.hh:288
void setTime(ScalarOrDuration t)
Set the current simulated time, don't change the current time step index.
Definition: common/timeloop.hh:261
void setTimeStepSize(Scalar dt) final
Set the current time step size to a given value.
Definition: common/timeloop.hh:320
bool finished() const override
Returns true if the simulation is finished.
Definition: common/timeloop.hh:385
Scalar timeStepSize_
Definition: common/timeloop.hh:468
void reportTimeStep() const
State info on cpu time.
Definition: common/timeloop.hh:417
void setTime(ScalarOrDuration t, int stepIdx)
Set the current simulated time and the time step index.
Definition: common/timeloop.hh:271
static constexpr Scalar baseEps_
Definition: common/timeloop.hh:461
Scalar timeStepSize() const final
Returns the suggested time step length so that we don't miss the beginning of the next episode or cr...
Definition: common/timeloop.hh:353
bool finished_
Definition: common/timeloop.hh:473
Dune::Timer timer_
Definition: common/timeloop.hh:463
void reset(std::chrono::duration< Rep1, Period1 > startTime, std::chrono::duration< Rep2, Period2 > dt, std::chrono::duration< Rep3, Period3 > tEnd, bool verbose=true)
Reset the time loop.
Definition: common/timeloop.hh:197
void setEndTime(Scalar t)
Set the time of simulated seconds at which the simulation runs.
Definition: common/timeloop.hh:296
Scalar startTime_
Definition: common/timeloop.hh:466
double wallClockTime() const
Returns the current wall clock time (cpu time) spend in this time loop.
Definition: common/timeloop.hh:306
Scalar timeAfterLastTimeStep_
Definition: common/timeloop.hh:471
Scalar time() const final
Return the time before the time integration. To get the time after the time integration you have to ...
Definition: common/timeloop.hh:282
Scalar timeStepWallClockTime_
Definition: common/timeloop.hh:471
Type traits.
Formatting based on the fmt-library which implements std::format of C++20.
std::chrono::duration< Rep > toSeconds(const std::string &s)
Try to construct an instance of std::chrono::seconds from a string including a unit suffix.
Definition: chrono.hh:63
Definition: adapt.hh:17
TimeLoop(std::chrono::duration< Rep1, Period1 >, std::chrono::duration< Rep2, Period2 >, std::chrono::duration< Rep3, Period3 >, bool verbose=true) -> TimeLoop< std::conditional_t< std::is_floating_point_v< std::common_type_t< Rep1, Rep2, Rep3 > >, std::common_type_t< Rep1, Rep2, Rep3 >, double > >
CheckPointTimeLoop(Args &&... args) -> CheckPointTimeLoop< typename decltype(TimeLoop{std::forward< Args >(args)...})::Scalar >
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.