https://mooseframework.inl.gov
ExplicitRK2.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 "ExplicitRK2.h"
11 #include "NonlinearSystem.h"
12 #include "FEProblem.h"
13 #include "PetscSupport.h"
14 
15 using namespace libMesh;
16 
19 {
21 
22  return params;
23 }
24 
26  : TimeIntegrator(parameters),
27  _stage(1),
28  _residual_old(addVector("residual_old", false, GHOSTED)),
29  _solution_older(_sys.solutionState(2))
30 {
31  mooseInfo("ExplicitRK2-derived TimeIntegrators (ExplicitMidpoint, Heun, Ralston) and other "
32  "multistage TimeIntegrators are known not to work with "
33  "Materials/AuxKernels that accumulate 'state' and should be used with caution.");
34 }
35 
36 void
38 {
39  if (_dt == _dt_old)
41  else
43 }
44 
45 void
47 {
48  // Since advanceState() is called in between stages 2 and 3, this
49  // changes the meaning of "_solution_old". In the second stage,
50  // "_solution_older" is actually the original _solution_old.
51  if (!_sys.solutionUDot())
52  mooseError("ExplicitRK2: Time derivative of solution (`u_dot`) is not stored. Please set "
53  "uDotRequested() to true in FEProblemBase befor requesting `u_dot`.");
54 
56  u_dot = *_solution;
59 }
60 
61 void
63  const dof_id_type & dof,
64  ADReal & /*ad_u_dotdot*/) const
65 {
67 }
68 
69 void
71 {
72  Real time_new = _fe_problem.time();
73  Real time_old = _fe_problem.timeOld();
74  Real time_stage2 = time_old + a() * _dt;
75 
76  // Reset iteration counts
79 
80  // There is no work to do for the first stage (Y_1 = y_n). The
81  // first solve therefore happens in the second stage. Note that the
82  // non-time Kernels (which should be marked implicit=false) are
83  // evaluated at the old solution during this stage.
85  _console << "1st solve" << std::endl;
86  _stage = 2;
87  _fe_problem.timeOld() = time_old;
88  _fe_problem.time() = time_stage2;
89  _nl->system().solve();
92 
93  // Abort time step immediately on stage failure - see TimeIntegrator doc page
95  return;
96 
97  // Advance solutions old->older, current->old. Also moves Material
98  // properties and other associated state forward in time.
100 
101  // The "update" stage (which we call stage 3) requires an additional
102  // solve with the mass matrix.
104  _console << "2nd solve" << std::endl;
105  _stage = 3;
106  _fe_problem.timeOld() = time_stage2;
107  _fe_problem.time() = time_new;
108  _nl->system().solve();
111 
112  // Error if solve didn't work, since we can't undo the advanceState
113  if (!_fe_problem.converged(_nl->number()))
114  mooseError("Aborting as ",
115  type(),
116  " has undefined behavior if it attempts to re-do a timestep after the first stage.");
117 
118  // Reset time at beginning of step to its original value
119  _fe_problem.timeOld() = time_old;
120 }
121 
122 void
124 {
125  if (_stage == 1)
126  {
127  // If postResidual() is called before solve(), _stage==1 and we don't
128  // need to do anything.
129  }
130  else if (_stage == 2)
131  {
132  // In the standard RK notation, the stage 2 residual is given by:
133  //
134  // R := M*(Y_2 - y_n)/dt - a*f(t_n, Y_1) = 0
135  //
136  // where:
137  // .) M is the mass matrix.
138  // .) f(t_n, Y_1) is the residual we are currently computing,
139  // since this method is intended to be used with "implicit=false"
140  // kernels.
141  // .) M*(Y_2 - y_n)/dt corresponds to the residual of the time kernels.
142  // .) The minus signs are "baked in" to the non-time residuals, so
143  // they do not appear here.
144  // .) The current non-time residual is saved for the next stage.
146  _residual_old->close();
147 
148  residual.add(1., *_Re_time);
149  residual.add(a(), *_residual_old);
150  residual.close();
151  }
152  else if (_stage == 3)
153  {
154  // In the standard RK notation, the update step residual is given by:
155  //
156  // R := M*(y_{n+1} - y_n)/dt - f(t_n+dt/2, Y_2) = 0
157  //
158  // where:
159  // .) M is the mass matrix.
160  // .) f(t_n+dt/2, Y_2) is the residual from stage 2.
161  // .) The minus sign is already baked in to the non-time
162  // residuals, so it does not appear here.
163  // .) Although this is an update step, we have to do a "solve"
164  // using the mass matrix.
165  residual.add(1., *_Re_time);
166  residual.add(b1(), *_residual_old);
167  residual.add(b2(), *_Re_non_time);
168  residual.close();
169  }
170  else
171  mooseError("ExplicitRK2::postResidual(): _stage = ", _stage, ", only _stage = 1-3 is allowed.");
172 }
virtual void initPetscOutputAndSomeSolverSettings()
Reinitialize PETSc output for proper linear/nonlinear iteration display.
virtual Real & time() const
FEProblemBase & _fe_problem
Reference to the problem.
void mooseInfo(Args &&... args) const
NumericVector< Number > * _residual_old
Buffer to store non-time residual from the first stage.
Definition: ExplicitRK2.h:82
NonlinearSystemBase * _nl
Pointer to the nonlinear system, can happen that we dont have any.
SystemBase & _sys
Reference to the system this time integrator operates on.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
DualNumber< Real, DNDerivativeType, true > ADReal
Definition: ADRealForward.h:46
Real & _dt
The current time step size.
Real & _dt_old
The previous time step size.
NumericVector< Number > * _Re_time
residual vector for time contributions
static InputParameters validParams()
Definition: ExplicitRK2.C:18
virtual void advanceState()
Advance all of the state holding vectors / datastructures so that we can move to the next timestep...
virtual void solve() override
Solves the time step and sets the number of nonlinear and linear iterations.
Definition: ExplicitRK2.C:70
virtual NumericVector< Number > * solutionUDot()
Definition: SystemBase.h:252
virtual Real a() const =0
The method coefficients.
virtual bool converged(const unsigned int sys_num)
Eventually we want to convert this virtual over to taking a solver system number argument.
Definition: SubProblem.h:113
unsigned int _n_linear_iterations
Total number of linear iterations over all stages of the time step.
const std::string & type() const
Get the type of this class.
Definition: MooseBase.h:51
unsigned int _stage
Definition: ExplicitRK2.h:79
unsigned int number() const
Gets the number of this system.
Definition: SystemBase.C:1159
virtual void solve()
virtual void close()=0
const NumericVector< Number > *const & _solution
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Base class for time integrators.
virtual Real b1() const =0
unsigned int getNumLinearIterationsLastSolve() const
Gets the number of linear iterations in the most recent solve.
void setConstJacobian(bool state)
Set flag that Jacobian is constant (for optimization purposes)
virtual void preSolve() override
Definition: ExplicitRK2.C:37
ExplicitRK2(const InputParameters &parameters)
Definition: ExplicitRK2.C:25
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
virtual void postResidual(NumericVector< Number > &residual) override
Callback to the NonLinearTimeIntegratorInterface called immediately after the residuals are computed ...
Definition: ExplicitRK2.C:123
virtual void computeTimeDerivatives() override
Computes the time derivative and the Jacobian of the time derivative.
Definition: ExplicitRK2.C:46
virtual Real & timeOld() const
const NumericVector< Number > & _solution_old
unsigned int _n_nonlinear_iterations
Total number of nonlinear iterations over all stages of the time step.
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
void computeADTimeDerivatives(ADReal &ad_u_dot, const dof_id_type &dof, ADReal &ad_u_dotdot) const override
method for computing local automatic differentiation time derivatives
Definition: ExplicitRK2.C:62
unsigned int getNumNonlinearIterationsLastSolve() const
Gets the number of nonlinear iterations in the most recent solve.
virtual void add(const numeric_index_type i, const T value)=0
NumericVector< Number > * _Re_non_time
residual vector for non-time contributions
void computeTimeDerivativeHelper(T &u_dot, const T2 &u_old, const T3 &u_older) const
Helper function that actually does the math for computing the time derivative.
Definition: ExplicitRK2.h:97
virtual Real b2() const =0
static InputParameters validParams()
uint8_t dof_id_type
const NumericVector< Number > & _solution_older
The older solution.
Definition: ExplicitRK2.h:85
void computeDuDotDu()
Compute _du_dot_du.
virtual libMesh::System & system() override
Get the reference to the libMesh system.