Line data Source code
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 : #pragma once 11 : 12 : // MOOSE includes 13 : #include "MooseObject.h" 14 : #include "Restartable.h" 15 : #include "NonlinearTimeIntegratorInterface.h" 16 : #include "LinearTimeIntegratorInterface.h" 17 : 18 : class FEProblemBase; 19 : class SystemBase; 20 : class NonlinearSystemBase; 21 : 22 : namespace libMesh 23 : { 24 : template <typename T> 25 : class NumericVector; 26 : } // namespace libMesh 27 : 28 : /** 29 : * Base class for time integrators 30 : * 31 : * Time integrators fulfill two functions: 32 : * 1) computing u_dot vector (used for computing time derivatives in kernels) and its derivative 33 : * 2) combining the residual vectors into the final one 34 : * 35 : * Capability (1) is used by both NonlinearSystem and AuxiliarySystem, while (2) can be obviously 36 : * used 37 : * only by NonlinearSystem (AuxiliarySystem does not produce residual). 38 : */ 39 : class TimeIntegrator : public MooseObject, 40 : public Restartable, 41 : public NonlinearTimeIntegratorInterface, 42 : public LinearTimeIntegratorInterface 43 : { 44 : public: 45 : static InputParameters validParams(); 46 : 47 : TimeIntegrator(const InputParameters & parameters); 48 : 49 : /** 50 : * Called to setup datastructures. 51 : * 52 : * WILL be called during recover/restart 53 : * 54 : * Should NOT do any computation for initial values 55 : * use init() for that 56 : * 57 : * Note: this doesn't inherit this from SetupInterface because 58 : * I'm not sure that we need all the other setup functions for 59 : * TimeIntegrator 60 : */ 61 27302 : virtual void initialSetup() {} 62 : 63 : /** 64 : * Called _only_ before the very first timestep (t_step = 0) 65 : * Never called again (not even during recover/restart) 66 : */ 67 : virtual void init(); 68 226985 : virtual void preSolve() {} 69 7640021 : virtual void preStep() {} 70 : 71 : /** 72 : * Solves the time step and sets the number of nonlinear and linear iterations. 73 : */ 74 : virtual void solve(); 75 : 76 : /** 77 : * Callback to the TimeIntegrator called immediately after 78 : * TimeIntegrator::solve() (so the name does make sense!). See 79 : * e.g. CrankNicolson for an example of what can be done in the 80 : * postSolve() callback -- there it is used to move the residual 81 : * from the "old" timestep forward in time to avoid recomputing it. 82 : */ 83 256642 : virtual void postSolve() {} 84 : 85 : /** 86 : * Callback to the TimeIntegrator called at the very end of time step. 87 : */ 88 181852 : virtual void postStep() {} 89 : 90 : virtual int order() = 0; 91 : 92 : /** 93 : * Computes the time derivative and the Jacobian of the time derivative 94 : * 95 : * This function is responsible for the following: 96 : * - computing the time derivative; a reference is retrieved from _sys.solutionUDot(). 97 : * - computing the time derivative Jacobian, stored in _du_dot_du, which is a 98 : * reference to _sys.duDotDus(). 99 : */ 100 : virtual void computeTimeDerivatives() = 0; 101 : 102 : /** 103 : * method for computing local automatic differentiation time derivatives 104 : */ 105 : virtual void computeADTimeDerivatives(ADReal & ad_u_dot, 106 : const dof_id_type & dof, 107 : ADReal & ad_u_dot_dot) const = 0; 108 : 109 : /** 110 : * Gets the total number of nonlinear iterations over all stages of the time step. 111 : */ 112 255969 : virtual unsigned int getNumNonlinearIterations() const { return _n_nonlinear_iterations; } 113 : 114 : /** 115 : * Gets the total number of linear iterations over all stages of the time step. 116 : */ 117 255969 : virtual unsigned int getNumLinearIterations() const { return _n_linear_iterations; } 118 : 119 : /** 120 : * Returns the time step size 121 : * @return The time step size 122 : */ 123 17672819 : const Real & dt() const { return _dt; } 124 : 125 : /** 126 : * Returns whether the explicit solvers are used 127 : */ 128 12 : virtual bool isExplicit() const { return false; } 129 : 130 : /* 131 : * Returns whether the time integrator controls its own state. Explicit 132 : * methods require extra care for determing when to store old solutions and 133 : * stateful material properties. 134 : */ 135 184697 : virtual bool advancesProblemState() const { return false; } 136 : 137 : /** 138 : * Return the number of states this requires in a linear 139 : * system setting 140 : */ 141 48 : virtual unsigned int numStatesRequired() const { return 1; } 142 : 143 : /** 144 : * Returns whether mass matrix is lumped 145 : */ 146 0 : virtual const bool & isLumped() const { return _is_lumped; } 147 : 148 : /** 149 : * @returns whether this integrator integrates the given variable 150 : */ 151 : bool integratesVar(const unsigned int var_num) const; 152 : 153 : /** 154 : * Record the linear and nonlinear iterations from a just finished solve 155 : */ 156 : void setNumIterationsLastSolve(); 157 : 158 : /** 159 : * @returns Whether the virtual solve method is overridden 160 : */ 161 : virtual bool overridesSolve() const = 0; 162 : 163 : protected: 164 : /** 165 : * Gets the number of nonlinear iterations in the most recent solve. 166 : */ 167 : unsigned int getNumNonlinearIterationsLastSolve() const; 168 : 169 : /** 170 : * Gets the number of linear iterations in the most recent solve. 171 : */ 172 : unsigned int getNumLinearIterationsLastSolve() const; 173 : 174 : /** 175 : * Copy from one vector into another. If the time integrator has been restricted to a subset of 176 : * variables, then this will selectively copy their dofs 177 : */ 178 : void copyVector(const NumericVector<Number> & from, NumericVector<Number> & to); 179 : 180 : /** 181 : * @returns The \p _du_dot_du multiplicative coefficient, e.g. if \p _du_dot_du is equivalent to 182 : * 2/dt, then this method returns 2 183 : */ 184 4374342 : virtual Real duDotDuCoeff() const { return 1; } 185 : 186 : /** 187 : * Compute \p _du_dot_du 188 : */ 189 : void computeDuDotDu(); 190 : 191 : /// Reference to the problem 192 : FEProblemBase & _fe_problem; 193 : 194 : /// Reference to the system this time integrator operates on 195 : SystemBase & _sys; 196 : 197 : /// Derivative of time derivative with respect to current solution: \f$ {du^dot}\over{du} \f$ for 198 : /// the different variables. We will only modify the elements in this vector corresponding to the 199 : /// variables that we integrate 200 : std::vector<Real> & _du_dot_du; 201 : 202 : /// @{ 203 : /// Solution vectors for different states and variable restrictions 204 : const NumericVector<Number> * const & _solution; 205 : const NumericVector<Number> & _solution_old; 206 : std::unique_ptr<NumericVector<Number>> & _solution_sub; 207 : std::unique_ptr<NumericVector<Number>> & _solution_old_sub; 208 : ///@} 209 : 210 : /// The current time step number 211 : int & _t_step; 212 : 213 : /// The current time step size 214 : Real & _dt; 215 : 216 : /// The previous time step size 217 : Real & _dt_old; 218 : 219 : /// Total number of nonlinear iterations over all stages of the time step 220 : unsigned int _n_nonlinear_iterations; 221 : /// Total number of linear iterations over all stages of the time step 222 : unsigned int _n_linear_iterations; 223 : 224 : /// Boolean flag that is set to true if lumped mass matrix is used 225 : bool _is_lumped; 226 : 227 : /// Whether the user has requested that the time integrator be applied to a subset of variables 228 : bool & _var_restriction; 229 : 230 : /// The local degree of freedom indices this time integrator is being applied to. If this 231 : /// container is empty then the time integrator is applied to all indices 232 : std::vector<dof_id_type> & _local_indices; 233 : 234 : /// The variables that this time integrator integrates 235 : std::unordered_set<unsigned int> & _vars; 236 : 237 : /// A vector that is used for creating 'from' subvectors in the \p copyVector() method 238 : std::unique_ptr<NumericVector<Number>> _from_subvector; 239 : };