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 (*m_oper)(input, output0);
566 }
567
568 void operator()([[maybe_unused]] int dir,
569 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
570 [[maybe_unused]] Array<OneD, NekDouble> &output,
571 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
572 {
573 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
574 }
575
576 /**
577 *
578 */
580 {
582
583 // Set lambda for this call
584 auto x = factors.find(StdRegions::eFactorLambda);
585 ASSERTL1(
586 x != factors.end(),
587 "Constant factor not defined: " +
588 std::string(
590 m_oper->SetLambda(-1 * x->second);
591 }
592
593 /**
594 * @brief Check whether necessary advection velocities are supplied,
595 * interleave and copy into vectorised containers.
596 *
597 * @param varcoeffs Map of variable coefficients
598 */
599 void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
600 {
601 // Check varcoeffs empty?
602 if (varcoeffs.empty())
603 {
604 return;
605 }
606
607 // Check whether varcoeffs need update (copied from
608 // GlobalMatrixKey.cpp) This is essential to only do the update +
609 // interleaving after each time step instead of doing it every time
610 // we apply the operator.
611 bool update = false;
612 if (m_varcoeffs.size() < varcoeffs.size())
613 {
614 update = true;
615 }
616 else if (m_varcoeffs.size() > varcoeffs.size())
617 {
618 update = true;
619 }
620 else
621 {
622 StdRegions::VarCoeffMap::const_iterator x, y;
623 for (x = m_varcoeffs.begin(), y = varcoeffs.begin();
624 x != m_varcoeffs.end(); ++x, ++y)
625 {
626 if (x->second.GetHash() < y->second.GetHash())
627 {
628 update = true;
629 break;
630 }
631 if (x->second.GetHash() > y->second.GetHash())
632 {
633 update = true;
634 break;
635 }
636 }
637 }
638 // return if no update required
639 if (!update)
640 {
641 return;
642 }
643 // else copy
644 m_varcoeffs = varcoeffs;
645
646 // Check advection velocities count
647 int ndir = 0;
648 for (auto &x : advVelTypes)
649 {
650 if (m_varcoeffs.count(x))
651 {
652 ndir++;
653 }
654 }
655 ASSERTL0(ndir, "Must define at least one advection velocity");
656 ASSERTL1(ndir <= m_coordim,
657 "Number of constants is larger than coordinate dimensions");
658
659 // Extract advection velocities, interleave and pass to
660 // libMatrixFree Multiply by -1/lambda for combined (Mass +
661 // Advection) IProduct operation in MatrixFree/AdvectionKernel
662 auto lambda = m_factors.find(StdRegions::eFactorLambda);
664 for (int i = 0; i < m_coordim; i++)
665 {
666 advVel[i] = Array<OneD, NekDouble>(
667 m_varcoeffs.find(advVelTypes[i])->second.GetValue());
668 Vmath::Smul(advVel[i].size(), -1 / lambda->second, advVel[i], 1,
669 advVel[i], 1);
670 }
671
672 // Interleave Advection Velocities
673 using namespace tinysimd;
674 using vec_t = simd<NekDouble>;
675 typedef std::vector<vec_t, tinysimd::allocator<vec_t>> VecVec_t;
676
677 // Arguments of GetDerivFactorsInterLeave function
678 int nElmt = m_nElmtPad;
679
680 ASSERTL1(nElmt % vec_t::width == 0,
681 "Number of elements not divisible by vector "
682 "width, padding not yet implemented.");
683
684 int nBlocks = nElmt / vec_t::width;
685
686 unsigned int n_vel = m_coordim;
687 alignas(vec_t::alignment) NekDouble vec[vec_t::width];
688
689 VecVec_t newAdvVel;
690 int nq = m_nqtot / m_numElmt;
691 int totalsize = m_nqtot; // nq * n_vel;
692
693 // The advection velocity varies at every quad point
694 // It is independent of DEFORMED
695 newAdvVel.resize(nBlocks * n_vel * nq);
696 auto *advVel_ptr = &newAdvVel[0];
697 for (int e = 0; e < nBlocks; ++e)
698 {
699 for (int q = 0; q < nq; q++)
700 {
701 for (int dir = 0; dir < n_vel; ++dir, ++advVel_ptr)
702 {
703 for (int j = 0; j < vec_t::width; ++j)
704 {
705 if ((vec_t::width * e + j) * nq + q < totalsize)
706 {
707 vec[j] =
708 advVel[dir][(vec_t::width * e + j) * nq + q];
709 }
710 else
711 {
712 vec[j] = 0.0;
713 }
714 }
715 (*advVel_ptr).load(&vec[0]);
716 }
717 }
718 }
719
720 m_oper->SetAdvectionVelocities(
722 }
723
724private:
725 std::shared_ptr<MatrixFree::LinearAdvectionDiffusionReaction> m_oper;
726 unsigned int m_nmtot;
727 unsigned int m_nqtot;
734
736 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
738 : Operator(pCollExp, pGeomData, factors),
739 MatrixFreeBase(pCollExp[0]->GetStdExp()->GetNcoeffs(),
740 pCollExp[0]->GetStdExp()->GetNcoeffs(),
741 pCollExp.size()),
743 {
744 m_nmtot = m_numElmt * pCollExp[0]->GetStdExp()->GetNcoeffs();
745
746 const auto dim = pCollExp[0]->GetStdExp()->GetShapeDimension();
747 m_coordim = dim;
748
749 // Basis vector.
750 std::vector<LibUtilities::BasisSharedPtr> basis(dim);
751 for (auto i = 0; i < dim; ++i)
752 {
753 basis[i] = pCollExp[0]->GetBasis(i);
754 }
755
756 // Get shape type
757 auto shapeType = pCollExp[0]->GetStdExp()->DetShapeType();
758
759 // Generate operator string and create operator.
760 std::string op_string = "LinearAdvectionDiffusionReaction";
761 op_string += MatrixFree::GetOpstring(shapeType, m_isDeformed);
763 op_string, basis, pCollExp.size());
764
765 // Get N quadpoints with padding
766 m_nqtot = m_numElmt * pCollExp[0]->GetStdExp()->GetTotPoints();
767
768 // set up required copies for operations
769 oper->SetUpBdata(basis);
770 oper->SetUpDBdata(basis);
771 oper->SetUpD(basis);
772 oper->SetUpZW(basis);
773
774 // Set Jacobian
775 oper->SetJac(pGeomData->GetJacInterLeave(pCollExp, m_nElmtPad));
776
777 // Store derivative factor
778 oper->SetDF(pGeomData->GetDerivFactorsInterLeave(pCollExp, m_nElmtPad));
779
780 m_oper = std::dynamic_pointer_cast<
781 MatrixFree::LinearAdvectionDiffusionReaction>(oper);
782 ASSERTL0(m_oper, "Failed to cast pointer.");
783
784 // Set factors
787 this->UpdateFactors(factors);
788 }
789};
790
791/// Factory initialisation for the
792/// LinearAdvectionDiffusionReaction_MatrixFree operators
793OperatorKey LinearAdvectionDiffusionReaction_MatrixFree::m_typeArr[] = {
796 eMatrixFree, false),
797 LinearAdvectionDiffusionReaction_MatrixFree::create,
798 "LinearAdvectionDiffusionReaction_MatrixFree_Quad"),
801 false),
802 LinearAdvectionDiffusionReaction_MatrixFree::create,
803 "LinearAdvectionDiffusionReaction_MatrixFree_Tri"),
806 false),
807 LinearAdvectionDiffusionReaction_MatrixFree::create,
808 "LinearAdvectionDiffusionReaction_MatrixFree_Hex"),
811 false),
812 LinearAdvectionDiffusionReaction_MatrixFree::create,
813 "LinearAdvectionDiffusionReaction_MatrixFree_Prism"),
816 false),
817 LinearAdvectionDiffusionReaction_MatrixFree::create,
818 "LinearAdvectionDiffusionReaction_MatrixFree_Pyr"),
821 eMatrixFree, false),
822 LinearAdvectionDiffusionReaction_MatrixFree::create,
823 "LinearAdvectionDiffusionReaction_MatrixFree_Tet"),
824};
825
826} // 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
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
STL namespace.
typename abi< ScalarType, width >::type simd
Definition: tinysimd.hpp:80