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 if constexpr (db::tag_is_retrievable_v<
142 const auto integration_order =
143 db::get<::Tags::HistoryEvolvedVariables<>>(box)
144 .integration_order();
145 db::mutate<all_mortar_data_tag>(
147 [&mortar_id, &integration_order](
149 all_mortar_data) noexcept {
150 all_mortar_data->at(mortar_id).integration_order(
156 return {std::move(box)};
160 template <
typename BoundaryScheme>
161 struct CollectDataForFluxes<
163 domain::Tags::BoundaryDirectionsInterior<BoundaryScheme::volume_dim>> {
165 static constexpr
size_t volume_dim = BoundaryScheme::volume_dim;
166 using temporal_id_tag =
typename BoundaryScheme::temporal_id_tag;
167 using all_mortar_data_tag =
169 using boundary_data_computer =
170 typename BoundaryScheme::boundary_data_computer;
173 template <
typename DbTags,
typename... InboxTags,
typename Metavariables,
174 typename ArrayIndex,
typename ActionList,
175 typename ParallelComponent>
177 db::DataBox<DbTags>& box,
180 const ArrayIndex& ,
const ActionList ,
181 const ParallelComponent*
const ) noexcept {
183 auto interior_boundary_data =
184 interface_apply<domain::Tags::BoundaryDirectionsInterior<volume_dim>,
185 boundary_data_computer>(box);
186 auto exterior_boundary_data =
187 interface_apply<domain::Tags::BoundaryDirectionsExterior<volume_dim>,
188 boundary_data_computer>(box);
196 const auto& temporal_id = get<temporal_id_tag>(box);
197 for (
const auto& direction :
199 const MortarId<volume_dim> mortar_id{
201 db::mutate<all_mortar_data_tag>(
204 &temporal_id, &mortar_id, &direction, &interior_boundary_data, &
205 exterior_boundary_data
207 all_mortar_data) noexcept {
210 all_mortar_data->at(mortar_id).local_insert(
211 temporal_id, std::move(interior_boundary_data.at(direction)));
212 all_mortar_data->at(mortar_id).remote_insert(
213 temporal_id, std::move(exterior_boundary_data.at(direction)));
217 return {std::move(box)};