Nektar++
library/Collections/Helmholtz.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: Helmholtz.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: Helmholtz operator implementations
32//
33///////////////////////////////////////////////////////////////////////////////
34
39#include <MatrixFreeOps/Operator.hpp>
40
41using namespace std;
42
43namespace Nektar::Collections
44{
45
53
54/**
55 * @brief Helmholtz help class to calculate the size of the collection
56 * that is given as an input and as an output to the Helmholtz Operator. The
57 * size evaluation takes into account that the evaluation of the Helmholtz
58 * operator takes input from the coeff space and gives the output in the coeff
59 * space too.
60 */
61class Helmholtz_Helper : virtual public Operator
62{
63protected:
65 {
66 // expect input to be number of elements by the number of coefficients
67 m_inputSize = m_numElmt * m_stdExp->GetNcoeffs();
68 m_inputSizeOther = m_numElmt * m_stdExp->GetTotPoints();
69
70 // expect output to be number of elements by the number of coefficients
71 // computation is from coeff space to coeff space
74 }
75};
76
77/**
78 * @brief Helmholtz operator using LocalRegions implementation.
79 */
81{
82public:
84
85 ~Helmholtz_NoCollection() final = default;
86
87 void operator()(const Array<OneD, const NekDouble> &entry0,
88 Array<OneD, NekDouble> &entry1,
89 [[maybe_unused]] Array<OneD, NekDouble> &entry2,
90 [[maybe_unused]] Array<OneD, NekDouble> &entry3,
91 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
92 {
93 unsigned int nmodes = m_expList[0]->GetNcoeffs();
94 unsigned int nphys = m_expList[0]->GetTotPoints();
96
97 for (int n = 0; n < m_numElmt; ++n)
98 {
99 // Restrict varcoeffs to size of element
101 if (m_varcoeffs.size())
102 {
103 varcoeffs =
104 StdRegions::RestrictCoeffMap(m_varcoeffs, n * nphys, nphys);
105 }
106
108 StdRegions::eHelmholtz, (m_expList)[n]->DetShapeType(),
109 *(m_expList)[n], m_factors, varcoeffs);
110 m_expList[n]->GeneralMatrixOp(entry0 + n * nmodes,
111 tmp = entry1 + n * nmodes, mkey);
112 }
113 }
114
115 void operator()([[maybe_unused]] int dir,
116 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
117 [[maybe_unused]] Array<OneD, NekDouble> &output,
118 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
119 {
120 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
121 }
122
124 {
126 }
127
128 void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
129 {
130 m_varcoeffs = varcoeffs;
131 }
132
133protected:
134 int m_dim;
136 vector<StdRegions::StdExpansionSharedPtr> m_expList;
139
140private:
141 Helmholtz_NoCollection(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
144 : Operator(pCollExp, pGeomData, factors), Helmholtz_Helper()
145 {
146 m_expList = pCollExp;
147 m_dim = pCollExp[0]->GetNumBases();
148 m_coordim = pCollExp[0]->GetCoordim();
149
152 }
153};
154
155/// Factory initialisation for the Helmholtz_NoCollection operators
156OperatorKey Helmholtz_NoCollection::m_typeArr[] = {
159 Helmholtz_NoCollection::create, "Helmholtz_NoCollection_Seg"),
162 Helmholtz_NoCollection::create, "Helmholtz_NoCollection_Tri"),
165 Helmholtz_NoCollection::create, "Helmholtz_NoCollection_NodalTri"),
168 Helmholtz_NoCollection::create, "Helmholtz_NoCollection_Quad"),
171 Helmholtz_NoCollection::create, "Helmholtz_NoCollection_Tet"),
174 Helmholtz_NoCollection::create, "Helmholtz_NoCollection_NodalTet"),
177 Helmholtz_NoCollection::create, "Helmholtz_NoCollection_Pyr"),
180 Helmholtz_NoCollection::create, "Helmholtz_NoCollection_Prism"),
183 Helmholtz_NoCollection::create, "Helmholtz_NoCollection_NodalPrism"),
186 Helmholtz_NoCollection::create, "Helmholtz_NoCollection_Hex")};
187
188/**
189 * @brief Helmholtz operator using LocalRegions implementation.
190 */
191class Helmholtz_IterPerExp final : virtual public Operator, Helmholtz_Helper
192{
193public:
195
196 ~Helmholtz_IterPerExp() final = default;
197
198 void operator()(const Array<OneD, const NekDouble> &input,
199 Array<OneD, NekDouble> &output,
200 [[maybe_unused]] Array<OneD, NekDouble> &output1,
201 [[maybe_unused]] Array<OneD, NekDouble> &output2,
202 Array<OneD, NekDouble> &wsp) final
203 {
204 const int nCoeffs = m_stdExp->GetNcoeffs();
205 const int nPhys = m_stdExp->GetTotPoints();
206
207 ASSERTL1(input.size() >= m_numElmt * nCoeffs,
208 "input array size is insufficient");
209 ASSERTL1(output.size() >= m_numElmt * nCoeffs,
210 "output array size is insufficient");
211
212 Array<OneD, NekDouble> tmpphys, t1;
215
216 tmpphys = wsp;
217 for (int i = 1; i < m_coordim + 1; ++i)
218 {
219 dtmp[i - 1] = wsp + i * nPhys;
220 tmp[i - 1] = wsp + (i + m_coordim) * nPhys;
221 }
222
223 for (int i = 0; i < m_numElmt; ++i)
224 {
225 m_stdExp->BwdTrans(input + i * nCoeffs, tmpphys);
226
227 // local derivative
228 m_stdExp->PhysDeriv(tmpphys, dtmp[0], dtmp[1], dtmp[2]);
229
230 // determine mass matrix term
231 if (m_isDeformed)
232 {
233 Vmath::Vmul(nPhys, m_jac + i * nPhys, 1, tmpphys, 1, tmpphys,
234 1);
235 }
236 else
237 {
238 Vmath::Smul(nPhys, m_jac[i], tmpphys, 1, tmpphys, 1);
239 }
240
241 m_stdExp->IProductWRTBase(tmpphys, t1 = output + i * nCoeffs);
242 Vmath::Smul(nCoeffs, m_lambda, output + i * nCoeffs, 1,
243 t1 = output + i * nCoeffs, 1);
244
245 if (m_isDeformed)
246 {
247 // calculate full derivative
248 for (int j = 0; j < m_coordim; ++j)
249 {
250 Vmath::Vmul(nPhys,
251 m_derivFac[j * m_dim].origin() + i * nPhys, 1,
252 &dtmp[0][0], 1, &tmp[j][0], 1);
253
254 for (int k = 1; k < m_dim; ++k)
255 {
257 nPhys,
258 m_derivFac[j * m_dim + k].origin() + i * nPhys, 1,
259 &dtmp[k][0], 1, &tmp[j][0], 1, &tmp[j][0], 1);
260 }
261 }
262
264 {
265 // calculate dtmp[i] = dx/dxi sum_j diff[0][j] tmp[j]
266 // + dy/dxi sum_j diff[1][j] tmp[j]
267 // + dz/dxi sum_j diff[2][j] tmp[j]
268
269 // First term
270 Vmath::Smul(nPhys, m_diff[0][0], &tmp[0][0], 1, &tmpphys[0],
271 1);
272 for (int l = 1; l < m_coordim; ++l)
273 {
274 Vmath::Svtvp(nPhys, m_diff[0][l], &tmp[l][0], 1,
275 &tmpphys[0], 1, &tmpphys[0], 1);
276 }
277
278 for (int j = 0; j < m_dim; ++j)
279 {
280 Vmath::Vmul(nPhys, m_derivFac[j].origin() + i * nPhys,
281 1, &tmpphys[0], 1, &dtmp[j][0], 1);
282 }
283
284 // Second and third terms
285 for (int k = 1; k < m_coordim; ++k)
286 {
287 Vmath::Smul(nPhys, m_diff[k][0], &tmp[0][0], 1,
288 &tmpphys[0], 1);
289 for (int l = 1; l < m_coordim; ++l)
290 {
291 Vmath::Svtvp(nPhys, m_diff[k][l], &tmp[l][0], 1,
292 &tmpphys[0], 1, &tmpphys[0], 1);
293 }
294
295 for (int j = 0; j < m_dim; ++j)
296 {
297 Vmath::Vvtvp(nPhys,
298 m_derivFac[j + k * m_dim].origin() +
299 i * nPhys,
300 1, &tmpphys[0], 1, &dtmp[j][0], 1,
301 &dtmp[j][0], 1);
302 }
303 }
304 }
305 else
306 {
307 // calculate dx/dxi tmp[0] + dy/dxi tmp[1]
308 // + dz/dxi tmp[2]
309 for (int j = 0; j < m_dim; ++j)
310 {
311 Vmath::Vmul(nPhys, m_derivFac[j].origin() + i * nPhys,
312 1, &tmp[0][0], 1, &dtmp[j][0], 1);
313
314 for (int k = 1; k < m_coordim; ++k)
315 {
316 Vmath::Vvtvp(nPhys,
317 m_derivFac[j + k * m_dim].origin() +
318 i * nPhys,
319 1, &tmp[k][0], 1, &dtmp[j][0], 1,
320 &dtmp[j][0], 1);
321 }
322 }
323 }
324
325 // calculate Iproduct WRT Std Deriv
326 for (int j = 0; j < m_dim; ++j)
327 {
328 // multiply by Jacobian
329 Vmath::Vmul(nPhys, m_jac + i * nPhys, 1, dtmp[j], 1,
330 dtmp[j], 1);
331
332 m_stdExp->IProductWRTDerivBase(j, dtmp[j], tmp[0]);
333 Vmath::Vadd(nCoeffs, tmp[0], 1, output + i * nCoeffs, 1,
334 t1 = output + i * nCoeffs, 1);
335 }
336 }
337 else
338 {
339 // calculate full derivative
340 for (int j = 0; j < m_coordim; ++j)
341 {
342 Vmath::Smul(nPhys, m_derivFac[j * m_dim][i], &dtmp[0][0], 1,
343 &tmp[j][0], 1);
344
345 for (int k = 1; k < m_dim; ++k)
346 {
347 Vmath::Svtvp(nPhys, m_derivFac[j * m_dim + k][i],
348 &dtmp[k][0], 1, &tmp[j][0], 1, &tmp[j][0],
349 1);
350 }
351 }
352
354 {
355 // calculate dtmp[i] = dx/dxi sum_j diff[0][j] tmp[j]
356 // + dy/dxi sum_j diff[1][j] tmp[j]
357 // + dz/dxi sum_j diff[2][j] tmp[j]
358
359 // First term
360 Vmath::Smul(nPhys, m_diff[0][0], &tmp[0][0], 1, &tmpphys[0],
361 1);
362 for (int l = 1; l < m_coordim; ++l)
363 {
364 Vmath::Svtvp(nPhys, m_diff[0][l], &tmp[l][0], 1,
365 &tmpphys[0], 1, &tmpphys[0], 1);
366 }
367
368 for (int j = 0; j < m_dim; ++j)
369 {
370 Vmath::Smul(nPhys, m_derivFac[j][i], &tmpphys[0], 1,
371 &dtmp[j][0], 1);
372 }
373
374 // Second and third terms
375 for (int k = 1; k < m_coordim; ++k)
376 {
377 Vmath::Smul(nPhys, m_diff[k][0], &tmp[0][0], 1,
378 &tmpphys[0], 1);
379 for (int l = 1; l < m_coordim; ++l)
380 {
381 Vmath::Svtvp(nPhys, m_diff[k][l], &tmp[l][0], 1,
382 &tmpphys[0], 1, &tmpphys[0], 1);
383 }
384
385 for (int j = 0; j < m_dim; ++j)
386 {
387 Vmath::Svtvp(nPhys, m_derivFac[j + k * m_dim][i],
388 &tmpphys[0], 1, &dtmp[j][0], 1,
389 &dtmp[j][0], 1);
390 }
391 }
392 }
393 else
394 {
395 // calculate dx/dxi tmp[0] + dy/dxi tmp[2]
396 // + dz/dxi tmp[3]
397 for (int j = 0; j < m_dim; ++j)
398 {
399 Vmath::Smul(nPhys, m_derivFac[j][i], &tmp[0][0], 1,
400 &dtmp[j][0], 1);
401
402 for (int k = 1; k < m_coordim; ++k)
403 {
404 Vmath::Svtvp(nPhys, m_derivFac[j + k * m_dim][i],
405 &tmp[k][0], 1, &dtmp[j][0], 1,
406 &dtmp[j][0], 1);
407 }
408 }
409 }
410
411 // calculate Iproduct WRT Std Deriv
412 for (int j = 0; j < m_dim; ++j)
413 {
414 // multiply by Jacobian
415 Vmath::Smul(nPhys, m_jac[i], dtmp[j], 1, dtmp[j], 1);
416
417 m_stdExp->IProductWRTDerivBase(j, dtmp[j], tmp[0]);
418 Vmath::Vadd(nCoeffs, tmp[0], 1, output + i * nCoeffs, 1,
419 t1 = output + i * nCoeffs, 1);
420 }
421 }
422 }
423 }
424
425 void operator()([[maybe_unused]] int dir,
426 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
427 [[maybe_unused]] Array<OneD, NekDouble> &output,
428 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
429 {
430 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
431 }
432
433 /**
434 * @brief Check the validity of supplied constant factors.
435 *
436 * @param factors Map of factors
437 */
439 {
440 // If match previous factors, nothing to do.
441 if (m_factors == factors)
442 {
443 return;
444 }
445
447
448 // Check Lambda constant of Helmholtz operator
449 auto x = factors.find(StdRegions::eFactorLambda);
450 ASSERTL1(
451 x != factors.end(),
452 "Constant factor not defined: " +
453 std::string(
455 m_lambda = x->second;
456
457 // If varcoeffs not supplied, nothing else to do.
458 m_HasVarCoeffDiff = false;
460 if (d == factors.end())
461 {
462 return;
463 }
464
466 for (int i = 0; i < m_coordim; ++i)
467 {
469 }
470
471 for (int i = 0; i < m_coordim; ++i)
472 {
473 d = factors.find(m_factorCoeffDef[i][i]);
474 if (d != factors.end())
475 {
476 m_diff[i][i] = d->second;
477 }
478 else
479 {
480 m_diff[i][i] = 1.0;
481 }
482
483 for (int j = i + 1; j < m_coordim; ++j)
484 {
485 d = factors.find(m_factorCoeffDef[i][j]);
486 if (d != factors.end())
487 {
488 m_diff[i][j] = m_diff[j][i] = d->second;
489 }
490 }
491 }
492 m_HasVarCoeffDiff = true;
493 }
494
495 /**
496 * @brief Check the validity of supplied variable coefficients.
497 * Note that the m_varcoeffs are not implemented for the IterPerExp
498 * operator.
499 * There exists a specialised implementation for variable diffusion in the
500 * above function UpdateFactors.
501 *
502 * @param varcoeffs Map of varcoeffs
503 */
504 void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
505 {
506 m_varcoeffs = varcoeffs;
507 }
508
509protected:
512 int m_dim;
526
527private:
528 Helmholtz_IterPerExp(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
531 : Operator(pCollExp, pGeomData, factors), Helmholtz_Helper()
532 {
533 m_dim = pCollExp[0]->GetShapeDimension();
534 m_coordim = pCollExp[0]->GetCoordim();
535 int nqtot = m_stdExp->GetTotPoints();
536
537 m_derivFac = pGeomData->GetDerivFactors(pCollExp);
538 m_jac = pGeomData->GetJac(pCollExp);
539 m_wspSize = (2 * m_coordim + 1) * nqtot;
540
541 m_lambda = 1.0;
542 m_HasVarCoeffDiff = false;
545 this->UpdateFactors(factors);
546 }
547};
548
549/// Factory initialisation for the Helmholtz_IterPerExp operators
550OperatorKey Helmholtz_IterPerExp::m_typeArr[] = {
553 Helmholtz_IterPerExp::create, "Helmholtz_IterPerExp_Seg"),
556 Helmholtz_IterPerExp::create, "Helmholtz_IterPerExp_Tri"),
559 Helmholtz_IterPerExp::create, "Helmholtz_IterPerExp_NodalTri"),
562 Helmholtz_IterPerExp::create, "Helmholtz_IterPerExp_Quad"),
565 Helmholtz_IterPerExp::create, "Helmholtz_IterPerExp_Tet"),
568 Helmholtz_IterPerExp::create, "Helmholtz_IterPerExp_NodalTet"),
571 Helmholtz_IterPerExp::create, "Helmholtz_IterPerExp_Pyr"),
574 Helmholtz_IterPerExp::create, "Helmholtz_IterPerExp_Prism"),
577 Helmholtz_IterPerExp::create, "Helmholtz_IterPerExp_NodalPrism"),
580 Helmholtz_IterPerExp::create, "Helmholtz_IterPerExp_Hex")};
581
582/**
583 * @brief Helmholtz operator using matrix free operators.
584 */
585class Helmholtz_MatrixFree final : virtual public Operator,
588{
589public:
591
592 ~Helmholtz_MatrixFree() final = default;
593
594 void operator()(const Array<OneD, const NekDouble> &input,
595 Array<OneD, NekDouble> &output0,
596 [[maybe_unused]] Array<OneD, NekDouble> &output1,
597 [[maybe_unused]] Array<OneD, NekDouble> &output2,
598 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
599 {
600 (*m_oper)(input, output0);
601 }
602
603 void operator()([[maybe_unused]] int dir,
604 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
605 [[maybe_unused]] Array<OneD, NekDouble> &output,
606 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
607 {
608 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
609 }
610
611 /**
612 *
613 */
615 {
616 if (factors == m_factors)
617 {
618 return;
619 }
620
622
623 // Set lambda for this call
624 auto x = factors.find(StdRegions::eFactorLambda);
625 ASSERTL1(
626 x != factors.end(),
627 "Constant factor not defined: " +
628 std::string(
630 m_oper->SetLambda(x->second);
631
632 // set constant diffusion coefficients
633 bool isConstVarDiff = false;
635 diff[0] = diff[2] = diff[5] = 1.0;
636
637 auto xd00 = factors.find(StdRegions::eFactorCoeffD00);
638 if (xd00 != factors.end() && xd00->second != 1.0)
639 {
640 isConstVarDiff = true;
641 diff[0] = xd00->second;
642 }
643
644 auto xd01 = factors.find(StdRegions::eFactorCoeffD01);
645 if (xd01 != factors.end() && xd01->second != 0.0)
646 {
647 isConstVarDiff = true;
648 diff[1] = xd01->second;
649 }
650
651 auto xd11 = factors.find(StdRegions::eFactorCoeffD11);
652 if (xd11 != factors.end() && xd11->second != 1.0)
653 {
654 isConstVarDiff = true;
655 diff[2] = xd11->second;
656 }
657
658 auto xd02 = factors.find(StdRegions::eFactorCoeffD02);
659 if (xd02 != factors.end() && xd02->second != 0.0)
660 {
661 isConstVarDiff = true;
662 diff[3] = xd02->second;
663 }
664
665 auto xd12 = factors.find(StdRegions::eFactorCoeffD12);
666 if (xd12 != factors.end() && xd12->second != 0.0)
667 {
668 isConstVarDiff = true;
669 diff[4] = xd12->second;
670 }
671
672 auto xd22 = factors.find(StdRegions::eFactorCoeffD22);
673 if (xd22 != factors.end() && xd22->second != 1.0)
674 {
675 isConstVarDiff = true;
676 diff[5] = xd22->second;
677 }
678
679 if (isConstVarDiff)
680 {
681 m_oper->SetConstVarDiffusion(diff);
682 }
683
684 // set random here for fn variable diffusion
685 auto k = factors.find(StdRegions::eFactorTau);
686 if (k != factors.end() && k->second != 0.0)
687 {
688 m_oper->SetVarDiffusion(diff);
689 }
690 }
691
692 /**
693 * @brief Check the validity of supplied variable coefficients.
694 * Note that the m_varcoeffs are not implemented for the MatrixFree
695 * operator.
696 * There exists a specialised implementation for variable diffusion in the
697 * above function UpdateFactors.
698 *
699 * @param varcoeffs Map of varcoeffs
700 */
701 void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
702 {
703 m_varcoeffs = varcoeffs;
704 }
705
706private:
707 std::shared_ptr<MatrixFree::Helmholtz> m_oper;
708 unsigned int m_nmtot;
711
712 Helmholtz_MatrixFree(vector<StdRegions::StdExpansionSharedPtr> pCollExp,
715 : Operator(pCollExp, pGeomData, factors),
716 MatrixFreeBase(pCollExp[0]->GetStdExp()->GetNcoeffs(),
717 pCollExp[0]->GetStdExp()->GetNcoeffs(),
718 pCollExp.size()),
720 {
721
722 m_nmtot = m_numElmt * pCollExp[0]->GetStdExp()->GetNcoeffs();
723
724 const auto dim = pCollExp[0]->GetStdExp()->GetShapeDimension();
725
726 // Basis vector.
727 std::vector<LibUtilities::BasisSharedPtr> basis(dim);
728 for (auto i = 0; i < dim; ++i)
729 {
730 basis[i] = pCollExp[0]->GetBasis(i);
731 }
732
733 // Get shape type
734 auto shapeType = pCollExp[0]->GetStdExp()->DetShapeType();
735
736 // Generate operator string and create operator.
737 std::string op_string = "Helmholtz";
738 op_string += MatrixFree::GetOpstring(shapeType, m_isDeformed);
740 op_string, basis, pCollExp.size());
741
742 // Set Jacobian
743 oper->SetJac(pGeomData->GetJacInterLeave(pCollExp, m_nElmtPad));
744
745 // Store derivative factor
746 oper->SetDF(pGeomData->GetDerivFactorsInterLeave(pCollExp, m_nElmtPad));
747
748 oper->SetUpBdata(basis);
749 oper->SetUpDBdata(basis);
750 oper->SetUpZW(basis);
751 oper->SetUpD(basis);
752
753 m_oper = std::dynamic_pointer_cast<MatrixFree::Helmholtz>(oper);
754 ASSERTL0(m_oper, "Failed to cast pointer.");
755
756 // Set factors
759 this->UpdateFactors(factors);
760 }
761};
762
763/// Factory initialisation for the Helmholtz_MatrixFree operators
764OperatorKey Helmholtz_MatrixFree::m_typeArr[] = {
767 Helmholtz_MatrixFree::create, "Helmholtz_MatrixFree_Quad"),
770 Helmholtz_MatrixFree::create, "Helmholtz_MatrixFree_Tri"),
773 Helmholtz_MatrixFree::create, "Helmholtz_MatrixFree_Hex"),
776 Helmholtz_MatrixFree::create, "Helmholtz_MatrixFree_Prism"),
779 Helmholtz_MatrixFree::create, "Helmholtz_MatrixFree_Pyr"),
782 Helmholtz_MatrixFree::create, "Helmholtz_MatrixFree_Tet"),
783};
784
785} // 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
Helmholtz help class to calculate the size of the collection that is given as an input and as an outp...
Helmholtz operator using LocalRegions implementation.
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
void UpdateFactors(StdRegions::FactorMap factors) override
Check the validity of supplied constant factors.
void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
Check the validity of supplied variable coefficients. Note that the m_varcoeffs are not implemented f...
const StdRegions::ConstFactorType m_factorCoeffDef[3][3]
Helmholtz_IterPerExp(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Array< OneD, Array< OneD, NekDouble > > m_diff
Helmholtz operator using matrix free operators.
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
Check the validity of supplied variable coefficients. Note that the m_varcoeffs are not implemented f...
std::shared_ptr< MatrixFree::Helmholtz > m_oper
void UpdateFactors(StdRegions::FactorMap factors) override
Update the supplied factor map.
Helmholtz_MatrixFree(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Helmholtz operator using LocalRegions implementation.
void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
Update the supplied variable coefficients.
Helmholtz_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
void UpdateFactors(StdRegions::FactorMap factors) override
Update the supplied factor map.
vector< StdRegions::StdExpansionSharedPtr > m_expList
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_outputSizeOther
Number of modes or quadrature points, opposite to m_outputSize.
Definition: Operator.h:231
unsigned int m_numElmt
number of elements that the operator is applied on
Definition: Operator.h:219
unsigned int m_inputSizeOther
Number of modes or quadrature points, opposite to m_inputSize.
Definition: Operator.h:229
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.
std::tuple< LibUtilities::ShapeType, OperatorType, ImplementationType, ExpansionIsNodal > OperatorKey
Key for describing an Operator.
Definition: Operator.h:120
std::shared_ptr< CoalescedGeomData > CoalescedGeomDataSharedPtr
OperatorFactory & GetOperatorFactory()
Returns the singleton Operator factory object.
Definition: Operator.cpp:44
const NekPoint< NekDouble > origin
static FactorMap NullFactorMap
Definition: StdRegions.hpp:435
const char *const ConstFactorTypeMap[]
Definition: StdRegions.hpp:413
VarCoeffMap RestrictCoeffMap(const VarCoeffMap &m, size_t offset, size_t cnt)
Definition: StdRegions.hpp:378
ConstFactorMap FactorMap
Definition: StdRegions.hpp:434
static VarCoeffMap NullVarCoeffMap
Definition: StdRegions.hpp:376
std::map< StdRegions::VarCoeffType, VarCoeffEntry > VarCoeffMap
Definition: StdRegions.hpp:375
std::vector< double > d(NPUPPER *NPUPPER)
StdRegions::ConstFactorMap factors
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 Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Svtvp (scalar times vector plus vector): z = alpha*x + y.
Definition: Vmath.hpp:396
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
Definition: Vmath.hpp:366
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.hpp:180
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.