Nektar++
IProductWRTBase.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: IProductWRTBase.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: IProductWRTBase operator implementations
32//
33///////////////////////////////////////////////////////////////////////////////
34
39#include <MatrixFreeOps/Operator.hpp>
40
41using namespace std;
42
43namespace Nektar::Collections
44{
45
53
54/**
55 * @brief Inner product help class to calculate the size of the collection
56 * that is given as an input and as an output to the IProductWRTBase Operator.
57 * The size evaluation takes into account the conversion from the physical space
58 * to the coefficient space.
59 */
60class IProductWRTBase_Helper : virtual public Operator
61{
62protected:
64 {
65 // expect input to be number of elements by the number of quad points
66 m_inputSize = m_numElmt * m_stdExp->GetTotPoints();
67 // expect input to be number of elements by the number of coefficients
68 m_outputSize = m_numElmt * m_stdExp->GetNcoeffs();
69 }
70};
71
72/**
73 * @brief Inner product operator using standard matrix approach
74 */
75class IProductWRTBase_StdMat final : virtual public Operator,
76 virtual public IProductWRTBase_Helper
77{
78public:
80
81 ~IProductWRTBase_StdMat() final = default;
82
83 void operator()(const Array<OneD, const NekDouble> &input,
84 Array<OneD, NekDouble> &output,
85 [[maybe_unused]] Array<OneD, NekDouble> &output1,
86 [[maybe_unused]] Array<OneD, NekDouble> &output2,
87 Array<OneD, NekDouble> &wsp) final
88 {
89 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
90
91 if (m_isDeformed)
92 {
93 Vmath::Vmul(m_jac.size(), m_jac, 1, input, 1, wsp, 1);
94 }
95 else
96 {
98 for (int e = 0; e < m_numElmt; ++e)
99 {
100 Vmath::Smul(m_nqe, m_jac[e], input + e * m_nqe, 1,
101 tmp = wsp + e * m_nqe, 1);
102 }
103 }
104
105 Blas::Dgemm('N', 'N', m_mat->GetRows(), m_numElmt, m_mat->GetColumns(),
106 1.0, m_mat->GetRawPtr(), m_mat->GetRows(), wsp.get(),
107 m_stdExp->GetTotPoints(), 0.0, output.get(),
108 m_stdExp->GetNcoeffs());
109 }
110
111 void operator()([[maybe_unused]] int dir,
112 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
113 [[maybe_unused]] Array<OneD, NekDouble> &output,
114 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
115 {
116 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
117 }
118
119protected:
122
123private:
124 IProductWRTBase_StdMat(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
127 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper()
128 {
129 m_jac = pGeomData->GetJac(pCollExp);
131 m_stdExp->DetShapeType(), *m_stdExp);
132 m_mat = m_stdExp->GetStdMatrix(key);
133 m_nqe = m_stdExp->GetTotPoints();
135 }
136};
137
138/// Factory initialisation for the IProductWRTBase_StdMat operators
139OperatorKey IProductWRTBase_StdMat::m_typeArr[] = {
142 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Seg"),
145 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Tri"),
148 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_NodalTri"),
151 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Quad"),
154 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Tet"),
157 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_NodalTet"),
160 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Pyr"),
163 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Prism"),
166 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_NodalPrism"),
169 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Hex"),
172 IProductWRTBase_StdMat::create, "IProductWRTBase_SumFac_Pyr")};
173
174/**
175 * @brief Inner product operator using operator using matrix free operators.
176 */
177class IProductWRTBase_MatrixFree final : virtual public Operator,
179 virtual public IProductWRTBase_Helper
180{
181public:
183
185
186 void operator()(const Array<OneD, const NekDouble> &input,
187 Array<OneD, NekDouble> &output,
188 [[maybe_unused]] Array<OneD, NekDouble> &output1,
189 [[maybe_unused]] Array<OneD, NekDouble> &output2,
190 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
191 {
192 if (m_isPadded)
193 {
194 // copy into padded vector
195 Vmath::Vcopy(m_nIn, input, 1, m_input, 1);
196 // call op
197 (*m_oper)(m_input, m_output);
198 // copy out of padded vector
199 Vmath::Vcopy(m_nOut, m_output, 1, output, 1);
200 }
201 else
202 {
203 (*m_oper)(input, output);
204 }
205 }
206
207 void operator()([[maybe_unused]] int dir,
208 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
209 [[maybe_unused]] Array<OneD, NekDouble> &output,
210 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
211 {
212 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
213 }
214
215private:
216 std::shared_ptr<MatrixFree::IProduct> m_oper;
217
219 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
221 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
222 MatrixFreeOneInOneOut(pCollExp[0]->GetStdExp()->GetTotPoints(),
223 pCollExp[0]->GetStdExp()->GetNcoeffs(),
224 pCollExp.size())
225 {
226 // Basis vector
227 const auto dim = pCollExp[0]->GetStdExp()->GetShapeDimension();
228 std::vector<LibUtilities::BasisSharedPtr> basis(dim);
229 for (unsigned int i = 0; i < dim; ++i)
230 {
231 basis[i] = pCollExp[0]->GetBasis(i);
232 }
233
234 // Get shape type
235 auto shapeType = pCollExp[0]->GetStdExp()->DetShapeType();
236
237 // Generate operator string and create operator.
238 std::string op_string = "IProduct";
239 op_string += MatrixFree::GetOpstring(shapeType, m_isDeformed);
241 op_string, basis, m_nElmtPad);
242
243 // Set Jacobian
244 oper->SetJac(pGeomData->GetJacInterLeave(pCollExp, m_nElmtPad));
245
246 m_oper = std::dynamic_pointer_cast<MatrixFree::IProduct>(oper);
247 ASSERTL0(m_oper, "Failed to cast pointer.");
248 }
249};
250
251/// Factory initialisation for the IProductWRTBase_MatrixFree operators
252OperatorKey IProductWRTBase_MatrixFree::m_typeArr[] = {
255 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Seg"),
258 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Quad"),
261 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Tri"),
264 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Hex"),
267 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Prism"),
270 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Pyr"),
273 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Tet")};
274
275/**
276 * @brief Inner product operator using element-wise operation
277 */
278class IProductWRTBase_IterPerExp final : virtual public Operator,
279 virtual public IProductWRTBase_Helper
280{
281public:
283
285
286 void operator()(const Array<OneD, const NekDouble> &input,
287 Array<OneD, NekDouble> &output,
288 [[maybe_unused]] Array<OneD, NekDouble> &output1,
289 [[maybe_unused]] Array<OneD, NekDouble> &output2,
290 Array<OneD, NekDouble> &wsp) final
291 {
292 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
293
294 const int nCoeffs = m_stdExp->GetNcoeffs();
295 const int nPhys = m_stdExp->GetTotPoints();
297
298 Vmath::Vmul(m_jacWStdW.size(), m_jacWStdW, 1, input, 1, wsp, 1);
299
300 for (int i = 0; i < m_numElmt; ++i)
301 {
302 m_stdExp->IProductWRTBase_SumFac(wsp + i * nPhys,
303 tmp = output + i * nCoeffs, false);
304 }
305 }
306
307 void operator()([[maybe_unused]] int dir,
308 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
309 [[maybe_unused]] Array<OneD, NekDouble> &output,
310 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
311 {
312 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
313 }
314
315protected:
317
318private:
320 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
322 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper()
323 {
324 int nqtot = pCollExp[0]->GetTotPoints();
325
326 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
327
328 m_wspSize = nqtot * m_numElmt;
329 }
330};
331
332/// Factory initialisation for the IProductWRTBase_IterPerExp operators
333OperatorKey IProductWRTBase_IterPerExp::m_typeArr[] = {
336 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Seg"),
339 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Tri"),
342 IProductWRTBase_IterPerExp::create,
343 "IProductWRTBase_IterPerExp_NodalTri"),
346 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Quad"),
349 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Tet"),
352 IProductWRTBase_IterPerExp::create,
353 "IProductWRTBase_IterPerExp_NodalTet"),
356 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Pyr"),
359 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Prism"),
362 IProductWRTBase_IterPerExp::create,
363 "IProductWRTBase_IterPerExp_NodalPrism"),
366 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Hex"),
367};
368
369/**
370 * @brief Inner product operator using original MultiRegions implementation.
371 */
372class IProductWRTBase_NoCollection final : virtual public Operator,
373 virtual public IProductWRTBase_Helper
374{
375public:
377
379
380 void operator()(const Array<OneD, const NekDouble> &input,
381 Array<OneD, NekDouble> &output,
382 [[maybe_unused]] Array<OneD, NekDouble> &output1,
383 [[maybe_unused]] Array<OneD, NekDouble> &output2,
384 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
385 {
386 const int nCoeffs = m_expList[0]->GetNcoeffs();
387 const int nPhys = m_expList[0]->GetTotPoints();
389
390 for (int i = 0; i < m_numElmt; ++i)
391 {
392 m_expList[i]->IProductWRTBase(input + i * nPhys,
393 tmp = output + i * nCoeffs);
394 }
395 }
396
397 void operator()([[maybe_unused]] int dir,
398 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
399 [[maybe_unused]] Array<OneD, NekDouble> &output,
400 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
401 {
402 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
403 }
404
405protected:
406 vector<StdRegions::StdExpansionSharedPtr> m_expList;
407
408private:
410 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
412 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper()
413 {
414 m_expList = pCollExp;
415 }
416};
417
418/// Factory initialisation for the IProductWRTBase_NoCollection operators
419OperatorKey IProductWRTBase_NoCollection::m_typeArr[] = {
422 IProductWRTBase_NoCollection::create,
423 "IProductWRTBase_NoCollection_Seg"),
426 IProductWRTBase_NoCollection::create,
427 "IProductWRTBase_NoCollection_Tri"),
430 IProductWRTBase_NoCollection::create,
431 "IProductWRTBase_NoCollection_NodalTri"),
434 IProductWRTBase_NoCollection::create,
435 "IProductWRTBase_NoCollection_Quad"),
438 IProductWRTBase_NoCollection::create,
439 "IProductWRTBase_NoCollection_Tet"),
442 IProductWRTBase_NoCollection::create,
443 "IProductWRTBase_NoCollection_NodalTet"),
446 IProductWRTBase_NoCollection::create,
447 "IProductWRTBase_NoCollection_Pyr"),
450 IProductWRTBase_NoCollection::create,
451 "IProductWRTBase_NoCollection_Prism"),
454 IProductWRTBase_NoCollection::create,
455 "IProductWRTBase_NoCollection_NodalPrism"),
458 IProductWRTBase_NoCollection::create,
459 "IProductWRTBase_NoCollection_Hex"),
460};
461
462/**
463 * @brief Inner product operator using sum-factorisation (Segment)
464 */
465class IProductWRTBase_SumFac_Seg final : virtual public Operator,
466 virtual public IProductWRTBase_Helper
467{
468public:
470
472
473 void operator()(const Array<OneD, const NekDouble> &input,
474 Array<OneD, NekDouble> &output,
475 [[maybe_unused]] Array<OneD, NekDouble> &output1,
476 [[maybe_unused]] Array<OneD, NekDouble> &output2,
477 Array<OneD, NekDouble> &wsp) final
478 {
479 if (m_colldir0)
480 {
481 Vmath::Vmul(m_numElmt * m_nquad0, m_jacWStdW, 1, input, 1, output,
482 1);
483 }
484 else
485 {
486 Vmath::Vmul(m_numElmt * m_nquad0, m_jacWStdW, 1, input, 1, wsp, 1);
487
488 // out = B0*in;
489 Blas::Dgemm('T', 'N', m_nmodes0, m_numElmt, m_nquad0, 1.0,
490 m_base0.get(), m_nquad0, &wsp[0], m_nquad0, 0.0,
491 &output[0], m_nmodes0);
492 }
493 }
494
495 void operator()([[maybe_unused]] int dir,
496 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
497 [[maybe_unused]] Array<OneD, NekDouble> &output,
498 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
499 {
500 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
501 }
502
503protected:
504 const int m_nquad0;
505 const int m_nmodes0;
506 const bool m_colldir0;
509
510private:
512 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
514 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
515 m_nquad0(m_stdExp->GetNumPoints(0)),
516 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
517 m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
518 m_base0(m_stdExp->GetBasis(0)->GetBdata())
519 {
521 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
522 }
523};
524
525/// Factory initialisation for the IProductWRTBase_SumFac_Seg operator
526OperatorKey IProductWRTBase_SumFac_Seg::m_type =
529 IProductWRTBase_SumFac_Seg::create, "IProductWRTBase_SumFac_Seg");
530
531/**
532 * @brief Inner product operator using sum-factorisation (Quad)
533 */
534class IProductWRTBase_SumFac_Quad final : virtual public Operator,
535 virtual public IProductWRTBase_Helper
536{
537public:
539
541
542 void operator()(const Array<OneD, const NekDouble> &input,
543 Array<OneD, NekDouble> &output,
544 [[maybe_unused]] Array<OneD, NekDouble> &output1,
545 [[maybe_unused]] Array<OneD, NekDouble> &output2,
546 Array<OneD, NekDouble> &wsp) final
547 {
548 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
549
552 output, wsp);
553 }
554
555 void operator()([[maybe_unused]] int dir,
556 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
557 [[maybe_unused]] Array<OneD, NekDouble> &output,
558 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
559 {
560 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
561 }
562
563protected:
564 const int m_nquad0;
565 const int m_nquad1;
566 const int m_nmodes0;
567 const int m_nmodes1;
568 const bool m_colldir0;
569 const bool m_colldir1;
573
574private:
576 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
578 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
579 m_nquad0(m_stdExp->GetNumPoints(0)),
580 m_nquad1(m_stdExp->GetNumPoints(1)),
581 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
582 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
583 m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
584 m_colldir1(m_stdExp->GetBasis(1)->Collocation()),
585 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
586 m_base1(m_stdExp->GetBasis(1)->GetBdata())
587 {
588 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
589 m_wspSize =
591 }
592};
593
594/// Factory initialisation for the IProductWRTBase_SumFac_Quad operator
595OperatorKey IProductWRTBase_SumFac_Quad::m_type =
598 IProductWRTBase_SumFac_Quad::create, "IProductWRTBase_SumFac_Quad");
599
600/**
601 * @brief Inner product operator using sum-factorisation (Tri)
602 */
603class IProductWRTBase_SumFac_Tri final : virtual public Operator,
604 virtual public IProductWRTBase_Helper
605{
606public:
608
610
611 void operator()(const Array<OneD, const NekDouble> &input,
612 Array<OneD, NekDouble> &output,
613 [[maybe_unused]] Array<OneD, NekDouble> &output1,
614 [[maybe_unused]] Array<OneD, NekDouble> &output2,
615 Array<OneD, NekDouble> &wsp) final
616 {
617 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
618
620 m_nmodes1, m_base0, m_base1, m_jacWStdW, input, output,
621 wsp);
622 }
623
624 void operator()([[maybe_unused]] int dir,
625 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
626 [[maybe_unused]] Array<OneD, NekDouble> &output,
627 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
628 {
629 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
630 }
631
632protected:
633 const int m_nquad0;
634 const int m_nquad1;
635 const int m_nmodes0;
636 const int m_nmodes1;
641
642private:
644 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
646 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
647 m_nquad0(m_stdExp->GetNumPoints(0)),
648 m_nquad1(m_stdExp->GetNumPoints(1)),
649 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
650 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
651 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
652 m_base1(m_stdExp->GetBasis(1)->GetBdata())
653 {
654 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
655 m_wspSize =
657 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
658 {
659 m_sortTopVertex = true;
660 }
661 else
662 {
663 m_sortTopVertex = false;
664 }
665 }
666};
667
668/// Factory initialisation for the IProductWRTBase_SumFac_Tri operator
669OperatorKey IProductWRTBase_SumFac_Tri::m_type =
672 IProductWRTBase_SumFac_Tri::create, "IProductWRTBase_SumFac_Tri");
673
674/**
675 * @brief Inner Product operator using sum-factorisation (Hex)
676 */
677class IProductWRTBase_SumFac_Hex final : virtual public Operator,
678 virtual public IProductWRTBase_Helper
679{
680public:
682
684
685 void operator()(const Array<OneD, const NekDouble> &input,
686 Array<OneD, NekDouble> &output,
687 [[maybe_unused]] Array<OneD, NekDouble> &output1,
688 [[maybe_unused]] Array<OneD, NekDouble> &output2,
689 Array<OneD, NekDouble> &wsp) final
690 {
691 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
692
695 m_base0, m_base1, m_base2, m_jacWStdW, input, output, wsp);
696 }
697
698 void operator()([[maybe_unused]] int dir,
699 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
700 [[maybe_unused]] Array<OneD, NekDouble> &output,
701 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
702 {
703 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
704 }
705
706protected:
707 const int m_nquad0;
708 const int m_nquad1;
709 const int m_nquad2;
710 const int m_nmodes0;
711 const int m_nmodes1;
712 const int m_nmodes2;
713 const bool m_colldir0;
714 const bool m_colldir1;
715 const bool m_colldir2;
720
721private:
723 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
725 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
726 m_nquad0(m_stdExp->GetNumPoints(0)),
727 m_nquad1(m_stdExp->GetNumPoints(1)),
728 m_nquad2(m_stdExp->GetNumPoints(2)),
729 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
730 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
731 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
732 m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
733 m_colldir1(m_stdExp->GetBasis(1)->Collocation()),
734 m_colldir2(m_stdExp->GetBasis(2)->Collocation()),
735 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
736 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
737 m_base2(m_stdExp->GetBasis(2)->GetBdata())
738
739 {
740 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
741 m_wspSize = 3 * m_numElmt *
742 (max(m_nquad0 * m_nquad1 * m_nquad2,
744 }
745};
746
747/// Factory initialisation for the IProductWRTBase_SumFac_Hex operator
748OperatorKey IProductWRTBase_SumFac_Hex::m_type =
751 IProductWRTBase_SumFac_Hex::create, "IProductWRTBase_SumFac_Hex");
752
753/**
754 * @brief Inner product operator using sum-factorisation (Tet)
755 */
756class IProductWRTBase_SumFac_Tet final : virtual public Operator,
757 virtual public IProductWRTBase_Helper
758{
759public:
761
763
764 void operator()(const Array<OneD, const NekDouble> &input,
765 Array<OneD, NekDouble> &output,
766 [[maybe_unused]] Array<OneD, NekDouble> &output1,
767 [[maybe_unused]] Array<OneD, NekDouble> &output2,
768 Array<OneD, NekDouble> &wsp) final
769 {
770 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
771
774 m_jacWStdW, input, output, wsp);
775 }
776
777 void operator()([[maybe_unused]] int dir,
778 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
779 [[maybe_unused]] Array<OneD, NekDouble> &output,
780 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
781 {
782 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
783 }
784
785protected:
786 const int m_nquad0;
787 const int m_nquad1;
788 const int m_nquad2;
789 const int m_nmodes0;
790 const int m_nmodes1;
791 const int m_nmodes2;
797
798private:
800 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
802 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
803 m_nquad0(m_stdExp->GetNumPoints(0)),
804 m_nquad1(m_stdExp->GetNumPoints(1)),
805 m_nquad2(m_stdExp->GetNumPoints(2)),
806 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
807 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
808 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
809 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
810 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
811 m_base2(m_stdExp->GetBasis(2)->GetBdata())
812 {
813 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
814 m_wspSize =
815 m_numElmt *
816 (max(m_nquad0 * m_nquad1 * m_nquad2,
817 m_nquad2 * m_nmodes0 * (2 * m_nmodes1 - m_nmodes0 + 1) / 2) +
819
820 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
821 {
822 m_sortTopEdge = true;
823 }
824 else
825 {
826 m_sortTopEdge = false;
827 }
828 }
829};
830
831/// Factory initialisation for the IProductWRTBase_SumFac_Tet operator
832OperatorKey IProductWRTBase_SumFac_Tet::m_type =
835 IProductWRTBase_SumFac_Tet::create, "IProductWRTBase_SumFac_Tet");
836
837/**
838 * @brief Inner Product operator using sum-factorisation (Prism)
839 */
840class IProductWRTBase_SumFac_Prism final : virtual public Operator,
842{
843public:
845
847
848 void operator()(const Array<OneD, const NekDouble> &input,
849 Array<OneD, NekDouble> &output,
850 [[maybe_unused]] Array<OneD, NekDouble> &output1,
851 [[maybe_unused]] Array<OneD, NekDouble> &output2,
852 Array<OneD, NekDouble> &wsp) final
853 {
854 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
855
858 m_base2, m_jacWStdW, input, output, wsp);
859 }
860
861 void operator()([[maybe_unused]] int dir,
862 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
863 [[maybe_unused]] Array<OneD, NekDouble> &output,
864 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
865 {
866 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
867 }
868
869protected:
870 const int m_nquad0;
871 const int m_nquad1;
872 const int m_nquad2;
873 const int m_nmodes0;
874 const int m_nmodes1;
875 const int m_nmodes2;
881
882private:
884 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
886 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
887 m_nquad0(m_stdExp->GetNumPoints(0)),
888 m_nquad1(m_stdExp->GetNumPoints(1)),
889 m_nquad2(m_stdExp->GetNumPoints(2)),
890 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
891 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
892 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
893 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
894 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
895 m_base2(m_stdExp->GetBasis(2)->GetBdata())
896
897 {
898 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
899
903
904 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
905 {
906 m_sortTopVertex = true;
907 }
908 else
909 {
910 m_sortTopVertex = false;
911 }
912 }
913};
914
915/// Factory initialisation for the IProductWRTBase_SumFac_Prism operator
916OperatorKey IProductWRTBase_SumFac_Prism::m_type =
919 IProductWRTBase_SumFac_Prism::create, "IProductWRTBase_SumFac_Prism");
920
921/**
922 * @brief Inner Product operator using sum-factorisation (Pyr)
923 */
924class IProductWRTBase_SumFac_Pyr final : virtual public Operator,
926{
927public:
929
931
932 void operator()(const Array<OneD, const NekDouble> &input,
933 Array<OneD, NekDouble> &output,
934 [[maybe_unused]] Array<OneD, NekDouble> &output1,
935 [[maybe_unused]] Array<OneD, NekDouble> &output2,
936 Array<OneD, NekDouble> &wsp) final
937 {
938 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
939
942 m_jacWStdW, input, output, wsp);
943 }
944
945 void operator()([[maybe_unused]] int dir,
946 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
947 [[maybe_unused]] Array<OneD, NekDouble> &output,
948 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
949 {
950 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
951 }
952
953protected:
954 const int m_nquad0;
955 const int m_nquad1;
956 const int m_nquad2;
957 const int m_nmodes0;
958 const int m_nmodes1;
959 const int m_nmodes2;
965
966private:
968 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
970 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
971 m_nquad0(m_stdExp->GetNumPoints(0)),
972 m_nquad1(m_stdExp->GetNumPoints(1)),
973 m_nquad2(m_stdExp->GetNumPoints(2)),
974 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
975 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
976 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
977 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
978 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
979 m_base2(m_stdExp->GetBasis(2)->GetBdata())
980
981 {
982 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
983
987
988 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
989 {
990 m_sortTopVertex = true;
991 }
992 else
993 {
994 m_sortTopVertex = false;
995 }
996 }
997};
998
999/// Factory initialisation for the IProductWRTBase_SumFac_Pyr operator
1000OperatorKey IProductWRTBase_SumFac_Pyr::m_type =
1003 IProductWRTBase_SumFac_Pyr::create, "IProductWRTBase_SumFac_Pyr");
1004
1005} // namespace Nektar::Collections
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:202
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:242
#define OPERATOR_CREATE(cname)
Definition: Operator.h:43
Inner product help class to calculate the size of the collection that is given as an input and as an ...
Inner product operator using element-wise operation.
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
IProductWRTBase_IterPerExp(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Inner product operator using operator using matrix free operators.
IProductWRTBase_MatrixFree(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
std::shared_ptr< MatrixFree::IProduct > m_oper
Inner product operator using original MultiRegions implementation.
vector< StdRegions::StdExpansionSharedPtr > m_expList
IProductWRTBase_NoCollection(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
Inner product operator using standard matrix approach.
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
IProductWRTBase_StdMat(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Inner Product operator using sum-factorisation (Hex)
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
IProductWRTBase_SumFac_Hex(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Inner Product operator using sum-factorisation (Prism)
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
IProductWRTBase_SumFac_Prism(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Inner Product operator using sum-factorisation (Pyr)
IProductWRTBase_SumFac_Pyr(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
Inner product operator using sum-factorisation (Quad)
IProductWRTBase_SumFac_Quad(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
Inner product operator using sum-factorisation (Segment)
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
IProductWRTBase_SumFac_Seg(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Inner product operator using sum-factorisation (Tet)
IProductWRTBase_SumFac_Tet(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
Inner product operator using sum-factorisation (Tri)
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
IProductWRTBase_SumFac_Tri(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
unsigned int m_nElmtPad
size after padding
Array< OneD, NekDouble > m_input
padded input/output vectors
Base class for operators on a collection of elements.
Definition: Operator.h:138
StdRegions::StdExpansionSharedPtr m_stdExp
Definition: Operator.h:217
unsigned int m_numElmt
number of elements that the operator is applied on
Definition: Operator.h:219
unsigned int m_outputSize
number of modes or quadrature points that are taken as output from an operator
Definition: Operator.h:227
unsigned int m_inputSize
number of modes or quadrature points that are passed as input to an operator
Definition: Operator.h:224
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
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:383
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:496
void PyrIProduct(bool sortTopVert, int numElmt, int nquad0, int nquad1, int nquad2, int nmodes0, int nmodes1, int nmodes2, const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &jac, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
Definition: IProduct.cpp:405
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:128
std::tuple< LibUtilities::ShapeType, OperatorType, ImplementationType, ExpansionIsNodal > OperatorKey
Key for describing an Operator.
Definition: Operator.h:120
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:46
std::shared_ptr< CoalescedGeomData > CoalescedGeomDataSharedPtr
OperatorFactory & GetOperatorFactory()
Returns the singleton Operator factory object.
Definition: Operator.cpp:44
void PrismIProduct(bool sortTopVert, int numElmt, int nquad0, int nquad1, int nquad2, int nmodes0, int nmodes1, int nmodes2, const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &jac, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp)
Definition: IProduct.cpp:338
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:170
@ eModified_A
Principle Modified Functions .
Definition: BasisType.h:48
ConstFactorMap FactorMap
Definition: StdRegions.hpp:434
StdRegions::ConstFactorMap factors
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:75
double NekDouble
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.hpp:72
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.hpp:100
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.hpp:825
STL namespace.