Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include "SolveObject.h" 13 : 14 : // System includes 15 : #include <string> 16 : 17 : class FixedPointSolve : public SolveObject 18 : { 19 : public: 20 : FixedPointSolve(Executioner & ex); 21 : 22 58115 : virtual ~FixedPointSolve() = default; 23 : 24 : static InputParameters fixedPointDefaultConvergenceParams(); 25 : static InputParameters validParams(); 26 : 27 : virtual void initialSetup() override; 28 : 29 : /** 30 : * Iteratively solves the FEProblem. 31 : * @return True if solver is converged. 32 : */ 33 : virtual bool solve() override; 34 : 35 : /// Enumeration for fixed point convergence reasons 36 : enum class MooseFixedPointConvergenceReason 37 : { 38 : UNSOLVED = 0, /// Not solved yet 39 : CONVERGED_NONLINEAR = 1, /// Main app nonlinear solve converged, FP unassessed 40 : CONVERGED_ABS = 2, /// FP converged by absolute residual tolerance 41 : CONVERGED_RELATIVE = 3, /// FP converged by relative residual tolerance 42 : CONVERGED_PP = 4, /// FP converged by absolute or relative PP tolerance 43 : REACH_MAX_ITS = 5, /// FP converged by hitting max iterations and accepting 44 : CONVERGED_OBJECT = 6, /// FP converged according to Convergence object 45 : DIVERGED_MAX_ITS = -1, /// FP diverged by hitting max iterations 46 : DIVERGED_NONLINEAR = -2, /// Main app nonlinear solve diverged 47 : DIVERGED_FAILED_MULTIAPP = -3, /// Multiapp solve diverged 48 : DIVERGED_OBJECT = -4 /// FP diverged according to Convergence object 49 : }; 50 : 51 : /** 52 : * Get the number of fixed point iterations performed 53 : * Because this returns the number of fixed point iterations, rather than the current 54 : * iteration count (which starts at 0), increment by 1. 55 : * 56 : * @return Number of fixed point iterations performed 57 : */ 58 88222 : unsigned int numFixedPointIts() const { return _fixed_point_it + 1; } 59 : 60 : /// Deprecated getter for the number of fixed point iterations 61 : unsigned int numPicardIts() const 62 : { 63 : mooseDeprecated("numPicards() is deprecated. Please use numFixedPointIts() instead."); 64 : 65 : return _fixed_point_it + 1; 66 : } 67 : 68 : /// Check the solver status 69 : MooseFixedPointConvergenceReason checkConvergence() const { return _fixed_point_status; } 70 : 71 : /// This function checks the _xfem_repeat_step flag set by solve. 72 234401 : bool XFEMRepeatStep() const { return _xfem_repeat_step; } 73 : 74 : /// Set fixed point status 75 11111 : void setFixedPointStatus(MooseFixedPointConvergenceReason status) 76 : { 77 11111 : _fixed_point_status = status; 78 11111 : } 79 : 80 : /// Clear fixed point status 81 802 : void clearFixedPointStatus() { _fixed_point_status = MooseFixedPointConvergenceReason::UNSOLVED; } 82 : 83 : /// Whether or not this has fixed point iterations 84 : bool hasFixedPointIteration() { return _has_fixed_point_its; } 85 : 86 : /// Set relaxation factor for the current solve as a SubApp 87 : void setMultiAppRelaxationFactor(Real factor) { _secondary_relaxation_factor = factor; } 88 : 89 : /// Set relaxation variables for the current solve as a SubApp 90 : void setMultiAppTransformedVariables(const std::vector<std::string> & vars) 91 : { 92 : _secondary_transformed_variables = vars; 93 : } 94 : 95 : /// Set relaxation postprocessors for the current solve as a SubApp 96 0 : virtual void setMultiAppTransformedPostprocessors(const std::vector<PostprocessorName> & pps) 97 : { 98 0 : _secondary_transformed_pps = pps; 99 0 : } 100 : 101 : /** 102 : * Allocate storage for the fixed point algorithm. 103 : * This creates the system vector of old (older, pre/post solve) variable values and the 104 : * array of old (older, pre/post solve) postprocessor values. 105 : * 106 : * @param primary Whether this routine is to allocate storage for the primary transformed 107 : * quantities (as main app) or the secondary ones (as a subapp) 108 : */ 109 : virtual void allocateStorage(const bool primary) = 0; 110 : 111 : /// Whether sub-applications are automatically advanced no matter what happens during their solves 112 : bool autoAdvance() const; 113 : 114 : /// Mark the current solve as failed due to external conditions 115 95 : void failStep() { _fail_step = true; } 116 : 117 : /// Print the convergence history of the coupling, at every fixed point iteration 118 : virtual void 119 : printFixedPointConvergenceHistory(Real initial_norm, 120 : const std::vector<Real> & timestep_begin_norms, 121 : const std::vector<Real> & timestep_end_norms) const = 0; 122 : 123 : /// Add to the list of systems that should keep their previous fixed point solutions 124 : void copyPreviousFixedPointSolutionForSystem(SystemBase * sys) 125 : { 126 : _systems_to_copy_previous_solutions_for.insert(sys); 127 : } 128 : 129 : protected: 130 : /** 131 : * Returns true if there is relaxation. 132 : * 133 : * @param primary True if this is the parent app; false if this is a child app. 134 : */ 135 : bool performingRelaxation(const bool primary) const; 136 : 137 : /** 138 : * Saves the current values of the variables, and update the old(er) vectors. 139 : * 140 : * @param primary Whether this routine is to save the variables for the primary transformed 141 : * quantities (as main app) or the secondary ones (as a subapp) 142 : */ 143 : virtual void saveVariableValues(const bool primary) = 0; 144 : 145 : /** 146 : * Saves the current values of the postprocessors, and update the old(er) vectors. 147 : * 148 : * @param primary Whether this routine is to save the variables for the primary transformed 149 : * quantities (as main app) or the secondary ones (as a subapp) 150 : */ 151 : virtual void savePostprocessorValues(const bool primary) = 0; 152 : 153 : /** 154 : * Use the fixed point algorithm transform instead of simply using the Picard update 155 : * This routine can be used to alternate Picard iterations and fixed point algorithm 156 : * updates based on the values of the variables before and after a solve / a Picard iteration. 157 : * 158 : * @param primary Whether this routine is used for the primary transformed 159 : * quantities (as main app) or the secondary ones (as a subapp) 160 : */ 161 : virtual bool useFixedPointAlgorithmUpdateInsteadOfPicard(const bool primary) = 0; 162 : 163 : /** 164 : * Perform one fixed point iteration or a full solve. 165 : * 166 : * @param transformed_dofs DoFs targetted by the fixed point algorithm 167 : * 168 : * @return True if both nonlinear solve and the execution of multiapps are successful. 169 : * 170 : * Note: this function also set _xfem_repeat_step flag for XFEM. It tracks _xfem_update_count 171 : * state. 172 : * FIXME: The proper design will be to let XFEM use Picard iteration to control the execution. 173 : */ 174 : virtual bool solveStep(const std::set<dof_id_type> & transformed_dofs); 175 : 176 : /// Save both the variable and postprocessor values 177 : virtual void saveAllValues(const bool primary); 178 : 179 : /** 180 : * Use the fixed point algorithm to transform the postprocessors. 181 : * If this routine is not called, the next value of the postprocessors will just be from 182 : * the unrelaxed Picard fixed point algorithm. 183 : * 184 : * @param primary Whether this routine is to save the variables for the primary transformed 185 : * quantities (as main app) or the secondary ones (as a subapp) 186 : */ 187 : virtual void transformPostprocessors(const bool primary) = 0; 188 : 189 : /** 190 : * Use the fixed point algorithm to transform the variables. 191 : * If this routine is not called, the next value of the variables will just be from 192 : * the unrelaxed Picard fixed point algorithm. 193 : * 194 : * @param transformed_dofs The dofs that will be affected by the algorithm 195 : * @param primary Whether this routine is to save the variables for the primary transformed 196 : * quantities (as main app) or the secondary ones (as a subapp) 197 : */ 198 : virtual void transformVariables(const std::set<dof_id_type> & transformed_dofs, 199 : const bool primary) = 0; 200 : 201 : /// Examine the various convergence metrics 202 : bool examineFixedPointConvergence(bool & converged); 203 : 204 : /// Print information about the fixed point convergence 205 : void printFixedPointConvergenceReason(); 206 : 207 : /// Find the system holding the variables to be transformed (accelerated or relaxed) 208 : /// @param primary whether we are looking at transformations as the parent or child app 209 : void findTransformedSystem(const bool primary); 210 : 211 : /// Whether or not we activate fixed point iteration 212 : const bool _has_fixed_point_its; 213 : 214 : /// Relaxation factor for fixed point Iteration 215 : const Real _relax_factor; 216 : /// The variables (transferred or not) that are going to be relaxed 217 : std::vector<std::string> _transformed_vars; // TODO: make const once relaxed_variables is removed 218 : /// The postprocessors (transferred or not) that are going to be relaxed 219 : const std::vector<PostprocessorName> _transformed_pps; 220 : /// Previous values of the relaxed postprocessors 221 : std::vector<std::vector<PostprocessorValue>> _transformed_pps_values; 222 : /// System holding the transformed variables 223 : SystemBase * _transformed_sys; 224 : /// All the systems that should save their previous solutions 225 : std::set<SystemBase *> _systems_to_copy_previous_solutions_for; 226 : 227 : /// Relaxation factor outside of fixed point iteration (used as a subapp) 228 : Real _secondary_relaxation_factor; 229 : /// Variables to be relaxed outside of fixed point iteration (used as a subapp) 230 : std::vector<std::string> _secondary_transformed_variables; 231 : /// Postprocessors to be relaxed outside of fixed point iteration (used as a subapp) 232 : std::vector<PostprocessorName> _secondary_transformed_pps; 233 : /// Previous values of the postprocessors relaxed outside of the fixed point iteration (used as a subapp) 234 : std::vector<std::vector<PostprocessorValue>> _secondary_transformed_pps_values; 235 : 236 : ///@{ Variables used by the fixed point iteration 237 : /// fixed point iteration counter 238 : unsigned int _fixed_point_it; 239 : /// fixed point iteration counter for the main app 240 : unsigned int _main_fixed_point_it; 241 : /// Status of fixed point solve 242 : MooseFixedPointConvergenceReason _fixed_point_status; 243 : ///@} 244 : private: 245 : /// Maximum number of xfem updates per step 246 : const unsigned int _max_xfem_update; 247 : /// Controls whether xfem should update the mesh at the beginning of the time step 248 : const bool _update_xfem_at_timestep_begin; 249 : 250 : /// Counter for number of xfem updates that have been performed in the current step 251 : unsigned int _xfem_update_count; 252 : /// Whether step should be repeated due to xfem modifying the mesh 253 : bool _xfem_repeat_step; 254 : 255 : /// Time of previous fixed point solve as a subapp 256 : Real _old_entering_time; 257 : 258 : /// force the current step to fail, triggering are repeat with a cut dt 259 : bool _fail_step; 260 : 261 : /// Whether the user has set the auto_advance parameter for handling advancement of 262 : /// sub-applications in multi-app contexts 263 : const bool _auto_advance_set_by_user; 264 : 265 : /// The value of auto_advance set by the user for handling advancement of sub-applications in 266 : /// multi-app contexts 267 : const bool _auto_advance_user_value; 268 : };