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 
48 
51 
52 namespace Nektar
53 {
54 namespace LibUtilities
55 {
56 
57 ///////////////////////////////////////////////////////////////////////////////
58 // IMEX Order N
59 
61 {
62 public:
63  IMEXTimeIntegrationScheme(std::string variant, unsigned int order,
64  std::vector<NekDouble> freeParams)
65  : TimeIntegrationSchemeGLM(variant, order, freeParams)
66  {
67  if (variant == "dirk" || variant == "DIRK")
68  {
69  ASSERTL1(freeParams.size() == 2,
70  "IMEX DIRK Time integration scheme invalid number "
71  "of free parameters, expected two "
72  "<implicit stages, explicit stages>, received " +
73  std::to_string(freeParams.size()));
74 
75  int s = freeParams[0];
76  int sigma = freeParams[1];
77 
80  new TimeIntegrationAlgorithmGLM(this));
81 
82  if (order == 1 && s == 1 && sigma == 1)
83  {
84  // This phase is Forward Backward Euler which has two steps.
87  }
88  else
89  {
91  m_integration_phases[0], order, freeParams);
92  }
93  }
94  else if (variant == "Gear")
95  {
98  new TimeIntegrationAlgorithmGLM(this));
100  new TimeIntegrationAlgorithmGLM(this));
101 
103  m_integration_phases[0], 2, std::vector<NekDouble>{2, 2});
106  }
107  else if (variant == "")
108  {
109  // Currently up to 4th order is implemented.
110  ASSERTL1(1 <= order && order <= 4,
111  "IMEX Time integration scheme bad order (1-4): " +
112  std::to_string(order));
113 
115 
116  for (unsigned int n = 0; n < order; ++n)
117  {
119  new TimeIntegrationAlgorithmGLM(this));
120  }
121 
122  // Last phase
124  m_integration_phases[order - 1], order);
125 
126  // Initial phases
127  switch (order)
128  {
129  case 1:
130  // No intial phase.
131  break;
132 
133  case 2:
135  m_integration_phases[0], 1);
136  // IMEXdirkTimeIntegrationScheme::SetupSchemeData(
137  // m_integration_phases[0], 2, std::vector<NekDouble>
138  // {2, 3});
139  break;
140 
141  case 3:
143  m_integration_phases[0], 3,
144  std::vector<NekDouble>{3, 4});
146  m_integration_phases[1], 3,
147  std::vector<NekDouble>{3, 4});
148  break;
149 
150  case 4:
152  m_integration_phases[0], 3,
153  std::vector<NekDouble>{3, 4});
155  m_integration_phases[1], 3,
156  std::vector<NekDouble>{3, 4});
158  m_integration_phases[2], 3,
159  std::vector<NekDouble>{3, 4});
160  break;
161 
162  default:
163  ASSERTL1(false, "IMEX Time integration scheme bad order: " +
164  std::to_string(order));
165  }
166  }
167  else
168  {
169  ASSERTL1(false, "IMEX Time integration scheme bad variant: " +
170  variant + ". Must be blank, 'dirk' or 'Gear'");
171  }
172  }
173 
175  {
176  }
177 
179  std::string variant, unsigned int order,
180  std::vector<NekDouble> freeParams)
181  {
184  variant, order, freeParams);
185 
186  return p;
187  }
188 
189  static std::string className;
190 
192  int order)
193  {
194  const NekDouble ABcoefficients[5] = {0.,
195  1., // 1st Order
196  2. / 3., // 2nd Order
197  6. / 11., // 3rd Order
198  12. / 25.}; // 4th Order
199 
200  // Nsteps = 2 * order
201 
202  // clang-format off
203  const NekDouble UVcoefficients[5][8] =
204  { { 0., 0., 0., 0.,
205  0., 0., 0., 0. },
206  // 1st Order
207  { 1., 1., 0., 0.,
208  0., 0., 0., 0. },
209  // 2nd Order
210  { 4./ 3., -1./ 3., 4./3., -2./ 3.,
211  0., 0., 0., 0. },
212  // 3rd Order
213  { 18./11., -9./11., 2./11., 18./11.,
214  -18./11., 6./11., 0., 0. },
215  // 4th Order
216  { 48./25., -36./25., 16./25., -3./25.,
217  48./25., -72./25., 48./25., -12./25. } };
218  // clang-format on
219 
220  phase->m_schemeType = eIMEX;
221  phase->m_order = order;
222  phase->m_name =
223  std::string("IMEXOrder" + std::to_string(phase->m_order));
224 
225  phase->m_numsteps = 2 * phase->m_order;
226  phase->m_numstages = 1;
227 
228  phase->m_A = Array<OneD, Array<TwoD, NekDouble>>(2);
229  phase->m_B = Array<OneD, Array<TwoD, NekDouble>>(2);
230 
231  phase->m_A[0] =
232  Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
233  phase->m_B[0] =
234  Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
235  phase->m_A[1] =
236  Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
237  phase->m_B[1] =
238  Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
239  phase->m_U =
240  Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numsteps, 0.0);
241  phase->m_V =
242  Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numsteps, 0.0);
243 
244  // Coefficients
245  phase->m_B[1][phase->m_order][0] = 1.0;
246 
247  phase->m_A[0][0][0] = ABcoefficients[phase->m_order];
248  phase->m_B[0][0][0] = ABcoefficients[phase->m_order];
249 
250  for (int n = 0; n < 2 * phase->m_order; ++n)
251  {
252  phase->m_U[0][n] = UVcoefficients[phase->m_order][n];
253  phase->m_V[0][n] = UVcoefficients[phase->m_order][n];
254  }
255 
256  // V evaluation value shuffling row n column n-1
257  for (int n = 1; n < 2 * phase->m_order; ++n)
258  {
259  if (n != phase->m_order)
260  phase->m_V[n][n - 1] = 1.0; // constant 1
261  }
262 
263  phase->m_numMultiStepValues = phase->m_order;
264  phase->m_numMultiStepImplicitDerivs = 0;
265  phase->m_numMultiStepDerivs = phase->m_order;
266 
267  phase->m_timeLevelOffset = Array<OneD, unsigned int>(phase->m_numsteps);
268 
269  // Values and derivatives needed.
270  for (int n = 0; n < phase->m_order; ++n)
271  {
272  phase->m_timeLevelOffset[n] = n;
273  phase->m_timeLevelOffset[phase->m_order + n] = n;
274  }
275 
276  phase->CheckAndVerify();
277  }
278 
279 protected:
280  LUE virtual std::string v_GetFullName() const override
281  {
282  return m_integration_phases[m_integration_phases.size() - 1]->m_name;
283  }
284 
285  LUE virtual std::string v_GetName() const override
286  {
287  return std::string("IMEX");
288  }
289 
290  LUE virtual NekDouble v_GetTimeStability() const override
291  {
292  return 1.0;
293  }
294 
295 }; // end class IMEXTimeIntegrationScheme
296 
297 ////////////////////////////////////////////////////////////////////////////////
298 // Backwards compatibility
300 {
301 public:
302  IMEXOrder1TimeIntegrationScheme(std::string variant, unsigned int order,
303  std::vector<NekDouble> freeParams)
304  : IMEXTimeIntegrationScheme("", 1, freeParams)
305  {
306  boost::ignore_unused(variant);
307  boost::ignore_unused(order);
308  }
309 
311  std::string variant, unsigned int order,
312  std::vector<NekDouble> freeParams)
313  {
314  boost::ignore_unused(variant);
315  boost::ignore_unused(order);
316 
319  "", 1, freeParams);
320  return p;
321  }
322 
323  static std::string className;
324 
325 }; // end class IMEXOrder1TimeIntegrationScheme
326 
328 {
329 public:
330  IMEXOrder2TimeIntegrationScheme(std::string variant, unsigned int order,
331  std::vector<NekDouble> freeParams)
332  : IMEXTimeIntegrationScheme("", 2, freeParams)
333  {
334  boost::ignore_unused(variant);
335  boost::ignore_unused(order);
336  }
337 
339  std::string variant, unsigned int order,
340  std::vector<NekDouble> freeParams)
341  {
342  boost::ignore_unused(variant);
343  boost::ignore_unused(order);
344 
347  "", 2, freeParams);
348  return p;
349  }
350 
351  static std::string className;
352 
353 }; // end class IMEXOrder2TimeIntegrationScheme
354 
356 {
357 public:
358  IMEXOrder3TimeIntegrationScheme(std::string variant, unsigned int order,
359  std::vector<NekDouble> freeParams)
360  : IMEXTimeIntegrationScheme("", 3, freeParams)
361  {
362  boost::ignore_unused(variant);
363  boost::ignore_unused(order);
364  }
365 
367  std::string variant, unsigned int order,
368  std::vector<NekDouble> freeParams)
369  {
370  boost::ignore_unused(variant);
371  boost::ignore_unused(order);
372 
375  "", 3, freeParams);
376  return p;
377  }
378 
379  static std::string className;
380 
381 }; // end class IMEXOrder3TimeIntegrationScheme
382 
384 {
385 public:
386  IMEXOrder4TimeIntegrationScheme(std::string variant, unsigned int order,
387  std::vector<NekDouble> freeParams)
388  : IMEXTimeIntegrationScheme("", 4, freeParams)
389  {
390  boost::ignore_unused(variant);
391  boost::ignore_unused(order);
392  }
393 
395  std::string variant, unsigned int order,
396  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 
409 }; // end class IMEXOrder4TimeIntegrationScheme
410 
411 } // end namespace LibUtilities
412 } // end namespace Nektar
413 
414 #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)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
IMEXOrder1TimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
IMEXOrder2TimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
IMEXOrder3TimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
IMEXOrder4TimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
IMEXTimeIntegrationScheme(std::string variant, unsigned int 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
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase, int order)
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase, unsigned int 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