Tags.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <array>
7 #include <cstddef>
8 #include <string>
9 
10 #include "DataStructures/DataBox/Subitems.hpp"
11 #include "DataStructures/DataBox/Tag.hpp"
12 #include "DataStructures/DataVector.hpp"
15 #include "Options/Options.hpp"
16 #include "ParallelAlgorithms/LinearSolver/Schwarz/OverlapHelpers.hpp"
17 #include "Utilities/Gsl.hpp"
18 #include "Utilities/TMPL.hpp"
19 
20 namespace LinearSolver::Schwarz {
21 
22 /// Option tags related to the Schwarz solver
23 namespace OptionTags {
24 
25 template <typename OptionsGroup>
26 struct MaxOverlap {
27  using type = size_t;
28  using group = OptionsGroup;
29  static constexpr Options::String help =
30  "Number of points that subdomains can extend into neighbors";
31 };
32 
33 template <typename SolverType, typename OptionsGroup>
35  using type = SolverType;
36  using group = OptionsGroup;
37  static constexpr Options::String help =
38  "Options for the linear solver on subdomains";
39 };
40 
41 } // namespace OptionTags
42 
43 /// Tags related to the Schwarz solver
44 namespace Tags {
45 
46 /// Number of points a subdomain can overlap with its neighbor
47 template <typename OptionsGroup>
49  static std::string name() noexcept {
50  return "MaxOverlap(" + Options::name<OptionsGroup>() + ")";
51  }
52  using type = size_t;
53  static constexpr bool pass_metavariables = false;
54  using option_tags = tmpl::list<OptionTags::MaxOverlap<OptionsGroup>>;
55  static type create_from_options(const type& value) noexcept { return value; }
56 };
57 
58 /// The serial linear solver used to solve subdomain operators
59 template <typename OptionsGroup>
61  static std::string name() noexcept {
62  return "SubdomainSolver(" + Options::name<OptionsGroup>() + ")";
63  }
64 };
65 
66 /// The serial linear solver of type `SolverType` used to solve subdomain
67 /// operators
68 template <typename SolverType, typename OptionsGroup>
70  using type = SolverType;
71  static constexpr bool pass_metavariables = false;
72  using option_tags =
73  tmpl::list<OptionTags::SubdomainSolver<SolverType, OptionsGroup>>;
74  static type create_from_options(const type& value) noexcept { return value; }
75 };
76 
77 /*!
78  * \brief The `Tag` on the overlap region with each neighbor, i.e. on a region
79  * extruding from the central element.
80  *
81  * Note that data on an overlap with a neighbor is typically oriented according
82  * to the neighbor's orientation, so re-orientation needs to happen whenever
83  * the data cross element boundaries.
84  */
85 template <typename Tag, size_t Dim, typename OptionsGroup>
87  static std::string name() noexcept {
88  return "Overlaps(" + db::tag_name<Tag>() + ", " +
89  Options::name<OptionsGroup>() + ")";
90  }
91  using tag = Tag;
93 };
94 
95 /// The number of points a neighbor's subdomain extends into the element
96 template <size_t Dim, typename OptionsGroup>
98  static std::string name() noexcept {
99  return "IntrudingExtents(" + Options::name<OptionsGroup>() + ")";
100  }
102 };
103 
104 /// The width in element-logical coordinates that a neighbor's subdomain extends
105 /// into the element
106 template <size_t Dim, typename OptionsGroup>
108  static std::string name() noexcept {
109  return "IntrudingOverlapWidths(" + Options::name<OptionsGroup>() + ")";
110  }
112 };
113 
114 /// Weighting field for combining data from multiple overlapping subdomains
115 template <typename OptionsGroup>
117  static std::string name() noexcept {
118  return "Weight(" + Options::name<OptionsGroup>() + ")";
119  }
120  using type = Scalar<DataVector>;
121 };
122 
123 /*!
124  * \brief A diagnostic quantity to check that weights are conserved
125  *
126  * This quantity and the `Tags::Weight` on the element should sum to one on all
127  * grid points. Residual values indicate that overlap data from neighboring
128  * subdomains and data on the element are combined in a non-conservative way.
129  */
130 template <typename OptionsGroup>
132  static std::string name() noexcept {
133  return "SummedIntrudingOverlapWeights(" + Options::name<OptionsGroup>() +
134  ")";
135  }
136  using type = Scalar<DataVector>;
137 };
138 
139 } // namespace Tags
140 } // namespace LinearSolver::Schwarz
141 
142 namespace db {
143 namespace detail {
144 // This implementation mirrors the interface tag subitems in `Domain/Tags.hpp`.
145 // Please see that implementation for details.
146 template <typename VariablesTag, size_t Dim, typename OptionsGroup,
147  typename Tags = typename VariablesTag::type::tags_list>
148 struct OverlapSubitemsImpl;
149 
150 template <typename VariablesTag, size_t Dim, typename OptionsGroup,
151  typename... Tags>
152 struct OverlapSubitemsImpl<VariablesTag, Dim, OptionsGroup,
153  tmpl::list<Tags...>> {
154  using type = tmpl::list<
156  using tag =
158  using return_type = NoSuchType;
159  template <typename Subtag>
160  static void create_item(
161  const gsl::not_null<typename tag::type*> parent_value,
162  const gsl::not_null<typename Subtag::type*> sub_value) noexcept {
163  sub_value->clear();
164  for (auto& [overlap_id, parent_overlap_vars] : *parent_value) {
165  auto& parent_overlap_field =
166  get<typename Subtag::tag>(parent_overlap_vars);
167  auto& sub_overlap_field = (*sub_value)[overlap_id];
168  for (size_t i = 0; i < parent_overlap_field.size(); ++i) {
169  sub_overlap_field[i].set_data_ref(&parent_overlap_field[i]);
170  }
171  }
172  }
173  template <typename Subtag>
174  static void create_compute_item(
176  const typename tag::type& parent_value) noexcept {
177  for (const auto& [overlap_id, parent_overlap_vars] : parent_value) {
178  const auto& parent_overlap_field =
179  get<typename Subtag::tag>(parent_overlap_vars);
180  auto& sub_overlap_field = (*sub_value)[overlap_id];
181  for (size_t i = 0; i < parent_overlap_field.size(); ++i) {
182  // clang-tidy: do not use const_cast
183  // The DataBox will only give out a const reference to the result of a
184  // compute item. Here, that is a reference to a const map to Tensors of
185  // DataVectors. There is no (publicly visible) indirection there, so
186  // having the map const will allow only const access to the contained
187  // DataVectors, so no modification through the pointer cast here is
188  // possible. See the implementation of subitems in `Domain/Tags.hpp` for
189  // details.
190  sub_overlap_field[i].set_data_ref(
191  const_cast<DataVector*>(&parent_overlap_field[i])); // NOLINT
192  }
193  }
194  }
195 };
196 } // namespace detail
197 
198 template <typename VariablesTag, size_t Dim, typename OptionsGroup>
199 struct Subitems<
200  LinearSolver::Schwarz::Tags::Overlaps<VariablesTag, Dim, OptionsGroup>,
201  Requires<tt::is_a_v<Variables, typename VariablesTag::type>>>
202  : detail::OverlapSubitemsImpl<VariablesTag, Dim, OptionsGroup> {};
203 
204 } // namespace db
NoSuchType
Used to mark "no type" or "bad state" for metaprogramming.
Definition: NoSuchType.hpp:10
std::string
Options.hpp
LinearSolver::Schwarz::Tags::MaxOverlap
Number of points a subdomain can overlap with its neighbor.
Definition: Tags.hpp:48
LinearSolver::Schwarz::Tags::IntrudingExtents
The number of points a neighbor's subdomain extends into the element.
Definition: Tags.hpp:97
db::SimpleTag
Mark a struct as a simple tag by inheriting from this.
Definition: Tag.hpp:36
LinearSolver::Schwarz
Items related to the Schwarz linear solver.
Definition: CommunicateOverlapFields.hpp:36
LinearSolver::Schwarz::Tags::SubdomainSolverBase
The serial linear solver used to solve subdomain operators.
Definition: Tags.hpp:60
cstddef
array
LinearSolver::Schwarz::OptionTags::MaxOverlap
Definition: Tags.hpp:26
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:42
LinearSolver::Schwarz::Tags::Weight
Weighting field for combining data from multiple overlapping subdomains.
Definition: Tags.hpp:116
LinearSolver::Schwarz::OptionTags::SubdomainSolver
Definition: Tags.hpp:34
db::BaseTag
Mark a (usually) empty struct as a base tag by inheriting from this.
Definition: Tag.hpp:69
LinearSolver::Schwarz::Tags::Overlaps
The Tag on the overlap region with each neighbor, i.e. on a region extruding from the central element...
Definition: Tags.hpp:86
Variables.hpp
LinearSolver::Schwarz::Tags::SummedIntrudingOverlapWeights
A diagnostic quantity to check that weights are conserved.
Definition: Tags.hpp:131
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
LinearSolver
Functionality for solving linear systems of equations.
Definition: Gmres.cpp:16
Gsl.hpp
Options::String
const char *const String
The string used in option structs.
Definition: Options.hpp:32
Tensor.hpp
db::Subitems
Definition: Subitems.hpp:32
LinearSolver::Schwarz::Tags::SubdomainSolver
The serial linear solver of type SolverType used to solve subdomain operators.
Definition: Tags.hpp:69
Requires
typename Requires_detail::requires_impl< B >::template_error_type_failed_to_meet_requirements_on_template_parameters Requires
Express requirements on the template parameters of a function or class, replaces std::enable_if_t
Definition: Requires.hpp:67
FixedHashMap
A hash table with a compile-time specified maximum size and ability to efficiently handle perfect has...
Definition: FixedHashMap.hpp:81
TMPL.hpp
db
Namespace for DataBox related things.
Definition: DataBox.hpp:43
gsl::not_null
Require a pointer to not be a nullptr
Definition: Gsl.hpp:183
LinearSolver::Schwarz::Tags::IntrudingOverlapWidths
The width in element-logical coordinates that a neighbor's subdomain extends into the element.
Definition: Tags.hpp:107
string