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
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 {
129 m_factors = factors;
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
161 m_factors = factors;
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 {
405 m_factors = factors;
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 {
581 m_factors = factors;
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 coordingates is larger than number of constants "
658 "provided (ndir = " +
659 std::to_string(ndir) +
660 ", m_coordim = " + std::to_string(m_coordim) + ")");
661
662 // Extract advection velocities, interleave and pass to
663 // libMatrixFree Multiply by -1/lambda for combined (Mass +
664 // Advection) IProduct operation in MatrixFree/AdvectionKernel
665 auto lambda = m_factors.find(StdRegions::eFactorLambda);
667 for (int i = 0; i < m_coordim; i++)
668 {
669 advVel[i] = Array<OneD, NekDouble>(
670 m_varcoeffs.find(advVelTypes[i])->second.GetValue());
671 Vmath::Smul(advVel[i].size(), -1 / lambda->second, advVel[i], 1,
672 advVel[i], 1);
673 }
674
675 // Interleave Advection Velocities
676 using namespace tinysimd;
677 using vec_t = simd<NekDouble>;
678 typedef std::vector<vec_t, tinysimd::allocator<vec_t>> VecVec_t;
679
680 // Arguments of GetDerivFactorsInterLeave function
681 int nElmt = m_nElmtPad;
682
683 ASSERTL1(nElmt % vec_t::width == 0,
684 "Number of elements not divisible by vector "
685 "width, padding not yet implemented.");
686
687 int nBlocks = nElmt / vec_t::width;
688
689 unsigned int n_vel = m_coordim;
690 alignas(vec_t::alignment) NekDouble vec[vec_t::width];
691
692 VecVec_t newAdvVel;
693 int nq = m_nqtot / m_numElmt;
694 int totalsize = m_nqtot; // nq * n_vel;
695
696 // The advection velocity varies at every quad point
697 // It is independent of DEFORMED
698 newAdvVel.resize(nBlocks * n_vel * nq);
699 auto *advVel_ptr = &newAdvVel[0];
700 for (int e = 0; e < nBlocks; ++e)
701 {
702 for (int q = 0; q < nq; q++)
703 {
704 for (int dir = 0; dir < n_vel; ++dir, ++advVel_ptr)
705 {
706 for (int j = 0; j < vec_t::width; ++j)
707 {
708 if ((vec_t::width * e + j) * nq + q < totalsize)
709 {
710 vec[j] =
711 advVel[dir][(vec_t::width * e + j) * nq + q];
712 }
713 else
714 {
715 vec[j] = 0.0;
716 }
717 }
718 (*advVel_ptr).load(&vec[0]);
719 }
720 }
721 }
722
723 m_oper->SetAdvectionVelocities(
725 }
726
727private:
728 std::shared_ptr<MatrixFree::LinearAdvectionDiffusionReaction> m_oper;
729 unsigned int m_nmtot;
730 unsigned int m_nqtot;
737
739 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
741 : Operator(pCollExp, pGeomData, factors),
742 MatrixFreeBase(pCollExp[0]->GetStdExp()->GetNcoeffs(),
743 pCollExp[0]->GetStdExp()->GetNcoeffs(),
744 pCollExp.size()),
746 {
747 m_nmtot = m_numElmt * pCollExp[0]->GetStdExp()->GetNcoeffs();
748
749 const auto dim = pCollExp[0]->GetStdExp()->GetShapeDimension();
750 m_coordim = dim;
751
752 // Basis vector.
753 std::vector<LibUtilities::BasisSharedPtr> basis(dim);
754 for (auto i = 0; i < dim; ++i)
755 {
756 basis[i] = pCollExp[0]->GetBasis(i);
757 }
758
759 // Get shape type
760 auto shapeType = pCollExp[0]->GetStdExp()->DetShapeType();
761
762 // Generate operator string and create operator.
763 std::string op_string = "LinearAdvectionDiffusionReaction";
764 op_string += MatrixFree::GetOpstring(shapeType, m_isDeformed);
765 auto oper = MatrixFree::GetOperatorFactory().CreateInstance(
766 op_string, basis, pCollExp.size());
767
768 // Get N quadpoints with padding
769 m_nqtot = m_numElmt * pCollExp[0]->GetStdExp()->GetTotPoints();
770
771 // set up required copies for operations
772 oper->SetUpBdata(basis);
773 oper->SetUpDBdata(basis);
774 oper->SetUpD(basis);
775 oper->SetUpZW(basis);
776
777 // Set Jacobian
778 oper->SetJac(pGeomData->GetJacInterLeave(pCollExp, m_nElmtPad));
779
780 // Store derivative factor
781 oper->SetDF(pGeomData->GetDerivFactorsInterLeave(pCollExp, m_nElmtPad));
782
783 m_oper = std::dynamic_pointer_cast<
784 MatrixFree::LinearAdvectionDiffusionReaction>(oper);
785 ASSERTL0(m_oper, "Failed to cast pointer.");
786
787 // Set factors
790 this->UpdateFactors(factors);
791 }
792};
793
794/// Factory initialisation for the
795/// LinearAdvectionDiffusionReaction_MatrixFree operators
796OperatorKey LinearAdvectionDiffusionReaction_MatrixFree::m_typeArr[] = {
799 eMatrixFree, false),
800 LinearAdvectionDiffusionReaction_MatrixFree::create,
801 "LinearAdvectionDiffusionReaction_MatrixFree_Quad"),
804 false),
805 LinearAdvectionDiffusionReaction_MatrixFree::create,
806 "LinearAdvectionDiffusionReaction_MatrixFree_Tri"),
809 false),
810 LinearAdvectionDiffusionReaction_MatrixFree::create,
811 "LinearAdvectionDiffusionReaction_MatrixFree_Hex"),
814 false),
815 LinearAdvectionDiffusionReaction_MatrixFree::create,
816 "LinearAdvectionDiffusionReaction_MatrixFree_Prism"),
819 false),
820 LinearAdvectionDiffusionReaction_MatrixFree::create,
821 "LinearAdvectionDiffusionReaction_MatrixFree_Pyr"),
824 eMatrixFree, false),
825 LinearAdvectionDiffusionReaction_MatrixFree::create,
826 "LinearAdvectionDiffusionReaction_MatrixFree_Tet"),
827};
828
829} // 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< 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.
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:80