Nektar++
LinearAdvectionDiffusionReaction.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: LinearAdvectionDiffusionReaction.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: LinearAdvectionDiffusionReaction operator implementations
32//
33///////////////////////////////////////////////////////////////////////////////
34
39#include <MatrixFreeOps/Operator.hpp>
40
41using namespace std;
42
43namespace Nektar::Collections
44{
45
53
54/**
55 * @brief LinearAdvectionDiffusionReaction help class to calculate the size of
56 * the collection that is given as an input and as an output to the
57 * LinearAdvectionDiffusionReaction Operator. The size evaluation takes into
58 * account that the evaluation of the LinearAdvectionDiffusionReaction operator
59 * takes input from the coeff space and gives the output in the coeff space too.
60 */
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 LinearAdvectionDiffusionReaction operator using LocalRegions
79 * implementation.
80 */
82 : virtual public Operator,
84{
85public:
87
89
90 void operator()(const Array<OneD, const NekDouble> &entry0,
91 Array<OneD, NekDouble> &entry1,
92 [[maybe_unused]] Array<OneD, NekDouble> &entry2,
93 [[maybe_unused]] Array<OneD, NekDouble> &entry3,
94 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
95 {
96 unsigned int nmodes = m_expList[0]->GetNcoeffs();
97 unsigned int nphys = m_expList[0]->GetTotPoints();
99
100 for (int n = 0; n < m_numElmt; ++n)
101 {
102 // Restrict varcoeffs to size of element
104 if (m_varcoeffs.size())
105 {
106 varcoeffs =
107 StdRegions::RestrictCoeffMap(m_varcoeffs, n * nphys, nphys);
108 }
109
112 (m_expList)[n]->DetShapeType(), *(m_expList)[n], m_factors,
113 varcoeffs);
114 m_expList[n]->GeneralMatrixOp(entry0 + n * nmodes,
115 tmp = entry1 + n * nmodes, mkey);
116 }
117 }
118
119 void operator()([[maybe_unused]] int dir,
120 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
121 [[maybe_unused]] Array<OneD, NekDouble> &output,
122 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
123 {
124 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
125 }
126
128 {
130 }
131
132 /**
133 * @brief Check whether necessary advection velocities are supplied
134 * and copy into local member for varcoeff map.
135 *
136 * @param varcoeffs Map of variable coefficients
137 */
138 void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
139 {
140 m_varcoeffs = varcoeffs;
141 }
142
143protected:
144 int m_dim;
146 vector<StdRegions::StdExpansionSharedPtr> m_expList;
149
150private:
152 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
154 : Operator(pCollExp, pGeomData, factors),
156 {
157 m_expList = pCollExp;
158 m_dim = pCollExp[0]->GetNumBases();
159 m_coordim = pCollExp[0]->GetCoordim();
160
163 }
164};
165
166/// Factory initialisation for the LinearAdvectionDiffusionReaction_NoCollection
167/// operators
168OperatorKey LinearAdvectionDiffusionReaction_NoCollection::m_typeArr[] = {
171 false),
172 LinearAdvectionDiffusionReaction_NoCollection::create,
173 "LinearAdvectionDiffusionReaction_NoCollection_Seg"),
176 false),
177 LinearAdvectionDiffusionReaction_NoCollection::create,
178 "LinearAdvectionDiffusionReaction_NoCollection_Tri"),
181 true),
182 LinearAdvectionDiffusionReaction_NoCollection::create,
183 "LinearAdvectionDiffusionReaction_NoCollection_NodalTri"),
186 eNoCollection, false),
187 LinearAdvectionDiffusionReaction_NoCollection::create,
188 "LinearAdvectionDiffusionReaction_NoCollection_Quad"),
191 eNoCollection, false),
192 LinearAdvectionDiffusionReaction_NoCollection::create,
193 "LinearAdvectionDiffusionReaction_NoCollection_Tet"),
196 eNoCollection, true),
197 LinearAdvectionDiffusionReaction_NoCollection::create,
198 "LinearAdvectionDiffusionReaction_NoCollection_NodalTet"),
201 false),
202 LinearAdvectionDiffusionReaction_NoCollection::create,
203 "LinearAdvectionDiffusionReaction_NoCollection_Pyr"),
206 false),
207 LinearAdvectionDiffusionReaction_NoCollection::create,
208 "LinearAdvectionDiffusionReaction_NoCollection_Prism"),
211 true),
212 LinearAdvectionDiffusionReaction_NoCollection::create,
213 "LinearAdvectionDiffusionReaction_NoCollection_NodalPrism"),
216 eNoCollection, false),
217 LinearAdvectionDiffusionReaction_NoCollection::create,
218 "LinearAdvectionDiffusionReaction_NoCollection_Hex")};
219
220/**
221 * @brief LinearAdvectionDiffusionReaction operator using LocalRegions
222 * implementation.
223 */
225 : virtual public Operator,
227{
228public:
230
232
233 void operator()(const Array<OneD, const NekDouble> &input,
234 Array<OneD, NekDouble> &output,
235 [[maybe_unused]] Array<OneD, NekDouble> &output1,
236 [[maybe_unused]] Array<OneD, NekDouble> &output2,
237 Array<OneD, NekDouble> &wsp) final
238 {
239 const int nCoeffs = m_stdExp->GetNcoeffs();
240 const int nPhys = m_stdExp->GetTotPoints();
241
242 ASSERTL1(input.size() >= m_numElmt * nCoeffs,
243 "input array size is insufficient");
244 ASSERTL1(output.size() >= m_numElmt * nCoeffs,
245 "output array size is insufficient");
246
247 Array<OneD, NekDouble> tmpphys, t1;
250
251 tmpphys = wsp;
252 for (int i = 1; i < m_coordim + 1; ++i)
253 {
254 dtmp[i - 1] = wsp + i * nPhys;
255 tmp[i - 1] = wsp + (i + m_coordim) * nPhys;
256 }
257
258 for (int i = 0; i < m_numElmt; ++i)
259 {
260 // Std u
261 m_stdExp->BwdTrans(input + i * nCoeffs, tmpphys);
262
263 // Std \nabla u
264 m_stdExp->PhysDeriv(tmpphys, dtmp[0], dtmp[1], dtmp[2]);
265
266 // Transform Std \nabla u -> Local \nabla u
267 // tmp[0] = dxi1/dx du/dxi1 + dxi2/dx du/dxi2 = du / dx
268 // tmp[1] = dxi1/dy du/dxi1 + dxi2/dy du/dxi2 = du / dy
269 if (m_isDeformed)
270 {
271 for (int j = 0; j < m_coordim; ++j)
272 {
273 Vmath::Vmul(nPhys,
274 m_derivFac[j * m_dim].origin() + i * nPhys, 1,
275 &dtmp[0][0], 1, &tmp[j][0], 1);
276
277 for (int k = 1; k < m_dim; ++k)
278 {
280 nPhys,
281 m_derivFac[j * m_dim + k].origin() + i * nPhys, 1,
282 &dtmp[k][0], 1, &tmp[j][0], 1, &tmp[j][0], 1);
283 }
284 }
285 }
286 else
287 {
288 for (int j = 0; j < m_coordim; ++j)
289 {
290 Vmath::Smul(nPhys, m_derivFac[j * m_dim][i], &dtmp[0][0], 1,
291 &tmp[j][0], 1);
292
293 for (int k = 1; k < m_dim; ++k)
294 {
295 Vmath::Svtvp(nPhys, m_derivFac[j * m_dim + k][i],
296 &dtmp[k][0], 1, &tmp[j][0], 1, &tmp[j][0],
297 1);
298 }
299 }
300 }
301
302 /// Mass term
303 // tmpphys *= \lambda = \lambda u
304 Vmath::Smul(nPhys, -m_lambda, tmpphys, 1, tmpphys, 1);
305
306 /// Add advection term
307 // tmpphys += V[0] * du / dx + V[1] * du / dy
308 for (int j = 0; j < m_coordim; ++j)
309 {
310 Vmath::Vvtvp(nPhys, m_advVel[j] + i * nPhys, 1, tmp[j], 1,
311 tmpphys, 1, tmpphys, 1);
312 }
313
314 // Multiply by Jacobian for inner product
315 if (m_isDeformed)
316 {
317 Vmath::Vmul(nPhys, m_jac + i * nPhys, 1, tmpphys, 1, tmpphys,
318 1);
319 }
320 else
321 {
322 Vmath::Smul(nPhys, m_jac[i], tmpphys, 1, tmpphys, 1);
323 }
324
325 // Compute inner product wrt base
326 m_stdExp->IProductWRTBase(tmpphys, t1 = output + i * nCoeffs);
327
328 /// Determine Laplacian term
329 // add derivFactors for IProdWRTDerivBase below
330 // dtmp[0] = dxi1/dx du/dx + dxi1/dy du/dy
331 // dtmp[1] = dxi2/dx du/dx + dxi2/dy du/dy
332 if (m_isDeformed)
333 {
334 for (int j = 0; j < m_dim; ++j)
335 {
336 Vmath::Vmul(nPhys, m_derivFac[j].origin() + i * nPhys, 1,
337 &tmp[0][0], 1, &dtmp[j][0], 1);
338
339 for (int k = 1; k < m_coordim; ++k)
340 {
342 nPhys,
343 m_derivFac[j + k * m_dim].origin() + i * nPhys, 1,
344 &tmp[k][0], 1, &dtmp[j][0], 1, &dtmp[j][0], 1);
345 }
346 }
347
348 // calculate Iproduct WRT Std Deriv
349 for (int j = 0; j < m_dim; ++j)
350 {
351
352 // multiply by Jacobian
353 Vmath::Vmul(nPhys, m_jac + i * nPhys, 1, dtmp[j], 1,
354 dtmp[j], 1);
355
356 m_stdExp->IProductWRTDerivBase(j, dtmp[j], tmp[0]);
357 Vmath::Vadd(nCoeffs, tmp[0], 1, output + i * nCoeffs, 1,
358 t1 = output + i * nCoeffs, 1);
359 }
360 }
361 else
362 {
363 for (int j = 0; j < m_dim; ++j)
364 {
365 Vmath::Smul(nPhys, m_derivFac[j][i], &tmp[0][0], 1,
366 &dtmp[j][0], 1);
367
368 for (int k = 1; k < m_coordim; ++k)
369 {
370 Vmath::Svtvp(nPhys, m_derivFac[j + k * m_dim][i],
371 &tmp[k][0], 1, &dtmp[j][0], 1, &dtmp[j][0],
372 1);
373 }
374 }
375
376 // calculate Iproduct WRT Std Deriv
377 for (int j = 0; j < m_dim; ++j)
378 {
379 // multiply by Jacobian for integration
380 Vmath::Smul(nPhys, m_jac[i], dtmp[j], 1, dtmp[j], 1);
381
382 m_stdExp->IProductWRTDerivBase(j, dtmp[j], tmp[0]);
383 Vmath::Vadd(nCoeffs, tmp[0], 1, output + i * nCoeffs, 1,
384 t1 = output + i * nCoeffs, 1);
385 }
386 }
387 }
388 }
389
390 void operator()([[maybe_unused]] int dir,
391 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
392 [[maybe_unused]] Array<OneD, NekDouble> &output,
393 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
394 {
395 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
396 }
397
398 /**
399 * @brief Check the validity of supplied constant factors.
400 *
401 * @param factors Map of factors
402 */
404 {
406
407 // Check Lambda constant of LinearAdvectionDiffusionReaction operator
408 auto x = factors.find(StdRegions::eFactorLambda);
409 ASSERTL1(
410 x != factors.end(),
411 "Constant factor not defined: " +
412 std::string(
414 m_lambda = x->second;
415 }
416
417 /**
418 * @brief Check whether necessary advection velocities are supplied
419 * and copy into local array for operator.
420 *
421 * @param varcoeffs Map of variable coefficients
422 */
423 void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
424 {
425 // Check whether any varcoeffs are provided
426 if (varcoeffs.empty())
427 {
428 return;
429 }
430
431 // Check advection velocities count
432 int ndir = 0;
433 for (auto &x : advVelTypes)
434 {
435 if (varcoeffs.count(x))
436 {
437 ndir++;
438 }
439 }
440 ASSERTL0(ndir, "Must define at least one advection velocity");
441 ASSERTL1(ndir <= m_coordim,
442 "Number of constants is larger than coordinate dimensions");
443
444 // Copy new varcoeffs
445 m_varcoeffs = varcoeffs;
446
447 // Hold advection velocity reference
448 // separate copy required for operator
449 for (int i = 0; i < m_coordim; i++)
450 {
451 m_advVel[i] = m_varcoeffs.find(advVelTypes[i])->second.GetValue();
452 }
453 }
454
455protected:
458 int m_dim;
467
468private:
470 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
472 : Operator(pCollExp, pGeomData, factors),
474 {
475 m_dim = pCollExp[0]->GetShapeDimension();
476 m_coordim = pCollExp[0]->GetCoordim();
477 int nqtot = m_stdExp->GetTotPoints();
478
479 m_derivFac = pGeomData->GetDerivFactors(pCollExp);
480 m_jac = pGeomData->GetJac(pCollExp);
481 m_wspSize = (2 * m_coordim + 1) * nqtot;
482
483 m_lambda = 1.0;
487 this->UpdateFactors(factors);
488 }
489};
490
491/// Factory initialisation for the
492/// LinearAdvectionDiffusionReaction_IterPerExp
493OperatorKey LinearAdvectionDiffusionReaction_IterPerExp::m_typeArr[] = {
496 false),
497 LinearAdvectionDiffusionReaction_IterPerExp::create,
498 "LinearAdvectionDiffusionReaction_IterPerExp_Seg"),
501 false),
502 LinearAdvectionDiffusionReaction_IterPerExp::create,
503 "LinearAdvectionDiffusionReaction_IterPerExp_Tri"),
506 true),
507 LinearAdvectionDiffusionReaction_IterPerExp::create,
508 "LinearAdvectionDiffusionReaction_IterPerExp_NodalTri"),
511 eIterPerExp, false),
512 LinearAdvectionDiffusionReaction_IterPerExp::create,
513 "LinearAdvectionDiffusionReaction_IterPerExp_Quad"),
516 eIterPerExp, false),
517 LinearAdvectionDiffusionReaction_IterPerExp::create,
518 "LinearAdvectionDiffusionReaction_IterPerExp_Tet"),
521 eIterPerExp, true),
522 LinearAdvectionDiffusionReaction_IterPerExp::create,
523 "LinearAdvectionDiffusionReaction_IterPerExp_NodalTet"),
526 false),
527 LinearAdvectionDiffusionReaction_IterPerExp::create,
528 "LinearAdvectionDiffusionReaction_IterPerExp_Pyr"),
531 false),
532 LinearAdvectionDiffusionReaction_IterPerExp::create,
533 "LinearAdvectionDiffusionReaction_IterPerExp_Prism"),
536 true),
537 LinearAdvectionDiffusionReaction_IterPerExp::create,
538 "LinearAdvectionDiffusionReaction_IterPerExp_NodalPrism"),
541 false),
542 LinearAdvectionDiffusionReaction_IterPerExp::create,
543 "LinearAdvectionDiffusionReaction_IterPerExp_Hex")};
544
545/*
546 * @brief LinearAdvectionDiffusionReaction operator using matrix free
547 * operators.
548 */
550 : virtual public Operator,
553{
554public:
556
558
559 void operator()(const Array<OneD, const NekDouble> &input,
560 Array<OneD, NekDouble> &output0,
561 [[maybe_unused]] Array<OneD, NekDouble> &output1,
562 [[maybe_unused]] Array<OneD, NekDouble> &output2,
563 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
564 {
565 if (m_isPadded)
566 {
567 // copy into padded vector
568 Vmath::Vcopy(m_nmtot, input, 1, m_input, 1);
569 (*m_oper)(m_input, m_output);
570 Vmath::Vcopy(m_nmtot, m_output, 1, output0, 1);
571 }
572 else
573 {
574 (*m_oper)(input, output0);
575 }
576 }
577
578 void operator()([[maybe_unused]] int dir,
579 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
580 [[maybe_unused]] Array<OneD, NekDouble> &output,
581 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
582 {
583 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
584 }
585
586 /**
587 *
588 */
590 {
592
593 // Set lambda for this call
594 auto x = factors.find(StdRegions::eFactorLambda);
595 ASSERTL1(
596 x != factors.end(),
597 "Constant factor not defined: " +
598 std::string(
600 m_oper->SetLambda(-1 * x->second);
601 }
602
603 /**
604 * @brief Check whether necessary advection velocities are supplied,
605 * interleave and copy into vectorised containers.
606 *
607 * @param varcoeffs Map of variable coefficients
608 */
609 void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
610 {
611 // Check varcoeffs empty?
612 if (varcoeffs.empty())
613 {
614 return;
615 }
616
617 // Check whether varcoeffs need update (copied from
618 // GlobalMatrixKey.cpp) This is essential to only do the update +
619 // interleaving after each time step instead of doing it every time
620 // we apply the operator.
621 bool update = false;
622 if (m_varcoeffs.size() < varcoeffs.size())
623 {
624 update = true;
625 }
626 else if (m_varcoeffs.size() > varcoeffs.size())
627 {
628 update = true;
629 }
630 else
631 {
632 StdRegions::VarCoeffMap::const_iterator x, y;
633 for (x = m_varcoeffs.begin(), y = varcoeffs.begin();
634 x != m_varcoeffs.end(); ++x, ++y)
635 {
636 if (x->second.GetHash() < y->second.GetHash())
637 {
638 update = true;
639 break;
640 }
641 if (x->second.GetHash() > y->second.GetHash())
642 {
643 update = true;
644 break;
645 }
646 }
647 }
648 // return if no update required
649 if (!update)
650 {
651 return;
652 }
653 // else copy
654 m_varcoeffs = varcoeffs;
655
656 // Check advection velocities count
657 int ndir = 0;
658 for (auto &x : advVelTypes)
659 {
660 if (m_varcoeffs.count(x))
661 {
662 ndir++;
663 }
664 }
665 ASSERTL0(ndir, "Must define at least one advection velocity");
666 ASSERTL1(ndir <= m_coordim,
667 "Number of constants is larger than coordinate dimensions");
668
669 // Extract advection velocities, interleave and pass to
670 // libMatrixFree Multiply by -1/lambda for combined (Mass +
671 // Advection) IProduct operation in MatrixFree/AdvectionKernel
672 auto lambda = m_factors.find(StdRegions::eFactorLambda);
674 for (int i = 0; i < m_coordim; i++)
675 {
676 advVel[i] = Array<OneD, NekDouble>(
677 m_varcoeffs.find(advVelTypes[i])->second.GetValue());
678 Vmath::Smul(advVel[i].size(), -1 / lambda->second, advVel[i], 1,
679 advVel[i], 1);
680 }
681
682 // Interleave Advection Velocities
683 using namespace tinysimd;
684 using vec_t = simd<NekDouble>;
685 typedef std::vector<vec_t, tinysimd::allocator<vec_t>> VecVec_t;
686
687 // Arguments of GetDerivFactorsInterLeave function
688 int nElmt = m_nElmtPad;
689
690 ASSERTL1(nElmt % vec_t::width == 0,
691 "Number of elements not divisible by vector "
692 "width, padding not yet implemented.");
693
694 int nBlocks = nElmt / vec_t::width;
695
696 unsigned int n_vel = m_coordim;
697 alignas(vec_t::alignment) NekDouble vec[vec_t::width];
698
699 VecVec_t newAdvVel;
700 int nq = m_nqtot / m_numElmt;
701 int totalsize = m_nqtot; // nq * n_vel;
702
703 // The advection velocity varies at every quad point
704 // It is independent of DEFORMED
705 newAdvVel.resize(nBlocks * n_vel * nq);
706 auto *advVel_ptr = &newAdvVel[0];
707 for (int e = 0; e < nBlocks; ++e)
708 {
709 for (int q = 0; q < nq; q++)
710 {
711 for (int dir = 0; dir < n_vel; ++dir, ++advVel_ptr)
712 {
713 for (int j = 0; j < vec_t::width; ++j)
714 {
715 if ((vec_t::width * e + j) * nq + q < totalsize)
716 {
717 vec[j] =
718 advVel[dir][(vec_t::width * e + j) * nq + q];
719 }
720 else
721 {
722 vec[j] = 0.0;
723 }
724 }
725 (*advVel_ptr).load(&vec[0]);
726 }
727 }
728 }
729
730 m_oper->SetAdvectionVelocities(
732 }
733
734private:
735 std::shared_ptr<MatrixFree::LinearAdvectionDiffusionReaction> m_oper;
736 unsigned int m_nmtot;
737 unsigned int m_nqtot;
744
746 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
748 : Operator(pCollExp, pGeomData, factors),
749 MatrixFreeOneInOneOut(pCollExp[0]->GetStdExp()->GetNcoeffs(),
750 pCollExp[0]->GetStdExp()->GetNcoeffs(),
751 pCollExp.size()),
753 {
754 m_nmtot = m_numElmt * pCollExp[0]->GetStdExp()->GetNcoeffs();
755
756 const auto dim = pCollExp[0]->GetStdExp()->GetShapeDimension();
757 m_coordim = dim;
758
759 // Basis vector.
760 std::vector<LibUtilities::BasisSharedPtr> basis(dim);
761 for (auto i = 0; i < dim; ++i)
762 {
763 basis[i] = pCollExp[0]->GetBasis(i);
764 }
765
766 // Get shape type
767 auto shapeType = pCollExp[0]->GetStdExp()->DetShapeType();
768
769 // Generate operator string and create operator.
770 std::string op_string = "LinearAdvectionDiffusionReaction";
771 op_string += MatrixFree::GetOpstring(shapeType, m_isDeformed);
773 op_string, basis, m_nElmtPad);
774
775 // Get N quadpoints with padding
776 m_nqtot = m_numElmt * pCollExp[0]->GetStdExp()->GetTotPoints();
777
778 // Set Jacobian
779 oper->SetJac(pGeomData->GetJacInterLeave(pCollExp, m_nElmtPad));
780
781 // Store derivative factor
782 oper->SetDF(pGeomData->GetDerivFactorsInterLeave(pCollExp, m_nElmtPad));
783
784 m_oper = std::dynamic_pointer_cast<
785 MatrixFree::LinearAdvectionDiffusionReaction>(oper);
786 ASSERTL0(m_oper, "Failed to cast pointer.");
787
788 // Set factors
791 this->UpdateFactors(factors);
792 }
793};
794
795/// Factory initialisation for the
796/// LinearAdvectionDiffusionReaction_MatrixFree operators
797OperatorKey LinearAdvectionDiffusionReaction_MatrixFree::m_typeArr[] = {
800 eMatrixFree, false),
801 LinearAdvectionDiffusionReaction_MatrixFree::create,
802 "LinearAdvectionDiffusionReaction_MatrixFree_Quad"),
805 false),
806 LinearAdvectionDiffusionReaction_MatrixFree::create,
807 "LinearAdvectionDiffusionReaction_MatrixFree_Tri"),
810 false),
811 LinearAdvectionDiffusionReaction_MatrixFree::create,
812 "LinearAdvectionDiffusionReaction_MatrixFree_Hex"),
815 false),
816 LinearAdvectionDiffusionReaction_MatrixFree::create,
817 "LinearAdvectionDiffusionReaction_MatrixFree_Prism"),
820 false),
821 LinearAdvectionDiffusionReaction_MatrixFree::create,
822 "LinearAdvectionDiffusionReaction_MatrixFree_Pyr"),
825 eMatrixFree, false),
826 LinearAdvectionDiffusionReaction_MatrixFree::create,
827 "LinearAdvectionDiffusionReaction_MatrixFree_Tet"),
828};
829
830} // 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
LinearAdvectionDiffusionReaction help class to calculate the size of the collection that is given as ...
LinearAdvectionDiffusionReaction operator using LocalRegions implementation.
void UpdateFactors(StdRegions::FactorMap factors) override
Check the validity of supplied constant factors.
LinearAdvectionDiffusionReaction_IterPerExp(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
Check whether necessary advection velocities are supplied and copy into local array for operator.
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
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 whether necessary advection velocities are supplied, interleave and copy into vectorised contai...
std::shared_ptr< MatrixFree::LinearAdvectionDiffusionReaction > m_oper
void UpdateFactors(StdRegions::FactorMap factors) override
Update the supplied factor map.
LinearAdvectionDiffusionReaction_MatrixFree(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
LinearAdvectionDiffusionReaction operator using LocalRegions implementation.
void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
Check whether necessary advection velocities are supplied and copy into local member for varcoeff map...
void UpdateFactors(StdRegions::FactorMap factors) override
Update the supplied factor map.
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
LinearAdvectionDiffusionReaction_NoCollection(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
unsigned int m_nElmtPad
size after padding
Array< OneD, NekDouble > m_input
padded input/output vectors
Base class for operators on a collection of elements.
Definition: Operator.h:138
StdRegions::StdExpansionSharedPtr m_stdExp
Definition: Operator.h:217
unsigned int m_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.
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
std::vector< vec_t, tinysimd::allocator< vec_t > > VecVec_t
simd< NekDouble > vec_t
@ eLinearAdvectionDiffusionReaction
Definition: Operator.h:66
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 > q(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
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.hpp:825
STL namespace.
typename abi< ScalarType, width >::type simd
Definition: tinysimd.hpp:80