Nektar++
Loading...
Searching...
No Matches
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
40#include <MatrixFreeOps/Operator.hpp>
42
43using namespace std;
44
45namespace Nektar::Collections
46{
47
58
59/**
60 * @brief Inner product help class to calculate the size of the collection
61 * that is given as an input and as an output to the IProductWRTBase Operator.
62 * The size evaluation takes into account the conversion from the physical space
63 * to the coefficient space.
64 */
65class IProductWRTBase_Helper : virtual public Operator
66{
67protected:
69 {
70 // expect input to be number of elements by the number of quad points
71 m_inputSize = m_numElmt * m_stdExp->GetTotPoints();
72 // expect input to be number of elements by the number of coefficients
73 m_outputSize = m_numElmt * m_stdExp->GetNcoeffs();
74 }
75};
76
77/**
78 * @brief Inner product operator using standard matrix approach
79 */
80class IProductWRTBase_StdMat final : virtual public Operator,
81 virtual public IProductWRTBase_Helper
82{
83public:
85
86 ~IProductWRTBase_StdMat() final = default;
87
88 void operator()(const Array<OneD, const NekDouble> &input,
89 Array<OneD, NekDouble> &output,
90 [[maybe_unused]] Array<OneD, NekDouble> &output1,
91 [[maybe_unused]] Array<OneD, NekDouble> &output2,
92 Array<OneD, NekDouble> &wsp) final
93 {
94 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
95
96 if (m_isDeformed)
97 {
98 Vmath::Vmul(m_jac.size(), m_jac, 1, input, 1, wsp, 1);
99 }
100 else
101 {
103 for (int e = 0; e < m_numElmt; ++e)
104 {
105 Vmath::Smul(m_nqe, m_jac[e], input + e * m_nqe, 1,
106 tmp = wsp + e * m_nqe, 1);
107 }
108 }
109
110 Blas::Dgemm('N', 'N', m_mat->GetRows(), m_numElmt, m_mat->GetColumns(),
111 1.0, m_mat->GetRawPtr(), m_mat->GetRows(), wsp.data(),
112 m_stdExp->GetTotPoints(), 0.0, output.data(),
113 m_stdExp->GetNcoeffs());
114 }
115
116 void operator()([[maybe_unused]] int dir,
117 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
118 [[maybe_unused]] Array<OneD, NekDouble> &output,
119 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
120 {
121 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
122 }
123
124protected:
127
128private:
129 IProductWRTBase_StdMat(vector<LocalRegions::ExpansionSharedPtr> pCollExp,
131 StdRegions::FactorMap factors)
132 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper()
133 {
134 m_jac = pGeomData->GetJac(pCollExp);
136 m_stdExp->DetShapeType(), *m_stdExp);
137 m_mat = m_stdExp->GetStdMatrix(key);
138 m_nqe = m_stdExp->GetTotPoints();
140 }
141};
142
143/// Factory initialisation for the IProductWRTBase_StdMat operators
144OperatorKey IProductWRTBase_StdMat::m_typeArr[] = {
146 OperatorKey(eSegment, eIProductWRTBase, eStdMat, false),
147 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Seg"),
149 OperatorKey(eTriangle, eIProductWRTBase, eStdMat, false),
150 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Tri"),
152 OperatorKey(eNodalTri, eIProductWRTBase, eStdMat, true),
153 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_NodalTri"),
155 OperatorKey(eQuadrilateral, eIProductWRTBase, eStdMat, false),
156 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Quad"),
158 OperatorKey(eTetrahedron, eIProductWRTBase, eStdMat, false),
159 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Tet"),
161 OperatorKey(eNodalTet, eIProductWRTBase, eStdMat, true),
162 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_NodalTet"),
164 OperatorKey(ePyramid, eIProductWRTBase, eStdMat, false),
165 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Pyr"),
167 OperatorKey(ePrism, eIProductWRTBase, eStdMat, false),
168 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Prism"),
170 OperatorKey(eNodalPrism, eIProductWRTBase, eStdMat, true),
171 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_NodalPrism"),
173 OperatorKey(eHexahedron, eIProductWRTBase, eStdMat, false),
174 IProductWRTBase_StdMat::create, "IProductWRTBase_StdMat_Hex"),
176 OperatorKey(ePyramid, eIProductWRTBase, eSumFac, false),
177 IProductWRTBase_StdMat::create, "IProductWRTBase_SumFac_Pyr")};
178
179/**
180 * @brief Inner product operator using operator using matrix free operators.
181 */
182class IProductWRTBase_MatrixFree final : virtual public Operator,
184 virtual public IProductWRTBase_Helper
185{
186public:
188
190
191 void operator()(const Array<OneD, const NekDouble> &input,
192 Array<OneD, NekDouble> &output,
193 [[maybe_unused]] Array<OneD, NekDouble> &output1,
194 [[maybe_unused]] Array<OneD, NekDouble> &output2,
195 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
196 {
197 (*m_oper)(input, output);
198 }
199
200 void operator()([[maybe_unused]] int dir,
201 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
202 [[maybe_unused]] Array<OneD, NekDouble> &output,
203 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
204 {
205 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
206 }
207
208private:
209 std::shared_ptr<MatrixFree::IProduct> m_oper;
210
212 vector<LocalRegions::ExpansionSharedPtr> pCollExp,
214 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
215 MatrixFreeBase(pCollExp[0]->GetTotPoints(), pCollExp[0]->GetNcoeffs(),
216 pCollExp.size())
217 {
218 // Basis vector
219 const auto dim = pCollExp[0]->GetShapeDimension();
220 std::vector<LibUtilities::BasisSharedPtr> basis(dim);
221 for (unsigned int i = 0; i < dim; ++i)
222 {
223 basis[i] = pCollExp[0]->GetBasis(i);
224 }
225
226 // Get shape type
227 auto shapeType = pCollExp[0]->DetShapeType();
228
229 // Generate operator string and create operator.
230 std::string op_string = "IProduct";
231 op_string += MatrixFree::GetOpstring(shapeType, m_isDeformed);
232 auto oper = MatrixFree::GetOperatorFactory().CreateInstance(
233 op_string, basis, pCollExp.size());
234
235 oper->SetUpBdata(basis);
236 oper->SetUpZW(basis);
237
238 // Set Jacobian
239 oper->SetJac(pGeomData->GetJacInterLeave(pCollExp, m_nElmtPad));
240
241 m_oper = std::dynamic_pointer_cast<MatrixFree::IProduct>(oper);
242 ASSERTL0(m_oper, "Failed to cast pointer.");
243 }
244};
245
246/// Factory initialisation for the IProductWRTBase_MatrixFree operators
247OperatorKey IProductWRTBase_MatrixFree::m_typeArr[] = {
249 OperatorKey(eSegment, eIProductWRTBase, eMatrixFree, false),
250 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Seg"),
252 OperatorKey(eQuadrilateral, eIProductWRTBase, eMatrixFree, false),
253 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Quad"),
255 OperatorKey(eTriangle, eIProductWRTBase, eMatrixFree, false),
256 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Tri"),
258 OperatorKey(eHexahedron, eIProductWRTBase, eMatrixFree, false),
259 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Hex"),
262 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Prism"),
264 OperatorKey(ePyramid, eIProductWRTBase, eMatrixFree, false),
265 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Pyr"),
267 OperatorKey(eTetrahedron, eIProductWRTBase, eMatrixFree, false),
268 IProductWRTBase_MatrixFree::create, "IProductWRTBase_MatrixFree_Tet")};
269
270/**
271 * @brief Inner product operator using element-wise operation
272 */
273class IProductWRTBase_IterPerExp final : virtual public Operator,
274 virtual public IProductWRTBase_Helper
275{
276public:
278
280
281 void operator()(const Array<OneD, const NekDouble> &input,
282 Array<OneD, NekDouble> &output,
283 [[maybe_unused]] Array<OneD, NekDouble> &output1,
284 [[maybe_unused]] Array<OneD, NekDouble> &output2,
285 Array<OneD, NekDouble> &wsp) final
286 {
287 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
288
289 const int nCoeffs = m_stdExp->GetNcoeffs();
290 const int nPhys = m_stdExp->GetTotPoints();
292
293 if (m_deformed)
294 {
295 Vmath::Vmul(m_jac.size(), m_jac, 1, input, 1, wsp, 1);
296 for (int i = 0; i < m_numElmt; ++i)
297 {
298 m_stdExp->IProductWRTBase(wsp + i * nPhys,
299 tmp = output + i * nCoeffs);
300 }
301 }
302 else
303 {
304 for (int i = 0; i < m_numElmt; ++i)
305 {
306 Vmath::Smul(nPhys, m_jac[i], input + i * nPhys, 1,
307 tmp = wsp + i * nPhys, 1);
308 m_stdExp->IProductWRTBase(wsp + i * nPhys,
309 tmp = output + i * nCoeffs);
310 }
311 }
312 }
313
314 void operator()([[maybe_unused]] int dir,
315 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
316 [[maybe_unused]] Array<OneD, NekDouble> &output,
317 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
318 {
319 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
320 }
321
322protected:
325
326private:
328 vector<LocalRegions::ExpansionSharedPtr> pCollExp,
330 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper()
331 {
332 int nqtot = pCollExp[0]->GetTotPoints();
333
334 m_deformed = (pCollExp[0]->GetGeomFactors()->GetGtype() ==
336 m_jac = pGeomData->GetJac(pCollExp);
337
338 m_wspSize = nqtot * m_numElmt;
339 }
340};
341
342/// Factory initialisation for the IProductWRTBase_IterPerExp operators
343OperatorKey IProductWRTBase_IterPerExp::m_typeArr[] = {
345 OperatorKey(eSegment, eIProductWRTBase, eIterPerExp, false),
346 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Seg"),
348 OperatorKey(eTriangle, eIProductWRTBase, eIterPerExp, false),
349 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Tri"),
351 OperatorKey(eNodalTri, eIProductWRTBase, eIterPerExp, true),
352 IProductWRTBase_IterPerExp::create,
353 "IProductWRTBase_IterPerExp_NodalTri"),
355 OperatorKey(eQuadrilateral, eIProductWRTBase, eIterPerExp, false),
356 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Quad"),
358 OperatorKey(eTetrahedron, eIProductWRTBase, eIterPerExp, false),
359 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Tet"),
361 OperatorKey(eNodalTet, eIProductWRTBase, eIterPerExp, true),
362 IProductWRTBase_IterPerExp::create,
363 "IProductWRTBase_IterPerExp_NodalTet"),
365 OperatorKey(ePyramid, eIProductWRTBase, eIterPerExp, false),
366 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Pyr"),
369 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Prism"),
371 OperatorKey(eNodalPrism, eIProductWRTBase, eIterPerExp, true),
372 IProductWRTBase_IterPerExp::create,
373 "IProductWRTBase_IterPerExp_NodalPrism"),
375 OperatorKey(eHexahedron, eIProductWRTBase, eIterPerExp, false),
376 IProductWRTBase_IterPerExp::create, "IProductWRTBase_IterPerExp_Hex"),
377};
378
379/**
380 * @brief Inner product operator using original MultiRegions implementation.
381 */
382class IProductWRTBase_NoCollection final : virtual public Operator,
383 virtual public IProductWRTBase_Helper
384{
385public:
387
389
390 void operator()(const Array<OneD, const NekDouble> &input,
391 Array<OneD, NekDouble> &output,
392 [[maybe_unused]] Array<OneD, NekDouble> &output1,
393 [[maybe_unused]] Array<OneD, NekDouble> &output2,
394 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
395 {
396 const int nCoeffs = m_expList[0]->GetNcoeffs();
397 const int nPhys = m_expList[0]->GetTotPoints();
399
400 for (int i = 0; i < m_numElmt; ++i)
401 {
402 m_expList[i]->IProductWRTBase(input + i * nPhys,
403 tmp = output + i * nCoeffs);
404 }
405 }
406
407 void operator()([[maybe_unused]] int dir,
408 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
409 [[maybe_unused]] Array<OneD, NekDouble> &output,
410 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
411 {
412 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
413 }
414
415protected:
416 vector<LocalRegions::ExpansionSharedPtr> m_expList;
417
418private:
420 vector<LocalRegions::ExpansionSharedPtr> pCollExp,
422 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper()
423 {
424 m_expList = pCollExp;
425 }
426};
427
428/// Factory initialisation for the IProductWRTBase_NoCollection operators
429OperatorKey IProductWRTBase_NoCollection::m_typeArr[] = {
431 OperatorKey(eSegment, eIProductWRTBase, eNoCollection, false),
432 IProductWRTBase_NoCollection::create,
433 "IProductWRTBase_NoCollection_Seg"),
435 OperatorKey(eTriangle, eIProductWRTBase, eNoCollection, false),
436 IProductWRTBase_NoCollection::create,
437 "IProductWRTBase_NoCollection_Tri"),
439 OperatorKey(eNodalTri, eIProductWRTBase, eNoCollection, true),
440 IProductWRTBase_NoCollection::create,
441 "IProductWRTBase_NoCollection_NodalTri"),
443 OperatorKey(eQuadrilateral, eIProductWRTBase, eNoCollection, false),
444 IProductWRTBase_NoCollection::create,
445 "IProductWRTBase_NoCollection_Quad"),
447 OperatorKey(eTetrahedron, eIProductWRTBase, eNoCollection, false),
448 IProductWRTBase_NoCollection::create,
449 "IProductWRTBase_NoCollection_Tet"),
451 OperatorKey(eNodalTet, eIProductWRTBase, eNoCollection, true),
452 IProductWRTBase_NoCollection::create,
453 "IProductWRTBase_NoCollection_NodalTet"),
455 OperatorKey(ePyramid, eIProductWRTBase, eNoCollection, false),
456 IProductWRTBase_NoCollection::create,
457 "IProductWRTBase_NoCollection_Pyr"),
460 IProductWRTBase_NoCollection::create,
461 "IProductWRTBase_NoCollection_Prism"),
463 OperatorKey(eNodalPrism, eIProductWRTBase, eNoCollection, true),
464 IProductWRTBase_NoCollection::create,
465 "IProductWRTBase_NoCollection_NodalPrism"),
467 OperatorKey(eHexahedron, eIProductWRTBase, eNoCollection, false),
468 IProductWRTBase_NoCollection::create,
469 "IProductWRTBase_NoCollection_Hex"),
470};
471
472/**
473 * @brief Inner product operator using sum-factorisation (Segment)
474 */
475class IProductWRTBase_SumFac_Seg final : virtual public Operator,
476 virtual public IProductWRTBase_Helper
477{
478public:
480
482
483 void operator()(const Array<OneD, const NekDouble> &input,
484 Array<OneD, NekDouble> &output,
485 [[maybe_unused]] Array<OneD, NekDouble> &output1,
486 [[maybe_unused]] Array<OneD, NekDouble> &output2,
487 Array<OneD, NekDouble> &wsp) final
488 {
489 if (m_colldir0)
490 {
491 Vmath::Vmul(m_numElmt * m_nquad0, m_jacWStdW, 1, input, 1, output,
492 1);
493 }
494 else
495 {
496 Vmath::Vmul(m_numElmt * m_nquad0, m_jacWStdW, 1, input, 1, wsp, 1);
497
498 // out = B0*in;
499 Blas::Dgemm('T', 'N', m_nmodes0, m_numElmt, m_nquad0, 1.0,
500 m_base0.data(), m_nquad0, &wsp[0], m_nquad0, 0.0,
501 &output[0], m_nmodes0);
502 }
503 }
504
505 void operator()([[maybe_unused]] int dir,
506 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
507 [[maybe_unused]] Array<OneD, NekDouble> &output,
508 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
509 {
510 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
511 }
512
513protected:
514 const int m_nquad0;
515 const int m_nmodes0;
516 const bool m_colldir0;
519
520private:
522 vector<LocalRegions::ExpansionSharedPtr> pCollExp,
524 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
525 m_nquad0(m_stdExp->GetNumPoints(0)),
526 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
527 m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
528 m_base0(m_stdExp->GetBasis(0)->GetBdata())
529 {
531 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
532 }
533};
534
535/// Factory initialisation for the IProductWRTBase_SumFac_Seg operator
536OperatorKey IProductWRTBase_SumFac_Seg::m_type =
538 OperatorKey(eSegment, eIProductWRTBase, eSumFac, false),
539 IProductWRTBase_SumFac_Seg::create, "IProductWRTBase_SumFac_Seg");
540
541/**
542 * @brief Inner product operator using sum-factorisation (Quad)
543 */
544class IProductWRTBase_SumFac_Quad final : virtual public Operator,
545 virtual public IProductWRTBase_Helper
546{
547public:
549
551
552 void operator()(const Array<OneD, const NekDouble> &input,
553 Array<OneD, NekDouble> &output,
554 [[maybe_unused]] Array<OneD, NekDouble> &output1,
555 [[maybe_unused]] Array<OneD, NekDouble> &output2,
556 Array<OneD, NekDouble> &wsp) final
557 {
558 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
559
562 output, wsp);
563 }
564
565 void operator()([[maybe_unused]] int dir,
566 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
567 [[maybe_unused]] Array<OneD, NekDouble> &output,
568 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
569 {
570 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
571 }
572
573protected:
574 const int m_nquad0;
575 const int m_nquad1;
576 const int m_nmodes0;
577 const int m_nmodes1;
578 const bool m_colldir0;
579 const bool m_colldir1;
583
584private:
586 vector<LocalRegions::ExpansionSharedPtr> pCollExp,
588 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
589 m_nquad0(m_stdExp->GetNumPoints(0)),
590 m_nquad1(m_stdExp->GetNumPoints(1)),
591 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
592 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
593 m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
594 m_colldir1(m_stdExp->GetBasis(1)->Collocation()),
595 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
596 m_base1(m_stdExp->GetBasis(1)->GetBdata())
597 {
598 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
599 m_wspSize =
601 }
602};
603
604/// Factory initialisation for the IProductWRTBase_SumFac_Quad operator
605OperatorKey IProductWRTBase_SumFac_Quad::m_type =
607 OperatorKey(eQuadrilateral, eIProductWRTBase, eSumFac, false),
608 IProductWRTBase_SumFac_Quad::create, "IProductWRTBase_SumFac_Quad");
609
610/**
611 * @brief Inner product operator using sum-factorisation (Tri)
612 */
613class IProductWRTBase_SumFac_Tri final : virtual public Operator,
614 virtual public IProductWRTBase_Helper
615{
616public:
618
620
621 void operator()(const Array<OneD, const NekDouble> &input,
622 Array<OneD, NekDouble> &output,
623 [[maybe_unused]] Array<OneD, NekDouble> &output1,
624 [[maybe_unused]] Array<OneD, NekDouble> &output2,
625 Array<OneD, NekDouble> &wsp) final
626 {
627 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
628
630 m_nmodes1, m_base0, m_base1, m_jacWStdW, input, output,
631 wsp);
632 }
633
634 void operator()([[maybe_unused]] int dir,
635 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
636 [[maybe_unused]] Array<OneD, NekDouble> &output,
637 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
638 {
639 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
640 }
641
642protected:
643 const int m_nquad0;
644 const int m_nquad1;
645 const int m_nmodes0;
646 const int m_nmodes1;
651
652private:
654 vector<LocalRegions::ExpansionSharedPtr> pCollExp,
656 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
657 m_nquad0(m_stdExp->GetNumPoints(0)),
658 m_nquad1(m_stdExp->GetNumPoints(1)),
659 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
660 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
661 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
662 m_base1(m_stdExp->GetBasis(1)->GetBdata())
663 {
664 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
665 m_wspSize =
667 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
668 {
669 m_sortTopVertex = true;
670 }
671 else
672 {
673 m_sortTopVertex = false;
674 }
675 }
676};
677
678/// Factory initialisation for the IProductWRTBase_SumFac_Tri operator
679OperatorKey IProductWRTBase_SumFac_Tri::m_type =
681 OperatorKey(eTriangle, eIProductWRTBase, eSumFac, false),
682 IProductWRTBase_SumFac_Tri::create, "IProductWRTBase_SumFac_Tri");
683
684/**
685 * @brief Inner Product operator using sum-factorisation (Hex)
686 */
687class IProductWRTBase_SumFac_Hex final : virtual public Operator,
688 virtual public IProductWRTBase_Helper
689{
690public:
692
694
695 void operator()(const Array<OneD, const NekDouble> &input,
696 Array<OneD, NekDouble> &output,
697 [[maybe_unused]] Array<OneD, NekDouble> &output1,
698 [[maybe_unused]] Array<OneD, NekDouble> &output2,
699 Array<OneD, NekDouble> &wsp) final
700 {
701 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
702
705 m_base0, m_base1, m_base2, m_jacWStdW, input, output, wsp);
706 }
707
708 void operator()([[maybe_unused]] int dir,
709 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
710 [[maybe_unused]] Array<OneD, NekDouble> &output,
711 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
712 {
713 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
714 }
715
716protected:
717 const int m_nquad0;
718 const int m_nquad1;
719 const int m_nquad2;
720 const int m_nmodes0;
721 const int m_nmodes1;
722 const int m_nmodes2;
723 const bool m_colldir0;
724 const bool m_colldir1;
725 const bool m_colldir2;
730
731private:
733 vector<LocalRegions::ExpansionSharedPtr> pCollExp,
735 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
736 m_nquad0(m_stdExp->GetNumPoints(0)),
737 m_nquad1(m_stdExp->GetNumPoints(1)),
738 m_nquad2(m_stdExp->GetNumPoints(2)),
739 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
740 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
741 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
742 m_colldir0(m_stdExp->GetBasis(0)->Collocation()),
743 m_colldir1(m_stdExp->GetBasis(1)->Collocation()),
744 m_colldir2(m_stdExp->GetBasis(2)->Collocation()),
745 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
746 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
747 m_base2(m_stdExp->GetBasis(2)->GetBdata())
748
749 {
750 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
751 m_wspSize = 3 * m_numElmt *
754 }
755};
756
757/// Factory initialisation for the IProductWRTBase_SumFac_Hex operator
758OperatorKey IProductWRTBase_SumFac_Hex::m_type =
760 OperatorKey(eHexahedron, eIProductWRTBase, eSumFac, false),
761 IProductWRTBase_SumFac_Hex::create, "IProductWRTBase_SumFac_Hex");
762
763/**
764 * @brief Inner product operator using sum-factorisation (Tet)
765 */
766class IProductWRTBase_SumFac_Tet final : virtual public Operator,
767 virtual public IProductWRTBase_Helper
768{
769public:
771
773
774 void operator()(const Array<OneD, const NekDouble> &input,
775 Array<OneD, NekDouble> &output,
776 [[maybe_unused]] Array<OneD, NekDouble> &output1,
777 [[maybe_unused]] Array<OneD, NekDouble> &output2,
778 Array<OneD, NekDouble> &wsp) final
779 {
780 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
781
784 m_jacWStdW, input, output, wsp);
785 }
786
787 void operator()([[maybe_unused]] int dir,
788 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
789 [[maybe_unused]] Array<OneD, NekDouble> &output,
790 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
791 {
792 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
793 }
794
795protected:
796 const int m_nquad0;
797 const int m_nquad1;
798 const int m_nquad2;
799 const int m_nmodes0;
800 const int m_nmodes1;
801 const int m_nmodes2;
807
808private:
810 vector<LocalRegions::ExpansionSharedPtr> pCollExp,
812 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
813 m_nquad0(m_stdExp->GetNumPoints(0)),
814 m_nquad1(m_stdExp->GetNumPoints(1)),
815 m_nquad2(m_stdExp->GetNumPoints(2)),
816 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
817 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
818 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
819 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
820 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
821 m_base2(m_stdExp->GetBasis(2)->GetBdata())
822 {
823 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
824 m_wspSize =
825 m_numElmt *
827 m_nquad2 * m_nmodes0 * (2 * m_nmodes1 - m_nmodes0 + 1) / 2) +
829
830 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
831 {
832 m_sortTopEdge = true;
833 }
834 else
835 {
836 m_sortTopEdge = false;
837 }
838 }
839};
840
841/// Factory initialisation for the IProductWRTBase_SumFac_Tet operator
842OperatorKey IProductWRTBase_SumFac_Tet::m_type =
844 OperatorKey(eTetrahedron, eIProductWRTBase, eSumFac, false),
845 IProductWRTBase_SumFac_Tet::create, "IProductWRTBase_SumFac_Tet");
846
847/**
848 * @brief Inner Product operator using sum-factorisation (Prism)
849 */
850class IProductWRTBase_SumFac_Prism final : virtual public Operator,
852{
853public:
855
857
858 void operator()(const Array<OneD, const NekDouble> &input,
859 Array<OneD, NekDouble> &output,
860 [[maybe_unused]] Array<OneD, NekDouble> &output1,
861 [[maybe_unused]] Array<OneD, NekDouble> &output2,
862 Array<OneD, NekDouble> &wsp) final
863 {
864 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
865
868 m_base2, m_jacWStdW, input, output, wsp);
869 }
870
871 void operator()([[maybe_unused]] int dir,
872 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
873 [[maybe_unused]] Array<OneD, NekDouble> &output,
874 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
875 {
876 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
877 }
878
879protected:
880 const int m_nquad0;
881 const int m_nquad1;
882 const int m_nquad2;
883 const int m_nmodes0;
884 const int m_nmodes1;
885 const int m_nmodes2;
891
892private:
894 vector<LocalRegions::ExpansionSharedPtr> pCollExp,
896 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
897 m_nquad0(m_stdExp->GetNumPoints(0)),
898 m_nquad1(m_stdExp->GetNumPoints(1)),
899 m_nquad2(m_stdExp->GetNumPoints(2)),
900 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
901 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
902 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
903 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
904 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
905 m_base2(m_stdExp->GetBasis(2)->GetBdata())
906
907 {
908 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
909
913
914 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
915 {
916 m_sortTopVertex = true;
917 }
918 else
919 {
920 m_sortTopVertex = false;
921 }
922 }
923};
924
925/// Factory initialisation for the IProductWRTBase_SumFac_Prism operator
926OperatorKey IProductWRTBase_SumFac_Prism::m_type =
928 OperatorKey(ePrism, eIProductWRTBase, eSumFac, false),
929 IProductWRTBase_SumFac_Prism::create, "IProductWRTBase_SumFac_Prism");
930
931/**
932 * @brief Inner Product operator using sum-factorisation (Pyr)
933 */
934class IProductWRTBase_SumFac_Pyr final : virtual public Operator,
936{
937public:
939
941
942 void operator()(const Array<OneD, const NekDouble> &input,
943 Array<OneD, NekDouble> &output,
944 [[maybe_unused]] Array<OneD, NekDouble> &output1,
945 [[maybe_unused]] Array<OneD, NekDouble> &output2,
946 Array<OneD, NekDouble> &wsp) final
947 {
948 ASSERTL1(wsp.size() == m_wspSize, "Incorrect workspace size");
949
952 m_jacWStdW, input, output, wsp);
953 }
954
955 void operator()([[maybe_unused]] int dir,
956 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
957 [[maybe_unused]] Array<OneD, NekDouble> &output,
958 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
959 {
960 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
961 }
962
963protected:
964 const int m_nquad0;
965 const int m_nquad1;
966 const int m_nquad2;
967 const int m_nmodes0;
968 const int m_nmodes1;
969 const int m_nmodes2;
975
976private:
978 vector<LocalRegions::ExpansionSharedPtr> pCollExp,
980 : Operator(pCollExp, pGeomData, factors), IProductWRTBase_Helper(),
981 m_nquad0(m_stdExp->GetNumPoints(0)),
982 m_nquad1(m_stdExp->GetNumPoints(1)),
983 m_nquad2(m_stdExp->GetNumPoints(2)),
984 m_nmodes0(m_stdExp->GetBasisNumModes(0)),
985 m_nmodes1(m_stdExp->GetBasisNumModes(1)),
986 m_nmodes2(m_stdExp->GetBasisNumModes(2)),
987 m_base0(m_stdExp->GetBasis(0)->GetBdata()),
988 m_base1(m_stdExp->GetBasis(1)->GetBdata()),
989 m_base2(m_stdExp->GetBasis(2)->GetBdata())
990
991 {
992 m_jacWStdW = pGeomData->GetJacWithStdWeights(pCollExp);
993
997
998 if (m_stdExp->GetBasis(0)->GetBasisType() == LibUtilities::eModified_A)
999 {
1000 m_sortTopVertex = true;
1001 }
1002 else
1003 {
1004 m_sortTopVertex = false;
1005 }
1006 }
1007};
1008
1009/// Factory initialisation for the IProductWRTBase_SumFac_Pyr operator
1010OperatorKey IProductWRTBase_SumFac_Pyr::m_type =
1012 OperatorKey(ePyramid, eIProductWRTBase, eSumFac, false),
1013 IProductWRTBase_SumFac_Pyr::create, "IProductWRTBase_SumFac_Pyr");
1014
1015} // namespace Nektar::Collections
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#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< LocalRegions::ExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Inner product operator using operator using matrix free operators.
IProductWRTBase_MatrixFree(vector< LocalRegions::ExpansionSharedPtr > 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.
IProductWRTBase_NoCollection(vector< LocalRegions::ExpansionSharedPtr > 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
vector< LocalRegions::ExpansionSharedPtr > m_expList
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< LocalRegions::ExpansionSharedPtr > 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< LocalRegions::ExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Inner Product operator using sum-factorisation (Prism)
IProductWRTBase_SumFac_Prism(vector< LocalRegions::ExpansionSharedPtr > 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 (Pyr)
IProductWRTBase_SumFac_Pyr(vector< LocalRegions::ExpansionSharedPtr > 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)
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
IProductWRTBase_SumFac_Quad(vector< LocalRegions::ExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
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< LocalRegions::ExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Inner product operator using sum-factorisation (Tet)
IProductWRTBase_SumFac_Tet(vector< LocalRegions::ExpansionSharedPtr > 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< LocalRegions::ExpansionSharedPtr > 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:230
unsigned int m_numElmt
number of elements that the operator is applied on
Definition Operator.h:232
unsigned int m_outputSize
number of modes or quadrature points that are taken as output from an operator
Definition Operator.h:240
unsigned int m_inputSize
number of modes or quadrature points that are passed as input to an operator
Definition Operator.h:237
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
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:324
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:406
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:339
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:171
@ eModified_A
Principle Modified Functions .
Definition BasisType.h:48
@ eDeformed
Geometry is curved or has non-constant factors.
ConstFactorMap FactorMap
std::shared_ptr< DNekMat > DNekMatSharedPtr
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.
scalarT< T > max(scalarT< T > lhs, scalarT< T > rhs)
Definition scalar.hpp:305