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 : #include "TimeIntegrator.h" 13 : 14 : /** 15 : * Explicit TVD (total-variation-diminishing) 16 : * second-order Runge-Kutta time integration methods: 17 : * 18 : * 19 : * Stage 1. R_{NL} = M*(U^{(1)}-U^n)/dt - F(t^n,U^n) 20 : * 21 : * t^{(1)} = t^{n} + dt = t^{n+1} 22 : * 23 : * Stage 2. R_{NL} = M*(2*U^{(2)}-U^{(1)}-U^n)/(2*dt) - (1/2)*F(t^{(1)},U^{(1)}) 24 : * 25 : * U^{n+1} = U^{(2)} 26 : * 27 : * Reference: 28 : * Gottlieb, S., & Shu, C. W. (1998). 29 : * Total variation diminishing Runge-Kutta schemes. 30 : * Mathematics of computation of the American Mathematical Society, 31 : * 67(221), 73-85. 32 : * 33 : * The method requires two mass matrix (linear) system solves 34 : * per timestep. Although strictly speaking these are "two stage" 35 : * methods, we treat the "update" step as a third stage, since in 36 : * finite element analysis the update step requires a mass matrix 37 : * solve. 38 : * 39 : * IMPORTANT: To use the explicit TimeIntegrators derived from this 40 : * method, you must generally add "implicit=false" to the Kernels, 41 : * Materials, etc. used in your simulation, so that MOOSE evaluates 42 : * them correctly! An important exception are TimeDerivative kernels, 43 : * which should never be marked "implicit=false". 44 : */ 45 : class ExplicitTVDRK2 : public TimeIntegrator 46 : { 47 : public: 48 : static InputParameters validParams(); 49 : 50 : ExplicitTVDRK2(const InputParameters & parameters); 51 : 52 : virtual void preSolve() override; 53 0 : virtual int order() override { return 2; } 54 : 55 : virtual void computeTimeDerivatives() override; 56 : void computeADTimeDerivatives(ADReal & ad_u_dot, 57 : const dof_id_type & dof, 58 : ADReal & ad_u_dotdot) const override; 59 : virtual void solve() override; 60 : virtual void postResidual(NumericVector<Number> & residual) override; 61 872 : virtual bool overridesSolve() const override { return true; } 62 : 63 : protected: 64 : /** 65 : * Helper function that actually does the math for computing the time derivative 66 : */ 67 : template <typename T, typename T2, typename T3> 68 : void computeTimeDerivativeHelper(T & u_dot, const T2 & u_old, const T3 & u_older) const; 69 : 70 : unsigned int _stage; 71 : 72 : /// Buffer to store non-time residual from the first stage. 73 : NumericVector<Number> * _residual_old; 74 : 75 : /// The older solution 76 : const NumericVector<Number> & _solution_older; 77 : }; 78 : 79 : template <typename T, typename T2, typename T3> 80 : void 81 1462 : ExplicitTVDRK2::computeTimeDerivativeHelper(T & u_dot, const T2 & u_old, const T3 & u_older) const 82 : { 83 1462 : if (_stage < 3) 84 : { 85 564 : u_dot -= u_old; 86 564 : u_dot *= 1. / _dt; 87 : } 88 : else 89 : { 90 898 : u_dot *= 2.; 91 898 : u_dot -= u_old; 92 898 : u_dot -= u_older; 93 898 : u_dot *= 0.5 / _dt; 94 : } 95 1462 : }