https://mooseframework.inl.gov
Loading...
Searching...
No Matches
LStableDirk2.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 "LStableDirk2.h"
11#include "NonlinearSystem.h"
12#include "FEProblem.h"
13#include "PetscSupport.h"
14
15using namespace libMesh;
16
18
21{
24 "Second order diagonally implicit Runge Kutta method (Dirk) with two stages.");
25 return params;
26}
27
29 : TimeIntegrator(parameters),
30 _stage(1),
31 _residual_stage1(addVector("residual_stage1", false, GHOSTED)),
32 _residual_stage2(addVector("residual_stage2", false, GHOSTED)),
33 _alpha(1. - 0.5 * std::sqrt(2))
34{
35 mooseInfo("LStableDirk2 and other multistage TimeIntegrators are known not to work with "
36 "Materials/AuxKernels that accumulate 'state' and should be used with caution.");
37}
38
39void
41{
42 // We are multiplying by the method coefficients in postResidual(), so
43 // the time derivatives are of the same form at every stage although
44 // the current solution varies depending on the stage.
45 if (!_sys.solutionUDot())
46 mooseError("LStableDirk2: Time derivative of solution (`u_dot`) is not stored. Please set "
47 "uDotRequested() to true in FEProblemBase befor requesting `u_dot`.");
48
50 u_dot = *_solution;
52 u_dot.close();
54}
55
56void
58 const dof_id_type & dof,
59 ADReal & /*ad_u_dotdot*/) const
60{
62}
63
64void
66{
67 // Time at end of step
68 Real time_new = _fe_problem.time();
69
70 // Time at beginning of step
71 Real time_old = _fe_problem.timeOld();
72
73 // Time at stage 1
74 Real time_stage1 = time_old + _alpha * _dt;
75
76 // Reset iteration counts
79
80 // Compute first stage
82 _console << "1st stage" << std::endl;
83 _stage = 1;
84 _fe_problem.time() = time_stage1;
85 _nl->system().solve();
89
90 // Abort time step immediately on stage failure - see TimeIntegrator doc page
92 return;
93
94 // Compute second stage
96 _console << "2nd stage" << std::endl;
97 _stage = 2;
98 _fe_problem.timeOld() = time_stage1;
99 _fe_problem.time() = time_new;
101 _nl->system().solve();
104
105 // Reset time at beginning of step to its original value
106 _fe_problem.timeOld() = time_old;
107}
108
109void
111{
112 if (_stage == 1)
113 {
114 // In the standard RK notation, the stage 1 residual is given by:
115 //
116 // R := (Y_1 - y_n)/dt - alpha*f(t_n + alpha*dt, Y_1) = 0
117 //
118 // where:
119 // .) f(t_n + alpha*dt, Y_1) corresponds to the residuals of the
120 // non-time kernels. We'll save this as "_residual_stage1" to use
121 // later.
122 // .) (Y_1 - y_n)/dt corresponds to the residual of the time kernels.
123 // .) The minus sign in front of alpha is already "baked in" to
124 // the non-time residuals, so it does not appear here.
127
128 residual.add(1., *_Re_time);
129 residual.add(_alpha, *_residual_stage1);
130 residual.close();
131 }
132 else if (_stage == 2)
133 {
134 // In the standard RK notation, the stage 2 residual is given by:
135 //
136 // R := (Y_2 - y_n)/dt - (1-alpha)*f(t_n + alpha*dt, Y_1) - alpha*f(t_n + dt, Y_2) = 0
137 //
138 // where:
139 // .) f(t_n + alpha*dt, Y_1) has already been saved as _residual_stage1.
140 // .) f(t_n + dt, Y_2) will now be saved as "_residual_stage2".
141 // .) (Y_2 - y_n)/dt corresponds to the residual of the time kernels.
142 // .) The minus signs are once again "baked in" to the non-time
143 // residuals, so they do not appear here.
144 //
145 // The solution at the end of stage 2, i.e. Y_2, is also the final solution.
148
149 residual.add(1., *_Re_time);
150 residual.add(1. - _alpha, *_residual_stage1);
151 residual.add(_alpha, *_residual_stage2);
152 residual.close();
153 }
154 else
155 mooseError("LStableDirk2::postResidual(): Member variable _stage can only have values 1 or 2.");
156}
DualNumber< Real, DNDerivativeType, true > ADReal
registerMooseObject("MooseApp", LStableDirk2)
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
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.
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.
Second order diagonally implicit Runge Kutta method (Dirk) with two stages.
static InputParameters validParams()
const Real _alpha
NumericVector< Number > * _residual_stage2
Buffer to store non-time residual from second stage solve.
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
virtual void computeTimeDerivatives() override
Computes the time derivative and the Jacobian of the time derivative.
unsigned int _stage
Indicates the current stage (1 or 2).
void computeTimeDerivativeHelper(T &u_dot, const T2 &u_old) const
Helper function that actually does the math for computing the time derivative.
NumericVector< Number > * _residual_stage1
Buffer to store non-time residual from first stage solve.
virtual void postResidual(NumericVector< Number > &residual) override
Callback to the NonLinearTimeIntegratorInterface called immediately after the residuals are computed ...
LStableDirk2(const InputParameters &parameters)
virtual void solve() override
Solves the time step and sets the number of nonlinear and linear iterations.
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 void potentiallySetupFiniteDifferencing()
Create finite differencing contexts for assembly of the Jacobian and/or approximating the action of t...
virtual libMesh::System & system() override
Get the reference to the libMesh system.
void destroyColoring()
Destroy the coloring object if it exists.
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.
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