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/NonlinearSolver/NewtonRaphson/ElementActions.hpp" 9 : #include "ParallelAlgorithms/NonlinearSolver/NewtonRaphson/ResidualMonitor.hpp" 10 : #include "ParallelAlgorithms/NonlinearSolver/Tags.hpp" 11 : #include "Utilities/TMPL.hpp" 12 : 13 : namespace NonlinearSolver { 14 : /// Items related to the NewtonRaphson nonlinear solver 15 : namespace newton_raphson { 16 : 17 : /*! 18 : * \brief A Newton-Raphson correction scheme for nonlinear systems of equations 19 : * \f$A_\mathrm{nonlinear}(x)=b\f$. 20 : * 21 : * We can use a correction scheme to solve a nonlinear problem 22 : * \f$A_\mathrm{nonlinear}(x)=b\f$ by repeatedly solving a linearization of it. 23 : * A Newton-Raphson scheme iteratively refines an initial guess \f$x_0\f$ by 24 : * repeatedly solving the linearized problem 25 : * 26 : * \f{equation} 27 : * \frac{\delta A_\mathrm{nonlinear}}{\delta x}(x_k) \delta x_k = 28 : * b-A_\mathrm{nonlinear}(x_k) \equiv r_k 29 : * \f} 30 : * 31 : * for the correction \f$\delta x_k\f$ and then updating the solution as 32 : * \f$x_{k+1}=x_k + \delta x_k\f$. 33 : * 34 : * The operations we need to supply to the algorithm are the nonlinear operator 35 : * \f$A_\mathrm{nonlinear}(x)\f$ and a linear solver for the linearized problem 36 : * \f$\frac{\delta A_\mathrm{nonlinear}}{\delta x}(x_k) \delta x_k = r_k\f$. 37 : * Each step of the algorithm expects that \f$A_\mathrm{nonlinear}(x)\f$ is 38 : * computed and stored in the DataBox as 39 : * `db::add_tag_prefix<NonlinearSolver::Tags::OperatorAppliedTo, FieldsTag>`. 40 : * To perform a solve, add the `solve` action list to an array parallel 41 : * component. Pass the actions that compute \f$A_\mathrm{nonlinear}(x)\f$ as 42 : * the first template parameter to `solve`. As the second template parameter, 43 : * pass the action list that performs a linear solve of the linearized operator 44 : * \f$\frac{\delta A_\mathrm{nonlinear}}{\delta x}(x)\f$ for the field 45 : * \f$\delta x\f$ (the `linear_solver_fields_tag`) sourced by 46 : * \f$r\f$ (the `linear_solver_source_tag`). You will find suitable iterative 47 : * linear solvers in the `LinearSolver` namespace. The third template parameter 48 : * allows you to pass any further actions you wish to run in each step of the 49 : * algorithm (such as observations). If you add the `solve` action list multiple 50 : * times, use the fourth template parameter to label each solve with a different 51 : * type. 52 : * 53 : * \par Globalization: 54 : * This nonlinear solver supports a line-search (or "backtracking") 55 : * globalization. If a step does not sufficiently decrease the residual (see 56 : * `NonlinearSolver::OptionTags::SufficientDecrease` for details on the 57 : * sufficient decrease condition), the step length is reduced until the residual 58 : * sufficiently decreases or the maximum number of globalization steps is 59 : * reached. The reduction in step length is determined by the minimum of a 60 : * quadratic (first globalization step) or cubic (subsequent globalization 61 : * steps) polynomial interpolation according to Algorithm A6.1.3 in 62 : * \cite DennisSchnabel (p. 325) (see 63 : * `NonlinearSolver::newton_raphson::next_step_length`). Alternatives to a 64 : * line-search globalization, such as a trust-region globalization or more 65 : * sophisticated nonlinear preconditioning techniques (see e.g. \cite Brune2015 66 : * for an overview), are not currently implemented. 67 : * 68 : * \par Array sections 69 : * This nonlinear solver supports running over a subset of the elements in the 70 : * array parallel component (see `Parallel::Section`). Set the 71 : * `ArraySectionIdTag` template parameter to restrict the solver to elements in 72 : * that section. Only a single section must be associated with the 73 : * `ArraySectionIdTag`. The default is `void`, which means running over all 74 : * elements in the array. Note that the actions in the `SolveLinearization` 75 : * list passed to `solve` will _not_ be restricted to run only on section 76 : * elements, so all elements in the array may participate in preconditioning 77 : * (see LinearSolver::multigrid::Multigrid). 78 : */ 79 : template <typename Metavariables, typename FieldsTag, typename OptionsGroup, 80 : typename SourceTag = 81 : db::add_tag_prefix<::Tags::FixedSource, FieldsTag>, 82 : typename ArraySectionIdTag = void> 83 1 : struct NewtonRaphson { 84 0 : using fields_tag = FieldsTag; 85 0 : using options_group = OptionsGroup; 86 0 : using source_tag = SourceTag; 87 : 88 0 : using operand_tag = fields_tag; 89 0 : using linear_solver_fields_tag = 90 : db::add_tag_prefix<NonlinearSolver::Tags::Correction, fields_tag>; 91 0 : using linear_solver_source_tag = 92 : db::add_tag_prefix<NonlinearSolver::Tags::Residual, fields_tag>; 93 : 94 0 : using component_list = tmpl::list< 95 : detail::ResidualMonitor<Metavariables, FieldsTag, OptionsGroup>>; 96 : 97 0 : using initialize_element = 98 : detail::InitializeElement<FieldsTag, OptionsGroup, SourceTag>; 99 : 100 0 : using register_element = tmpl::list<>; 101 : 102 0 : using amr_projectors = initialize_element; 103 : 104 : template <typename ApplyNonlinearOperator, typename SolveLinearization, 105 : typename ObserveActions = tmpl::list<>, 106 : typename Label = OptionsGroup> 107 0 : using solve = tmpl::list< 108 : detail::PrepareSolve<FieldsTag, OptionsGroup, Label, ArraySectionIdTag>, 109 : ApplyNonlinearOperator, ObserveActions, 110 : detail::SendInitialResidualMagnitude<FieldsTag, OptionsGroup, Label, 111 : ArraySectionIdTag>, 112 : detail::ReceiveInitialHasConverged<FieldsTag, OptionsGroup, Label, 113 : ArraySectionIdTag>, 114 : detail::PrepareStep<FieldsTag, OptionsGroup, Label, ArraySectionIdTag>, 115 : SolveLinearization, 116 : detail::PerformStep<FieldsTag, OptionsGroup, Label, ArraySectionIdTag>, 117 : ApplyNonlinearOperator, 118 : detail::ContributeToResidualMagnitudeReduction<FieldsTag, OptionsGroup, 119 : Label, ArraySectionIdTag>, 120 : detail::Globalize<FieldsTag, OptionsGroup, Label, ArraySectionIdTag>, 121 : ObserveActions, 122 : detail::CompleteStep<FieldsTag, OptionsGroup, Label, ArraySectionIdTag>>; 123 : }; 124 : 125 : } // namespace newton_raphson 126 : } // namespace NonlinearSolver