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
47namespace Nektar
48{
49namespace LibUtilities
50{
51
53{
54public:
56 : m_parent(parent)
57 {
58 }
59
61 {
62 }
63
65
66 /**
67 * \brief This function initialises the time integration scheme.
68 *
69 * Given the solution at the initial time level \f$\boldsymbol{y}(t_0)\f$,
70 * this function generates the vectors \f$\boldsymbol{y}^{[n]}\f$ and
71 * \f$t^{[n]}\f$ needed to evaluate the time integration scheme formulated
72 * as a General Linear Method. These vectors are embedded in an object of
73 * the class TimeIntegrationSolutionGLM. This class is the abstraction of
74 * the input and output vectors of the General Linear Method.
75 *
76 * For single-step methods, this function is trivial as it just wraps a
77 * TimeIntegrationSolutionGLM object around the given initial values and
78 * initial time. However, for multistep methods, actual time stepping is
79 * being done to evaluate the necessary parameters at multiple time levels
80 * needed to start the actual integration.
81 *
82 * \param timestep The size of the timestep, i.e. \f$\Delta t\f$.
83 * \param time on input: the initial time, i.e. \f$t_0\f$.
84 * \param time on output: the new time-level after initialisation, in
85 * general this yields
86 * \f$t = t_0 + (r-1)\Delta t\f$ where \f$r\f$ is the number of steps
87 * of the multi-step method.
88 * \param nsteps on output: he number of initialisation steps required. In
89 * general this corresponds to \f$r-1\f$
90 * where \f$r\f$ is the number of steps of the multi-step method.
91 * \param f an object of the class FuncType, where FuncType should have a
92 * method FuncType::ODEforcing
93 * to evaluate the right hand side \f$f(t,\boldsymbol{y})\f$ of the
94 * ODE.
95 * \param y_0 the initial value \f$\boldsymbol{y}(t_0)\f$
96 * \return An object of the class TimeIntegrationSolutionGLM which
97 * represents the vectors \f$\boldsymbol{y}^{[n]}\f$ and \f$t^{[n]}\f$ that
98 * can be used to start the actual integration.
99 */
101 const NekDouble deltaT, ConstDoubleArray &y_0, const NekDouble time);
102
103 /**
104 * \brief Explicit integration of an ODE.
105 *
106 * This function explicitely perfroms a single integration step of the ODE
107 * system:
108 * \f[
109 * \frac{d\boldsymbol{y}}{dt}=\boldsymbol{f}(t,\boldsymbol{y})
110 * \f]
111 *
112 * \param deltaT The size of the timestep, i.e. \f$\Delta t\f$.
113 * \param f an object of the class FuncType, where FuncType should have a
114 * method FuncType::ODEforcing
115 * to evaluate the right hand side \f$f(t,\boldsymbol{y})\f$ of the
116 * ODE.
117 * \param y on input: the vectors \f$\boldsymbol{y}^{[n-1]}\f$ and
118 * \f$t^{[n-1]}\f$ (which corresponds to the
119 * solution at the old time level)
120 * \param y on output: the vectors \f$\boldsymbol{y}^{[n]}\f$ and
121 * \f$t^{[n]}\f$ (which corresponds to the
122 * solution at the old new level)
123 * \return The actual solution \f$\boldsymbol{y}^{n}\f$ at the new time
124 * level
125 * (which in fact is also embedded in the argument y).
126 */
129
130 // Does the actual multi-stage multi-step integration.
131 LUE void TimeIntegrate(const NekDouble deltaT, ConstTripleArray &y_old,
132 ConstSingleArray &t_old, TripleArray &y_new,
133 SingleArray &t_new);
134
135 // Check and verify GLM schemes.
137 {
141 };
142
144 {
145 return m_schemeType;
146 }
147
148 inline size_t GetNmultiStepValues() const
149 {
151 }
152
153 inline size_t GetNmultiStepImplicitDerivs() const
154 {
156 }
157
158 inline size_t GetNmultiStepExplicitDerivs() const
159 {
161 }
162
164 {
165 return m_timeLevelOffset;
166 }
167
168 // Variables - all public for easy access when setting up the phase.
169 /// Parent scheme object.
171
172 std::string m_name;
173 std::string m_variant;
174 size_t m_order{0};
175 std::vector<NekDouble> m_freeParams;
176
177 // Type of time integration scheme (Explicit, Implicit, IMEX, etc).
179
180 // Number of stages in multi-stage component.
181 size_t m_numstages{0};
182
183 // Number of steps in this integration phase.
184 size_t m_numsteps{0};
185
186 // Number of entries in input and output vector that correspond to VALUES at
187 // previous time levels.
189
190 // Number of entries in input and output vector that correspond to implicit
191 // DERIVATIVES at previous levels.
193
194 // Number of entries in input and output vector that correspond to explicit
195 // DERIVATIVES at previous levels.
197
198 // Denotes to which time-level the entries in both input and output vector
199 // correspond, e.g.
200 // INPUT VECTOR --------> m_inputTimeLevelOffset
201 // _ _ _ _
202 // | u^n | | 0 |
203 // | u^{n-1} | | 1 |
204 // | u^{n-2} | -----> | 2 |
205 // | dt f(u^{n-1})| | 1 |
206 // | dt f(u^{n-2})| | 2 |
207 // - - - -
213
214 // Arrays used for the exponential integrators.
216
219
222
223 // bool to identify array initialization.
224 bool m_initialised{false};
225
226 // Values uses for exponential integration.
227 NekDouble m_lastDeltaT{0}; /// Last delta T
228 NekDouble m_lastNVars{0}; /// Last number of vars
229
230 size_t m_nvars; /// The number of variables in integration scheme.
231 size_t m_npoints; /// The size of inner data which is stored for reuse.
232
233 // Friend classes
234 LUE friend std::ostream &operator<<(std::ostream &os,
235 const TimeIntegrationScheme &rhs);
236 LUE friend std::ostream &operator<<(
237 std::ostream &os, const TimeIntegrationSchemeSharedPtr &rhs);
238
239 LUE friend std::ostream &operator<<(std::ostream &os,
240 const TimeIntegrationAlgorithmGLM &rhs);
241 LUE friend std::ostream &operator<<(
242 std::ostream &os, const TimeIntegrationAlgorithmGLMSharedPtr &rhs);
243
244private:
246
247 DoubleArray m_Y; /// Array containing the stage values
248 DoubleArray m_tmp; /// Explicit RHS of each stage equation
249
250 TripleArray m_F; /// Array corresponding to the stage Derivatives
251 TripleArray m_F_IMEX; /// Used to store the Explicit stage derivative of
252 /// IMEX schemes
253
254 NekDouble m_T{0}; /// ime at the different stages
255
256 bool m_firstStageEqualsOldSolution{false}; /// Optimisation-flag
257 bool m_lastStageEqualsNewSolution{false}; /// Optimisation-flag
258
262
264 ConstSingleArray &t_old,
265 TripleArray &y_new,
266 SingleArray &t_new) const;
267
268 // Helpers
269 inline NekDouble A(const size_t i, const size_t j) const
270 {
271 return m_A[0][i][j];
272 }
273
274 // Overloaded accessor for GLM parameter A; both exponential and
275 // conventional schemes are currently supported
276 inline NekDouble A(const size_t k, const size_t i, const size_t j) const
277 {
279 {
280 // For exponential schemes, the parameter A is specific for
281 // each variable k
282 return m_A_phi[k][i][j];
283 }
284 else
285 {
286 return m_A[0][i][j];
287 }
288 }
289
290 inline NekDouble B(const size_t i, const size_t j) const
291 {
292 return m_B[0][i][j];
293 }
294
295 // Overloaded accessor for GLM parameter B; both exponential and
296 // conventional schemes are currently supported
297 inline NekDouble B(const size_t k, const size_t i, const size_t j) const
298 {
300 {
301 // For exponential schemes, the parameter B is specific for
302 // each variable k
303 return m_B_phi[k][i][j];
304 }
305 else
306 {
307 return m_B[0][i][j];
308 }
309 }
310
311 inline NekDouble U(const size_t i, const size_t j) const
312 {
313 return m_U[i][j];
314 }
315
316 // Overloaded accessor for GLM parameter U; both exponential and
317 // conventional schemes are currently supported
318 inline NekDouble U(const size_t k, const size_t i, const size_t j) const
319 {
321 {
322 // For exponential schemes, the parameter U is specific for
323 // each variable k
324 return m_U_phi[k][i][j];
325 }
326 else
327 {
328 return m_U[i][j];
329 }
330 }
331
332 inline NekDouble V(const size_t i, const size_t j) const
333 {
334 return m_V[i][j];
335 }
336
337 // Overloaded accessor for GLM parameter V; both exponential and
338 // conventional schemes are currently supported
339 inline NekDouble V(const size_t k, const size_t i, const size_t j) const
340 {
342 {
343 // For exponential schemes, the parameter V is specific for
344 // each variable k
345 return m_V_phi[k][i][j];
346 }
347 else
348 {
349 return m_V[i][j];
350 }
351 }
352
353 inline NekDouble A_IMEX(const size_t i, const size_t j) const
354 {
355 return m_A[1][i][j];
356 }
357
358 inline NekDouble B_IMEX(const size_t i, const size_t j) const
359 {
360 return m_B[1][i][j];
361 }
362
363 inline size_t GetNsteps(void) const
364 {
365 return m_numsteps;
366 }
367
368 inline size_t GetNstages(void) const
369 {
370 return m_numstages;
371 }
372
373 inline size_t GetFirstDim(ConstTripleArray &y) const
374 {
375 return y[0].size();
376 }
377
378 inline size_t GetSecondDim(ConstTripleArray &y) const
379 {
380 return y[0][0].size();
381 }
382
383}; // end class TimeIntegrationAlgorithmGLM
384
385LUE std::ostream &operator<<(std::ostream &os,
386 const TimeIntegrationAlgorithmGLM &rhs);
387
388LUE std::ostream &operator<<(std::ostream &os,
390
391// =========================================================================
392
393} // end of namespace LibUtilities
394} // end of namespace Nektar
395
396#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
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble