Nektar++
IProductWRTDerivBase.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: IProductWRTDerivBase.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 // 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: IProductWRTDerivBase operator implementations
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include <boost/core/ignore_unused.hpp>
36 
37 #include <Collections/Operator.h>
38 #include <Collections/Collection.h>
39 #include <Collections/IProduct.h>
40 
41 using namespace std;
42 
43 namespace Nektar {
44 namespace Collections {
45 
53 
54 /**
55  * @brief Inner product WRT deriv base operator using standard matrix approach
56  */
58 {
59  public:
61 
63  {
64  }
65 
66  virtual void operator()(
67  const Array<OneD, const NekDouble> &entry0,
68  Array<OneD, NekDouble> &entry1,
69  Array<OneD, NekDouble> &entry2,
70  Array<OneD, NekDouble> &entry3,
72  {
73  int nPhys = m_stdExp->GetTotPoints();
74  int ntot = m_numElmt*nPhys;
75  int nmodes = m_stdExp->GetNcoeffs();
79 
80  in[0] = entry0; in[1] = entry1;
81  in[2] = entry2;
82 
83  output = (m_coordim == 3)? entry3: (m_coordim == 2)?
84  entry2: entry1;
85 
86  for(int i = 0; i < m_dim; ++i)
87  {
88  tmp[i] = wsp + i*ntot;
89  }
90 
91  // calculate dx/dxi in[0] + dy/dxi in[1] + dz/dxi in[2]
92  for(int i = 0; i < m_dim; ++i)
93  {
94  Vmath::Vmul (ntot,m_derivFac[i],1, in[0],1,
95  tmp[i],1);
96  for(int j = 1; j < m_coordim; ++j)
97  {
98  Vmath::Vvtvp (ntot,m_derivFac[i +j*m_dim],1,
99  in[j],1, tmp[i], 1, tmp[i],1);
100  }
101  }
102 
103  // calculate Iproduct WRT Std Deriv
104 
105  // First component
106  Vmath::Vmul(ntot,m_jac,1,tmp[0],1,tmp[0],1);
107  Blas::Dgemm('N', 'N', m_iProdWRTStdDBase[0]->GetRows(),
108  m_numElmt,m_iProdWRTStdDBase[0]->GetColumns(),
109  1.0, m_iProdWRTStdDBase[0]->GetRawPtr(),
110  m_iProdWRTStdDBase[0]->GetRows(),
111  tmp[0].get(), nPhys, 0.0,
112  output.get(), nmodes);
113 
114  // Other components
115  for(int i = 1; i < m_dim; ++i)
116  {
117  Vmath::Vmul(ntot,m_jac,1,tmp[i],1,tmp[i],1);
118  Blas::Dgemm('N', 'N', m_iProdWRTStdDBase[i]->GetRows(),
119  m_numElmt,m_iProdWRTStdDBase[i]->GetColumns(),
120  1.0, m_iProdWRTStdDBase[i]->GetRawPtr(),
121  m_iProdWRTStdDBase[i]->GetRows(),
122  tmp[i].get(), nPhys, 1.0,
123  output.get(), nmodes);
124  }
125  }
126 
127  virtual void operator()(
128  int dir,
129  const Array<OneD, const NekDouble> &input,
130  Array<OneD, NekDouble> &output,
132  {
133  boost::ignore_unused(dir, input, output, wsp);
134  NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
135  }
136 
137  protected:
141  int m_dim;
143 
144  private:
146  vector<StdRegions::StdExpansionSharedPtr> pCollExp,
147  CoalescedGeomDataSharedPtr pGeomData)
148  : Operator(pCollExp, pGeomData)
149  {
150  LibUtilities::PointsKeyVector PtsKey = m_stdExp->GetPointsKeys();
151  m_dim = PtsKey.size();
152  m_coordim = pCollExp[0]->GetCoordim();
153 
154  int nqtot = m_stdExp->GetTotPoints();
155  int nmodes = m_stdExp->GetNcoeffs();
156 
157  // set up a IProductWRTDerivBase StdMat.
158  m_iProdWRTStdDBase = Array<OneD, DNekMatSharedPtr>(m_dim);
159  for(int i = 0; i < m_dim; ++i)
160  {
161  Array<OneD, NekDouble> tmp(nqtot),tmp1(nmodes);
162  m_iProdWRTStdDBase[i] = MemoryManager<DNekMat>
163  ::AllocateSharedPtr(nmodes,nqtot);
164  for(int j = 0; j < nqtot; ++j)
165  {
166  Vmath::Zero(nqtot,tmp,1);
167  tmp[j] = 1.0;
168  m_stdExp->IProductWRTDerivBase(i,tmp,tmp1);
169  Vmath::Vcopy(nmodes, &tmp1[0],1,
170  &(m_iProdWRTStdDBase[i]->GetPtr())[0]
171  + j*nmodes, 1);
172  }
173  }
174  m_derivFac = pGeomData->GetDerivFactors(pCollExp);
175  m_jac = pGeomData->GetJac(pCollExp);
176  m_wspSize = m_dim*nqtot*m_numElmt;
177  }
178 };
179 
180 /// Factory initialisation for the IProductWRTDerivBase_StdMat operators
181 OperatorKey IProductWRTDerivBase_StdMat::m_typeArr[] = {
184  IProductWRTDerivBase_StdMat::create,
185  "IProductWRTDerivBase_StdMat_Seg"),
188  IProductWRTDerivBase_StdMat::create,
189  "IProductWRTDerivBase_StdMat_Tri"),
192  IProductWRTDerivBase_StdMat::create,
193  "IProductWRTDerivBase_StdMat_NodalTri"),
196  IProductWRTDerivBase_StdMat::create,
197  "IProductWRTDerivBase_StdMat_Quad"),
200  IProductWRTDerivBase_StdMat::create,
201  "IProductWRTDerivBase_StdMat_Tet"),
204  IProductWRTDerivBase_StdMat::create,
205  "IProductWRTDerivBase_StdMat_NodalTet"),
208  IProductWRTDerivBase_StdMat::create,
209  "IProductWRTDerivBase_StdMat_Pyr"),
212  IProductWRTDerivBase_StdMat::create,
213  "IProductWRTDerivBase_StdMat_Prism"),
216  IProductWRTDerivBase_StdMat::create,
217  "IProductWRTDerivBase_StdMat_NodalPrism"),
220  IProductWRTDerivBase_StdMat::create,
221  "IProductWRTDerivBase_StdMat_Hex"),
224  IProductWRTDerivBase_StdMat::create, "IProductWRTDerivBase_SumFac_Pyr")
225 };
226 
227 
228 /**
229  * @brief Inner product WRT deriv base operator using element-wise operation
230  */
232 {
233  public:
235 
237  {
238  }
239 
240  virtual void operator()(
241  const Array<OneD, const NekDouble> &entry0,
242  Array<OneD, NekDouble> &entry1,
243  Array<OneD, NekDouble> &entry2,
244  Array<OneD, NekDouble> &entry3,
246  {
247  unsigned int nPhys = m_stdExp->GetTotPoints();
248  unsigned int ntot = m_numElmt*nPhys;
249  unsigned int nmodes = m_stdExp->GetNcoeffs();
250  unsigned int nmax = max(ntot,m_numElmt*nmodes);
252  Array<OneD, NekDouble> output, tmp1;
254 
255  in[0] = entry0; in[1] = entry1; in[2] = entry2;
256 
257  output = (m_coordim == 3)? entry3: (m_coordim == 2)?
258  entry2: entry1;
259 
260  for(int i = 0; i < m_dim; ++i)
261  {
262  tmp[i] = wsp + i*nmax;
263  }
264 
265  // calculate dx/dxi in[0] + dy/dxi in[2] + dz/dxi in[3]
266  for(int i = 0; i < m_dim; ++i)
267  {
268  Vmath::Vmul (ntot,m_derivFac[i],1, in[0],1,
269  tmp[i],1);
270  for(int j = 1; j < m_coordim; ++j)
271  {
272  Vmath::Vvtvp (ntot,m_derivFac[i +j*m_dim],1,
273  in[j],1, tmp[i], 1, tmp[i],1);
274  }
275  }
276 
277  // calculate Iproduct WRT Std Deriv
278  // first component
279  Vmath::Vmul(ntot,m_jac,1,tmp[0],1,tmp[0],1);
280  for(int n = 0; n < m_numElmt; ++n)
281  {
282  m_stdExp->IProductWRTDerivBase(0,tmp[0]+n*nPhys,
283  tmp1 = output + n*nmodes);
284  }
285 
286  // other components
287  for(int i = 1; i < m_dim; ++i)
288  {
289  // multiply by Jacobian
290  Vmath::Vmul(ntot,m_jac,1,tmp[i],1,tmp[i],1);
291  for(int n = 0; n < m_numElmt; ++n)
292  {
293  m_stdExp->IProductWRTDerivBase(i,tmp[i]+n*nPhys,tmp[0]);
294  Vmath::Vadd(nmodes,tmp[0],1,output+n*nmodes,1,
295  tmp1 = output+n*nmodes,1);
296  }
297  }
298  }
299 
300  virtual void operator()(
301  int dir,
302  const Array<OneD, const NekDouble> &input,
303  Array<OneD, NekDouble> &output,
305  {
306  boost::ignore_unused(dir, input, output, wsp);
307  NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
308  }
309 
310  protected:
313  int m_dim;
315 
316  private:
318  vector<StdRegions::StdExpansionSharedPtr> pCollExp,
319  CoalescedGeomDataSharedPtr pGeomData)
320  : Operator(pCollExp, pGeomData)
321  {
322  LibUtilities::PointsKeyVector PtsKey = m_stdExp->GetPointsKeys();
323  m_dim = PtsKey.size();
324  m_coordim = pCollExp[0]->GetCoordim();
325 
326  int nqtot = m_stdExp->GetTotPoints();
327 
328  m_derivFac = pGeomData->GetDerivFactors(pCollExp);
329  m_jac = pGeomData->GetJac(pCollExp);
330  m_wspSize = m_dim*nqtot*m_numElmt;
331  }
332 };
333 
334 /// Factory initialisation for the IProductWRTDerivBase_IterPerExp operators
335 OperatorKey IProductWRTDerivBase_IterPerExp::m_typeArr[] = {
338  IProductWRTDerivBase_IterPerExp::create,
339  "IProductWRTDerivBase_IterPerExp_Seg"),
342  IProductWRTDerivBase_IterPerExp::create,
343  "IProductWRTDerivBase_IterPerExp_Tri"),
346  IProductWRTDerivBase_IterPerExp::create,
347  "IProductWRTDerivBase_IterPerExp_NodalTri"),
350  IProductWRTDerivBase_IterPerExp::create,
351  "IProductWRTDerivBase_IterPerExp_Quad"),
354  IProductWRTDerivBase_IterPerExp::create,
355  "IProductWRTDerivBase_IterPerExp_Tet"),
358  IProductWRTDerivBase_IterPerExp::create,
359  "IProductWRTDerivBase_IterPerExp_NodalTet"),
362  IProductWRTDerivBase_IterPerExp::create,
363  "IProductWRTDerivBase_IterPerExp_Pyr"),
366  IProductWRTDerivBase_IterPerExp::create,
367  "IProductWRTDerivBase_IterPerExp_Prism"),
370  IProductWRTDerivBase_IterPerExp::create,
371  "IProductWRTDerivBase_IterPerExp_NodalPrism"),
374  IProductWRTDerivBase_IterPerExp::create,
375  "IProductWRTDerivBase_IterPerExp_Hex")
376 };
377 
378 
379 /**
380  * @brief Inner product WRT deriv base operator using LocalRegions
381  * implementation.
382  */
384 {
385  public:
387 
389  {
390  }
391 
392  virtual void operator()(
393  const Array<OneD, const NekDouble> &entry0,
394  Array<OneD, NekDouble> &entry1,
395  Array<OneD, NekDouble> &entry2,
396  Array<OneD, NekDouble> &entry3,
398  {
399  boost::ignore_unused(wsp);
400 
401  unsigned int nmodes = m_expList[0]->GetNcoeffs();
402  unsigned int nPhys = m_expList[0]->GetTotPoints();
403  Array<OneD, NekDouble> tmp(nmodes),tmp1;
404 
406  Array<OneD, NekDouble> output;
407  in[0] = entry0; in[1] = entry1; in[2] = entry2;
408 
409  output = (m_coordim == 3)? entry3: (m_coordim == 2)?
410  entry2: entry1;
411 
412  for(int n = 0; n < m_numElmt; ++n)
413  {
414  m_expList[n]->IProductWRTDerivBase(0,
415  in[0] + n * nPhys,
416  tmp1 = output + n * nmodes);
417  }
418 
419  for(int i = 1; i < m_dim; ++i)
420  {
421  for(int n = 0; n < m_numElmt; ++n)
422  {
423  m_expList[n]->IProductWRTDerivBase(i,in[i]+n*nPhys,tmp);
424 
425  Vmath::Vadd(nmodes,tmp,1,output+n*nmodes,1,
426  tmp1 = output+n*nmodes,1);
427  }
428  }
429  }
430 
431  virtual void operator()(
432  int dir,
433  const Array<OneD, const NekDouble> &input,
434  Array<OneD, NekDouble> &output,
436  {
437  boost::ignore_unused(dir, input, output, wsp);
438  NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
439  }
440 
441  protected:
442  int m_dim;
444  vector<StdRegions::StdExpansionSharedPtr> m_expList;
445 
446  private:
448  vector<StdRegions::StdExpansionSharedPtr> pCollExp,
449  CoalescedGeomDataSharedPtr pGeomData)
450  : Operator(pCollExp, pGeomData)
451  {
452  m_expList = pCollExp;
453  m_dim = pCollExp[0]->GetNumBases();
454  m_coordim = pCollExp[0]->GetCoordim();
455  }
456 };
457 
458 /// Factory initialisation for the IProductWRTDerivBase_NoCollection operators
459 OperatorKey IProductWRTDerivBase_NoCollection::m_typeArr[] = {
462  IProductWRTDerivBase_NoCollection::create,
463  "IProductWRTDerivBase_NoCollection_Seg"),
466  IProductWRTDerivBase_NoCollection::create,
467  "IProductWRTDerivBase_NoCollection_Tri"),
470  IProductWRTDerivBase_NoCollection::create,
471  "IProductWRTDerivBase_NoCollection_NodalTri"),
474  IProductWRTDerivBase_NoCollection::create,
475  "IProductWRTDerivBase_NoCollection_Quad"),
478  IProductWRTDerivBase_NoCollection::create,
479  "IProductWRTDerivBase_NoCollection_Tet"),
482  IProductWRTDerivBase_NoCollection::create,
483  "IProductWRTDerivBase_NoCollection_NodalTet"),
486  IProductWRTDerivBase_NoCollection::create,
487  "IProductWRTDerivBase_NoCollection_Pyr"),
490  IProductWRTDerivBase_NoCollection::create,
491  "IProductWRTDerivBase_NoCollection_Prism"),
494  IProductWRTDerivBase_NoCollection::create,
495  "IProductWRTDerivBase_NoCollection_NodalPrism"),
498  IProductWRTDerivBase_NoCollection::create,
499  "IProductWRTDerivBase_NoCollection_Hex")
500 };
501 
502 
503 /**
504  * @brief Inner product WRT deriv base operator using sum-factorisation
505  * (Segment)
506  */
508 {
509  public:
511 
513  {
514  }
515 
516  virtual void operator()(
517  const Array<OneD, const NekDouble> &input,
518  Array<OneD, NekDouble> &output,
519  Array<OneD, NekDouble> &output1,
520  Array<OneD, NekDouble> &output2,
522  {
523  boost::ignore_unused(output1, output2);
524 
525  Vmath::Vmul(m_numElmt*m_nquad0, m_jac, 1, input, 1, wsp, 1);
526  Vmath::Vmul(m_numElmt*m_nquad0, &m_derivFac[0][0], 1,
527  &wsp[0], 1,
528  &wsp[0], 1);
529 
530  // out = B0*in;
531  Blas::Dgemm('T', 'N', m_nmodes0, m_numElmt, m_nquad0,
532  1.0, m_derbase0.get(), m_nquad0,
533  &wsp[0], m_nquad0, 0.0,
534  &output[0], m_nmodes0);
535  }
536 
537  virtual void operator()(
538  int dir,
539  const Array<OneD, const NekDouble> &input,
540  Array<OneD, NekDouble> &output,
542  {
543  boost::ignore_unused(dir, input, output, wsp);
544  NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
545  }
546 
547  protected:
548  const int m_nquad0;
549  const int m_nmodes0;
553 
554  private:
556  vector<StdRegions::StdExpansionSharedPtr> pCollExp,
557  CoalescedGeomDataSharedPtr pGeomData)
558  : Operator (pCollExp, pGeomData),
559  m_nquad0 (m_stdExp->GetNumPoints(0)),
560  m_nmodes0 (m_stdExp->GetBasisNumModes(0)),
561  m_derbase0(m_stdExp->GetBasis(0)->GetDbdata())
562  {
563  m_wspSize = m_numElmt*m_nquad0;
564  m_derivFac = pGeomData->GetDerivFactors(pCollExp);
565  m_jac = pGeomData->GetJacWithStdWeights(pCollExp);
566  }
567 };
568 
569 /// Factory initialisation for the IProductWRTDerivBase_SumFac_Seg operator
570 OperatorKey IProductWRTDerivBase_SumFac_Seg::m_type = GetOperatorFactory().
571  RegisterCreatorFunction(
573  IProductWRTDerivBase_SumFac_Seg::create,
574  "IProductWRTDerivBase_SumFac_Seg");
575 
576 
577 /**
578  * @brief Inner product WRT deriv base operator using sum-factorisation (Quad)
579  */
581 {
582  public:
584 
586  {
587  }
588 
589  virtual void operator()(
590  const Array<OneD, const NekDouble> &entry0,
591  Array<OneD, NekDouble> &entry1,
592  Array<OneD, NekDouble> &entry2,
593  Array<OneD, NekDouble> &entry3,
595  {
596  unsigned int nPhys = m_stdExp->GetTotPoints();
597  unsigned int ntot = m_numElmt*nPhys;
598  unsigned int nmodes = m_stdExp->GetNcoeffs();
599  unsigned int nmax = max(ntot,m_numElmt*nmodes);
601  Array<OneD, NekDouble> output, wsp1;
603 
604  in[0] = entry0; in[1] = entry1; in[2] = entry2;
605 
606  output = (m_coordim == 2)? entry2: entry3;
607 
608  tmp[0] = wsp; tmp[1] = wsp + nmax;
609  wsp1 = wsp + 2*nmax;
610 
611  // calculate dx/dxi in[0] + dy/dxi in[1]
612  for(int i = 0; i < 2; ++i)
613  {
614  Vmath::Vmul (ntot,m_derivFac[i],1, in[0],1,
615  tmp[i],1);
616  for(int j = 1; j < 2; ++j)
617  {
618  Vmath::Vvtvp (ntot,m_derivFac[i +j*2],1,
619  in[j],1, tmp[i], 1, tmp[i],1);
620  }
621  }
622 
623  // Iproduct wrt derivative of base 0
624  QuadIProduct(false, m_colldir1,m_numElmt,
625  m_nquad0, m_nquad1,
626  m_nmodes0, m_nmodes1,
627  m_derbase0, m_base1,
628  m_jac, tmp[0], output, wsp1);
629 
630  // Iproduct wrt derivative of base 1
631  QuadIProduct(m_colldir0, false, m_numElmt,
632  m_nquad0, m_nquad1,
633  m_nmodes0, m_nmodes1,
634  m_base0, m_derbase1,
635  m_jac, tmp[1], tmp[0], wsp1);
636 
637  Vmath::Vadd(m_numElmt*nmodes,tmp[0],1,output,1,output,1);
638  }
639 
640  virtual void operator()(
641  int dir,
642  const Array<OneD, const NekDouble> &input,
643  Array<OneD, NekDouble> &output,
645  {
646  boost::ignore_unused(dir, input, output, wsp);
647  NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
648  }
649 
650  protected:
651  const int m_nquad0;
652  const int m_nquad1;
653  const int m_nmodes0;
654  const int m_nmodes1;
655  const bool m_colldir0;
656  const bool m_colldir1;
664 
665  private:
667  vector<StdRegions::StdExpansionSharedPtr> pCollExp,
668  CoalescedGeomDataSharedPtr pGeomData)
669  : Operator(pCollExp, pGeomData),
670  m_nquad0 (m_stdExp->GetNumPoints(0)),
671  m_nquad1 (m_stdExp->GetNumPoints(1)),
672  m_nmodes0 (m_stdExp->GetBasisNumModes(0)),
673  m_nmodes1 (m_stdExp->GetBasisNumModes(1)),
674  m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
675  m_colldir1(m_stdExp->GetBasis(1)->Collocation()),
676  m_base0 (m_stdExp->GetBasis(0)->GetBdata()),
677  m_base1 (m_stdExp->GetBasis(1)->GetBdata()),
678  m_derbase0(m_stdExp->GetBasis(0)->GetDbdata()),
679  m_derbase1(m_stdExp->GetBasis(1)->GetDbdata())
680  {
681  LibUtilities::PointsKeyVector PtsKey = m_stdExp->GetPointsKeys();
682  m_coordim = pCollExp[0]->GetCoordim();
683 
684  m_derivFac = pGeomData->GetDerivFactors(pCollExp);
685  m_jac = pGeomData->GetJacWithStdWeights(pCollExp);
686  m_wspSize = 4 * m_numElmt * (max(m_nquad0*m_nquad1,
687  m_nmodes0*m_nmodes1));
688  }
689 };
690 
691 /// Factory initialisation for the IProductWRTDerivBase_SumFac_Quad operator
692 OperatorKey IProductWRTDerivBase_SumFac_Quad::m_type =
695  IProductWRTDerivBase_SumFac_Quad::create,
696  "IProductWRTDerivBase_IterPerExp_Quad");
697 
698 
699 /**
700  * @brief Inner product WRT deriv base operator using sum-factorisation (Tri)
701  */
703 {
704  public:
706 
708  {
709  }
710 
711  /**
712  * This method calculates:
713  *
714  * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) \f]
715  *
716  * which can be represented in terms of local cartesian
717  * derivaties as:
718  *
719  * \f[ ((d\phi/d\xi_0\, d\xi_0/dx +
720  * d\phi/d\xi_1\, d\xi_1/dx),in[0]) + \f]
721  *
722  * \f[ ((d\phi/d\xi_0\, d\xi_0/dy +
723  * d\phi/d\xi_1\, d\xi_1/dy),in[1]) + \f]
724  *
725  * where we note that
726  *
727  * \f[ d\phi/d\xi_0 = d\phi/d\eta_0\, d\eta_0/d\xi_0 =
728  * d\phi/d\eta_0 2/(1-\eta_1) \f]
729  *
730  * \f[ d\phi/d\xi_1 = d\phi/d\eta_1\, d\eta_1/d\xi_1 +
731  * d\phi/d\eta_1\, d\eta_1/d\xi_1 = d\phi/d\eta_0 (1+\eta_0)/(1-\eta_1)
732  * + d\phi/d\eta_1 \f]
733  *
734  * and so the full inner products are
735  *
736  * \f[ (d\phi/dx,in[0]) + (dphi/dy,in[1]) =
737  * (d\phi/d\eta_0, ((2/(1-\eta_1) (d\xi_0/dx in[0] + d\xi_0/dy in[1])
738  * + (1-\eta_0)/(1-\eta_1) (d\xi_1/dx in[0]+d\xi_1/dy in[1]))
739  * + (d\phi/d\eta_1, (d\xi_1/dx in[0] + d\xi_1/dy in[1])) \f]
740  *
741  */
742  virtual void operator()(
743  const Array<OneD, const NekDouble> &entry0,
744  Array<OneD, NekDouble> &entry1,
745  Array<OneD, NekDouble> &entry2,
746  Array<OneD, NekDouble> &entry3,
748  {
749  unsigned int nPhys = m_stdExp->GetTotPoints();
750  unsigned int ntot = m_numElmt*nPhys;
751  unsigned int nmodes = m_stdExp->GetNcoeffs();
752  unsigned int nmax = max(ntot,m_numElmt*nmodes);
754  Array<OneD, NekDouble> output, wsp1;
756 
757  in[0] = entry0; in[1] = entry1; in[2] = entry2;
758 
759  output = (m_coordim == 2)? entry2: entry3;
760 
761  tmp[0] = wsp; tmp[1] = wsp + nmax;
762  wsp1 = wsp + 2*nmax;
763 
764  for(int i = 0; i < 2; ++i)
765  {
766  Vmath::Vmul (ntot,m_derivFac[i],1, in[0],1, tmp[i],1);
767 
768  for(int j = 1; j < 2; ++j)
769  {
770  Vmath::Vvtvp (ntot,m_derivFac[i +j*2],1,
771  in[j],1, tmp[i], 1, tmp[i],1);
772  }
773  }
774 
775  // Multiply by factor: 2/(1-z1)
776  for (int i = 0; i < m_numElmt; ++i)
777  {
778  // scale tmp[0] by geometric factor: 2/(1-z1)
779  Vmath::Vmul(nPhys,&m_fac0[0],1,tmp[0].get()+i*nPhys,1,
780  tmp[0].get()+i*nPhys,1);
781 
782  // scale tmp[1] by geometric factor (1+z0)/(1-z1)
783  Vmath::Vvtvp(nPhys,&m_fac1[0],1,tmp[1].get()+i*nPhys,1,
784  tmp[0].get()+i*nPhys,1,tmp[0].get()+i*nPhys,1);
785  }
786 
787  // Iproduct wrt derivative of base 0
788  TriIProduct(m_sortTopVertex, m_numElmt, m_nquad0, m_nquad1,
789  m_nmodes0, m_nmodes1, m_derbase0, m_base1,
790  m_jac, tmp[0], output, wsp1);
791 
792  // Iproduct wrt derivative of base 1
793  TriIProduct(m_sortTopVertex, m_numElmt, m_nquad0, m_nquad1,
794  m_nmodes0, m_nmodes1, m_base0, m_derbase1,
795  m_jac, tmp[1], tmp[0], wsp1);
796 
797  Vmath::Vadd(m_numElmt*nmodes,tmp[0],1,output,1,output,1);
798  }
799 
800  virtual void operator()(
801  int dir,
802  const Array<OneD, const NekDouble> &input,
803  Array<OneD, NekDouble> &output,
805  {
806  boost::ignore_unused(dir, input, output, wsp);
807  NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
808  }
809 
810  protected:
811  const int m_nquad0;
812  const int m_nquad1;
813  const int m_nmodes0;
814  const int m_nmodes1;
815  const bool m_colldir0;
816  const bool m_colldir1;
827 
828  private:
830  vector<StdRegions::StdExpansionSharedPtr> pCollExp,
831  CoalescedGeomDataSharedPtr pGeomData)
832  : Operator(pCollExp, pGeomData),
833  m_nquad0 (m_stdExp->GetNumPoints(0)),
834  m_nquad1 (m_stdExp->GetNumPoints(1)),
835  m_nmodes0 (m_stdExp->GetBasisNumModes(0)),
836  m_nmodes1 (m_stdExp->GetBasisNumModes(1)),
837  m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
838  m_colldir1(m_stdExp->GetBasis(1)->Collocation()),
839  m_base0 (m_stdExp->GetBasis(0)->GetBdata()),
840  m_base1 (m_stdExp->GetBasis(1)->GetBdata()),
841  m_derbase0(m_stdExp->GetBasis(0)->GetDbdata()),
842  m_derbase1(m_stdExp->GetBasis(1)->GetDbdata())
843  {
844  LibUtilities::PointsKeyVector PtsKey = m_stdExp->GetPointsKeys();
845  m_coordim = pCollExp[0]->GetCoordim();
846 
847  m_derivFac = pGeomData->GetDerivFactors(pCollExp);
848  m_jac = pGeomData->GetJacWithStdWeights(pCollExp);
849  m_wspSize = 4 * m_numElmt * (max(m_nquad0*m_nquad1,
850  m_nmodes0*m_nmodes1));
851 
852  if(m_stdExp->GetBasis(0)->GetBasisType()
854  {
855  m_sortTopVertex = true;
856  }
857  else
858  {
859  m_sortTopVertex = false;
860  }
861 
863  = m_stdExp->GetBasis(0)->GetZ();
865  = m_stdExp->GetBasis(1)->GetZ();
866 
867  m_fac0 = Array<OneD, NekDouble>(m_nquad0*m_nquad1);
868  // set up geometric factor: 2/(1-z1)
869  for (int i = 0; i < m_nquad0; ++i)
870  {
871  for(int j = 0; j < m_nquad1; ++j)
872  {
873  m_fac0[i+j*m_nquad0] = 2.0/(1-z1[j]);
874  }
875  }
876 
877  m_fac1 = Array<OneD, NekDouble>(m_nquad0*m_nquad1);
878  // set up geometric factor: (1+z0)/(1-z1)
879  for (int i = 0; i < m_nquad0; ++i)
880  {
881  for(int j = 0; j < m_nquad1; ++j)
882  {
883  m_fac1[i+j*m_nquad0] = (1+z0[i])/(1-z1[j]);
884  }
885  }
886  }
887 };
888 
889 /// Factory initialisation for the IProductWRTDerivBase_SumFac_Tri operator
890 OperatorKey IProductWRTDerivBase_SumFac_Tri::m_type =
893  IProductWRTDerivBase_SumFac_Tri::create,
894  "IProductWRTDerivBase_IterPerExp_Tri");
895 
896 
897 /**
898  * @brief Inner product WRT deriv base operator using sum-factorisation (Hex)
899  */
901 {
902  public:
904 
906  {
907  }
908 
909  virtual void operator()(
910  const Array<OneD, const NekDouble> &entry0,
911  Array<OneD, NekDouble> &entry1,
912  Array<OneD, NekDouble> &entry2,
913  Array<OneD, NekDouble> &entry3,
915  {
916  unsigned int nPhys = m_stdExp->GetTotPoints();
917  unsigned int ntot = m_numElmt*nPhys;
918  unsigned int nmodes = m_stdExp->GetNcoeffs();
919  unsigned int nmax = max(ntot,m_numElmt*nmodes);
921  Array<OneD, NekDouble> output, wsp1;
923 
924  in[0] = entry0; in[1] = entry1;
925  in[2] = entry2;
926 
927  output = entry3;
928 
929  for(int i = 0; i < 3; ++i)
930  {
931  tmp[i] = wsp + i*nmax;
932  }
933 
934  // calculate dx/dxi in[0] + dy/dxi in[1] + dz/dxi in[2]
935  for(int i = 0; i < 3; ++i)
936  {
937  Vmath::Vmul (ntot,m_derivFac[i],1, in[0],1,
938  tmp[i],1);
939  for(int j = 1; j < 3; ++j)
940  {
941  Vmath::Vvtvp (ntot,m_derivFac[i+3*j],1,
942  in[j],1, tmp[i], 1, tmp[i],1);
943  }
944  }
945 
946  wsp1 = wsp + 3*nmax;
947 
948  // calculate Iproduct WRT Std Deriv
949  HexIProduct(false,m_colldir1,m_colldir2, m_numElmt,
950  m_nquad0, m_nquad1, m_nquad2,
951  m_nmodes0, m_nmodes1, m_nmodes2,
952  m_derbase0, m_base1, m_base2,
953  m_jac,tmp[0],output,wsp1);
954 
955  HexIProduct(m_colldir0,false,m_colldir2, m_numElmt,
956  m_nquad0, m_nquad1, m_nquad2,
957  m_nmodes0, m_nmodes1, m_nmodes2,
958  m_base0, m_derbase1, m_base2,
959  m_jac,tmp[1],tmp[0],wsp1);
960  Vmath::Vadd(m_numElmt*nmodes,tmp[0],1,output,1,output,1);
961 
962  HexIProduct(m_colldir0,m_colldir1,false, m_numElmt,
963  m_nquad0, m_nquad1, m_nquad2,
964  m_nmodes0, m_nmodes1, m_nmodes2,
965  m_base0, m_base1, m_derbase2,
966  m_jac,tmp[2],tmp[0],wsp1);
967  Vmath::Vadd(m_numElmt*nmodes,tmp[0],1,output,1,output,1);
968  }
969 
970  virtual void operator()(
971  int dir,
972  const Array<OneD, const NekDouble> &input,
973  Array<OneD, NekDouble> &output,
975  {
976  boost::ignore_unused(dir, input, output, wsp);
977  NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
978  }
979 
980  protected:
981  const int m_nquad0;
982  const int m_nquad1;
983  const int m_nquad2;
984  const int m_nmodes0;
985  const int m_nmodes1;
986  const int m_nmodes2;
987  const bool m_colldir0;
988  const bool m_colldir1;
989  const bool m_colldir2;
998 
999  private:
1001  vector<StdRegions::StdExpansionSharedPtr> pCollExp,
1002  CoalescedGeomDataSharedPtr pGeomData)
1003  : Operator (pCollExp, pGeomData),
1004  m_nquad0 (m_stdExp->GetNumPoints(0)),
1005  m_nquad1 (m_stdExp->GetNumPoints(1)),
1006  m_nquad2 (m_stdExp->GetNumPoints(2)),
1007  m_nmodes0 (m_stdExp->GetBasisNumModes(0)),
1008  m_nmodes1 (m_stdExp->GetBasisNumModes(1)),
1009  m_nmodes2 (m_stdExp->GetBasisNumModes(2)),
1010  m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
1011  m_colldir1(m_stdExp->GetBasis(1)->Collocation()),
1012  m_colldir2(m_stdExp->GetBasis(2)->Collocation()),
1013  m_base0 (m_stdExp->GetBasis(0)->GetBdata()),
1014  m_base1 (m_stdExp->GetBasis(1)->GetBdata()),
1015  m_base2 (m_stdExp->GetBasis(2)->GetBdata()),
1016  m_derbase0(m_stdExp->GetBasis(0)->GetDbdata()),
1017  m_derbase1(m_stdExp->GetBasis(1)->GetDbdata()),
1018  m_derbase2(m_stdExp->GetBasis(2)->GetDbdata())
1019 
1020  {
1021  m_jac = pGeomData->GetJacWithStdWeights(pCollExp);
1022  m_wspSize = 6 * m_numElmt * (max(m_nquad0*m_nquad1*m_nquad2,
1023  m_nmodes0*m_nmodes1*m_nmodes2));
1024  m_derivFac = pGeomData->GetDerivFactors(pCollExp);
1025  }
1026 };
1027 
1028 /// Factory initialisation for the IProductWRTDerivBase_SumFac_Hex operator
1029 OperatorKey IProductWRTDerivBase_SumFac_Hex::m_type = GetOperatorFactory().
1030  RegisterCreatorFunction(
1032  IProductWRTDerivBase_SumFac_Hex::create,
1033  "IProductWRTDerivBase_SumFac_Hex");
1034 
1035 
1036 /**
1037  * @brief Inner product WRT deriv base operator using sum-factorisation (Tet)
1038  */
1040 {
1041  public:
1043 
1044 
1045  /**
1046  * This method calculates:
1047  *
1048  * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) + (d\phi/dz,in[2]) \f]
1049  *
1050  * which can be represented in terms of local cartesian
1051  * derivaties as:
1052  *
1053  * \f[ ((d\phi/d\xi_0\, d\xi_0/dx +
1054  * d\phi/d\xi_1\, d\xi_1/dx +
1055  * d\phi/d\xi_2\, d\xi_2/dx),in[0]) + \f]
1056  *
1057  * \f[ ((d\phi/d\xi_0\, d\xi_0/dy +
1058  * d\phi/d\xi_1\, d\xi_1/dy +
1059  * d\phi/d\xi_2\, d\xi_2/dy),in[1]) + \f]
1060  *
1061  * \f[ ((d\phi/d\xi_0\, d\xi_0/dz +
1062  * d\phi/d\xi_1\, d\xi_1/dz +
1063  * d\phi/d\xi_2\, d\xi_2/dz),in[2]) \, \f]
1064  *
1065  * where we note that
1066  *
1067  * \f[ d\phi/d\xi_0 = d\phi/d\eta_0 4/((1-\eta_1)(1-\eta_2)) \f]
1068  *
1069  * \f[ d\phi/d\xi_1 = d\phi/d\eta_0 2(1+\eta_0)/((1-\eta_1)(1-\eta_2))
1070  * + d\phi/d\eta_1 2/(1-\eta_2) \f]
1071  *
1072  * \f[ d\phi/d\xi_2 = d\phi/d\eta_0 2(1+\eta_0)/((1-\eta_1)(1-\eta_2))
1073  * + d\phi/d\eta_1 (1+\eta_1)/(1-\eta_2) + d\phi/d\eta_2 \f]
1074  *
1075  * and so the full inner products are
1076  *
1077  * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) + (d\phi/dz,in[2]) = \f]
1078  *
1079  * \f[ (d\phi/d\eta_0, fac0 (tmp0 + fac1(tmp1 + tmp2)))
1080  * + (d\phi/d\eta_1, fac2 (tmp1 + fac3 tmp2))
1081  * + (d\phi/d\eta_2, tmp2) \f]
1082  *
1083  * where
1084  *
1085  * \f[ \begin{array}{lcl}
1086  * tmp0 &=& (d\xi_0/dx in[0] + d\xi_0/dy in[1] + d\xi_0/dz in[2]) \\
1087  * tmp1 &=& (d\xi_1/dx in[0] + d\xi_1/dy in[1] + d\xi_1/dz in[2]) \\
1088  * tmp2 &=& (d\xi_2/dx in[0] + d\xi_2/dy in[1] + d\xi_2/dz in[2])
1089  * \end{array} \f]
1090  *
1091  * \f[ \begin{array}{lcl}
1092  * fac0 &= & 4/((1-\eta_1)(1-\eta_2)) \\
1093  * fac1 &= & (1+\eta_0)/2 \\
1094  * fac2 &= & 2/(1-\eta_2) \\
1095  * fac3 &= & (1+\eta_1)/2 \end{array} \f]
1096  *
1097  */
1098  virtual void operator()(
1099  const Array<OneD, const NekDouble> &entry0,
1100  Array<OneD, NekDouble> &entry1,
1101  Array<OneD, NekDouble> &entry2,
1102  Array<OneD, NekDouble> &entry3,
1103  Array<OneD, NekDouble> &wsp)
1104  {
1105  unsigned int nPhys = m_stdExp->GetTotPoints();
1106  unsigned int ntot = m_numElmt*nPhys;
1107  unsigned int nmodes = m_stdExp->GetNcoeffs();
1108  unsigned int nmax = max(ntot,m_numElmt*nmodes);
1110  Array<OneD, NekDouble> output, wsp1;
1112 
1113  in[0] = entry0; in[1] = entry1;
1114  in[2] = entry2;
1115 
1116  output = entry3;
1117 
1118  for(int i = 0; i < 3; ++i)
1119  {
1120  tmp[i] = wsp + i*nmax;
1121  }
1122 
1123  for(int i = 0; i < 3; ++i)
1124  {
1125  Vmath::Vmul (ntot,m_derivFac[i],1, in[0],1,tmp[i],1);
1126  for(int j = 1; j < 3; ++j)
1127  {
1128  Vmath::Vvtvp (ntot,m_derivFac[i+3*j],1,
1129  in[j],1, tmp[i], 1, tmp[i],1);
1130  }
1131  }
1132 
1133  wsp1 = wsp + 3*nmax;
1134 
1135  // Sort into eta factors
1136  for (int i = 0; i < m_numElmt; ++i)
1137  {
1138  // add tmp[1] + tmp[2]
1139  Vmath::Vadd(nPhys, tmp[1].get() + i*nPhys, 1,
1140  tmp[2].get() + i*nPhys, 1,
1141  wsp1.get(), 1);
1142 
1143  // scale wsp1 by fac1 and add to tmp0
1144  Vmath::Vvtvp(nPhys,&m_fac1[0],1,wsp1.get(),1,
1145  tmp[0].get()+i*nPhys,1,tmp[0].get()+i*nPhys,1);
1146 
1147  // scale tmp[0] by fac0
1148  Vmath::Vmul(nPhys,&m_fac0[0],1,tmp[0].get()+i*nPhys,1,
1149  tmp[0].get()+i*nPhys,1);
1150 
1151  // scale tmp[2] by fac3 and add to tmp1
1152  Vmath::Vvtvp(nPhys,&m_fac3[0],1,tmp[2].get()+i*nPhys,1,
1153  tmp[1].get()+i*nPhys,1,tmp[1].get()+i*nPhys,1);
1154 
1155  // scale tmp[1] by fac2
1156  Vmath::Vmul(nPhys,&m_fac2[0],1,tmp[1].get()+i*nPhys,1,
1157  tmp[1].get()+i*nPhys,1);
1158  }
1159 
1160 
1161  // calculate Iproduct WRT Std Deriv
1162  TetIProduct(m_sortTopEdge, m_numElmt,
1163  m_nquad0, m_nquad1, m_nquad2,
1164  m_nmodes0, m_nmodes1, m_nmodes2,
1165  m_derbase0, m_base1, m_base2,
1166  m_jac,tmp[0],output,wsp1);
1167 
1168  TetIProduct(m_sortTopEdge, m_numElmt,
1169  m_nquad0, m_nquad1, m_nquad2,
1170  m_nmodes0, m_nmodes1, m_nmodes2,
1171  m_base0, m_derbase1, m_base2,
1172  m_jac,tmp[1],tmp[0],wsp1);
1173  Vmath::Vadd(m_numElmt*nmodes,tmp[0],1,output,1,output,1);
1174 
1175  TetIProduct(m_sortTopEdge, m_numElmt,
1176  m_nquad0, m_nquad1, m_nquad2,
1177  m_nmodes0, m_nmodes1, m_nmodes2,
1178  m_base0, m_base1, m_derbase2,
1179  m_jac,tmp[2],tmp[0],wsp1);
1180  Vmath::Vadd(m_numElmt*nmodes,tmp[0],1,output,1,output,1);
1181  }
1182 
1183  virtual void operator()(
1184  int dir,
1185  const Array<OneD, const NekDouble> &input,
1186  Array<OneD, NekDouble> &output,
1188  {
1189  boost::ignore_unused(dir, input, output, wsp);
1190  NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
1191  }
1192 
1193  protected:
1194  const int m_nquad0;
1195  const int m_nquad1;
1196  const int m_nquad2;
1197  const int m_nmodes0;
1198  const int m_nmodes1;
1199  const int m_nmodes2;
1213 
1214  private:
1216  vector<StdRegions::StdExpansionSharedPtr> pCollExp,
1217  CoalescedGeomDataSharedPtr pGeomData)
1218  : Operator (pCollExp, pGeomData),
1219  m_nquad0 (m_stdExp->GetNumPoints(0)),
1220  m_nquad1 (m_stdExp->GetNumPoints(1)),
1221  m_nquad2 (m_stdExp->GetNumPoints(2)),
1222  m_nmodes0 (m_stdExp->GetBasisNumModes(0)),
1223  m_nmodes1 (m_stdExp->GetBasisNumModes(1)),
1224  m_nmodes2 (m_stdExp->GetBasisNumModes(2)),
1225  m_base0 (m_stdExp->GetBasis(0)->GetBdata()),
1226  m_base1 (m_stdExp->GetBasis(1)->GetBdata()),
1227  m_base2 (m_stdExp->GetBasis(2)->GetBdata()),
1228  m_derbase0(m_stdExp->GetBasis(0)->GetDbdata()),
1229  m_derbase1(m_stdExp->GetBasis(1)->GetDbdata()),
1230  m_derbase2(m_stdExp->GetBasis(2)->GetDbdata())
1231 
1232  {
1233  m_jac = pGeomData->GetJacWithStdWeights(pCollExp);
1234  m_wspSize = 6 * m_numElmt * (max(m_nquad0*m_nquad1*m_nquad2,
1235  m_nmodes0*m_nmodes1*m_nmodes2));
1236  m_derivFac = pGeomData->GetDerivFactors(pCollExp);
1237 
1238 
1240  = m_stdExp->GetBasis(0)->GetZ();
1242  = m_stdExp->GetBasis(1)->GetZ();
1244  = m_stdExp->GetBasis(2)->GetZ();
1245 
1246  m_fac0 = Array<OneD, NekDouble>(m_nquad0*m_nquad1*m_nquad2);
1247  m_fac1 = Array<OneD, NekDouble>(m_nquad0*m_nquad1*m_nquad2);
1248  m_fac2 = Array<OneD, NekDouble>(m_nquad0*m_nquad1*m_nquad2);
1249  m_fac3 = Array<OneD, NekDouble>(m_nquad0*m_nquad1*m_nquad2);
1250  // calculate 2.0/((1-eta_1)(1-eta_2))
1251  for (int i = 0; i < m_nquad0; ++i)
1252  {
1253  for(int j = 0; j < m_nquad1; ++j)
1254  {
1255  for(int k = 0; k < m_nquad2; ++k)
1256  {
1257 
1258  m_fac0[i + j*m_nquad0 + k*m_nquad0*m_nquad1]
1259  = 4.0/((1-z1[j])*(1-z2[k]));
1260  m_fac1[i + j*m_nquad0 + k*m_nquad0*m_nquad1]
1261  = (1+z0[i])*0.5;
1262  m_fac2[i + j*m_nquad0 + k*m_nquad0*m_nquad1]
1263  = 2.0/(1-z2[k]);
1264  m_fac3[i + j*m_nquad0 + k*m_nquad0*m_nquad1]
1265  = (1+z1[j])*0.5;
1266  }
1267  }
1268  }
1269 
1270  if(m_stdExp->GetBasis(0)->GetBasisType()
1272  {
1273  m_sortTopEdge = true;
1274  }
1275  else
1276  {
1277  m_sortTopEdge = false;
1278  }
1279 
1280  }
1281 };
1282 
1283 /// Factory initialisation for the IProductWRTDerivBase_SumFac_Tet operator
1284 OperatorKey IProductWRTDerivBase_SumFac_Tet::m_type = GetOperatorFactory().
1285  RegisterCreatorFunction(
1287  IProductWRTDerivBase_SumFac_Tet::create,
1288  "IProductWRTDerivBase_SumFac_Tet");
1289 
1290 
1291 /**
1292  * @brief Inner product WRT deriv base operator using sum-factorisation (Prism)
1293  */
1295 {
1296  public:
1298 
1300  {
1301  }
1302 
1303  /**
1304  * This method calculates:
1305  *
1306  * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) + (d\phi/dz,in[2]) \f]
1307  *
1308  * which can be represented in terms of local cartesian
1309  * derivaties as:
1310  *
1311  * \f[ ((d\phi/d\xi_0\, d\xi_0/dx +
1312  * d\phi/d\xi_1\, d\xi_1/dx +
1313  * d\phi/d\xi_2\, d\xi_2/dx),in[0]) + \f]
1314  *
1315  * \f[ ((d\phi/d\xi_0\, d\xi_0/dy +
1316  * d\phi/d\xi_1\, d\xi_1/dy +
1317  * d\phi/d\xi_2\, d\xi_2/dy),in[1]) + \f]
1318  *
1319  * \f[ ((d\phi/d\xi_0\, d\xi_0/dz +
1320  * d\phi/d\xi_1\, d\xi_1/dz +
1321  * d\phi/d\xi_2\, d\xi_2/dz),in[2]) \, \f]
1322  *
1323  * where we note that
1324  *
1325  * \f[ d\phi/d\xi_0 =
1326  * d\phi/d\eta_0 d\eta_0/d\xi_0 = d\phi/d\eta_0 2/(1-\eta_2) \f]
1327  *
1328  * \f[ d\phi/d\xi_2 =
1329  * d\phi/d\eta_0 d\eta_0/d\xi_2 + d\phi/d\eta_2 d\eta_2/d\xi_2 =
1330  * d\phi/d\eta_0 (1+\eta_0)/(1-\eta_2) + d\phi/d\eta_2 \f]
1331  *
1332  *
1333  * and so the full inner products are
1334  *
1335  * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) + (d\phi/dz,in[2]) = \f]
1336  *
1337  * \f[ (d\phi/d\eta_0, ((2/(1-\eta_2) (d\xi_0/dx in[0] + d\xi_0/dy in[1]
1338  * + d\xi_0/dz in[2])
1339  * + (1-\eta_0)/(1-\eta_2) (d\xi_2/dx in[0] + d\xi_2/dy in[1]
1340  * + d\xi_2/dz in[2] )) + \f]
1341  *
1342  * \f[ (d\phi/d\eta_1, (d\xi_1/dx in[0] + d\xi_1/dy in[1]
1343  * + d\xi_1/dz in[2])) + \f]
1344  *
1345  * \f[ (d\phi/d\eta_2, (d\xi_2/dx in[0] + d\xi_2/dy in[1]
1346  * + d\xi_2/dz in[2])) \f]
1347  *
1348  */
1349  virtual void operator()(
1350  const Array<OneD, const NekDouble> &entry0,
1351  Array<OneD, NekDouble> &entry1,
1352  Array<OneD, NekDouble> &entry2,
1353  Array<OneD, NekDouble> &entry3,
1355  {
1356  unsigned int nPhys = m_stdExp->GetTotPoints();
1357  unsigned int ntot = m_numElmt*nPhys;
1358  unsigned int nmodes = m_stdExp->GetNcoeffs();
1359  unsigned int nmax = max(ntot,m_numElmt*nmodes);
1361  Array<OneD, NekDouble> output, wsp1;
1363 
1364  in[0] = entry0; in[1] = entry1;
1365  in[2] = entry2;
1366 
1367  output = entry3;
1368 
1369  for(int i = 0; i < 3; ++i)
1370  {
1371  tmp[i] = wsp + i*nmax;
1372  }
1373 
1374  for(int i = 0; i < 3; ++i)
1375  {
1376  Vmath::Vmul (ntot,m_derivFac[i],1, in[0],1,
1377  tmp[i],1);
1378  for(int j = 1; j < 3; ++j)
1379  {
1380  Vmath::Vvtvp (ntot,m_derivFac[i+3*j],1,
1381  in[j],1, tmp[i], 1, tmp[i],1);
1382  }
1383  }
1384  wsp1 = wsp + 3*nmax;
1385 
1386  // Sort into eta factors
1387  for (int i = 0; i < m_numElmt; ++i)
1388  {
1389  // scale tmp[0] by fac0
1390  Vmath::Vmul(nPhys,&m_fac0[0],1,tmp[0].get()+i*nPhys,1,
1391  tmp[0].get()+i*nPhys,1);
1392 
1393  // scale tmp[2] by fac1 and add to tmp0
1394  Vmath::Vvtvp(nPhys,&m_fac1[0],1,tmp[2].get()+i*nPhys,1,
1395  tmp[0].get()+i*nPhys,1,tmp[0].get()+i*nPhys,1);
1396  }
1397 
1398  // calculate Iproduct WRT Std Deriv
1399  PrismIProduct(m_sortTopVertex, m_numElmt,
1400  m_nquad0, m_nquad1, m_nquad2,
1401  m_nmodes0, m_nmodes1, m_nmodes2,
1402  m_derbase0, m_base1, m_base2,
1403  m_jac,tmp[0],output,wsp1);
1404 
1405  PrismIProduct(m_sortTopVertex, m_numElmt,
1406  m_nquad0, m_nquad1, m_nquad2,
1407  m_nmodes0, m_nmodes1, m_nmodes2,
1408  m_base0, m_derbase1, m_base2,
1409  m_jac,tmp[1],tmp[0],wsp1);
1410  Vmath::Vadd(m_numElmt*nmodes,tmp[0],1,output,1,output,1);
1411 
1412  PrismIProduct(m_sortTopVertex, m_numElmt,
1413  m_nquad0, m_nquad1, m_nquad2,
1414  m_nmodes0, m_nmodes1, m_nmodes2,
1415  m_base0, m_base1, m_derbase2,
1416  m_jac,tmp[2],tmp[0],wsp1);
1417  Vmath::Vadd(m_numElmt*nmodes,tmp[0],1,output,1,output,1);
1418  }
1419 
1420  virtual void operator()(
1421  int dir,
1422  const Array<OneD, const NekDouble> &input,
1423  Array<OneD, NekDouble> &output,
1425  {
1426  boost::ignore_unused(dir, input, output, wsp);
1427  NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
1428  }
1429 
1430 
1431  protected:
1432  const int m_nquad0;
1433  const int m_nquad1;
1434  const int m_nquad2;
1435  const int m_nmodes0;
1436  const int m_nmodes1;
1437  const int m_nmodes2;
1449 
1450  private:
1452  vector<StdRegions::StdExpansionSharedPtr> pCollExp,
1453  CoalescedGeomDataSharedPtr pGeomData)
1454  : Operator (pCollExp, pGeomData),
1455  m_nquad0 (m_stdExp->GetNumPoints(0)),
1456  m_nquad1 (m_stdExp->GetNumPoints(1)),
1457  m_nquad2 (m_stdExp->GetNumPoints(2)),
1458  m_nmodes0 (m_stdExp->GetBasisNumModes(0)),
1459  m_nmodes1 (m_stdExp->GetBasisNumModes(1)),
1460  m_nmodes2 (m_stdExp->GetBasisNumModes(2)),
1461  m_base0 (m_stdExp->GetBasis(0)->GetBdata()),
1462  m_base1 (m_stdExp->GetBasis(1)->GetBdata()),
1463  m_base2 (m_stdExp->GetBasis(2)->GetBdata()),
1464  m_derbase0(m_stdExp->GetBasis(0)->GetDbdata()),
1465  m_derbase1(m_stdExp->GetBasis(1)->GetDbdata()),
1466  m_derbase2(m_stdExp->GetBasis(2)->GetDbdata())
1467 
1468  {
1469  m_jac = pGeomData->GetJacWithStdWeights(pCollExp);
1470  m_wspSize = 6 * m_numElmt * (max(m_nquad0*m_nquad1*m_nquad2,
1471  m_nmodes0*m_nmodes1*m_nmodes2));
1472  m_derivFac = pGeomData->GetDerivFactors(pCollExp);
1473 
1474  if(m_stdExp->GetBasis(0)->GetBasisType()
1476  {
1477  m_sortTopVertex = true;
1478  }
1479  else
1480  {
1481  m_sortTopVertex = false;
1482  }
1483 
1485  = m_stdExp->GetBasis(0)->GetZ();
1487  = m_stdExp->GetBasis(2)->GetZ();
1488 
1489  m_fac0 = Array<OneD, NekDouble>(m_nquad0*m_nquad1*m_nquad2);
1490  m_fac1 = Array<OneD, NekDouble>(m_nquad0*m_nquad1*m_nquad2);
1491 
1492  for (int i = 0; i < m_nquad0; ++i)
1493  {
1494  for(int j = 0; j < m_nquad1; ++j)
1495  {
1496  for(int k = 0; k < m_nquad2; ++k)
1497  {
1498  // set up geometric factor: 2/(1-z1)
1499  m_fac0[i + j*m_nquad0 + k*m_nquad0*m_nquad1]
1500  = 2.0/(1-z2[k]);
1501  // set up geometric factor: (1+z0)/(1-z1)
1502  m_fac1[i + j*m_nquad0 + k*m_nquad0*m_nquad1]
1503  = (1+z0[i])/(1-z2[k]);
1504 
1505  }
1506  }
1507  }
1508  }
1509 };
1510 
1511 /// Factory initialisation for the IProductWRTDerivBase_SumFac_Prism operator
1512 OperatorKey IProductWRTDerivBase_SumFac_Prism::m_type = GetOperatorFactory().
1513  RegisterCreatorFunction(
1515  IProductWRTDerivBase_SumFac_Prism::create,
1516  "IProductWRTDerivBase_SumFac_Prism");
1517 
1518 
1519 
1520 /**
1521  * @brief Inner product WRT deriv base operator using sum-factorisation (Pyr)
1522  */
1524 {
1525  public:
1527 
1529  {
1530  }
1531 
1532 
1533  /**
1534  * This method calculates:
1535  *
1536  * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) + (d\phi/dz,in[2]) \f]
1537  *
1538  * which can be represented in terms of local cartesian
1539  * derivaties as:
1540  *
1541  * \f[ ((d\phi/d\xi_0\, d\xi_0/dx +
1542  * d\phi/d\xi_1\, d\xi_1/dx +
1543  * d\phi/d\xi_2\, d\xi_2/dx),in[0]) + \f]
1544  *
1545  * \f[ ((d\phi/d\xi_0\, d\xi_0/dy +
1546  * d\phi/d\xi_1\, d\xi_1/dy +
1547  * d\phi/d\xi_2\, d\xi_2/dy),in[1]) + \f]
1548  *
1549  * \f[ ((d\phi/d\xi_0\, d\xi_0/dz +
1550  * d\phi/d\xi_1\, d\xi_1/dz +
1551  * d\phi/d\xi_2\, d\xi_2/dz),in[2]) \, \f]
1552  *
1553  * where we note that
1554  *
1555  * \f[ d\phi/d\xi_0 =
1556  * d\phi/d\eta_0\, d\eta_0/d\xi_0 =
1557  * d\phi/d\eta_0\, 2/(1-\eta_2). \f]
1558  *
1559  * \f[ d\phi/d\xi_1 =
1560  * d\phi/d\eta_1\, d\eta_1/d\xi_1 =
1561  * d\phi/d\eta_1\, 2/(1-\eta_2) \f]
1562  *
1563  * \f[ d\phi/d\xi_2 =
1564  * d\phi/d\eta_0\, d\eta_0/d\xi_2 +
1565  * d\phi/d\eta_1\, d\eta_1/d\xi_2 +
1566  * d\phi/d\eta_2\, d\eta_2/d\xi_2 =
1567  * d\phi/d\eta_0 (1+\eta_0)/(1-\eta_2) +
1568  * d\phi/d\eta_1 (1+\eta_1)/(1-\eta_2) + d\phi/d\eta_2 \f]
1569  *
1570  * and so the full inner products are
1571  *
1572  * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) + (d\phi/dz,in[2]) = \f]
1573  *
1574  * \f[ (d\phi/d\eta_0, ((2/(1-\eta_2) (d\xi_0/dx in[0] +
1575  * d\xi_0/dy in[1] +
1576  * (1-\eta_0)/(1-\eta_2) (d\xi_2/dx in[0] + d\xi_2/dy in[1]
1577  * + d\xi_2/dz in[2] )) + \f]
1578  * \f[ (d\phi/d\eta_1, ((2/(1-\eta_2) (d\xi_1/dx in[0] +
1579  * d\xi_0/dy in[1] + d\xi_0/dz in[2]) +
1580  * (1-\eta_1)/(1-\eta_2) (d\xi_2/dx in[0] + d\xi_2/dy in[1] +
1581  * d\xi_2/dz in[2] )) \f]
1582  *
1583  * \f[ (d\phi/d\eta_2, (d\xi_2/dx in[0] + d\xi_2/dy in[1] +
1584  * d\xi_2/dz in[2])) \f]
1585  */
1586  virtual void operator()(
1587  const Array<OneD, const NekDouble> &entry0,
1588  Array<OneD, NekDouble> &entry1,
1589  Array<OneD, NekDouble> &entry2,
1590  Array<OneD, NekDouble> &entry3,
1592  {
1593  unsigned int nPhys = m_stdExp->GetTotPoints();
1594  unsigned int ntot = m_numElmt*nPhys;
1595  unsigned int nmodes = m_stdExp->GetNcoeffs();
1596  unsigned int nmax = max(ntot,m_numElmt*nmodes);
1598  Array<OneD, NekDouble> output, wsp1;
1600 
1601  in[0] = entry0; in[1] = entry1;
1602  in[2] = entry2;
1603 
1604  output = entry3;
1605 
1606  for(int i = 0; i < 3; ++i)
1607  {
1608  tmp[i] = wsp + i*nmax;
1609  }
1610 
1611  for(int i = 0; i < 3; ++i)
1612  {
1613  Vmath::Vmul (ntot,m_derivFac[i],1, in[0],1, tmp[i],1);
1614  for(int j = 1; j < 3; ++j)
1615  {
1616  Vmath::Vvtvp (ntot,m_derivFac[i+3*j],1,
1617  in[j],1, tmp[i], 1, tmp[i],1);
1618  }
1619  }
1620  wsp1 = wsp + 3*nmax;
1621 
1622  // Sort into eta factors
1623  for (int i = 0; i < m_numElmt; ++i)
1624  {
1625  // scale tmp[0] by fac0
1626  Vmath::Vmul(nPhys,&m_fac0[0],1,tmp[0].get()+i*nPhys,1,
1627  tmp[0].get()+i*nPhys,1);
1628 
1629  // scale tmp[2] by fac1 and add to tmp0
1630  Vmath::Vvtvp(nPhys,&m_fac1[0],1,tmp[2].get()+i*nPhys,1,
1631  tmp[0].get()+i*nPhys,1,tmp[0].get()+i*nPhys,1);
1632 
1633  // scale tmp[1] by fac0
1634  Vmath::Vmul(nPhys,&m_fac0[0],1,tmp[1].get()+i*nPhys,1,
1635  tmp[1].get()+i*nPhys,1);
1636 
1637  // scale tmp[2] by fac2 and add to tmp1
1638  Vmath::Vvtvp(nPhys,&m_fac2[0],1,tmp[2].get()+i*nPhys,1,
1639  tmp[1].get()+i*nPhys,1,tmp[1].get()+i*nPhys,1);
1640  }
1641 
1642  // calculate Iproduct WRT Std Deriv
1643  PyrIProduct(m_sortTopVertex, m_numElmt,
1644  m_nquad0, m_nquad1, m_nquad2,
1645  m_nmodes0, m_nmodes1, m_nmodes2,
1646  m_derbase0, m_base1, m_base2,
1647  m_jac,tmp[0],output,wsp1);
1648 
1649  PyrIProduct(m_sortTopVertex, m_numElmt,
1650  m_nquad0, m_nquad1, m_nquad2,
1651  m_nmodes0, m_nmodes1, m_nmodes2,
1652  m_base0, m_derbase1, m_base2,
1653  m_jac,tmp[1],tmp[0],wsp1);
1654  Vmath::Vadd(m_numElmt*nmodes,tmp[0],1,output,1,output,1);
1655 
1656  PyrIProduct(m_sortTopVertex, m_numElmt,
1657  m_nquad0, m_nquad1, m_nquad2,
1658  m_nmodes0, m_nmodes1, m_nmodes2,
1659  m_base0, m_base1, m_derbase2,
1660  m_jac,tmp[2],tmp[0],wsp1);
1661  Vmath::Vadd(m_numElmt*nmodes,tmp[0],1,output,1,output,1);
1662  }
1663 
1664  virtual void operator()(
1665  int dir,
1666  const Array<OneD, const NekDouble> &input,
1667  Array<OneD, NekDouble> &output,
1669  {
1670  boost::ignore_unused(dir, input, output, wsp);
1671  NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
1672  }
1673 
1674 
1675  protected:
1676  const int m_nquad0;
1677  const int m_nquad1;
1678  const int m_nquad2;
1679  const int m_nmodes0;
1680  const int m_nmodes1;
1681  const int m_nmodes2;
1694 
1695  private:
1697  vector<StdRegions::StdExpansionSharedPtr> pCollExp,
1698  CoalescedGeomDataSharedPtr pGeomData)
1699  : Operator (pCollExp, pGeomData),
1700  m_nquad0 (m_stdExp->GetNumPoints(0)),
1701  m_nquad1 (m_stdExp->GetNumPoints(1)),
1702  m_nquad2 (m_stdExp->GetNumPoints(2)),
1703  m_nmodes0 (m_stdExp->GetBasisNumModes(0)),
1704  m_nmodes1 (m_stdExp->GetBasisNumModes(1)),
1705  m_nmodes2 (m_stdExp->GetBasisNumModes(2)),
1706  m_base0 (m_stdExp->GetBasis(0)->GetBdata()),
1707  m_base1 (m_stdExp->GetBasis(1)->GetBdata()),
1708  m_base2 (m_stdExp->GetBasis(2)->GetBdata()),
1709  m_derbase0(m_stdExp->GetBasis(0)->GetDbdata()),
1710  m_derbase1(m_stdExp->GetBasis(1)->GetDbdata()),
1711  m_derbase2(m_stdExp->GetBasis(2)->GetDbdata())
1712 
1713  {
1714  m_jac = pGeomData->GetJacWithStdWeights(pCollExp);
1715  m_wspSize = 6 * m_numElmt * (max(m_nquad0*m_nquad1*m_nquad2,
1716  m_nmodes0*m_nmodes1*m_nmodes2));
1717  m_derivFac = pGeomData->GetDerivFactors(pCollExp);
1718 
1719  if(m_stdExp->GetBasis(0)->GetBasisType()
1721  {
1722  m_sortTopVertex = true;
1723  }
1724  else
1725  {
1726  m_sortTopVertex = false;
1727  }
1728 
1730  = m_stdExp->GetBasis(0)->GetZ();
1732  = m_stdExp->GetBasis(1)->GetZ();
1734  = m_stdExp->GetBasis(2)->GetZ();
1735 
1736  m_fac0 = Array<OneD, NekDouble>(m_nquad0*m_nquad1*m_nquad2);
1737  m_fac1 = Array<OneD, NekDouble>(m_nquad0*m_nquad1*m_nquad2);
1738  m_fac2 = Array<OneD, NekDouble>(m_nquad0*m_nquad1*m_nquad2);
1739 
1740  for (int i = 0; i < m_nquad0; ++i)
1741  {
1742  for(int j = 0; j < m_nquad1; ++j)
1743  {
1744  for(int k = 0; k < m_nquad2; ++k)
1745  {
1746  // set up geometric factor: 2/(1-z2)
1747  m_fac0[i + j*m_nquad0 + k*m_nquad0*m_nquad1]
1748  = 2.0/(1-z2[k]);
1749  // set up geometric factor: (1+z0)/(1-z2)
1750  m_fac1[i + j*m_nquad0 + k*m_nquad0*m_nquad1]
1751  = (1+z0[i])/(1-z2[k]);
1752  // set up geometric factor: (1+z1)/(1-z2)
1753  m_fac2[i + j*m_nquad0 + k*m_nquad0*m_nquad1]
1754  = (1+z1[j])/(1-z2[k]);
1755 
1756  }
1757  }
1758  }
1759  }
1760 };
1761 
1762 /// Factory initialisation for the IProductWRTDerivBase_SumFac_Pyr operator
1763 OperatorKey IProductWRTDerivBase_SumFac_Pyr::m_type = GetOperatorFactory().
1764  RegisterCreatorFunction(
1766  IProductWRTDerivBase_SumFac_Pyr::create,
1767  "IProductWRTDerivBase_SumFac_Pyr");
1768 
1769 
1770 }
1771 }
virtual void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
std::shared_ptr< CoalescedGeomData > CoalescedGeomDataSharedPtr
Inner product WRT deriv base operator using sum-factorisation (Tri)
Inner product WRT deriv base operator using sum-factorisation (Segment)
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:178
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:209
IProductWRTDerivBase_StdMat(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData)
std::vector< PointsKey > PointsKeyVector
Definition: Points.h:246
void PyrIProduct(bool sortTopVertex, 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:427
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
std::tuple< LibUtilities::ShapeType, OperatorType, ImplementationType, ExpansionIsNodal > OperatorKey
Key for describing an Operator.
Definition: Operator.h:161
IProductWRTDerivBase_SumFac_Tri(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData)
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
Definition: Vmath.cpp:445
Principle Modified Functions .
Definition: BasisType.h:48
Inner product WRT deriv base operator using LocalRegions implementation.
Inner product WRT deriv base operator using standard matrix approach.
STL namespace.
IProductWRTDerivBase_SumFac_Quad(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData)
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
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 A[m x n], B[n x k], C[m x k].
Definition: Blas.hpp:213
Base class for operators on a collection of elements.
Definition: Operator.h:109
virtual void operator()(const Array< OneD, const NekDouble > &entry0, Array< OneD, NekDouble > &entry1, Array< OneD, NekDouble > &entry2, Array< OneD, NekDouble > &entry3, Array< OneD, NekDouble > &wsp)
virtual void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
virtual void operator()(const Array< OneD, const NekDouble > &entry0, Array< OneD, NekDouble > &entry1, Array< OneD, NekDouble > &entry2, Array< OneD, NekDouble > &entry3, Array< OneD, NekDouble > &wsp)
Perform operation.
virtual void operator()(const Array< OneD, const NekDouble > &entry0, Array< OneD, NekDouble > &entry1, Array< OneD, NekDouble > &entry2, Array< OneD, NekDouble > &entry3, Array< OneD, NekDouble > &wsp)
Perform operation.
virtual void operator()(const Array< OneD, const NekDouble > &entry0, Array< OneD, NekDouble > &entry1, Array< OneD, NekDouble > &entry2, Array< OneD, NekDouble > &entry3, Array< OneD, NekDouble > &wsp)
Perform operation.
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:522
virtual void operator()(const Array< OneD, const NekDouble > &entry0, Array< OneD, NekDouble > &entry1, Array< OneD, NekDouble > &entry2, Array< OneD, NekDouble > &entry3, Array< OneD, NekDouble > &wsp)
IProductWRTDerivBase_SumFac_Prism(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData)
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:134
virtual void operator()(const Array< OneD, const NekDouble > &entry0, Array< OneD, NekDouble > &entry1, Array< OneD, NekDouble > &entry2, Array< OneD, NekDouble > &entry3, Array< OneD, NekDouble > &wsp)
Perform operation.
Inner product WRT deriv base operator using sum-factorisation (Tet)
virtual void operator()(const Array< OneD, const NekDouble > &entry0, Array< OneD, NekDouble > &entry1, Array< OneD, NekDouble > &entry2, Array< OneD, NekDouble > &entry3, Array< OneD, NekDouble > &wsp)
Perform operation.
virtual void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
virtual void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
virtual void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
IProductWRTDerivBase_SumFac_Seg(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData)
IProductWRTDerivBase_SumFac_Pyr(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData)
virtual void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
IProductWRTDerivBase_NoCollection(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData)
Inner product WRT deriv base operator using element-wise operation.
virtual void operator()(const Array< OneD, const NekDouble > &entry0, Array< OneD, NekDouble > &entry1, Array< OneD, NekDouble > &entry2, Array< OneD, NekDouble > &entry3, Array< OneD, NekDouble > &wsp)
Inner product WRT deriv base operator using sum-factorisation (Quad)
IProductWRTDerivBase_IterPerExp(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData)
Inner product WRT deriv base operator using sum-factorisation (Hex)
double NekDouble
OperatorFactory & GetOperatorFactory()
Returns the singleton Operator factory object.
Definition: Operator.cpp:108
virtual void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp)
Perform operation.
virtual void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
void PrismIProduct(bool sortTopVertex, 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:355
Inner product WRT deriv base operator using sum-factorisation (Prism)
#define OPERATOR_CREATE(cname)
Definition: Operator.h:45
IProductWRTDerivBase_SumFac_Hex(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData)
virtual void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
virtual void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
virtual void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:199
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:376
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1064
Inner product WRT deriv base operator using sum-factorisation (Pyr)
IProductWRTDerivBase_SumFac_Tet(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData)
vector< StdRegions::StdExpansionSharedPtr > m_expList
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.cpp:302
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:186