From 8fe950bc8f6ac32343e63ba8a025b159f5a5bbfa Mon Sep 17 00:00:00 2001 From: Elias Pipping <elias.pipping@fu-berlin.de> Date: Mon, 22 May 2017 21:01:27 +0200 Subject: [PATCH] [Cleanup] Make adaptive timestepping comprehensible --- src/time-stepping/adaptivetimestepper.cc | 98 ++++++++++++------------ src/time-stepping/adaptivetimestepper.hh | 6 +- 2 files changed, 49 insertions(+), 55 deletions(-) diff --git a/src/time-stepping/adaptivetimestepper.cc b/src/time-stepping/adaptivetimestepper.cc index f3c2197c..d6bce3d5 100644 --- a/src/time-stepping/adaptivetimestepper.cc +++ b/src/time-stepping/adaptivetimestepper.cc @@ -32,6 +32,7 @@ AdaptiveTimeStepper<Factory, Updaters, ErrorNorm>::AdaptiveTimeStepper( parset_(parset), globalFriction_(globalFriction), current_(current), + R1_(), externalForces_(externalForces), mustRefine_(mustRefine), errorNorm_(errorNorm) {} @@ -42,73 +43,68 @@ bool AdaptiveTimeStepper<Factory, Updaters, ErrorNorm>::reachedEnd() { } template <class Factory, class Updaters, class ErrorNorm> -bool AdaptiveTimeStepper<Factory, Updaters, ErrorNorm>::coarsen() { - bool didCoarsen = false; - while (relativeTime_ + relativeTau_ < 1.0) { - R2_ = {R1_.updaters.clone(), FixedPointIterationCounter()}; - step(R2_, relativeTime_ + relativeTau_, relativeTau_); - - UpdatersWithCount C{current_.clone(), FixedPointIterationCounter()}; - step(C, relativeTime_, 2.0 * relativeTau_); +IterationRegister AdaptiveTimeStepper<Factory, Updaters, ErrorNorm>::advance() { + /* + | C | We check here if making the step R1 of size tau is a + | R1 | R2 | good idea. To check if we can coarsen, we compare + |F1|F2| | the result of (R1+R2) with C, i.e. two steps of size + tau with one of size 2*tau. To check if we need to + refine, we compare the result of (F1+F2) with R1, i.e. two steps + of size tau/2 with one of size tau. The method makes multiple + coarsening/refining attempts, with coarsening coming first. */ + if (R1_.updaters == Updaters()) + R1_ = step(current_, relativeTime_, relativeTau_); - if (!mustRefine_(C.updaters, R2_.updaters)) { - R2_ = {}; - R1_ = C; - relativeTau_ *= 2.0; - didCoarsen = true; - } else { + bool didCoarsen = false; + iterationRegister_.reset(); + UpdatersWithCount R2; + UpdatersWithCount C; + while (relativeTime_ + relativeTau_ <= 1.0) { + R2 = step(R1_.updaters, relativeTime_ + relativeTau_, relativeTau_); + C = step(current_, relativeTime_, 2 * relativeTau_); + if (mustRefine_(R2.updaters, C.updaters)) break; - } - } - return didCoarsen; -} -template <class Factory, class Updaters, class ErrorNorm> -void AdaptiveTimeStepper<Factory, Updaters, ErrorNorm>::refine() { - while (true) { - UpdatersWithCount F1{current_.clone(), FixedPointIterationCounter()}; - step(F1, relativeTime_, relativeTau_ / 2.0); - UpdatersWithCount F2{F1.updaters.clone(), FixedPointIterationCounter()}; - step(F2, relativeTime_ + relativeTau_ / 2.0, relativeTau_ / 2.0); + didCoarsen = true; + relativeTau_ *= 2; + R1_ = C; + } + UpdatersWithCount F1; + UpdatersWithCount F2; + if (!didCoarsen) { + while (true) { + F1 = step(current_, relativeTime_, relativeTau_ / 2.0); + F2 = step(F1.updaters, relativeTime_ + relativeTau_ / 2.0, + relativeTau_ / 2.0); + if (!mustRefine_(F2.updaters, R1_.updaters)) + break; - if (!mustRefine_(R1_.updaters, F2.updaters)) { - break; - } else { - R1_ = F1; - R2_ = F2; relativeTau_ /= 2.0; + R1_ = F1; + R2 = F2; } } -} -template <class Factory, class Updaters, class ErrorNorm> -IterationRegister AdaptiveTimeStepper<Factory, Updaters, ErrorNorm>::advance() { - if (R2_.updaters == Updaters()) { - R1_ = {current_.clone(), FixedPointIterationCounter()}; - step(R1_, relativeTime_, relativeTau_); // counting again upon restart - } else { - R1_ = R2_; - } - - iterationRegister_.reset(); - if (!coarsen()) - refine(); - - current_ = R1_.updaters; iterationRegister_.registerFinalCount(R1_.count); relativeTime_ += relativeTau_; + current_ = R1_.updaters; + R1_ = R2; return iterationRegister_; } template <class Factory, class Updaters, class ErrorNorm> -void AdaptiveTimeStepper<Factory, Updaters, ErrorNorm>::step( - UpdatersWithCount &updatersAndCount, double rTime, double rTau) { - updatersAndCount.count = +typename AdaptiveTimeStepper<Factory, Updaters, ErrorNorm>::UpdatersWithCount +AdaptiveTimeStepper<Factory, Updaters, ErrorNorm>::step( + Updaters const &oldUpdaters, double rTime, double rTau) { + UpdatersWithCount newUpdatersAndCount = {oldUpdaters.clone(), {}}; + newUpdatersAndCount.count = MyCoupledTimeStepper(finalTime_, factory_, parset_, globalFriction_, - updatersAndCount.updaters, errorNorm_, - externalForces_).step(rTime, rTau); - iterationRegister_.registerCount(updatersAndCount.count); + newUpdatersAndCount.updaters, errorNorm_, + externalForces_) + .step(rTime, rTau); + iterationRegister_.registerCount(newUpdatersAndCount.count); + return newUpdatersAndCount; } #include "adaptivetimestepper_tmpl.cc" diff --git a/src/time-stepping/adaptivetimestepper.hh b/src/time-stepping/adaptivetimestepper.hh index c53b5add..73f75ba6 100644 --- a/src/time-stepping/adaptivetimestepper.hh +++ b/src/time-stepping/adaptivetimestepper.hh @@ -38,15 +38,14 @@ class AdaptiveTimeStepper { std::function<bool(Updaters &, Updaters &)> mustRefine); bool reachedEnd(); - bool coarsen(); - void refine(); IterationRegister advance(); double relativeTime_; double relativeTau_; private: - void step(UpdatersWithCount &updatersWithCount, double rTime, double rTau); + UpdatersWithCount step(Updaters const &oldUpdaters, double rTime, + double rTau); double finalTime_; Factory &factory_; @@ -54,7 +53,6 @@ class AdaptiveTimeStepper { std::shared_ptr<Nonlinearity> globalFriction_; Updaters ¤t_; UpdatersWithCount R1_; - UpdatersWithCount R2_; std::function<void(double, Vector &)> externalForces_; std::function<bool(Updaters &, Updaters &)> mustRefine_; ErrorNorm const &errorNorm_; -- GitLab