DiscontinuousGalerkin.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 <utility>
9 #include <vector>
10 
14 #include "DataStructures/Tensor/EagerMath/Magnitude.hpp"
15 #include "Domain/Direction.hpp"
16 #include "Domain/Element.hpp"
17 #include "Domain/Mesh.hpp"
18 #include "Domain/Neighbors.hpp"
19 #include "Domain/OrientationMap.hpp"
20 #include "Domain/Tags.hpp"
21 #include "Evolution/Initialization/Helpers.hpp"
22 #include "NumericalAlgorithms/DiscontinuousGalerkin/FluxCommunicationTypes.hpp"
23 #include "NumericalAlgorithms/DiscontinuousGalerkin/MortarHelpers.hpp"
24 #include "NumericalAlgorithms/DiscontinuousGalerkin/Tags.hpp"
25 #include "Utilities/Gsl.hpp"
26 #include "Utilities/TMPL.hpp"
27 
28 /// \cond
29 namespace Frame {
30 struct Inertial;
31 } // namespace Frame
32 /// \endcond
33 
34 namespace Elliptic {
35 namespace Initialization {
36 
37 /*!
38  * \brief Initializes DataBox tags related to discontinuous Galerkin fluxes
39  *
40  * With:
41  * - `flux_comm_types` = `dg::FluxCommunicationTypes<Metavariables>`
42  * - `mortar_data_tag` = `flux_comm_types::simple_mortar_data_tag`
43  * - `interface<Tag>` =
44  * `Tags::Interface<Tags::InternalDirections<volume_dim>, Tag>`
45  * - `boundary<Tag>` =
46  * `Tags::Interface<Tags::BoundaryDirectionsInterior<volume_dim>, Tag>`
47  * - `mortar<Tag>` = `Tags::Mortars<Tag, volume_dim>`
48  *
49  * Uses:
50  * - Metavariables:
51  * - `temporal_id`
52  * - Items required by `flux_comm_types`
53  * - System:
54  * - `volume_dim`
55  * - DataBox:
56  * - `Tags::Element<volume_dim>`
57  * - `Tags::Mesh<volume_dim>`
58  * - `temporal_id`
59  * - `Tags::InternalDirections<volume_dim>`
60  * - `Tags::BoundaryDirectionsInterior<volume_dim>`
61  * - `interface<Tags::Mesh<volume_dim - 1>>`
62  * - `boundary<Tags::Mesh<volume_dim - 1>>`
63  *
64  * DataBox:
65  * - Adds:
66  * - `mortar_data_tag`
67  * - `mortar<Tags::Next<temporal_id>>`
68  * - `mortar<Tags::Mesh<volume_dim - 1>>`
69  * - `mortar<Tags::MortarSize<volume_dim - 1>>`
70  * - `interface<flux_comm_types::normal_dot_fluxes_tag>`
71  * - `boundary<flux_comm_types::normal_dot_fluxes_tag>`
72  */
73 template <typename Metavariables>
75  static constexpr size_t volume_dim = Metavariables::system::volume_dim;
76  using temporal_id_tag = typename Metavariables::temporal_id;
78  using mortar_data_tag = typename flux_comm_types::simple_mortar_data_tag;
79 
80  template <typename Tag>
81  using interface_tag =
83  template <typename Tag>
84  using boundary_tag =
86  template <typename Tag>
88 
89  using simple_tags = db::AddSimpleTags<
91  mortar_tag<Tags::Mesh<volume_dim - 1>>,
92  mortar_tag<Tags::MortarSize<volume_dim - 1>>,
95 
96  using compute_tags = db::AddComputeTags<>;
97 
98  // This function is mostly copied from
99  // `Evolution/Initialization/DiscontinuousGalerkin.hpp`.
100  // It could be useful to move some of this functionality into compute items.
101  template <typename TagsList>
102  static auto add_mortar_data(db::DataBox<TagsList>&& box,
104  initial_extents) noexcept {
105  const auto& element = db::get<Tags::Element<volume_dim>>(box);
106  const auto& mesh = db::get<Tags::Mesh<volume_dim>>(box);
107 
108  db::item_type<mortar_data_tag> mortar_data{};
110  mortar_next_temporal_ids{};
111  db::item_type<mortar_tag<Tags::Mesh<volume_dim - 1>>> mortar_meshes{};
112  db::item_type<mortar_tag<Tags::MortarSize<volume_dim - 1>>> mortar_sizes{};
113  const auto& temporal_id = get<temporal_id_tag>(box);
114  for (const auto& direction_neighbors : element.neighbors()) {
115  const auto& direction = direction_neighbors.first;
116  const auto& neighbors = direction_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, temporal_id});
121  mortar_meshes.emplace(
122  mortar_id,
123  ::dg::mortar_mesh(
124  mesh.slice_away(direction.dimension()),
125  ::Initialization::element_mesh(initial_extents, neighbor,
126  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  // Add mortars for external boundaries
135  for (const auto& direction : element.external_boundaries()) {
136  const auto mortar_id = std::make_pair(
138  mortar_data[mortar_id]; // Default initialize data
139  mortar_next_temporal_ids.insert({mortar_id, temporal_id});
140  mortar_meshes.emplace(mortar_id, mesh.slice_away(direction.dimension()));
141  mortar_sizes.emplace(
142  mortar_id, make_array<volume_dim - 1>(Spectral::MortarSize::Full));
143  }
144 
145  return db::create_from<
147  db::AddSimpleTags<mortar_data_tag,
148  mortar_tag<Tags::Next<temporal_id_tag>>,
149  mortar_tag<Tags::Mesh<volume_dim - 1>>,
150  mortar_tag<Tags::MortarSize<volume_dim - 1>>>>(
151  std::move(box), std::move(mortar_data),
152  std::move(mortar_next_temporal_ids), std::move(mortar_meshes),
153  std::move(mortar_sizes));
154  }
155 
156  template <typename TagsList>
157  static auto initialize(db::DataBox<TagsList>&& box,
159  initial_extents) noexcept {
160  auto mortar_box = add_mortar_data(std::move(box), initial_extents);
161 
162  const auto& internal_directions =
163  db::get<Tags::InternalDirections<volume_dim>>(mortar_box);
164  const auto& boundary_directions =
165  db::get<Tags::BoundaryDirectionsInterior<volume_dim>>(mortar_box);
166 
168  interface_tag<typename flux_comm_types::normal_dot_fluxes_tag>>
169  normal_dot_fluxes{};
170  for (const auto& direction : internal_directions) {
171  const auto& interface_num_points =
172  db::get<interface_tag<Tags::Mesh<volume_dim - 1>>>(mortar_box)
173  .at(direction)
174  .number_of_grid_points();
175  normal_dot_fluxes[direction].initialize(interface_num_points, 0.);
176  }
178  boundary_normal_dot_fluxes{};
179  for (const auto& direction : boundary_directions) {
180  const auto& interface_num_points =
181  db::get<boundary_tag<Tags::Mesh<volume_dim - 1>>>(mortar_box)
182  .at(direction)
183  .number_of_grid_points();
184  boundary_normal_dot_fluxes[direction].initialize(interface_num_points,
185  0.);
186  }
187 
188  return db::create_from<
191  interface_tag<typename flux_comm_types::normal_dot_fluxes_tag>,
192  boundary_tag<typename flux_comm_types::normal_dot_fluxes_tag>>>(
193  std::move(mortar_box), std::move(normal_dot_fluxes),
194  std::move(boundary_normal_dot_fluxes));
195  }
196 };
197 } // namespace Initialization
198 } // namespace Elliptic
Defines class template Direction.
Items for initializing the DataBoxes of parallel components.
Definition: ConservativeSystem.hpp:21
Definition: ComputeOperatorAction.hpp:28
Initializes DataBox tags related to discontinuous Galerkin fluxes.
Definition: DiscontinuousGalerkin.hpp:74
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.
tmpl::flatten< tmpl::list< Tags... > > RemoveTags
List of Tags to remove from the DataBox.
Definition: DataBox.hpp:1220
Defines class template Neighbors.
Mesh< Dim > element_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: Helpers.hpp:31
Data on mortars, indexed by (Direction, ElementId) pairs.
Definition: Tags.hpp:34
Holds an IterationId that identifies a step in the linear solver algorithm.
Definition: Tags.hpp:66
Defines classes and functions used for manipulating DataBox&#39;s.
constexpr auto create_from(db::DataBox< TagsList > &&box, Args &&... args) noexcept
Create a new DataBox from an existing one adding or removing items and compute items.
Definition: DataBox.hpp:1414
tmpl::flatten< tmpl::list< Tags... > > AddSimpleTags
List of Tags to add to the DataBox.
Definition: DataBox.hpp:1227
Indicates the Frame that a TensorIndexType is in.
Definition: IndexType.hpp:36
Definition: InterpolationTargetWedgeSectionTorus.hpp:24
Types related to flux communication.
Definition: FluxCommunicationTypes.hpp:37
Size of a mortar, relative to the element face. That is, the part of the face that it covers...
Definition: Tags.hpp:46
Defines the class template Mesh.
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
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)
The computational grid of the Element in the DataBox.
Definition: Tags.hpp:75
typename DataBox_detail::item_type_impl< TagList, Tag >::type item_type
Get the type that is returned by the Tag. If it is a base tag then a TagList must be passed as a seco...
Definition: DataBoxTag.hpp:410
Defines functions and classes from the GSL.
Defines tags related to domain quantities.
BasedMortars< Tags::VariablesBoundaryData, Tags::SimpleBoundaryData< db::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:85
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...
Tag which is either a SimpleTag for quantities on an interface, base tag to a compute item which acts...
Definition: Tags.hpp:217
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
tmpl::flatten< tmpl::list< Tags... > > AddComputeTags
List of Compute Item Tags to add to the DataBox.
Definition: DataBox.hpp:1234
Defines class Element.