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 (*m_oper)(input, output);
193 }
194
195 void operator()([[maybe_unused]] int dir,
196 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
197 [[maybe_unused]] Array<OneD, NekDouble> &output,
198 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
199 {
200 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
201 }
202
203private:
204 std::shared_ptr<MatrixFree::IProduct> m_oper;
205
207 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
209 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
210 MatrixFreeBase(pCollExp[0]->GetStdExp()->GetTotPoints(),
211 pCollExp[0]->GetStdExp()->GetNcoeffs(),
212 pCollExp.size())
213 {
214 // Basis vector
215 const auto dim = pCollExp[0]->GetStdExp()->GetShapeDimension();
216 std::vector<LibUtilities::BasisSharedPtr> basis(dim);
217 for (unsigned int i = 0; i < dim; ++i)
218 {
219 basis[i] = pCollExp[0]->GetBasis(i);
220 }
221
222 // Get shape type
223 auto shapeType = pCollExp[0]->GetStdExp()->DetShapeType();
224
225 // Generate operator string and create operator.
226 std::string op_string = "IProduct";
227 op_string += MatrixFree::GetOpstring(shapeType, m_isDeformed);
229 op_string, basis, pCollExp.size());
230
231 oper->SetUpBdata(basis);
232 oper->SetUpZW(basis);
233
234 // Set Jacobian
235 oper->SetJac(pGeomData->GetJacInterLeave(pCollExp, m_nElmtPad));
236
237 m_oper = std::dynamic_pointer_cast<MatrixFree::IProduct>(oper);
238 ASSERTL0(m_oper, "Failed to cast pointer.");
239 }
240};
241
242/// Factory initialisation for the IProductWRTBase_MatrixFree operators
243OperatorKey IProductWRTBase_MatrixFree::m_typeArr[] = {
246 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Seg"),
249 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Quad"),
252 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Tri"),
255 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Hex"),
258 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Prism"),
261 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Pyr"),
264 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Tet")};
265
266/**
267 * @brief Inner product operator using element-wise operation
268 */
269class IProductWRTBase_IterPerExp final : virtual public Operator,
270 virtual public IProductWRTBase_Helper
271{
272public:
274
276
277 void operator()(const Array<OneD, const NekDouble> &input,
278 Array<OneD, NekDouble> &output,
279 [[maybe_unused]] Array<OneD, NekDouble> &output1,
280 [[maybe_unused]] Array<OneD, NekDouble> &output2,
281 Array<OneD, NekDouble> &wsp) final
282 {
283 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
284
285 const int nCoeffs = m_stdExp->GetNcoeffs();
286 const int nPhys = m_stdExp->GetTotPoints();
288
289 Vmath::Vmul(m_jacWStdW.size(), m_jacWStdW, 1, input, 1, wsp, 1);
290
291 for (int i = 0; i < m_numElmt; ++i)
292 {
293 m_stdExp->IProductWRTBase_SumFac(wsp + i * nPhys,
294 tmp = output + i * nCoeffs, false);
295 }
296 }
297
298 void operator()([[maybe_unused]] int dir,
299 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
300 [[maybe_unused]] Array<OneD, NekDouble> &output,
301 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
302 {
303 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
304 }
305
306protected:
308
309private:
311 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
313 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper()
314 {
315 int nqtot = pCollExp[0]->GetTotPoints();
316
317 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
318
319 m_wspSize = nqtot * m_numElmt;
320 }
321};
322
323/// Factory initialisation for the IProductWRTBase_IterPerExp operators
324OperatorKey IProductWRTBase_IterPerExp::m_typeArr[] = {
327 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Seg"),
330 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Tri"),
333 IProductWRTBase_IterPerExp::create,
334 "IProductWRTBase_IterPerExp_NodalTri"),
337 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Quad"),
340 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Tet"),
343 IProductWRTBase_IterPerExp::create,
344 "IProductWRTBase_IterPerExp_NodalTet"),
347 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Pyr"),
350 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Prism"),
353 IProductWRTBase_IterPerExp::create,
354 "IProductWRTBase_IterPerExp_NodalPrism"),
357 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Hex"),
358};
359
360/**
361 * @brief Inner product operator using original MultiRegions implementation.
362 */
363class IProductWRTBase_NoCollection final : virtual public Operator,
364 virtual public IProductWRTBase_Helper
365{
366public:
368
370
371 void operator()(const Array<OneD, const NekDouble> &input,
372 Array<OneD, NekDouble> &output,
373 [[maybe_unused]] Array<OneD, NekDouble> &output1,
374 [[maybe_unused]] Array<OneD, NekDouble> &output2,
375 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
376 {
377 const int nCoeffs = m_expList[0]->GetNcoeffs();
378 const int nPhys = m_expList[0]->GetTotPoints();
380
381 for (int i = 0; i < m_numElmt; ++i)
382 {
383 m_expList[i]->IProductWRTBase(input + i * nPhys,
384 tmp = output + i * nCoeffs);
385 }
386 }
387
388 void operator()([[maybe_unused]] int dir,
389 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
390 [[maybe_unused]] Array<OneD, NekDouble> &output,
391 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
392 {
393 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
394 }
395
396protected:
397 vector<StdRegions::StdExpansionSharedPtr> m_expList;
398
399private:
401 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
403 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper()
404 {
405 m_expList = pCollExp;
406 }
407};
408
409/// Factory initialisation for the IProductWRTBase_NoCollection operators
410OperatorKey IProductWRTBase_NoCollection::m_typeArr[] = {
413 IProductWRTBase_NoCollection::create,
414 "IProductWRTBase_NoCollection_Seg"),
417 IProductWRTBase_NoCollection::create,
418 "IProductWRTBase_NoCollection_Tri"),
421 IProductWRTBase_NoCollection::create,
422 "IProductWRTBase_NoCollection_NodalTri"),
425 IProductWRTBase_NoCollection::create,
426 "IProductWRTBase_NoCollection_Quad"),
429 IProductWRTBase_NoCollection::create,
430 "IProductWRTBase_NoCollection_Tet"),
433 IProductWRTBase_NoCollection::create,
434 "IProductWRTBase_NoCollection_NodalTet"),
437 IProductWRTBase_NoCollection::create,
438 "IProductWRTBase_NoCollection_Pyr"),
441 IProductWRTBase_NoCollection::create,
442 "IProductWRTBase_NoCollection_Prism"),
445 IProductWRTBase_NoCollection::create,
446 "IProductWRTBase_NoCollection_NodalPrism"),
449 IProductWRTBase_NoCollection::create,
450 "IProductWRTBase_NoCollection_Hex"),
451};
452
453/**
454 * @brief Inner product operator using sum-factorisation (Segment)
455 */
456class IProductWRTBase_SumFac_Seg final : virtual public Operator,
457 virtual public IProductWRTBase_Helper
458{
459public:
461
463
464 void operator()(const Array<OneD, const NekDouble> &input,
465 Array<OneD, NekDouble> &output,
466 [[maybe_unused]] Array<OneD, NekDouble> &output1,
467 [[maybe_unused]] Array<OneD, NekDouble> &output2,
468 Array<OneD, NekDouble> &wsp) final
469 {
470 if (m_colldir0)
471 {
472 Vmath::Vmul(m_numElmt * m_nquad0, m_jacWStdW, 1, input, 1, output,
473 1);
474 }
475 else
476 {
477 Vmath::Vmul(m_numElmt * m_nquad0, m_jacWStdW, 1, input, 1, wsp, 1);
478
479 // out = B0*in;
480 Blas::Dgemm('T', 'N', m_nmodes0, m_numElmt, m_nquad0, 1.0,
481 m_base0.get(), m_nquad0, &wsp[0], m_nquad0, 0.0,
482 &output[0], m_nmodes0);
483 }
484 }
485
486 void operator()([[maybe_unused]] int dir,
487 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
488 [[maybe_unused]] Array<OneD, NekDouble> &output,
489 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
490 {
491 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
492 }
493
494protected:
495 const int m_nquad0;
496 const int m_nmodes0;
497 const bool m_colldir0;
500
501private:
503 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
505 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
506 m_nquad0(m_stdExp->GetNumPoints(0)),
507 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
508 m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
509 m_base0(m_stdExp->GetBasis(0)->GetBdata())
510 {
512 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
513 }
514};
515
516/// Factory initialisation for the IProductWRTBase_SumFac_Seg operator
517OperatorKey IProductWRTBase_SumFac_Seg::m_type =
520 IProductWRTBase_SumFac_Seg::create, "IProductWRTBase_SumFac_Seg");
521
522/**
523 * @brief Inner product operator using sum-factorisation (Quad)
524 */
525class IProductWRTBase_SumFac_Quad final : virtual public Operator,
526 virtual public IProductWRTBase_Helper
527{
528public:
530
532
533 void operator()(const Array<OneD, const NekDouble> &input,
534 Array<OneD, NekDouble> &output,
535 [[maybe_unused]] Array<OneD, NekDouble> &output1,
536 [[maybe_unused]] Array<OneD, NekDouble> &output2,
537 Array<OneD, NekDouble> &wsp) final
538 {
539 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
540
543 output, wsp);
544 }
545
546 void operator()([[maybe_unused]] int dir,
547 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
548 [[maybe_unused]] Array<OneD, NekDouble> &output,
549 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
550 {
551 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
552 }
553
554protected:
555 const int m_nquad0;
556 const int m_nquad1;
557 const int m_nmodes0;
558 const int m_nmodes1;
559 const bool m_colldir0;
560 const bool m_colldir1;
564
565private:
567 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
569 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
570 m_nquad0(m_stdExp->GetNumPoints(0)),
571 m_nquad1(m_stdExp->GetNumPoints(1)),
572 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
573 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
574 m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
575 m_colldir1(m_stdExp->GetBasis(1)->Collocation()),
576 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
577 m_base1(m_stdExp->GetBasis(1)->GetBdata())
578 {
579 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
580 m_wspSize =
582 }
583};
584
585/// Factory initialisation for the IProductWRTBase_SumFac_Quad operator
586OperatorKey IProductWRTBase_SumFac_Quad::m_type =
589 IProductWRTBase_SumFac_Quad::create, "IProductWRTBase_SumFac_Quad");
590
591/**
592 * @brief Inner product operator using sum-factorisation (Tri)
593 */
594class IProductWRTBase_SumFac_Tri final : virtual public Operator,
595 virtual public IProductWRTBase_Helper
596{
597public:
599
601
602 void operator()(const Array<OneD, const NekDouble> &input,
603 Array<OneD, NekDouble> &output,
604 [[maybe_unused]] Array<OneD, NekDouble> &output1,
605 [[maybe_unused]] Array<OneD, NekDouble> &output2,
606 Array<OneD, NekDouble> &wsp) final
607 {
608 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
609
611 m_nmodes1, m_base0, m_base1, m_jacWStdW, input, output,
612 wsp);
613 }
614
615 void operator()([[maybe_unused]] int dir,
616 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
617 [[maybe_unused]] Array<OneD, NekDouble> &output,
618 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
619 {
620 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
621 }
622
623protected:
624 const int m_nquad0;
625 const int m_nquad1;
626 const int m_nmodes0;
627 const int m_nmodes1;
632
633private:
635 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
637 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
638 m_nquad0(m_stdExp->GetNumPoints(0)),
639 m_nquad1(m_stdExp->GetNumPoints(1)),
640 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
641 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
642 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
643 m_base1(m_stdExp->GetBasis(1)->GetBdata())
644 {
645 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
646 m_wspSize =
648 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
649 {
650 m_sortTopVertex = true;
651 }
652 else
653 {
654 m_sortTopVertex = false;
655 }
656 }
657};
658
659/// Factory initialisation for the IProductWRTBase_SumFac_Tri operator
660OperatorKey IProductWRTBase_SumFac_Tri::m_type =
663 IProductWRTBase_SumFac_Tri::create, "IProductWRTBase_SumFac_Tri");
664
665/**
666 * @brief Inner Product operator using sum-factorisation (Hex)
667 */
668class IProductWRTBase_SumFac_Hex final : virtual public Operator,
669 virtual public IProductWRTBase_Helper
670{
671public:
673
675
676 void operator()(const Array<OneD, const NekDouble> &input,
677 Array<OneD, NekDouble> &output,
678 [[maybe_unused]] Array<OneD, NekDouble> &output1,
679 [[maybe_unused]] Array<OneD, NekDouble> &output2,
680 Array<OneD, NekDouble> &wsp) final
681 {
682 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
683
686 m_base0, m_base1, m_base2, m_jacWStdW, input, output, wsp);
687 }
688
689 void operator()([[maybe_unused]] int dir,
690 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
691 [[maybe_unused]] Array<OneD, NekDouble> &output,
692 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
693 {
694 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
695 }
696
697protected:
698 const int m_nquad0;
699 const int m_nquad1;
700 const int m_nquad2;
701 const int m_nmodes0;
702 const int m_nmodes1;
703 const int m_nmodes2;
704 const bool m_colldir0;
705 const bool m_colldir1;
706 const bool m_colldir2;
711
712private:
714 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
716 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
717 m_nquad0(m_stdExp->GetNumPoints(0)),
718 m_nquad1(m_stdExp->GetNumPoints(1)),
719 m_nquad2(m_stdExp->GetNumPoints(2)),
720 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
721 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
722 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
723 m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
724 m_colldir1(m_stdExp->GetBasis(1)->Collocation()),
725 m_colldir2(m_stdExp->GetBasis(2)->Collocation()),
726 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
727 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
728 m_base2(m_stdExp->GetBasis(2)->GetBdata())
729
730 {
731 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
732 m_wspSize = 3 * m_numElmt *
733 (max(m_nquad0 * m_nquad1 * m_nquad2,
735 }
736};
737
738/// Factory initialisation for the IProductWRTBase_SumFac_Hex operator
739OperatorKey IProductWRTBase_SumFac_Hex::m_type =
742 IProductWRTBase_SumFac_Hex::create, "IProductWRTBase_SumFac_Hex");
743
744/**
745 * @brief Inner product operator using sum-factorisation (Tet)
746 */
747class IProductWRTBase_SumFac_Tet final : virtual public Operator,
748 virtual public IProductWRTBase_Helper
749{
750public:
752
754
755 void operator()(const Array<OneD, const NekDouble> &input,
756 Array<OneD, NekDouble> &output,
757 [[maybe_unused]] Array<OneD, NekDouble> &output1,
758 [[maybe_unused]] Array<OneD, NekDouble> &output2,
759 Array<OneD, NekDouble> &wsp) final
760 {
761 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
762
765 m_jacWStdW, input, output, wsp);
766 }
767
768 void operator()([[maybe_unused]] int dir,
769 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
770 [[maybe_unused]] Array<OneD, NekDouble> &output,
771 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
772 {
773 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
774 }
775
776protected:
777 const int m_nquad0;
778 const int m_nquad1;
779 const int m_nquad2;
780 const int m_nmodes0;
781 const int m_nmodes1;
782 const int m_nmodes2;
788
789private:
791 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
793 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
794 m_nquad0(m_stdExp->GetNumPoints(0)),
795 m_nquad1(m_stdExp->GetNumPoints(1)),
796 m_nquad2(m_stdExp->GetNumPoints(2)),
797 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
798 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
799 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
800 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
801 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
802 m_base2(m_stdExp->GetBasis(2)->GetBdata())
803 {
804 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
805 m_wspSize =
806 m_numElmt *
807 (max(m_nquad0 * m_nquad1 * m_nquad2,
808 m_nquad2 * m_nmodes0 * (2 * m_nmodes1 - m_nmodes0 + 1) / 2) +
810
811 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
812 {
813 m_sortTopEdge = true;
814 }
815 else
816 {
817 m_sortTopEdge = false;
818 }
819 }
820};
821
822/// Factory initialisation for the IProductWRTBase_SumFac_Tet operator
823OperatorKey IProductWRTBase_SumFac_Tet::m_type =
826 IProductWRTBase_SumFac_Tet::create, "IProductWRTBase_SumFac_Tet");
827
828/**
829 * @brief Inner Product operator using sum-factorisation (Prism)
830 */
831class IProductWRTBase_SumFac_Prism final : virtual public Operator,
833{
834public:
836
838
839 void operator()(const Array<OneD, const NekDouble> &input,
840 Array<OneD, NekDouble> &output,
841 [[maybe_unused]] Array<OneD, NekDouble> &output1,
842 [[maybe_unused]] Array<OneD, NekDouble> &output2,
843 Array<OneD, NekDouble> &wsp) final
844 {
845 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
846
849 m_base2, m_jacWStdW, input, output, wsp);
850 }
851
852 void operator()([[maybe_unused]] int dir,
853 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
854 [[maybe_unused]] Array<OneD, NekDouble> &output,
855 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
856 {
857 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
858 }
859
860protected:
861 const int m_nquad0;
862 const int m_nquad1;
863 const int m_nquad2;
864 const int m_nmodes0;
865 const int m_nmodes1;
866 const int m_nmodes2;
872
873private:
875 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
877 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
878 m_nquad0(m_stdExp->GetNumPoints(0)),
879 m_nquad1(m_stdExp->GetNumPoints(1)),
880 m_nquad2(m_stdExp->GetNumPoints(2)),
881 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
882 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
883 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
884 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
885 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
886 m_base2(m_stdExp->GetBasis(2)->GetBdata())
887
888 {
889 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
890
894
895 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
896 {
897 m_sortTopVertex = true;
898 }
899 else
900 {
901 m_sortTopVertex = false;
902 }
903 }
904};
905
906/// Factory initialisation for the IProductWRTBase_SumFac_Prism operator
907OperatorKey IProductWRTBase_SumFac_Prism::m_type =
910 IProductWRTBase_SumFac_Prism::create, "IProductWRTBase_SumFac_Prism");
911
912/**
913 * @brief Inner Product operator using sum-factorisation (Pyr)
914 */
915class IProductWRTBase_SumFac_Pyr final : virtual public Operator,
917{
918public:
920
922
923 void operator()(const Array<OneD, const NekDouble> &input,
924 Array<OneD, NekDouble> &output,
925 [[maybe_unused]] Array<OneD, NekDouble> &output1,
926 [[maybe_unused]] Array<OneD, NekDouble> &output2,
927 Array<OneD, NekDouble> &wsp) final
928 {
929 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
930
933 m_jacWStdW, input, output, wsp);
934 }
935
936 void operator()([[maybe_unused]] int dir,
937 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
938 [[maybe_unused]] Array<OneD, NekDouble> &output,
939 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
940 {
941 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
942 }
943
944protected:
945 const int m_nquad0;
946 const int m_nquad1;
947 const int m_nquad2;
948 const int m_nmodes0;
949 const int m_nmodes1;
950 const int m_nmodes2;
956
957private:
959 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
961 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
962 m_nquad0(m_stdExp->GetNumPoints(0)),
963 m_nquad1(m_stdExp->GetNumPoints(1)),
964 m_nquad2(m_stdExp->GetNumPoints(2)),
965 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
966 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
967 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
968 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
969 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
970 m_base2(m_stdExp->GetBasis(2)->GetBdata())
971
972 {
973 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
974
978
979 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
980 {
981 m_sortTopVertex = true;
982 }
983 else
984 {
985 m_sortTopVertex = false;
986 }
987 }
988};
989
990/// Factory initialisation for the IProductWRTBase_SumFac_Pyr operator
991OperatorKey IProductWRTBase_SumFac_Pyr::m_type =
994 IProductWRTBase_SumFac_Pyr::create, "IProductWRTBase_SumFac_Pyr");
995
996} // 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
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
STL namespace.