SimpleTimes.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 /// \file
5 /// Defines class StepControllers::SimpleTimes
6 
7 #pragma once
8 
9 #include <cmath>
10 #include <pup.h>
11 #include <utility>
12 
13 #include "Options/Options.hpp"
15 #include "Time/Slab.hpp"
16 #include "Time/StepControllers/StepController.hpp" // IWYU pragma: keep
17 #include "Time/Time.hpp"
19 #include "Utilities/FractionUtilities.hpp"
20 #include "Utilities/TMPL.hpp"
21 
22 namespace StepControllers {
23 
24 /// \ingroup TimeSteppersGroup
25 ///
26 /// A StepController that roughly splits the remaining time, but
27 /// prefers simpler (smaller denominator) fractions of slabs.
28 class SimpleTimes : public StepController {
29  public:
30  /// \cond
31  SimpleTimes() = default;
32  explicit SimpleTimes(CkMigrateMessage* /*unused*/) noexcept {}
34  /// \endcond
35 
36  using options = tmpl::list<>;
37  static constexpr OptionString help = {
38  "Chooses steps by dividing the remainder of the slab approximately\n"
39  "evenly, but preferring evaluation times that are simple (i.e., small\n"
40  "denominator) fractions of the slab."};
41 
42  TimeDelta choose_step(const Time& time,
43  const double desired_step) const noexcept override {
44  const Time goal =
45  desired_step > 0 ? time.slab().end() : time.slab().start();
46  const TimeDelta remaining = goal - time;
47  if (std::abs(desired_step) >= std::abs(remaining.value())) {
48  return remaining;
49  }
50 
51  // First arg: don't take a step so small that it will force an extra step
52  // Second arg: don't choose a value too far from the request
53  const double min_step =
54  max_by_magnitude(std::fmod(remaining.value(), desired_step),
55  0.5 * desired_step);
56 
57  const double full_slab = time.slab().duration().value();
58  const auto current_position = time.fraction().value();
59  using Fraction = Time::rational_t;
60  Fraction step_end = simplest_fraction_in_interval<Fraction>(
61  current_position + min_step / full_slab,
62  current_position + desired_step / full_slab);
63 
64  // clang-tidy: move trivially copyable type
65  return Time(time.slab(), std::move(step_end)) - time; // NOLINT
66  }
67 };
68 } // namespace StepControllers
constexpr const T & max_by_magnitude(const T &a, const T &b)
Return the argument with the largest magnitude.
Definition: ConstantExpressions.hpp:211
A StepController that roughly splits the remaining time, but prefers simpler (smaller denominator) fr...
Definition: SimpleTimes.hpp:28
The time in a simulation. Times can be safely compared for exact equality as long as they do not belo...
Definition: Time.hpp:31
Defines base class StepController.
Defines classes and functions for making classes creatable from input files.
Defines macros to allow serialization of abstract template base classes.
Defines Time and TimeDelta.
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:26
StepControllers take desired step sizes (generally determined by StepChoosers) and convert them into ...
Definition: StepController.hpp:31
#define WRAPPED_PUPable_decl(className)
Wraps the Charm++ macro, see the Charm++ documentation.
Definition: CharmPupable.hpp:36
A rational number.
Definition: Rational.hpp:24
Holds all the StepControllers.
Definition: BinaryFraction.cpp:6
Represents an interval of time within a single slab.
Definition: Time.hpp:108
Defines class Slab.
Define simple functions for constant expressions.
Wraps the template metaprogramming library used (brigand)
double value() const noexcept
Approximate numerical length of the interval.
Definition: Time.hpp:131