Nektar++
kernel.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: kernel.cpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Scientific Computing and Imaging Institute,
10 // University of Utah (USA) and Department of Aeronautics, Imperial
11 // College London (UK).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description:
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
36 
37 namespace Nektar
38 {
39 namespace LibUtilities
40 {
41 Kernel::Kernel(int order)
42 {
43  UpdateKernelOrder(order);
48  k_center = 0.0;
49 }
50 
52 {
54 
55  int i, j;
56 
57  if (k_order == 1.0)
58  {
59  b_spline[0][0] = 1.0;
60  }
61  else if (k_order == 2)
62  {
63  NekDouble out[2][2] = {{1.0, 0.0}, {-1.0, 1.0}};
64  for (i = 0; i < k_order; i++)
65  {
66  for (j = 0; j < k_order; j++)
67  {
68  out_final[i][j] = out[i][j];
69  }
70  }
71  }
72  else if (k_order == 3)
73  {
74  NekDouble out[3][3] = {
75  {0.5, 0.0, 0.0}, {-1.0, 1.0, 0.5}, {0.5, -1.0, 0.5}};
76  for (i = 0; i < k_order; i++)
77  {
78  for (j = 0; j < k_order; j++)
79  {
80  out_final[i][j] = out[i][j];
81  }
82  }
83  }
84  else if (k_order == 4)
85  {
86  NekDouble out[4][4] = {{1.0 / 6.0, 0, 0, 0},
87  {-0.5, 0.5, 0.5, 1.0 / 6.0},
88  {0.5, -1.0, 0, 2.0 / 3},
89  {-1.0 / 6.0, 0.5, -0.5, 1.0 / 6.0}};
90  for (i = 0; i < k_order; i++)
91  {
92  for (j = 0; j < k_order; j++)
93  {
94  out_final[i][j] = out[i][j];
95  }
96  }
97  }
98  else if (k_order == 5)
99  {
100  NekDouble out[5][5] = {
101  {1.0 / 24.0, 0, 0, 0, 0},
102  {-1.0 / 6, 1.0 / 6, 0.25, 1.0 / 6, 1.0 / 24},
103  {0.25, -0.5, -0.25, 0.5, 11.0 / 24},
104  {-1.0 / 6, 0.5, -0.25, -0.5, 11.0 / 24},
105  {1.0 / 24, -1.0 / 6.0, 0.25, -1.0 / 6, 1.0 / 24}};
106  for (i = 0; i < k_order; i++)
107  {
108  for (j = 0; j < k_order; j++)
109  {
110  out_final[i][j] = out[i][j];
111  }
112  }
113  }
114  else if (k_order == 6)
115  {
116  NekDouble out[6][6] = {
117  {1.0 / 1.020, 0, 0, 0, 0, 0},
118  {-1.0 / 24, 1.0 / 24, 1.0 / 12, 1.0 / 12, 1.0 / 24, 1.0 / 120},
119  {1.0 / 12, -1.0 / 6, -1.0 / 6, 1.0 / 6, 5.0 / 12, 13.0 / 60},
120  {-1.0 / 12, 0.25, 0, -1.0 / 2, 0, 11.0 / 20},
121  {1.0 / 24, -1.0 / 6, 1.0 / 6, 1.0 / 6, -5.0 / 12, 13.0 / 60},
122  {-1.0 / 120, 1.0 / 24, -1.0 / 12, 1.0 / 12, -1.0 / 24, 1.0 / 120}};
123  for (i = 0; i < k_order; i++)
124  {
125  for (j = 0; j < k_order; j++)
126  {
127  out_final[i][j] = out[i][j];
128  }
129  }
130  }
131  else if (k_order == 7)
132  {
133  NekDouble out[7][7] = {{1.0 / 720, 0, 0, 0, 0, 0, 0},
134  {-1.0 / 120, 1.0 / 120, 1.0 / 48, 1.0 / 36,
135  1.0 / 48, 1.0 / 120, 1.0 / 720},
136  {1.0 / 48, -1.0 / 24, -1.0 / 16, 1.0 / 36,
137  3.0 / 16, 5.0 / 24, 19.0 / 240},
138  {-1.0 / 36, 1.0 / 1.02, 1.0 / 24, -2.0 / 9,
139  -5.0 / 24, 1.0 / 3, 151.0 / 360},
140  {1.0 / 48, -1.0 / 12, 1.0 / 24, 2.0 / 9,
141  -5.0 / 24, -1.0 / 3, 151.0 / 360},
142  {-1.0 / 120, 1.0 / 24, -1.0 / 16, -1.0 / 36,
143  3.0 / 16, -5.0 / 24, 19.0 / 240},
144  {1.0 / 720, -1.0 / 120, 1.0 / 48, -1.0 / 36,
145  1.0 / 48, -1.0 / 120, 1.0 / 720}};
146  for (i = 0; i < k_order; i++)
147  {
148  for (j = 0; j < k_order; j++)
149  {
150  out_final[i][j] = out[i][j];
151  }
152  }
153  }
154  else if (k_order == 8)
155  {
156  NekDouble out[8][8] = {
157  {1.0 / 5040, 0, 0, 0, 0, 0, 0, 0},
158  {-1.0 / 720, 1.0 / 720, 1.0 / 240, 1.0 / 144, 1.0 / 144, 1.0 / 240,
159  1.0 / 720, 1.0 / 5040},
160  {1.0 / 240, -1.0 / 120, -1.0 / 60, 0, 1.0 / 18, 1.0 / 10, 7.0 / 90,
161  1.0 / 42},
162  {-1.0 / 144, 1.0 / 48, 1.0 / 48, -1.0 / 16, -19.0 / 144, 1.0 / 16,
163  49.0 / 144, 397.0 / 1680},
164  {1.0 / 144, -1.0 / 36, 0, 1.0 / 9, 0, -1.0 / 3, 0, 151.0 / 315},
165  {-1.0 / 240, 1.0 / 48, -1.0 / 48, -1.0 / 16, 19.0 / 144, 1.0 / 16,
166  -49.0 / 144, 397.0 / 1680},
167  {1.0 / 720, -1.0 / 120, 1.0 / 60, 0, -1.0 / 18, 1.0 / 10, -7.0 / 90,
168  1.0 / 42},
169  {-1.0 / 5040, 1.0 / 720, -1.0 / 240, 1.0 / 144, -1.0 / 144,
170  1.0 / 240, -1.0 / 720, 1.0 / 5040}};
171  for (i = 0; i < k_order; i++)
172  {
173  for (j = 0; j < k_order; j++)
174  {
175  out_final[i][j] = out[i][j];
176  }
177  }
178  }
179 
180  b_spline = out_final;
181 
182  ASSERTL0(k_order <= 8, "Order is not supported");
183 }
184 
186 {
187  int i;
189 
190  if (k_order == 2)
191  {
192  NekDouble out[3] = {-1.0 / 12, 7.0 / 6, -1.0 / 12};
193  for (i = 0; i < k_ncoeffs; i++)
194  {
195  out_final[i] = out[i];
196  }
197  }
198  else if (k_order == 3)
199  {
200  NekDouble out[5] = {37.0 / 1920, -97.0 / 480, 437.0 / 320, -97.0 / 480,
201  37.0 / 1920};
202  for (i = 0; i < k_ncoeffs; i++)
203  {
204  out_final[i] = out[i];
205  }
206  }
207  else if (k_order == 4)
208  {
209  NekDouble out[7] = {-41.0 / 7560, 311.0 / 5040, -919.0 / 2520,
210  12223.0 / 7560, -919.0 / 2520, 311.0 / 5040,
211  -41.0 / 7560};
212  for (i = 0; i < k_ncoeffs; i++)
213  {
214  out_final[i] = out[i];
215  }
216  }
217  else if (k_order == 5)
218  {
219  NekDouble out[9] = {
220  153617.0 / 92897280, -35411.0 / 1658880, 3153959.0 / 23224320,
221  -6803459.0 / 11612160, 18017975.0 / 9289728, -6803459.0 / 11612160,
222  3153959.0 / 23224320, -35411.0 / 1658880, 153617.0 / 92897280};
223  for (i = 0; i < k_ncoeffs; i++)
224  {
225  out_final[i] = out[i];
226  }
227  }
228  else if (k_order == 6)
229  {
230  NekDouble out[11] = {
231  -4201.0 / 7983360, 30773.0 / 3991680, -20813.0 / 380160,
232  2825.0 / 11088, -1179649.0 / 1330560, 1569217.0 / 665280,
233  -1179649.0 / 1330560, 2825.0 / 11088, -20813.0 / 380160,
234  30773.0 / 3991680, -4201.0 / 7983360};
235  for (i = 0; i < k_ncoeffs; i++)
236  {
237  out_final[i] = out[i];
238  }
239  }
240  else if (k_order == 7)
241  {
242  NekDouble out[13] = {13154671847.0 / 76517631590400.0,
243  -18073154507.0 / 6376469299200.0,
244  287360344573.0 / 12752938598400.0,
245  -2217732343517.0 / 19129407897600.0,
246  1240941746699.0 / 2833986355200.0,
247  -275386671493.0 / 212548976640.0,
248  2648644782397.0 / 910924185600.0,
249  -275386671493.0 / 212548976640.0,
250  1240941746699.0 / 2833986355200.0,
251  -2217732343517.0 / 19129407897600.0,
252  287360344573.0 / 12752938598400.0,
253  -18073154507.0 / 6376469299200.0,
254  13154671847.0 / 76517631590400.0};
255  for (i = 0; i < k_ncoeffs; i++)
256  {
257  out_final[i] = out[i];
258  }
259  }
260  else if (k_order == 8)
261  {
262  NekDouble out[15] = {
263  -800993.0 / 14010796800.0, 73587167.0 / 70053984000.0,
264  -651305719.0 / 70053984000.0, 3714581677.0 / 70053984000.0,
265  -3085236289.0 / 14010796800.0, 1426328231.0 / 2001542400.0,
266  -43268401973.0 / 23351328000.0, 42401344373.0 / 11675664000.0,
267  -43268401973.0 / 23351328000.0, 1426328231.0 / 2001542400.0,
268  -3085236289.0 / 14010796800.0, 3714581677.0 / 70053984000.0,
269  -651305719.0 / 70053984000.0, 73587167.0 / 70053984000.0,
270  -800993.0 / 14010796800.0};
271  for (i = 0; i < k_ncoeffs; i++)
272  {
273  out_final[i] = out[i];
274  }
275  }
276 
277  k_coeffs = out_final;
278  ASSERTL0(k_order <= 8, "Order is not supported");
279 }
280 
282 {
283  int i;
285  temp[0] = -(k_width / 2.0) * h; // it needs to get scaled by h
286  for (i = 1; i < k_width + 1; i++)
287  {
288  temp[i] = temp[i - 1] + h;
289  }
290  k_breaks = temp;
291 }
292 
294  Array<OneD, NekDouble> &outarray)
295 {
296  int i;
297  for (i = 0; i < k_width + 1; i++)
298  {
299  outarray[i] = k_breaks[i] + x_value;
300  }
301 
302  // Update the center of the kernel
303  k_center = x_value;
304 }
305 
307  Array<OneD, NekDouble> &outarray)
308 {
309  int j;
310  NekDouble first = ceil(inarray[0] / h) * h;
311  int index = k_width;
312  NekDouble last = floor(inarray[index] / h) * h;
313  int count = (int)((last - first) / h) +
314  1; // number of mesh breaks under the kernel support
315  Array<OneD, NekDouble> mesh_breaks(count);
316  mesh_breaks[0] = first;
317  for (j = 1; j < count; j++)
318  {
319  mesh_breaks[j] = mesh_breaks[j - 1] + h;
320  }
321  outarray = mesh_breaks;
322 }
323 
325  Array<OneD, NekDouble> &outarray)
326 {
327  int gamma, i;
328  int degree = k_order - 1;
329  int nvalues = inarray.size();
330  Array<OneD, NekDouble> bs_values(nvalues);
331 
332  for (i = 0; i < nvalues; i++)
333  {
334  outarray[i] = 0.0;
335  }
336 
337  for (gamma = -degree; gamma <= degree; gamma++)
338  {
339  int cIndex = gamma + degree;
340 
341  // Evaluate the bSpline values
342  EvaluateBspline(inarray, h, k_center + (gamma * h), bs_values);
343 
344  for (i = 0; i < nvalues; i++)
345  {
346  outarray[i] += k_coeffs[cIndex] * bs_values[i];
347  }
348  }
349 }
350 
352  NekDouble offset, Array<OneD, NekDouble> &outarray)
353 {
354  int i;
355  NekDouble min_value = -k_order / 2.0;
356  NekDouble max_value = k_order / 2.0;
357 
358  int nvalues = inarray.size();
359 
360  // Make a copy for further modifications
361  Array<OneD, NekDouble> inarray_cp(nvalues);
362 
363  for (i = 0; i < nvalues; i++)
364  {
365  inarray_cp[i] = inarray[i] - offset;
366  inarray_cp[i] = inarray_cp[i] / h;
367  int interval = (int)floor(inarray_cp[i] -
368  min_value); // determines to which interval of
369  // the bspline the value belongs
370 
371  if (inarray_cp[i] >= min_value && inarray_cp[i] <= max_value)
372  {
373  if (interval >= k_order)
374  {
375  interval -= 1;
376  }
377  NekDouble shift = min_value + interval;
378  inarray_cp[i] -= shift;
379  outarray[i] = EvaluateBsplinePoly(inarray_cp[i], interval);
380  }
381  else
382  {
383  outarray[i] = 0.0;
384  }
385  }
386 }
387 
389 {
390  int i;
391  int deg = k_order - 1;
392  NekDouble poly_value = b_spline[interval][0];
393 
394  for (i = 0; i < deg; i++)
395  {
396  poly_value = poly_value * x_value + b_spline[interval][i + 1];
397  }
398 
399  return poly_value;
400 }
401 
403  Array<OneD, NekDouble> &inarray2,
404  Array<OneD, NekDouble> &outarray)
405 {
406  int j;
407  int kIndex = 0; // Keeps track of the kernel breaks
408  int mIndex = 0; // Keeps track of the mesh breaks
409  for (j = 0; j < outarray.size(); j++)
410  {
411  if (mIndex >= inarray2.size())
412  {
413  outarray[j] = inarray1[kIndex];
414  kIndex++;
415  }
416  else if (kIndex >= inarray1.size())
417  {
418  outarray[j] = inarray2[mIndex];
419  mIndex++;
420  }
421  else if (inarray1[kIndex] < inarray2[mIndex])
422  {
423  outarray[j] = inarray1[kIndex];
424  kIndex++;
425  }
426  else
427  {
428  outarray[j] = inarray2[mIndex];
429  mIndex++;
430  }
431  }
432 }
433 
434 } // namespace LibUtilities
435 } // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
void EvaluateBspline(Array< OneD, NekDouble > inarray, NekDouble h, NekDouble offset, Array< OneD, NekDouble > &outarray)
This function evaluates the bspline at input values.
Definition: kernel.cpp:351
void UpdateKernelCoeffs()
This funciton updates the kernel coefficients.
Definition: kernel.cpp:185
void EvaluateKernel(Array< OneD, NekDouble > inarray, NekDouble h, Array< OneD, NekDouble > &outarray)
This funciton evaluates the kernel at input values.
Definition: kernel.cpp:324
void FindMeshUnderKernel(Array< OneD, NekDouble > &inarray, NekDouble h, Array< OneD, NekDouble > &outarray)
This funciton calculates the mesh breaks under the kernel support.
Definition: kernel.cpp:306
void UpdateKernelBspline()
The default destructor.
Definition: kernel.cpp:51
void MoveKernelCenter(NekDouble x_value, Array< OneD, NekDouble > &outarray)
This funciton moves the center of the kernel to the.
Definition: kernel.cpp:293
NekDouble EvaluateBsplinePoly(NekDouble x_value, int interval)
This funciton evaluates the piecewise bspline polynomial.
Definition: kernel.cpp:388
void UpdateKernelBreaks(NekDouble h)
This funciton updates the kernel breaks.
Definition: kernel.cpp:281
Array< OneD, NekDouble > k_breaks
Definition: kernel.h:210
void UpdateKernelOrder(int order)
This funciton sets the k_order variable.
Definition: kernel.h:106
Array< TwoD, NekDouble > b_spline
Definition: kernel.h:206
void UpdateKernelNumOfCoeffs()
This funciton sets the k_ncoeffs variable.
Definition: kernel.h:114
void Sort(Array< OneD, NekDouble > &inarray1, Array< OneD, NekDouble > &inarray2, Array< OneD, NekDouble > &outarray)
This funciton performs the ordered merge of.
Definition: kernel.cpp:402
Array< OneD, NekDouble > k_coeffs
Definition: kernel.h:208
void UpdateKernelWidth()
This funciton sets the kernel width size.
Definition: kernel.h:122
Kernel()
The default constructor.
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble