Line data Source code
1 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 :
14 : #include "DataStructures/DataBox/PrefixHelpers.hpp"
15 : #include "DataStructures/DataBox/Prefixes.hpp"
16 : #include "DataStructures/DataBox/Tag.hpp"
17 : #include "DataStructures/DataBox/TagName.hpp"
18 : #include "DataStructures/DynamicMatrix.hpp"
19 : #include "Options/String.hpp"
20 : #include "Utilities/Gsl.hpp"
21 : #include "Utilities/TMPL.hpp"
22 : #include "Utilities/TypeTraits/GetFundamentalType.hpp"
23 :
24 : /*!
25 : * \ingroup LinearSolverGroup
26 : * \brief Functionality for solving linear systems of equations
27 : */
28 : namespace LinearSolver {
29 :
30 : namespace OptionTags {
31 :
32 : template <typename OptionsGroup>
33 0 : struct OutputVolumeData {
34 0 : using type = bool;
35 0 : static constexpr Options::String help =
36 : "Record volume data for debugging purposes.";
37 0 : using group = OptionsGroup;
38 0 : static bool suggested_value() { return false; }
39 : };
40 :
41 : } // namespace OptionTags
42 :
43 : /*!
44 : * \ingroup LinearSolverGroup
45 : * \brief The \ref DataBoxGroup tags associated with the linear solver
46 : */
47 : namespace Tags {
48 :
49 : /*!
50 : * \brief The operand that the local linear operator \f$A\f$ is applied to
51 : *
52 : * \details The result of the operation should be wrapped in
53 : * `LinearSolver::Tags::OperatorAppliedTo`.
54 : */
55 : template <typename Tag>
56 1 : struct Operand : db::PrefixTag, db::SimpleTag {
57 0 : static std::string name() {
58 : // Add "Linear" prefix to abbreviate the namespace for uniqueness
59 : return "LinearOperand(" + db::tag_name<Tag>() + ")";
60 : }
61 0 : using type = typename Tag::type;
62 0 : using tag = Tag;
63 : };
64 :
65 : /*!
66 : * \brief The linear operator \f$A\f$ applied to the data in `Tag`
67 : */
68 : template <typename Tag>
69 1 : struct OperatorAppliedTo : db::PrefixTag, db::SimpleTag {
70 0 : static std::string name() {
71 : // Add "Linear" prefix to abbreviate the namespace for uniqueness
72 : return "LinearOperatorAppliedTo(" + db::tag_name<Tag>() + ")";
73 : }
74 0 : using type = typename Tag::type;
75 0 : using tag = Tag;
76 : };
77 :
78 : /*!
79 : * \brief The residual \f$r=b - Ax\f$
80 : */
81 : template <typename Tag>
82 1 : struct Residual : db::PrefixTag, db::SimpleTag {
83 0 : static std::string name() {
84 : // Add "Linear" prefix to abbreviate the namespace for uniqueness
85 : return "LinearResidual(" + db::tag_name<Tag>() + ")";
86 : }
87 0 : using type = typename Tag::type;
88 0 : using tag = Tag;
89 : };
90 :
91 : /// Compute the residual \f$r=b - Ax\f$ from the `SourceTag` \f$b\f$ and the
92 : /// `db::add_tag_prefix<LinearSolver::Tags::OperatorAppliedTo, FieldsTag>`
93 : /// \f$Ax\f$.
94 : template <typename FieldsTag, typename SourceTag>
95 1 : struct ResidualCompute : db::add_tag_prefix<Residual, FieldsTag>,
96 : db::ComputeTag {
97 0 : using base = db::add_tag_prefix<Residual, FieldsTag>;
98 0 : using argument_tags =
99 : tmpl::list<SourceTag, db::add_tag_prefix<OperatorAppliedTo, FieldsTag>>;
100 0 : using return_type = typename base::type;
101 0 : static void function(
102 : const gsl::not_null<return_type*> residual,
103 : const typename SourceTag::type& source,
104 : const typename db::add_tag_prefix<OperatorAppliedTo, FieldsTag>::type&
105 : operator_applied_to_fields) {
106 : *residual = source - operator_applied_to_fields;
107 : }
108 : };
109 :
110 : /*!
111 : * \brief The magnitude square \f$\langle \cdot,\cdot\rangle\f$ w.r.t.
112 : * the `LinearSolver::inner_product`
113 : */
114 : template <typename Tag>
115 1 : struct MagnitudeSquare : db::PrefixTag, db::SimpleTag {
116 0 : static std::string name() {
117 : // Add "Linear" prefix to abbreviate the namespace for uniqueness
118 : return "LinearMagnitudeSquare(" + db::tag_name<Tag>() + ")";
119 : }
120 0 : using type = double;
121 0 : using tag = Tag;
122 : };
123 :
124 : /*!
125 : * \brief The magnitude \f$\sqrt{\langle \cdot,\cdot\rangle}\f$ w.r.t.
126 : * the `LinearSolver::inner_product`
127 : */
128 : template <typename Tag>
129 1 : struct Magnitude : db::PrefixTag, db::SimpleTag {
130 0 : static std::string name() {
131 : // Add "Linear" prefix to abbreviate the namespace for uniqueness
132 : return "LinearMagnitude(" + db::tag_name<Tag>() + ")";
133 : }
134 0 : using type = double;
135 0 : using tag = Tag;
136 : };
137 :
138 : /*!
139 : * \brief The prefix for tags related to an orthogonalization procedure
140 : */
141 : template <typename Tag>
142 1 : struct Orthogonalization : db::PrefixTag, db::SimpleTag {
143 0 : static std::string name() {
144 : // Add "Linear" prefix to abbreviate the namespace for uniqueness
145 : return "LinearOrthogonalization(" + db::tag_name<Tag>() + ")";
146 : }
147 0 : using type = typename Tag::type;
148 0 : using tag = Tag;
149 : };
150 :
151 : /*!
152 : * \brief A Hessenberg matrix built up during an orthogonalization procedure
153 : */
154 : template <typename Tag>
155 1 : struct OrthogonalizationHistory : db::PrefixTag, db::SimpleTag {
156 0 : using ValueType = tt::get_complex_or_fundamental_type_t<typename Tag::type>;
157 0 : static std::string name() {
158 : // Add "Linear" prefix to abbreviate the namespace for uniqueness
159 : return "LinearOrthogonalizationHistory(" + db::tag_name<Tag>() + ")";
160 : }
161 0 : using type = blaze::DynamicMatrix<ValueType>;
162 0 : using tag = Tag;
163 : };
164 :
165 : /*!
166 : * \brief A set of \f$n\f$ vectors that form a basis of the \f$n\f$-th Krylov
167 : * subspace \f$K_n(A,b)\f$
168 : *
169 : * \details The Krylov subspace \f$K_n(A,b)\f$ spanned by this basis is the one
170 : * generated by the linear operator \f$A\f$ and source \f$b\f$ that are
171 : * represented by the tags
172 : * `db::add_tag_prefix<LinearSolver::Tags::OperatorAppliedTo,
173 : * db::add_tag_prefix<LinearSolver::Tags::Operand, Tag>>` and
174 : * `db::add_tag_prefix<::Tags::FixedSource, Tag>`, respectively. Therefore, each
175 : * basis vector is of the type db::add_tag_prefix<Operand, Tag>::type.
176 : */
177 : template <typename Tag>
178 1 : struct KrylovSubspaceBasis : db::PrefixTag, db::SimpleTag {
179 : // Use automatically generated name because a Krylov subspace always refers to
180 : // a linear operator
181 0 : using type = std::vector<typename Tag::type>;
182 0 : using tag = Tag;
183 : };
184 :
185 : /// Indicates the `Tag` is related to preconditioning of the linear solve
186 : template <typename Tag>
187 1 : struct Preconditioned : db::PrefixTag, db::SimpleTag {
188 0 : using type = typename Tag::type;
189 0 : using tag = Tag;
190 : };
191 :
192 : /// Whether or not volume data should be recorded for debugging purposes
193 : template <typename OptionsGroup>
194 1 : struct OutputVolumeData : db::SimpleTag {
195 0 : using type = bool;
196 0 : static constexpr bool pass_metavariables = false;
197 0 : using option_tags = tmpl::list<OptionTags::OutputVolumeData<OptionsGroup>>;
198 0 : static type create_from_options(const type value) { return value; };
199 0 : static std::string name() {
200 : return "OutputVolumeData(" + pretty_type::name<OptionsGroup>() + ")";
201 : }
202 : };
203 :
204 : /// Continuously incrementing ID for volume observations
205 : template <typename OptionsGroup>
206 1 : struct ObservationId : db::SimpleTag {
207 0 : using type = size_t;
208 0 : static std::string name() {
209 : return "ObservationId(" + pretty_type::name<OptionsGroup>() + ")";
210 : }
211 : };
212 :
213 : } // namespace Tags
214 : } // namespace LinearSolver
|