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/Conservative/Tags.hpp"
22 #include "Evolution/Initialization/Helpers.hpp"
23 #include "NumericalAlgorithms/DiscontinuousGalerkin/FluxCommunicationTypes.hpp"
24 #include "NumericalAlgorithms/DiscontinuousGalerkin/MortarHelpers.hpp"
25 #include "NumericalAlgorithms/DiscontinuousGalerkin/Tags.hpp"
26 #include "Utilities/Gsl.hpp"
27 #include "Utilities/TMPL.hpp"
28 
29 /// \cond
30 namespace Frame {
31 struct Inertial;
32 } // namespace Frame
33 /// \endcond
34 
35 namespace Initialization {
36 
37 /// \brief Initialize items related to the discontinuous Galerkin method
38 ///
39 /// Uses:
40 /// - DataBox:
41 /// * `Tags::Element<Dim>`
42 /// * `Tags::Mesh<Dim>`
43 /// * `Tags::Next<temporal_id_tag>`
44 /// * `Tags::Interface<Tags::InternalDirections<Dim>, Tags::Mesh<Dim - 1>>`
45 ///
46 /// DataBox changes:
47 /// - Adds:
48 /// * Tags::Interface<Tags::InternalDirections<Dim>,
49 /// typename flux_comm_types::normal_dot_fluxes_tag>
50 /// * mortar_data_tag
51 /// * Tags::Mortars<Tags::Next<temporal_id_tag>, dim>
52 /// * Tags::Mortars<Tags::Mesh<dim - 1>, dim>
53 /// * Tags::Mortars<Tags::MortarSize<dim - 1>, dim>
54 /// - Removes: nothing
55 /// - Modifies: nothing
56 template <typename Metavariables>
58  static constexpr size_t dim = Metavariables::system::volume_dim;
59  using temporal_id_tag = typename Metavariables::temporal_id;
61  using mortar_data_tag = tmpl::conditional_t<
62  Metavariables::local_time_stepping,
65 
66  template <typename Tag>
68 
69  template <typename Tag>
70  using interior_boundary_tag =
72 
73  template <typename Tag>
74  using external_boundary_tag =
76 
77  template <typename TagsList>
78  static auto add_mortar_data(
80  const std::vector<std::array<size_t, dim>>& initial_extents) noexcept {
81  const auto& element = db::get<Tags::Element<dim>>(box);
82  const auto& mesh = db::get<Tags::Mesh<dim>>(box);
83 
84  typename mortar_data_tag::type mortar_data{};
86  mortar_next_temporal_ids{};
87  typename Tags::Mortars<Tags::Mesh<dim - 1>, dim>::type mortar_meshes{};
88  typename Tags::Mortars<Tags::MortarSize<dim - 1>, dim>::type mortar_sizes{};
89  const auto& temporal_id = get<Tags::Next<temporal_id_tag>>(box);
90  for (const auto& direction_neighbors : element.neighbors()) {
91  const auto& direction = direction_neighbors.first;
92  const auto& neighbors = direction_neighbors.second;
93  for (const auto& neighbor : neighbors) {
94  const auto mortar_id = std::make_pair(direction, neighbor);
95  mortar_data[mortar_id]; // Default initialize data
96  mortar_next_temporal_ids.insert({mortar_id, temporal_id});
97  mortar_meshes.emplace(
98  mortar_id, dg::mortar_mesh(mesh.slice_away(direction.dimension()),
99  element_mesh(initial_extents, neighbor,
100  neighbors.orientation())
101  .slice_away(direction.dimension())));
102  mortar_sizes.emplace(
103  mortar_id,
104  dg::mortar_size(element.id(), neighbor, direction.dimension(),
105  neighbors.orientation()));
106  }
107  }
108 
109  for (const auto& direction : element.external_boundaries()) {
110  const auto mortar_id =
111  std::make_pair(direction, ElementId<dim>::external_boundary_id());
112  mortar_data[mortar_id];
113  // Since no communication needs to happen for boundary conditions,
114  // the temporal id is not advanced on the boundary, so we set it equal
115  // to the current temporal id in the element
116  mortar_next_temporal_ids.insert({mortar_id, temporal_id});
117  mortar_meshes.emplace(mortar_id, mesh.slice_away(direction.dimension()));
118  mortar_sizes.emplace(mortar_id,
119  make_array<dim - 1>(Spectral::MortarSize::Full));
120  }
121 
122  return db::create_from<
124  db::AddSimpleTags<mortar_data_tag,
126  Tags::Mortars<Tags::Mesh<dim - 1>, dim>,
127  Tags::Mortars<Tags::MortarSize<dim - 1>, dim>>>(
128  std::move(box), std::move(mortar_data),
129  std::move(mortar_next_temporal_ids), std::move(mortar_meshes),
130  std::move(mortar_sizes));
131  }
132 
133  template <typename LocalSystem, bool IsInFluxConservativeForm =
134  LocalSystem::is_in_flux_conservative_form>
135  struct Impl {
136  using simple_tags = db::AddSimpleTags<
137  mortar_data_tag, Tags::Mortars<Tags::Next<temporal_id_tag>, dim>,
138  Tags::Mortars<Tags::Mesh<dim - 1>, dim>,
139  Tags::Mortars<Tags::MortarSize<dim - 1>, dim>,
143 
144  using compute_tags = db::AddComputeTags<>;
145 
146  template <typename TagsList>
147  static auto initialize(
148  db::DataBox<TagsList>&& box,
149  const std::vector<std::array<size_t, dim>>& initial_extents) noexcept {
150  auto box2 = add_mortar_data(std::move(box), initial_extents);
151 
152  const auto& internal_directions =
153  db::get<Tags::InternalDirections<dim>>(box2);
154 
155  const auto& boundary_directions =
156  db::get<Tags::BoundaryDirectionsInterior<dim>>(box2);
157 
158  typename interface_tag<typename flux_comm_types::normal_dot_fluxes_tag>::
159  type normal_dot_fluxes_interface{};
160  for (const auto& direction : internal_directions) {
161  const auto& interface_num_points =
162  db::get<interface_tag<Tags::Mesh<dim - 1>>>(box2)
163  .at(direction)
164  .number_of_grid_points();
165  normal_dot_fluxes_interface[direction].initialize(interface_num_points,
166  0.);
167  }
168 
169  typename interior_boundary_tag<
171  normal_dot_fluxes_boundary_exterior{},
172  normal_dot_fluxes_boundary_interior{};
173  for (const auto& direction : boundary_directions) {
174  const auto& boundary_num_points =
175  db::get<interior_boundary_tag<Tags::Mesh<dim - 1>>>(box2)
176  .at(direction)
177  .number_of_grid_points();
178  normal_dot_fluxes_boundary_exterior[direction].initialize(
179  boundary_num_points, 0.);
180  normal_dot_fluxes_boundary_interior[direction].initialize(
181  boundary_num_points, 0.);
182  }
183 
184  return db::create_from<
187  interface_tag<typename flux_comm_types::normal_dot_fluxes_tag>,
191  typename flux_comm_types::normal_dot_fluxes_tag>>>(
192  std::move(box2), std::move(normal_dot_fluxes_interface),
193  std::move(normal_dot_fluxes_boundary_interior),
194  std::move(normal_dot_fluxes_boundary_exterior));
195  }
196  };
197 
198  template <typename LocalSystem>
199  struct Impl<LocalSystem, true> {
200  using simple_tags =
201  db::AddSimpleTags<mortar_data_tag,
203  Tags::Mortars<Tags::Mesh<dim - 1>, dim>,
204  Tags::Mortars<Tags::MortarSize<dim - 1>, dim>>;
205 
206  template <typename Tag>
207  using interface_compute_tag =
209 
210  template <typename Tag>
213 
214  template <typename Tag>
217 
218  using char_speed_tag = typename LocalSystem::char_speeds_tag;
219 
220  using compute_tags = db::AddComputeTags<
221  Tags::Slice<
223  db::add_tag_prefix<Tags::Flux, typename LocalSystem::variables_tag,
224  tmpl::size_t<dim>, Frame::Inertial>>,
226  typename LocalSystem::variables_tag, dim, Frame::Inertial>>,
228  Tags::Slice<
230  db::add_tag_prefix<Tags::Flux, typename LocalSystem::variables_tag,
231  tmpl::size_t<dim>, Frame::Inertial>>,
233  typename LocalSystem::variables_tag, dim, Frame::Inertial>>,
235  Tags::Slice<
237  db::add_tag_prefix<Tags::Flux, typename LocalSystem::variables_tag,
238  tmpl::size_t<dim>, Frame::Inertial>>,
240  typename LocalSystem::variables_tag, dim, Frame::Inertial>>,
242 
243  template <typename TagsList>
244  static auto initialize(
245  db::DataBox<TagsList>&& box,
246  const std::vector<std::array<size_t, dim>>& initial_extents) noexcept {
247  return db::create_from<db::RemoveTags<>, db::AddSimpleTags<>,
248  compute_tags>(
249  add_mortar_data(std::move(box), initial_extents));
250  }
251  };
252 
254  using simple_tags = typename impl::simple_tags;
255  using compute_tags = typename impl::compute_tags;
256 
257  template <typename TagsList>
258  static auto initialize(
259  db::DataBox<TagsList>&& box,
260  const std::vector<std::array<size_t, dim>>& initial_extents) noexcept {
261  return impl::initialize(std::move(box), initial_extents);
262  }
263 };
264 
265 } // 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:533
Defines class template Direction.
The set of directions to neighboring Elements.
Definition: Tags.hpp:145
Items for initializing the DataBoxes of parallel components.
Definition: ConservativeSystem.hpp:21
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.
Definition: DiscontinuousGalerkin.hpp:135
The set of directions which correspond to external boundaries. Used for representing data on the inte...
Definition: Tags.hpp:163
tmpl::flatten< tmpl::list< Tags... > > RemoveTags
List of Tags to remove from the DataBox.
Definition: DataBox.hpp:1220
Prefix computing a boundary unit normal vector dotted into the flux from a flux on the boundary...
Definition: Tags.hpp:30
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
Initialize items related to the discontinuous Galerkin method.
Definition: DiscontinuousGalerkin.hpp:57
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
Derived tag for representing a compute item which acts on Tags on an interface. Can be retrieved usin...
Definition: Tags.hpp:440
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
Prefix indicating a flux.
Definition: Prefixes.hpp:38
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
Derived tag for representing a compute item which slices a Tag containing a Variables from the volume...
Definition: Tags.hpp:479
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
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
Definition: IndexType.hpp:44
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...
The set of directions which correspond to external boundaries. To be used to represent data which exi...
Definition: Tags.hpp:177
db::add_tag_prefix< Tags::NormalDotFlux, typename system::variables_tag > normal_dot_fluxes_tag
The DataBox tag for the normal fluxes of the evolved variables.
Definition: FluxCommunicationTypes.hpp:49
Tag which is either a SimpleTag for quantities on an interface, base tag to a compute item which acts...
Definition: Tags.hpp:217
BasedMortars< Tags::VariablesBoundaryData, Tags::BoundaryHistory< LocalData, PackagedData, db::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
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.