Nektar++
Loading...
Searching...
No Matches
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
54
55/**
56 * @brief LinearAdvectionDiffusionReaction help class to calculate the size of
57 * the collection that is given as an input and as an output to the
58 * LinearAdvectionDiffusionReaction Operator. The size evaluation takes into
59 * account that the evaluation of the LinearAdvectionDiffusionReaction operator
60 * takes input from the coeff space and gives the output in the coeff space too.
61 */
63{
64protected:
66 {
67 // expect input to be number of elements by the number of coefficients
68 m_inputSize = m_numElmt * m_stdExp->GetNcoeffs();
69
70 // expect output to be number of elements by the number of coefficients
71 // computation is from coeff space to coeff space
73 }
74};
75
76/**
77 * @brief LinearAdvectionDiffusionReaction operator using LocalRegions
78 * implementation.
79 */
81 : virtual public Operator,
83{
84public:
86
88
89 void operator()(const Array<OneD, const NekDouble> &entry0,
90 Array<OneD, NekDouble> &entry1,
91 [[maybe_unused]] Array<OneD, NekDouble> &entry2,
92 [[maybe_unused]] Array<OneD, NekDouble> &entry3,
93 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
94 {
95 unsigned int nmodes = m_expList[0]->GetNcoeffs();
96 unsigned int nphys = m_expList[0]->GetTotPoints();
98
99 for (int n = 0; n < m_numElmt; ++n)
100 {
101 // Restrict varcoeffs to size of element
103 if (m_varcoeffs.size())
104 {
105 varcoeffs =
106 StdRegions::RestrictCoeffMap(m_varcoeffs, n * nphys, nphys);
107 }
108
111 (m_expList)[n]->DetShapeType(), *(m_expList)[n], m_factors,
112 varcoeffs);
113 m_expList[n]->GeneralMatrixOp(entry0 + n * nmodes,
114 tmp = entry1 + n * nmodes, mkey);
115 }
116 }
117
118 void operator()([[maybe_unused]] int dir,
119 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
120 [[maybe_unused]] Array<OneD, NekDouble> &output,
121 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
122 {
123 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
124 }
125
127 {
128 m_factors = factors;
129 }
130
131 /**
132 * @brief Check whether necessary advection velocities are supplied
133 * and copy into local member for varcoeff map.
134 *
135 * @param varcoeffs Map of variable coefficients
136 */
137 void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
138 {
139 m_varcoeffs = varcoeffs;
140 }
141
142protected:
143 int m_dim;
145 vector<LocalRegions::ExpansionSharedPtr> m_expList;
148
149private:
151 vector<LocalRegions::ExpansionSharedPtr> pCollExp,
153 : Operator(pCollExp, pGeomData, factors),
155 {
156 m_expList = pCollExp;
157 m_dim = pCollExp[0]->GetNumBases();
158 m_coordim = pCollExp[0]->GetCoordim();
159
160 m_factors = factors;
162 }
163};
164
165/// Factory initialisation for the LinearAdvectionDiffusionReaction_NoCollection
166/// operators
167OperatorKey LinearAdvectionDiffusionReaction_NoCollection::m_typeArr[] = {
170 false),
171 LinearAdvectionDiffusionReaction_NoCollection::create,
172 "LinearAdvectionDiffusionReaction_NoCollection_Seg"),
175 false),
176 LinearAdvectionDiffusionReaction_NoCollection::create,
177 "LinearAdvectionDiffusionReaction_NoCollection_Tri"),
180 true),
181 LinearAdvectionDiffusionReaction_NoCollection::create,
182 "LinearAdvectionDiffusionReaction_NoCollection_NodalTri"),
185 eNoCollection, false),
186 LinearAdvectionDiffusionReaction_NoCollection::create,
187 "LinearAdvectionDiffusionReaction_NoCollection_Quad"),
190 eNoCollection, false),
191 LinearAdvectionDiffusionReaction_NoCollection::create,
192 "LinearAdvectionDiffusionReaction_NoCollection_Tet"),
195 eNoCollection, true),
196 LinearAdvectionDiffusionReaction_NoCollection::create,
197 "LinearAdvectionDiffusionReaction_NoCollection_NodalTet"),
200 false),
201 LinearAdvectionDiffusionReaction_NoCollection::create,
202 "LinearAdvectionDiffusionReaction_NoCollection_Pyr"),
205 false),
206 LinearAdvectionDiffusionReaction_NoCollection::create,
207 "LinearAdvectionDiffusionReaction_NoCollection_Prism"),
210 true),
211 LinearAdvectionDiffusionReaction_NoCollection::create,
212 "LinearAdvectionDiffusionReaction_NoCollection_NodalPrism"),
215 eNoCollection, false),
216 LinearAdvectionDiffusionReaction_NoCollection::create,
217 "LinearAdvectionDiffusionReaction_NoCollection_Hex")};
218
219/**
220 * @brief LinearAdvectionDiffusionReaction operator using LocalRegions
221 * implementation.
222 */
224 : virtual public Operator,
226{
227public:
229
231
232 void operator()(const Array<OneD, const NekDouble> &input,
233 Array<OneD, NekDouble> &output,
234 [[maybe_unused]] Array<OneD, NekDouble> &output1,
235 [[maybe_unused]] Array<OneD, NekDouble> &output2,
236 Array<OneD, NekDouble> &wsp) final
237 {
238 const int nCoeffs = m_stdExp->GetNcoeffs();
239 const int nPhys = m_stdExp->GetTotPoints();
240
241 ASSERTL1(input.size() >= m_numElmt * nCoeffs,
242 "input array size is insufficient");
243 ASSERTL1(output.size() >= m_numElmt * nCoeffs,
244 "output array size is insufficient");
245
246 Array<OneD, NekDouble> tmpphys, t1;
249
250 tmpphys = wsp;
251 for (int i = 1; i < m_coordim + 1; ++i)
252 {
253 dtmp[i - 1] = wsp + i * nPhys;
254 tmp[i - 1] = wsp + (i + m_coordim) * nPhys;
255 }
256
257 for (int i = 0; i < m_numElmt; ++i)
258 {
259 // Std u
260 m_stdExp->BwdTrans(input + i * nCoeffs, tmpphys);
261
262 // Std \nabla u
263 m_stdExp->PhysDeriv(tmpphys, dtmp[0], dtmp[1], dtmp[2]);
264
265 // Transform Std \nabla u -> Local \nabla u
266 // tmp[0] = dxi1/dx du/dxi1 + dxi2/dx du/dxi2 = du / dx
267 // tmp[1] = dxi1/dy du/dxi1 + dxi2/dy du/dxi2 = du / dy
268 if (m_isDeformed)
269 {
270 for (int j = 0; j < m_coordim; ++j)
271 {
272 Vmath::Vmul(nPhys,
273 m_derivFac[j * m_dim].origin() + i * nPhys, 1,
274 &dtmp[0][0], 1, &tmp[j][0], 1);
275
276 for (int k = 1; k < m_dim; ++k)
277 {
279 nPhys,
280 m_derivFac[j * m_dim + k].origin() + i * nPhys, 1,
281 &dtmp[k][0], 1, &tmp[j][0], 1, &tmp[j][0], 1);
282 }
283 }
284 }
285 else
286 {
287 for (int j = 0; j < m_coordim; ++j)
288 {
289 Vmath::Smul(nPhys, m_derivFac[j * m_dim][i], &dtmp[0][0], 1,
290 &tmp[j][0], 1);
291
292 for (int k = 1; k < m_dim; ++k)
293 {
294 Vmath::Svtvp(nPhys, m_derivFac[j * m_dim + k][i],
295 &dtmp[k][0], 1, &tmp[j][0], 1, &tmp[j][0],
296 1);
297 }
298 }
299 }
300
301 /// Mass term
302 // tmpphys *= \lambda = \lambda u
303 Vmath::Smul(nPhys, -m_lambda, tmpphys, 1, tmpphys, 1);
304
305 /// Add advection term
306 // tmpphys += V[0] * du / dx + V[1] * du / dy
307 for (int j = 0; j < m_coordim; ++j)
308 {
309 Vmath::Vvtvp(nPhys, m_advVel[j] + i * nPhys, 1, tmp[j], 1,
310 tmpphys, 1, tmpphys, 1);
311 }
312
313 // Multiply by Jacobian for inner product
314 if (m_isDeformed)
315 {
316 Vmath::Vmul(nPhys, m_jac + i * nPhys, 1, tmpphys, 1, tmpphys,
317 1);
318 }
319 else
320 {
321 Vmath::Smul(nPhys, m_jac[i], tmpphys, 1, tmpphys, 1);
322 }
323
324 // Compute inner product wrt base
325 m_stdExp->IProductWRTBase(tmpphys, t1 = output + i * nCoeffs);
326
327 /// Determine Laplacian term
328 // add derivFactors for IProdWRTDerivBase below
329 // dtmp[0] = dxi1/dx du/dx + dxi1/dy du/dy
330 // dtmp[1] = dxi2/dx du/dx + dxi2/dy du/dy
331 if (m_isDeformed)
332 {
333 for (int j = 0; j < m_dim; ++j)
334 {
335 Vmath::Vmul(nPhys, m_derivFac[j].origin() + i * nPhys, 1,
336 &tmp[0][0], 1, &dtmp[j][0], 1);
337
338 for (int k = 1; k < m_coordim; ++k)
339 {
341 nPhys,
342 m_derivFac[j + k * m_dim].origin() + i * nPhys, 1,
343 &tmp[k][0], 1, &dtmp[j][0], 1, &dtmp[j][0], 1);
344 }
345 }
346
347 // calculate Iproduct WRT Std Deriv
348 for (int j = 0; j < m_dim; ++j)
349 {
350
351 // multiply by Jacobian
352 Vmath::Vmul(nPhys, m_jac + i * nPhys, 1, dtmp[j], 1,
353 dtmp[j], 1);
354
355 m_stdExp->IProductWRTDerivBase(j, dtmp[j], tmp[0]);
356 Vmath::Vadd(nCoeffs, tmp[0], 1, output + i * nCoeffs, 1,
357 t1 = output + i * nCoeffs, 1);
358 }
359 }
360 else
361 {
362 for (int j = 0; j < m_dim; ++j)
363 {
364 Vmath::Smul(nPhys, m_derivFac[j][i], &tmp[0][0], 1,
365 &dtmp[j][0], 1);
366
367 for (int k = 1; k < m_coordim; ++k)
368 {
369 Vmath::Svtvp(nPhys, m_derivFac[j + k * m_dim][i],
370 &tmp[k][0], 1, &dtmp[j][0], 1, &dtmp[j][0],
371 1);
372 }
373 }
374
375 // calculate Iproduct WRT Std Deriv
376 for (int j = 0; j < m_dim; ++j)
377 {
378 // multiply by Jacobian for integration
379 Vmath::Smul(nPhys, m_jac[i], dtmp[j], 1, dtmp[j], 1);
380
381 m_stdExp->IProductWRTDerivBase(j, dtmp[j], tmp[0]);
382 Vmath::Vadd(nCoeffs, tmp[0], 1, output + i * nCoeffs, 1,
383 t1 = output + i * nCoeffs, 1);
384 }
385 }
386 }
387 }
388
389 void operator()([[maybe_unused]] int dir,
390 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
391 [[maybe_unused]] Array<OneD, NekDouble> &output,
392 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
393 {
394 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
395 }
396
397 /**
398 * @brief Check the validity of supplied constant factors.
399 *
400 * @param factors Map of factors
401 */
403 {
404 m_factors = factors;
405
406 // Check Lambda constant of LinearAdvectionDiffusionReaction operator
407 auto x = factors.find(StdRegions::eFactorLambda);
408 ASSERTL1(
409 x != factors.end(),
410 "Constant factor not defined: " +
411 std::string(
413 m_lambda = x->second;
414 }
415
416 /**
417 * @brief Check whether necessary advection velocities are supplied
418 * and copy into local array for operator.
419 *
420 * @param varcoeffs Map of variable coefficients
421 */
422 void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
423 {
424 // Check whether any varcoeffs are provided
425 if (varcoeffs.empty())
426 {
427 return;
428 }
429
430 // Check advection velocities count
431 int ndir = 0;
432 for (auto &x : advVelTypes)
433 {
434 if (varcoeffs.count(x))
435 {
436 ndir++;
437 }
438 }
439 ASSERTL0(ndir, "Must define at least one advection velocity");
440 ASSERTL1(ndir <= m_coordim,
441 "Number of constants is larger than coordinate dimensions");
442
443 // Copy new varcoeffs
444 m_varcoeffs = varcoeffs;
445
446 // Hold advection velocity reference
447 // separate copy required for operator
448 for (int i = 0; i < m_coordim; i++)
449 {
450 m_advVel[i] = m_varcoeffs.find(advVelTypes[i])->second.GetValue();
451 }
452 }
453
454protected:
457 int m_dim;
466
467private:
469 vector<LocalRegions::ExpansionSharedPtr> pCollExp,
471 : Operator(pCollExp, pGeomData, factors),
473 {
474 m_dim = pCollExp[0]->GetShapeDimension();
475 m_coordim = pCollExp[0]->GetCoordim();
476 int nqtot = m_stdExp->GetTotPoints();
477
478 m_derivFac = pGeomData->GetDerivFactors(pCollExp);
479 m_jac = pGeomData->GetJac(pCollExp);
480 m_wspSize = (2 * m_coordim + 1) * nqtot;
481
482 m_lambda = 1.0;
486 this->UpdateFactors(factors);
487 }
488};
489
490/// Factory initialisation for the
491/// LinearAdvectionDiffusionReaction_IterPerExp
492OperatorKey LinearAdvectionDiffusionReaction_IterPerExp::m_typeArr[] = {
495 false),
496 LinearAdvectionDiffusionReaction_IterPerExp::create,
497 "LinearAdvectionDiffusionReaction_IterPerExp_Seg"),
500 false),
501 LinearAdvectionDiffusionReaction_IterPerExp::create,
502 "LinearAdvectionDiffusionReaction_IterPerExp_Tri"),
505 true),
506 LinearAdvectionDiffusionReaction_IterPerExp::create,
507 "LinearAdvectionDiffusionReaction_IterPerExp_NodalTri"),
510 eIterPerExp, false),
511 LinearAdvectionDiffusionReaction_IterPerExp::create,
512 "LinearAdvectionDiffusionReaction_IterPerExp_Quad"),
515 eIterPerExp, false),
516 LinearAdvectionDiffusionReaction_IterPerExp::create,
517 "LinearAdvectionDiffusionReaction_IterPerExp_Tet"),
520 eIterPerExp, true),
521 LinearAdvectionDiffusionReaction_IterPerExp::create,
522 "LinearAdvectionDiffusionReaction_IterPerExp_NodalTet"),
525 false),
526 LinearAdvectionDiffusionReaction_IterPerExp::create,
527 "LinearAdvectionDiffusionReaction_IterPerExp_Pyr"),
530 false),
531 LinearAdvectionDiffusionReaction_IterPerExp::create,
532 "LinearAdvectionDiffusionReaction_IterPerExp_Prism"),
535 true),
536 LinearAdvectionDiffusionReaction_IterPerExp::create,
537 "LinearAdvectionDiffusionReaction_IterPerExp_NodalPrism"),
540 false),
541 LinearAdvectionDiffusionReaction_IterPerExp::create,
542 "LinearAdvectionDiffusionReaction_IterPerExp_Hex")};
543
544/*
545 * @brief LinearAdvectionDiffusionReaction operator using matrix free
546 * operators.
547 */
549 : virtual public Operator,
552{
553public:
555
557
558 void operator()(const Array<OneD, const NekDouble> &input,
559 Array<OneD, NekDouble> &output0,
560 [[maybe_unused]] Array<OneD, NekDouble> &output1,
561 [[maybe_unused]] Array<OneD, NekDouble> &output2,
562 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
563 {
564 (*m_oper)(input, output0);
565 }
566
567 void operator()([[maybe_unused]] int dir,
568 [[maybe_unused]] const Array<OneD, const NekDouble> &input,
569 [[maybe_unused]] Array<OneD, NekDouble> &output,
570 [[maybe_unused]] Array<OneD, NekDouble> &wsp) final
571 {
572 NEKERROR(ErrorUtil::efatal, "Not valid for this operator.");
573 }
574
575 /**
576 *
577 */
579 {
580 m_factors = factors;
581
582 // Set lambda for this call
583 auto x = factors.find(StdRegions::eFactorLambda);
584 ASSERTL1(
585 x != factors.end(),
586 "Constant factor not defined: " +
587 std::string(
589 m_oper->SetLambda(-1 * x->second);
590 }
591
592 /**
593 * @brief Check whether necessary advection velocities are supplied,
594 * interleave and copy into vectorised containers.
595 *
596 * @param varcoeffs Map of variable coefficients
597 */
598 void UpdateVarcoeffs(StdRegions::VarCoeffMap &varcoeffs) override
599 {
600 // Check varcoeffs empty?
601 if (varcoeffs.empty())
602 {
603 return;
604 }
605
606 // Check whether varcoeffs need update (copied from
607 // GlobalMatrixKey.cpp) This is essential to only do the update +
608 // interleaving after each time step instead of doing it every time
609 // we apply the operator.
610 bool update = false;
611 if (m_varcoeffs.size() < varcoeffs.size())
612 {
613 update = true;
614 }
615 else if (m_varcoeffs.size() > varcoeffs.size())
616 {
617 update = true;
618 }
619 else
620 {
621 StdRegions::VarCoeffMap::const_iterator x, y;
622 for (x = m_varcoeffs.begin(), y = varcoeffs.begin();
623 x != m_varcoeffs.end(); ++x, ++y)
624 {
625 if (x->second.GetHash() < y->second.GetHash())
626 {
627 update = true;
628 break;
629 }
630 if (x->second.GetHash() > y->second.GetHash())
631 {
632 update = true;
633 break;
634 }
635 }
636 }
637 // return if no update required
638 if (!update)
639 {
640 return;
641 }
642 // else copy
643 m_varcoeffs = varcoeffs;
644
645 // Check advection velocities count
646 int ndir = 0;
647 for (auto &x : advVelTypes)
648 {
649 if (m_varcoeffs.count(x))
650 {
651 ndir++;
652 }
653 }
654 ASSERTL0(ndir, "Must define at least one advection velocity");
655 ASSERTL1(ndir >= m_coordim,
656 "Number of coordingates is larger than number of constants "
657 "provided (ndir = " +
658 std::to_string(ndir) +
659 ", m_coordim = " + std::to_string(m_coordim) + ")");
660
661 // Extract advection velocities, interleave and pass to
662 // libMatrixFree Multiply by -1/lambda for combined (Mass +
663 // Advection) IProduct operation in MatrixFree/AdvectionKernel
664 auto lambda = m_factors.find(StdRegions::eFactorLambda);
666 for (int i = 0; i < m_coordim; i++)
667 {
668 advVel[i] = Array<OneD, NekDouble>(
669 m_varcoeffs.find(advVelTypes[i])->second.GetValue());
670 Vmath::Smul(advVel[i].size(), -1 / lambda->second, advVel[i], 1,
671 advVel[i], 1);
672 }
673
674 // Interleave Advection Velocities
675 using namespace tinysimd;
676 using vec_t = simd<NekDouble>;
677 typedef std::vector<vec_t, tinysimd::allocator<vec_t>> VecVec_t;
678
679 // Arguments of GetDerivFactorsInterLeave function
680 int nElmt = m_nElmtPad;
681
682 ASSERTL1(nElmt % vec_t::width == 0,
683 "Number of elements not divisible by vector "
684 "width, padding not yet implemented.");
685
686 int nBlocks = nElmt / vec_t::width;
687
688 unsigned int n_vel = m_coordim;
689 alignas(vec_t::alignment) NekDouble vec[vec_t::width];
690
691 VecVec_t newAdvVel;
692 int nq = m_nqtot / m_numElmt;
693 int totalsize = m_nqtot; // nq * n_vel;
694
695 // The advection velocity varies at every quad point
696 // It is independent of DEFORMED
697 newAdvVel.resize(nBlocks * n_vel * nq);
698 auto *advVel_ptr = &newAdvVel[0];
699 for (int e = 0; e < nBlocks; ++e)
700 {
701 for (int q = 0; q < nq; q++)
702 {
703 for (int dir = 0; dir < n_vel; ++dir, ++advVel_ptr)
704 {
705 for (int j = 0; j < vec_t::width; ++j)
706 {
707 if ((vec_t::width * e + j) * nq + q < totalsize)
708 {
709 vec[j] =
710 advVel[dir][(vec_t::width * e + j) * nq + q];
711 }
712 else
713 {
714 vec[j] = 0.0;
715 }
716 }
717 (*advVel_ptr).load(&vec[0]);
718 }
719 }
720 }
721
722 m_oper->SetAdvectionVelocities(
724 }
725
726private:
727 std::shared_ptr<MatrixFree::LinearAdvectionDiffusionReaction> m_oper;
728 unsigned int m_nmtot;
729 unsigned int m_nqtot;
736
738 vector<LocalRegions::ExpansionSharedPtr> pCollExp,
740 : Operator(pCollExp, pGeomData, factors),
741 MatrixFreeBase(pCollExp[0]->GetNcoeffs(), pCollExp[0]->GetNcoeffs(),
742 pCollExp.size()),
744 {
745 m_nmtot = m_numElmt * pCollExp[0]->GetNcoeffs();
746
747 const auto dim = pCollExp[0]->GetShapeDimension();
748 m_coordim = dim;
749
750 // Basis vector.
751 std::vector<LibUtilities::BasisSharedPtr> basis(dim);
752 for (auto i = 0; i < dim; ++i)
753 {
754 basis[i] = pCollExp[0]->GetBasis(i);
755 }
756
757 // Get shape type
758 auto shapeType = pCollExp[0]->DetShapeType();
759
760 // Generate operator string and create operator.
761 std::string op_string = "LinearAdvectionDiffusionReaction";
762 op_string += MatrixFree::GetOpstring(shapeType, m_isDeformed);
763 auto oper = MatrixFree::GetOperatorFactory().CreateInstance(
764 op_string, basis, pCollExp.size());
765
766 // Get N quadpoints with padding
767 m_nqtot = m_numElmt * pCollExp[0]->GetTotPoints();
768
769 // set up required copies for operations
770 oper->SetUpBdata(basis);
771 oper->SetUpDBdata(basis);
772 oper->SetUpD(basis);
773 oper->SetUpZW(basis);
774
775 // Set Jacobian
776 oper->SetJac(pGeomData->GetJacInterLeave(pCollExp, m_nElmtPad));
777
778 // Store derivative factor
779 oper->SetDF(pGeomData->GetDerivFactorsInterLeave(pCollExp, m_nElmtPad));
780
781 m_oper = std::dynamic_pointer_cast<
782 MatrixFree::LinearAdvectionDiffusionReaction>(oper);
783 ASSERTL0(m_oper, "Failed to cast pointer.");
784
785 // Set factors
788 this->UpdateFactors(factors);
789 }
790};
791
792/// Factory initialisation for the
793/// LinearAdvectionDiffusionReaction_MatrixFree operators
794OperatorKey LinearAdvectionDiffusionReaction_MatrixFree::m_typeArr[] = {
797 eMatrixFree, false),
798 LinearAdvectionDiffusionReaction_MatrixFree::create,
799 "LinearAdvectionDiffusionReaction_MatrixFree_Quad"),
802 false),
803 LinearAdvectionDiffusionReaction_MatrixFree::create,
804 "LinearAdvectionDiffusionReaction_MatrixFree_Tri"),
807 false),
808 LinearAdvectionDiffusionReaction_MatrixFree::create,
809 "LinearAdvectionDiffusionReaction_MatrixFree_Hex"),
812 false),
813 LinearAdvectionDiffusionReaction_MatrixFree::create,
814 "LinearAdvectionDiffusionReaction_MatrixFree_Prism"),
817 false),
818 LinearAdvectionDiffusionReaction_MatrixFree::create,
819 "LinearAdvectionDiffusionReaction_MatrixFree_Pyr"),
822 eMatrixFree, false),
823 LinearAdvectionDiffusionReaction_MatrixFree::create,
824 "LinearAdvectionDiffusionReaction_MatrixFree_Tet"),
825};
826
827} // 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
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< LocalRegions::ExpansionSharedPtr > 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
LinearAdvectionDiffusionReaction_MatrixFree(vector< LocalRegions::ExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
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 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< 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.
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
static FactorMap NullFactorMap
const char *const ConstFactorTypeMap[]
VarCoeffMap RestrictCoeffMap(const VarCoeffMap &m, size_t offset, size_t cnt)
ConstFactorMap FactorMap
static VarCoeffMap NullVarCoeffMap
std::map< StdRegions::VarCoeffType, VarCoeffEntry > VarCoeffMap
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:132