Nektar++
Loading...
Searching...
No Matches
IMEXdirkTimeIntegrationSchemes.h
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: IMEXdirkTimeIntegrationSchemes.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 IMEX Dirk based 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_DIRK_TIME_INTEGRATION_SCHEME
42#define NEKTAR_LIB_UTILITIES_TIME_INTEGRATION_IMEX_DIRK_TIME_INTEGRATION_SCHEME
43
44#define LUE LIB_UTILITIES_EXPORT
45
47
49{
50
51///////////////////////////////////////////////////////////////////////////////
52// IMEXDirk-(s, sigma, p), where s is the number of stages of the
53// implicit scheme, sigma is the number of stages of the explicit
54// scheme and p is the combined order of the scheme.
55
57{
58public:
59 IMEXdirkTimeIntegrationScheme(std::string variant, size_t order,
60 std::vector<NekDouble> freeParams)
61 : TimeIntegrationSchemeGLM(variant, order, freeParams)
62 {
63 ASSERTL1(freeParams.size() == 2,
64 "IMEX DIRK Time integration scheme invalid number "
65 "of free parameters, expected two "
66 "<implicit stages, explicit stages>, received " +
67 std::to_string(freeParams.size()));
68
69 size_t s = freeParams[0];
70 size_t sigma = freeParams[1];
71
75
76 if (order == 1 && s == 1 && sigma == 1)
77 {
78 // This phase is Forward Backward Euler which has two steps.
81 }
82 else
83 {
85 m_integration_phases[0], order, freeParams);
86 }
87 }
88
89 ~IMEXdirkTimeIntegrationScheme() override = default;
90
92 std::string variant, size_t order, std::vector<NekDouble> freeParams)
93 {
96 variant, order, freeParams);
97
98 return p;
99 }
100
101 static std::string className;
102
104 size_t order,
105 std::vector<NekDouble> freeParams)
106 {
107 ASSERTL1(freeParams.size() == 2,
108 "IMEX DIRK Time integration scheme invalid number "
109 "of free parameters, expected two "
110 "<implicit stages, explicit stages>, received " +
111 std::to_string(freeParams.size()) + ".");
112
113 size_t s = freeParams[0];
114 size_t sigma = freeParams[1];
115
116 phase->m_schemeType = eIMEX;
117 phase->m_variant = "DIRK";
118 phase->m_order = order;
119 phase->m_name = "IMEX_DIRK"
120 "_" +
121 std::to_string(s) + "_" + std::to_string(sigma) + "_" +
122 std::to_string(phase->m_order);
123
124 phase->m_numsteps = 1;
125 phase->m_numstages = s + 1;
126
127 phase->m_A = Array<OneD, Array<TwoD, NekDouble>>(2);
128 phase->m_B = Array<OneD, Array<TwoD, NekDouble>>(2);
129
130 phase->m_A[0] =
131 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
132 phase->m_B[0] =
133 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
134 phase->m_A[1] =
135 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
136 phase->m_B[1] =
137 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
138 phase->m_U =
139 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numsteps, 1.0);
140 phase->m_V =
141 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numsteps, 1.0);
142
143 if (s == 1 && sigma == 2 && order == 1)
144 {
146 }
147 else if (s == 1 && sigma == 2 && order == 2)
148 {
150 }
151 else if (s == 2 && sigma == 2 && order == 2)
152 {
154 }
155 else if (s == 2 && sigma == 3 && order == 2)
156 {
158 }
159 else if (s == 2 && sigma == 3 && order == 3)
160 {
162 }
163 else if (s == 3 && sigma == 4 && order == 3)
164 {
166 }
167 else if (s == 4 && sigma == 4 && order == 3)
168 {
170 }
171 else
172 {
173 ASSERTL1(false,
174 "IMEX DIRK Time integration scheme bad type "
175 "(s, sigma, order) : (" +
176 std::to_string(s) + "," + std::to_string(sigma) + "," +
177 std::to_string(order) + "). " +
178 "Allowed combinations: (1,1,1), (1,2,1), (1,2,2), "
179 "(2,2,2), (2,3,2), (2,3,3), (3,4,3), (4,4,3)");
180 }
181
182 phase->m_numMultiStepValues = 1;
183 phase->m_numMultiStepImplicitDerivs = 0;
184 phase->m_numMultiStepExplicitDerivs = 0;
185 phase->m_timeLevelOffset = Array<OneD, size_t>(phase->m_numsteps);
186 phase->m_timeLevelOffset[0] = 0;
187
188 phase->CheckAndVerify();
189 }
190
191 ///////////////////////////////////////////////////////////////////////////////
192 // IMEX Dirk 1 1 1 : Forward - Backward Euler IMEX
195 {
196 phase->m_schemeType = eIMEX;
197 phase->m_order = 1;
198 phase->m_name =
199 std::string("IMEXdirk_1_1_" + std::to_string(phase->m_order));
200
201 phase->m_numsteps = 2;
202 phase->m_numstages = 1;
203
204 phase->m_A = Array<OneD, Array<TwoD, NekDouble>>(2);
205 phase->m_B = Array<OneD, Array<TwoD, NekDouble>>(2);
206
207 phase->m_A[0] =
208 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
209 phase->m_B[0] =
210 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
211 phase->m_A[1] =
212 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
213 phase->m_B[1] =
214 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
215 phase->m_U =
216 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numsteps, 0.0);
217 phase->m_V =
218 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numsteps, 0.0);
219
220 phase->m_A[0][0][0] = 1.0;
221
222 phase->m_B[0][0][0] = 1.0;
223 phase->m_B[1][1][0] = 1.0;
224
225 phase->m_U[0][0] = 1.0;
226 phase->m_U[0][1] = 1.0;
227
228 phase->m_V[0][0] = 1.0;
229 phase->m_V[0][1] = 1.0;
230
231 phase->m_numMultiStepValues = 1;
232 phase->m_numMultiStepImplicitDerivs = 0;
233 phase->m_numMultiStepExplicitDerivs = 1;
234
235 phase->m_timeLevelOffset = Array<OneD, size_t>(phase->m_numsteps);
236 phase->m_timeLevelOffset[0] = 0;
237 phase->m_timeLevelOffset[1] = 0;
238
239 phase->CheckAndVerify();
240 }
241
242 ///////////////////////////////////////////////////////////////////////////////
243 // IMEX Dirk 1 2 1 : Forward - Backward Euler IMEX w/B implicit == B
244 // explicit
247 {
248 phase->m_A[0][1][1] = 1.0;
249 phase->m_B[0][0][1] = 1.0;
250
251 phase->m_A[1][1][0] = 1.0;
252 phase->m_B[1][0][1] = 1.0;
253
254 // U and V set to 1 when allocated.
255 }
256
257 ////////////////////////////////////////////////////////////////////////////
258 // IMEX Dirk 1 2 2 : Implict-Explicit Midpoint IMEX
261 {
262 phase->m_A[0][1][1] = 1.0 / 2.0;
263 phase->m_B[0][0][1] = 1.0;
264
265 phase->m_A[1][1][0] = 1.0 / 2.0;
266 phase->m_B[1][0][1] = 1.0;
267
268 // U and V set to 1 when allocated.
269 }
270
271 ////////////////////////////////////////////////////////////////////////////
272 // IMEX Dirk 2 2 2 : L Stable, two stage, second order IMEX
275 {
276 const NekDouble glambda = 1.0 - sqrt(2.0) / 2.0;
277 const NekDouble gdelta = -sqrt(2.0) / 2.0;
278
279 phase->m_A[0][1][1] = glambda;
280 phase->m_A[0][2][1] = 1.0 - glambda;
281 phase->m_A[0][2][2] = glambda;
282
283 phase->m_B[0][0][1] = 1.0 - glambda;
284 phase->m_B[0][0][2] = glambda;
285
286 phase->m_A[1][1][0] = glambda;
287 phase->m_A[1][2][0] = gdelta;
288 phase->m_A[1][2][1] = 1.0 - gdelta;
289
290 phase->m_B[1][0][0] = gdelta;
291 phase->m_B[1][0][1] = 1.0 - gdelta;
292
293 // U and V set to 1 when allocated.
294 }
295
296 ////////////////////////////////////////////////////////////////////////////
297 // IMEX Dirk 2 3 2 : L Stable, two stage, second order IMEX
300 {
301 const NekDouble lambda = (2.0 - sqrt(2.0)) / 2.0;
302 const NekDouble delta = -2.0 * sqrt(2.0) / 3.0;
303
304 phase->m_A[0][1][1] = lambda;
305 phase->m_A[0][2][1] = 1.0 - lambda;
306 phase->m_A[0][2][2] = lambda;
307
308 phase->m_B[0][0][1] = 1.0 - lambda;
309 phase->m_B[0][0][2] = lambda;
310
311 phase->m_A[1][1][0] = lambda;
312 phase->m_A[1][2][0] = delta;
313 phase->m_A[1][2][1] = 1.0 - delta;
314
315 phase->m_B[1][0][1] = 1.0 - lambda;
316 phase->m_B[1][0][2] = lambda;
317
318 // U and V set to 1 when allocated.
319 }
320
321 ////////////////////////////////////////////////////////////////////////////
322 // IMEX Dirk 2 3 3 : L Stable, two stage, third order IMEX
325 {
326 const NekDouble glambda = (3.0 + sqrt(3.0)) / 6.0;
327
328 phase->m_A[0][1][1] = glambda;
329 phase->m_A[0][2][1] = 1.0 - 2.0 * glambda;
330 phase->m_A[0][2][2] = glambda;
331
332 phase->m_B[0][0][1] = 0.5;
333 phase->m_B[0][0][2] = 0.5;
334
335 phase->m_A[1][1][0] = glambda;
336 phase->m_A[1][2][0] = glambda - 1.0;
337 phase->m_A[1][2][1] = 2.0 * (1.0 - glambda);
338
339 phase->m_B[1][0][1] = 0.5;
340 phase->m_B[1][0][2] = 0.5;
341
342 // U and V set to 1 when allocated.
343 }
344
345 ////////////////////////////////////////////////////////////////////////////
346 // IMEX Dirk 3 4 3 : L Stable, three stage, third order IMEX
349 {
350 constexpr NekDouble lambda = 0.4358665215;
351
352 phase->m_A[0][1][1] = lambda;
353 phase->m_A[0][2][1] = 0.5 * (1.0 - lambda);
354 phase->m_A[0][2][2] = lambda;
355 phase->m_A[0][3][1] =
356 0.25 * (-6.0 * lambda * lambda + 16.0 * lambda - 1.0);
357 phase->m_A[0][3][2] =
358 0.25 * (6.0 * lambda * lambda - 20.0 * lambda + 5.0);
359 phase->m_A[0][3][3] = lambda;
360
361 phase->m_B[0][0][1] =
362 0.25 * (-6.0 * lambda * lambda + 16.0 * lambda - 1.0);
363 phase->m_B[0][0][2] =
364 0.25 * (6.0 * lambda * lambda - 20.0 * lambda + 5.0);
365 phase->m_B[0][0][3] = lambda;
366
367 phase->m_A[1][1][0] = 0.4358665215;
368 phase->m_A[1][2][0] = 0.3212788860;
369 phase->m_A[1][2][1] = 0.3966543747;
370 phase->m_A[1][3][0] = -0.105858296;
371 phase->m_A[1][3][1] = 0.5529291479;
372 phase->m_A[1][3][2] = 0.5529291479;
373
374 phase->m_B[1][0][1] =
375 0.25 * (-6.0 * lambda * lambda + 16.0 * lambda - 1.0);
376 phase->m_B[1][0][2] =
377 0.25 * (6.0 * lambda * lambda - 20.0 * lambda + 5.0);
378 phase->m_B[1][0][3] = lambda;
379
380 // U and V set to 1 when allocated.
381 }
382
383 ////////////////////////////////////////////////////////////////////////////
384 // IMEX Dirk 4 4 3 : L Stable, four stage, third order IMEX
387 {
388 phase->m_A[0][1][1] = 1.0 / 2.0;
389 phase->m_A[0][2][1] = 1.0 / 6.0;
390 phase->m_A[0][2][2] = 1.0 / 2.0;
391 phase->m_A[0][3][1] = -1.0 / 2.0;
392 phase->m_A[0][3][2] = 1.0 / 2.0;
393 phase->m_A[0][3][3] = 1.0 / 2.0;
394 phase->m_A[0][4][1] = 3.0 / 2.0;
395 phase->m_A[0][4][2] = -3.0 / 2.0;
396 phase->m_A[0][4][3] = 1.0 / 2.0;
397 phase->m_A[0][4][4] = 1.0 / 2.0;
398
399 phase->m_B[0][0][1] = 3.0 / 2.0;
400 phase->m_B[0][0][2] = -3.0 / 2.0;
401 phase->m_B[0][0][3] = 1.0 / 2.0;
402 phase->m_B[0][0][4] = 1.0 / 2.0;
403
404 phase->m_A[1][1][0] = 1.0 / 2.0;
405 phase->m_A[1][2][0] = 11.0 / 18.0;
406 phase->m_A[1][2][1] = 1.0 / 18.0;
407 phase->m_A[1][3][0] = 5.0 / 6.0;
408 phase->m_A[1][3][1] = -5.0 / 6.0;
409 phase->m_A[1][3][2] = 1.0 / 2.0;
410 phase->m_A[1][4][0] = 1.0 / 4.0;
411 phase->m_A[1][4][1] = 7.0 / 4.0;
412 phase->m_A[1][4][2] = 3.0 / 4.0;
413 phase->m_A[1][4][3] = -7.0 / 4.0;
414
415 phase->m_B[1][0][0] = 1.0 / 4.0;
416 phase->m_B[1][0][1] = 7.0 / 4.0;
417 phase->m_B[1][0][2] = 3.0 / 4.0;
418 phase->m_B[1][0][3] = -7.0 / 4.0;
419
420 // U and V set to 1 when allocated.
421 }
422
423protected:
424 LUE std::string v_GetFullName() const override
425 {
426 return m_integration_phases.back()->m_name;
427 }
428
429 LUE std::string v_GetName() const override
430 {
431 return std::string("IMEX");
432 }
433
435 {
436 return 1.0;
437 }
438
439}; // end class IMEXdirkTimeIntegrationScheme
440
441} // namespace Nektar::LibUtilities
442
443#endif
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase, size_t order, std::vector< NekDouble > freeParams)
static LUE void SetupSchemeData_2_2_2(TimeIntegrationAlgorithmGLMSharedPtr &phase)
IMEXdirkTimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static LUE void SetupSchemeData_1_2_2(TimeIntegrationAlgorithmGLMSharedPtr &phase)
static LUE void SetupSchemeData_2_3_3(TimeIntegrationAlgorithmGLMSharedPtr &phase)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static LUE void SetupSchemeData_2_3_2(TimeIntegrationAlgorithmGLMSharedPtr &phase)
static LUE void SetupSchemeData_3_4_3(TimeIntegrationAlgorithmGLMSharedPtr &phase)
static LUE void SetupSchemeData_1_1_1(TimeIntegrationAlgorithmGLMSharedPtr &phase)
static LUE void SetupSchemeData_4_4_3(TimeIntegrationAlgorithmGLMSharedPtr &phase)
static LUE void SetupSchemeData_1_2_1(TimeIntegrationAlgorithmGLMSharedPtr &phase)
Base class for GLM time integration schemes.
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
scalarT< T > sqrt(scalarT< T > in)
Definition scalar.hpp:290