InitializeMortars.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <array>
7 #include <cstddef>
8 #include <tuple>
9 #include <utility>
10 #include <vector>
11 
15 #include "DataStructures/Tensor/EagerMath/Magnitude.hpp"
16 #include "Domain/CreateInitialMesh.hpp"
17 #include "Domain/Direction.hpp"
18 #include "Domain/Element.hpp"
19 #include "Domain/Mesh.hpp"
20 #include "Domain/Neighbors.hpp"
21 #include "Domain/OrientationMap.hpp"
22 #include "Domain/Tags.hpp"
23 #include "NumericalAlgorithms/DiscontinuousGalerkin/FluxCommunicationTypes.hpp"
24 #include "NumericalAlgorithms/DiscontinuousGalerkin/MortarHelpers.hpp"
25 #include "NumericalAlgorithms/DiscontinuousGalerkin/Tags.hpp"
26 #include "ParallelAlgorithms/Initialization/MergeIntoDataBox.hpp"
27 #include "Utilities/Gsl.hpp"
28 #include "Utilities/TMPL.hpp"
29 
30 /// \cond
31 namespace Frame {
32 struct Inertial;
33 } // namespace Frame
34 namespace Parallel {
35 template <typename Metavariables>
36 class ConstGlobalCache;
37 } // namespace Parallel
38 /// \endcond
39 
40 namespace dg {
41 namespace Actions {
42 /*!
43  * \ingroup InitializationGroup
44  * \brief Initialize mortars between elements for exchanging fluxes.
45  *
46  * If the template parameter `AddFluxBoundaryConditionMortars`
47  * is set to `false` then the mortar data for flux boundary conditions are not
48  * initialized and other boundary conditions can be applied. In this case, the
49  * `Tags::Mortars` items have no entries for external boundary directions.
50  *
51  * \note This action assumes that the current state is _before_ any mortar
52  * communications take place and the first communication will happen at the
53  * `Tags::Next<temporal_id>`.
54  *
55  * Uses:
56  * - Metavariables:
57  * - `temporal_id`
58  * - `local_time_stepping`
59  * - System:
60  * - `volume_dim`
61  * - DataBox:
62  * - `Tags::Element<Dim>`
63  * - `Tags::Mesh<Dim>`
64  * - `Tags::Next<temporal_id>`
65  * - `Tags::Interface<Tags::InternalDirections<Dim>, Tags::Mesh<Dim - 1>>`
66  * - `Tags::Interface<
67  * Tags::BoundaryDirectionsInterior<Dim>, Tags::Mesh<Dim - 1>>`
68  *
69  * DataBox changes:
70  * - Adds:
71  * - Tags::VariablesBoundaryData
72  * - Tags::Mortars<Tags::Next<temporal_id_tag>, dim>
73  * - Tags::Mortars<Tags::Mesh<dim - 1>, dim>
74  * - Tags::Mortars<Tags::MortarSize<dim - 1>, dim>
75  * - Removes: nothing
76  * - Modifies: nothing
77  */
78 template <typename Metavariables, bool AddFluxBoundaryConditionMortars = true>
80  private:
81  static constexpr size_t dim = Metavariables::system::volume_dim;
82  using temporal_id_tag = typename Metavariables::temporal_id;
84  using mortar_data_tag = tmpl::conditional_t<
85  Metavariables::local_time_stepping,
88 
89  public:
90  using initialization_tags = tmpl::list<::Tags::InitialExtents<dim>>;
91 
92  template <typename DataBox, typename... InboxTags, typename ArrayIndex,
93  typename ActionList, typename ParallelComponent,
95  DataBox>> = nullptr>
96  static auto apply(DataBox& box,
97  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
99  const ArrayIndex& /*array_index*/, ActionList /*meta*/,
100  const ParallelComponent* const /*meta*/) noexcept {
101  const auto& element = db::get<::Tags::Element<dim>>(box);
102  const auto& next_temporal_id = get<::Tags::Next<temporal_id_tag>>(box);
103  const auto& initial_extents = db::get<::Tags::InitialExtents<dim>>(box);
104 
105  db::item_type<mortar_data_tag> mortar_data{};
107  mortar_next_temporal_ids{};
108  db::item_type<::Tags::Mortars<::Tags::Mesh<dim - 1>, dim>> mortar_meshes{};
110  mortar_sizes{};
111  const auto& interface_meshes =
112  db::get<::Tags::Interface<::Tags::InternalDirections<dim>,
113  ::Tags::Mesh<dim - 1>>>(box);
114  for (const auto& direction_and_neighbors : element.neighbors()) {
115  const auto& direction = direction_and_neighbors.first;
116  const auto& neighbors = direction_and_neighbors.second;
117  for (const auto& neighbor : neighbors) {
118  const auto mortar_id = std::make_pair(direction, neighbor);
119  mortar_data[mortar_id]; // Default initialize data
120  mortar_next_temporal_ids.insert({mortar_id, next_temporal_id});
121  mortar_meshes.emplace(
122  mortar_id,
124  interface_meshes.at(direction),
126  initial_extents, neighbor, neighbors.orientation())
127  .slice_away(direction.dimension())));
128  mortar_sizes.emplace(
129  mortar_id,
130  dg::mortar_size(element.id(), neighbor, direction.dimension(),
131  neighbors.orientation()));
132  }
133  }
134 
135  if (AddFluxBoundaryConditionMortars) {
136  const auto& boundary_meshes =
137  db::get<::Tags::Interface<::Tags::BoundaryDirectionsInterior<dim>,
138  ::Tags::Mesh<dim - 1>>>(box);
139  for (const auto& direction : element.external_boundaries()) {
140  const auto mortar_id =
141  std::make_pair(direction, ElementId<dim>::external_boundary_id());
142  mortar_data[mortar_id]; // Default initialize data
143  mortar_meshes.emplace(mortar_id, boundary_meshes.at(direction));
144  mortar_sizes.emplace(mortar_id,
145  make_array<dim - 1>(Spectral::MortarSize::Full));
146  // Since no communication needs to happen for boundary conditions
147  // the temporal id is not advanced on the boundary, so we don't need to
148  // initialize it.
149  }
150  }
151 
152  return std::make_tuple(
156  mortar_data_tag,
160  std::move(box), std::move(mortar_data),
161  std::move(mortar_next_temporal_ids), std::move(mortar_meshes),
162  std::move(mortar_sizes)));
163  }
164 
165  template <typename DataBox, typename... InboxTags, typename ArrayIndex,
166  typename ActionList, typename ParallelComponent,
168  DataBox>> = nullptr>
170  DataBox& /*box*/, const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
172  const ArrayIndex& /*array_index*/, ActionList /*meta*/,
173  const ParallelComponent* const /*meta*/) noexcept {
174  ERROR(
175  "Dependencies not fulfilled. Did you forget to terminate the phase "
176  "after removing options?");
177  }
178 };
179 } // namespace Actions
180 } // namespace dg
Defines class template Direction.
BasedMortars< Tags::VariablesBoundaryData, Tags::BoundaryHistory< LocalData, PackagedData, db::const_item_type< typename system::variables_tag > >, volume_dim > local_time_stepping_mortar_data_tag
The DataBox tag for the data stored on the mortars for local stepping.
Definition: FluxCommunicationTypes.hpp:93
#define ERROR(m)
prints an error message to the standard error stream and aborts the program.
Definition: Error.hpp:36
Initialize mortars between elements for exchanging fluxes.
Definition: InitializeMortars.hpp:79
Definition: ApplyBoundaryFluxesLocalTimeStepping.hpp:33
An ElementId uniquely labels an Element. It is constructed from the BlockId of the Block to which the...
Definition: ElementId.hpp:36
Mesh< Dim > mortar_mesh(const Mesh< Dim > &face_mesh1, const Mesh< Dim > &face_mesh2) noexcept
Find a mesh for a mortar capable of representing data from either of two faces.
Definition: MortarHelpers.cpp:19
Define prefixes for DataBox tags.
Contains functions that forward to Charm++ parallel functions.
Definition: Abort.hpp:13
auto merge_into_databox(db::DataBox< DbTagsList > &&box, Args &&... args) noexcept
Add tags that are not yet in the DataBox.
Definition: MergeIntoDataBox.hpp:132
Mesh< Dim > create_initial_mesh(const std::vector< std::array< size_t, Dim >> &initial_extents, const ElementId< Dim > &element_id, const OrientationMap< Dim > &orientation) noexcept
Construct the initial Mesh of an Element.
Definition: CreateInitialMesh.cpp:21
Defines class template Neighbors.
Data on mortars, indexed by (Direction, ElementId) pairs.
Definition: Tags.hpp:34
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
Indicates the Frame that a TensorIndexType is in.
Definition: IndexType.hpp:36
Types related to flux communication.
Definition: FluxCommunicationTypes.hpp:36
A Charm++ chare that caches constant data once per Charm++ node.
Definition: ConstGlobalCache.hpp:135
Size of a mortar, relative to the element face. That is, the part of the face that it covers...
Definition: Tags.hpp:48
Defines the class template Mesh.
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
std::array< Spectral::MortarSize, Dim - 1 > mortar_size(const ElementId< Dim > &self, const ElementId< Dim > &neighbor, const size_t dimension, const OrientationMap< Dim > &orientation) noexcept
Determine the size of the mortar (i.e., the part of the face it covers) for communicating with a neig...
Definition: MortarHelpers.cpp:36
BasedMortars< Tags::VariablesBoundaryData, Tags::SimpleBoundaryData< db::const_item_type< typename Metavariables::temporal_id >, LocalData, PackagedData >, volume_dim > simple_mortar_data_tag
The DataBox tag for the data stored on the mortars for global stepping.
Definition: FluxCommunicationTypes.hpp:84
Wraps the template metaprogramming library used (brigand)
The computational grid of the Element in the DataBox.
Definition: Tags.hpp:119
Prefix indicating the value a quantity will take on the next iteration of the algorithm.
Definition: Prefixes.hpp:150
typename DataBox_detail::item_type_impl< TagList, Tag >::type item_type
Get the type that can be written to the Tag. If it is a base tag then a TagList must be passed as a s...
Definition: DataBoxTag.hpp:461
Defines functions and classes from the GSL.
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
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...
Definition: ComputeTimeDerivative.hpp:28
Defines class Element.