Nektar++
IProduct.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: IProduct.cpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 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 // 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 
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: IProduct operators for multiple calls in different operators
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include <Collections/Collection.h>
36 #include <Collections/IProduct.h>
37 
38 using namespace std;
39 
40 namespace Nektar
41 {
42 namespace Collections
43 {
44 
45 /**
46  *
47  */
48 void QuadIProduct(bool colldir0, bool colldir1, int numElmt, int nquad0,
49  int nquad1, int nmodes0, int nmodes1,
50  const Array<OneD, const NekDouble> &base0,
51  const Array<OneD, const NekDouble> &base1,
53  const Array<OneD, const NekDouble> &input,
55 {
56  int totpoints = nquad0 * nquad1;
57  int totmodes = nmodes0 * nmodes1;
58 
59  Vmath::Vmul(numElmt * totpoints, jac, 1, input, 1, wsp, 1);
60 
61  if (colldir0 && colldir1)
62  {
63  Vmath::Vcopy(numElmt * totmodes, wsp.get(), 1, output.get(), 1);
64  }
65  else
66  {
67  Array<OneD, NekDouble> wsp1 = wsp + max(totpoints, totmodes) * numElmt;
68  if (colldir0)
69  {
70  for (int i = 0; i < nquad0; ++i)
71  {
72  Vmath::Vcopy(nquad1 * numElmt, &wsp[i], nquad0,
73  &wsp1[i * nquad1 * numElmt], 1);
74  }
75  }
76  else
77  {
78  Blas::Dgemm('T', 'N', nquad1 * numElmt, nmodes0, nquad0, 1.0,
79  &wsp[0], nquad0, base0.get(), nquad0, 0.0, &wsp1[0],
80  nquad1 * numElmt);
81  }
82 
83  if (numElmt > 1)
84  {
85 
86  if (colldir1)
87  {
88  for (int i = 0; i < nquad1; ++i)
89  {
90  Vmath::Vcopy(numElmt * nmodes0, &wsp1[i], nquad1,
91  &wsp[i * numElmt * nmodes0], 1);
92  }
93  }
94  else
95  {
96 
97  Blas::Dgemm('T', 'N', numElmt * nmodes0, nmodes1, nquad1, 1.0,
98  &wsp1[0], nquad1, base1.get(), nquad1, 0.0, &wsp[0],
99  numElmt * nmodes0);
100  }
101 
102  for (int i = 0; i < totmodes; ++i)
103  {
104  Vmath::Vcopy(numElmt, &wsp[i * numElmt], 1, &output[i],
105  totmodes);
106  }
107  }
108  else
109  {
110  if (colldir1)
111  {
112  for (int i = 0; i < nquad1; ++i)
113  {
114  Vmath::Vcopy(numElmt * nmodes0, &wsp1[i], nquad1,
115  &output[i * numElmt * nmodes0], 1);
116  }
117  }
118  else
119  {
120  Blas::Dgemm('T', 'N', nmodes0, nmodes1, nquad1, 1.0, &wsp1[0],
121  nquad1, base1.get(), nquad1, 0.0, &output[0],
122  nmodes0);
123  }
124  }
125  }
126 }
127 
128 /**
129  *
130  */
131 void TriIProduct(bool sortTopVertex, int numElmt, int nquad0, int nquad1,
132  int nmodes0, int nmodes1,
133  const Array<OneD, const NekDouble> &base0,
134  const Array<OneD, const NekDouble> &base1,
135  const Array<OneD, const NekDouble> &jac,
136  const Array<OneD, const NekDouble> &input,
138 {
139  int totmodes =
141  int totpoints = nquad0 * nquad1;
142 
143  Vmath::Vmul(numElmt * totpoints, jac, 1, input, 1, wsp, 1);
144 
145  Array<OneD, NekDouble> wsp1 = wsp + max(totpoints, totmodes) * numElmt;
146 
147  Blas::Dgemm('T', 'N', nquad1 * numElmt, nmodes0, nquad0, 1.0, &wsp[0],
148  nquad0, base0.get(), nquad0, 0.0, &wsp1[0], nquad1 * numElmt);
149 
150  int i, mode;
151  // Inner product with respect to 'b' direction
152  for (mode = i = 0; i < nmodes0; ++i)
153  {
154  Blas::Dgemm('T', 'N', nmodes1 - i, numElmt, nquad1, 1.0,
155  base1.get() + mode * nquad1, nquad1,
156  wsp1.get() + i * nquad1 * numElmt, nquad1, 0.0,
157  &output[mode], totmodes);
158 
159  mode += nmodes1 - i;
160  }
161 
162  // fix for modified basis by splitting top vertex mode
163  if (sortTopVertex)
164  {
165  Blas::Dgemv('T', nquad1, numElmt, 1.0, wsp1.get() + nquad1 * numElmt,
166  nquad1, base1.get() + nquad1, 1, 1.0, &output[1], totmodes);
167  }
168 }
169 
170 /**
171  *
172  */
173 void HexIProduct(bool colldir0, bool colldir1, bool colldir2, int numElmt,
174  int nquad0, int nquad1, int nquad2, int nmodes0, int nmodes1,
175  int nmodes2, const Array<OneD, const NekDouble> &base0,
176  const Array<OneD, const NekDouble> &base1,
177  const Array<OneD, const NekDouble> &base2,
178  const Array<OneD, const NekDouble> &jac,
179  const Array<OneD, const NekDouble> &input,
181 {
182  int totmodes = nmodes0 * nmodes1 * nmodes2;
183  int totpoints = nquad0 * nquad1 * nquad2;
184 
185  if (colldir0 && colldir1 && colldir2)
186  {
187 
188  Vmath::Vmul(numElmt * totpoints, jac, 1, input, 1, output, 1);
189  }
190  else
191  {
192  Vmath::Vmul(numElmt * totpoints, jac, 1, input, 1, wsp, 1);
193 
194  // Assign second half of workspace for 2nd DGEMM operation.
195  Array<OneD, NekDouble> wsp1 = wsp + totpoints * numElmt;
196 
197  // note sure what criterion we should use to swap around these
198  // strategies
199  if (numElmt < nmodes0 || 1)
200  {
201  Array<OneD, NekDouble> wsp2 = wsp1 + nmodes0 * nquad1 * nquad2;
202 
203  // loop over elements
204  for (int n = 0; n < numElmt; ++n)
205  {
206  if (colldir0)
207  {
208 
209  for (int i = 0; i < nmodes0; ++i)
210  {
211  Vmath::Vcopy(nquad1 * nquad2, &wsp[n * totpoints] + i,
212  nquad0, wsp1.get() + nquad1 * nquad2 * i,
213  1);
214  }
215  }
216  else
217  {
218  Blas::Dgemm('T', 'N', nquad1 * nquad2, nmodes0, nquad0, 1.0,
219  &wsp[n * totpoints], nquad0, base0.get(),
220  nquad0, 0.0, wsp1.get(), nquad1 * nquad2);
221  }
222 
223  if (colldir1)
224  {
225  // reshuffle data for next operation.
226  for (int i = 0; i < nmodes1; ++i)
227  {
228  Vmath::Vcopy(nquad2 * nmodes0, wsp1.get() + i, nquad1,
229  wsp2.get() + nquad2 * nmodes0 * i, 1);
230  }
231  }
232  else
233  {
234  Blas::Dgemm('T', 'N', nquad2 * nmodes0, nmodes1, nquad1,
235  1.0, wsp1.get(), nquad1, base1.get(), nquad1,
236  0.0, wsp2.get(), nquad2 * nmodes0);
237  }
238 
239  if (colldir2)
240  {
241  // reshuffle data for next operation.
242  for (int i = 0; i < nmodes2; ++i)
243  {
244  Vmath::Vcopy(
245  nmodes0 * nmodes1, wsp2.get() + i, nquad2,
246  &output[n * totmodes] + nmodes0 * nmodes1 * i, 1);
247  }
248  }
249  else
250  {
251  Blas::Dgemm('T', 'N', nmodes0 * nmodes1, nmodes2, nquad2,
252  1.0, wsp2.get(), nquad2, base2.get(), nquad2,
253  0.0, &output[n * totmodes], nmodes0 * nmodes1);
254  }
255  }
256  }
257  else
258  {
260  wsp1 + numElmt * (max(totpoints, totmodes));
261 
262  if (colldir0)
263  {
264  for (int i = 0; i < nquad0; ++i)
265  {
266  Vmath::Vcopy(nquad1 * nquad2 * numElmt, &wsp[i], nquad0,
267  &wsp1[i * nquad1 * nquad2 * numElmt], 1);
268  }
269  }
270  else
271  {
272  // large degmm but copy at end.
273  Blas::Dgemm('T', 'N', nquad1 * nquad2 * numElmt, nmodes0,
274  nquad0, 1.0, &wsp[0], nquad0, base0.get(), nquad0,
275  0.0, &wsp1[0], nquad1 * nquad2 * numElmt);
276  }
277 
278  if (colldir1)
279  {
280  for (int i = 0; i < nquad1; ++i)
281  {
282  Vmath::Vcopy(nquad2 * numElmt * nmodes0, &wsp1[i], nquad1,
283  &wsp2[i * nquad2 * numElmt * nmodes0], 1);
284  }
285  }
286  else
287  {
288  Blas::Dgemm('T', 'N', nquad2 * numElmt * nmodes0, nmodes1,
289  nquad1, 1.0, &wsp1[0], nquad1, base1.get(), nquad1,
290  0.0, &wsp2[0], nquad2 * numElmt * nmodes0);
291  }
292 
293  if (numElmt > 1)
294  {
295  if (colldir2)
296  {
297  for (int i = 0; i < nquad2; ++i)
298  {
299  Vmath::Vcopy(nmodes0 * nmodes1, &wsp2[i], nquad2,
300  &output[i * nmodes0 * nmodes1], 1);
301  }
302  }
303  else
304  {
305  Blas::Dgemm('T', 'N', numElmt * nmodes0 * nmodes1, nmodes2,
306  nquad2, 1.0, &wsp2[0], nquad2, base2.get(),
307  nquad2, 0.0, &wsp1[0],
308  numElmt * nmodes0 * nmodes1);
309  }
310 
311  for (int i = 0; i < totmodes; ++i)
312  {
313  Vmath::Vcopy(numElmt, &wsp1[i * numElmt], 1, &output[i],
314  totmodes);
315  }
316  }
317  else
318  {
319  if (colldir2)
320  {
321  for (int i = 0; i < nquad2; ++i)
322  {
323  Vmath::Vcopy(nmodes0 * nmodes1, &wsp2[i], nquad2,
324  &output[i * nmodes0 * nmodes1], 1);
325  }
326  }
327  else
328  {
329  Blas::Dgemm('T', 'N', numElmt * nmodes0 * nmodes1, nmodes2,
330  nquad2, 1.0, &wsp2[0], nquad2, base2.get(),
331  nquad2, 0.0, &output[0],
332  numElmt * nmodes0 * nmodes1);
333  }
334  }
335  }
336  }
337 }
338 
339 /**
340  *
341  */
342 void PrismIProduct(bool sortTopVertex, int numElmt, int nquad0, int nquad1,
343  int nquad2, int nmodes0, int nmodes1, int nmodes2,
344  const Array<OneD, const NekDouble> &base0,
345  const Array<OneD, const NekDouble> &base1,
346  const Array<OneD, const NekDouble> &base2,
347  const Array<OneD, const NekDouble> &jac,
348  const Array<OneD, const NekDouble> &input,
350 {
352  nmodes0, nmodes1, nmodes2);
353  int totpoints = nquad0 * nquad1 * nquad2;
354  int cnt;
355  int mode, mode1;
356 
357  Vmath::Vmul(numElmt * totpoints, jac, 1, input, 1, wsp, 1);
358 
360  wsp + numElmt * nquad2 * (max(nquad0 * nquad1, nmodes0 * nmodes1));
361 
362  // Perform iproduct with respect to the '0' direction
363  Blas::Dgemm('T', 'N', nquad1 * nquad2 * numElmt, nmodes0, nquad0, 1.0,
364  wsp.get(), nquad0, base0.get(), nquad0, 0.0, wsp1.get(),
365  nquad1 * nquad2 * numElmt);
366 
367  // Perform iproduct with respect to the '1' direction
368  Blas::Dgemm('T', 'N', nquad2 * numElmt * nmodes0, nmodes1, nquad1, 1.0,
369  wsp1.get(), nquad1, base1.get(), nquad1, 0.0, wsp.get(),
370  nquad2 * numElmt * nmodes0);
371 
372  // Inner product with respect to the '2' direction (not sure if it would
373  // be better to swap loops?)
374  mode = mode1 = cnt = 0;
375  for (int i = 0; i < nmodes0; ++i)
376  {
377  cnt = i * nquad2 * numElmt;
378  for (int j = 0; j < nmodes1; ++j)
379  {
380  Blas::Dgemm('T', 'N', nmodes2 - i, numElmt, nquad2, 1.0,
381  base2.get() + mode * nquad2, nquad2,
382  wsp.get() + j * nquad2 * numElmt * nmodes0 + cnt,
383  nquad2, 0.0, output.get() + mode1, totmodes);
384  mode1 += nmodes2 - i;
385  }
386  mode += nmodes2 - i;
387  }
388 
389  // fix for modified basis by splitting top vertex mode
390  if (sortTopVertex)
391  {
392  // top singular vertex
393  // ((1+a)/2 components entry into (1+c)/2)
394  // Could be made into an mxv if we have specialised base1[1]
395  for (int j = 0; j < nmodes1; ++j)
396  {
397  Blas::Dgemv('T', nquad2, numElmt, 1.0,
398  wsp.get() + j * nquad2 * numElmt * nmodes0 +
399  nquad2 * numElmt,
400  nquad2, base2.get() + nquad2, 1, 1.0,
401  &output[j * nmodes2 + 1], totmodes);
402  }
403  }
404 }
405 
406 /**
407  *
408  */
409 void PyrIProduct(bool sortTopVertex, int numElmt, int nquad0, int nquad1,
410  int nquad2, int nmodes0, int nmodes1, int nmodes2,
411  const Array<OneD, const NekDouble> &base0,
412  const Array<OneD, const NekDouble> &base1,
413  const Array<OneD, const NekDouble> &base2,
414  const Array<OneD, const NekDouble> &jac,
415  const Array<OneD, const NekDouble> &input,
417 {
419  nmodes0, nmodes1, nmodes2);
420  int totpoints = nquad0 * nquad1 * nquad2;
421  int cnt;
422  int mode, mode1;
423 
424  ASSERTL1(wsp.size() >=
425  numElmt * (nquad1 * nquad2 * nmodes0 +
426  nquad2 * max(nquad0 * nquad1, nmodes0 * nmodes1)),
427  "Insufficient workspace size");
428 
429  Vmath::Vmul(numElmt * totpoints, jac, 1, input, 1, wsp, 1);
430 
432  wsp + numElmt * nquad2 * (max(nquad0 * nquad1, nmodes0 * nmodes1));
433 
434  // Perform iproduct with respect to the '0' direction
435  Blas::Dgemm('T', 'N', nquad1 * nquad2 * numElmt, nmodes0, nquad0, 1.0,
436  wsp.get(), nquad0, base0.get(), nquad0, 0.0, wsp1.get(),
437  nquad1 * nquad2 * numElmt);
438 
439  // Inner product with respect to the '1' direction
440  mode = 0;
441  for (int i = 0; i < nmodes0; ++i)
442  {
443  Blas::Dgemm('T', 'N', nquad2 * numElmt, nmodes1, nquad1, 1.0,
444  wsp1.get() + i * nquad1 * nquad2 * numElmt, nquad1,
445  base1.get(), nquad1, 0.0,
446  wsp.get() + mode * nquad2 * numElmt, nquad2 * numElmt);
447  mode += nmodes1;
448  }
449 
450  // Inner product with respect to the '2' direction
451  mode = mode1 = cnt = 0;
452  for (int i = 0; i < nmodes0; ++i)
453  {
454  for (int j = 0; j < nmodes1; ++j, ++cnt)
455  {
456  int ijmax = max(i, j);
457  Blas::Dgemm('T', 'N', nmodes2 - ijmax, numElmt, nquad2, 1.0,
458  base2.get() + mode * nquad2, nquad2,
459  wsp.get() + cnt * nquad2 * numElmt, nquad2, 0.0,
460  output.get() + mode1, totmodes);
461  mode += nmodes2 - ijmax;
462  mode1 += nmodes2 - ijmax;
463  }
464 
465  // increment mode in case order1!=order2
466  for (int j = nmodes1; j < nmodes2; ++j)
467  {
468  int ijmax = max(i, j);
469  mode += nmodes2 - ijmax;
470  }
471  }
472 
473  // fix for modified basis for top singular vertex component
474  // Already have evaluated (1+c)/2 (1-b)/2 (1-a)/2
475  if (sortTopVertex)
476  {
477  for (int n = 0; n < numElmt; ++n)
478  {
479  // add in (1+c)/2 (1+b)/2 component
480  output[1 + n * totmodes] +=
481  Blas::Ddot(nquad2, base2.get() + nquad2, 1,
482  &wsp[nquad2 * numElmt + n * nquad2], 1);
483 
484  // add in (1+c)/2 (1-b)/2 (1+a)/2 component
485  output[1 + n * totmodes] +=
486  Blas::Ddot(nquad2, base2.get() + nquad2, 1,
487  &wsp[nquad2 * nmodes1 * numElmt + n * nquad2], 1);
488 
489  // add in (1+c)/2 (1+b)/2 (1+a)/2 component
490  output[1 + n * totmodes] += Blas::Ddot(
491  nquad2, base2.get() + nquad2, 1,
492  &wsp[nquad2 * (nmodes1 + 1) * numElmt + n * nquad2], 1);
493  }
494  }
495 }
496 
497 /**
498  *
499  */
500 void TetIProduct(bool sortTopEdge, int numElmt, int nquad0, int nquad1,
501  int nquad2, int nmodes0, int nmodes1, int nmodes2,
502  const Array<OneD, const NekDouble> &base0,
503  const Array<OneD, const NekDouble> &base1,
504  const Array<OneD, const NekDouble> &base2,
505  const Array<OneD, const NekDouble> &jac,
506  const Array<OneD, const NekDouble> &input,
508 {
510  nmodes0, nmodes1, nmodes2);
511  int totpoints = nquad0 * nquad1 * nquad2;
512  int cnt;
513  int mode, mode1;
514 
515  Vmath::Vmul(numElmt * totpoints, jac, 1, input, 1, wsp, 1);
516 
518  wsp +
519  nquad2 * numElmt *
520  (max(nquad0 * nquad1, nmodes0 * (2 * nmodes1 - nmodes0 + 1) / 2));
521 
522  // Perform iproduct with respect to the '0' direction
523  Blas::Dgemm('T', 'N', nquad1 * nquad2 * numElmt, nmodes0, nquad0, 1.0,
524  wsp.get(), nquad0, base0.get(), nquad0, 0.0, wsp1.get(),
525  nquad1 * nquad2 * numElmt);
526 
527  // Inner product with respect to the '1' direction
528  mode = 0;
529  for (int i = 0; i < nmodes0; ++i)
530  {
531  Blas::Dgemm('T', 'N', nquad2 * numElmt, nmodes1 - i, nquad1, 1.0,
532  wsp1.get() + i * nquad1 * nquad2 * numElmt, nquad1,
533  base1.get() + mode * nquad1, nquad1, 0.0,
534  wsp.get() + mode * nquad2 * numElmt, nquad2 * numElmt);
535  mode += nmodes1 - i;
536  }
537 
538  // fix for modified basis by splitting top vertex mode
539  if (sortTopEdge)
540  {
541  // base singular vertex and singular edge (1+b)/2
542  // ((1+a)/2 components entry into (1+b)/2)
543  // Could be made into an mxm if we have specialised base1[1]
544  for (int n = 0; n < numElmt; ++n)
545  {
546  Blas::Dgemv('T', nquad1, nquad2, 1.0,
547  wsp1.get() + numElmt * nquad1 * nquad2 +
548  n * nquad1 * nquad2,
549  nquad1, base1.get() + nquad1, 1, 1.0,
550  wsp.get() + nquad2 * numElmt + n * nquad2, 1);
551  }
552  }
553 
554  // Inner product with respect to the '2' direction
555  mode = mode1 = cnt = 0;
556  for (int i = 0; i < nmodes0; ++i)
557  {
558  for (int j = 0; j < nmodes1 - i; ++j, ++cnt)
559  {
560  Blas::Dgemm('T', 'N', nmodes2 - i - j, numElmt, nquad2, 1.0,
561  base2.get() + mode * nquad2, nquad2,
562  wsp.get() + cnt * nquad2 * numElmt, nquad2, 0.0,
563  output.get() + mode1, totmodes);
564  mode += nmodes2 - i - j;
565  mode1 += nmodes2 - i - j;
566  }
567 
568  // increment mode in case order1!=order2
569  mode += (nmodes2 - nmodes1) * (nmodes2 - nmodes1 + 1) / 2;
570  }
571 
572  // fix for modified basis for top singular vertex component
573  // Already have evaluated (1+c)/2 (1-b)/2 (1-a)/2
574  if (sortTopEdge)
575  {
576  for (int n = 0; n < numElmt; ++n)
577  {
578  // add in (1+c)/2 (1+b)/2 component
579  output[1 + n * totmodes] +=
580  Blas::Ddot(nquad2, base2.get() + nquad2, 1,
581  &wsp[nquad2 * numElmt + n * nquad2], 1);
582 
583  // add in (1+c)/2 (1-b)/2 (1+a)/2 component
584  output[1 + n * totmodes] +=
585  Blas::Ddot(nquad2, base2.get() + nquad2, 1,
586  &wsp[nquad2 * nmodes1 * numElmt + n * nquad2], 1);
587  }
588  }
589 }
590 
591 } // namespace Collections
592 } // namespace Nektar
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
static void Dgemv(const char &trans, const int &m, const int &n, const double &alpha, const double *a, const int &lda, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = A x where A[m x n].
Definition: Blas.hpp:246
static double Ddot(const int &n, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: output = .
Definition: Blas.hpp:182
static void Dgemm(const char &transa, const char &transb, const int &m, const int &n, const int &k, const double &alpha, const double *a, const int &lda, const double *b, const int &ldb, const double &beta, double *c, const int &ldc)
BLAS level 3: Matrix-matrix multiply C = A x B where op(A)[m x k], op(B)[k x n], C[m x n] DGEMM perfo...
Definition: Blas.hpp:368
void TetIProduct(bool sortTopEdge, int numElmt, int nquad0, int nquad1, int nquad2, int nmodes0, int nmodes1, int nmodes2, const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &jac, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
Definition: IProduct.cpp:500
void PyrIProduct(bool sortTopVert, int numElmt, int nquad0, int nquad1, int nquad2, int nmodes0, int nmodes1, int nmodes2, const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &jac, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
Definition: IProduct.cpp:409
void TriIProduct(bool sortTopVertex, int numElmt, int nquad0, int nquad1, int nmodes0, int nmodes1, const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &jac, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
Definition: IProduct.cpp:131
void QuadIProduct(bool colldir0, bool colldir1, int numElmt, int nquad0, int nquad1, int nmodes0, int nmodes1, const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &jac, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
Definition: IProduct.cpp:48
void PrismIProduct(bool sortTopVert, int numElmt, int nquad0, int nquad1, int nquad2, int nmodes0, int nmodes1, int nmodes2, const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &jac, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
Definition: IProduct.cpp:342
void HexIProduct(bool colldir0, bool colldir1, bool colldir2, int numElmt, int nquad0, int nquad1, int nquad2, int nmodes0, int nmodes1, int nmodes2, const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &jac, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
Definition: IProduct.cpp:173
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:209
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1255