SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/NonlinearSolver - Tags.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 22.6 % 62 14
Test Date: 2026-10-22 17:29:42
Legend: Lines:     hit not hit

            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              : 
      12              : #include "DataStructures/DataBox/PrefixHelpers.hpp"
      13              : #include "DataStructures/DataBox/Tag.hpp"
      14              : #include "Options/String.hpp"
      15              : #include "Utilities/Gsl.hpp"
      16              : #include "Utilities/PrettyType.hpp"
      17              : 
      18              : /// Functionality for solving nonlinear systems of equations
      19              : namespace NonlinearSolver {
      20              : 
      21              : /// Options related to nonlinear solvers
      22            1 : namespace OptionTags {
      23              : 
      24              : /*!
      25              :  * \brief Sufficient decrease parameter of the line search globalization
      26              :  *
      27              :  * The sufficient decrease parameter is the acceptable decrease of the residual
      28              :  * magnitude in each step of the nonlinear solver. It is measured as a fraction
      29              :  * of the predicted decrease in residual magnitude if the problem was linear.
      30              :  * For example, a sufficient decrease parameter of 1 means that a nonlinear
      31              :  * solver step is expected to decrease the residual exactly as expected for a
      32              :  * linear problem, i.e. immediately to zero. A sufficient decrease parameter of
      33              :  * 0.5 means that decreasing the residual by half of that amount in each
      34              :  * nonlinear solver step is acceptable.
      35              :  *
      36              :  * Nonlinear solver steps that fail the sufficient decrease condition (also
      37              :  * known as _Armijo condition_) undergo a globalization procedure such as a line
      38              :  * search.
      39              :  *
      40              :  * A typical value for the sufficient decrease parameter is \f$10^{-4}\f$. Set
      41              :  * to values closer to unity when the nonlinear solver overshoots, e.g. when the
      42              :  * initial guess is particularly bad. Larger values mean the nonlinear solver is
      43              :  * stricter with accepting steps, preferring to apply the globalization
      44              :  * strategy.
      45              :  */
      46              : template <typename OptionsGroup>
      47            1 : struct SufficientDecrease {
      48            0 :   using type = double;
      49            0 :   static constexpr Options::String help = {
      50              :       "Fraction of decrease predicted by linearization"};
      51            0 :   static type lower_bound() { return 0.; }
      52            0 :   static type upper_bound() { return 1.; }
      53            0 :   static type suggested_value() { return 1.e-4; }
      54            0 :   using group = OptionsGroup;
      55              : };
      56              : 
      57              : /*!
      58              :  * \brief Nonlinear solver steps are damped by this factor
      59              :  *
      60              :  * Instead of attempting to take full-length steps when correcting the solution
      61              :  * in each nonlinear solver step (see `NonlinearSolver::Tags::Correction`),
      62              :  * reduce the step length by this factor. This damping occurs before any
      63              :  * globalization steps that may further reduce the step length.
      64              :  */
      65              : template <typename OptionsGroup>
      66            1 : struct DampingFactor {
      67            0 :   using type = double;
      68            0 :   static constexpr Options::String help = {
      69              :       "Multiply corrections by this factor"};
      70            0 :   static type lower_bound() { return 0.; }
      71            0 :   static type upper_bound() { return 1.; }
      72            0 :   static type suggested_value() { return 1.; }
      73            0 :   using group = OptionsGroup;
      74              : };
      75              : 
      76              : /*!
      77              :  * \brief The maximum number of allowed globalization steps
      78              :  *
      79              :  * Nonlinear solves of well-posed problems should never hit this limit because
      80              :  * the step size shrinks and eventually triggers the sufficient-decrease
      81              :  * condition (see `NonlinearSolver::OptionTags::SufficientDecrease`). So the
      82              :  * suggested value just provides a safety-net to prevent the globalization
      83              :  * from running forever when the problem is ill-posed.
      84              :  */
      85              : template <typename OptionsGroup>
      86            1 : struct MaxGlobalizationSteps {
      87            0 :   using type = size_t;
      88            0 :   static constexpr Options::String help = {
      89              :       "Maximum number of globalization steps"};
      90            0 :   static type suggested_value() { return 40; }
      91            0 :   using group = OptionsGroup;
      92              : };
      93              : 
      94              : }  // namespace OptionTags
      95              : 
      96            0 : namespace Tags {
      97              : 
      98              : /*!
      99              :  * \brief The correction \f$\delta x\f$ to improve a solution \f$x_0\f$
     100              :  *
     101              :  * A linear problem \f$Ax=b\f$ can be equivalently formulated as the problem
     102              :  * \f$A\delta x=b-A x_0\f$ for the correction \f$\delta x\f$ to an initial guess
     103              :  * \f$x_0\f$. More importantly, we can use a correction scheme to solve a
     104              :  * nonlinear problem \f$A_\mathrm{nonlinear}(x)=b\f$ by repeatedly solving a
     105              :  * linearization of it. For instance, a Newton-Raphson scheme iteratively
     106              :  * refines an initial guess \f$x_0\f$ by repeatedly solving the linearized
     107              :  * problem
     108              :  *
     109              :  * \f{equation}
     110              :  * \frac{\delta A_\mathrm{nonlinear}}{\delta x}(x_k)\delta x_k =
     111              :  * b-A_\mathrm{nonlinear}(x_k)
     112              :  * \f}
     113              :  *
     114              :  * for the correction \f$\delta x_k\f$ and then updating the solution as
     115              :  * \f$x_{k+1}=x_k + \delta x_k\f$.
     116              :  */
     117              : template <typename Tag>
     118            1 : struct Correction : db::PrefixTag, db::SimpleTag {
     119            0 :   using type = typename Tag::type;
     120            0 :   using tag = Tag;
     121              : };
     122              : 
     123              : /*!
     124              :  * \brief The nonlinear operator \f$A_\mathrm{nonlinear}\f$ applied to the data
     125              :  * in `Tag`
     126              :  */
     127              : template <typename Tag>
     128            1 : struct OperatorAppliedTo : db::PrefixTag, db::SimpleTag {
     129            0 :   static std::string name() {
     130              :     // Add "Nonlinear" prefix to abbreviate the namespace for uniqueness
     131              :     return "NonlinearOperatorAppliedTo(" + db::tag_name<Tag>() + ")";
     132              :   }
     133            0 :   using type = typename Tag::type;
     134            0 :   using tag = Tag;
     135              : };
     136              : 
     137              : /*!
     138              :  * \brief The nonlinear residual
     139              :  * \f$r_\mathrm{nonlinear} = b - A_\mathrm{nonlinear}(\delta x)\f$
     140              :  */
     141              : template <typename Tag>
     142            1 : struct Residual : db::PrefixTag, db::SimpleTag {
     143            0 :   static std::string name() {
     144              :     // Add "Nonlinear" prefix to abbreviate the namespace for uniqueness
     145              :     return "NonlinearResidual(" + db::tag_name<Tag>() + ")";
     146              :   }
     147            0 :   using type = typename Tag::type;
     148            0 :   using tag = Tag;
     149              : };
     150              : 
     151              : /// Compute the residual \f$r=b - Ax\f$ from the `SourceTag` \f$b\f$ and the
     152              : /// `db::add_tag_prefix<NonlinearSolver::Tags::OperatorAppliedTo, FieldsTag>`
     153              : /// \f$Ax\f$.
     154              : template <typename FieldsTag, typename SourceTag>
     155            1 : struct ResidualCompute : db::add_tag_prefix<Residual, FieldsTag>,
     156              :                          db::ComputeTag {
     157            0 :   using base = db::add_tag_prefix<Residual, FieldsTag>;
     158            0 :   using argument_tags =
     159              :       tmpl::list<SourceTag, db::add_tag_prefix<OperatorAppliedTo, FieldsTag>>;
     160            0 :   using return_type = typename base::type;
     161            0 :   static void function(
     162              :       const gsl::not_null<return_type*> residual,
     163              :       const typename SourceTag::type& source,
     164              :       const typename db::add_tag_prefix<OperatorAppliedTo, FieldsTag>::type&
     165              :           operator_applied_to_fields) {
     166              :     *residual = source - operator_applied_to_fields;
     167              :   }
     168              : };
     169              : 
     170              : /*!
     171              :  * \brief The length of nonlinear solver steps
     172              :  *
     173              :  * Instead of taking full-length nonlinear solver steps when correcting the
     174              :  * solution as detailed in `NonlinearSolver::Tags::Correction`, the correction
     175              :  * is multiplied by this step length.
     176              :  *
     177              :  * The `NonlinearSolver::Tags::DampingFactor` multiplies the initial length of
     178              :  * each step such that the nonlinear solver never takes full-length steps if the
     179              :  * damping factor is below one. The step length can be further reduced by the
     180              :  * globalization procedure. See `NonlinearSolver::NewtonRaphson` for details.
     181              :  */
     182              : template <typename OptionsGroup>
     183            1 : struct StepLength : db::SimpleTag {
     184            0 :   static std::string name() {
     185              :     return "StepLength(" + pretty_type::name<OptionsGroup>() + ")";
     186              :   }
     187            0 :   using type = double;
     188              : };
     189              : 
     190              : /*!
     191              :  * \brief Sufficient decrease parameter of the line search globalization
     192              :  *
     193              :  * \see `NonlinearSolver::OptionTags::SufficientDecrease`
     194              :  */
     195              : template <typename OptionsGroup>
     196            1 : struct SufficientDecrease : db::SimpleTag {
     197            0 :   static std::string name() {
     198              :     return "SufficientDecrease(" + pretty_type::name<OptionsGroup>() + ")";
     199              :   }
     200            0 :   using type = double;
     201            0 :   static constexpr bool pass_metavariables = false;
     202            0 :   using option_tags = tmpl::list<OptionTags::SufficientDecrease<OptionsGroup>>;
     203            0 :   static type create_from_options(const type& option) { return option; }
     204              : };
     205              : 
     206              : /*!
     207              :  * \brief Nonlinear solver steps are damped by this factor
     208              :  *
     209              :  * \see `NonlinearSolver::OptionTags::DampingFactor`
     210              :  */
     211              : template <typename OptionsGroup>
     212            1 : struct DampingFactor : db::SimpleTag {
     213            0 :   static std::string name() {
     214              :     return "DampingFactor(" + pretty_type::name<OptionsGroup>() + ")";
     215              :   }
     216            0 :   using type = double;
     217            0 :   static constexpr bool pass_metavariables = false;
     218            0 :   using option_tags = tmpl::list<OptionTags::DampingFactor<OptionsGroup>>;
     219            0 :   static type create_from_options(const type& option) { return option; }
     220              : };
     221              : 
     222              : /*!
     223              :  * \brief The maximum number of allowed globalization steps
     224              :  *
     225              :  * \see `NonlinearSolver::OptionTags::MinStepLength`
     226              :  */
     227              : template <typename OptionsGroup>
     228            1 : struct MaxGlobalizationSteps : db::SimpleTag {
     229            0 :   static std::string name() {
     230              :     return "MaxGlobalizationSteps(" + pretty_type::name<OptionsGroup>() + ")";
     231              :   }
     232            0 :   using type = size_t;
     233            0 :   static constexpr bool pass_metavariables = false;
     234            0 :   using option_tags =
     235              :       tmpl::list<OptionTags::MaxGlobalizationSteps<OptionsGroup>>;
     236            0 :   static type create_from_options(const type& option) { return option; }
     237              : };
     238              : 
     239              : /// Prefix indicating the `Tag` is related to the globalization procedure
     240              : template <typename Tag>
     241            1 : struct Globalization : db::PrefixTag, db::SimpleTag {
     242            0 :   using type = typename Tag::type;
     243            0 :   using tag = Tag;
     244              : };
     245              : 
     246              : }  // namespace Tags
     247              : }  // namespace NonlinearSolver
        

Generated by: LCOV version 2.0-1