Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
CrankNicolson.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 "CrankNicolson.h"
11 #include "NonlinearSystem.h"
12 #include "FEProblem.h"
13 
15 
18 {
20  params.addClassDescription("Crank-Nicolson time integrator.");
21  return params;
22 }
23 
25  : TimeIntegrator(parameters), _residual_old(addVector("residual_old", false, libMesh::GHOSTED))
26 {
27 }
28 
29 void
31 {
32  if (!_sys.solutionUDot())
33  mooseError("CrankNicolson: Time derivative of solution (`u_dot`) is not stored. Please set "
34  "uDotRequested() to true in FEProblemBase befor requesting `u_dot`.");
35 
37  if (!_var_restriction)
38  {
39  u_dot = *_solution;
41  }
42  else
43  {
44  auto u_dot_sub = u_dot.get_subvector(_local_indices);
47  *u_dot_sub = *_solution_sub;
49  u_dot.restore_subvector(std::move(u_dot_sub), _local_indices);
50  // Scatter info needed for ghosts
51  u_dot.close();
52  }
53 
54  for (const auto i : index_range(_du_dot_du))
55  if (integratesVar(i))
56  _du_dot_du[i] = 2. / _dt;
57 }
58 
59 void
61  const dof_id_type & dof,
62  ADReal & /*ad_u_dotdot*/) const
63 {
65 }
66 
67 void
69 {
71 
72  if (!_sys.solutionUDot())
73  mooseError("CrankNicolson: Time derivative of solution (`u_dot`) is not stored. Please set "
74  "uDotRequested() to true in FEProblemBase befor requesting `u_dot`.");
75 
76  // time derivative is assumed to be zero on initial
78  u_dot.zero();
80 
81  if (_nl)
82  {
83  // compute residual for the initial time step
84  // Note: we can not directly pass _residual_old in computeResidualTag because
85  // the function will call postResidual, which will cause _residual_old
86  // to be added on top of itself prohibited by PETSc.
87  // Objects executed on initial have been executed by FEProblem,
88  // so we can and should directly call NonlinearSystem residual evaluation.
92 
94  }
95 }
96 
97 void
99 {
100  // PETSc 3.19 insists on having closed vectors when doing VecAXPY,
101  // and that's probably a good idea with earlier versions too, but
102  // we don't always get here with _Re_time closed.
103  std::vector<unsigned char> inputs_closed = {
105 
106  // We might have done work on one processor but not all processors,
107  // so we have to sync our closed() checks. Congrats to the BISON
108  // folks for test coverage that caught that.
109  comm().min(inputs_closed);
110 
111  if (!inputs_closed[0])
112  _Re_time->close();
113  if (!inputs_closed[1])
114  _Re_non_time->close();
115  if (!inputs_closed[2])
116  _residual_old->close();
117 
118  if (!_var_restriction)
119  {
120  residual += *_Re_time;
121  residual += *_Re_non_time;
122  residual += *_residual_old;
123  }
124  else
125  {
126  auto residual_sub = residual.get_subvector(_local_indices);
127  auto re_time_sub = _Re_time->get_subvector(_local_indices);
128  auto re_non_time_sub = _Re_non_time->get_subvector(_local_indices);
129  auto residual_old_sub = _residual_old->get_subvector(_local_indices);
130  *residual_sub += *re_time_sub;
131  *residual_sub += *re_non_time_sub;
132  *residual_sub += *residual_old_sub;
133  residual.restore_subvector(std::move(residual_sub), _local_indices);
134  _Re_time->restore_subvector(std::move(re_time_sub), _local_indices);
135  _Re_non_time->restore_subvector(std::move(re_non_time_sub), _local_indices);
136  _residual_old->restore_subvector(std::move(residual_old_sub), _local_indices);
137  }
138 }
139 
140 void
142 {
144 }
145 
146 Real
148 {
149  return 2;
150 }
NumericVector< Number > * _residual_old
Definition: CrankNicolson.h:48
virtual void postResidual(NumericVector< Number > &residual) override
Callback to the NonLinearTimeIntegratorInterface called immediately after the residuals are computed ...
Definition: CrankNicolson.C:98
void clearCurrentResidualVectorTags()
Clear the current residual vector tag data structure.
void computeTimeDerivativeHelper(T &u_dot, const T2 &u_old) const
Helper function that actually does the math for computing the time derivative.
Definition: CrankNicolson.h:53
bool & _var_restriction
Whether the user has requested that the time integrator be applied to a subset of variables...
FEProblemBase & _fe_problem
Reference to the problem.
virtual void init() override
Called only before the very first timestep (t_step = 0) Never called again (not even during recover/r...
Definition: CrankNicolson.C:68
virtual Real duDotDuCoeff() const override
TagID nonTimeVectorTag() const override
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...
const Parallel::Communicator & comm() const
virtual void postStep() override
Callback to the TimeIntegrator called at the very end of time step.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
DualNumber< Real, DNDerivativeType, true > ADReal
Definition: ADRealForward.h:47
Real & _dt
The current time step size.
NumericVector< Number > * _Re_time
residual vector for time contributions
virtual void zero()=0
virtual void init()
Called only before the very first timestep (t_step = 0) Never called again (not even during recover/r...
virtual void create_subvector(NumericVector< Number > &, const std::vector< numeric_index_type > &, bool=true) const
void min(const T &r, T &o, Request &req) const
GHOSTED
virtual NumericVector< Number > * solutionUDot()
Definition: SystemBase.h:252
std::vector< dof_id_type > & _local_indices
The local degree of freedom indices this time integrator is being applied to.
registerMooseObject("MooseApp", CrankNicolson)
virtual std::unique_ptr< NumericVector< Number > > get_subvector(const std::vector< numeric_index_type > &)
std::unique_ptr< NumericVector< Number > > & _solution_old_sub
virtual void close()=0
std::vector< Real > & _du_dot_du
Derivative of time derivative with respect to current solution: for the different variables...
CrankNicolson(const InputParameters &parameters)
Definition: CrankNicolson.C:24
virtual bool closed() const
virtual NumericVector< Number > & RHS()=0
const NumericVector< Number > *const & _solution
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Base class for time integrators.
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...
void setCurrentResidualVectorTags(const std::set< TagID > &vector_tags)
Set the current residual vector tag data structure based on the passed in tag IDs.
const NumericVector< Number > & _solution_old
bool integratesVar(const unsigned int var_num) const
void computeResidualTag(NumericVector< Number > &residual, TagID tag_id)
Computes residual for a given tag.
static InputParameters validParams()
Definition: CrankNicolson.C:17
NumericVector< Number > * _Re_non_time
residual vector for non-time contributions
virtual void computeTimeDerivatives() override
Computes the time derivative and the Jacobian of the time derivative.
Definition: CrankNicolson.C:30
static InputParameters validParams()
Crank-Nicolson time integrator.
Definition: CrankNicolson.h:22
auto index_range(const T &sizable)
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: CrankNicolson.C:60
std::unique_ptr< NumericVector< Number > > & _solution_sub
uint8_t dof_id_type
void computeDuDotDu()
Compute _du_dot_du.
void copyVector(const NumericVector< Number > &from, NumericVector< Number > &to)
Copy from one vector into another.
virtual void restore_subvector(std::unique_ptr< NumericVector< Number >>, const std::vector< numeric_index_type > &)