Nektar++
TimeIntegrationAlgorithmGLM.h
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: TimeIntegrationAlgorithmGLM.h
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2019 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// License for the specific language governing rights and limitations under
14// Permission is hereby granted, free of charge, to any person obtaining a
15// copy of this software and associated documentation files (the "Software"),
16// to deal in the Software without restriction, including without limitation
17// the rights to use, copy, modify, merge, publish, distribute, sublicense,
18// and/or sell copies of the Software, and to permit persons to whom the
19// Software is furnished to do so, subject to the following conditions:
20//
21// The above copyright notice and this permission notice shall be included
22// in all copies or substantial portions of the Software.
23//
24// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30// DEALINGS IN THE SOFTWARE.
31//
32// Description: Header file of time integration scheme data class
33//
34// The TimeIntegrationAlgorithmGLM class should only be used by the
35// TimeIntegrationSchemeGLM class.
36//
37///////////////////////////////////////////////////////////////////////////////
38
39#ifndef NEKTAR_LIB_UTILITIES_TIME_INTEGRATION_TIME_INTEGRATION_ALGORITHM_GLM
40#define NEKTAR_LIB_UTILITIES_TIME_INTEGRATION_TIME_INTEGRATION_ALGORITHM_GLM
41
42#define LUE LIB_UTILITIES_EXPORT
43
46
48{
49
51{
52public:
54 : m_parent(parent)
55 {
56 }
57
59 {
60 }
61
63
64 /**
65 * \brief This function initialises the time integration scheme.
66 *
67 * Given the solution at the initial time level \f$\boldsymbol{y}(t_0)\f$,
68 * this function generates the vectors \f$\boldsymbol{y}^{[n]}\f$ and
69 * \f$t^{[n]}\f$ needed to evaluate the time integration scheme formulated
70 * as a General Linear Method. These vectors are embedded in an object of
71 * the class TimeIntegrationSolutionGLM. This class is the abstraction of
72 * the input and output vectors of the General Linear Method.
73 *
74 * For single-step methods, this function is trivial as it just wraps a
75 * TimeIntegrationSolutionGLM object around the given initial values and
76 * initial time. However, for multistep methods, actual time stepping is
77 * being done to evaluate the necessary parameters at multiple time levels
78 * needed to start the actual integration.
79 *
80 * \param timestep The size of the timestep, i.e. \f$\Delta t\f$.
81 * \param time on input: the initial time, i.e. \f$t_0\f$.
82 * \param time on output: the new time-level after initialisation, in
83 * general this yields
84 * \f$t = t_0 + (r-1)\Delta t\f$ where \f$r\f$ is the number of steps
85 * of the multi-step method.
86 * \param nsteps on output: he number of initialisation steps required. In
87 * general this corresponds to \f$r-1\f$
88 * where \f$r\f$ is the number of steps of the multi-step method.
89 * \param f an object of the class FuncType, where FuncType should have a
90 * method FuncType::ODEforcing
91 * to evaluate the right hand side \f$f(t,\boldsymbol{y})\f$ of the
92 * ODE.
93 * \param y_0 the initial value \f$\boldsymbol{y}(t_0)\f$
94 * \return An object of the class TimeIntegrationSolutionGLM which
95 * represents the vectors \f$\boldsymbol{y}^{[n]}\f$ and \f$t^{[n]}\f$ that
96 * can be used to start the actual integration.
97 */
99 const NekDouble deltaT, ConstDoubleArray &y_0, const NekDouble time);
100
101 /**
102 * \brief Explicit integration of an ODE.
103 *
104 * This function explicitely perfroms a single integration step of the ODE
105 * system:
106 * \f[
107 * \frac{d\boldsymbol{y}}{dt}=\boldsymbol{f}(t,\boldsymbol{y})
108 * \f]
109 *
110 * \param deltaT The size of the timestep, i.e. \f$\Delta t\f$.
111 * \param f an object of the class FuncType, where FuncType should have a
112 * method FuncType::ODEforcing
113 * to evaluate the right hand side \f$f(t,\boldsymbol{y})\f$ of the
114 * ODE.
115 * \param y on input: the vectors \f$\boldsymbol{y}^{[n-1]}\f$ and
116 * \f$t^{[n-1]}\f$ (which corresponds to the
117 * solution at the old time level)
118 * \param y on output: the vectors \f$\boldsymbol{y}^{[n]}\f$ and
119 * \f$t^{[n]}\f$ (which corresponds to the
120 * solution at the old new level)
121 * \return The actual solution \f$\boldsymbol{y}^{n}\f$ at the new time
122 * level
123 * (which in fact is also embedded in the argument y).
124 */
127
128 // Does the actual multi-stage multi-step integration.
129 LUE void TimeIntegrate(const NekDouble deltaT, ConstTripleArray &y_old,
130 ConstSingleArray &t_old, TripleArray &y_new,
131 SingleArray &t_new);
132
133 // Check and verify GLM schemes.
135 {
139 };
140
142 {
143 return m_schemeType;
144 }
145
146 inline size_t GetNmultiStepValues() const
147 {
149 }
150
151 inline size_t GetNmultiStepImplicitDerivs() const
152 {
154 }
155
156 inline size_t GetNmultiStepExplicitDerivs() const
157 {
159 }
160
162 {
163 return m_timeLevelOffset;
164 }
165
166 // Variables - all public for easy access when setting up the phase.
167 /// Parent scheme object.
169
170 std::string m_name;
171 std::string m_variant;
172 size_t m_order{0};
173 std::vector<NekDouble> m_freeParams;
174
175 // Type of time integration scheme (Explicit, Implicit, IMEX, etc).
177
178 // Number of stages in multi-stage component.
179 size_t m_numstages{0};
180
181 // Number of steps in this integration phase.
182 size_t m_numsteps{0};
183
184 // Number of entries in input and output vector that correspond to VALUES at
185 // previous time levels.
187
188 // Number of entries in input and output vector that correspond to implicit
189 // DERIVATIVES at previous levels.
191
192 // Number of entries in input and output vector that correspond to explicit
193 // DERIVATIVES at previous levels.
195
196 // Denotes to which time-level the entries in both input and output vector
197 // correspond, e.g.
198 // INPUT VECTOR --------> m_inputTimeLevelOffset
199 // _ _ _ _
200 // | u^n | | 0 |
201 // | u^{n-1} | | 1 |
202 // | u^{n-2} | -----> | 2 |
203 // | dt f(u^{n-1})| | 1 |
204 // | dt f(u^{n-2})| | 2 |
205 // - - - -
211
212 // Arrays used for the exponential integrators.
214
217
220
221 // bool to identify array initialization.
222 bool m_initialised{false};
223
224 // Values uses for exponential integration.
225 NekDouble m_lastDeltaT{0}; /// Last delta T
226 NekDouble m_lastNVars{0}; /// Last number of vars
227
228 size_t m_nvars; /// The number of variables in integration scheme.
229 size_t m_npoints; /// The size of inner data which is stored for reuse.
230
231 // Friend classes
232 LUE friend std::ostream &operator<<(std::ostream &os,
233 const TimeIntegrationScheme &rhs);
234 LUE friend std::ostream &operator<<(
235 std::ostream &os, const TimeIntegrationSchemeSharedPtr &rhs);
236
237 LUE friend std::ostream &operator<<(std::ostream &os,
238 const TimeIntegrationAlgorithmGLM &rhs);
239 LUE friend std::ostream &operator<<(
240 std::ostream &os, const TimeIntegrationAlgorithmGLMSharedPtr &rhs);
241
242private:
244
245 DoubleArray m_Y; /// Array containing the stage values
246 DoubleArray m_tmp; /// Explicit RHS of each stage equation
247
248 TripleArray m_F; /// Array corresponding to the stage Derivatives
249 TripleArray m_F_IMEX; /// Used to store the Explicit stage derivative of
250 /// IMEX schemes
251
252 NekDouble m_T{0}; /// ime at the different stages
253
254 bool m_firstStageEqualsOldSolution{false}; /// Optimisation-flag
255 bool m_lastStageEqualsNewSolution{false}; /// Optimisation-flag
256
260
262 ConstSingleArray &t_old,
263 TripleArray &y_new,
264 SingleArray &t_new) const;
265
266 // Helpers
267 inline NekDouble A(const size_t i, const size_t j) const
268 {
269 return m_A[0][i][j];
270 }
271
272 // Overloaded accessor for GLM parameter A; both exponential and
273 // conventional schemes are currently supported
274 inline NekDouble A(const size_t k, const size_t i, const size_t j) const
275 {
277 {
278 // For exponential schemes, the parameter A is specific for
279 // each variable k
280 return m_A_phi[k][i][j];
281 }
282 else
283 {
284 return m_A[0][i][j];
285 }
286 }
287
288 inline NekDouble B(const size_t i, const size_t j) const
289 {
290 return m_B[0][i][j];
291 }
292
293 // Overloaded accessor for GLM parameter B; both exponential and
294 // conventional schemes are currently supported
295 inline NekDouble B(const size_t k, const size_t i, const size_t j) const
296 {
298 {
299 // For exponential schemes, the parameter B is specific for
300 // each variable k
301 return m_B_phi[k][i][j];
302 }
303 else
304 {
305 return m_B[0][i][j];
306 }
307 }
308
309 inline NekDouble U(const size_t i, const size_t j) const
310 {
311 return m_U[i][j];
312 }
313
314 // Overloaded accessor for GLM parameter U; both exponential and
315 // conventional schemes are currently supported
316 inline NekDouble U(const size_t k, const size_t i, const size_t j) const
317 {
319 {
320 // For exponential schemes, the parameter U is specific for
321 // each variable k
322 return m_U_phi[k][i][j];
323 }
324 else
325 {
326 return m_U[i][j];
327 }
328 }
329
330 inline NekDouble V(const size_t i, const size_t j) const
331 {
332 return m_V[i][j];
333 }
334
335 // Overloaded accessor for GLM parameter V; both exponential and
336 // conventional schemes are currently supported
337 inline NekDouble V(const size_t k, const size_t i, const size_t j) const
338 {
340 {
341 // For exponential schemes, the parameter V is specific for
342 // each variable k
343 return m_V_phi[k][i][j];
344 }
345 else
346 {
347 return m_V[i][j];
348 }
349 }
350
351 inline NekDouble A_IMEX(const size_t i, const size_t j) const
352 {
353 return m_A[1][i][j];
354 }
355
356 inline NekDouble B_IMEX(const size_t i, const size_t j) const
357 {
358 return m_B[1][i][j];
359 }
360
361 inline size_t GetNsteps(void) const
362 {
363 return m_numsteps;
364 }
365
366 inline size_t GetNstages(void) const
367 {
368 return m_numstages;
369 }
370
371 inline size_t GetFirstDim(ConstTripleArray &y) const
372 {
373 return y[0].size();
374 }
375
376 inline size_t GetSecondDim(ConstTripleArray &y) const
377 {
378 return y[0][0].size();
379 }
380
381}; // end class TimeIntegrationAlgorithmGLM
382
383LUE std::ostream &operator<<(std::ostream &os,
384 const TimeIntegrationAlgorithmGLM &rhs);
385
386LUE std::ostream &operator<<(std::ostream &os,
388
389// =========================================================================
390
391} // namespace Nektar::LibUtilities
392
393#endif
NekDouble V(const size_t k, const size_t i, const size_t j) const
TimeIntegrationAlgorithmGLM(const TimeIntegrationSchemeGLM *parent)
NekDouble U(const size_t k, const size_t i, const size_t j) const
NekDouble A(const size_t k, const size_t i, const size_t j) const
NekDouble B(const size_t k, const size_t i, const size_t j) const
NekDouble V(const size_t i, const size_t j) const
LUE friend std::ostream & operator<<(std::ostream &os, const TimeIntegrationScheme &rhs)
The size of inner data which is stored for reuse.
const TimeIntegrationSchemeGLM * m_parent
Parent scheme object.
TripleArray m_F
Explicit RHS of each stage equation.
DoubleArray m_tmp
Array containing the stage values.
NekDouble A(const size_t i, const size_t j) const
NekDouble B_IMEX(const size_t i, const size_t j) const
bool CheckTimeIntegrateArguments(ConstTripleArray &y_old, ConstSingleArray &t_old, TripleArray &y_new, SingleArray &t_new) const
NekDouble A_IMEX(const size_t i, const size_t j) const
NekDouble B(const size_t i, const size_t j) const
NekDouble U(const size_t i, const size_t j) const
NekDouble m_T
Used to store the Explicit stage derivative of IMEX schemes.
const Array< OneD, const size_t > & GetTimeLevelOffset() const
size_t m_npoints
The number of variables in integration scheme.
void InitializeScheme(const TimeIntegrationSchemeOperators &op)
LUE ConstDoubleArray & TimeIntegrate(const NekDouble deltaT, TimeIntegrationSolutionGLMSharedPtr &y)
Explicit integration of an ODE.
LUE TimeIntegrationSolutionGLMSharedPtr InitializeData(const NekDouble deltaT, ConstDoubleArray &y_0, const NekDouble time)
This function initialises the time integration scheme.
TripleArray m_F_IMEX
Array corresponding to the stage Derivatives.
Base class for GLM time integration schemes.
Base class for time integration schemes.
Binds a set of functions for use by time integration schemes.
std::shared_ptr< TimeIntegrationAlgorithmGLM > TimeIntegrationAlgorithmGLMSharedPtr
@ eExponential
Exponential scheme.
std::shared_ptr< TimeIntegrationSolutionGLM > TimeIntegrationSolutionGLMSharedPtr
std::ostream & operator<<(std::ostream &os, const BasisKey &rhs)
std::shared_ptr< TimeIntegrationScheme > TimeIntegrationSchemeSharedPtr
double NekDouble