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