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 "Utilities/Gsl.hpp" 20 : 21 : /*! 22 : * \ingroup LinearSolverGroup 23 : * \brief Functionality for solving linear systems of equations 24 : */ 25 : namespace LinearSolver { 26 : 27 : /*! 28 : * \ingroup LinearSolverGroup 29 : * \brief The \ref DataBoxGroup tags associated with the linear solver 30 : */ 31 1 : namespace Tags { 32 : 33 : /*! 34 : * \brief The operand that the local linear operator \f$A\f$ is applied to 35 : * 36 : * \details The result of the operation should be wrapped in 37 : * `LinearSolver::Tags::OperatorAppliedTo`. 38 : */ 39 : template <typename Tag> 40 1 : struct Operand : db::PrefixTag, db::SimpleTag { 41 0 : static std::string name() { 42 : // Add "Linear" prefix to abbreviate the namespace for uniqueness 43 : return "LinearOperand(" + db::tag_name<Tag>() + ")"; 44 : } 45 0 : using type = typename Tag::type; 46 0 : using tag = Tag; 47 : }; 48 : 49 : /*! 50 : * \brief The linear operator \f$A\f$ applied to the data in `Tag` 51 : */ 52 : template <typename Tag> 53 1 : struct OperatorAppliedTo : db::PrefixTag, db::SimpleTag { 54 0 : static std::string name() { 55 : // Add "Linear" prefix to abbreviate the namespace for uniqueness 56 : return "LinearOperatorAppliedTo(" + db::tag_name<Tag>() + ")"; 57 : } 58 0 : using type = typename Tag::type; 59 0 : using tag = Tag; 60 : }; 61 : 62 : /*! 63 : * \brief The residual \f$r=b - Ax\f$ 64 : */ 65 : template <typename Tag> 66 1 : struct Residual : db::PrefixTag, db::SimpleTag { 67 0 : static std::string name() { 68 : // Add "Linear" prefix to abbreviate the namespace for uniqueness 69 : return "LinearResidual(" + db::tag_name<Tag>() + ")"; 70 : } 71 0 : using type = typename Tag::type; 72 0 : using tag = Tag; 73 : }; 74 : 75 : /// Compute the residual \f$r=b - Ax\f$ from the `SourceTag` \f$b\f$ and the 76 : /// `db::add_tag_prefix<LinearSolver::Tags::OperatorAppliedTo, FieldsTag>` 77 : /// \f$Ax\f$. 78 : template <typename FieldsTag, typename SourceTag> 79 1 : struct ResidualCompute : db::add_tag_prefix<Residual, FieldsTag>, 80 : db::ComputeTag { 81 0 : using base = db::add_tag_prefix<Residual, FieldsTag>; 82 0 : using argument_tags = 83 : tmpl::list<SourceTag, db::add_tag_prefix<OperatorAppliedTo, FieldsTag>>; 84 0 : using return_type = typename base::type; 85 0 : static void function( 86 : const gsl::not_null<return_type*> residual, 87 : const typename SourceTag::type& source, 88 : const typename db::add_tag_prefix<OperatorAppliedTo, FieldsTag>::type& 89 : operator_applied_to_fields) { 90 : *residual = source - operator_applied_to_fields; 91 : } 92 : }; 93 : 94 : /*! 95 : * \brief The magnitude square \f$\langle \cdot,\cdot\rangle\f$ w.r.t. 96 : * the `LinearSolver::inner_product` 97 : */ 98 : template <typename Tag> 99 1 : struct MagnitudeSquare : db::PrefixTag, db::SimpleTag { 100 0 : static std::string name() { 101 : // Add "Linear" prefix to abbreviate the namespace for uniqueness 102 : return "LinearMagnitudeSquare(" + db::tag_name<Tag>() + ")"; 103 : } 104 0 : using type = double; 105 0 : using tag = Tag; 106 : }; 107 : 108 : /*! 109 : * \brief The magnitude \f$\sqrt{\langle \cdot,\cdot\rangle}\f$ w.r.t. 110 : * the `LinearSolver::inner_product` 111 : */ 112 : template <typename Tag> 113 1 : struct Magnitude : db::PrefixTag, db::SimpleTag { 114 0 : static std::string name() { 115 : // Add "Linear" prefix to abbreviate the namespace for uniqueness 116 : return "LinearMagnitude(" + db::tag_name<Tag>() + ")"; 117 : } 118 0 : using type = double; 119 0 : using tag = Tag; 120 : }; 121 : 122 : /*! 123 : * \brief The prefix for tags related to an orthogonalization procedure 124 : */ 125 : template <typename Tag> 126 1 : struct Orthogonalization : db::PrefixTag, db::SimpleTag { 127 0 : static std::string name() { 128 : // Add "Linear" prefix to abbreviate the namespace for uniqueness 129 : return "LinearOrthogonalization(" + db::tag_name<Tag>() + ")"; 130 : } 131 0 : using type = typename Tag::type; 132 0 : using tag = Tag; 133 : }; 134 : 135 : /*! 136 : * \brief A Hessenberg matrix built up during an orthogonalization procedure 137 : */ 138 : template <typename Tag> 139 1 : struct OrthogonalizationHistory : db::PrefixTag, db::SimpleTag { 140 0 : static std::string name() { 141 : // Add "Linear" prefix to abbreviate the namespace for uniqueness 142 : return "LinearOrthogonalizationHistory(" + db::tag_name<Tag>() + ")"; 143 : } 144 0 : using type = blaze::DynamicMatrix<double>; 145 0 : using tag = Tag; 146 : }; 147 : 148 : /*! 149 : * \brief A set of \f$n\f$ vectors that form a basis of the \f$n\f$-th Krylov 150 : * subspace \f$K_n(A,b)\f$ 151 : * 152 : * \details The Krylov subspace \f$K_n(A,b)\f$ spanned by this basis is the one 153 : * generated by the linear operator \f$A\f$ and source \f$b\f$ that are 154 : * represented by the tags 155 : * `db::add_tag_prefix<LinearSolver::Tags::OperatorAppliedTo, 156 : * db::add_tag_prefix<LinearSolver::Tags::Operand, Tag>>` and 157 : * `db::add_tag_prefix<::Tags::FixedSource, Tag>`, respectively. Therefore, each 158 : * basis vector is of the type db::add_tag_prefix<Operand, Tag>::type. 159 : */ 160 : template <typename Tag> 161 1 : struct KrylovSubspaceBasis : db::PrefixTag, db::SimpleTag { 162 : // Use automatically generated name because a Krylov subspace always refers to 163 : // a linear operator 164 0 : using type = std::vector<typename Tag::type>; 165 0 : using tag = Tag; 166 : }; 167 : 168 : /// Indicates the `Tag` is related to preconditioning of the linear solve 169 : template <typename Tag> 170 1 : struct Preconditioned : db::PrefixTag, db::SimpleTag { 171 0 : using type = typename Tag::type; 172 0 : using tag = Tag; 173 : }; 174 : 175 : } // namespace Tags 176 : } // namespace LinearSolver