Nektar++
Loading...
Searching...
No Matches
StdQuadExp.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: StdQuadExp.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: Quadrilateral routines built upon StdExpansion2D
32//
33///////////////////////////////////////////////////////////////////////////////
34
38
39using namespace std;
43
44namespace Nektar::StdRegions
45{
46// Declaration of scalar routine
50
51/** \brief Constructor using BasisKey class for quadrature
52 * points and order definition
53 */
55 const LibUtilities::BasisKey &Bb)
56 : StdExpansion(Ba.GetNumModes() * Bb.GetNumModes(), 2, Ba, Bb),
57 StdExpansion2D(Ba.GetNumModes() * Bb.GetNumModes(), Ba, Bb)
58{
59 // cache integration weights for future use
60 m_weights.push_back(m_base[0]->GetW());
61
62 // cache integration weights for future use
63 m_weights.push_back(m_base[1]->GetW());
64}
65
66/////////////////////////////
67// Differentiation Methods //
68/////////////////////////////
69/** \brief Calculate the derivative of the physical points
70 *
71 * For quadrilateral region can use the Tensor_Deriv function
72 * defined under StdExpansion.
73 */
74
78 [[maybe_unused]] Array<OneD, NekDouble> &out_d2)
79{
80 PhysTensorDeriv(inarray, out_d0, out_d1);
81}
82
83////////////////
84// Transforms //
85////////////////
86
88 Array<OneD, NekDouble> &outarray)
89{
90 int nquad0 = m_base[0]->GetNumPoints();
91 int nquad1 = m_base[1]->GetNumPoints();
92
93 if (m_base[0]->Collocation() && m_base[1]->Collocation())
94 {
95 std::memcpy(outarray.data(), inarray.data(),
96 nquad0 * nquad1 * sizeof(NekDouble));
97 }
98 else
99 {
100 const Array<OneD, const NekDouble> base0 = m_base[0]->GetBdata();
101 const Array<OneD, const NekDouble> base1 = m_base[1]->GetBdata();
102
103 int nmodes0 = m_base[0]->GetNumModes();
104 int nmodes1 = m_base[1]->GetNumModes();
105
106 std::vector<vec_t, tinysimd::allocator<vec_t>> wsp0(nmodes1 * nquad0);
107
108 // Switch statment using boost_pp and macros. This unfolls intwo a
109 // nested swtich statement where the outer swtich statement runs
110 // from SMIN to SMAX for modal order and the inner switch
111 // statemets run from the outer value of the case to 2*SMAX for
112 // the quadrature order. If you want to see it unwrapped compile
113 // in verbose mode and add --preprocess to the c++ command.
114 // Default case
115#undef BWDTRANS_DEF
116#define BWDTRANS_DEF \
117 BwdTransQuadKernel( \
118 nmodes0, nmodes1, nquad0, nquad1, (const vec_t *)base0.data(), \
119 (const vec_t *)base1.data(), wsp0.data(), \
120 (const vec_t *)inarray.data(), (vec_t *)outarray.data())
121
122 // Inner loop case over quarature points
123#undef BWDTRANS_Q
124#define BWDTRANS_Q(r, i) \
125 case NQ(i): \
126 BwdTransQuadKernel( \
127 NM(i), NM(i), NQ(i), NQ(i), (const vec_t *)base0.data(), \
128 (const vec_t *)base1.data(), wsp0.data(), \
129 (const vec_t *)inarray.data(), (vec_t *)outarray.data()); \
130 break;
131
132 // outer loop case over modes
133#undef BWDTRANS_M
134#define BWDTRANS_M(r, i) \
135 case NM(i): \
136 { \
137 switch (nquad0) \
138 { \
139 BOOST_PP_FOR_##r((NM(i), NM_P1(i), BOOST_PP_MUL(2, NM(i))), \
140 STDLEV2TEST1, STDLEV2UPDATE1, BWDTRANS_Q) default \
141 : BWDTRANS_DEF; \
142 break; \
143 } \
144 } \
145 break;
146
147 // templated cases on equi-ordered modes and standard quad
148 // usage where quad order goes from mode order to 2(*mode
149 // order)
150 if ((nmodes0 == nmodes1) && (nquad0 == nquad1))
151 {
152 switch (nmodes0)
153 {
154 BOOST_PP_FOR((SMIN, 0, SMAX), STDLEV2TEST, STDLEV2UPDATE,
156 default:
158 break;
159 }
160 }
161 else
162 {
164 }
165 }
166}
167
169 const Array<OneD, const NekDouble> &inarray,
170 Array<OneD, NekDouble> &outarray)
171{
172 if ((m_base[0]->Collocation()) && (m_base[1]->Collocation()))
173 {
174 Vmath::Vcopy(m_ncoeffs, inarray, 1, outarray, 1);
175 }
176 else
177 {
178 int i, j;
179 int npoints[2] = {m_base[0]->GetNumPoints(), m_base[1]->GetNumPoints()};
180 int nmodes[2] = {m_base[0]->GetNumModes(), m_base[1]->GetNumModes()};
181
182 fill(outarray.data(), outarray.data() + m_ncoeffs, 0.0);
183
184 Array<OneD, NekDouble> physEdge[4];
185 Array<OneD, NekDouble> coeffEdge[4];
186 for (i = 0; i < 4; i++)
187 {
188 physEdge[i] = Array<OneD, NekDouble>(npoints[i % 2]);
189 coeffEdge[i] = Array<OneD, NekDouble>(nmodes[i % 2]);
190 }
191
192 for (i = 0; i < npoints[0]; i++)
193 {
194 physEdge[0][i] = inarray[i];
195 physEdge[2][i] = inarray[npoints[0] * npoints[1] - 1 - i];
196 }
197
198 for (i = 0; i < npoints[1]; i++)
199 {
200 physEdge[1][i] = inarray[npoints[0] - 1 + i * npoints[0]];
201 physEdge[3][i] =
202 inarray[(npoints[1] - 1) * npoints[0] - i * npoints[0]];
203 }
204
205 StdSegExpSharedPtr segexp[2] = {
207 m_base[0]->GetBasisKey()),
209 m_base[1]->GetBasisKey())};
210
212 Array<OneD, int> signArray;
214
215 for (i = 0; i < 4; i++)
216 {
217 segexp[i % 2]->FwdTransBndConstrained(physEdge[i], coeffEdge[i]);
218
219 GetTraceToElementMap(i, mapArray, signArray);
220 for (j = 0; j < nmodes[i % 2]; j++)
221 {
222 sign = (NekDouble)signArray[j];
223 outarray[mapArray[j]] = sign * coeffEdge[i][j];
224 }
225 }
226
229
230 StdMatrixKey masskey(eMass, DetShapeType(), *this);
231 MassMatrixOp(outarray, tmp0, masskey);
232 IProductWRTBase(inarray, tmp1);
233
234 Vmath::Vsub(m_ncoeffs, tmp1, 1, tmp0, 1, tmp1, 1);
235
236 // get Mass matrix inverse (only of interior DOF)
237 // use block (1,1) of the static condensed system
238 // note: this block alreay contains the inverse matrix
239 DNekMatSharedPtr matsys =
240 (m_stdStaticCondMatrixManager[masskey])->GetBlock(1, 1);
241
242 int nBoundaryDofs = NumBndryCoeffs();
243 int nInteriorDofs = m_ncoeffs - nBoundaryDofs;
244
245 Array<OneD, NekDouble> rhs(nInteriorDofs);
246 Array<OneD, NekDouble> result(nInteriorDofs);
247
248 GetInteriorMap(mapArray);
249
250 for (i = 0; i < nInteriorDofs; i++)
251 {
252 rhs[i] = tmp1[mapArray[i]];
253 }
254
255 Blas::Dgemv('N', nInteriorDofs, nInteriorDofs, 1.0,
256 &(matsys->GetPtr())[0], nInteriorDofs, rhs.data(), 1, 0.0,
257 result.data(), 1);
258
259 for (i = 0; i < nInteriorDofs; i++)
260 {
261 outarray[mapArray[i]] = result[i];
262 }
263 }
264}
265
266/////////////////////////////
267// Inner Product Functions //
268/////////////////////////////
269/** \brief Inner product of \a inarray over region with respect to the
270 * expansion basis (this)->m_base[0] and return in \a outarray
271 *
272 * @param base0 - An array containing the values of the basis in the
273 * 0-direction at the quarature poitns
274 * @param base1 - An array containing the values of the basis in the
275 * 1-direction at the quarature poitns
276 * @param inarray - Array of values evaluated at the physical
277 * quadrature points
278 * @param outarray the values of the inner product with respect to
279 * each basis over region will be stored in the array \a outarray as
280 * output of the function
281 * @param jac - An array of size 1 if not deformed or the number of
282 * quadrature points if deformed holding the values of the jacobian
283 * @param Deformed - a bool identifying if the inner product is to be
284 * treated as a deformed or regular integration which just relates to
285 * how the \param jac array is treated
286 * @param CollDir0 - bool to identify if 0-direction basis is a
287 * collocated expansion
288 * @param CollDir1 - bool to identify if 1-direction basis is a
289 * collocated expansion
290 */
292 const Array<OneD, const NekDouble> &base0,
293 const Array<OneD, const NekDouble> &base1,
294 const Array<OneD, const NekDouble> &inarray,
296 const bool Deformed, const bool CollDir0, const bool CollDir1)
297{
298 int nquad0 = m_base[0]->GetNumPoints();
299 int nquad1 = m_base[1]->GetNumPoints();
300 int order0 = m_base[0]->GetNumModes();
301 int order1 = m_base[1]->GetNumModes();
302
303 std::vector<vec_t, tinysimd::allocator<vec_t>> wsp0(nquad1);
304
305 // Swith statment using boost_pp and macros. This unfolls intwo a
306 // nested swtich statement where the outer swtich statement runs
307 // from SMIN to SMAX for modal order and the inner switch
308 // statemets run from the outer value of the case to 2*SMAX for
309 // the quadrature order. If you want to see it unwrapped compile
310 // in verbose mode and add --preprocess to the c++ command.
311 if (Deformed)
312 {
313 // Default case
314#undef IPRODUCTWRTBASE_DEF
315#define IPRODUCTWRTBASE_DEF \
316 IProductQuadKernel<false, false, true>( \
317 order0, order1, nquad0, nquad1, (const vec_t *)inarray.data(), \
318 (const vec_t *)base0.data(), (const vec_t *)base1.data(), \
319 (const vec_t *)m_weights[0].data(), \
320 (const vec_t *)m_weights[1].data(), (const vec_t *)jac.data(), \
321 (vec_t *)wsp0.data(), (vec_t *)outarray.data(), 1.0, CollDir0, \
322 CollDir1)
323
324 // Inner loop case over quarature points
325#undef IPRODUCTWRTBASE_Q
326#define IPRODUCTWRTBASE_Q(r, i) \
327 case NQ(i): \
328 IProductQuadKernel<false, false, true>( \
329 NM(i), NM(i), NQ(i), NQ(i), (const vec_t *)inarray.data(), \
330 (const vec_t *)base0.data(), (const vec_t *)base1.data(), \
331 (const vec_t *)m_weights[0].data(), \
332 (const vec_t *)m_weights[1].data(), (const vec_t *)jac.data(), \
333 (vec_t *)wsp0.data(), (vec_t *)outarray.data(), 1.0, CollDir0, \
334 CollDir1); \
335 break;
336
337 // outer loop case over modes
338#undef IPRODUCTWRTBASE_M
339#define IPRODUCTWRTBASE_M(r, i) \
340 case NM(i): \
341 { \
342 switch (nquad0) \
343 { \
344 BOOST_PP_FOR_##r((NM(i), NM_P1(i), BOOST_PP_MUL(2, NM(i))), \
345 STDLEV2TEST1, STDLEV2UPDATE1, \
346 IPRODUCTWRTBASE_Q) default : IPRODUCTWRTBASE_DEF; \
347 break; \
348 } \
349 } \
350 break;
351
352 // templated cases on equi-ordered modes and standard quad usage
353 // where quad order goes from mode order to 2(*mode order)
354 if ((order0 == order1) && (nquad0 == nquad1))
355 {
356 switch (order0)
357 {
358 BOOST_PP_FOR((SMIN, 0, SMAX), STDLEV2TEST, STDLEV2UPDATE,
360 default:
362 break;
363 }
364 }
365 else
366 {
368 }
369 }
370 else // non-deformed case
371 {
372 // Default case
373#undef IPRODUCTWRTBASE_DEF
374#define IPRODUCTWRTBASE_DEF \
375 IProductQuadKernel<false, false, false>( \
376 order0, order1, nquad0, nquad1, (const vec_t *)inarray.data(), \
377 (const vec_t *)base0.data(), (const vec_t *)base1.data(), \
378 (const vec_t *)m_weights[0].data(), \
379 (const vec_t *)m_weights[1].data(), (const vec_t *)jac.data(), \
380 (vec_t *)wsp0.data(), (vec_t *)outarray.data(), 1.0, CollDir0, \
381 CollDir1)
382
383 // Inner loop case over quarature points
384#undef IPRODUCTWRTBASE_Q
385#define IPRODUCTWRTBASE_Q(r, i) \
386 case NQ(i): \
387 IProductQuadKernel<false, false, false>( \
388 NM(i), NM(i), NQ(i), NQ(i), (const vec_t *)inarray.data(), \
389 (const vec_t *)base0.data(), (const vec_t *)base1.data(), \
390 (const vec_t *)m_weights[0].data(), \
391 (const vec_t *)m_weights[1].data(), (const vec_t *)jac.data(), \
392 (vec_t *)wsp0.data(), (vec_t *)outarray.data(), 1.0, CollDir0, \
393 CollDir1); \
394 break;
395
396 // outer loop case over modes
397#undef IPRODUCTWRTBASE_M
398#define IPRODUCTWRTBASE_M(r, i) \
399 case NM(i): \
400 { \
401 switch (nquad0) \
402 { \
403 BOOST_PP_FOR_##r((NM(i), NM_P1(i), BOOST_PP_MUL(2, NM(i))), \
404 STDLEV2TEST1, STDLEV2UPDATE1, \
405 IPRODUCTWRTBASE_Q) default : IPRODUCTWRTBASE_DEF; \
406 break; \
407 } \
408 } \
409 break;
410
411 // templated cases on equi-ordered modes and standard quad usage
412 // where quad order goes from mode order to 2(*mode order)
413 if ((order0 == order1) && (nquad0 == nquad1))
414 {
415 switch (order0)
416 {
417 BOOST_PP_FOR((SMIN, 0, SMAX), STDLEV2TEST, STDLEV2UPDATE,
419 default:
421 break;
422 }
423 }
424 else
425 {
427 }
428 }
429}
430
432 const int dir, const Array<OneD, const NekDouble> &inarray,
433 Array<OneD, NekDouble> &outarray)
434{
435 ASSERTL0((dir == 0) || (dir == 1), "input dir is out of range");
436
437 Array<OneD, NekDouble> one(1, 1.0);
438 if (dir) // dir == 1
439 {
440 v_IProductWRTBaseKernel(m_base[0]->GetBdata(), m_base[1]->GetDbdata(),
441 inarray, outarray, one, false,
442 m_base[0]->Collocation(), false);
443 }
444 else // dir == 0
445 {
446 v_IProductWRTBaseKernel(m_base[0]->GetDbdata(), m_base[1]->GetBdata(),
447 inarray, outarray, one, false, false,
448 m_base[1]->Collocation());
449 }
450}
451
452//////////////////////////
453// Evaluation functions //
454//////////////////////////
455
458{
459 eta[0] = xi[0];
460 eta[1] = xi[1];
461}
462
465{
466 xi[0] = eta[0];
467 xi[1] = eta[1];
468}
469
470/** \brief Fill outarray with mode \a mode of expansion
471 *
472 * Note for quadrilateral expansions _base[0] (i.e. p) modes run
473 * fastest
474 */
475
476void StdQuadExp::v_FillMode(const int mode, Array<OneD, NekDouble> &outarray)
477{
478 int i;
479 int nquad0 = m_base[0]->GetNumPoints();
480 int nquad1 = m_base[1]->GetNumPoints();
481 Array<OneD, const NekDouble> base0 = m_base[0]->GetBdata();
482 Array<OneD, const NekDouble> base1 = m_base[1]->GetBdata();
483 int btmp0 = m_base[0]->GetNumModes();
484 int mode0 = mode % btmp0;
485 int mode1 = mode / btmp0;
486
487 ASSERTL2(mode1 == (int)floor((1.0 * mode) / btmp0),
488 "Integer Truncation not Equiv to Floor");
489
490 ASSERTL2(m_ncoeffs > mode,
491 "calling argument mode is larger than total expansion order");
492
493 for (i = 0; i < nquad1; ++i)
494 {
495 Vmath::Vcopy(nquad0, (NekDouble *)(base0.data() + mode0 * nquad0), 1,
496 &outarray[0] + i * nquad0, 1);
497 }
498
499 for (i = 0; i < nquad0; ++i)
500 {
501 Vmath::Vmul(nquad1, (NekDouble *)(base1.data() + mode1 * nquad1), 1,
502 &outarray[0] + i, nquad0, &outarray[0] + i, nquad0);
503 }
504}
505
506//////////////////////
507// Helper functions //
508//////////////////////
509
511{
512 return 4;
513}
514
516{
517 return 4;
518}
519
520int StdQuadExp::v_GetTraceNcoeffs(const int i) const
521{
522 ASSERTL2((i >= 0) && (i <= 3), "edge id is out of range");
523
524 if ((i == 0) || (i == 2))
525 {
526 return GetBasisNumModes(0);
527 }
528 else
529 {
530 return GetBasisNumModes(1);
531 }
532}
533
535{
536 ASSERTL2((i >= 0) && (i <= 4), "edge id is out of range");
537 if ((i == 0) || (i == 2))
538 {
539 return GetBasisNumModes(0) - 2;
540 }
541 else
542 {
543 return GetBasisNumModes(1) - 2;
544 }
545}
546
548{
549 ASSERTL2((i >= 0) && (i <= 3), "edge id is out of range");
550
551 if ((i == 0) || (i == 2))
552 {
553 return GetNumPoints(0);
554 }
555 else
556 {
557 return GetNumPoints(1);
558 }
559}
560
562 const int i, [[maybe_unused]] const int j,
563 [[maybe_unused]] bool UseGLL) const
564{
565 ASSERTL2((i >= 0) && (i <= 3), "edge id is out of range");
566
567 if ((i == 0) || (i == 2))
568 {
569 switch (GetBasis(0)->GetBasisType())
570 {
572 {
574 GetBasis(0)->GetNumModes(),
575 GetBasis(0)->GetPointsKey());
576 }
577 break;
578 default:
579 {
580 return GetBasis(0)->GetBasisKey();
581 }
582 }
583 }
584 else
585 {
586 switch (GetBasis(1)->GetBasisType())
587 {
589 {
591 GetBasis(1)->GetNumModes(),
592 GetBasis(1)->GetPointsKey());
593 }
594 break;
595 default:
596 {
597 return GetBasis(1)->GetBasisKey();
598 }
599 }
600 }
601}
602
607
609{
613 "BasisType is not a boundary interior form");
617 "BasisType is not a boundary interior form");
618
619 return 4 + 2 * (GetBasisNumModes(0) - 2) + 2 * (GetBasisNumModes(1) - 2);
620}
621
623{
627 "BasisType is not a boundary interior form");
631 "BasisType is not a boundary interior form");
632
633 return 2 * GetBasisNumModes(0) + 2 * GetBasisNumModes(1);
634}
635
637 const std::vector<unsigned int> &nummodes, int &modes_offset)
638{
639 int nmodes = nummodes[modes_offset] * nummodes[modes_offset + 1];
640 modes_offset += 2;
641
642 return nmodes;
643}
644
646{
647 bool returnval = false;
648
651 {
654 {
655 returnval = true;
656 }
657 }
658
659 return returnval;
660}
661
663 Array<OneD, NekDouble> &coords_1,
664 [[maybe_unused]] Array<OneD, NekDouble> &coords_2)
665{
666 Array<OneD, const NekDouble> z0 = m_base[0]->GetZ();
667 Array<OneD, const NekDouble> z1 = m_base[1]->GetZ();
668 int nq0 = GetNumPoints(0);
669 int nq1 = GetNumPoints(1);
670 int i;
671
672 for (i = 0; i < nq1; ++i)
673 {
674 Vmath::Vcopy(nq0, z0.data(), 1, &coords_0[0] + i * nq0, 1);
675 Vmath::Fill(nq0, z1[i], &coords_1[0] + i * nq0, 1);
676 }
677}
678
679/**
680 * @brief This function evaluates the basis function mode @p mode at a
681 * point @p coords of the domain.
682 *
683 * This function uses barycentric interpolation with the tensor
684 * product separation of the basis function to improve performance.
685 *
686 * @param coord The coordinate inside the standard region.
687 * @param mode The mode number to be evaluated.
688 *
689 * @return The value of the basis function @p mode at @p coords.
690 */
692 const Array<OneD, const NekDouble> &coords, int mode)
693{
694 ASSERTL2(coords[0] > -1 - NekConstants::kNekZeroTol, "coord[0] < -1");
695 ASSERTL2(coords[0] < 1 + NekConstants::kNekZeroTol, "coord[0] > 1");
696 ASSERTL2(coords[1] > -1 - NekConstants::kNekZeroTol, "coord[1] < -1");
697 ASSERTL2(coords[1] < 1 + NekConstants::kNekZeroTol, "coord[1] > 1");
698
699 const int nm0 = m_base[0]->GetNumModes();
700 const int nm1 = m_base[1]->GetNumModes();
701
702 return StdExpansion::BaryEvaluateBasis<0>(coords[0], mode % nm1) *
703 StdExpansion::BaryEvaluateBasis<1>(coords[1], mode / nm0);
704}
705
707 const Array<OneD, NekDouble> &coord,
708 const Array<OneD, const NekDouble> &inarray,
709 std::array<NekDouble, 3> &firstOrderDerivs)
710{
711 return BaryTensorDeriv(coord, inarray, firstOrderDerivs);
712}
713
714//////////////
715// Mappings //
716//////////////
717
719{
720 int i;
721 int cnt = 0;
722 int nummodes0, nummodes1;
723 int value1 = 0, value2 = 0;
724 if (outarray.size() != NumBndryCoeffs())
725 {
727 }
728
729 nummodes0 = m_base[0]->GetNumModes();
730 nummodes1 = m_base[1]->GetNumModes();
731
732 const LibUtilities::BasisType Btype0 = GetBasisType(0);
733 const LibUtilities::BasisType Btype1 = GetBasisType(1);
734
735 switch (Btype1)
736 {
739 value1 = nummodes0;
740 break;
742 value1 = 2 * nummodes0;
743 break;
744 default:
745 ASSERTL0(0, "Mapping array is not defined for this expansion");
746 break;
747 }
748
749 for (i = 0; i < value1; i++)
750 {
751 outarray[i] = i;
752 }
753 cnt = value1;
754
755 switch (Btype0)
756 {
759 value2 = value1 + nummodes0 - 1;
760 break;
762 value2 = value1 + 1;
763 break;
764 default:
765 ASSERTL0(0, "Mapping array is not defined for this expansion");
766 break;
767 }
768
769 for (i = 0; i < nummodes1 - 2; i++)
770 {
771 outarray[cnt++] = value1 + i * nummodes0;
772 outarray[cnt++] = value2 + i * nummodes0;
773 }
774
775 if (Btype1 == LibUtilities::eGLL_Lagrange ||
777 {
778 for (i = nummodes0 * (nummodes1 - 1); i < GetNcoeffs(); i++)
779 {
780 outarray[cnt++] = i;
781 }
782 }
783}
784
786{
787 int i, j;
788 int cnt = 0;
789 int nummodes0, nummodes1;
790 int startvalue = 0;
791 if (outarray.size() != GetNcoeffs() - NumBndryCoeffs())
792 {
794 }
795
796 nummodes0 = m_base[0]->GetNumModes();
797 nummodes1 = m_base[1]->GetNumModes();
798
799 const LibUtilities::BasisType Btype0 = GetBasisType(0);
800 const LibUtilities::BasisType Btype1 = GetBasisType(1);
801
802 switch (Btype1)
803 {
805 startvalue = nummodes0;
806 break;
808 startvalue = 2 * nummodes0;
809 break;
810 default:
811 ASSERTL0(0, "Mapping array is not defined for this expansion");
812 break;
813 }
814
815 switch (Btype0)
816 {
818 startvalue++;
819 break;
821 startvalue += 2;
822 break;
823 default:
824 ASSERTL0(0, "Mapping array is not defined for this expansion");
825 break;
826 }
827
828 for (i = 0; i < nummodes1 - 2; i++)
829 {
830 for (j = 0; j < nummodes0 - 2; j++)
831 {
832 outarray[cnt++] = startvalue + j;
833 }
834 startvalue += nummodes0;
835 }
836}
837
838int StdQuadExp::v_GetVertexMap(int localVertexId, bool useCoeffPacking)
839{
840 int localDOF = 0;
841
842 if (useCoeffPacking == true)
843 {
844 switch (localVertexId)
845 {
846 case 0:
847 {
848 localDOF = 0;
849 }
850 break;
851 case 1:
852 {
854 {
855 localDOF = m_base[0]->GetNumModes() - 1;
856 }
857 else
858 {
859 localDOF = 1;
860 }
861 }
862 break;
863 case 2:
864 {
866 {
867 localDOF = m_base[0]->GetNumModes() *
868 (m_base[1]->GetNumModes() - 1);
869 }
870 else
871 {
872 localDOF = m_base[0]->GetNumModes();
873 }
874 }
875 break;
876 case 3:
877 {
879 {
880 localDOF =
881 m_base[0]->GetNumModes() * m_base[1]->GetNumModes() - 1;
882 }
883 else
884 {
885 localDOF = m_base[0]->GetNumModes() + 1;
886 }
887 }
888 break;
889 default:
890 ASSERTL0(false, "eid must be between 0 and 3");
891 break;
892 }
893 }
894 else
895 {
896 switch (localVertexId)
897 {
898 case 0:
899 {
900 localDOF = 0;
901 }
902 break;
903 case 1:
904 {
906 {
907 localDOF = m_base[0]->GetNumModes() - 1;
908 }
909 else
910 {
911 localDOF = 1;
912 }
913 }
914 break;
915 case 2:
916 {
918 {
919 localDOF =
920 m_base[0]->GetNumModes() * m_base[1]->GetNumModes() - 1;
921 }
922 else
923 {
924 localDOF = m_base[0]->GetNumModes() + 1;
925 }
926 }
927 break;
928 case 3:
929 {
931 {
932 localDOF = m_base[0]->GetNumModes() *
933 (m_base[1]->GetNumModes() - 1);
934 }
935 else
936 {
937 localDOF = m_base[0]->GetNumModes();
938 }
939 }
940 break;
941 default:
942 ASSERTL0(false, "eid must be between 0 and 3");
943 break;
944 }
945 }
946 return localDOF;
947}
948
949/** \brief Get the map of the coefficient location to teh
950 * local trace coefficients
951 */
952
953void StdQuadExp::v_GetTraceCoeffMap(const unsigned int traceid,
955{
956 ASSERTL1(traceid < 4, "traceid must be between 0 and 3");
957
958 unsigned int i;
959 unsigned int order0 = m_base[0]->GetNumModes();
960 unsigned int order1 = m_base[1]->GetNumModes();
961 unsigned int numModes = (traceid % 2) ? order1 : order0;
962
963 if (maparray.size() != numModes)
964 {
965 maparray = Array<OneD, unsigned int>(numModes);
966 }
967
968 const LibUtilities::BasisType bType = GetBasisType(traceid % 2);
969
970 if (bType == LibUtilities::eModified_A)
971 {
972 switch (traceid)
973 {
974 case 0:
975 {
976 for (i = 0; i < numModes; i++)
977 {
978 maparray[i] = i;
979 }
980 }
981 break;
982 case 1:
983 {
984 for (i = 0; i < numModes; i++)
985 {
986 maparray[i] = i * order0 + 1;
987 }
988 }
989 break;
990 case 2:
991 {
992 for (i = 0; i < numModes; i++)
993 {
994 maparray[i] = order0 + i;
995 }
996 }
997 break;
998 case 3:
999 {
1000 for (i = 0; i < numModes; i++)
1001 {
1002 maparray[i] = i * order0;
1003 }
1004 }
1005 break;
1006 default:
1007 break;
1008 }
1009 }
1010 else if (bType == LibUtilities::eGLL_Lagrange ||
1012 {
1013 switch (traceid)
1014 {
1015 case 0:
1016 {
1017 for (i = 0; i < numModes; i++)
1018 {
1019 maparray[i] = i;
1020 }
1021 }
1022 break;
1023 case 1:
1024 {
1025 for (i = 0; i < numModes; i++)
1026 {
1027 maparray[i] = (i + 1) * order0 - 1;
1028 }
1029 }
1030 break;
1031 case 2:
1032 {
1033 for (i = 0; i < numModes; i++)
1034 {
1035 maparray[i] = order0 * (order1 - 1) + i;
1036 }
1037 }
1038 break;
1039 case 3:
1040 {
1041 for (i = 0; i < numModes; i++)
1042 {
1043 maparray[i] = order0 * i;
1044 }
1045 }
1046 break;
1047 default:
1048 break;
1049 }
1050 }
1051 else
1052 {
1053 ASSERTL0(false, "Mapping not defined for this type of basis");
1054 }
1055}
1056
1058 const int eid, Array<OneD, unsigned int> &maparray,
1059 Array<OneD, int> &signarray, const Orientation edgeOrient)
1060{
1061 int i;
1062 const int nummodes0 = m_base[0]->GetNumModes();
1063 const int nummodes1 = m_base[1]->GetNumModes();
1064 const int nEdgeIntCoeffs = GetTraceNcoeffs(eid) - 2;
1065 const LibUtilities::BasisType bType = GetBasisType(eid % 2);
1066
1067 if (maparray.size() != nEdgeIntCoeffs)
1068 {
1069 maparray = Array<OneD, unsigned int>(nEdgeIntCoeffs);
1070 }
1071
1072 if (signarray.size() != nEdgeIntCoeffs)
1073 {
1074 signarray = Array<OneD, int>(nEdgeIntCoeffs, 1);
1075 }
1076 else
1077 {
1078 fill(signarray.data(), signarray.data() + nEdgeIntCoeffs, 1);
1079 }
1080
1081 if (bType == LibUtilities::eModified_A)
1082 {
1083 switch (eid)
1084 {
1085 case 0:
1086 {
1087 for (i = 0; i < nEdgeIntCoeffs; i++)
1088 {
1089 maparray[i] = i + 2;
1090 }
1091 }
1092 break;
1093 case 1:
1094 {
1095 for (i = 0; i < nEdgeIntCoeffs; i++)
1096 {
1097 maparray[i] = (i + 2) * nummodes0 + 1;
1098 }
1099 }
1100 break;
1101 case 2:
1102 {
1103 for (i = 0; i < nEdgeIntCoeffs; i++)
1104 {
1105 maparray[i] = nummodes0 + i + 2;
1106 }
1107 }
1108 break;
1109 case 3:
1110 {
1111 for (i = 0; i < nEdgeIntCoeffs; i++)
1112 {
1113 maparray[i] = (i + 2) * nummodes0;
1114 }
1115 }
1116 break;
1117 default:
1118 ASSERTL0(false, "eid must be between 0 and 3");
1119 break;
1120 }
1121
1122 if (edgeOrient == eBackwards)
1123 {
1124 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1125 {
1126 signarray[i] = -1;
1127 }
1128 }
1129 }
1130 else if (bType == LibUtilities::eGLL_Lagrange)
1131 {
1132 switch (eid)
1133 {
1134 case 0:
1135 {
1136 for (i = 0; i < nEdgeIntCoeffs; i++)
1137 {
1138 maparray[i] = i + 1;
1139 }
1140 }
1141 break;
1142 case 1:
1143 {
1144 for (i = 0; i < nEdgeIntCoeffs; i++)
1145 {
1146 maparray[i] = (i + 2) * nummodes0 - 1;
1147 }
1148 }
1149 break;
1150 case 2:
1151 {
1152 for (i = 0; i < nEdgeIntCoeffs; i++)
1153 {
1154 maparray[i] = nummodes0 * (nummodes1 - 1) + i + 1;
1155 }
1156 }
1157 break;
1158 case 3:
1159 {
1160 for (i = 0; i < nEdgeIntCoeffs; i++)
1161 {
1162 maparray[i] = nummodes0 * (i + 1);
1163 }
1164 }
1165 break;
1166 default:
1167 ASSERTL0(false, "eid must be between 0 and 3");
1168 break;
1169 }
1170 if (edgeOrient == eBackwards)
1171 {
1172 reverse(maparray.data(), maparray.data() + nEdgeIntCoeffs);
1173 }
1174 }
1175 else
1176 {
1177 ASSERTL0(false, "Mapping not defined for this type of basis");
1178 }
1179}
1180
1181///////////////////////
1182// Wrapper Functions //
1183///////////////////////
1184
1186{
1187 int i, j;
1188 int order0 = GetBasisNumModes(0);
1189 int order1 = GetBasisNumModes(1);
1190 MatrixType mtype = mkey.GetMatrixType();
1191
1192 DNekMatSharedPtr Mat;
1193
1194 switch (mtype)
1195 {
1197 {
1198 int nq0 = m_base[0]->GetNumPoints();
1199 int nq1 = m_base[1]->GetNumPoints();
1200 int nq;
1201
1202 // take definition from key
1204 {
1205 nq = (int)mkey.GetConstFactor(eFactorConst);
1206 }
1207 else
1208 {
1209 nq = max(nq0, nq1);
1210 }
1211
1212 int neq =
1215 Array<OneD, NekDouble> coll(2);
1217 Array<OneD, NekDouble> tmp(nq0);
1218
1219 Mat = MemoryManager<DNekMat>::AllocateSharedPtr(neq, nq0 * nq1);
1220 int cnt = 0;
1221
1222 for (i = 0; i < nq; ++i)
1223 {
1224 for (j = 0; j < nq; ++j, ++cnt)
1225 {
1226 coords[cnt] = Array<OneD, NekDouble>(2);
1227 coords[cnt][0] = -1.0 + 2 * j / (NekDouble)(nq - 1);
1228 coords[cnt][1] = -1.0 + 2 * i / (NekDouble)(nq - 1);
1229 }
1230 }
1231
1232 for (i = 0; i < neq; ++i)
1233 {
1234 LocCoordToLocCollapsed(coords[i], coll);
1235
1236 I[0] = m_base[0]->GetI(coll);
1237 I[1] = m_base[1]->GetI(coll + 1);
1238
1239 // interpolate first coordinate direction
1240 for (j = 0; j < nq1; ++j)
1241 {
1242 NekDouble fac = (I[1]->GetPtr())[j];
1243 Vmath::Smul(nq0, fac, I[0]->GetPtr(), 1, tmp, 1);
1244
1245 Vmath::Vcopy(nq0, &tmp[0], 1,
1246 Mat->GetRawPtr() + j * nq0 * neq + i, neq);
1247 }
1248 }
1249 break;
1250 }
1251 case ePhysInterpToGLL:
1252 {
1253 int nq0 = m_base[0]->GetNumPoints();
1254 int nq1 = m_base[1]->GetNumPoints();
1255 int nq;
1256
1257 // take definition from key
1259 {
1260 nq = (int)mkey.GetConstFactor(eFactorConst);
1261 }
1262 else
1263 {
1264 nq = max(nq0, nq1);
1265 }
1266
1267 int neq =
1270 Array<OneD, NekDouble> coll(2);
1272 Array<OneD, NekDouble> tmp(nq0);
1273
1274 Mat = MemoryManager<DNekMat>::AllocateSharedPtr(neq, nq0 * nq1);
1275 int cnt = 0;
1276
1277 const LibUtilities::PointsKey key(
1279
1281 LibUtilities::PointsManager()[key]->GetPoints(z);
1282
1283 for (int i = 0; i < nq; ++i)
1284 {
1285 for (int j = 0; j < nq; ++j, ++cnt)
1286 {
1287 coords[cnt] = Array<OneD, NekDouble>(2);
1288 coords[cnt][0] = z[j];
1289 coords[cnt][1] = z[i];
1290 }
1291 }
1292
1293 for (int i = 0; i < neq; ++i)
1294 {
1295 LocCoordToLocCollapsed(coords[i], coll);
1296
1297 I[0] = m_base[0]->GetI(coll);
1298 I[1] = m_base[1]->GetI(coll + 1);
1299
1300 // interpolate first coordinate direction
1301 for (int j = 0; j < nq1; ++j)
1302 {
1303 NekDouble fac = (I[1]->GetPtr())[j];
1304 Vmath::Smul(nq0, fac, I[0]->GetPtr(), 1, tmp, 1);
1305
1306 Vmath::Vcopy(nq0, &tmp[0], 1,
1307 Mat->GetRawPtr() + j * nq0 * neq + i, neq);
1308 }
1309 }
1310 break;
1311 }
1312 case eEquiSpacedToPhys:
1313 {
1314 int nm0 = m_base[0]->GetNumPoints();
1315 int nm1 = m_base[1]->GetNumPoints();
1316 int neq;
1317
1318 // take definition from key
1320 {
1321 neq = (int)mkey.GetConstFactor(eFactorConst);
1322 }
1323 else
1324 {
1325 neq = max(nm0, nm1);
1326 }
1327
1328 // set up an exansion with the same number of modes as neq;
1330 m_base[0]->GetPointsKey());
1332 m_base[1]->GetPointsKey());
1333
1334 StdQuadExp Exp2D(ba, bb);
1335 int ncoeffs = Exp2D.GetNcoeffs();
1336
1337 // Get hold of equispaced to coeff matrix
1338 ConstFactorMap cmap;
1339 cmap[eFactorConst] = neq;
1340 StdMatrixKey Ikey(eEquiSpacedToCoeffs, DetShapeType(), *this, cmap);
1341 DNekMatSharedPtr intmat = Exp2D.GetStdMatrix(Ikey);
1342
1343 int nqtot = GetTotPoints();
1344
1345 // generate a matrix
1346 Mat = MemoryManager<DNekMat>::AllocateSharedPtr(nqtot, ncoeffs);
1347 NekDouble *ptr = Mat->GetRawPtr();
1348
1349 Array<OneD, NekDouble> qmode(nqtot);
1350
1351 // Get first mode at quadrature points
1352 Exp2D.FillMode(0, qmode);
1353
1354 // first part of matrix-matrix multiply intiailising out matrix
1355 for (int j = 0; j < ncoeffs; ++j)
1356 {
1357 NekDouble val = (*intmat)(0, j);
1358 Vmath::Smul(nqtot, val, qmode.data(), 1, ptr + j * nqtot, 1);
1359 }
1360
1361 for (int i = 1; i < ncoeffs; ++i)
1362 {
1363 // Get mode at quadrature points
1364 Exp2D.FillMode(i, qmode);
1365
1366 for (int j = 0; j < ncoeffs; ++j)
1367 {
1368 NekDouble val = (*intmat)(i, j);
1369 Vmath::Svtvp(nqtot, val, qmode.data(), 1, ptr + j * nqtot,
1370 1, ptr + j * nqtot, 1);
1371 }
1372 }
1373 }
1374 break;
1375 case eMass:
1376 {
1378 // For Fourier basis set the imaginary component of mean mode
1379 // to have a unit diagonal component in mass matrix
1381 {
1382 for (i = 0; i < order1; ++i)
1383 {
1384 (*Mat)(order0 *i + 1, i * order0 + 1) = 1.0;
1385 }
1386 }
1387
1389 {
1390 for (i = 0; i < order0; ++i)
1391 {
1392 (*Mat)(order0 + i, order0 + i) = 1.0;
1393 }
1394 }
1395 break;
1396 }
1397 case eFwdTrans:
1398 {
1399 Mat =
1401 StdMatrixKey iprodkey(eIProductWRTBase, DetShapeType(), *this);
1402 DNekMat &Iprod = *GetStdMatrix(iprodkey);
1403 StdMatrixKey imasskey(eInvMass, DetShapeType(), *this);
1404 DNekMat &Imass = *GetStdMatrix(imasskey);
1405
1406 (*Mat) = Imass * Iprod;
1407 break;
1408 }
1409 case eGaussDG:
1410 {
1411 ConstFactorMap factors = mkey.GetConstFactors();
1412
1413 int edge = (int)factors[StdRegions::eFactorGaussEdge];
1414 int dir = (edge + 1) % 2;
1415 int nCoeffs = m_base[dir]->GetNumModes();
1416
1417 const LibUtilities::PointsKey BS_p(
1420 nCoeffs, BS_p);
1421
1422 Array<OneD, NekDouble> coords(1, 0.0);
1423 coords[0] = (edge == 0 || edge == 3) ? -1.0 : 1.0;
1424
1427 DNekMatSharedPtr m_Ix = basis->GetI(coords);
1428
1430 Vmath::Vcopy(nCoeffs, m_Ix->GetPtr(), 1, Mat->GetPtr(), 1);
1431 break;
1432 }
1433 default:
1434 {
1436 break;
1437 }
1438 }
1439
1440 return Mat;
1441}
1442
1444{
1445 return GenMatrix(mkey);
1446}
1447
1448///////////////////////////////////
1449// Operator evaluation functions //
1450///////////////////////////////////
1451
1453 const StdMatrixKey &mkey)
1454{
1455 // Generate an orthonogal expansion
1456 int qa = m_base[0]->GetNumPoints();
1457 int qb = m_base[1]->GetNumPoints();
1458 int nmodes_a = m_base[0]->GetNumModes();
1459 int nmodes_b = m_base[1]->GetNumModes();
1460 int nmodes = min(nmodes_a, nmodes_b);
1461 // Declare orthogonal basis.
1464
1467 StdQuadExp OrthoExp(Ba, Bb);
1468
1469 // SVV parameters loaded from the .xml case file
1470 Array<OneD, NekDouble> orthocoeffs(OrthoExp.GetNcoeffs());
1471
1472 // project onto modal space.
1473 OrthoExp.FwdTrans(array, orthocoeffs);
1474
1475 if (mkey.ConstFactorExists(
1476 eFactorSVVPowerKerDiffCoeff)) // Rodrigo's power kernel
1477 {
1479 NekDouble SvvDiffCoeff =
1482
1483 for (int j = 0; j < nmodes_a; ++j)
1484 {
1485 for (int k = 0; k < nmodes_b; ++k)
1486 {
1487 // linear space but makes high modes very negative
1488 NekDouble fac = std::max(
1489 pow((1.0 * j) / (nmodes_a - 1), cutoff * nmodes_a),
1490 pow((1.0 * k) / (nmodes_b - 1), cutoff * nmodes_b));
1491
1492 orthocoeffs[j * nmodes_b + k] *= SvvDiffCoeff * fac;
1493 }
1494 }
1495 }
1496 else if (mkey.ConstFactorExists(
1497 eFactorSVVDGKerDiffCoeff)) // Rodrigo/mansoor's DG kernel
1498 {
1501 int max_ab = max(nmodes_a - kSVVDGFiltermodesmin,
1502 nmodes_b - kSVVDGFiltermodesmin);
1503 max_ab = max(max_ab, 0);
1504 max_ab = min(max_ab, kSVVDGFiltermodesmax - kSVVDGFiltermodesmin);
1505
1506 for (int j = 0; j < nmodes_a; ++j)
1507 {
1508 for (int k = 0; k < nmodes_b; ++k)
1509 {
1510 int maxjk = max(j, k);
1511 maxjk = min(maxjk, kSVVDGFiltermodesmax - 1);
1512
1513 orthocoeffs[j * nmodes_b + k] *=
1514 SvvDiffCoeff * kSVVDGFilter[max_ab][maxjk];
1515 }
1516 }
1517 }
1518 else
1519 {
1520 NekDouble SvvDiffCoeff = mkey.GetConstFactor(eFactorSVVDiffCoeff);
1521 // Exponential Kernel implementation
1522 int cutoff = (int)(mkey.GetConstFactor(eFactorSVVCutoffRatio) *
1523 min(nmodes_a, nmodes_b));
1524
1525 //------"New" Version August 22nd '13--------------------
1526 for (int j = 0; j < nmodes_a; ++j)
1527 {
1528 for (int k = 0; k < nmodes_b; ++k)
1529 {
1530 if (j + k >= cutoff) // to filter out only the "high-modes"
1531 {
1532 orthocoeffs[j * nmodes_b + k] *=
1533 (SvvDiffCoeff *
1534 exp(-(j + k - nmodes) * (j + k - nmodes) /
1535 ((NekDouble)((j + k - cutoff + 1) *
1536 (j + k - cutoff + 1)))));
1537 }
1538 else
1539 {
1540 orthocoeffs[j * nmodes_b + k] *= 0.0;
1541 }
1542 }
1543 }
1544 }
1545
1546 // backward transform to physical space
1547 OrthoExp.BwdTrans(orthocoeffs, array);
1548}
1549
1551 const NekDouble alpha,
1552 const NekDouble exponent,
1553 const NekDouble cutoff)
1554{
1555 // Generate an orthogonal expansion
1556 int qa = m_base[0]->GetNumPoints();
1557 int qb = m_base[1]->GetNumPoints();
1558 int nmodesA = m_base[0]->GetNumModes();
1559 int nmodesB = m_base[1]->GetNumModes();
1560 int P = nmodesA - 1;
1561 int Q = nmodesB - 1;
1562
1563 // Declare orthogonal basis.
1566
1569 StdQuadExp OrthoExp(Ba, Bb);
1570
1571 // Cutoff
1572 int Pcut = cutoff * P;
1573 int Qcut = cutoff * Q;
1574
1575 // Project onto orthogonal space.
1576 Array<OneD, NekDouble> orthocoeffs(OrthoExp.GetNcoeffs());
1577 OrthoExp.FwdTrans(array, orthocoeffs);
1578
1579 //
1580 NekDouble fac, fac1, fac2;
1581 for (int i = 0; i < nmodesA; ++i)
1582 {
1583 for (int j = 0; j < nmodesB; ++j)
1584 {
1585 // to filter out only the "high-modes"
1586 if (i > Pcut || j > Qcut)
1587 {
1588 fac1 = (NekDouble)(i - Pcut) / ((NekDouble)(P - Pcut));
1589 fac2 = (NekDouble)(j - Qcut) / ((NekDouble)(Q - Qcut));
1590 fac = max(fac1, fac2);
1591 fac = pow(fac, exponent);
1592 orthocoeffs[i * nmodesB + j] *= exp(-alpha * fac);
1593 }
1594 }
1595 }
1596
1597 // backward transform to physical space
1598 OrthoExp.BwdTrans(orthocoeffs, array);
1599}
1600
1602 int numMin, const Array<OneD, const NekDouble> &inarray,
1603 Array<OneD, NekDouble> &outarray)
1604{
1605 int n_coeffs = inarray.size();
1606
1607 Array<OneD, NekDouble> coeff(n_coeffs);
1608 Array<OneD, NekDouble> coeff_tmp(n_coeffs, 0.0);
1611
1612 int nmodes0 = m_base[0]->GetNumModes();
1613 int nmodes1 = m_base[1]->GetNumModes();
1614 int numMax = nmodes0;
1615
1616 Vmath::Vcopy(n_coeffs, inarray, 1, coeff_tmp, 1);
1617
1618 const LibUtilities::PointsKey Pkey0(nmodes0,
1620 const LibUtilities::PointsKey Pkey1(nmodes1,
1622
1623 LibUtilities::BasisKey b0(m_base[0]->GetBasisType(), nmodes0, Pkey0);
1624 LibUtilities::BasisKey b1(m_base[1]->GetBasisType(), nmodes1, Pkey1);
1625
1626 LibUtilities::BasisKey bortho0(LibUtilities::eOrtho_A, nmodes0, Pkey0);
1627 LibUtilities::BasisKey bortho1(LibUtilities::eOrtho_A, nmodes1, Pkey1);
1628
1629 LibUtilities::InterpCoeff2D(b0, b1, coeff_tmp, bortho0, bortho1, coeff);
1630
1631 Vmath::Zero(n_coeffs, coeff_tmp, 1);
1632
1633 int cnt = 0;
1634 for (int i = 0; i < numMin + 1; ++i)
1635 {
1636 Vmath::Vcopy(numMin, tmp = coeff + cnt, 1, tmp2 = coeff_tmp + cnt, 1);
1637
1638 cnt = i * numMax;
1639 }
1640
1641 LibUtilities::InterpCoeff2D(bortho0, bortho1, coeff_tmp, b0, b1, outarray);
1642}
1643
1645 Array<OneD, NekDouble> &outarray,
1646 const StdMatrixKey &mkey)
1647{
1648 StdExpansion::MassMatrixOp_MatFree(inarray, outarray, mkey);
1649}
1650
1652 const Array<OneD, const NekDouble> &inarray,
1653 Array<OneD, NekDouble> &outarray, const StdMatrixKey &mkey)
1654{
1655 StdQuadExp::v_LaplacianMatrixOp_MatFree(inarray, outarray, mkey);
1656}
1657
1659 const int k1, const int k2, const Array<OneD, const NekDouble> &inarray,
1660 Array<OneD, NekDouble> &outarray, const StdMatrixKey &mkey)
1661{
1662 StdExpansion::LaplacianMatrixOp_MatFree(k1, k2, inarray, outarray, mkey);
1663}
1664
1666 const int i, const Array<OneD, const NekDouble> &inarray,
1667 Array<OneD, NekDouble> &outarray, const StdMatrixKey &mkey)
1668{
1669 StdExpansion::WeakDerivMatrixOp_MatFree(i, inarray, outarray, mkey);
1670}
1671
1673 const Array<OneD, const NekDouble> &inarray,
1674 Array<OneD, NekDouble> &outarray, const StdMatrixKey &mkey)
1675{
1676 StdQuadExp::v_HelmholtzMatrixOp_MatFree(inarray, outarray, mkey);
1677}
1678
1680 Array<OneD, int> &conn, [[maybe_unused]] bool standard)
1681{
1682 int np1 = m_base[0]->GetNumPoints();
1683 int np2 = m_base[1]->GetNumPoints();
1684 int np = max(np1, np2);
1685
1686 conn = Array<OneD, int>(6 * (np - 1) * (np - 1));
1687
1688 int row = 0;
1689 int rowp1 = 0;
1690 int cnt = 0;
1691 for (int i = 0; i < np - 1; ++i)
1692 {
1693 rowp1 += np;
1694 for (int j = 0; j < np - 1; ++j)
1695 {
1696 conn[cnt++] = row + j;
1697 conn[cnt++] = row + j + 1;
1698 conn[cnt++] = rowp1 + j;
1699
1700 conn[cnt++] = rowp1 + j + 1;
1701 conn[cnt++] = rowp1 + j;
1702 conn[cnt++] = row + j + 1;
1703 }
1704 row += np;
1705 }
1706}
1707
1708} // namespace Nektar::StdRegions
#define ASSERTL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
#define sign(a, b)
return the sign(b)*a
Definition Polylib.cpp:47
#define BWDTRANS_M(r, i)
#define IPRODUCTWRTBASE_DEF
#define BWDTRANS_DEF
#define IPRODUCTWRTBASE_M(r, i)
#define STDLEV2TEST(r, state)
#define STDLEV2UPDATE(r, state)
Describes the specification for a Basis.
Definition Basis.h:45
Defines a specification for a set of points.
Definition Points.h:50
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
void PhysTensorDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray_d0, Array< OneD, NekDouble > &outarray_d1)
Calculate the 2D derivative in the local tensor/collapsed coordinate at the physical points.
NekDouble BaryTensorDeriv(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs)
The base class for all shapes.
virtual void v_LaplacianMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
const LibUtilities::BasisSharedPtr & GetBasis(int dir) const
This function gets the shared point to basis in the dir direction.
int GetNcoeffs(void) const
This function returns the total number of coefficients used in the expansion.
int GetTotPoints() const
This function returns the total number of quadrature points used in the element.
void FillMode(const int mode, Array< OneD, NekDouble > &outarray)
This function fills the array outarray with the mode-th mode of the expansion.
void WeakDerivMatrixOp_MatFree(const int i, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
LibUtilities::BasisType GetBasisType(const int dir) const
This function returns the type of basis used in the dir direction.
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
void LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta)
Convert local cartesian coordinate xi into local collapsed coordinates eta.
void MassMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
virtual void v_HelmholtzMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
DNekMatSharedPtr CreateGeneralMatrix(const StdMatrixKey &mkey)
this function generates the mass matrix
void IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
this function calculates the inner product of a given function f with the different modes of the expa...
void LaplacianMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
void GetTraceToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, Orientation traceOrient=eForwards, int P=-1, int Q=-1)
LibUtilities::ShapeType DetShapeType() const
This function returns the shape of the expansion domain.
void GetInteriorMap(Array< OneD, unsigned int > &outarray)
void BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function performs the Backward transformation from coefficient space to physical space.
int GetTraceNcoeffs(const int i) const
This function returns the number of expansion coefficients belonging to the i-th trace.
DNekMatSharedPtr GenMatrix(const StdMatrixKey &mkey)
LibUtilities::PointsType GetPointsType(const int dir) const
This function returns the type of quadrature points used in the dir direction.
void FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
LibUtilities::NekManager< StdMatrixKey, DNekBlkMat, StdMatrixKey::opLess > m_stdStaticCondMatrixManager
int GetNumPoints(const int dir) const
This function returns the number of quadrature points in the dir direction.
int GetBasisNumModes(const int dir) const
This function returns the number of expansion modes in the dir direction.
Array< OneD, LibUtilities::BasisSharedPtr > m_base
std::vector< Array< OneD, const NekDouble > > m_weights
void MassMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
MatrixType GetMatrixType() const
const ConstFactorMap & GetConstFactors() const
NekDouble GetConstFactor(const ConstFactorType &factor) const
bool ConstFactorExists(const ConstFactorType &factor) const
void v_ExponentialFilter(Array< OneD, NekDouble > &array, const NekDouble alpha, const NekDouble exponent, const NekDouble cutoff) override
int v_NumDGBndryCoeffs() const final
void v_FwdTransBndConstrained(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta) override
int v_GetVertexMap(int localVertexId, bool useCoeffPacking=false) override
bool v_IsBoundaryInteriorExpansion() const override
int v_GetTraceNcoeffs(const int i) const final
void v_ReduceOrderCoeffs(int numMin, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
int v_GetTraceNumPoints(const int i) const final
void v_HelmholtzMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
int v_NumBndryCoeffs() const final
void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdMatrixKey &mkey) override
void v_GetCoords(Array< OneD, NekDouble > &coords_0, Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2) override
NekDouble v_PhysEvaluateBasis(const Array< OneD, const NekDouble > &coords, int mode) override
This function evaluates the basis function mode mode at a point coords of the domain.
int v_CalcNumberOfCoefficients(const std::vector< unsigned int > &nummodes, int &modes_offset) override
void v_GetInteriorMap(Array< OneD, unsigned int > &outarray) override
void v_StdPhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1, Array< OneD, NekDouble > &out_d2=NullNekDouble1DArray) override
Calculate the derivative of the physical points.
void v_BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_WeakDerivMatrixOp(const int i, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
void v_LocCollapsedToLocCoord(const Array< OneD, const NekDouble > &eta, Array< OneD, NekDouble > &xi) override
NekDouble v_PhysEvalFirstDeriv(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs) override
void v_GetTraceCoeffMap(const unsigned int traceid, Array< OneD, unsigned int > &maparray) override
Get the map of the coefficient location to teh local trace coefficients.
const LibUtilities::BasisKey v_GetTraceBasisKey(const int i, const int j, bool UseGLL=false) const final
DNekMatSharedPtr v_CreateStdMatrix(const StdMatrixKey &mkey) override
void v_GetSimplexEquiSpacedConnectivity(Array< OneD, int > &conn, bool standard=true) override
void v_MassMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_GetTraceInteriorToElementMap(const int eid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation edgeOrient=eForwards) override
void v_GetBoundaryMap(Array< OneD, unsigned int > &outarray) override
DNekMatSharedPtr v_GenMatrix(const StdMatrixKey &mkey) override
int v_GetTraceIntNcoeffs(const int i) const final
StdQuadExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb)
Constructor using BasisKey class for quadrature points and order definition.
void v_LaplacianMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
LibUtilities::ShapeType v_DetShapeType() const final
void v_FillMode(const int mode, Array< OneD, NekDouble > &array) override
Fill outarray with mode mode of expansion.
void v_IProductWRTBaseKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const Array< OneD, NekDouble > &jac, const bool Deformed, const bool CollDir0=false, const bool CollDir1=false) override
Inner product of inarray over region with respect to the expansion basis (this)->m_base[0] and return...
static void Dgemv(const char &trans, const int &m, const int &n, const double &alpha, const double *a, const int &lda, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = alpha A x plus beta y where A[m x n].
Definition Blas.hpp:152
constexpr int getNumberOfCoefficients(int Na, int Nb)
BasisManagerT & BasisManager(void)
std::shared_ptr< Basis > BasisSharedPtr
PointsManagerT & PointsManager(void)
void InterpCoeff2D(const BasisKey &fbasis0, const BasisKey &fbasis1, const Array< OneD, const NekDouble > &from, const BasisKey &tbasis0, const BasisKey &tbasis1, Array< OneD, NekDouble > &to)
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
Definition PointsType.h:51
@ eGaussGaussLegendre
1D Gauss-Gauss-Legendre quadrature points
Definition PointsType.h:46
@ eGauss_Lagrange
Lagrange Polynomials using the Gauss points.
Definition BasisType.h:57
@ eOrtho_A
Principle Orthogonal Functions .
Definition BasisType.h:42
@ eGLL_Lagrange
Lagrange for SEM basis .
Definition BasisType.h:56
@ eModified_A
Principle Modified Functions .
Definition BasisType.h:48
@ eFourier
Fourier Expansion .
Definition BasisType.h:55
static const NekDouble kNekZeroTol
const int kSVVDGFiltermodesmin
tinysimd::scalarT< double > vec_t
const int kSVVDGFiltermodesmax
const NekDouble kSVVDGFilter[9][11]
std::map< ConstFactorType, NekDouble > ConstFactorMap
std::shared_ptr< StdSegExp > StdSegExpSharedPtr
Definition StdSegExp.h:182
std::shared_ptr< DNekMat > DNekMatSharedPtr
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 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 Zero(int n, T *x, const int incx)
Zero vector.
Definition Vmath.hpp:273
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition Vmath.hpp:54
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition Vmath.hpp:825
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
Definition Vmath.hpp:220
STL namespace.
scalarT< T > max(scalarT< T > lhs, scalarT< T > rhs)
Definition scalar.hpp:305
scalarT< T > min(scalarT< T > lhs, scalarT< T > rhs)
Definition scalar.hpp:300