18 #include "Informer/Tags.hpp"
19 #include "Informer/Verbosity.hpp"
20 #include "NumericalAlgorithms/Convergence/Tags.hpp"
22 #include "Parallel/InboxInserters.hpp"
23 #include "Parallel/Invoke.hpp"
25 #include "ParallelAlgorithms/DiscontinuousGalerkin/HasReceivedFromAllMortars.hpp"
26 #include "ParallelAlgorithms/LinearSolver/Schwarz/OverlapHelpers.hpp"
27 #include "ParallelAlgorithms/LinearSolver/Schwarz/Tags.hpp"
29 #include "Utilities/TaggedTuple.hpp"
41 template <
size_t Dim,
typename OverlapFields,
typename OptionsGroup>
42 struct OverlapFieldsTag
44 OverlapFieldsTag<Dim, OverlapFields, OptionsGroup>> {
45 using temporal_id = size_t;
67 template <
typename OverlapFields,
typename OptionsGroup,
bool RestrictToOverlap>
71 template <
typename... OverlapFields,
typename OptionsGroup,
72 bool RestrictToOverlap>
75 using const_global_cache_tags =
76 tmpl::list<Tags::MaxOverlap<OptionsGroup>,
79 template <
typename DbTagsList,
typename... InboxTags,
typename Metavariables,
80 size_t Dim,
typename ActionList,
typename ParallelComponent>
82 db::DataBox<DbTagsList>& box,
86 const ParallelComponent*
const ) noexcept {
87 const auto& element = get<domain::Tags::Element<Dim>>(box);
91 element.number_of_neighbors() == 0)) {
92 return {std::move(box)};
96 const auto& iteration_id =
97 get<Convergence::Tags::IterationId<OptionsGroup>>(box);
99 ::Verbosity::Debug)) {
101 "(%zu): Send overlap fields\n",
102 element_id, iteration_id);
106 auto& receiver_proxy =
107 Parallel::get_parallel_component<ParallelComponent>(
cache);
108 for (
const auto& direction_and_neighbors : element.neighbors()) {
109 const auto& direction = direction_and_neighbors.first;
110 const auto& neighbors = direction_and_neighbors.second;
113 if constexpr (RestrictToOverlap) {
114 const auto& element_extents =
115 get<domain::Tags::Mesh<Dim>>(box).extents();
116 const size_t intruding_extent =
117 gsl::at(
get<Tags::IntrudingExtents<Dim, OptionsGroup>>(box),
118 direction.dimension());
121 db::get<OverlapFields>(box), element_extents,
122 intruding_extent, direction))...);
125 db::get<OverlapFields>(box))...);
128 const auto direction_from_neighbor =
129 neighbors.orientation()(direction.opposite());
130 for (
auto neighbor = neighbors.begin(); neighbor != neighbors.end();
133 Dim, tmpl::list<OverlapFields...>, OptionsGroup>>(
134 receiver_proxy[*neighbor], iteration_id,
136 OverlapId<Dim>{direction_from_neighbor, element.id()},
137 (std::next(neighbor) == neighbors.end())
139 ? std::move(overlap_fields)
143 return {std::move(box)};
159 template <
size_t Dim,
typename OverlapFields,
typename OptionsGroup>
163 template <
size_t Dim,
typename... OverlapFields,
typename OptionsGroup>
166 using overlap_fields_tag =
167 detail::OverlapFieldsTag<Dim, tmpl::list<OverlapFields...>, OptionsGroup>;
170 using const_global_cache_tags =
171 tmpl::list<Tags::MaxOverlap<OptionsGroup>,
173 using inbox_tags = tmpl::list<overlap_fields_tag>;
175 template <
typename DbTagsList,
typename... InboxTags,
typename Metavariables>
176 static bool is_ready(
const db::DataBox<DbTagsList>& box,
183 return dg::has_received_from_all_mortars<overlap_fields_tag>(
188 template <
typename DbTagsList,
typename... InboxTags,
typename Metavariables,
189 typename ActionList,
typename ParallelComponent>
194 const ParallelComponent*
const ) noexcept {
199 return {std::move(box)};
203 const auto& iteration_id =
204 get<Convergence::Tags::IterationId<OptionsGroup>>(box);
206 ::Verbosity::Debug)) {
208 "(%zu): Receive overlap fields\n",
209 element_id, iteration_id);
213 auto received_overlap_fields =
214 std::move(tuples::get<overlap_fields_tag>(inboxes)
215 .extract(iteration_id)
217 db::mutate<Tags::Overlaps<OverlapFields, Dim, OptionsGroup>...>(
219 const auto... local_overlap_fields) noexcept {
220 for (
auto& [overlap_id, overlap_fields] : received_overlap_fields) {
222 std::move(get<OverlapFields>(overlap_fields))...);
226 return {std::move(box)};