https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
15using 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
36void
44
45void
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
61void
63 const dof_id_type & dof,
64 ADReal & /*ad_u_dotdot*/) const
65{
67}
68
69void
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
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
122void
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.
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}
DualNumber< Real, DNDerivativeType, true > ADReal
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
const NumericVector< Number > & _solution_older
The older solution.
Definition ExplicitRK2.h:85
virtual Real a() const =0
The method coefficients.
static InputParameters validParams()
Definition ExplicitRK2.C:18
ExplicitRK2(const InputParameters &parameters)
Definition ExplicitRK2.C:25
virtual void solve() override
Solves the time step and sets the number of nonlinear and linear iterations.
Definition ExplicitRK2.C:70
virtual Real b1() const =0
unsigned int _stage
Definition ExplicitRK2.h:79
virtual void preSolve() override
Definition ExplicitRK2.C:37
virtual void postResidual(NumericVector< Number > &residual) override
Callback to the NonLinearTimeIntegratorInterface called immediately after the residuals are computed ...
NumericVector< Number > * _residual_old
Buffer to store non-time residual from the first stage.
Definition ExplicitRK2.h:82
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
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
virtual Real b2() const =0
virtual void computeTimeDerivatives() override
Computes the time derivative and the Jacobian of the time derivative.
Definition ExplicitRK2.C:46
virtual void advanceState()
Advance all of the state holding vectors / datastructures so that we can move to the next timestep.
void setConstJacobian(bool state)
Set flag that Jacobian is constant (for optimization purposes)
virtual Real & timeOld() const
virtual Real & time() const
virtual void initPetscOutputAndSomeSolverSettings()
Reinitialize PETSc output for proper linear/nonlinear iteration display.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
const std::string & type() const
Get the type of this class.
Definition MooseBase.h:93
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition MooseBase.h:271
void mooseInfo(Args &&... args) const
Definition MooseBase.h:334
virtual libMesh::System & system() override
Get the reference to the libMesh system.
NonlinearSystemBase * _nl
Pointer to the nonlinear system, can happen that we dont have any.
NumericVector< Number > * _Re_non_time
residual vector for non-time contributions
NumericVector< Number > * _Re_time
residual vector for time contributions
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
virtual NumericVector< Number > * solutionUDot()
Definition SystemBase.h:280
unsigned int number() const
Gets the number of this system.
Base class for time integrators.
void computeDuDotDu()
Compute _du_dot_du.
unsigned int getNumLinearIterationsLastSolve() const
Gets the number of linear iterations in the most recent solve.
Real & _dt_old
The previous time step size.
const NumericVector< Number > *const & _solution
unsigned int _n_linear_iterations
Total number of linear iterations over all stages of the time step.
unsigned int _n_nonlinear_iterations
Total number of nonlinear iterations over all stages of the time step.
static InputParameters validParams()
FEProblemBase & _fe_problem
Reference to the problem.
unsigned int getNumNonlinearIterationsLastSolve() const
Gets the number of nonlinear iterations in the most recent solve.
SystemBase & _sys
Reference to the system this time integrator operates on.
Real & _dt
The current time step size.
const NumericVector< Number > & _solution_old
virtual void close()=0
virtual void add(const numeric_index_type i, const T value)=0
virtual void solve()
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
uint8_t dof_id_type
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real