Nektar++
IMEXTimeIntegrationSchemes.h
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: IMEXTimeIntegrationSchemes.h
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2018 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: Combined header file for all basic IMEX time integration
33// schemes.
34//
35///////////////////////////////////////////////////////////////////////////////
36
37// Note : If adding a new integrator be sure to register the
38// integrator with the Time Integration Scheme Facatory in
39// SchemeInitializor.cpp.
40
41#ifndef NEKTAR_LIB_UTILITIES_TIME_INTEGRATION_IMEX_TIME_INTEGRATION_SCHEME
42#define NEKTAR_LIB_UTILITIES_TIME_INTEGRATION_IMEX_TIME_INTEGRATION_SCHEME
43
44#define LUE LIB_UTILITIES_EXPORT
45
46#include <boost/core/ignore_unused.hpp>
47
51
53{
54
55///////////////////////////////////////////////////////////////////////////////
56// IMEX Order N
57
59{
60public:
61 IMEXTimeIntegrationScheme(std::string variant, size_t order,
62 std::vector<NekDouble> freeParams)
63 : TimeIntegrationSchemeGLM(variant, order, freeParams)
64 {
65 if (variant == "dirk" || variant == "DIRK")
66 {
67 ASSERTL1(freeParams.size() == 2,
68 "IMEX DIRK Time integration scheme invalid number "
69 "of free parameters, expected two "
70 "<implicit stages, explicit stages>, received " +
71 std::to_string(freeParams.size()));
72
73 size_t s = freeParams[0];
74 size_t sigma = freeParams[1];
75
79
80 if (order == 1 && s == 1 && sigma == 1)
81 {
82 // This phase is Forward Backward Euler which has two steps.
85 }
86 else
87 {
89 m_integration_phases[0], order, freeParams);
90 }
91 }
92 else if (variant == "Gear")
93 {
99
101 m_integration_phases[0], 2, std::vector<NekDouble>{2, 2});
104 }
105 else if (variant == "")
106 {
107 // Currently up to 4th order is implemented.
108 ASSERTL1(1 <= order && order <= 4,
109 "IMEX Time integration scheme bad order (1-4): " +
110 std::to_string(order));
111
113
114 for (size_t n = 0; n < order; ++n)
115 {
118 }
119
120 // Last phase
122 m_integration_phases[order - 1], order);
123
124 // Initial phases
125 switch (order)
126 {
127 case 1:
128 // No intial phase.
129 break;
130
131 case 2:
134 break;
135
136 case 3:
139 std::vector<NekDouble>{3, 4});
142 std::vector<NekDouble>{3, 4});
143 break;
144
145 case 4:
148 std::vector<NekDouble>{3, 4});
151 std::vector<NekDouble>{3, 4});
154 std::vector<NekDouble>{3, 4});
155 break;
156
157 default:
158 ASSERTL1(false, "IMEX Time integration scheme bad order: " +
159 std::to_string(order));
160 }
161 }
162 else
163 {
164 ASSERTL1(false, "IMEX Time integration scheme bad variant: " +
165 variant + ". Must be blank, 'dirk' or 'Gear'");
166 }
167 }
168
170 {
171 }
172
174 std::string variant, size_t order, std::vector<NekDouble> freeParams)
175 {
178 variant, order, freeParams);
179
180 return p;
181 }
182
183 static std::string className;
184
186 size_t order)
187 {
188 constexpr NekDouble ABcoefficients[5] = {0.,
189 1., // 1st Order
190 2. / 3., // 2nd Order
191 6. / 11., // 3rd Order
192 12. / 25.}; // 4th Order
193
194 // Nsteps = 2 * order
195
196 // clang-format off
197 constexpr NekDouble UVcoefficients[5][8] =
198 { { 0., 0., 0., 0.,
199 0., 0., 0., 0. },
200 // 1st Order
201 { 1., 1., 0., 0.,
202 0., 0., 0., 0. },
203 // 2nd Order
204 { 4./ 3., -1./ 3., 4./3., -2./ 3.,
205 0., 0., 0., 0. },
206 // 3rd Order
207 { 18./11., -9./11., 2./11., 18./11.,
208 -18./11., 6./11., 0., 0. },
209 // 4th Order
210 { 48./25., -36./25., 16./25., -3./25.,
211 48./25., -72./25., 48./25., -12./25. } };
212 // clang-format on
213
214 phase->m_schemeType = eIMEX;
215 phase->m_order = order;
216 phase->m_name =
217 std::string("IMEXOrder" + std::to_string(phase->m_order));
218
219 phase->m_numsteps = 2 * phase->m_order;
220 phase->m_numstages = 1;
221
222 phase->m_A = Array<OneD, Array<TwoD, NekDouble>>(2);
223 phase->m_B = Array<OneD, Array<TwoD, NekDouble>>(2);
224
225 phase->m_A[0] =
226 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
227 phase->m_B[0] =
228 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
229 phase->m_A[1] =
230 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
231 phase->m_B[1] =
232 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
233 phase->m_U =
234 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numsteps, 0.0);
235 phase->m_V =
236 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numsteps, 0.0);
237
238 // Coefficients
239 phase->m_B[1][phase->m_order][0] = 1.0;
240
241 phase->m_A[0][0][0] = ABcoefficients[phase->m_order];
242 phase->m_B[0][0][0] = ABcoefficients[phase->m_order];
243
244 for (size_t n = 0; n < 2 * phase->m_order; ++n)
245 {
246 phase->m_U[0][n] = UVcoefficients[phase->m_order][n];
247 phase->m_V[0][n] = UVcoefficients[phase->m_order][n];
248 }
249
250 // V evaluation value shuffling row n column n-1
251 for (size_t n = 1; n < 2 * phase->m_order; ++n)
252 {
253 if (n != phase->m_order)
254 {
255 phase->m_V[n][n - 1] = 1.0; // constant 1
256 }
257 }
258
259 phase->m_numMultiStepValues = phase->m_order;
260 phase->m_numMultiStepImplicitDerivs = 0;
261 phase->m_numMultiStepExplicitDerivs = phase->m_order;
262
263 phase->m_timeLevelOffset = Array<OneD, size_t>(phase->m_numsteps);
264
265 // Values and derivatives needed.
266 for (size_t n = 0; n < phase->m_order; ++n)
267 {
268 phase->m_timeLevelOffset[n] = n;
269 phase->m_timeLevelOffset[phase->m_order + n] = n;
270 }
271
272 phase->CheckAndVerify();
273 }
274
275protected:
276 LUE std::string v_GetFullName() const override
277 {
278 return m_integration_phases.back()->m_name;
279 }
280
281 LUE std::string v_GetName() const override
282 {
283 return std::string("IMEX");
284 }
285
287 {
288 return 1.0;
289 }
290
291}; // end class IMEXTimeIntegrationScheme
292
293////////////////////////////////////////////////////////////////////////////////
294// Backwards compatibility
296{
297public:
298 IMEXOrder1TimeIntegrationScheme(std::string variant, size_t order,
299 std::vector<NekDouble> freeParams)
300 : IMEXTimeIntegrationScheme("", 1, freeParams)
301 {
302 boost::ignore_unused(variant, order);
303 }
304
306 [[maybe_unused]] std::string variant, [[maybe_unused]] size_t order,
307 std::vector<NekDouble> freeParams)
308 {
311 "", 1, freeParams);
312 return p;
313 }
314
315 static std::string className;
316
317protected:
319
320}; // end class IMEXOrder1TimeIntegrationScheme
321
323{
324public:
325 IMEXOrder2TimeIntegrationScheme(std::string variant, size_t order,
326 std::vector<NekDouble> freeParams)
327 : IMEXTimeIntegrationScheme("", 2, freeParams)
328 {
329 boost::ignore_unused(variant, order);
330 }
331
333 [[maybe_unused]] std::string variant, [[maybe_unused]] size_t order,
334 std::vector<NekDouble> freeParams)
335 {
338 "", 2, freeParams);
339 return p;
340 }
341
342 static std::string className;
343
344protected:
346
347}; // end class IMEXOrder2TimeIntegrationScheme
348
350{
351public:
352 IMEXOrder3TimeIntegrationScheme(std::string variant, size_t order,
353 std::vector<NekDouble> freeParams)
354 : IMEXTimeIntegrationScheme("", 3, freeParams)
355 {
356 boost::ignore_unused(variant, order);
357 }
358
360 [[maybe_unused]] std::string variant, [[maybe_unused]] size_t order,
361 std::vector<NekDouble> freeParams)
362 {
365 "", 3, freeParams);
366 return p;
367 }
368
369 static std::string className;
370
371protected:
373
374}; // end class IMEXOrder3TimeIntegrationScheme
375
377{
378public:
379 IMEXOrder4TimeIntegrationScheme(std::string variant, size_t order,
380 std::vector<NekDouble> freeParams)
381 : IMEXTimeIntegrationScheme("", 4, freeParams)
382 {
383 boost::ignore_unused(variant, order);
384 }
385
387 [[maybe_unused]] std::string variant, [[maybe_unused]] size_t order,
388 std::vector<NekDouble> freeParams)
389 {
390
393 "", 4, freeParams);
394 return p;
395 }
396
397 static std::string className;
398
399protected:
401
402}; // end class IMEXOrder4TimeIntegrationScheme
403
404} // namespace Nektar::LibUtilities
405
406#endif
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:242
#define LUE
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase)
IMEXOrder1TimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
IMEXOrder2TimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
IMEXOrder3TimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
IMEXOrder4TimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
IMEXTimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase, size_t order)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase, size_t order, std::vector< NekDouble > freeParams)
static LUE void SetupSchemeData_1_1_1(TimeIntegrationAlgorithmGLMSharedPtr &phase)
Base class for GLM time integration schemes.
TimeIntegrationAlgorithmGLMVector m_integration_phases
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< TimeIntegrationAlgorithmGLM > TimeIntegrationAlgorithmGLMSharedPtr
@ eIMEX
Implicit Explicit General Linear Method.
std::vector< TimeIntegrationAlgorithmGLMSharedPtr > TimeIntegrationAlgorithmGLMVector
std::shared_ptr< TimeIntegrationScheme > TimeIntegrationSchemeSharedPtr
double NekDouble