ChangeStepSize.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <limits>
7 #include <tuple>
8 
13 #include "Time/Tags.hpp"
14 #include "Time/TimeSteppers/TimeStepper.hpp"
15 #include "Utilities/Gsl.hpp"
16 #include "Utilities/TMPL.hpp"
18 
19 /// \cond
20 class TimeDelta;
21 class TimeId;
22 // IWYU pragma: no_forward_declare db::DataBox
23 /// \endcond
24 
25 namespace Actions {
26 /// \ingroup ActionsGroup
27 /// \ingroup TimeGroup
28 /// \brief Adjust the step size for local time stepping
29 ///
30 /// Uses:
31 /// - ConstGlobalCache:
32 /// - OptionTags::StepChoosers<StepChooserRegistrars>
33 /// - OptionTags::StepController
34 /// - OptionTags::TimeStepper
35 /// - DataBox:
36 /// - Tags::HistoryEvolvedVariables<variables_tag, dt_variables_tag>
37 /// - Tags::TimeId
38 /// - Tags::TimeStep
39 ///
40 /// DataBox changes:
41 /// - Adds: nothing
42 /// - Removes: nothing
43 /// - Modifies: Tags::Next<Tags::TimeId>, Tags::TimeStep
44 template <typename StepChooserRegistrars>
47  using const_global_cache_tags =
48  tmpl::list<step_choosers_tag, OptionTags::StepController>;
49 
50  template <typename DbTags, typename... InboxTags, typename Metavariables,
51  typename ArrayIndex, typename ActionList,
52  typename ParallelComponent>
53  static std::tuple<db::DataBox<DbTags>&&> apply(
56  const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
57  const ParallelComponent* const /*meta*/) noexcept {
58  static_assert(Metavariables::local_time_stepping,
59  "ChangeStepSize can only be used with local time-stepping.");
60 
61  using variables_tag = typename Metavariables::system::variables_tag;
62  using dt_variables_tag = db::add_tag_prefix<Tags::dt, variables_tag>;
63 
64  const LtsTimeStepper& time_stepper =
65  Parallel::get<OptionTags::TimeStepper>(cache);
66  const auto& step_choosers = Parallel::get<step_choosers_tag>(cache);
67  const auto& step_controller =
68  Parallel::get<OptionTags::StepController>(cache);
69 
70  const auto& time_id = db::get<Tags::TimeId>(box);
71 
72  if (not time_stepper.can_change_step_size(
73  time_id,
74  db::get<
76  box))) {
77  return std::forward_as_tuple(std::move(box));
78  }
79 
80  const auto& current_step = db::get<Tags::TimeStep>(box);
81 
82  // The step choosers return the magnitude of the desired step, so
83  // we always want the minimum requirement, but we have to negate
84  // the final answer if time is running backwards.
85  double desired_step = std::numeric_limits<double>::infinity();
86  for (const auto& step_chooser : step_choosers) {
87  desired_step =
88  std::min(desired_step, step_chooser->desired_step(box, cache));
89  }
90  if (not current_step.is_positive()) {
91  desired_step = -desired_step;
92  }
93 
94  const auto new_step =
95  step_controller.choose_step(time_id.time(), desired_step);
96  if (new_step != current_step) {
97  const auto new_next_time_id =
98  time_stepper.next_time_id(time_id, new_step);
99 
100  db::mutate<Tags::Next<Tags::TimeId>, Tags::TimeStep>(
101  make_not_null(&box),
102  [&new_next_time_id, &new_step](
103  const gsl::not_null<TimeId*> next_time_id,
104  const gsl::not_null<TimeDelta*> time_step) noexcept {
105  *next_time_id = new_next_time_id;
106  *time_step = new_step;
107  });
108  }
109 
110  return std::forward_as_tuple(std::move(box));
111  }
112 };
113 } // namespace Actions
Prefix< DataBox_detail::dispatch_add_tag_prefix_impl< Prefix, Tag, Args... >, Args... > add_tag_prefix
Wrap Tag in Prefix<_, Args...>, also wrapping variables tags if Tag is a Tags::Variables.
Definition: DataBoxTag.hpp:533
Tag for step size.
Definition: Tags.hpp:45
Defines class tuples::TaggedTuple.
Adjust the step size for local time stepping.
Definition: ChangeStepSize.hpp:45
Definition: Tags.hpp:122
A unique identifier for the temporal state of an integrated system.
Definition: TimeId.hpp:25
Define prefixes for DataBox tags.
Base class for TimeSteppers with local time-stepping support, derived from TimeStepper.
Definition: TimeStepper.hpp:105
Prefix for TimeStepper history.
Definition: Tags.hpp:75
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:272
Defines classes and functions used for manipulating DataBox&#39;s.
Represents an interval of time within a single slab.
Definition: Time.hpp:108
T infinity(T... args)
Definition: InterpolationTargetWedgeSectionTorus.hpp:24
A Charm++ chare that caches constant data once per Charm++ node.
Definition: ConstGlobalCache.hpp:76
bool can_change_step_size(const TimeId &time_id, const TimeSteppers::History< Vars, DerivVars > &history) const noexcept
Whether a local change in the step size is allowed before taking a step. This should be called after ...
Definition: TimeStepper.hpp:159
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:1211
Wraps the template metaprogramming library used (brigand)
Defines functions and classes from the GSL.
gsl::not_null< T * > make_not_null(T *ptr) noexcept
Construct a not_null from a pointer. Often this will be done as an implicit conversion, but it may be necessary to perform the conversion explicitly when type deduction is desired.
Definition: Gsl.hpp:863
Definition: SolvePoissonProblem.hpp:38
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...
Defines class template ConstGlobalCache.
Defines tags related to Time quantities.
Definition: ComputeTimeDerivative.hpp:28
Require a pointer to not be a nullptr
Definition: ConservativeFromPrimitive.hpp:12