SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/LinearSolver/ConjugateGradient - ConjugateGradient.hpp Hit Total Coverage
Commit: 9ddc33268b29014a4956c8f0c24ca90b397463e1 Lines: 4 11 36.4 %
Date: 2024-04-26 20:00:04
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/ConjugateGradient/ElementActions.hpp"
       9             : #include "ParallelAlgorithms/LinearSolver/ConjugateGradient/InitializeElement.hpp"
      10             : #include "ParallelAlgorithms/LinearSolver/ConjugateGradient/ResidualMonitor.hpp"
      11             : #include "Utilities/TMPL.hpp"
      12             : 
      13             : /// Items related to the conjugate gradient linear solver
      14             : ///
      15             : /// \see `LinearSolver::cg::ConjugateGradient`
      16           1 : namespace LinearSolver::cg {
      17             : 
      18             : /*!
      19             :  * \ingroup LinearSolverGroup
      20             :  * \brief A conjugate gradient solver for linear systems of equations \f$Ax=b\f$
      21             :  * where the operator \f$A\f$ is symmetric.
      22             :  *
      23             :  * \details The only operation we need to supply to the algorithm is the
      24             :  * result of the operation \f$A(p)\f$ (see \ref LinearSolverGroup) that in the
      25             :  * case of the conjugate gradient algorithm must be symmetric. Each step of the
      26             :  * algorithm expects that \f$A(p)\f$ is computed and stored in the DataBox as
      27             :  * %db::add_tag_prefix<LinearSolver::Tags::OperatorAppliedTo,
      28             :  * db::add_tag_prefix<LinearSolver::Tags::Operand, FieldsTag>>. To perform a
      29             :  * solve, add the `solve` action list to an array parallel component. Pass the
      30             :  * actions that compute \f$A(q)\f$, as well as any further actions you wish to
      31             :  * run in each step of the algorithm, as the first template parameter to
      32             :  * `solve`. If you add the `solve` action list multiple times, use the second
      33             :  * template parameter to label each solve with a different type.
      34             :  *
      35             :  * Note that the operand \f$p\f$ for which \f$A(p)\f$ needs to be computed is
      36             :  * not the field \f$x\f$ we are solving for but
      37             :  * `db::add_tag_prefix<LinearSolver::Tags::Operand, FieldsTag>`. This field is
      38             :  * initially set to the residual \f$r = b - A(x_0)\f$ where \f$x_0\f$ is the
      39             :  * initial value of the `FieldsTag`.
      40             :  *
      41             :  * When the algorithm step is performed after the operator action \f$A(p)\f$ has
      42             :  * been computed and stored in the DataBox, the conjugate gradient algorithm
      43             :  * implemented here will converge the field \f$x\f$ towards the solution and
      44             :  * update the operand \f$p\f$ in the process. This requires two reductions over
      45             :  * all elements that are received by a `ResidualMonitor` singleton parallel
      46             :  * component, processed, and then broadcast back to all elements. The actions
      47             :  * are implemented in the `cg::detail` namespace and constitute the full
      48             :  * algorithm in the following order:
      49             :  * 1. `PerformStep` (on elements): Compute the inner product \f$\langle p,
      50             :  * A(p)\rangle\f$ and reduce.
      51             :  * 2. `ComputeAlpha` (on `ResidualMonitor`): Compute
      52             :  * \f$\alpha=\frac{r^2}{\langle p, A(p)\rangle}\f$ and broadcast.
      53             :  * 3. `UpdateFieldValues` (on elements): Update \f$x\f$ and \f$r\f$, then
      54             :  * compute the inner product \f$\langle r, r\rangle\f$ and reduce to find the
      55             :  * new \f$r^2\f$.
      56             :  * 4. `UpdateResidual` (on `ResidualMonitor`): Store the new \f$r^2\f$ and
      57             :  * broadcast the ratio of the new and old \f$r^2\f$, as well as a termination
      58             :  * flag if the `Convergence::Tags::Criteria` are met.
      59             :  * 5. `UpdateOperand` (on elements): Update \f$p\f$.
      60             :  *
      61             :  * \see Gmres for a linear solver that can invert nonsymmetric operators
      62             :  * \f$A\f$.
      63             :  */
      64             : template <typename Metavariables, typename FieldsTag, typename OptionsGroup,
      65             :           typename SourceTag =
      66             :               db::add_tag_prefix<::Tags::FixedSource, FieldsTag>>
      67           1 : struct ConjugateGradient {
      68           0 :   using fields_tag = FieldsTag;
      69           0 :   using options_group = OptionsGroup;
      70           0 :   using source_tag = SourceTag;
      71             : 
      72             :   /// Apply the linear operator to this tag in each iteration
      73           1 :   using operand_tag =
      74             :       db::add_tag_prefix<LinearSolver::Tags::Operand, fields_tag>;
      75             : 
      76             :   /*!
      77             :    * \brief The parallel components used by the conjugate gradient linear solver
      78             :    */
      79           1 :   using component_list = tmpl::list<
      80             :       detail::ResidualMonitor<Metavariables, FieldsTag, OptionsGroup>>;
      81             : 
      82           0 :   using initialize_element = detail::InitializeElement<FieldsTag, OptionsGroup>;
      83             : 
      84           0 :   using register_element = tmpl::list<>;
      85             : 
      86             :   template <typename ApplyOperatorActions, typename Label = OptionsGroup>
      87           0 :   using solve = tmpl::list<
      88             :       detail::PrepareSolve<FieldsTag, OptionsGroup, Label, SourceTag>,
      89             :       detail::InitializeHasConverged<FieldsTag, OptionsGroup, Label>,
      90             :       ApplyOperatorActions, detail::PerformStep<FieldsTag, OptionsGroup, Label>,
      91             :       detail::UpdateFieldValues<FieldsTag, OptionsGroup, Label>,
      92             :       detail::UpdateOperand<FieldsTag, OptionsGroup, Label>>;
      93             : };
      94             : 
      95             : }  // namespace LinearSolver::cg

Generated by: LCOV version 1.14