9 #include "Domain/InterfaceHelpers.hpp"
11 #include "NumericalAlgorithms/DiscontinuousGalerkin/MortarHelpers.hpp"
12 #include "NumericalAlgorithms/DiscontinuousGalerkin/Tags.hpp"
13 #include "NumericalAlgorithms/Spectral/Projection.hpp"
18 template <
typename Metavariables>
22 template <
typename... Tags>
67 template <
typename BoundaryScheme,
typename DirectionsTag>
71 template <
typename BoundaryScheme>
73 BoundaryScheme::volume_dim>> {
75 static constexpr
size_t volume_dim = BoundaryScheme::volume_dim;
76 using temporal_id_tag =
typename BoundaryScheme::temporal_id_tag;
77 using all_mortar_data_tag =
79 using boundary_data_computer =
80 typename BoundaryScheme::boundary_data_computer;
83 template <
typename DbTags,
typename... InboxTags,
typename Metavariables,
84 typename ArrayIndex,
typename ActionList,
85 typename ParallelComponent>
87 db::DataBox<DbTags>& box,
90 const ArrayIndex& ,
const ActionList ,
91 const ParallelComponent*
const ) noexcept {
93 auto boundary_data_on_interfaces =
94 interface_apply<domain::Tags::InternalDirections<volume_dim>,
95 boundary_data_computer>(box);
98 const auto& element = db::get<domain::Tags::Element<volume_dim>>(box);
99 const auto& face_meshes =
get<
102 const auto& mortar_meshes =
105 const auto& mortar_sizes =
108 const auto& temporal_id = get<temporal_id_tag>(box);
109 for (
const auto& direction_and_neighbors : element.neighbors()) {
110 const auto& direction = direction_and_neighbors.first;
111 const auto& face_mesh = face_meshes.at(direction);
112 for (
const auto& neighbor : direction_and_neighbors.second) {
113 const auto mortar_id = std::make_pair(direction, neighbor);
114 const auto&
mortar_mesh = mortar_meshes.at(mortar_id);
115 const auto&
mortar_size = mortar_sizes.at(mortar_id);
122 auto boundary_data_on_mortar =
124 ? boundary_data_on_interfaces.at(direction).project_to_mortar(
126 : std::move(boundary_data_on_interfaces.at(direction));
129 db::mutate<all_mortar_data_tag>(
131 [&mortar_id, &temporal_id, &boundary_data_on_mortar ](
133 all_mortar_data) noexcept {
134 all_mortar_data->at(mortar_id).local_insert(
135 temporal_id, std::move(boundary_data_on_mortar));
139 return {std::move(box)};
143 template <
typename BoundaryScheme>
144 struct CollectDataForFluxes<
146 domain::Tags::BoundaryDirectionsInterior<BoundaryScheme::volume_dim>> {
148 static constexpr
size_t volume_dim = BoundaryScheme::volume_dim;
149 using temporal_id_tag =
typename BoundaryScheme::temporal_id_tag;
150 using all_mortar_data_tag =
152 using boundary_data_computer =
153 typename BoundaryScheme::boundary_data_computer;
156 template <
typename DbTags,
typename... InboxTags,
typename Metavariables,
157 typename ArrayIndex,
typename ActionList,
158 typename ParallelComponent>
160 db::DataBox<DbTags>& box,
163 const ArrayIndex& ,
const ActionList ,
164 const ParallelComponent*
const ) noexcept {
166 auto interior_boundary_data =
167 interface_apply<domain::Tags::BoundaryDirectionsInterior<volume_dim>,
168 boundary_data_computer>(box);
169 auto exterior_boundary_data =
170 interface_apply<domain::Tags::BoundaryDirectionsExterior<volume_dim>,
171 boundary_data_computer>(box);
179 const auto& temporal_id = get<temporal_id_tag>(box);
180 for (
const auto& direction :
182 const MortarId<volume_dim> mortar_id{
184 db::mutate<all_mortar_data_tag>(
187 &temporal_id, &mortar_id, &direction, &interior_boundary_data, &
188 exterior_boundary_data
190 all_mortar_data) noexcept {
193 all_mortar_data->at(mortar_id).local_insert(
194 temporal_id, std::move(interior_boundary_data.at(direction)));
195 all_mortar_data->at(mortar_id).remote_insert(
196 temporal_id, std::move(exterior_boundary_data.at(direction)));
200 return {std::move(box)};