FirstOrderScheme.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <utility>
8 
10 #include "DataStructures/DataVector.hpp"
11 #include "DataStructures/Tensor/EagerMath/Magnitude.hpp"
14 #include "Domain/Direction.hpp"
15 #include "Domain/FaceNormal.hpp"
16 #include "Domain/InterfaceHelpers.hpp"
17 #include "Domain/Mesh.hpp"
18 #include "NumericalAlgorithms/DiscontinuousGalerkin/BoundarySchemes/FirstOrder/BoundaryData.hpp"
19 #include "NumericalAlgorithms/DiscontinuousGalerkin/BoundarySchemes/FirstOrder/BoundaryFlux.hpp"
20 #include "NumericalAlgorithms/DiscontinuousGalerkin/MortarHelpers.hpp"
21 #include "NumericalAlgorithms/DiscontinuousGalerkin/Protocols.hpp"
22 #include "NumericalAlgorithms/DiscontinuousGalerkin/SimpleMortarData.hpp"
23 #include "NumericalAlgorithms/DiscontinuousGalerkin/Tags.hpp"
24 #include "Utilities/ProtocolHelpers.hpp"
25 #include "Utilities/TMPL.hpp"
26 
27 namespace dg {
28 namespace FirstOrderScheme {
29 
30 namespace detail {
31 
32 template <size_t Dim, typename VariablesTag, typename NumericalFluxComputerTag,
33  typename NumericalFlux =
35  typename ArgsTagsList = typename NumericalFlux::argument_tags>
36 struct boundary_data_computer_impl;
37 
38 template <size_t Dim, typename VariablesTag, typename NumericalFluxComputerTag,
39  typename NumericalFlux, typename... ArgsTags>
40 struct boundary_data_computer_impl<Dim, VariablesTag, NumericalFluxComputerTag,
41  NumericalFlux, tmpl::list<ArgsTags...>> {
42  using n_dot_fluxes_tag =
44  using argument_tags =
45  tmpl::list<NumericalFluxComputerTag, domain::Tags::Mesh<Dim - 1>,
46  n_dot_fluxes_tag, ArgsTags...>;
47  using volume_tags = tmpl::append<tmpl::list<NumericalFluxComputerTag>,
48  get_volume_tags<NumericalFlux>>;
49  static auto apply(
50  const NumericalFlux& numerical_flux_computer,
51  const Mesh<Dim - 1>& face_mesh,
52  const db::const_item_type<n_dot_fluxes_tag>& normal_dot_fluxes,
53  const db::const_item_type<ArgsTags>&... args) noexcept {
55  numerical_flux_computer, face_mesh, normal_dot_fluxes, args...);
56  }
57 };
58 
59 } // namespace detail
60 
61 /*!
62  * \ingroup DiscontinuousGalerkinGroup
63  * \brief Boundary contributions for a first-order DG scheme
64  *
65  * Computes Eq. (2.20) in \cite Teukolsky2015ega and lifts it to the
66  * volume (see `dg::lift_flux`) on all mortars that touch an element. The
67  * resulting boundary contributions are added to the DG operator data in
68  * `db::add_tag_prefix<TemporalIdTag::template step_prefix, VariablesTag>`.
69  */
70 template <size_t Dim, typename VariablesTag, typename NumericalFluxComputerTag,
71  typename TemporalIdTag>
73  static constexpr size_t volume_dim = Dim;
74  using variables_tag = VariablesTag;
75  using numerical_flux_computer_tag = NumericalFluxComputerTag;
77  using temporal_id_tag = TemporalIdTag;
78  using receive_temporal_id_tag = temporal_id_tag;
79  using dt_variables_tag =
81 
82  static_assert(
83  tt::conforms_to_v<NumericalFlux, dg::protocols::NumericalFlux>,
84  "The type held by the 'NumericalFluxComputerTag' must conform to the "
85  "'dg::protocols::NumericalFlux'.");
86  // We need the `VariablesTag` as an explicit template parameter only because
87  // it may be prefixed.
88  static_assert(cpp17::is_same_v<typename NumericalFlux::variables_tags,
89  db::get_variables_tags_list<variables_tag>>,
90  "The 'VariablesTag' and the 'NumericalFluxComputerTag' must "
91  "have the same list of variables.");
92 
94  using boundary_data_computer =
95  detail::boundary_data_computer_impl<Dim, VariablesTag,
96  NumericalFluxComputerTag>;
97 
98  using mortar_data_tag =
100  BoundaryData>;
101 
102  // Only a shortcut
105 
106  using return_tags =
107  tmpl::list<dt_variables_tag, ::Tags::Mortars<mortar_data_tag, Dim>>;
108  using argument_tags = tmpl::list<
110  ::Tags::Mortars<domain::Tags::Mesh<Dim - 1>, Dim>,
111  ::Tags::Mortars<::Tags::MortarSize<Dim - 1>, Dim>,
112  NumericalFluxComputerTag,
116  magnitude_of_face_normal_tag>>;
117 
118  static void apply(
119  const gsl::not_null<db::item_type<dt_variables_tag>*> dt_variables,
121  all_mortar_data,
122  const Mesh<Dim>& volume_mesh,
123  const db::const_item_type<
124  ::Tags::Mortars<domain::Tags::Mesh<Dim - 1>, Dim>>& mortar_meshes,
125  const db::const_item_type<
126  ::Tags::Mortars<::Tags::MortarSize<Dim - 1>, Dim>>& mortar_sizes,
127  const NumericalFlux& normal_dot_numerical_flux_computer,
129  domain::Tags::InternalDirections<Dim>, magnitude_of_face_normal_tag>>&
130  face_normal_magnitudes_internal,
131  const db::const_item_type<
133  magnitude_of_face_normal_tag>>&
134  face_normal_magnitudes_boundary) noexcept {
135  // Iterate over all mortars
136  for (auto& mortar_id_and_data : *all_mortar_data) {
137  // Retrieve mortar data
138  const auto& mortar_id = mortar_id_and_data.first;
139  auto& mortar_data = mortar_id_and_data.second;
140  const auto& direction = mortar_id.first;
141  const size_t dimension = direction.dimension();
142 
143  // Extract local and remote data
144  const auto extracted_mortar_data = mortar_data.extract();
145  const auto& local_data = extracted_mortar_data.first;
146  const auto& remote_data = extracted_mortar_data.second;
147 
148  const auto& magnitude_of_face_normal =
149  mortar_id.second == ElementId<Dim>::external_boundary_id()
150  ? face_normal_magnitudes_boundary.at(direction)
151  : face_normal_magnitudes_internal.at(direction);
152 
153  auto boundary_flux_on_slice =
155  local_data, remote_data, normal_dot_numerical_flux_computer,
156  magnitude_of_face_normal, volume_mesh.extents(dimension),
157  volume_mesh.slice_away(dimension), mortar_meshes.at(mortar_id),
158  mortar_sizes.at(mortar_id)));
159 
160  // Add the flux contribution to the volume data
161  add_slice_to_data(dt_variables, std::move(boundary_flux_on_slice),
162  volume_mesh.extents(), dimension,
163  index_to_slice_at(volume_mesh.extents(), direction));
164  }
165  }
166 };
167 
168 } // namespace FirstOrderScheme
169 } // namespace dg
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: PrefixHelpers.hpp:145
Defines class template Direction.
size_t index_to_slice_at(const Index< Dim > &extents, const Direction< Dim > &direction) noexcept
Finds the index in the perpendicular dimension of an element boundary.
Definition: IndexToSliceAt.hpp:15
The computational grid of the Element in the DataBox.
Definition: Tags.hpp:105
Tag which is either a SimpleTag for quantities on an interface, base tag to a compute item which acts...
Definition: Tags.hpp:269
typename detail::BoundaryDataImpl< NumericalFluxType >::type BoundaryData
The data on element boundaries that&#39;s needed for the (strong) first-order boundary scheme...
Definition: BoundaryData.hpp:47
Definition: Digraph.hpp:11
Functionality related to discontinuous Galerkin schemes.
Definition: ApplyBoundaryFluxesLocalTimeStepping.hpp:33
The set of directions to neighboring Elements.
Definition: Tags.hpp:195
Holds the number of grid points, basis, and quadrature in each direction of the computational grid...
Definition: Mesh.hpp:50
Variables< typename NumericalFluxType::variables_tags > boundary_flux(const dg::SimpleBoundaryData< AllFieldsTags, AllExtraDataTags > &local_boundary_data, const dg::SimpleBoundaryData< AllFieldsTags, AllExtraDataTags > &remote_boundary_data, const NumericalFluxType &numerical_flux_computer, const Scalar< DataVector > &magnitude_of_face_normal, const size_t extent_perpendicular_to_boundary, const Mesh< FaceDim > &face_mesh, const Mesh< FaceDim > &mortar_mesh, const MortarSize< FaceDim > &mortar_size) noexcept
Compute the boundary flux contribution and lift it to the volume.
Definition: BoundaryFlux.hpp:48
Mesh< Dim - 1 > slice_away(size_t d) const noexcept
Returns a Mesh with dimension d removed (zero-indexed).
Definition: Mesh.cpp:18
The set of directions which correspond to external boundaries. Used for representing data on the inte...
Definition: Tags.hpp:214
Definition: Determinant.hpp:11
Data on mortars, indexed by (Direction, ElementId) pairs.
Definition: Tags.hpp:38
Boundary contributions for a first-order DG scheme.
Definition: FirstOrderScheme.hpp:72
constexpr bool is_same_v
Variable template for is_same.
Definition: TypeTraits.hpp:194
Defines class Variables.
Size of a mortar, relative to the element face. That is, the part of the face that it covers...
Definition: Tags.hpp:52
Defines the class template Mesh.
Defines classes for Tensor.
static ElementId< VolumeDim > external_boundary_id() noexcept
Returns an ElementId meant for identifying data on external boundaries, which should never correspond...
Definition: ElementId.cpp:75
Declares function unnormalized_face_normal.
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:1444
auto package_boundary_data(const NumericalFluxType &numerical_flux_computer, const Mesh< FaceDim > &face_mesh, const Variables< db::wrap_tags_in< ::Tags::NormalDotFlux, typename NumericalFluxType::variables_tags >> &normal_dot_fluxes, const NumericalFluxArgs &... args) noexcept
Package the data on element boundaries that&#39;s needed for the (strong) first-order boundary scheme...
Definition: BoundaryData.hpp:63
Simple boundary communication data.
Definition: Tags.hpp:30
std::conditional_t< tmpl2::flat_all_v< detail::has_variables_tags_v< ConformingType >, detail::has_argument_tags_v< ConformingType >, detail::has_package_field_tags_v< ConformingType >, detail::has_package_extra_tags_v< ConformingType > >, cpp17::conjunction< detail::IsPackageDataCallable< ConformingType >, detail::IsNumericalFluxCallable< ConformingType > >, std::false_type > NumericalFlux
Defines the interface for DG numerical fluxes.
Definition: Protocols.hpp:140
const Index< Dim > & extents() const noexcept
The number of grid points in each dimension of the grid.
Definition: Mesh.hpp:113
Wraps the template metaprogramming library used (brigand)
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:246
The magnitude of a (co)vector.
Definition: Magnitude.hpp:80
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...
void add_slice_to_data(const gsl::not_null< Variables< TagsList > *> volume_vars, const Variables< TagsList > &vars_on_slice, const Index< VolumeDim > &extents, const size_t sliced_dim, const size_t fixed_index) noexcept
Adds data on a codimension 1 slice to a volume quantity. The slice has a constant logical coordinate ...
Definition: SliceVariables.hpp:82
Require a pointer to not be a nullptr
Definition: Gsl.hpp:182