Evolution.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <tuple>
8 #include <utility>
9 
14 #include "Domain/Mesh.hpp"
15 #include "Domain/Tags.hpp"
16 #include "Evolution/Initialization/Tags.hpp"
20 #include "ParallelAlgorithms/Initialization/MergeIntoDataBox.hpp"
21 #include "Time/Slab.hpp"
23 #include "Time/Tags.hpp"
24 #include "Time/Time.hpp"
25 #include "Time/TimeStepId.hpp"
26 #include "Utilities/Requires.hpp"
27 #include "Utilities/TMPL.hpp"
28 
29 /// \cond
30 namespace Frame {
31 struct Inertial;
32 } // namespace Frame
33 /// \endcond
34 
35 namespace Evolution_detail {
36 // Global time stepping
37 template <typename Metavariables,
39 TimeDelta get_initial_time_step(
40  const Time& initial_time, const double initial_dt_value,
41  const Parallel::ConstGlobalCache<Metavariables>& /*cache*/) noexcept {
42  return (initial_dt_value > 0.0 ? 1 : -1) * initial_time.slab().duration();
43 }
44 
45 // Local time stepping
46 template <typename Metavariables,
48 TimeDelta get_initial_time_step(
49  const Time& initial_time, const double initial_dt_value,
50  const Parallel::ConstGlobalCache<Metavariables>& cache) noexcept {
51  const auto& step_controller = Parallel::get<Tags::StepController>(cache);
52  return step_controller.choose_step(initial_time, initial_dt_value);
53 }
54 } // namespace Evolution_detail
55 
56 namespace Initialization {
57 namespace Actions {
58 /// \ingroup InitializationGroup
59 /// \brief Initialize items related to time-evolution of the system
60 ///
61 /// Since we have not started the evolution yet, we initialize the state
62 /// _before_ the initial time. So `Tags::TimeStepId` is undefined at this point,
63 /// and `Tags::Next<Tags::TimeStepId>` is the initial time.
64 ///
65 /// DataBox changes:
66 /// - Adds:
67 /// * Tags::TimeStepId
68 /// * `Tags::Next<Tags::TimeStepId>`
69 /// * Tags::TimeStep
70 /// * `db::add_tag_prefix<Tags::dt, variables_tag>`
71 /// * `Tags::HistoryEvolvedVariables<variables_tag, dt_variables_tag>`
72 /// * Tags::Time
73 /// * Tags::ComputeDeriv (for non-conservative systems)
74 /// * Tags::ComputeDiv (for conservative systems)
75 /// - Removes: nothing
76 /// - Modifies: nothing
77 ///
78 /// \note HistoryEvolvedVariables is allocated, but needs to be initialized
79 template <typename Metavariables>
80 struct Evolution {
81  using initialization_tags =
84 
85  static constexpr size_t dim = Metavariables::volume_dim;
86  using variables_tag = typename Metavariables::system::variables_tag;
87  using dt_variables_tag = db::add_tag_prefix<::Tags::dt, variables_tag>;
88 
89  template <typename System, bool IsInFluxConservativeForm =
90  System::is_in_flux_conservative_form>
91  struct ComputeTags {
92  using type = db::AddComputeTags<
95  variables_tag,
98  typename System::gradients_tags>>;
99  };
100 
101  template <typename System>
102  struct ComputeTags<System, true> {
103  using type = db::AddComputeTags<
110  };
111 
112  template <typename DbTagsList, typename... InboxTags, typename ArrayIndex,
113  typename ActionList, typename ParallelComponent,
114  Requires<tmpl::list_contains_v<
117  static auto apply(db::DataBox<DbTagsList>& box,
118  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
120  const ArrayIndex& /*array_index*/, ActionList /*meta*/,
121  const ParallelComponent* const /*meta*/) noexcept {
122  using DtVars = typename dt_variables_tag::type;
123 
124  const double initial_time_value = db::get<Tags::InitialTime>(box);
125  const double initial_dt_value = db::get<Tags::InitialTimeDelta>(box);
126  const double initial_slab_size =
127  db::get<Tags::InitialSlabSize<Metavariables::local_time_stepping>>(box);
128 
129  const bool time_runs_forward = initial_dt_value > 0.0;
130  const Slab initial_slab =
131  time_runs_forward
132  ? Slab::with_duration_from_start(initial_time_value,
133  initial_slab_size)
134  : Slab::with_duration_to_end(initial_time_value, initial_slab_size);
135  const Time initial_time =
136  time_runs_forward ? initial_slab.start() : initial_slab.end();
137  const TimeDelta initial_dt = Evolution_detail::get_initial_time_step(
138  initial_time, initial_dt_value, cache);
139 
140  const size_t num_grid_points =
141  db::get<::Tags::Mesh<dim>>(box).number_of_grid_points();
142 
143  // Will be overwritten before use
144  DtVars dt_vars{num_grid_points};
145  typename ::Tags::HistoryEvolvedVariables<variables_tag,
146  dt_variables_tag>::type history;
147 
148  // The slab number is increased in the self-start phase each
149  // time one order of accuracy is obtained, and the evolution
150  // proper starts with slab 0.
151  const auto& time_stepper = Parallel::get<::Tags::TimeStepperBase>(cache);
152 
153  const TimeStepId time_id(
154  time_runs_forward,
155  -static_cast<int64_t>(time_stepper.number_of_past_steps()),
156  initial_time);
157 
158  using compute_tags =
159  typename ComputeTags<typename Metavariables::system>::type;
160  return std::make_tuple(
162  Evolution,
165  ::Tags::TimeStep, dt_variables_tag,
167  variables_tag, dt_variables_tag>>,
168  compute_tags>(
169  std::move(box),
170  // At this point we have not started evolution yet, so the current
171  // time is undefined and _next_ is the initial time.
173  initial_dt, std::move(dt_vars), std::move(history)));
174  }
175 
176  template <typename DbTagsList, typename... InboxTags, typename ArrayIndex,
177  typename ActionList, typename ParallelComponent,
178  Requires<not tmpl::list_contains_v<
179  typename db::DataBox<DbTagsList>::simple_item_tags,
180  Initialization::Tags::InitialTime>> = nullptr>
182  db::DataBox<DbTagsList>& /*box*/,
183  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
185  const ArrayIndex& /*array_index*/, ActionList /*meta*/,
186  const ParallelComponent* const /*meta*/) noexcept {
187  ERROR(
188  "Could not find dependency 'Initialization::Tags::InitialTime' in "
189  "DataBox.");
190  }
191 };
192 } // namespace Actions
193 } // namespace Initialization
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:616
Tag for step size.
Definition: Tags.hpp:42
#define ERROR(m)
prints an error message to the standard error stream and aborts the program.
Definition: Error.hpp:36
Definition: ConservativeSystem.hpp:34
T signaling_NaN(T... args)
static Slab with_duration_to_end(double end, double duration) noexcept
Construct a slab with a given end time and duration. The actual duration may differ by roundoff from ...
Definition: Slab.hpp:49
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 class TimeStepId.
Defines base class StepController.
static Slab with_duration_from_start(double start, double duration) noexcept
Construct a slab with a given start time and duration. The actual duration may differ by roundoff fro...
Definition: Slab.hpp:43
Define prefixes for DataBox tags.
A chunk of time. Every element must reach slab boundaries exactly, no matter how it actually takes ti...
Definition: Slab.hpp:29
Tag for the current time as a double.
Definition: Tags.hpp:72
Defines the type alias Requires.
auto merge_into_databox(db::DataBox< DbTagsList > &&box, Args &&... args) noexcept
Add tags that are not yet in the DataBox.
Definition: MergeIntoDataBox.hpp:132
Defines Time and TimeDelta.
Tag for TimeStepId for the algorithm state.
Definition: Tags.hpp:32
A unique identifier for the temporal state of an integrated system.
Definition: TimeStepId.hpp:25
Computes the inverse Jacobian of the map held by MapTag at the coordinates held by SourceCoordsTag...
Definition: Tags.hpp:169
Tag for the TimeStepper history.
Definition: Tags.hpp:86
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:273
Defines classes and functions used for manipulating DataBox&#39;s.
tmpl::flatten< tmpl::list< Tags... > > AddSimpleTags
List of Tags to add to the DataBox.
Definition: DataBox.hpp:1222
Represents an interval of time within a single slab.
Definition: Time.hpp:108
Defines functions computing partial derivatives.
Defines class Slab.
Indicates the Frame that a TensorIndexType is in.
Definition: IndexType.hpp:36
Definition: InterpolationTargetWedgeSectionTorus.hpp:24
Defines class Variables.
A Charm++ chare that caches constant data once per Charm++ node.
Definition: ConstGlobalCache.hpp:135
Defines the class template Mesh.
Compute the spatial derivatives of tags in a Variables.
Definition: PartialDerivatives.hpp:152
The coordinates in a given frame.
Definition: Tags.hpp:139
constexpr auto apply(F &&f, const DataBox< BoxTags > &box, Args &&... args) noexcept
Apply the invokable f with argument Tags TagsList from DataBox box
Definition: DataBox.hpp:1623
Wraps the template metaprogramming library used (brigand)
Prefix indicating the value a quantity will take on the next iteration of the algorithm.
Definition: Prefixes.hpp:150
Defines tags related to domain quantities.
typename Requires_detail::requires_impl< B >::template_error_type_failed_to_meet_requirements_on_template_parameters Requires
Express requirements on the template parameters of a function or class, replaces std::enable_if_t ...
Definition: Requires.hpp:67
Definition: IndexType.hpp:44
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...
Defines class template ConstGlobalCache.
Compute the divergence of a Variables.
Definition: Divergence.hpp:81
Definition: Tags.hpp:18
Tag for computing the substep time from (from Tags::TimeStepId)
Definition: Tags.hpp:61
Initialize items related to time-evolution of the system.
Definition: Evolution.hpp:80
Definition: Evolution.hpp:35
Defines tags related to Time quantities.
Defines functions and tags for taking a divergence.
Definition: ComputeTimeDerivative.hpp:28
tmpl::flatten< tmpl::list< Tags... > > AddComputeTags
List of Compute Item Tags to add to the DataBox.
Definition: DataBox.hpp:1243