AddMeshVelocityNonconservative.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <boost/optional.hpp>
7 #include <tuple>
8 
11 #include "Domain/TagsTimeDependent.hpp"
13 #include "Utilities/Gsl.hpp"
14 #include "Utilities/Requires.hpp"
15 #include "Utilities/TMPL.hpp"
16 #include "Utilities/TaggedTuple.hpp"
17 
18 /// \cond
19 namespace Frame {
20 struct Inertial;
21 } // namespace Frame
22 namespace Parallel {
23 template <typename Metavariables>
24 class ConstGlobalCache;
25 } // namespace Parallel
26 // IWYU pragma: no_forward_declare db::DataBox
27 /// \endcond
28 
29 namespace evolution {
30 namespace Actions {
31 /*!
32  * \ingroup ActionsGroup
33  * \brief Compute and add the advective term for nonconservative systems on
34  * moving meshes
35  *
36  * Adds the following term to the time derivative:
37  *
38  * \f{align}{
39  * v^i_g \partial_i u_\alpha,
40  * \f}
41  *
42  * where \f$u_\alpha\f$ are the evolved variables and \f$v^i_g\f$ is the
43  * velocity of the mesh.
44  *
45  * \note The term is always added in the `Frame::Inertial` frame, and the plus
46  * sign arises because we add it to the time derivative.
47  *
48  * Uses:
49  * - DataBox:
50  * - `Tags::deriv<system::variables_tags, Dim, Frame::Inertial>`
51  * - `domain::Tags::MeshVelocity<Dim>`
52  *
53  * DataBox changes:
54  * - Adds: nothing
55  * - Removes: nothing
56  * - Modifies: `Tags::dt<system::variable_tags>`
57  */
59  template <typename DbTagsList, typename... InboxTags, typename Metavariables,
60  typename ArrayIndex, typename ActionList,
61  typename ParallelComponent>
62  static std::tuple<db::DataBox<DbTagsList>&&> apply(
64  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
66  const ArrayIndex& /*array_index*/, ActionList /*meta*/,
67  const ParallelComponent* const /*meta*/) noexcept { // NOLINT const
68  using variables_tags =
69  typename Metavariables::system::variables_tag::tags_list;
70  const auto& mesh_velocity =
71  db::get<::domain::Tags::MeshVelocity<Metavariables::volume_dim>>(box);
72 
73  if (static_cast<bool>(mesh_velocity)) {
74  tmpl::for_each<variables_tags>([&box, &mesh_velocity](
75  auto variables_tag_v) noexcept {
76  using variable_tag = typename decltype(variables_tag_v)::type;
77  using dt_variable_tag = db::add_tag_prefix<::Tags::dt, variable_tag>;
78  using deriv_tag =
79  db::add_tag_prefix<::Tags::deriv, variable_tag,
80  tmpl::size_t<Metavariables::volume_dim>,
82 
83  db::mutate<dt_variable_tag>(
84  make_not_null(&box),
85  [](const auto dt_var_ptr, const auto& deriv_tensor,
86  const boost::optional<tnsr::I<
87  DataVector, Metavariables::volume_dim, Frame::Inertial>>&
88  grid_velocity) noexcept {
89  for (size_t storage_index = 0;
90  storage_index < deriv_tensor.size(); ++storage_index) {
91  // We grab the `deriv_tensor_index`, which would be e.g.
92  // `(i, a, b)`, so `(0, 2, 3)`
93  const auto deriv_tensor_index =
94  deriv_tensor.get_tensor_index(storage_index);
95  // Then we drop the derivative index (the first entry) to get
96  // `(a, b)` (or `(2, 3)`)
97  const auto tensor_index =
98  all_but_specified_element_of(deriv_tensor_index, 0);
99  // Set `deriv_index` to `i` (or `0` in the example)
100  const size_t deriv_index = gsl::at(deriv_tensor_index, 0);
101  dt_var_ptr->get(tensor_index) +=
102  grid_velocity->get(deriv_index) *
103  deriv_tensor[storage_index];
104  }
105  },
106  db::get<deriv_tag>(box), mesh_velocity);
107  });
108  }
109  return std::forward_as_tuple(std::move(box));
110  }
111 };
112 } // namespace Actions
113 } // namespace evolution
Parallel::ConstGlobalCache
Definition: ElementReceiveInterpPoints.hpp:16
gsl::at
constexpr T & at(std::array< T, N > &arr, Size index)
Retrieve a entry from a container, with checks in Debug mode that the index being retrieved is valid.
Definition: Gsl.hpp:124
all_but_specified_element_of
std::array< T, Dim - 1 > all_but_specified_element_of(const std::array< T, Dim > &a, const size_t element_to_remove) noexcept
Construct an array from an existing array omitting one element.
Definition: StdArrayHelpers.hpp:98
Frame::Inertial
Definition: IndexType.hpp:44
evolution
Functionality for evolving hyperbolic partial differential equations.
Definition: AddMeshVelocityNonconservative.hpp:29
tuple
db::add_tag_prefix
Prefix< DataBox_detail::dispatch_add_tag_prefix_impl< Prefix, Tag, Args... >, Args... > add_tag_prefix
Definition: PrefixHelpers.hpp:145
DataBox.hpp
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:272
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:42
evolution::Actions::AddMeshVelocityNonconservative
Compute and add the advective term for nonconservative systems on moving meshes.
Definition: AddMeshVelocityNonconservative.hpp:58
Gsl.hpp
Frame
Definition: IndexType.hpp:36
Requires.hpp
Tags::deriv
Prefix indicating spatial derivatives.
Definition: PartialDerivatives.hpp:54
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:879
PartialDerivatives.hpp
Prefixes.hpp
db::DataBox
Definition: InterpolationTargetWedgeSectionTorus.hpp:24
Parallel
Contains functions that forward to Charm++ parallel functions.
Definition: ElementReceiveInterpPoints.hpp:14
TMPL.hpp