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 struct boundary_data_computer_impl {
34  using NumericalFlux = typename NumericalFluxComputerTag::type;
35  using n_dot_fluxes_tag =
37  using argument_tags =
38  tmpl::push_front<typename NumericalFlux::argument_tags,
39  NumericalFluxComputerTag, domain::Tags::Mesh<Dim - 1>,
40  n_dot_fluxes_tag>;
41  using volume_tags = tmpl::push_front<get_volume_tags<NumericalFlux>,
42  NumericalFluxComputerTag>;
43  template <typename... Args>
44  static auto apply(const NumericalFlux& numerical_flux_computer,
45  const Mesh<Dim - 1>& face_mesh,
46  const typename n_dot_fluxes_tag::type& normal_dot_fluxes,
47  const Args&... args) noexcept {
49  numerical_flux_computer, face_mesh, normal_dot_fluxes, args...);
50  }
51 };
52 
53 } // namespace detail
54 
55 /*!
56  * \ingroup DiscontinuousGalerkinGroup
57  * \brief Boundary contributions for a first-order DG scheme
58  *
59  * Computes Eq. (2.20) in \cite Teukolsky2015ega and lifts it to the
60  * volume (see `dg::lift_flux`) on all mortars that touch an element. The
61  * resulting boundary contributions are added to the DG operator data in
62  * `db::add_tag_prefix<TemporalIdTag::template step_prefix, VariablesTag>`.
63  */
64 template <size_t Dim, typename VariablesTag, typename NumericalFluxComputerTag,
65  typename TemporalIdTag>
67  static constexpr size_t volume_dim = Dim;
68  using variables_tag = VariablesTag;
69  using numerical_flux_computer_tag = NumericalFluxComputerTag;
70  using NumericalFlux = typename NumericalFluxComputerTag::type;
71  using temporal_id_tag = TemporalIdTag;
72  using receive_temporal_id_tag = temporal_id_tag;
73  using dt_variables_tag =
75 
76  static_assert(
77  tt::assert_conforms_to<NumericalFlux, dg::protocols::NumericalFlux>);
78  // We need the `VariablesTag` as an explicit template parameter only because
79  // it may be prefixed.
80  static_assert(std::is_same_v<typename NumericalFlux::variables_tags,
81  db::get_variables_tags_list<variables_tag>>,
82  "The 'VariablesTag' and the 'NumericalFluxComputerTag' must "
83  "have the same list of variables.");
84 
86  using boundary_data_computer =
87  detail::boundary_data_computer_impl<Dim, VariablesTag,
88  NumericalFluxComputerTag>;
89 
90  using mortar_data_tag = Tags::SimpleMortarData<typename TemporalIdTag::type,
91  BoundaryData, BoundaryData>;
92 
93  // Only a shortcut
96 
97  using return_tags =
98  tmpl::list<dt_variables_tag, ::Tags::Mortars<mortar_data_tag, Dim>>;
99  using argument_tags = tmpl::list<
101  ::Tags::Mortars<domain::Tags::Mesh<Dim - 1>, Dim>,
102  ::Tags::Mortars<::Tags::MortarSize<Dim - 1>, Dim>,
103  NumericalFluxComputerTag,
108 
109  static void apply(
110  const gsl::not_null<db::item_type<dt_variables_tag>*> dt_variables,
112  all_mortar_data,
113  const Mesh<Dim>& volume_mesh,
114  const MortarMap<Dim, Mesh<Dim - 1>>& mortar_meshes,
115  const MortarMap<Dim, MortarSize<Dim - 1>>& mortar_sizes,
116  const NumericalFlux& normal_dot_numerical_flux_computer,
118  face_normal_magnitudes_internal,
120  face_normal_magnitudes_boundary) noexcept {
121  // Iterate over all mortars
122  for (auto& mortar_id_and_data : *all_mortar_data) {
123  // Retrieve mortar data
124  const auto& mortar_id = mortar_id_and_data.first;
125  auto& mortar_data = mortar_id_and_data.second;
126  const auto& direction = mortar_id.first;
127  const size_t dimension = direction.dimension();
128 
129  // Extract local and remote data
130  const auto extracted_mortar_data = mortar_data.extract();
131  const auto& local_data = extracted_mortar_data.first;
132  const auto& remote_data = extracted_mortar_data.second;
133 
134  const auto& magnitude_of_face_normal =
135  mortar_id.second == ElementId<Dim>::external_boundary_id()
136  ? face_normal_magnitudes_boundary.at(direction)
137  : face_normal_magnitudes_internal.at(direction);
138 
139  auto boundary_flux_on_slice =
141  local_data, remote_data, normal_dot_numerical_flux_computer,
142  magnitude_of_face_normal, volume_mesh.extents(dimension),
143  volume_mesh.slice_away(dimension), mortar_meshes.at(mortar_id),
144  mortar_sizes.at(mortar_id)));
145 
146  // Add the flux contribution to the volume data
147  add_slice_to_data(dt_variables, std::move(boundary_flux_on_slice),
148  volume_mesh.extents(), dimension,
149  index_to_slice_at(volume_mesh.extents(), direction));
150  }
151  }
152 };
153 
154 } // namespace FirstOrderScheme
155 } // namespace dg
domain::push_front
CoordinateMap< SourceFrame, TargetFrame, NewMap, Maps... > push_front(CoordinateMap< SourceFrame, TargetFrame, Maps... > old_map, NewMap new_map) noexcept
Creates a CoordinateMap by prepending the new map to the beginning of the old maps.
DataBoxTag.hpp
Mesh::slice_away
Mesh< Dim - 1 > slice_away(size_t d) const noexcept
Returns a Mesh with dimension d removed (zero-indexed).
Definition: Mesh.cpp:18
utility
Tags::MortarSize
Definition: Tags.hpp:52
FaceNormal.hpp
domain::Tags::Mesh
The computational grid of the Element in the DataBox.
Definition: Tags.hpp:106
db::add_tag_prefix
Prefix< DataBox_detail::dispatch_add_tag_prefix_impl< Prefix, Tag, Args... >, Args... > add_tag_prefix
Definition: PrefixHelpers.hpp:145
Direction
Definition: Direction.hpp:23
dg
Functionality related to discontinuous Galerkin schemes.
Definition: ComputeNonconservativeBoundaryFluxes.hpp:23
ElementId::external_boundary_id
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
db::apply
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:1443
dg::FirstOrderScheme::package_boundary_data
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's needed for the (strong) first-order boundary scheme.
Definition: BoundaryData.hpp:62
cstddef
std::array
db::item_type
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
index_to_slice_at
size_t index_to_slice_at(const Index< Dim > &extents, const Direction< Dim > &direction) noexcept
Definition: IndexToSliceAt.hpp:15
Variables.hpp
dg::FirstOrderScheme::BoundaryData
typename detail::BoundaryDataImpl< NumericalFluxType >::type BoundaryData
The data on element boundaries that's needed for the (strong) first-order boundary scheme.
Definition: BoundaryData.hpp:46
Mesh
Holds the number of grid points, basis, and quadrature in each direction of the computational grid.
Definition: Mesh.hpp:50
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
Tags::Magnitude
Definition: Magnitude.hpp:101
domain::Tags::Interface
Tag which is either a SimpleTag for quantities on an interface, base tag to a compute item which acts...
Definition: Tags.hpp:309
dg::FirstOrderScheme::FirstOrderScheme
Boundary contributions for a first-order DG scheme.
Definition: FirstOrderScheme.hpp:66
Tensor.hpp
Direction.hpp
Mesh.hpp
dg::FirstOrderScheme::boundary_flux
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::extents
const Index< Dim > & extents() const noexcept
The number of grid points in each dimension of the grid.
Definition: Mesh.hpp:113
Tags::SimpleMortarData
Simple boundary communication data.
Definition: Tags.hpp:30
std::unordered_map
add_slice_to_data
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
TMPL.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: Gsl.hpp:183
Tags::Mortars
Definition: Tags.hpp:38