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
120 [[maybe_unused]] int coll_phys_offset) override
121 {
122 ASSERTL0(false, "Not valid for this operator.");
123 }
124
125protected:
128
129private:
130 IProductWRTBase_StdMat(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
133 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper()
134 {
135 m_jac = pGeomData->GetJac(pCollExp);
137 m_stdExp->DetShapeType(), *m_stdExp);
138 m_mat = m_stdExp->GetStdMatrix(key);
139 m_nqe = m_stdExp->GetTotPoints();
141 }
142};
143
144/// Factory initialisation for the IProductWRTBase_StdMat operators
145OperatorKey IProductWRTBase_StdMat::m_typeArr[] = {
148 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Seg"),
151 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Tri"),
154 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_NodalTri"),
157 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Quad"),
160 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Tet"),
163 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_NodalTet"),
166 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Pyr"),
169 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Prism"),
172 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_NodalPrism"),
175 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Hex"),
178 IProductWRTBase_StdMat::create, "IProductWRTBase_SumFac_Pyr")};
179
180/**
181 * @brief Inner product operator using operator using matrix free operators.
182 */
183class IProductWRTBase_MatrixFree final : virtual public Operator,
185 virtual public IProductWRTBase_Helper
186{
187public:
189
191
192 void operator()(const Array<OneD, const NekDouble> &input,
193 Array<OneD, NekDouble> &output,
194 [[maybe_unused]] Array<OneD, NekDouble> &output1,
195 [[maybe_unused]] Array<OneD, NekDouble> &output2,
196 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
197 {
198 if (m_isPadded)
199 {
200 // copy into padded vector
201 Vmath::Vcopy(m_nIn, input, 1, m_input, 1);
202 // call op
203 (*m_oper)(m_input, m_output);
204 // copy out of padded vector
205 Vmath::Vcopy(m_nOut, m_output, 1, output, 1);
206 }
207 else
208 {
209 (*m_oper)(input, output);
210 }
211 }
212
213 void operator()([[maybe_unused]] int dir,
214 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
215 [[maybe_unused]] Array<OneD, NekDouble> &output,
216 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
217 {
218 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
219 }
220
222 [[maybe_unused]] int coll_phys_offset) override
223 {
224 ASSERTL0(false, "Not valid for this operator.");
225 }
226
227private:
228 std::shared_ptr<MatrixFree::IProduct> m_oper;
229
231 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
233 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
234 MatrixFreeOneInOneOut(pCollExp[0]->GetStdExp()->GetTotPoints(),
235 pCollExp[0]->GetStdExp()->GetNcoeffs(),
236 pCollExp.size())
237 {
238 // Basis vector
239 const auto dim = pCollExp[0]->GetStdExp()->GetShapeDimension();
240 std::vector<LibUtilities::BasisSharedPtr> basis(dim);
241 for (unsigned int i = 0; i < dim; ++i)
242 {
243 basis[i] = pCollExp[0]->GetBasis(i);
244 }
245
246 // Get shape type
247 auto shapeType = pCollExp[0]->GetStdExp()->DetShapeType();
248
249 // Generate operator string and create operator.
250 std::string op_string = "IProduct";
251 op_string += MatrixFree::GetOpstring(shapeType, m_isDeformed);
253 op_string, basis, m_nElmtPad);
254
255 // Set Jacobian
256 oper->SetJac(pGeomData->GetJacInterLeave(pCollExp, m_nElmtPad));
257
258 m_oper = std::dynamic_pointer_cast<MatrixFree::IProduct>(oper);
259 ASSERTL0(m_oper, "Failed to cast pointer.");
260 }
261};
262
263/// Factory initialisation for the IProductWRTBase_MatrixFree operators
264OperatorKey IProductWRTBase_MatrixFree::m_typeArr[] = {
267 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Seg"),
270 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Quad"),
273 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Tri"),
276 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Hex"),
279 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Prism"),
282 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Pyr"),
285 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Tet")};
286
287/**
288 * @brief Inner product operator using element-wise operation
289 */
290class IProductWRTBase_IterPerExp final : virtual public Operator,
291 virtual public IProductWRTBase_Helper
292{
293public:
295
297
298 void operator()(const Array<OneD, const NekDouble> &input,
299 Array<OneD, NekDouble> &output,
300 [[maybe_unused]] Array<OneD, NekDouble> &output1,
301 [[maybe_unused]] Array<OneD, NekDouble> &output2,
302 Array<OneD, NekDouble> &wsp) final
303 {
304 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
305
306 const int nCoeffs = m_stdExp->GetNcoeffs();
307 const int nPhys = m_stdExp->GetTotPoints();
309
310 Vmath::Vmul(m_jacWStdW.size(), m_jacWStdW, 1, input, 1, wsp, 1);
311
312 for (int i = 0; i < m_numElmt; ++i)
313 {
314 m_stdExp->IProductWRTBase_SumFac(wsp + i * nPhys,
315 tmp = output + i * nCoeffs, false);
316 }
317 }
318
319 void operator()([[maybe_unused]] int dir,
320 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
321 [[maybe_unused]] Array<OneD, NekDouble> &output,
322 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
323 {
324 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
325 }
326
328 [[maybe_unused]] int coll_phys_offset) override
329 {
330 ASSERTL0(false, "Not valid for this operator.");
331 }
332
333protected:
335
336private:
338 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
340 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper()
341 {
342 int nqtot = pCollExp[0]->GetTotPoints();
343
344 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
345
346 m_wspSize = nqtot * m_numElmt;
347 }
348};
349
350/// Factory initialisation for the IProductWRTBase_IterPerExp operators
351OperatorKey IProductWRTBase_IterPerExp::m_typeArr[] = {
354 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Seg"),
357 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Tri"),
360 IProductWRTBase_IterPerExp::create,
361 "IProductWRTBase_IterPerExp_NodalTri"),
364 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Quad"),
367 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Tet"),
370 IProductWRTBase_IterPerExp::create,
371 "IProductWRTBase_IterPerExp_NodalTet"),
374 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Pyr"),
377 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Prism"),
380 IProductWRTBase_IterPerExp::create,
381 "IProductWRTBase_IterPerExp_NodalPrism"),
384 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Hex"),
385};
386
387/**
388 * @brief Inner product operator using original MultiRegions implementation.
389 */
390class IProductWRTBase_NoCollection final : virtual public Operator,
391 virtual public IProductWRTBase_Helper
392{
393public:
395
397
398 void operator()(const Array<OneD, const NekDouble> &input,
399 Array<OneD, NekDouble> &output,
400 [[maybe_unused]] Array<OneD, NekDouble> &output1,
401 [[maybe_unused]] Array<OneD, NekDouble> &output2,
402 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
403 {
404 const int nCoeffs = m_expList[0]->GetNcoeffs();
405 const int nPhys = m_expList[0]->GetTotPoints();
407
408 for (int i = 0; i < m_numElmt; ++i)
409 {
410 m_expList[i]->IProductWRTBase(input + i * nPhys,
411 tmp = output + i * nCoeffs);
412 }
413 }
414
415 void operator()([[maybe_unused]] int dir,
416 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
417 [[maybe_unused]] Array<OneD, NekDouble> &output,
418 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
419 {
420 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
421 }
422
424 [[maybe_unused]] int coll_phys_offset) override
425 {
426 ASSERTL0(false, "Not valid for this operator.");
427 }
428
429protected:
430 vector<StdRegions::StdExpansionSharedPtr> m_expList;
431
432private:
434 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
436 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper()
437 {
438 m_expList = pCollExp;
439 }
440};
441
442/// Factory initialisation for the IProductWRTBase_NoCollection operators
443OperatorKey IProductWRTBase_NoCollection::m_typeArr[] = {
446 IProductWRTBase_NoCollection::create,
447 "IProductWRTBase_NoCollection_Seg"),
450 IProductWRTBase_NoCollection::create,
451 "IProductWRTBase_NoCollection_Tri"),
454 IProductWRTBase_NoCollection::create,
455 "IProductWRTBase_NoCollection_NodalTri"),
458 IProductWRTBase_NoCollection::create,
459 "IProductWRTBase_NoCollection_Quad"),
462 IProductWRTBase_NoCollection::create,
463 "IProductWRTBase_NoCollection_Tet"),
466 IProductWRTBase_NoCollection::create,
467 "IProductWRTBase_NoCollection_NodalTet"),
470 IProductWRTBase_NoCollection::create,
471 "IProductWRTBase_NoCollection_Pyr"),
474 IProductWRTBase_NoCollection::create,
475 "IProductWRTBase_NoCollection_Prism"),
478 IProductWRTBase_NoCollection::create,
479 "IProductWRTBase_NoCollection_NodalPrism"),
482 IProductWRTBase_NoCollection::create,
483 "IProductWRTBase_NoCollection_Hex"),
484};
485
486/**
487 * @brief Inner product operator using sum-factorisation (Segment)
488 */
489class IProductWRTBase_SumFac_Seg final : virtual public Operator,
490 virtual public IProductWRTBase_Helper
491{
492public:
494
496
497 void operator()(const Array<OneD, const NekDouble> &input,
498 Array<OneD, NekDouble> &output,
499 [[maybe_unused]] Array<OneD, NekDouble> &output1,
500 [[maybe_unused]] Array<OneD, NekDouble> &output2,
501 Array<OneD, NekDouble> &wsp) final
502 {
503 if (m_colldir0)
504 {
505 Vmath::Vmul(m_numElmt * m_nquad0, m_jacWStdW, 1, input, 1, output,
506 1);
507 }
508 else
509 {
510 Vmath::Vmul(m_numElmt * m_nquad0, m_jacWStdW, 1, input, 1, wsp, 1);
511
512 // out = B0*in;
513 Blas::Dgemm('T', 'N', m_nmodes0, m_numElmt, m_nquad0, 1.0,
514 m_base0.get(), m_nquad0, &wsp[0], m_nquad0, 0.0,
515 &output[0], m_nmodes0);
516 }
517 }
518
519 void operator()([[maybe_unused]] int dir,
520 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
521 [[maybe_unused]] Array<OneD, NekDouble> &output,
522 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
523 {
524 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
525 }
526
528 [[maybe_unused]] int coll_phys_offset) override
529 {
530 ASSERTL0(false, "Not valid for this operator.");
531 }
532
533protected:
534 const int m_nquad0;
535 const int m_nmodes0;
536 const bool m_colldir0;
539
540private:
542 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
544 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
545 m_nquad0(m_stdExp->GetNumPoints(0)),
546 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
547 m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
548 m_base0(m_stdExp->GetBasis(0)->GetBdata())
549 {
551 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
552 }
553};
554
555/// Factory initialisation for the IProductWRTBase_SumFac_Seg operator
556OperatorKey IProductWRTBase_SumFac_Seg::m_type =
559 IProductWRTBase_SumFac_Seg::create, "IProductWRTBase_SumFac_Seg");
560
561/**
562 * @brief Inner product operator using sum-factorisation (Quad)
563 */
564class IProductWRTBase_SumFac_Quad final : virtual public Operator,
565 virtual public IProductWRTBase_Helper
566{
567public:
569
571
572 void operator()(const Array<OneD, const NekDouble> &input,
573 Array<OneD, NekDouble> &output,
574 [[maybe_unused]] Array<OneD, NekDouble> &output1,
575 [[maybe_unused]] Array<OneD, NekDouble> &output2,
576 Array<OneD, NekDouble> &wsp) final
577 {
578 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
579
582 output, wsp);
583 }
584
585 void operator()([[maybe_unused]] int dir,
586 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
587 [[maybe_unused]] Array<OneD, NekDouble> &output,
588 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
589 {
590 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
591 }
592
594 [[maybe_unused]] int coll_phys_offset) override
595 {
596 ASSERTL0(false, "Not valid for this operator.");
597 }
598
599protected:
600 const int m_nquad0;
601 const int m_nquad1;
602 const int m_nmodes0;
603 const int m_nmodes1;
604 const bool m_colldir0;
605 const bool m_colldir1;
609
610private:
612 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
614 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
615 m_nquad0(m_stdExp->GetNumPoints(0)),
616 m_nquad1(m_stdExp->GetNumPoints(1)),
617 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
618 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
619 m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
620 m_colldir1(m_stdExp->GetBasis(1)->Collocation()),
621 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
622 m_base1(m_stdExp->GetBasis(1)->GetBdata())
623 {
624 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
625 m_wspSize =
627 }
628};
629
630/// Factory initialisation for the IProductWRTBase_SumFac_Quad operator
631OperatorKey IProductWRTBase_SumFac_Quad::m_type =
634 IProductWRTBase_SumFac_Quad::create, "IProductWRTBase_SumFac_Quad");
635
636/**
637 * @brief Inner product operator using sum-factorisation (Tri)
638 */
639class IProductWRTBase_SumFac_Tri final : virtual public Operator,
640 virtual public IProductWRTBase_Helper
641{
642public:
644
646
647 void operator()(const Array<OneD, const NekDouble> &input,
648 Array<OneD, NekDouble> &output,
649 [[maybe_unused]] Array<OneD, NekDouble> &output1,
650 [[maybe_unused]] Array<OneD, NekDouble> &output2,
651 Array<OneD, NekDouble> &wsp) final
652 {
653 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
654
656 m_nmodes1, m_base0, m_base1, m_jacWStdW, input, output,
657 wsp);
658 }
659
660 void operator()([[maybe_unused]] int dir,
661 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
662 [[maybe_unused]] Array<OneD, NekDouble> &output,
663 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
664 {
665 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
666 }
667
669 [[maybe_unused]] int coll_phys_offset) override
670 {
671 ASSERTL0(false, "Not valid for this operator.");
672 }
673
674protected:
675 const int m_nquad0;
676 const int m_nquad1;
677 const int m_nmodes0;
678 const int m_nmodes1;
683
684private:
686 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
688 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
689 m_nquad0(m_stdExp->GetNumPoints(0)),
690 m_nquad1(m_stdExp->GetNumPoints(1)),
691 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
692 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
693 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
694 m_base1(m_stdExp->GetBasis(1)->GetBdata())
695 {
696 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
697 m_wspSize =
699 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
700 {
701 m_sortTopVertex = true;
702 }
703 else
704 {
705 m_sortTopVertex = false;
706 }
707 }
708};
709
710/// Factory initialisation for the IProductWRTBase_SumFac_Tri operator
711OperatorKey IProductWRTBase_SumFac_Tri::m_type =
714 IProductWRTBase_SumFac_Tri::create, "IProductWRTBase_SumFac_Tri");
715
716/**
717 * @brief Inner Product operator using sum-factorisation (Hex)
718 */
719class IProductWRTBase_SumFac_Hex final : virtual public Operator,
720 virtual public IProductWRTBase_Helper
721{
722public:
724
726
727 void operator()(const Array<OneD, const NekDouble> &input,
728 Array<OneD, NekDouble> &output,
729 [[maybe_unused]] Array<OneD, NekDouble> &output1,
730 [[maybe_unused]] Array<OneD, NekDouble> &output2,
731 Array<OneD, NekDouble> &wsp) final
732 {
733 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
734
737 m_base0, m_base1, m_base2, m_jacWStdW, input, output, wsp);
738 }
739
740 void operator()([[maybe_unused]] int dir,
741 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
742 [[maybe_unused]] Array<OneD, NekDouble> &output,
743 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
744 {
745 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
746 }
747
749 [[maybe_unused]] int coll_phys_offset) override
750 {
751 ASSERTL0(false, "Not valid for this operator.");
752 }
753
754protected:
755 const int m_nquad0;
756 const int m_nquad1;
757 const int m_nquad2;
758 const int m_nmodes0;
759 const int m_nmodes1;
760 const int m_nmodes2;
761 const bool m_colldir0;
762 const bool m_colldir1;
763 const bool m_colldir2;
768
769private:
771 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
773 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
774 m_nquad0(m_stdExp->GetNumPoints(0)),
775 m_nquad1(m_stdExp->GetNumPoints(1)),
776 m_nquad2(m_stdExp->GetNumPoints(2)),
777 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
778 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
779 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
780 m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
781 m_colldir1(m_stdExp->GetBasis(1)->Collocation()),
782 m_colldir2(m_stdExp->GetBasis(2)->Collocation()),
783 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
784 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
785 m_base2(m_stdExp->GetBasis(2)->GetBdata())
786
787 {
788 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
789 m_wspSize = 3 * m_numElmt *
790 (max(m_nquad0 * m_nquad1 * m_nquad2,
792 }
793};
794
795/// Factory initialisation for the IProductWRTBase_SumFac_Hex operator
796OperatorKey IProductWRTBase_SumFac_Hex::m_type =
799 IProductWRTBase_SumFac_Hex::create, "IProductWRTBase_SumFac_Hex");
800
801/**
802 * @brief Inner product operator using sum-factorisation (Tet)
803 */
804class IProductWRTBase_SumFac_Tet final : virtual public Operator,
805 virtual public IProductWRTBase_Helper
806{
807public:
809
811
812 void operator()(const Array<OneD, const NekDouble> &input,
813 Array<OneD, NekDouble> &output,
814 [[maybe_unused]] Array<OneD, NekDouble> &output1,
815 [[maybe_unused]] Array<OneD, NekDouble> &output2,
816 Array<OneD, NekDouble> &wsp) final
817 {
818 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
819
822 m_jacWStdW, input, output, wsp);
823 }
824
825 void operator()([[maybe_unused]] int dir,
826 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
827 [[maybe_unused]] Array<OneD, NekDouble> &output,
828 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
829 {
830 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
831 }
832
834 [[maybe_unused]] int coll_phys_offset) override
835 {
836 ASSERTL0(false, "Not valid for this operator.");
837 }
838
839protected:
840 const int m_nquad0;
841 const int m_nquad1;
842 const int m_nquad2;
843 const int m_nmodes0;
844 const int m_nmodes1;
845 const int m_nmodes2;
851
852private:
854 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
856 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
857 m_nquad0(m_stdExp->GetNumPoints(0)),
858 m_nquad1(m_stdExp->GetNumPoints(1)),
859 m_nquad2(m_stdExp->GetNumPoints(2)),
860 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
861 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
862 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
863 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
864 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
865 m_base2(m_stdExp->GetBasis(2)->GetBdata())
866 {
867 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
868 m_wspSize =
869 m_numElmt *
870 (max(m_nquad0 * m_nquad1 * m_nquad2,
871 m_nquad2 * m_nmodes0 * (2 * m_nmodes1 - m_nmodes0 + 1) / 2) +
873
874 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
875 {
876 m_sortTopEdge = true;
877 }
878 else
879 {
880 m_sortTopEdge = false;
881 }
882 }
883};
884
885/// Factory initialisation for the IProductWRTBase_SumFac_Tet operator
886OperatorKey IProductWRTBase_SumFac_Tet::m_type =
889 IProductWRTBase_SumFac_Tet::create, "IProductWRTBase_SumFac_Tet");
890
891/**
892 * @brief Inner Product operator using sum-factorisation (Prism)
893 */
894class IProductWRTBase_SumFac_Prism final : virtual public Operator,
896{
897public:
899
901
902 void operator()(const Array<OneD, const NekDouble> &input,
903 Array<OneD, NekDouble> &output,
904 [[maybe_unused]] Array<OneD, NekDouble> &output1,
905 [[maybe_unused]] Array<OneD, NekDouble> &output2,
906 Array<OneD, NekDouble> &wsp) final
907 {
908 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
909
912 m_base2, m_jacWStdW, input, output, wsp);
913 }
914
915 void operator()([[maybe_unused]] int dir,
916 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
917 [[maybe_unused]] Array<OneD, NekDouble> &output,
918 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
919 {
920 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
921 }
922
924 [[maybe_unused]] int coll_phys_offset) override
925 {
926 ASSERTL0(false, "Not valid for this operator.");
927 }
928
929protected:
930 const int m_nquad0;
931 const int m_nquad1;
932 const int m_nquad2;
933 const int m_nmodes0;
934 const int m_nmodes1;
935 const int m_nmodes2;
941
942private:
944 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
946 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
947 m_nquad0(m_stdExp->GetNumPoints(0)),
948 m_nquad1(m_stdExp->GetNumPoints(1)),
949 m_nquad2(m_stdExp->GetNumPoints(2)),
950 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
951 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
952 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
953 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
954 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
955 m_base2(m_stdExp->GetBasis(2)->GetBdata())
956
957 {
958 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
959
963
964 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
965 {
966 m_sortTopVertex = true;
967 }
968 else
969 {
970 m_sortTopVertex = false;
971 }
972 }
973};
974
975/// Factory initialisation for the IProductWRTBase_SumFac_Prism operator
976OperatorKey IProductWRTBase_SumFac_Prism::m_type =
979 IProductWRTBase_SumFac_Prism::create, "IProductWRTBase_SumFac_Prism");
980
981/**
982 * @brief Inner Product operator using sum-factorisation (Pyr)
983 */
984class IProductWRTBase_SumFac_Pyr final : virtual public Operator,
986{
987public:
989
991
992 void operator()(const Array<OneD, const NekDouble> &input,
993 Array<OneD, NekDouble> &output,
994 [[maybe_unused]] Array<OneD, NekDouble> &output1,
995 [[maybe_unused]] Array<OneD, NekDouble> &output2,
996 Array<OneD, NekDouble> &wsp) final
997 {
998 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
999
1002 m_jacWStdW, input, output, wsp);
1003 }
1004
1005 void operator()([[maybe_unused]] int dir,
1006 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
1007 [[maybe_unused]] Array<OneD, NekDouble> &output,
1008 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
1009 {
1010 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
1011 }
1012
1014 [[maybe_unused]] int coll_phys_offset) override
1015 {
1016 ASSERTL0(false, "Not valid for this operator.");
1017 }
1018
1019protected:
1020 const int m_nquad0;
1021 const int m_nquad1;
1022 const int m_nquad2;
1023 const int m_nmodes0;
1024 const int m_nmodes1;
1025 const int m_nmodes2;
1031
1032private:
1034 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
1036 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
1037 m_nquad0(m_stdExp->GetNumPoints(0)),
1038 m_nquad1(m_stdExp->GetNumPoints(1)),
1039 m_nquad2(m_stdExp->GetNumPoints(2)),
1040 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
1041 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
1042 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
1043 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
1044 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
1045 m_base2(m_stdExp->GetBasis(2)->GetBdata())
1046
1047 {
1048 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
1049
1051 (max(m_nquad0 * m_nquad1, m_nmodes0 * m_nmodes1)) +
1053
1054 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
1055 {
1056 m_sortTopVertex = true;
1057 }
1058 else
1059 {
1060 m_sortTopVertex = false;
1061 }
1062 }
1063};
1064
1065/// Factory initialisation for the IProductWRTBase_SumFac_Pyr operator
1066OperatorKey IProductWRTBase_SumFac_Pyr::m_type =
1069 IProductWRTBase_SumFac_Pyr::create, "IProductWRTBase_SumFac_Pyr");
1070
1071} // 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)
void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
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
void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Inner product operator using original MultiRegions implementation.
vector< StdRegions::StdExpansionSharedPtr > m_expList
void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
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)
void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
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)
void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Inner Product operator using sum-factorisation (Prism)
void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
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)
void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
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
void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
Inner product operator using sum-factorisation (Segment)
void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
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)
void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
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
void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset) override
Check the validity of the supplied factor map.
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:133
StdRegions::StdExpansionSharedPtr m_stdExp
Definition: Operator.h:188
unsigned int m_numElmt
number of elements that the operator is applied on
Definition: Operator.h:190
unsigned int m_outputSize
number of modes or quadrature points that are taken as output from an operator
Definition: Operator.h:198
unsigned int m_inputSize
number of modes or quadrature points that are passed as input to an operator
Definition: Operator.h:195
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:197
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:143
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:115
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:406
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