SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/LinearSolver/Gmres - Gmres.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 30.8 % 13 4
Test Date: 2026-10-22 17:29:42
Legend: Lines:     hit not hit

            Line data    Source code
       1            0 : // Distributed under the MIT License.
       2              : // See LICENSE.txt for details.
       3              : 
       4              : #pragma once
       5              : 
       6              : #include "DataStructures/DataBox/PrefixHelpers.hpp"
       7              : #include "DataStructures/DataBox/Prefixes.hpp"
       8              : #include "ParallelAlgorithms/LinearSolver/Gmres/ElementActions.hpp"
       9              : #include "ParallelAlgorithms/LinearSolver/Gmres/InitializeElement.hpp"
      10              : #include "ParallelAlgorithms/LinearSolver/Gmres/ResidualMonitor.hpp"
      11              : #include "ParallelAlgorithms/LinearSolver/Tags.hpp"
      12              : #include "Utilities/TMPL.hpp"
      13              : 
      14              : /// Items related to the GMRES linear solver
      15              : ///
      16              : /// \see `LinearSolver::gmres::Gmres`
      17              : namespace LinearSolver::gmres {
      18              : 
      19              : /*!
      20              :  * \ingroup LinearSolverGroup
      21              :  * \brief A GMRES solver for nonsymmetric linear systems of equations
      22              :  * \f$Ax=b\f$.
      23              :  *
      24              :  * \details The only operation we need to supply to the algorithm is the
      25              :  * result of the operation \f$A(p)\f$ (see \ref LinearSolverGroup). Each step of
      26              :  * the algorithm expects that \f$A(q)\f$ is computed and stored in the DataBox
      27              :  * as `db::add_tag_prefix<LinearSolver::Tags::OperatorAppliedTo, operand_tag>`.
      28              :  * To perform a solve, add the `solve` action list to an array parallel
      29              :  * component. Pass the actions that compute \f$A(q)\f$ as the first template
      30              :  * parameter to `solve`. The second template parameter allows you to pass any
      31              :  * further actions you wish to run in each step of the algorithm (such as
      32              :  * observations). If you add the `solve` action list multiple times, use the
      33              :  * third template parameter to label each solve with a different type.
      34              :  *
      35              :  * This linear solver supports preconditioning. Enable preconditioning by
      36              :  * setting the `Preconditioned` template parameter to `true`. If you do, run a
      37              :  * preconditioner (e.g. another parallel linear solver) in each step. The
      38              :  * preconditioner should approximately solve the linear problem \f$A(q)=b\f$
      39              :  * where \f$q\f$ is the `operand_tag` and \f$b\f$ is the
      40              :  * `preconditioner_source_tag`. Make sure the tag
      41              :  * `db::add_tag_prefix<LinearSolver::Tags::OperatorAppliedTo, operand_tag>`
      42              :  * is updated with the preconditioned result in each step of the algorithm, i.e.
      43              :  * that it is \f$A(q)\f$ where \f$q\f$ is the preconditioner's approximate
      44              :  * solution to \f$A(q)=b\f$. The preconditioner always begins at an initial
      45              :  * guess of zero. It does not need to compute the operator applied to the
      46              :  * initial guess, since it's zero as well due to the linearity of the operator.
      47              :  *
      48              :  * Note that the operand \f$q\f$ for which \f$A(q)\f$ needs to be computed is
      49              :  * not the field \f$x\f$ we are solving for but
      50              :  * `db::add_tag_prefix<LinearSolver::Tags::Operand, FieldsTag>`. This field is
      51              :  * initially set to the residual \f$q_0 = b - A(x_0)\f$ where \f$x_0\f$ is the
      52              :  * initial value of the `FieldsTag`.
      53              :  *
      54              :  * When the algorithm step is performed after the operator action \f$A(q)\f$ has
      55              :  * been computed and stored in the DataBox, the GMRES algorithm implemented here
      56              :  * will converge the field \f$x\f$ towards the solution and update the operand
      57              :  * \f$q\f$ in the process. This requires reductions over all elements that are
      58              :  * received by a `ResidualMonitor` singleton parallel component, processed, and
      59              :  * then broadcast back to all elements. Since the reductions are performed to
      60              :  * find a vector that is orthogonal to those used in previous steps, the number
      61              :  * of reductions increases linearly with iterations. No restarting mechanism is
      62              :  * currently implemented. The actions are implemented in the `gmres::detail`
      63              :  * namespace and constitute the full algorithm in the following order:
      64              :  * 1. `PerformStep` (on elements): Start an Arnoldi orthogonalization by
      65              :  * computing the inner product between \f$A(q)\f$ and the first of the
      66              :  * previously determined set of orthogonal vectors.
      67              :  * 2. `StoreOrthogonalization` (on `ResidualMonitor`): Keep track of the
      68              :  * computed inner product in a Hessenberg matrix, then broadcast.
      69              :  * 3. `OrthogonalizeOperand` (on elements): Proceed with the Arnoldi
      70              :  * orthogonalization by computing inner products and reducing to
      71              :  * `StoreOrthogonalization` on the `ResidualMonitor` until the new orthogonal
      72              :  * vector is constructed. Then compute its magnitude and reduce.
      73              :  * 4. `StoreOrthogonalization` (on `ResidualMonitor`): Perform a QR
      74              :  * decomposition of the Hessenberg matrix to produce a residual vector.
      75              :  * Broadcast to `NormalizeOperandAndUpdateField` along with a termination
      76              :  * flag if the `Convergence::Tags::Criteria` are met.
      77              :  * 5. `NormalizeOperandAndUpdateField` (on elements): Set the operand \f$q\f$ as
      78              :  * the new orthogonal vector and normalize. Use the residual vector and the set
      79              :  * of orthogonal vectors to determine the solution \f$x\f$.
      80              :  *
      81              :  * \par Array sections
      82              :  * This linear solver supports running over a subset of the elements in the
      83              :  * array parallel component (see `Parallel::Section`). Set the
      84              :  * `ArraySectionIdTag` template parameter to restrict the solver to elements in
      85              :  * that section. Only a single section must be associated with the
      86              :  * `ArraySectionIdTag`. The default is `void`, which means running over all
      87              :  * elements in the array. Note that the actions in the `ApplyOperatorActions`
      88              :  * list passed to `solve` will _not_ be restricted to run only on section
      89              :  * elements, so all elements in the array may participate in preconditioning
      90              :  * (see LinearSolver::multigrid::Multigrid).
      91              :  *
      92              :  * \see ConjugateGradient for a linear solver that is more efficient when the
      93              :  * linear operator \f$A\f$ is symmetric.
      94              :  */
      95              : template <typename Metavariables, typename FieldsTag, typename OptionsGroup,
      96              :           bool Preconditioned,
      97              :           typename SourceTag =
      98              :               db::add_tag_prefix<::Tags::FixedSource, FieldsTag>,
      99              :           typename ArraySectionIdTag = void>
     100            1 : struct Gmres {
     101            0 :   using fields_tag = FieldsTag;
     102            0 :   using options_group = OptionsGroup;
     103            0 :   using source_tag = SourceTag;
     104            0 :   static constexpr bool preconditioned = Preconditioned;
     105              : 
     106              :   /// Apply the linear operator to this tag in each iteration
     107            1 :   using operand_tag = std::conditional_t<
     108              :       Preconditioned,
     109              :       db::add_tag_prefix<
     110              :           LinearSolver::Tags::Preconditioned,
     111              :           db::add_tag_prefix<LinearSolver::Tags::Operand, fields_tag>>,
     112              :       db::add_tag_prefix<LinearSolver::Tags::Operand, fields_tag>>;
     113              : 
     114              :   /// Invoke a linear solver on the `operand_tag` sourced by the
     115              :   /// `preconditioner_source_tag` before applying the operator in each step
     116            1 :   using preconditioner_source_tag =
     117              :       db::add_tag_prefix<LinearSolver::Tags::Operand, fields_tag>;
     118              : 
     119              :   /*!
     120              :    * \brief The parallel components used by the GMRES linear solver
     121              :    */
     122            1 :   using component_list = tmpl::list<
     123              :       detail::ResidualMonitor<Metavariables, FieldsTag, OptionsGroup>>;
     124              : 
     125            0 :   using initialize_element =
     126              :       detail::InitializeElement<FieldsTag, OptionsGroup, Preconditioned>;
     127              : 
     128            0 :   using register_element = tmpl::list<>;
     129              : 
     130            0 :   using amr_projectors = initialize_element;
     131              : 
     132              :   template <typename ApplyOperatorActions,
     133              :             typename ObserveActions = tmpl::list<>,
     134              :             typename Label = OptionsGroup>
     135            0 :   using solve = tmpl::list<
     136              :       detail::PrepareSolve<FieldsTag, OptionsGroup, Preconditioned, Label,
     137              :                            SourceTag, ArraySectionIdTag>,
     138              :       ObserveActions,
     139              :       detail::NormalizeInitialOperand<FieldsTag, OptionsGroup, Preconditioned,
     140              :                                       Label, ArraySectionIdTag>,
     141              :       detail::PrepareStep<FieldsTag, OptionsGroup, Preconditioned, Label,
     142              :                           ArraySectionIdTag>,
     143              :       ApplyOperatorActions,
     144              :       detail::PerformStep<FieldsTag, OptionsGroup, Preconditioned, Label,
     145              :                           ArraySectionIdTag>,
     146              :       detail::OrthogonalizeOperand<FieldsTag, OptionsGroup, Preconditioned,
     147              :                                    Label, ArraySectionIdTag>,
     148              :       detail::NormalizeOperandAndUpdateField<
     149              :           FieldsTag, OptionsGroup, Preconditioned, Label, ArraySectionIdTag>,
     150              :       ObserveActions,
     151              :       detail::CompleteStep<FieldsTag, OptionsGroup, Preconditioned, Label,
     152              :                            ArraySectionIdTag>>;
     153              : };
     154              : 
     155              : }  // namespace LinearSolver::gmres
        

Generated by: LCOV version 2.0-1