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
47
50
51namespace Nektar
52{
53namespace LibUtilities
54{
55
56///////////////////////////////////////////////////////////////////////////////
57// IMEX Order N
58
60{
61public:
62 IMEXTimeIntegrationScheme(std::string variant, size_t order,
63 std::vector<NekDouble> freeParams)
64 : TimeIntegrationSchemeGLM(variant, order, freeParams)
65 {
66 if (variant == "dirk" || variant == "DIRK")
67 {
68 ASSERTL1(freeParams.size() == 2,
69 "IMEX DIRK Time integration scheme invalid number "
70 "of free parameters, expected two "
71 "<implicit stages, explicit stages>, received " +
72 std::to_string(freeParams.size()));
73
74 size_t s = freeParams[0];
75 size_t sigma = freeParams[1];
76
80
81 if (order == 1 && s == 1 && sigma == 1)
82 {
83 // This phase is Forward Backward Euler which has two steps.
86 }
87 else
88 {
90 m_integration_phases[0], order, freeParams);
91 }
92 }
93 else if (variant == "Gear")
94 {
100
102 m_integration_phases[0], 2, std::vector<NekDouble>{2, 2});
105 }
106 else if (variant == "")
107 {
108 // Currently up to 4th order is implemented.
109 ASSERTL1(1 <= order && order <= 4,
110 "IMEX Time integration scheme bad order (1-4): " +
111 std::to_string(order));
112
114
115 for (size_t n = 0; n < order; ++n)
116 {
119 }
120
121 // Last phase
123 m_integration_phases[order - 1], order);
124
125 // Initial phases
126 switch (order)
127 {
128 case 1:
129 // No intial phase.
130 break;
131
132 case 2:
135 break;
136
137 case 3:
140 std::vector<NekDouble>{3, 4});
143 std::vector<NekDouble>{3, 4});
144 break;
145
146 case 4:
149 std::vector<NekDouble>{3, 4});
152 std::vector<NekDouble>{3, 4});
155 std::vector<NekDouble>{3, 4});
156 break;
157
158 default:
159 ASSERTL1(false, "IMEX Time integration scheme bad order: " +
160 std::to_string(order));
161 }
162 }
163 else
164 {
165 ASSERTL1(false, "IMEX Time integration scheme bad variant: " +
166 variant + ". Must be blank, 'dirk' or 'Gear'");
167 }
168 }
169
171 {
172 }
173
175 std::string variant, size_t order, std::vector<NekDouble> freeParams)
176 {
179 variant, order, freeParams);
180
181 return p;
182 }
183
184 static std::string className;
185
187 size_t order)
188 {
189 constexpr NekDouble ABcoefficients[5] = {0.,
190 1., // 1st Order
191 2. / 3., // 2nd Order
192 6. / 11., // 3rd Order
193 12. / 25.}; // 4th Order
194
195 // Nsteps = 2 * order
196
197 // clang-format off
198 constexpr NekDouble UVcoefficients[5][8] =
199 { { 0., 0., 0., 0.,
200 0., 0., 0., 0. },
201 // 1st Order
202 { 1., 1., 0., 0.,
203 0., 0., 0., 0. },
204 // 2nd Order
205 { 4./ 3., -1./ 3., 4./3., -2./ 3.,
206 0., 0., 0., 0. },
207 // 3rd Order
208 { 18./11., -9./11., 2./11., 18./11.,
209 -18./11., 6./11., 0., 0. },
210 // 4th Order
211 { 48./25., -36./25., 16./25., -3./25.,
212 48./25., -72./25., 48./25., -12./25. } };
213 // clang-format on
214
215 phase->m_schemeType = eIMEX;
216 phase->m_order = order;
217 phase->m_name =
218 std::string("IMEXOrder" + std::to_string(phase->m_order));
219
220 phase->m_numsteps = 2 * phase->m_order;
221 phase->m_numstages = 1;
222
223 phase->m_A = Array<OneD, Array<TwoD, NekDouble>>(2);
224 phase->m_B = Array<OneD, Array<TwoD, NekDouble>>(2);
225
226 phase->m_A[0] =
227 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
228 phase->m_B[0] =
229 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
230 phase->m_A[1] =
231 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
232 phase->m_B[1] =
233 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
234 phase->m_U =
235 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numsteps, 0.0);
236 phase->m_V =
237 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numsteps, 0.0);
238
239 // Coefficients
240 phase->m_B[1][phase->m_order][0] = 1.0;
241
242 phase->m_A[0][0][0] = ABcoefficients[phase->m_order];
243 phase->m_B[0][0][0] = ABcoefficients[phase->m_order];
244
245 for (size_t n = 0; n < 2 * phase->m_order; ++n)
246 {
247 phase->m_U[0][n] = UVcoefficients[phase->m_order][n];
248 phase->m_V[0][n] = UVcoefficients[phase->m_order][n];
249 }
250
251 // V evaluation value shuffling row n column n-1
252 for (size_t n = 1; n < 2 * phase->m_order; ++n)
253 {
254 if (n != phase->m_order)
255 phase->m_V[n][n - 1] = 1.0; // constant 1
256 }
257
258 phase->m_numMultiStepValues = phase->m_order;
259 phase->m_numMultiStepImplicitDerivs = 0;
260 phase->m_numMultiStepExplicitDerivs = phase->m_order;
261
262 phase->m_timeLevelOffset = Array<OneD, size_t>(phase->m_numsteps);
263
264 // Values and derivatives needed.
265 for (size_t n = 0; n < phase->m_order; ++n)
266 {
267 phase->m_timeLevelOffset[n] = n;
268 phase->m_timeLevelOffset[phase->m_order + n] = n;
269 }
270
271 phase->CheckAndVerify();
272 }
273
274protected:
275 LUE virtual std::string v_GetFullName() const override
276 {
277 return m_integration_phases.back()->m_name;
278 }
279
280 LUE virtual std::string v_GetName() const override
281 {
282 return std::string("IMEX");
283 }
284
285 LUE virtual NekDouble v_GetTimeStability() const override
286 {
287 return 1.0;
288 }
289
290}; // end class IMEXTimeIntegrationScheme
291
292////////////////////////////////////////////////////////////////////////////////
293// Backwards compatibility
295{
296public:
297 IMEXOrder1TimeIntegrationScheme(std::string variant, size_t order,
298 std::vector<NekDouble> freeParams)
299 : IMEXTimeIntegrationScheme("", 1, freeParams)
300 {
301 boost::ignore_unused(variant);
302 boost::ignore_unused(order);
303 }
304
306 std::string variant, size_t order, std::vector<NekDouble> freeParams)
307 {
308 boost::ignore_unused(variant);
309 boost::ignore_unused(order);
310
313 "", 1, freeParams);
314 return p;
315 }
316
317 static std::string className;
318
319protected:
321
322}; // end class IMEXOrder1TimeIntegrationScheme
323
325{
326public:
327 IMEXOrder2TimeIntegrationScheme(std::string variant, size_t order,
328 std::vector<NekDouble> freeParams)
329 : IMEXTimeIntegrationScheme("", 2, freeParams)
330 {
331 boost::ignore_unused(variant);
332 boost::ignore_unused(order);
333 }
334
336 std::string variant, size_t order, std::vector<NekDouble> freeParams)
337 {
338 boost::ignore_unused(variant);
339 boost::ignore_unused(order);
340
343 "", 2, freeParams);
344 return p;
345 }
346
347 static std::string className;
348
349protected:
351
352}; // end class IMEXOrder2TimeIntegrationScheme
353
355{
356public:
357 IMEXOrder3TimeIntegrationScheme(std::string variant, size_t order,
358 std::vector<NekDouble> freeParams)
359 : IMEXTimeIntegrationScheme("", 3, freeParams)
360 {
361 boost::ignore_unused(variant);
362 boost::ignore_unused(order);
363 }
364
366 std::string variant, size_t order, std::vector<NekDouble> freeParams)
367 {
368 boost::ignore_unused(variant);
369 boost::ignore_unused(order);
370
373 "", 3, freeParams);
374 return p;
375 }
376
377 static std::string className;
378
379protected:
381
382}; // end class IMEXOrder3TimeIntegrationScheme
383
385{
386public:
387 IMEXOrder4TimeIntegrationScheme(std::string variant, size_t order,
388 std::vector<NekDouble> freeParams)
389 : IMEXTimeIntegrationScheme("", 4, freeParams)
390 {
391 boost::ignore_unused(variant);
392 boost::ignore_unused(order);
393 }
394
396 std::string variant, size_t order, std::vector<NekDouble> freeParams)
397 {
398 boost::ignore_unused(variant);
399 boost::ignore_unused(order);
400
403 "", 4, freeParams);
404 return p;
405 }
406
407 static std::string className;
408
409protected:
411
412}; // end class IMEXOrder4TimeIntegrationScheme
413
414} // end namespace LibUtilities
415} // end namespace Nektar
416
417#endif
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
#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)
virtual LUE std::string v_GetFullName() const override
virtual LUE std::string v_GetName() const override
virtual LUE NekDouble v_GetTimeStability() const override
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
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble