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