SetVariables.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 
12 #include "Domain/CoordinateMaps/Tags.hpp"
13 #include "Domain/Tags.hpp"
14 #include "Domain/TagsTimeDependent.hpp"
15 #include "Evolution/Initialization/InitialData.hpp"
16 #include "Evolution/Initialization/Tags.hpp"
17 #include "Evolution/TypeTraits.hpp"
19 #include "Parallel/GlobalCache.hpp"
20 #include "ParallelAlgorithms/Initialization/MergeIntoDataBox.hpp"
21 #include "PointwiseFunctions/AnalyticData/Tags.hpp"
22 #include "PointwiseFunctions/AnalyticSolutions/Tags.hpp"
23 #include "Utilities/Gsl.hpp"
24 #include "Utilities/Requires.hpp"
25 #include "Utilities/TMPL.hpp"
26 #include "Utilities/TaggedTuple.hpp"
27 
28 /// \cond
29 namespace Parallel {
30 template <typename Metavariables>
31 class GlobalCache;
32 } // namespace Parallel
33 /// \endcond
34 
35 namespace evolution {
36 namespace Initialization {
37 namespace Actions {
38 /// \ingroup InitializationGroup
39 /// \brief Sets variables needed for evolution of hyperbolic systems
40 ///
41 /// Uses:
42 /// - DataBox:
43 /// * `CoordinatesTag`
44 /// - GlobalCache:
45 /// * `OptionTags::AnalyticSolutionBase` or `OptionTags::AnalyticDataBase`
46 ///
47 /// DataBox changes:
48 /// - Adds: nothing
49 /// - Removes: nothing
50 /// - Modifies:
51 /// * System::variables_tag (if system has no primitive variables)
52 /// * System::primitive_variables_tag (if system has primitive variables)
53 template <typename LogicalCoordinatesTag>
54 struct SetVariables {
55  using initialization_option_tags =
56  tmpl::list<::Initialization::Tags::InitialTime>;
57 
58  template <typename DbTagsList, typename... InboxTags, typename Metavariables,
59  typename ArrayIndex, typename ActionList,
60  typename ParallelComponent>
61  static std::tuple<db::DataBox<DbTagsList>&&> apply(
62  db::DataBox<DbTagsList>& box,
63  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
64  const Parallel::GlobalCache<Metavariables>& /*cache*/,
65  const ArrayIndex& /*array_index*/, ActionList /*meta*/,
66  const ParallelComponent* const /*meta*/) noexcept {
67  if constexpr (tmpl::list_contains_v<
68  typename db::DataBox<DbTagsList>::simple_item_tags,
70  impl<Metavariables>(make_not_null(&box));
71  } else {
72  ERROR(
73  "Could not find dependency 'Initialization::Tags::InitialTime' in "
74  "DataBox.");
75  }
76  return {std::move(box)};
77  }
78 
79  private:
80  template <typename Metavariables, typename DbTagsList>
81  static void impl(const gsl::not_null<db::DataBox<DbTagsList>*> box) noexcept {
82  const double initial_time =
83  db::get<::Initialization::Tags::InitialTime>(*box);
84  const auto inertial_coords =
86  Metavariables::volume_dim, Frame::Grid, Frame::Inertial>>(*box)(
87  db::get<::domain::Tags::ElementMap<Metavariables::volume_dim,
88  Frame::Grid>>(*box)(
89  db::get<LogicalCoordinatesTag>(*box)),
90  initial_time, db::get<::domain::Tags::FunctionsOfTime>(*box));
91 
92  using system = typename Metavariables::system;
93 
94  const auto& solution_or_data =
95  db::get<::Tags::AnalyticSolutionOrData>(*box);
96 
97  if constexpr (Metavariables::system::has_primitive_and_conservative_vars) {
98  using primitives_tag = typename system::primitive_variables_tag;
99  // Set initial data from analytic solution
100  db::mutate<primitives_tag>(
101  box, [&initial_time, &inertial_coords, &solution_or_data ](
103  primitive_vars) noexcept {
104  primitive_vars->assign_subset(evolution::initial_data(
105  solution_or_data, inertial_coords, initial_time,
106  typename Metavariables::analytic_variables_tags{}));
107  });
108  } else {
109  using variables_tag = typename system::variables_tag;
110 
111  // Set initial data from analytic solution
112  using Vars = typename variables_tag::type;
113  db::mutate<variables_tag>(
114  box, [&initial_time, &inertial_coords,
115  &solution_or_data](const gsl::not_null<Vars*> vars) noexcept {
116  vars->assign_subset(evolution::initial_data(
117  solution_or_data, inertial_coords, initial_time,
118  typename Vars::tags_list{}));
119  });
120  }
121  }
122 };
123 } // namespace Actions
124 } // namespace Initialization
125 } // namespace evolution
utility
Frame::Inertial
Definition: IndexType.hpp:44
Parallel::GlobalCache
Definition: ElementReceiveInterpPoints.hpp:15
evolution
Functionality for evolving hyperbolic partial differential equations.
Definition: AddMeshVelocityNonconservative.hpp:29
Frame::Grid
Definition: IndexType.hpp:43
GlobalCache.hpp
Tags.hpp
tuple
db::get
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:969
Initialization::Tags::InitialTime
Definition: Tags.hpp:18
ERROR
#define ERROR(m)
prints an error message to the standard error stream and aborts the program.
Definition: Error.hpp:36
evolution::initial_data
decltype(auto) initial_data(const SolutionOrData &solution_or_data, Coordinates &&coordinates, const double time, const tmpl::list< Tags... > tags) noexcept
Extract initial data either from analytic data or from an analytic solution at a specified time.
Definition: InitialData.hpp:17
DataBox.hpp
cstddef
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:271
domain::CoordinateMaps::Tags::CoordinateMap
Definition: Tags.hpp:30
Variables.hpp
evolution::Initialization::Actions::SetVariables
Sets variables needed for evolution of hyperbolic systems.
Definition: SetVariables.hpp:54
Gsl.hpp
Requires.hpp
make_not_null
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,...
Definition: Gsl.hpp:880
Mesh.hpp
TMPL.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecThirdOrderPiecewisePolynomial.hpp:13
domain::Tags::ElementMap
Definition: Tags.hpp:115