https://mooseframework.inl.gov
PseudoTimestep.C
Go to the documentation of this file.
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 #include "PseudoTimestep.h"
11 #include "FEProblemBase.h"
12 #include "NonlinearSystemBase.h"
13 #include "MathUtils.h"
14 #include "TransientBase.h"
15 #include "Restartable.h"
16 #include "libmesh/enum_norm_type.h"
17 
19 
22 {
24 
26  MooseEnum method("SER RDM EXP", "SER");
27 
28  method.addDocumentation("SER", "Switched evolution relaxation");
29  method.addDocumentation("EXP", "Exponential progression");
30  method.addDocumentation("RDM", "Residual difference method");
31 
33  "method", method, "The method used for pseudotimestep timemarching");
34  params.addRequiredRangeCheckedParam<Real>("initial_dt", "initial_dt > 0", "Initial timestep");
36  "alpha", "alpha > 0", "The parameter alpha used in the scaling of the timestep");
37  params.addParam<Real>("max_dt", "The largest timestep allowed");
38  params.addParam<unsigned int>(
39  "iterations_window",
40  "For how many iterations should the residual be tracked (only applies to the SER method)");
41  // Because this post-processor is meant to be used with PostprocessorDT, it
42  // should be executed on initial (not included by default) and timestep end.
43  params.set<ExecFlagEnum>("execute_on") = {EXEC_TIMESTEP_END, EXEC_INITIAL};
44  params.suppressParameter<ExecFlagEnum>("execute_on");
45 
46  params.addClassDescription("Computes pseudo-time steps for obtaining steady-state solutions "
47  "through a pseudo transient process.");
48 
49  return params;
50 }
51 
53  : GeneralPostprocessor(parameters),
54  _method(getParam<MooseEnum>("method").getEnum<PseudotimeMethod>()),
55  _initial_dt(getParam<Real>("initial_dt")),
56  _alpha(getParam<Real>("alpha")),
57  _bound(isParamValid("max_dt")),
58  _max_dt(_bound ? getParam<Real>("max_dt") : std::numeric_limits<Real>::max()),
59  _residual_norms_sequence(declareRestartableData<std::vector<Real>>("residual_norms_sequence")),
60  _iterations_step_sequence(declareRestartableData<std::vector<Real>>("iterations_step_sequence"))
61 {
62  if (!_fe_problem.isTransient())
63  mooseError("This pseudotimestepper can only be used if the steady state is computed via time "
64  "integration.");
65 
67  {
68  if (parameters.isParamValid("iterations_window"))
69  _iterations_window = getParam<unsigned int>("iterations_window");
70  else
72  }
73  else if (parameters.isParamValid("iterations_window"))
74  mooseError("The iterations window can be only provided for the SER method.");
75 }
76 
77 void
79 {
80  // start with the max
82 }
83 
84 Real
86 {
87  return _dt;
88 }
89 
90 Real
92 {
94  Real res_norm = 0.0;
95  for (const auto var_num : make_range(nl.system().n_vars()))
96  {
97  auto var_res =
99  res_norm = res_norm + std::pow(var_res, 2);
100  }
101  res_norm = std::sqrt(res_norm);
102  return res_norm;
103 }
104 
105 void
107 {
108  unsigned int curr_step = _fe_problem.timeStep();
109  Real step_dt = _fe_problem.dt();
110 
111  unsigned int res_size = _residual_norms_sequence.size();
112 
113  _console << "Current step " << curr_step << " and current dt " << step_dt
114  << " for steady state residual " << _residual_norms_sequence[res_size - 1]
115  << " at time " << curr_time << std::endl;
116 }
117 
118 Real
120 {
121  const unsigned int curr_step = _fe_problem.timeStep();
122 
123  const unsigned int steps_size = _iterations_step_sequence.size();
124  const unsigned int res_size = _residual_norms_sequence.size();
125  const unsigned int prev_steps = std::min(_iterations_window + 1, curr_step);
126 
127  const Real factor = std::pow(_residual_norms_sequence[res_size - prev_steps] /
128  _residual_norms_sequence[res_size - 1],
129  _alpha);
130 
131  const Real update_dt = _iterations_step_sequence[steps_size - 1] * factor;
132  return update_dt;
133 }
134 
135 Real
137 {
138  const unsigned int res_size = _residual_norms_sequence.size();
139  const unsigned int steps_size = _iterations_step_sequence.size();
140 
141  Real exponent = 0.0;
142 
143  if (_residual_norms_sequence[res_size - 1] < _residual_norms_sequence[res_size - 2])
144  exponent = (_residual_norms_sequence[res_size - 2] - _residual_norms_sequence[res_size - 1]) /
145  _residual_norms_sequence[res_size - 2];
146  const Real update_dt = _iterations_step_sequence[steps_size - 1] * std::pow(_alpha, exponent);
147  return update_dt;
148 }
149 
150 Real
152 {
153  const Real factor = MathUtils::pow(_alpha, _fe_problem.timeStep() - 1);
154 
155  const Real update_dt = _initial_dt * factor;
156  return update_dt;
157 }
158 
159 void
161 {
162  TransientBase * transient = dynamic_cast<TransientBase *>(_app.getExecutioner());
163 
164  Real res_norm;
165  Real curr_dt;
166  Real update_dt;
167 
169  _dt = _initial_dt;
170 
171  // at the end of each timestep call the postprocessor to set values for dt
173  {
174  // This is all in case a timestep fails and needs to be re-done
175  // Otherwise this is a simply a push_back operation for the vectors
176  mooseAssert(_fe_problem.timeStep() >= 1, "Should at least be on the first time step.");
177  const std::size_t curr_step = _fe_problem.timeStep();
178  mooseAssert(_residual_norms_sequence.size() <= curr_step &&
179  curr_step - _residual_norms_sequence.size() <= 1,
180  "Vector is improper length.");
181  mooseAssert(_residual_norms_sequence.size() == _iterations_step_sequence.size(),
182  "Vectors should be same length.");
183  _residual_norms_sequence.resize(curr_step);
184  _iterations_step_sequence.resize(curr_step);
185 
186  res_norm = currentResidualNorm();
187  _residual_norms_sequence[curr_step - 1] = res_norm;
188 
189  curr_dt = transient->getDT();
190  _iterations_step_sequence[curr_step - 1] = curr_dt;
191 
192  _dt = curr_dt;
193 
194  // since some of the residual methods require previous residuals the pseudo timesteppers
195  // start at the second step in the computation
196  if (_fe_problem.timeStep() > 1)
197  {
198  update_dt = curr_dt;
199  switch (_method)
200  {
202  update_dt = timestepSER();
203  break;
205  update_dt = timestepEXP();
206  break;
208  update_dt = timestepRDM();
209  break;
210  }
211  if (_bound)
212  _dt = std::min(_max_dt, update_dt);
213  else
214  _dt = update_dt;
215  }
217  }
218 }
Real currentResidualNorm() const
Computes the norm of the non-time dependent residual.
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:21
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
These methods add an range checked parameters.
virtual Real & time() const
virtual void initialize() override
Called before execute() is ever called so that data can be cleared.
const ExecFlagType & _current_execute_flag
Reference to FEProblemBase.
registerMooseObject("MooseApp", PseudoTimestep)
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
virtual Real getValue() const override
This will get called to actually grab the final value the postprocessor has calculated.
Real _max_dt
Upper bound on timestep.
const ExecFlagType EXEC_TIMESTEP_END
Definition: Moose.C:34
void outputPseudoTimestep(Real curr_dt) const
Outputs the status of the residual and timestep at the end of time step.
This class is here to combine the Postprocessor interface and the base class Postprocessor object alo...
Real timestepRDM() const
implementation of RDM method
const Real _initial_dt
Required parameters for the pseudotimestepper.
virtual void execute() override
Execute method.
Computes a time step size based on pseudo-timestep continuation.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
auto max(const L &left, const R &right)
void suppressParameter(const std::string &name)
This method suppresses an inherited parameter so that it isn&#39;t required or valid in the derived class...
Nonlinear system to be solved.
static InputParameters validParams()
PseudotimeMethod
Enum class containing the different options for selecting the timestep size for pseudo-transient simu...
std::vector< Real > & _iterations_step_sequence
const Real _alpha
Real calculate_norm(const NumericVector< Number > &v, unsigned int var, FEMNormType norm_type, std::set< unsigned int > *skip_dimensions=nullptr) const
std::vector< Real > & _residual_norms_sequence
arrays for storing residual and iterations sequence
Real timestepSER() const
implementation of SER method
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
static InputParameters validParams()
Base class for transient executioners that use a FixedPointSolve solve object for multiapp-main app i...
Definition: TransientBase.h:27
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
SystemBase & _sys
Reference to the system object for this user object.
Definition: UserObject.h:215
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:84
unsigned int number() const
Gets the number of this system.
Definition: SystemBase.C:1159
const PseudotimeMethod _method
The timestep selection method.
Executioner * getExecutioner() const
Retrieve the Executioner for this App.
Definition: MooseApp.C:2118
virtual int & timeStep() const
unsigned int _iterations_window
Number of iterations over which the residual can be lagged.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
Definition: UserObject.h:211
void addDocumentation(const std::string &name, const std::string &doc)
Add an item documentation string.
PseudoTimestep(const InputParameters &parameters)
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
const InputParameters & parameters() const
Get the parameters of the object.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
virtual bool isTransient() const override
unsigned int n_vars() const
Real _dt
Transient pseudotimestep.
T pow(T x, int e)
Definition: MathUtils.h:91
bool _bound
Boolean to check if an upper bound was provided.
NumericVector< Number > & getResidualNonTimeVector()
Return a numeric vector that is associated with the nontime tag.
Real timestepEXP() const
implementation of EXP method
auto min(const L &left, const R &right)
virtual Real & dt() const
MooseUnits pow(const MooseUnits &, int)
Definition: Units.C:537
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.
const ExecFlagType EXEC_INITIAL
Definition: Moose.C:28
virtual libMesh::System & system() override
Get the reference to the libMesh system.