Line data Source code
1 : /**********************************************************************/ 2 : /* DO NOT MODIFY THIS HEADER */ 3 : /* Swift, a Fourier spectral solver for MOOSE */ 4 : /* */ 5 : /* Copyright 2024 Battelle Energy Alliance, LLC */ 6 : /* ALL RIGHTS RESERVED */ 7 : /**********************************************************************/ 8 : 9 : // MOOSE includes 10 : #include "TensorSolveIterationAdaptiveDT.h" 11 : #include "TensorProblem.h" 12 : #include "IterativeTensorSolverInterface.h" 13 : #include "TensorSolver.h" 14 : 15 : #include <limits> 16 : 17 : registerMooseObject("MooseApp", TensorSolveIterationAdaptiveDT); 18 : 19 : InputParameters 20 0 : TensorSolveIterationAdaptiveDT::validParams() 21 : { 22 0 : InputParameters params = TimeStepper::validParams(); 23 0 : params.addClassDescription( 24 : "Adjust the timestep based on the number of internal TensorSolve iterations"); 25 0 : params.addParam<unsigned int>( 26 : "min_iterations", 27 : "If the solve takes less than 'min_iterations', dt is increased by 'growth_factor'"); 28 0 : params.addParam<unsigned int>( 29 : "max_iterations", 30 : "If the solve takes more than 'max_iterations', dt is decreased by 'cutback_factor'"); 31 : 32 0 : params.addParam<std::vector<PostprocessorName>>("timestep_limiting_postprocessor", {}, 33 : "If specified, a list of postprocessor values " 34 : "used as an upper limit for the " 35 : "current time step length"); 36 0 : params.addRequiredParam<Real>("dt", "The default timestep size between solves"); 37 0 : params.addParam<Real>("growth_factor", 38 0 : 2.0, 39 : "Factor to apply to timestep if easy convergence or if recovering " 40 : "from failed solve"); 41 0 : params.addParam<Real>("cutback_factor", 42 0 : 0.5, 43 : "Factor to apply to timestep if difficult convergence " 44 : "occurs. " 45 : "For failed solves, use cutback_factor_at_failure"); 46 : 47 0 : params.declareControllable("growth_factor cutback_factor"); 48 : 49 0 : return params; 50 0 : } 51 : 52 0 : TensorSolveIterationAdaptiveDT::TensorSolveIterationAdaptiveDT(const InputParameters & parameters) 53 : : TimeStepper(parameters), 54 : PostprocessorInterface(this), 55 0 : _dt_old(declareRestartableData<Real>("dt_old", 0.0)), 56 0 : _input_dt(getParam<Real>("dt")), 57 0 : _min_iterations(getParam<unsigned int>("min_iterations")), 58 0 : _max_iterations(getParam<unsigned int>("max_iterations")), 59 0 : _growth_factor(getParam<Real>("growth_factor")), 60 0 : _cutback_factor(getParam<Real>("cutback_factor")), 61 0 : _cutback_occurred(declareRestartableData<bool>("cutback_occurred", false)), 62 0 : _tensor_problem(TensorProblem::cast(this, _fe_problem)) 63 : { 64 0 : for (const auto & name : 65 0 : getParam<std::vector<PostprocessorName>>("timestep_limiting_postprocessor")) 66 0 : _pps_value.push_back(&getPostprocessorValueByName(name)); 67 0 : } 68 : 69 : Real 70 0 : TensorSolveIterationAdaptiveDT::computeInitialDT() 71 : { 72 0 : return _input_dt; 73 : } 74 : 75 : Real 76 0 : TensorSolveIterationAdaptiveDT::computeDT() 77 : { 78 0 : Real dt = _dt_old; 79 : 80 0 : if (_cutback_occurred) 81 : { 82 0 : _cutback_occurred = false; 83 : 84 : // Don't allow it to grow this step, but shrink if needed 85 0 : computeAdaptiveDT(dt, /* allowToGrow = */ false); 86 : } 87 : else 88 0 : computeAdaptiveDT(dt); 89 : 90 0 : return dt; 91 : } 92 : 93 : bool 94 0 : TensorSolveIterationAdaptiveDT::constrainStep(Real & dt) 95 : { 96 0 : bool at_sync_point = TimeStepper::constrainStep(dt); 97 : 98 : // Limit the timestep to postprocessor value 99 0 : limitDTToPostprocessorValue(dt); 100 : 101 0 : return at_sync_point; 102 : } 103 : 104 : bool 105 0 : TensorSolveIterationAdaptiveDT::converged() const 106 : { 107 0 : const auto & iterative_solver = _tensor_problem.getSolver<IterativeTensorSolverInterface>(); 108 0 : return iterative_solver.isConverged(); 109 : } 110 : 111 : Real 112 0 : TensorSolveIterationAdaptiveDT::computeFailedDT() 113 : { 114 0 : _cutback_occurred = true; 115 : 116 : // Can't cut back any more 117 0 : if (_dt <= _dt_min) 118 0 : mooseError("Solve failed and timestep already at dtmin, cannot continue!"); 119 : 120 0 : if (_verbose) 121 : { 122 0 : _console << "\nSolve failed with dt: " << std::setw(9) << _dt 123 0 : << "\nRetrying with reduced dt: " << std::setw(9) << _dt * _cutback_factor_at_failure 124 0 : << std::endl; 125 : } 126 : else 127 0 : _console << "\nSolve failed, cutting timestep." << std::endl; 128 : 129 0 : return _dt * _cutback_factor_at_failure; 130 : } 131 : 132 : void 133 0 : TensorSolveIterationAdaptiveDT::limitDTToPostprocessorValue(Real & limitedDT) const 134 : { 135 0 : if (_pps_value.empty() || _t_step <= 1) 136 0 : return; 137 : 138 0 : Real limiting_pps_value = *_pps_value[0]; 139 : unsigned int i_min = 0; 140 0 : for (const auto i : index_range(_pps_value)) 141 0 : if (*_pps_value[i] < limiting_pps_value) 142 : { 143 0 : limiting_pps_value = *_pps_value[i]; 144 0 : i_min = i; 145 : } 146 : 147 0 : if (limitedDT > limiting_pps_value) 148 : { 149 0 : if (limiting_pps_value < 0) 150 0 : mooseWarning( 151 0 : "Negative timestep limiting postprocessor '" + 152 0 : getParam<std::vector<PostprocessorName>>("timestep_limiting_postprocessor")[i_min] + 153 0 : "': " + std::to_string(limiting_pps_value)); 154 0 : limitedDT = std::max(_dt_min, limiting_pps_value); 155 : 156 0 : if (_verbose) 157 0 : _console << "Limiting dt to postprocessor value. dt = " << limitedDT << std::endl; 158 : } 159 : } 160 : 161 : void 162 0 : TensorSolveIterationAdaptiveDT::computeAdaptiveDT(Real & dt, bool allowToGrow, bool allowToShrink) 163 : { 164 0 : const auto & iterative_solver = _tensor_problem.getSolver<IterativeTensorSolverInterface>(); 165 0 : const auto previous_iterations = iterative_solver.getIterations(); 166 : 167 0 : if (allowToGrow && previous_iterations < _min_iterations) 168 : // Grow the timestep 169 0 : dt *= _growth_factor; 170 0 : else if (allowToShrink && previous_iterations > _max_iterations) 171 : // Shrink the timestep 172 0 : dt *= _cutback_factor; 173 0 : } 174 : 175 : void 176 0 : TensorSolveIterationAdaptiveDT::acceptStep() 177 : { 178 0 : TimeStepper::acceptStep(); 179 0 : _dt_old = _dt; 180 0 : } 181 :