Nektar++
BwdTrans.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: BwdTrans.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: BwdTrans operator implementations
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
37 #include <Collections/Operator.h>
38 #include <MatrixFreeOps/Operator.hpp>
39 #include <boost/core/ignore_unused.hpp>
40 
41 using namespace std;
42 
43 namespace Nektar
44 {
45 namespace Collections
46 {
47 
55 
56 /**
57  * @brief Backward transform operator using standard matrix approach.
58  */
59 class BwdTrans_StdMat final : public Operator
60 {
61 public:
64  {
65  }
66 
68  Array<OneD, NekDouble> &output,
69  Array<OneD, NekDouble> &output1,
70  Array<OneD, NekDouble> &output2,
71  Array<OneD, NekDouble> &wsp) override
72  {
73  boost::ignore_unused(output1, output2, wsp);
74  Blas::Dgemm('N', 'N', m_mat->GetRows(), m_numElmt, m_mat->GetColumns(),
75  1.0, m_mat->GetRawPtr(), m_mat->GetRows(), input.get(),
76  m_stdExp->GetNcoeffs(), 0.0, output.get(),
77  m_stdExp->GetTotPoints());
78  }
79 
80  void operator()(int dir, const Array<OneD, const NekDouble> &input,
81  Array<OneD, NekDouble> &output,
82  Array<OneD, NekDouble> &wsp) override final
83  {
84  boost::ignore_unused(dir, input, output, wsp);
85  ASSERTL0(false, "Not valid for this operator.");
86  }
87 
88  virtual void CheckFactors(StdRegions::FactorMap factors,
89  int coll_phys_offset) override
90  {
91  boost::ignore_unused(factors, coll_phys_offset);
92  ASSERTL0(false, "Not valid for this operator.");
93  }
94 
95 protected:
97 
98 private:
99  BwdTrans_StdMat(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
100  CoalescedGeomDataSharedPtr pGeomData,
101  StdRegions::FactorMap factors)
102  : Operator(pCollExp, pGeomData, factors)
103  {
105  m_stdExp->DetShapeType(), *m_stdExp);
106  m_mat = m_stdExp->GetStdMatrix(key);
107  }
108 };
109 
110 /// Factory initialisation for the BwdTrans_StdMat operators
111 OperatorKey BwdTrans_StdMat::m_typeArr[] = {
114  BwdTrans_StdMat::create, "BwdTrans_StdMat_Seg"),
117  BwdTrans_StdMat::create, "BwdTrans_StdMat_Tri"),
120  BwdTrans_StdMat::create, "BwdTrans_StdMat_NodalTri"),
123  BwdTrans_StdMat::create, "BwdTrans_StdMat_Quad"),
126  BwdTrans_StdMat::create, "BwdTrans_StdMat_Tet"),
129  BwdTrans_StdMat::create, "BwdTrans_StdMat_NodalTet"),
132  BwdTrans_StdMat::create, "BwdTrans_StdMat_Pyr"),
134  OperatorKey(ePrism, eBwdTrans, eStdMat, false), BwdTrans_StdMat::create,
135  "BwdTrans_StdMat_Prism"),
137  OperatorKey(ePrism, eBwdTrans, eStdMat, true), BwdTrans_StdMat::create,
138  "BwdTrans_StdMat_NodalPrism"),
141  BwdTrans_StdMat::create, "BwdTrans_StdMat_Hex"),
144  BwdTrans_StdMat::create, "BwdTrans_SumFac_Pyr")};
145 
146 /**
147  * @brief Backward transform operator using matrix free operators.
148  */
150 {
151 public:
153 
155  {
156  }
157 
159  Array<OneD, NekDouble> &output0,
160  Array<OneD, NekDouble> &output1,
161  Array<OneD, NekDouble> &output2,
162  Array<OneD, NekDouble> &wsp) override final
163  {
164  boost::ignore_unused(output1, output2, wsp);
165 
166  if (m_isPadded)
167  {
168  // copy into padded vector
169  Vmath::Vcopy(m_nIn, input, 1, m_input, 1);
170  // call op
171  (*m_oper)(m_input, m_output);
172  // copy out of padded vector
173  Vmath::Vcopy(m_nOut, m_output, 1, output0, 1);
174  }
175  else
176  {
177  (*m_oper)(input, output0);
178  }
179  }
180 
181  void operator()(int dir, const Array<OneD, const NekDouble> &input,
182  Array<OneD, NekDouble> &output,
183  Array<OneD, NekDouble> &wsp) override final
184  {
185  boost::ignore_unused(dir, input, output, wsp);
186  NEKERROR(ErrorUtil::efatal,
187  "BwdTrans_MatrixFree: Not valid for this operator.");
188  }
189 
190  virtual void CheckFactors(StdRegions::FactorMap factors,
191  int coll_phys_offset) override
192  {
193  boost::ignore_unused(factors, coll_phys_offset);
194  ASSERTL0(false, "Not valid for this operator.");
195  }
196 
197 private:
198  std::shared_ptr<MatrixFree::BwdTrans> m_oper;
199 
200  BwdTrans_MatrixFree(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
201  CoalescedGeomDataSharedPtr pGeomData,
202  StdRegions::FactorMap factors)
203  : Operator(pCollExp, pGeomData, factors),
204  MatrixFreeOneInOneOut(pCollExp[0]->GetStdExp()->GetNcoeffs(),
205  pCollExp[0]->GetStdExp()->GetTotPoints(),
206  pCollExp.size())
207  {
208  // Basis vector.
209  const auto dim = pCollExp[0]->GetStdExp()->GetShapeDimension();
210  std::vector<LibUtilities::BasisSharedPtr> basis(dim);
211  for (auto i = 0; i < dim; ++i)
212  {
213  basis[i] = pCollExp[0]->GetBasis(i);
214  }
215 
216  // Get shape type
217  auto shapeType = pCollExp[0]->GetStdExp()->DetShapeType();
218 
219  // Generate operator string and create operator.
220  std::string op_string = "BwdTrans";
221  op_string += MatrixFree::GetOpstring(shapeType, false);
223  op_string, basis, m_nElmtPad);
224 
225  m_oper = std::dynamic_pointer_cast<MatrixFree::BwdTrans>(oper);
226  ASSERTL0(m_oper, "Failed to cast pointer.");
227  }
228 };
229 
230 /// Factory initialisation for the BwdTrans_MatrixFree operators
231 OperatorKey BwdTrans_MatrixFree::m_typeArr[] = {
234  BwdTrans_MatrixFree::create, "BwdTrans_MatrixFree_Seg"),
237  BwdTrans_MatrixFree::create, "BwdTrans_MatrixFree_Quad"),
240  BwdTrans_MatrixFree::create, "BwdTrans_MatrixFree_Tri"),
243  BwdTrans_MatrixFree::create, "BwdTrans_MatrixFree_Hex"),
246  BwdTrans_MatrixFree::create, "BwdTrans_MatrixFree_Prism"),
249  BwdTrans_MatrixFree::create, "BwdTrans_MatrixFree_Tet"),
252  BwdTrans_MatrixFree::create, "BwdTrans_MatrixFree_Pyr")};
253 
254 /**
255  * @brief Backward transform operator using default StdRegions operator
256  */
257 class BwdTrans_IterPerExp final : public Operator
258 {
259 public:
261 
263  {
264  }
265 
267  Array<OneD, NekDouble> &output,
268  Array<OneD, NekDouble> &output1,
269  Array<OneD, NekDouble> &output2,
270  Array<OneD, NekDouble> &wsp) override
271  {
272  boost::ignore_unused(output1, output2, wsp);
273 
274  const int nCoeffs = m_stdExp->GetNcoeffs();
275  const int nPhys = m_stdExp->GetTotPoints();
277 
278  for (int i = 0; i < m_numElmt; ++i)
279  {
280  m_stdExp->BwdTrans(input + i * nCoeffs, tmp = output + i * nPhys);
281  }
282  }
283 
284  void operator()(int dir, const Array<OneD, const NekDouble> &input,
285  Array<OneD, NekDouble> &output,
286  Array<OneD, NekDouble> &wsp) override final
287  {
288  boost::ignore_unused(dir, input, output, wsp);
289  ASSERTL0(false, "Not valid for this operator.");
290  }
291 
292  virtual void CheckFactors(StdRegions::FactorMap factors,
293  int coll_phys_offset) override
294  {
295  boost::ignore_unused(factors, coll_phys_offset);
296  ASSERTL0(false, "Not valid for this operator.");
297  }
298 
299 private:
300  BwdTrans_IterPerExp(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
301  CoalescedGeomDataSharedPtr pGeomData,
302  StdRegions::FactorMap factors)
303  : Operator(pCollExp, pGeomData, factors)
304  {
305  }
306 };
307 
308 /// Factory initialisation for the BwdTrans_IterPerExp operators
309 OperatorKey BwdTrans_IterPerExp::m_typeArr[] = {
312  BwdTrans_IterPerExp::create, "BwdTrans_IterPerExp_Seg"),
315  BwdTrans_IterPerExp::create, "BwdTrans_IterPerExp_Tri"),
318  BwdTrans_IterPerExp::create, "BwdTrans_IterPerExp_NodalTri"),
321  BwdTrans_IterPerExp::create, "BwdTrans_IterPerExp_Quad"),
324  BwdTrans_IterPerExp::create, "BwdTrans_IterPerExp_Tet"),
327  BwdTrans_IterPerExp::create, "BwdTrans_IterPerExp_NodalTet"),
330  BwdTrans_IterPerExp::create, "BwdTrans_IterPerExp_Pyr"),
333  BwdTrans_IterPerExp::create, "BwdTrans_IterPerExp_Prism"),
336  BwdTrans_IterPerExp::create, "BwdTrans_IterPerExp_NodalPrism"),
339  BwdTrans_IterPerExp::create, "BwdTrans_IterPerExp_Hex"),
340 };
341 
342 /**
343  * @brief Backward transform operator using LocalRegions implementation.
344  */
345 class BwdTrans_NoCollection final : public Operator
346 {
347 public:
349 
351  {
352  }
353 
355  Array<OneD, NekDouble> &output,
356  Array<OneD, NekDouble> &output1,
357  Array<OneD, NekDouble> &output2,
358  Array<OneD, NekDouble> &wsp) override
359  {
360  boost::ignore_unused(output1, output2, wsp);
361 
362  const int nCoeffs = m_expList[0]->GetNcoeffs();
363  const int nPhys = m_expList[0]->GetTotPoints();
365 
366  for (int i = 0; i < m_numElmt; ++i)
367  {
368  m_expList[i]->BwdTrans(input + i * nCoeffs,
369  tmp = output + i * nPhys);
370  }
371  }
372 
373  void operator()(int dir, const Array<OneD, const NekDouble> &input,
374  Array<OneD, NekDouble> &output,
375  Array<OneD, NekDouble> &wsp) override final
376  {
377  boost::ignore_unused(dir, input, output, wsp);
378  ASSERTL0(false, "Not valid for this operator.");
379  }
380 
381  virtual void CheckFactors(StdRegions::FactorMap factors,
382  int coll_phys_offset) override
383  {
384  boost::ignore_unused(factors, coll_phys_offset);
385  ASSERTL0(false, "Not valid for this operator.");
386  }
387 
388 protected:
389  vector<StdRegions::StdExpansionSharedPtr> m_expList;
390 
391 private:
392  BwdTrans_NoCollection(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
393  CoalescedGeomDataSharedPtr pGeomData,
394  StdRegions::FactorMap factors)
395  : Operator(pCollExp, pGeomData, factors)
396  {
397  m_expList = pCollExp;
398  }
399 };
400 
401 /// Factory initialisation for the BwdTrans_NoCollection operators
402 OperatorKey BwdTrans_NoCollection::m_typeArr[] = {
405  BwdTrans_NoCollection::create, "BwdTrans_NoCollection_Seg"),
408  BwdTrans_NoCollection::create, "BwdTrans_NoCollection_Tri"),
411  BwdTrans_NoCollection::create, "BwdTrans_NoCollection_NodalTri"),
414  BwdTrans_NoCollection::create, "BwdTrans_NoCollection_Quad"),
417  BwdTrans_NoCollection::create, "BwdTrans_NoCollection_Tet"),
420  BwdTrans_NoCollection::create, "BwdTrans_NoCollection_NodalTet"),
423  BwdTrans_NoCollection::create, "BwdTrans_NoCollection_Pyr"),
426  BwdTrans_NoCollection::create, "BwdTrans_NoCollection_Prism"),
429  BwdTrans_NoCollection::create, "BwdTrans_NoCollection_NodalPrism"),
432  BwdTrans_NoCollection::create, "BwdTrans_NoCollection_Hex"),
433 };
434 
435 /**
436  * @brief Backward transform operator using sum-factorisation (Segment)
437  */
438 class BwdTrans_SumFac_Seg final : public Operator
439 {
440 public:
442 
444  {
445  }
446 
448  Array<OneD, NekDouble> &output,
449  Array<OneD, NekDouble> &output1,
450  Array<OneD, NekDouble> &output2,
451  Array<OneD, NekDouble> &wsp) override
452  {
453  boost::ignore_unused(output1, output2, wsp);
454  if (m_colldir0)
455  {
456  Vmath::Vcopy(m_numElmt * m_nmodes0, input.get(), 1, output.get(),
457  1);
458  }
459  else
460  {
461  // out = B0*in;
462  Blas::Dgemm('N', 'N', m_nquad0, m_numElmt, m_nmodes0, 1.0,
463  m_base0.get(), m_nquad0, &input[0], m_nmodes0, 0.0,
464  &output[0], m_nquad0);
465  }
466  }
467 
468  void operator()(int dir, const Array<OneD, const NekDouble> &input,
469  Array<OneD, NekDouble> &output,
470  Array<OneD, NekDouble> &wsp) override final
471  {
472  boost::ignore_unused(dir, input, output, wsp);
473  ASSERTL0(false, "Not valid for this operator.");
474  }
475 
476  virtual void CheckFactors(StdRegions::FactorMap factors,
477  int coll_phys_offset) override
478  {
479  boost::ignore_unused(factors, coll_phys_offset);
480  ASSERTL0(false, "Not valid for this operator.");
481  }
482 
483 protected:
484  const int m_nquad0;
485  const int m_nmodes0;
486  const bool m_colldir0;
488 
489 private:
490  BwdTrans_SumFac_Seg(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
491  CoalescedGeomDataSharedPtr pGeomData,
492  StdRegions::FactorMap factors)
493  : Operator(pCollExp, pGeomData, factors),
494  m_nquad0(m_stdExp->GetNumPoints(0)),
495  m_nmodes0(m_stdExp->GetBasisNumModes(0)),
496  m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
497  m_base0(m_stdExp->GetBasis(0)->GetBdata())
498  {
499  m_wspSize = 0;
500  }
501 };
502 
503 /// Factory initialisation for the BwdTrans_SumFac_Seg operator
504 OperatorKey BwdTrans_SumFac_Seg::m_type =
507  BwdTrans_SumFac_Seg::create, "BwdTrans_SumFac_Seg");
508 
509 /**
510  * @brief Backward transform operator using sum-factorisation (Quad)
511  */
512 class BwdTrans_SumFac_Quad final : public Operator
513 {
514 public:
516 
518  {
519  }
520 
522  Array<OneD, NekDouble> &output,
523  Array<OneD, NekDouble> &output1,
524  Array<OneD, NekDouble> &output2,
525  Array<OneD, NekDouble> &wsp) override
526  {
527  boost::ignore_unused(output1, output2);
528 
529  int i = 0;
530  if (m_colldir0 && m_colldir1)
531  {
532  Vmath::Vcopy(m_numElmt * m_nmodes0 * m_nmodes1, input.get(), 1,
533  output.get(), 1);
534  }
535  else if (m_colldir0)
536  {
538  m_stdExp->GetBasis(1)->GetBdata();
539 
540  for (i = 0; i < m_numElmt; ++i)
541  {
542  Blas::Dgemm('N', 'T', m_nquad0, m_nquad1, m_nmodes1, 1.0,
543  &input[i * m_nquad0 * m_nmodes1], m_nquad0,
544  base1.get(), m_nquad1, 0.0,
545  &output[i * m_nquad0 * m_nquad1], m_nquad0);
546  }
547  }
548  else if (m_colldir1)
549  {
550  Blas::Dgemm('N', 'N', m_nquad0, m_nmodes1 * m_numElmt, m_nmodes0,
551  1.0, m_base0.get(), m_nquad0, &input[0], m_nmodes0, 0.0,
552  &output[0], m_nquad0);
553  }
554  else
555  {
556  ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
557 
558  // Those two calls correpsond to the operation
559  // out = B0*in*Transpose(B1);
560  Blas::Dgemm('N', 'N', m_nquad0, m_nmodes1 * m_numElmt, m_nmodes0,
561  1.0, m_base0.get(), m_nquad0, &input[0], m_nmodes0, 0.0,
562  &wsp[0], m_nquad0);
563 
564  for (i = 0; i < m_numElmt; ++i)
565  {
566  Blas::Dgemm('N', 'T', m_nquad0, m_nquad1, m_nmodes1, 1.0,
567  &wsp[i * m_nquad0 * m_nmodes1], m_nquad0,
568  m_base1.get(), m_nquad1, 0.0,
569  &output[i * m_nquad0 * m_nquad1], m_nquad0);
570  }
571  }
572  }
573 
574  void operator()(int dir, const Array<OneD, const NekDouble> &input,
575  Array<OneD, NekDouble> &output,
576  Array<OneD, NekDouble> &wsp) override final
577  {
578  boost::ignore_unused(dir, input, output, wsp);
579  ASSERTL0(false, "Not valid for this operator.");
580  }
581 
582  virtual void CheckFactors(StdRegions::FactorMap factors,
583  int coll_phys_offset) override
584  {
585  boost::ignore_unused(factors, coll_phys_offset);
586  ASSERTL0(false, "Not valid for this operator.");
587  }
588 
589 protected:
590  const int m_nquad0;
591  const int m_nquad1;
592  const int m_nmodes0;
593  const int m_nmodes1;
594  const bool m_colldir0;
595  const bool m_colldir1;
598 
599 private:
600  BwdTrans_SumFac_Quad(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
601  CoalescedGeomDataSharedPtr pGeomData,
602  StdRegions::FactorMap factors)
603  : Operator(pCollExp, pGeomData, factors),
604  m_nquad0(m_stdExp->GetNumPoints(0)),
605  m_nquad1(m_stdExp->GetNumPoints(1)),
606  m_nmodes0(m_stdExp->GetBasisNumModes(0)),
607  m_nmodes1(m_stdExp->GetBasisNumModes(1)),
608  m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
609  m_colldir1(m_stdExp->GetBasis(1)->Collocation()),
610  m_base0(m_stdExp->GetBasis(0)->GetBdata()),
611  m_base1(m_stdExp->GetBasis(1)->GetBdata())
612  {
613  m_wspSize = m_nquad0 * m_nmodes1 * m_numElmt;
614  }
615 };
616 
617 /// Factory initialisation for the BwdTrans_SumFac_Quad operator
618 OperatorKey BwdTrans_SumFac_Quad::m_type =
621  BwdTrans_SumFac_Quad::create, "BwdTrans_SumFac_Quad");
622 
623 /**
624  * @brief Backward transform operator using sum-factorisation (Tri)
625  */
626 class BwdTrans_SumFac_Tri final : public Operator
627 {
628 public:
630 
632  {
633  }
634 
636  Array<OneD, NekDouble> &output,
637  Array<OneD, NekDouble> &output1,
638  Array<OneD, NekDouble> &output2,
639  Array<OneD, NekDouble> &wsp) override
640  {
641  boost::ignore_unused(output1, output2);
642 
643  ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
644 
645  int ncoeffs = m_stdExp->GetNcoeffs();
646  int i = 0;
647  int mode = 0;
648 
649  for (i = mode = 0; i < m_nmodes0; ++i)
650  {
651  Blas::Dgemm('N', 'N', m_nquad1, m_numElmt, m_nmodes1 - i, 1.0,
652  m_base1.get() + mode * m_nquad1, m_nquad1,
653  &input[0] + mode, ncoeffs, 0.0,
654  &wsp[i * m_nquad1 * m_numElmt], m_nquad1);
655  mode += m_nmodes1 - i;
656  }
657 
658  // fix for modified basis by splitting top vertex mode
659  if (m_sortTopVertex)
660  {
661  for (i = 0; i < m_numElmt; ++i)
662  {
663  Blas::Daxpy(m_nquad1, input[1 + i * ncoeffs],
664  m_base1.get() + m_nquad1, 1,
665  &wsp[m_nquad1 * m_numElmt] + i * m_nquad1, 1);
666  }
667  }
668 
669  Blas::Dgemm('N', 'T', m_nquad0, m_nquad1 * m_numElmt, m_nmodes0, 1.0,
670  m_base0.get(), m_nquad0, &wsp[0], m_nquad1 * m_numElmt, 0.0,
671  &output[0], m_nquad0);
672  }
673 
674  void operator()(int dir, const Array<OneD, const NekDouble> &input,
675  Array<OneD, NekDouble> &output,
676  Array<OneD, NekDouble> &wsp) override final
677  {
678  boost::ignore_unused(dir, input, output, wsp);
679  ASSERTL0(false, "Not valid for this operator.");
680  }
681 
682  virtual void CheckFactors(StdRegions::FactorMap factors,
683  int coll_phys_offset) override
684  {
685  boost::ignore_unused(factors, coll_phys_offset);
686  ASSERTL0(false, "Not valid for this operator.");
687  }
688 
689 protected:
690  const int m_nquad0;
691  const int m_nquad1;
692  const int m_nmodes0;
693  const int m_nmodes1;
697 
698 private:
699  BwdTrans_SumFac_Tri(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
700  CoalescedGeomDataSharedPtr pGeomData,
701  StdRegions::FactorMap factors)
702  : Operator(pCollExp, pGeomData, factors),
703  m_nquad0(m_stdExp->GetNumPoints(0)),
704  m_nquad1(m_stdExp->GetNumPoints(1)),
705  m_nmodes0(m_stdExp->GetBasisNumModes(0)),
706  m_nmodes1(m_stdExp->GetBasisNumModes(1)),
707  m_base0(m_stdExp->GetBasis(0)->GetBdata()),
708  m_base1(m_stdExp->GetBasis(1)->GetBdata())
709  {
710  m_wspSize = m_nquad0 * m_nmodes1 * m_numElmt;
711  if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
712  {
713  m_sortTopVertex = true;
714  }
715  else
716  {
717  m_sortTopVertex = false;
718  }
719  }
720 };
721 
722 /// Factory initialisation for the BwdTrans_SumFac_Tri operator
723 OperatorKey BwdTrans_SumFac_Tri::m_type =
726  BwdTrans_SumFac_Tri::create, "BwdTrans_SumFac_Tri");
727 
728 /// Backward transform operator using sum-factorisation (Hex)
729 class BwdTrans_SumFac_Hex final : public Operator
730 {
731 public:
733 
735  {
736  }
737 
739  Array<OneD, NekDouble> &output,
740  Array<OneD, NekDouble> &output1,
741  Array<OneD, NekDouble> &output2,
742  Array<OneD, NekDouble> &wsp) override
743  {
744  boost::ignore_unused(output1, output2);
745 
746  if (m_colldir0 && m_colldir1 && m_colldir2)
747  {
748  Vmath::Vcopy(m_numElmt * m_nmodes0 * m_nmodes1 * m_nmodes2,
749  input.get(), 1, output.get(), 1);
750  }
751  else
752  {
753  ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
754 
755  // Assign second half of workspace for 2nd DGEMM operation.
756  int totmodes = m_nmodes0 * m_nmodes1 * m_nmodes2;
757 
759  wsp + m_nmodes0 * m_nmodes1 * m_nquad2 * m_numElmt;
760 
761  // loop over elements and do bwd trans wrt c
762  for (int n = 0; n < m_numElmt; ++n)
763  {
764  Blas::Dgemm('N', 'T', m_nquad2, m_nmodes0 * m_nmodes1,
765  m_nmodes2, 1.0, m_base2.get(), m_nquad2,
766  &input[n * totmodes], m_nmodes0 * m_nmodes1, 0.0,
767  &wsp[n * m_nquad2], m_nquad2 * m_numElmt);
768  }
769 
770  // trans wrt b
771  Blas::Dgemm('N', 'T', m_nquad1, m_nquad2 * m_numElmt * m_nmodes0,
772  m_nmodes1, 1.0, m_base1.get(), m_nquad1, wsp.get(),
773  m_nquad2 * m_numElmt * m_nmodes0, 0.0, wsp2.get(),
774  m_nquad1);
775 
776  // trans wrt a
777  Blas::Dgemm('N', 'T', m_nquad0, m_nquad1 * m_nquad2 * m_numElmt,
778  m_nmodes0, 1.0, m_base0.get(), m_nquad0, wsp2.get(),
779  m_nquad1 * m_nquad2 * m_numElmt, 0.0, output.get(),
780  m_nquad0);
781  }
782  }
783 
784  void operator()(int dir, const Array<OneD, const NekDouble> &input,
785  Array<OneD, NekDouble> &output,
786  Array<OneD, NekDouble> &wsp) override final
787  {
788  boost::ignore_unused(dir, input, output, wsp);
789  ASSERTL0(false, "Not valid for this operator.");
790  }
791 
792  virtual void CheckFactors(StdRegions::FactorMap factors,
793  int coll_phys_offset) override
794  {
795  boost::ignore_unused(factors, coll_phys_offset);
796  ASSERTL0(false, "Not valid for this operator.");
797  }
798 
799 protected:
800  const int m_nquad0;
801  const int m_nquad1;
802  const int m_nquad2;
803  const int m_nmodes0;
804  const int m_nmodes1;
805  const int m_nmodes2;
809  const bool m_colldir0;
810  const bool m_colldir1;
811  const bool m_colldir2;
812 
813 private:
814  BwdTrans_SumFac_Hex(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
815  CoalescedGeomDataSharedPtr pGeomData,
816  StdRegions::FactorMap factors)
817  : Operator(pCollExp, pGeomData, factors),
818  m_nquad0(pCollExp[0]->GetNumPoints(0)),
819  m_nquad1(pCollExp[0]->GetNumPoints(1)),
820  m_nquad2(pCollExp[0]->GetNumPoints(2)),
821  m_nmodes0(pCollExp[0]->GetBasisNumModes(0)),
822  m_nmodes1(pCollExp[0]->GetBasisNumModes(1)),
823  m_nmodes2(pCollExp[0]->GetBasisNumModes(2)),
824  m_base0(pCollExp[0]->GetBasis(0)->GetBdata()),
825  m_base1(pCollExp[0]->GetBasis(1)->GetBdata()),
826  m_base2(pCollExp[0]->GetBasis(2)->GetBdata()),
827  m_colldir0(pCollExp[0]->GetBasis(0)->Collocation()),
828  m_colldir1(pCollExp[0]->GetBasis(1)->Collocation()),
829  m_colldir2(pCollExp[0]->GetBasis(2)->Collocation())
830  {
831  m_wspSize = m_numElmt * m_nmodes0 *
832  (m_nmodes1 * m_nquad2 + m_nquad1 * m_nquad2);
833  }
834 };
835 
836 /// Factory initialisation for the BwdTrans_SumFac_Hex operator
837 OperatorKey BwdTrans_SumFac_Hex::m_type =
840  BwdTrans_SumFac_Hex::create, "BwdTrans_SumFac_Hex");
841 
842 /**
843  * @brief Backward transform operator using sum-factorisation (Tet)
844  */
845 class BwdTrans_SumFac_Tet final : public Operator
846 {
847 public:
849 
851  {
852  }
853 
855  Array<OneD, NekDouble> &output,
856  Array<OneD, NekDouble> &output1,
857  Array<OneD, NekDouble> &output2,
858  Array<OneD, NekDouble> &wsp) override final
859  {
860  boost::ignore_unused(output1, output2);
861 
862  ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
863 
864  Array<OneD, NekDouble> tmp = wsp;
866  tmp + m_numElmt * m_nquad2 * m_nmodes0 *
867  (2 * m_nmodes1 - m_nmodes0 + 1) / 2;
868 
869  int mode = 0;
870  int mode1 = 0;
871  int cnt = 0;
872  int ncoeffs = m_stdExp->GetNcoeffs();
873 
874  // Perform summation over '2' direction
875  for (int i = 0; i < m_nmodes0; ++i)
876  {
877  for (int j = 0; j < m_nmodes1 - i; ++j, ++cnt)
878  {
879  Blas::Dgemm('N', 'N', m_nquad2, m_numElmt, m_nmodes2 - i - j,
880  1.0, m_base2.get() + mode * m_nquad2, m_nquad2,
881  input.get() + mode1, ncoeffs, 0.0,
882  tmp.get() + cnt * m_nquad2 * m_numElmt, m_nquad2);
883  mode += m_nmodes2 - i - j;
884  mode1 += m_nmodes2 - i - j;
885  }
886 
887  // increment mode in case m_nmodes1!=m_nmodes2
888  mode += (m_nmodes2 - m_nmodes1) * (m_nmodes2 - m_nmodes1 + 1) / 2;
889  }
890 
891  // vertex mode - currently (1+c)/2 x (1-b)/2 x (1-a)/2
892  // component is evaluated
893  if (m_sortTopEdge)
894  {
895  for (int i = 0; i < m_numElmt; ++i)
896  {
897  // top singular vertex
898  // (1+c)/2 x (1+b)/2 x (1-a)/2 component
899  Blas::Daxpy(m_nquad2, input[1 + i * ncoeffs],
900  m_base2.get() + m_nquad2, 1,
901  &tmp[m_nquad2 * m_numElmt] + i * m_nquad2, 1);
902 
903  // top singular vertex
904  // (1+c)/2 x (1-b)/2 x (1+a)/2 component
905  Blas::Daxpy(
906  m_nquad2, input[1 + i * ncoeffs], m_base2.get() + m_nquad2,
907  1, &tmp[m_nmodes1 * m_nquad2 * m_numElmt] + i * m_nquad2,
908  1);
909  }
910  }
911 
912  // Perform summation over '1' direction
913  mode = 0;
914  for (int i = 0; i < m_nmodes0; ++i)
915  {
916  Blas::Dgemm('N', 'T', m_nquad1, m_nquad2 * m_numElmt, m_nmodes1 - i,
917  1.0, m_base1.get() + mode * m_nquad1, m_nquad1,
918  tmp.get() + mode * m_nquad2 * m_numElmt,
919  m_nquad2 * m_numElmt, 0.0,
920  tmp1.get() + i * m_nquad1 * m_nquad2 * m_numElmt,
921  m_nquad1);
922  mode += m_nmodes1 - i;
923  }
924 
925  // fix for modified basis by adding additional split of
926  // top and base singular vertex modes as well as singular
927  // edge
928  if (m_sortTopEdge)
929  {
930  // this could probably be a dgemv or higher if we
931  // made a specialised m_base1[m_nuqad1] array
932  // containing multiply copies
933  for (int i = 0; i < m_numElmt; ++i)
934  {
935  // sort out singular vertices and singular
936  // edge components with (1+b)/2 (1+a)/2 form
937  for (int j = 0; j < m_nquad2; ++j)
938  {
939  Blas::Daxpy(m_nquad1,
940  tmp[m_nquad2 * m_numElmt + i * m_nquad2 + j],
941  m_base1.get() + m_nquad1, 1,
942  &tmp1[m_nquad1 * m_nquad2 * m_numElmt] +
943  i * m_nquad1 * m_nquad2 + j * m_nquad1,
944  1);
945  }
946  }
947  }
948 
949  // Perform summation over '0' direction
950  Blas::Dgemm('N', 'T', m_nquad0, m_nquad1 * m_nquad2 * m_numElmt,
951  m_nmodes0, 1.0, m_base0.get(), m_nquad0, tmp1.get(),
952  m_nquad1 * m_nquad2 * m_numElmt, 0.0, output.get(),
953  m_nquad0);
954  }
955 
956  void operator()(int dir, const Array<OneD, const NekDouble> &input,
957  Array<OneD, NekDouble> &output,
958  Array<OneD, NekDouble> &wsp) override final
959  {
960  boost::ignore_unused(dir, input, output, wsp);
961  ASSERTL0(false, "Not valid for this operator.");
962  }
963 
964  virtual void CheckFactors(StdRegions::FactorMap factors,
965  int coll_phys_offset) override
966  {
967  boost::ignore_unused(factors, coll_phys_offset);
968  ASSERTL0(false, "Not valid for this operator.");
969  }
970 
971 protected:
972  const int m_nquad0;
973  const int m_nquad1;
974  const int m_nquad2;
975  const int m_nmodes0;
976  const int m_nmodes1;
977  const int m_nmodes2;
982 
983 private:
984  BwdTrans_SumFac_Tet(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
985  CoalescedGeomDataSharedPtr pGeomData,
986  StdRegions::FactorMap factors)
987  : Operator(pCollExp, pGeomData, factors),
988  m_nquad0(m_stdExp->GetNumPoints(0)),
989  m_nquad1(m_stdExp->GetNumPoints(1)),
990  m_nquad2(m_stdExp->GetNumPoints(2)),
991  m_nmodes0(m_stdExp->GetBasisNumModes(0)),
992  m_nmodes1(m_stdExp->GetBasisNumModes(1)),
993  m_nmodes2(m_stdExp->GetBasisNumModes(2)),
994  m_base0(m_stdExp->GetBasis(0)->GetBdata()),
995  m_base1(m_stdExp->GetBasis(1)->GetBdata()),
996  m_base2(m_stdExp->GetBasis(2)->GetBdata())
997  {
998  m_wspSize = m_numElmt * (m_nquad2 * m_nmodes0 *
999  (2 * m_nmodes1 - m_nmodes0 + 1) / 2 +
1000  m_nquad2 * m_nquad1 * m_nmodes0);
1001 
1002  if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
1003  {
1004  m_sortTopEdge = true;
1005  }
1006  else
1007  {
1008  m_sortTopEdge = false;
1009  }
1010  }
1011 };
1012 
1013 /// Factory initialisation for the BwdTrans_SumFac_Tet operator
1014 OperatorKey BwdTrans_SumFac_Tet::m_type =
1017  BwdTrans_SumFac_Tet::create, "BwdTrans_SumFac_Tet");
1018 
1019 /**
1020  * @brief Backward transform operator using sum-factorisation (Prism)
1021  */
1022 class BwdTrans_SumFac_Prism final : public Operator
1023 {
1024 public:
1026 
1028  {
1029  }
1030 
1032  Array<OneD, NekDouble> &output,
1033  Array<OneD, NekDouble> &output1,
1034  Array<OneD, NekDouble> &output2,
1035  Array<OneD, NekDouble> &wsp) override final
1036  {
1037  boost::ignore_unused(output1, output2);
1038 
1039  ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
1040 
1041  // Assign second half of workspace for 2nd DGEMM operation.
1042  int totmodes = m_stdExp->GetNcoeffs();
1043 
1044  Array<OneD, NekDouble> wsp2 =
1045  wsp + m_nmodes0 * m_nmodes1 * m_nquad2 * m_numElmt;
1046 
1047  Vmath::Zero(m_nmodes0 * m_nmodes1 * m_nquad2 * m_numElmt, wsp, 1);
1048  int i = 0;
1049  int j = 0;
1050  int mode = 0;
1051  int mode1 = 0;
1052  int cnt = 0;
1053  for (i = mode = mode1 = 0; i < m_nmodes0; ++i)
1054  {
1055  cnt = i * m_nquad2 * m_numElmt;
1056  for (j = 0; j < m_nmodes1; ++j)
1057  {
1058  Blas::Dgemm('N', 'N', m_nquad2, m_numElmt, m_nmodes2 - i, 1.0,
1059  m_base2.get() + mode * m_nquad2, m_nquad2,
1060  input.get() + mode1, totmodes, 0.0,
1061  &wsp[j * m_nquad2 * m_numElmt * m_nmodes0 + cnt],
1062  m_nquad2);
1063  mode1 += m_nmodes2 - i;
1064  }
1065  mode += m_nmodes2 - i;
1066  }
1067 
1068  // fix for modified basis by splitting top vertex mode
1069  if (m_sortTopVertex)
1070  {
1071  for (j = 0; j < m_nmodes1; ++j)
1072  {
1073  for (i = 0; i < m_numElmt; ++i)
1074  {
1075  Blas::Daxpy(m_nquad2,
1076  input[1 + i * totmodes + j * m_nmodes2],
1077  m_base2.get() + m_nquad2, 1,
1078  &wsp[j * m_nquad2 * m_numElmt * m_nmodes0 +
1079  m_nquad2 * m_numElmt] +
1080  i * m_nquad2,
1081  1);
1082  }
1083  }
1084  // Believe this could be made into a m_nmodes1
1085  // dgemv if we made an array of m_numElmt copies
1086  // of m_base2[m_quad2] (which are of size
1087  // m_nquad2.
1088  }
1089 
1090  // Perform summation over '1' direction
1091  Blas::Dgemm('N', 'T', m_nquad1, m_nquad2 * m_numElmt * m_nmodes0,
1092  m_nmodes1, 1.0, m_base1.get(), m_nquad1, wsp.get(),
1093  m_nquad2 * m_numElmt * m_nmodes0, 0.0, wsp2.get(),
1094  m_nquad1);
1095 
1096  // Perform summation over '0' direction
1097  Blas::Dgemm('N', 'T', m_nquad0, m_nquad1 * m_nquad2 * m_numElmt,
1098  m_nmodes0, 1.0, m_base0.get(), m_nquad0, wsp2.get(),
1099  m_nquad1 * m_nquad2 * m_numElmt, 0.0, output.get(),
1100  m_nquad0);
1101  }
1102 
1103  void operator()(int dir, const Array<OneD, const NekDouble> &input,
1104  Array<OneD, NekDouble> &output,
1105  Array<OneD, NekDouble> &wsp) override final
1106  {
1107  boost::ignore_unused(dir, input, output, wsp);
1108  ASSERTL0(false, "Not valid for this operator.");
1109  }
1110 
1111  virtual void CheckFactors(StdRegions::FactorMap factors,
1112  int coll_phys_offset) override
1113  {
1114  boost::ignore_unused(factors, coll_phys_offset);
1115  ASSERTL0(false, "Not valid for this operator.");
1116  }
1117 
1118 protected:
1119  const int m_nquad0;
1120  const int m_nquad1;
1121  const int m_nquad2;
1122  const int m_nmodes0;
1123  const int m_nmodes1;
1124  const int m_nmodes2;
1129 
1130 private:
1131  BwdTrans_SumFac_Prism(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
1132  CoalescedGeomDataSharedPtr pGeomData,
1133  StdRegions::FactorMap factors)
1134  : Operator(pCollExp, pGeomData, factors),
1135  m_nquad0(m_stdExp->GetNumPoints(0)),
1136  m_nquad1(m_stdExp->GetNumPoints(1)),
1137  m_nquad2(m_stdExp->GetNumPoints(2)),
1138  m_nmodes0(m_stdExp->GetBasisNumModes(0)),
1139  m_nmodes1(m_stdExp->GetBasisNumModes(1)),
1140  m_nmodes2(m_stdExp->GetBasisNumModes(2)),
1141  m_base0(m_stdExp->GetBasis(0)->GetBdata()),
1142  m_base1(m_stdExp->GetBasis(1)->GetBdata()),
1143  m_base2(m_stdExp->GetBasis(2)->GetBdata())
1144  {
1145  m_wspSize = m_numElmt * m_nmodes0 *
1146  (m_nmodes1 * m_nquad2 + m_nquad1 * m_nquad2);
1147 
1148  if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
1149  {
1150  m_sortTopVertex = true;
1151  }
1152  else
1153  {
1154  m_sortTopVertex = false;
1155  }
1156  }
1157 };
1158 
1159 /// Factory initialisation for the BwdTrans_SumFac_Prism operator
1160 OperatorKey BwdTrans_SumFac_Prism::m_type =
1162  OperatorKey(ePrism, eBwdTrans, eSumFac, false),
1163  BwdTrans_SumFac_Prism::create, "BwdTrans_SumFac_Prism");
1164 
1165 /**
1166  * @brief Backward transform operator using sum-factorisation (Pyr)
1167  */
1168 class BwdTrans_SumFac_Pyr final : public Operator
1169 {
1170 public:
1172 
1174  {
1175  }
1176 
1178  Array<OneD, NekDouble> &output,
1179  Array<OneD, NekDouble> &output1,
1180  Array<OneD, NekDouble> &output2,
1181  Array<OneD, NekDouble> &wsp) override final
1182  {
1183  boost::ignore_unused(output1, output2);
1184 
1185  ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
1186 
1187  // Assign second half of workspace for 2nd DGEMM operation.
1188  int totmodes = m_stdExp->GetNcoeffs();
1189 
1190  Array<OneD, NekDouble> wsp2 =
1191  wsp + m_nmodes0 * m_nmodes1 * m_nquad2 * m_numElmt;
1192 
1193  Vmath::Zero(m_nmodes0 * m_nmodes1 * m_nquad2 * m_numElmt, wsp, 1);
1194  int i = 0;
1195  int j = 0;
1196  int mode = 0;
1197  int mode1 = 0;
1198  int cnt = 0;
1199  for (i = 0; i < m_nmodes0; ++i)
1200  {
1201  for (j = 0; j < m_nmodes1; ++j, ++cnt)
1202  {
1203  int ijmax = max(i, j);
1204  Blas::Dgemm('N', 'N', m_nquad2, m_numElmt, m_nmodes2 - ijmax,
1205  1.0, m_base2.get() + mode * m_nquad2, m_nquad2,
1206  input.get() + mode1, totmodes, 0.0,
1207  wsp.get() + cnt * m_nquad2 * m_numElmt, m_nquad2);
1208  mode += m_nmodes2 - ijmax;
1209  mode1 += m_nmodes2 - ijmax;
1210  }
1211 
1212  // increment mode in case order1!=order2
1213  for (j = m_nmodes1; j < m_nmodes2 - i; ++j)
1214  {
1215  int ijmax = max(i, j);
1216  mode += m_nmodes2 - ijmax;
1217  }
1218  }
1219 
1220  // vertex mode - currently (1+c)/2 x (1-b)/2 x (1-a)/2
1221  // component is evaluated
1222  if (m_sortTopVertex)
1223  {
1224  for (i = 0; i < m_numElmt; ++i)
1225  {
1226  // top singular vertex
1227  // (1+c)/2 x (1+b)/2 x (1-a)/2 component
1228  Blas::Daxpy(m_nquad2, input[1 + i * totmodes],
1229  m_base2.get() + m_nquad2, 1,
1230  &wsp[m_nquad2 * m_numElmt] + i * m_nquad2, 1);
1231 
1232  // top singular vertex
1233  // (1+c)/2 x (1-b)/2 x (1+a)/2 component
1234  Blas::Daxpy(
1235  m_nquad2, input[1 + i * totmodes], m_base2.get() + m_nquad2,
1236  1, &wsp[m_nmodes1 * m_nquad2 * m_numElmt] + i * m_nquad2,
1237  1);
1238 
1239  // top singular vertex
1240  // (1+c)/2 x (1+b)/2 x (1+a)/2 component
1241  Blas::Daxpy(m_nquad2, input[1 + i * totmodes],
1242  m_base2.get() + m_nquad2, 1,
1243  &wsp[(m_nmodes1 + 1) * m_nquad2 * m_numElmt] +
1244  i * m_nquad2,
1245  1);
1246  }
1247  }
1248 
1249  // Perform summation over '1' direction
1250  mode = 0;
1251  for (i = 0; i < m_nmodes0; ++i)
1252  {
1253  Blas::Dgemm('N', 'T', m_nquad1, m_nquad2 * m_numElmt, m_nmodes1,
1254  1.0, m_base1.get(), m_nquad1,
1255  wsp.get() + mode * m_nquad2 * m_numElmt,
1256  m_nquad2 * m_numElmt, 0.0,
1257  wsp2.get() + i * m_nquad1 * m_nquad2 * m_numElmt,
1258  m_nquad1);
1259  mode += m_nmodes1;
1260  }
1261 
1262  // Perform summation over '0' direction
1263  Blas::Dgemm('N', 'T', m_nquad0, m_nquad1 * m_nquad2 * m_numElmt,
1264  m_nmodes0, 1.0, m_base0.get(), m_nquad0, wsp2.get(),
1265  m_nquad1 * m_nquad2 * m_numElmt, 0.0, output.get(),
1266  m_nquad0);
1267  }
1268 
1269  void operator()(int dir, const Array<OneD, const NekDouble> &input,
1270  Array<OneD, NekDouble> &output,
1271  Array<OneD, NekDouble> &wsp) override final
1272  {
1273  boost::ignore_unused(dir, input, output, wsp);
1274  ASSERTL0(false, "Not valid for this operator.");
1275  }
1276 
1277  virtual void CheckFactors(StdRegions::FactorMap factors,
1278  int coll_phys_offset) override
1279  {
1280  boost::ignore_unused(factors, coll_phys_offset);
1281  ASSERTL0(false, "Not valid for this operator.");
1282  }
1283 
1284 protected:
1285  const int m_nquad0;
1286  const int m_nquad1;
1287  const int m_nquad2;
1288  const int m_nmodes0;
1289  const int m_nmodes1;
1290  const int m_nmodes2;
1295 
1296 private:
1297  BwdTrans_SumFac_Pyr(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
1298  CoalescedGeomDataSharedPtr pGeomData,
1299  StdRegions::FactorMap factors)
1300  : Operator(pCollExp, pGeomData, factors),
1301  m_nquad0(m_stdExp->GetNumPoints(0)),
1302  m_nquad1(m_stdExp->GetNumPoints(1)),
1303  m_nquad2(m_stdExp->GetNumPoints(2)),
1304  m_nmodes0(m_stdExp->GetBasisNumModes(0)),
1305  m_nmodes1(m_stdExp->GetBasisNumModes(1)),
1306  m_nmodes2(m_stdExp->GetBasisNumModes(2)),
1307  m_base0(m_stdExp->GetBasis(0)->GetBdata()),
1308  m_base1(m_stdExp->GetBasis(1)->GetBdata()),
1309  m_base2(m_stdExp->GetBasis(2)->GetBdata())
1310  {
1311  m_wspSize = m_numElmt * m_nmodes0 * m_nquad2 * (m_nmodes1 + m_nquad1);
1312 
1313  if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
1314  {
1315  m_sortTopVertex = true;
1316  }
1317  else
1318  {
1319  m_sortTopVertex = false;
1320  }
1321  }
1322 };
1323 
1324 /// Factory initialisation for the BwdTrans_SumFac_Pyr operator
1325 OperatorKey BwdTrans_SumFac_Pyr::m_type =
1328  BwdTrans_SumFac_Pyr::create, "BwdTrans_SumFac_Pyr");
1329 
1330 } // namespace Collections
1331 
1332 } // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
#define OPERATOR_CREATE(cname)
Definition: Operator.h:45
Backward transform operator using default StdRegions operator.
Definition: BwdTrans.cpp:258
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) override final
Definition: BwdTrans.cpp:284
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Definition: BwdTrans.cpp:292
BwdTrans_IterPerExp(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Definition: BwdTrans.cpp:300
void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp) override
Perform operation.
Definition: BwdTrans.cpp:266
Backward transform operator using matrix free operators.
Definition: BwdTrans.cpp:150
std::shared_ptr< MatrixFree::BwdTrans > m_oper
Definition: BwdTrans.cpp:198
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Definition: BwdTrans.cpp:190
void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output0, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp) override final
Perform operation.
Definition: BwdTrans.cpp:158
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) override final
Definition: BwdTrans.cpp:181
BwdTrans_MatrixFree(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Definition: BwdTrans.cpp:200
Backward transform operator using LocalRegions implementation.
Definition: BwdTrans.cpp:346
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) override final
Definition: BwdTrans.cpp:373
BwdTrans_NoCollection(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Definition: BwdTrans.cpp:392
void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp) override
Perform operation.
Definition: BwdTrans.cpp:354
vector< StdRegions::StdExpansionSharedPtr > m_expList
Definition: BwdTrans.cpp:389
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Definition: BwdTrans.cpp:381
Backward transform operator using standard matrix approach.
Definition: BwdTrans.cpp:60
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Definition: BwdTrans.cpp:88
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) override final
Definition: BwdTrans.cpp:80
BwdTrans_StdMat(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Definition: BwdTrans.cpp:99
void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp) override
Perform operation.
Definition: BwdTrans.cpp:67
Backward transform operator using sum-factorisation (Hex)
Definition: BwdTrans.cpp:730
void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp) override
Perform operation.
Definition: BwdTrans.cpp:738
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Definition: BwdTrans.cpp:792
Array< OneD, const NekDouble > m_base1
Definition: BwdTrans.cpp:807
Array< OneD, const NekDouble > m_base2
Definition: BwdTrans.cpp:808
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) override final
Definition: BwdTrans.cpp:784
Array< OneD, const NekDouble > m_base0
Definition: BwdTrans.cpp:806
BwdTrans_SumFac_Hex(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Definition: BwdTrans.cpp:814
Backward transform operator using sum-factorisation (Prism)
Definition: BwdTrans.cpp:1023
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Definition: BwdTrans.cpp:1111
BwdTrans_SumFac_Prism(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Definition: BwdTrans.cpp:1131
void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp) override final
Perform operation.
Definition: BwdTrans.cpp:1031
Array< OneD, const NekDouble > m_base0
Definition: BwdTrans.cpp:1125
Array< OneD, const NekDouble > m_base1
Definition: BwdTrans.cpp:1126
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) override final
Definition: BwdTrans.cpp:1103
Array< OneD, const NekDouble > m_base2
Definition: BwdTrans.cpp:1127
Backward transform operator using sum-factorisation (Pyr)
Definition: BwdTrans.cpp:1169
Array< OneD, const NekDouble > m_base2
Definition: BwdTrans.cpp:1293
void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp) override final
Perform operation.
Definition: BwdTrans.cpp:1177
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Definition: BwdTrans.cpp:1277
BwdTrans_SumFac_Pyr(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Definition: BwdTrans.cpp:1297
Array< OneD, const NekDouble > m_base1
Definition: BwdTrans.cpp:1292
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) override final
Definition: BwdTrans.cpp:1269
Array< OneD, const NekDouble > m_base0
Definition: BwdTrans.cpp:1291
Backward transform operator using sum-factorisation (Quad)
Definition: BwdTrans.cpp:513
Array< OneD, const NekDouble > m_base1
Definition: BwdTrans.cpp:597
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Definition: BwdTrans.cpp:582
Array< OneD, const NekDouble > m_base0
Definition: BwdTrans.cpp:596
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) override final
Definition: BwdTrans.cpp:574
void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp) override
Perform operation.
Definition: BwdTrans.cpp:521
BwdTrans_SumFac_Quad(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Definition: BwdTrans.cpp:600
Backward transform operator using sum-factorisation (Segment)
Definition: BwdTrans.cpp:439
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Definition: BwdTrans.cpp:476
BwdTrans_SumFac_Seg(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Definition: BwdTrans.cpp:490
Array< OneD, const NekDouble > m_base0
Definition: BwdTrans.cpp:487
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) override final
Definition: BwdTrans.cpp:468
void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp) override
Perform operation.
Definition: BwdTrans.cpp:447
Backward transform operator using sum-factorisation (Tet)
Definition: BwdTrans.cpp:846
BwdTrans_SumFac_Tet(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Definition: BwdTrans.cpp:984
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Definition: BwdTrans.cpp:964
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) override final
Definition: BwdTrans.cpp:956
Array< OneD, const NekDouble > m_base1
Definition: BwdTrans.cpp:979
Array< OneD, const NekDouble > m_base0
Definition: BwdTrans.cpp:978
Array< OneD, const NekDouble > m_base2
Definition: BwdTrans.cpp:980
void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp) override final
Perform operation.
Definition: BwdTrans.cpp:854
Backward transform operator using sum-factorisation (Tri)
Definition: BwdTrans.cpp:627
BwdTrans_SumFac_Tri(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Definition: BwdTrans.cpp:699
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Definition: BwdTrans.cpp:682
void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp) override
Perform operation.
Definition: BwdTrans.cpp:635
Array< OneD, const NekDouble > m_base0
Definition: BwdTrans.cpp:694
Array< OneD, const NekDouble > m_base1
Definition: BwdTrans.cpp:695
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) override final
Definition: BwdTrans.cpp:674
Base class for operators on a collection of elements.
Definition: Operator.h:119
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
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
static void Daxpy(const int &n, const double &alpha, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: y = alpha x plus y.
Definition: Blas.hpp:154
std::tuple< LibUtilities::ShapeType, OperatorType, ImplementationType, ExpansionIsNodal > OperatorKey
Key for describing an Operator.
Definition: Operator.h:177
std::shared_ptr< CoalescedGeomData > CoalescedGeomDataSharedPtr
OperatorFactory & GetOperatorFactory()
Returns the singleton Operator factory object.
Definition: Operator.cpp:117
@ eModified_A
Principle Modified Functions .
Definition: BasisType.h:50
ConstFactorMap FactorMap
Definition: StdRegions.hpp:403
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:75
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:492
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1255