Tags.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 /// \file
5 /// Defines DataBox tags for the linear solver
6 
7 #pragma once
8 
9 #include <cstddef>
10 #include <string>
11 #include <utility>
12 #include <vector>
13 
17 #include "Informer/Verbosity.hpp"
18 #include "NumericalAlgorithms/Convergence/Criteria.hpp"
19 #include "NumericalAlgorithms/Convergence/HasConverged.hpp"
20 #include "Utilities/Requires.hpp"
21 #include "Utilities/TypeTraits.hpp"
22 
23 /// \cond
24 namespace LinearSolver {
25 namespace Tags {
26 struct ConvergenceCriteria;
27 } // namespace Tags
28 } // namespace LinearSolver
29 /// \endcond
30 
31 /*!
32  * \ingroup LinearSolverGroup
33  * \brief Functionality for solving linear systems of equations
34  */
35 namespace LinearSolver {
36 
37 /*!
38  * \ingroup LinearSolverGroup
39  * \brief The \ref DataBoxGroup tags associated with the linear solver
40  */
41 namespace Tags {
42 
43 /*!
44  * \brief The operand that the local linear operator \f$A\f$ is applied to
45  *
46  * \details The result of the operation should be wrapped in
47  * `LinearSolver::Tags::OperatorAppliedTo`.
48  */
49 template <typename Tag>
51  static std::string name() noexcept {
52  // Add "Linear" prefix to abbreviate the namespace for uniqueness
53  return "LinearOperand(" + Tag::name() + ")";
54  }
55  using type = typename Tag::type;
56  using tag = Tag;
57 };
58 
59 /*!
60  * \brief The linear operator \f$A\f$ applied to the data in `Tag`
61  */
62 template <typename Tag>
64  static std::string name() noexcept {
65  // Add "Linear" prefix to abbreviate the namespace for uniqueness
66  return "LinearOperatorAppliedTo(" + Tag::name() + ")";
67  }
68  using type = typename Tag::type;
69  using tag = Tag;
70 };
71 
72 /*!
73  * \brief Holds an `IterationId` that identifies a step in the linear solver
74  * algorithm
75  */
77  static std::string name() noexcept {
78  // Add "Linear" prefix to abbreviate the namespace for uniqueness
79  return "LinearIterationId";
80  }
81  using type = size_t;
82  template <typename Tag>
84 };
85 
86 /*!
87  * \brief The residual \f$r=b - Ax\f$
88  */
89 template <typename Tag>
91  static std::string name() noexcept {
92  // Add "Linear" prefix to abbreviate the namespace for uniqueness
93  return "LinearResidual(" + Tag::name() + ")";
94  }
95  using type = typename Tag::type;
96  using tag = Tag;
97 };
98 
99 template <typename Tag>
101  static std::string name() noexcept { return "Initial(" + Tag::name() + ")"; }
102  using type = typename Tag::type;
103  using tag = Tag;
104 };
105 
106 /*!
107  * \brief The magnitude square \f$\langle \cdot,\cdot\rangle\f$ w.r.t.
108  * the `LinearSolver::inner_product`
109  */
110 template <typename Tag>
112  static std::string name() noexcept {
113  // Add "Linear" prefix to abbreviate the namespace for uniqueness
114  return "LinearMagnitudeSquare(" + Tag::name() + ")";
115  }
116  using type = double;
117  using tag = Tag;
118 };
119 
120 /*!
121  * \brief The magnitude \f$\sqrt{\langle \cdot,\cdot\rangle}\f$ w.r.t.
122  * the `LinearSolver::inner_product`
123  */
124 template <typename Tag>
126  static std::string name() noexcept {
127  // Add "Linear" prefix to abbreviate the namespace for uniqueness
128  return "LinearMagnitude(" + Tag::name() + ")";
129  }
130  using type = double;
131  using tag = Tag;
132 };
133 
134 /*!
135  * \brief Compute the `LinearSolver::Magnitude` of a tag from its
136  * `LinearSolver::MagnitudeSquare`.
137  */
138 template <typename MagnitudeSquareTag,
141  : db::add_tag_prefix<Magnitude, db::remove_tag_prefix<MagnitudeSquareTag>>,
143  static constexpr double function(const double& magnitude_square) noexcept {
144  return sqrt(magnitude_square);
145  }
146  using argument_tags = tmpl::list<MagnitudeSquareTag>;
147 };
148 
149 /*!
150  * \brief The prefix for tags related to an orthogonalization procedurce
151  */
152 template <typename Tag>
154  static std::string name() noexcept {
155  // Add "Linear" prefix to abbreviate the namespace for uniqueness
156  return "LinearOrthogonalization(" + Tag::name() + ")";
157  }
158  using type = typename Tag::type;
159  using tag = Tag;
160 };
161 
162 /*!
163  * \brief A Hessenberg matrix built up during an orthogonalization procedure
164  */
165 template <typename Tag>
167  static std::string name() noexcept {
168  // Add "Linear" prefix to abbreviate the namespace for uniqueness
169  return "LinearOrthogonalizationHistory(" + Tag::name() + ")";
170  }
171  using type = DenseMatrix<double>;
172  using tag = Tag;
173 };
174 
175 /*!
176  * \brief A set of \f$n\f$ vectors that form a basis of the \f$n\f$-th Krylov
177  * subspace \f$K_n(A,b)\f$
178  *
179  * \details The Krylov subspace \f$K_n(A,b)\f$ spanned by this basis is the one
180  * generated by the linear operator \f$A\f$ and source \f$b\f$ that are
181  * represented by the tags
182  * `db::add_tag_prefix<LinearSolver::Tags::OperatorAppliedTo,
183  * db::add_tag_prefix<LinearSolver::Tags::Operand, Tag>>` and
184  * `db::add_tag_prefix<::Tags::FixedSource, Tag>`, respectively. Therefore, each
185  * basis vector is of the type `db::const_item_type<db::add_tag_prefix<Operand,
186  * Tag>>`.
187  */
188 template <typename Tag>
190  static std::string name() noexcept {
191  // No "Linear" prefix since a Krylov subspace always refers to a linear
192  // operator
193  return "KrylovSubspaceBasis(" + Tag::name() + ")";
194  }
195  using type =
197  using tag = Tag;
198 };
199 
200 /*!
201  * \brief Holds a `Convergence::HasConverged` flag that signals the linear
202  * solver has converged, along with the reason for convergence.
203  */
205  static std::string name() noexcept { return "LinearSolverHasConverged"; }
207 };
208 
209 /*
210  * \brief Employs the `LinearSolver::Tags::ConvergenceCriteria` to
211  * determine the linear solver has converged.
212  */
213 template <typename FieldsTag>
215  private:
216  using residual_magnitude_tag = db::add_tag_prefix<
219  using initial_residual_magnitude_tag =
221 
222  public:
223  using argument_tags =
225  LinearSolver::Tags::IterationId, residual_magnitude_tag,
226  initial_residual_magnitude_tag>;
228  const Convergence::Criteria& convergence_criteria,
229  const size_t& iteration_id, const double& residual_magnitude,
230  const double& initial_residual_magnitude) noexcept {
231  return Convergence::HasConverged(convergence_criteria, iteration_id,
232  residual_magnitude,
233  initial_residual_magnitude);
234  }
235 };
236 
237 } // namespace Tags
238 
239 /*!
240  * \ingroup LinearSolverGroup
241  * \brief Option tags related to the iterative linear solver
242  */
243 namespace OptionTags {
244 
245 /*!
246  * \ingroup OptionGroupsGroup
247  * \brief Groups option tags related to the iterative linear solver, e.g.
248  * convergence criteria.
249  */
250 struct Group {
251  static std::string name() noexcept { return "LinearSolver"; }
252  static constexpr OptionString help =
253  "Options for the iterative linear solver";
254 };
255 
257  static constexpr OptionString help =
258  "Determine convergence of the linear solve";
259  using type = Convergence::Criteria;
260  using group = Group;
261 };
262 
263 struct Verbosity {
264  using type = ::Verbosity;
265  static constexpr OptionString help = "Logging verbosity";
266  using group = Group;
267  static type default_value() noexcept { return ::Verbosity::Quiet; }
268 };
269 
270 } // namespace OptionTags
271 
272 namespace Tags {
273 /*!
274  * \brief `Convergence::Criteria` that determine the linear solve has converged
275  *
276  * \note The smallest possible residual magnitude the linear solver can reach is
277  * the product between the machine epsilon and the condition number of the
278  * linear operator that is being inverted. Smaller residuals are numerical
279  * artifacts. Requiring an absolute or relative residual below this limit will
280  * likely lead to termination by `MaxIterations`.
281  *
282  * \note Remember that when the linear operator \f$A\f$ corresponds to a PDE
283  * discretization, decreasing the linear solver residual below the
284  * discretization error will not improve the numerical solution any further.
285  * I.e. the error \f$e_k=x_k-x_\mathrm{analytic}\f$ to an analytic solution
286  * will be dominated by the linear solver residual at first, but even if the
287  * discretization \f$Ax_k=b\f$ was exactly solved after some iteration \f$k\f$,
288  * the discretization residual
289  * \f$Ae_k=b-Ax_\mathrm{analytic}=r_\mathrm{discretization}\f$ would still
290  * remain. Therefore, ideally choose the absolute or relative residual criteria
291  * based on an estimate of the discretization residual.
292  */
294  using type = Convergence::Criteria;
295  static std::string name() noexcept { return "ConvergenceCriteria"; }
296  using option_tags = tmpl::list<LinearSolver::OptionTags::ConvergenceCriteria>;
298  const Convergence::Criteria& convergence_criteria) noexcept {
299  return convergence_criteria;
300  }
301 };
302 
304  static std::string name() noexcept { return "Verbosity"; }
305  using type = ::Verbosity;
306  using option_tags = tmpl::list<LinearSolver::OptionTags::Verbosity>;
308  const ::Verbosity& verbosity) noexcept {
309  return verbosity;
310  }
311 };
312 } // namespace Tags
313 } // namespace LinearSolver
314 
315 namespace Tags {
316 
317 template <>
318 struct NextCompute<LinearSolver::Tags::IterationId>
319  : Next<LinearSolver::Tags::IterationId>, db::ComputeTag {
320  using argument_tags = tmpl::list<LinearSolver::Tags::IterationId>;
321  static size_t function(const size_t& iteration_id) noexcept {
322  return iteration_id + 1;
323  }
324 };
325 
326 } // namespace Tags
The magnitude w.r.t. the LinearSolver::inner_product
Definition: Tags.hpp:125
Prefix< DataBox_detail::dispatch_add_tag_prefix_impl< Prefix, Tag, Args... >, Args... > add_tag_prefix
Wrap Tag in Prefix<_, Args...>, also wrapping variables tags if Tag is a Tags::Variables.
Definition: DataBoxTag.hpp:616
A Hessenberg matrix built up during an orthogonalization procedure.
Definition: Tags.hpp:166
Functionality for solving linear systems of equations.
Definition: TerminateIfConverged.hpp:22
Groups option tags related to the iterative linear solver, e.g. convergence criteria.
Definition: Tags.hpp:250
Marks a DataBoxTag as being a compute item that executes a function.
Definition: DataBoxTag.hpp:154
The magnitude square w.r.t. the LinearSolver::inner_product
Definition: Tags.hpp:111
Define prefixes for DataBox tags.
Tags for the DataBox inherit from this type.
Definition: DataBoxTag.hpp:64
Holds a Convergence::HasConverged flag that signals the linear solver has converged, along with the reason for convergence.
Definition: Tags.hpp:204
Definition: Tags.hpp:100
Defines the type alias Requires.
The operand that the local linear operator is applied to.
Definition: Tags.hpp:50
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:29
Signals convergence of the algorithm.
Definition: HasConverged.hpp:54
A set of vectors that form a basis of the -th Krylov subspace .
Definition: Tags.hpp:189
A dynamically sized matrix of arbitrary type.
Definition: DenseMatrix.hpp:29
Compute item for Tags::Next<Tag>
Definition: Prefixes.hpp:163
Holds an IterationId that identifies a step in the linear solver algorithm.
Definition: Tags.hpp:76
Defines class DenseMatrix.
Verbosity
Indicates how much informative output a class should output.
Definition: Verbosity.hpp:16
Criteria that determine an iterative algorithm has converged.
Definition: Criteria.hpp:35
Definition: Strahlkorper.hpp:167
Definition: DataBoxTag.hpp:29
The prefix for tags related to an orthogonalization procedurce.
Definition: Tags.hpp:153
Convergence::Criteria that determine the linear solve has converged
Definition: Tags.hpp:293
Definition: Tags.hpp:303
Prefix indicating the value a quantity will take on the next iteration of the algorithm.
Definition: Prefixes.hpp:150
Marks an item as being a prefix to another tag.
Definition: DataBoxTag.hpp:111
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
Compute the LinearSolver::Magnitude of a tag from its LinearSolver::MagnitudeSquare.
Definition: Tags.hpp:140
The linear operator applied to the data in Tag
Definition: Tags.hpp:63
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...
Definition: Tags.hpp:263
Defines type traits, some of which are future STL type_traits header.
tuples::TaggedTuple< Tags... > create_from_options(const tuples::TaggedTuple< OptionTags... > &options, tmpl::list< Tags... >) noexcept
Given a list of tags and a tagged tuple containing items created from input options, return a tagged tuple of items constructed by calls to create_from_options for each tag in the list.
Definition: ParallelComponentHelpers.hpp:182
The residual .
Definition: Tags.hpp:90