Nektar++
StdTriExp.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: StdTriExp.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: Triangle routines built upon StdExpansion2D
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#include <boost/core/ignore_unused.hpp>
36
39#include <StdRegions/StdSegExp.h> // for StdSegExp, etc
41
42using namespace std;
43
44namespace Nektar
45{
46namespace StdRegions
47{
49{
50}
51
53 const LibUtilities::BasisKey &Bb)
54 : StdExpansion(LibUtilities::StdTriData::getNumberOfCoefficients(
55 Ba.GetNumModes(), Bb.GetNumModes()),
56 2, Ba, Bb),
57 StdExpansion2D(LibUtilities::StdTriData::getNumberOfCoefficients(
58 Ba.GetNumModes(), Bb.GetNumModes()),
59 Ba, Bb)
60{
61 ASSERTL0(Ba.GetNumModes() <= Bb.GetNumModes(),
62 "order in 'a' direction is higher than order "
63 "in 'b' direction");
64}
65
67{
68}
69
70// Destructor
72{
73}
74
75//-------------------------------
76// Integration Methods
77//-------------------------------
79{
80 int i;
81 int nquad1 = m_base[1]->GetNumPoints();
82 Array<OneD, NekDouble> w1_tmp(nquad1);
83
87
88 switch (m_base[1]->GetPointsType())
89 {
90 case LibUtilities::eGaussRadauMAlpha1Beta0: // (0,1) Jacobi Inner
91 // product
92 {
93 Vmath::Smul(nquad1, 0.5, w1, 1, w1_tmp, 1);
94 break;
95 }
96 default:
97 {
98 // include jacobian factor on whatever coordinates are defined.
99 for (i = 0; i < nquad1; ++i)
100 {
101 w1_tmp[i] = 0.5 * (1 - z1[i]) * w1[i];
102 }
103 break;
104 }
105 }
106
107 return StdExpansion2D::Integral(inarray, w0, w1_tmp);
108}
109
110//-----------------------------
111// Differentiation Methods
112//-----------------------------
113
114/**
115 * \brief Calculate the derivative of the physical points.
116 *
117 * \f$ \frac{\partial u}{\partial x_1} = \left .
118 * \frac{2.0}{1-\eta_2} \frac{\partial u}{\partial d\eta_1}
119 * \right |_{\eta_2}\f$
120 *
121 * \f$ \frac{\partial u}{\partial x_2} = \left .
122 * \frac{1+\eta_1}{1-\eta_2} \frac{\partial u}{\partial d\eta_1}
123 * \right |_{\eta_2} + \left . \frac{\partial u}{\partial d\eta_2}
124 * \right |_{\eta_1} \f$
125 */
130{
131 boost::ignore_unused(out_d2);
132
133 int i;
134 int nquad0 = m_base[0]->GetNumPoints();
135 int nquad1 = m_base[1]->GetNumPoints();
136 Array<OneD, NekDouble> wsp(std::max(nquad0, nquad1));
137
138 const Array<OneD, const NekDouble> &z0 = m_base[0]->GetZ();
139 const Array<OneD, const NekDouble> &z1 = m_base[1]->GetZ();
140
141 // set up geometric factor: 2/(1-z1)
142 Vmath::Sadd(nquad1, -1.0, z1, 1, wsp, 1);
143 Vmath::Sdiv(nquad1, -2.0, wsp, 1, wsp, 1);
144
145 if (out_d0.size() > 0)
146 {
147 PhysTensorDeriv(inarray, out_d0, out_d1);
148
149 for (i = 0; i < nquad1; ++i)
150 {
151 Blas::Dscal(nquad0, wsp[i], &out_d0[0] + i * nquad0, 1);
152 }
153
154 // if no d1 required do not need to calculate both deriv
155 if (out_d1.size() > 0)
156 {
157 // set up geometric factor: (1+z0)/2
158 Vmath::Sadd(nquad0, 1.0, z0, 1, wsp, 1);
159 Vmath::Smul(nquad0, 0.5, wsp, 1, wsp, 1);
160
161 for (i = 0; i < nquad1; ++i)
162 {
163 Vmath::Vvtvp(nquad0, &wsp[0], 1, &out_d0[0] + i * nquad0, 1,
164 &out_d1[0] + i * nquad0, 1,
165 &out_d1[0] + i * nquad0, 1);
166 }
167 }
168 }
169 else if (out_d1.size() > 0)
170 {
171 Array<OneD, NekDouble> diff0(nquad0 * nquad1);
172 PhysTensorDeriv(inarray, diff0, out_d1);
173
174 for (i = 0; i < nquad1; ++i)
175 {
176 Blas::Dscal(nquad0, wsp[i], &diff0[0] + i * nquad0, 1);
177 }
178
179 Vmath::Sadd(nquad0, 1.0, z0, 1, wsp, 1);
180 Vmath::Smul(nquad0, 0.5, wsp, 1, wsp, 1);
181
182 for (i = 0; i < nquad1; ++i)
183 {
184 Vmath::Vvtvp(nquad0, &wsp[0], 1, &diff0[0] + i * nquad0, 1,
185 &out_d1[0] + i * nquad0, 1, &out_d1[0] + i * nquad0,
186 1);
187 }
188 }
189}
190
191void StdTriExp::v_PhysDeriv(const int dir,
192 const Array<OneD, const NekDouble> &inarray,
193 Array<OneD, NekDouble> &outarray)
194{
195 switch (dir)
196 {
197 case 0:
198 {
199 v_PhysDeriv(inarray, outarray, NullNekDouble1DArray);
200 break;
201 }
202 case 1:
203 {
204 v_PhysDeriv(inarray, NullNekDouble1DArray, outarray);
205 break;
206 }
207 default:
208 {
209 ASSERTL1(false, "input dir is out of range");
210 break;
211 }
212 }
213}
214
219{
220 boost::ignore_unused(out_d2);
221 StdTriExp::v_PhysDeriv(inarray, out_d0, out_d1);
222}
223
224void StdTriExp::v_StdPhysDeriv(const int dir,
225 const Array<OneD, const NekDouble> &inarray,
226 Array<OneD, NekDouble> &outarray)
227{
228 StdTriExp::v_PhysDeriv(dir, inarray, outarray);
229}
230
231//---------------------------------------
232// Transforms
233//---------------------------------------
234
235/**
236 * \brief Backward tranform for triangular elements
237 *
238 * @note 'q' (base[1]) runs fastest in this element.
239 */
241 Array<OneD, NekDouble> &outarray)
242{
243 v_BwdTrans_SumFac(inarray, outarray);
244}
245
247 Array<OneD, NekDouble> &outarray)
248{
250 m_base[0]->GetNumModes());
251
252 BwdTrans_SumFacKernel(m_base[0]->GetBdata(), m_base[1]->GetBdata(), inarray,
253 outarray, wsp);
254}
255
257 const Array<OneD, const NekDouble> &base0,
258 const Array<OneD, const NekDouble> &base1,
259 const Array<OneD, const NekDouble> &inarray,
261 bool doCheckCollDir0, bool doCheckCollDir1)
262{
263 boost::ignore_unused(doCheckCollDir0, doCheckCollDir1);
264
265 int i;
266 int mode;
267 int nquad0 = m_base[0]->GetNumPoints();
268 int nquad1 = m_base[1]->GetNumPoints();
269 int nmodes0 = m_base[0]->GetNumModes();
270 int nmodes1 = m_base[1]->GetNumModes();
271
272 ASSERTL1(wsp.size() >= nquad1 * nmodes0,
273 "Workspace size is not sufficient");
276 "Basis[1] is not of general tensor type");
277
278 for (i = mode = 0; i < nmodes0; ++i)
279 {
280 Blas::Dgemv('N', nquad1, nmodes1 - i, 1.0, base1.get() + mode * nquad1,
281 nquad1, &inarray[0] + mode, 1, 0.0, &wsp[0] + i * nquad1,
282 1);
283 mode += nmodes1 - i;
284 }
285
286 // fix for modified basis by splitting top vertex mode
288 {
289 Blas::Daxpy(nquad1, inarray[1], base1.get() + nquad1, 1,
290 &wsp[0] + nquad1, 1);
291 }
292
293 Blas::Dgemm('N', 'T', nquad0, nquad1, nmodes0, 1.0, base0.get(), nquad0,
294 &wsp[0], nquad1, 0.0, &outarray[0], nquad0);
295}
296
298 Array<OneD, NekDouble> &outarray)
299{
300 v_IProductWRTBase(inarray, outarray);
301
302 // get Mass matrix inverse
303 StdMatrixKey masskey(eInvMass, DetShapeType(), *this);
304 DNekMatSharedPtr matsys = GetStdMatrix(masskey);
305
306 // copy inarray in case inarray == outarray
307 NekVector<NekDouble> in(m_ncoeffs, outarray, eCopy);
309
310 out = (*matsys) * in;
311}
312
314 const Array<OneD, const NekDouble> &inarray,
315 Array<OneD, NekDouble> &outarray)
316{
317 int i, j;
318 int npoints[2] = {m_base[0]->GetNumPoints(), m_base[1]->GetNumPoints()};
319 int nmodes[2] = {m_base[0]->GetNumModes(), m_base[1]->GetNumModes()};
320
321 fill(outarray.get(), outarray.get() + m_ncoeffs, 0.0);
322
323 Array<OneD, NekDouble> physEdge[3];
324 Array<OneD, NekDouble> coeffEdge[3];
325 for (i = 0; i < 3; i++)
326 {
327 physEdge[i] = Array<OneD, NekDouble>(npoints[i != 0]);
328 coeffEdge[i] = Array<OneD, NekDouble>(nmodes[i != 0]);
329 }
330
331 for (i = 0; i < npoints[0]; i++)
332 {
333 physEdge[0][i] = inarray[i];
334 }
335
336 for (i = 0; i < npoints[1]; i++)
337 {
338 physEdge[1][i] = inarray[npoints[0] - 1 + i * npoints[0]];
339 physEdge[2][i] =
340 inarray[(npoints[1] - 1) * npoints[0] - i * npoints[0]];
341 }
342
343 StdSegExpSharedPtr segexp[2] = {
345 m_base[0]->GetBasisKey()),
347 m_base[1]->GetBasisKey())};
348
350 Array<OneD, int> signArray;
352
353 for (i = 0; i < 3; i++)
354 {
355 segexp[i != 0]->FwdTransBndConstrained(physEdge[i], coeffEdge[i]);
356
357 GetTraceToElementMap(i, mapArray, signArray);
358 for (j = 0; j < nmodes[i != 0]; j++)
359 {
360 sign = (NekDouble)signArray[j];
361 outarray[mapArray[j]] = sign * coeffEdge[i][j];
362 }
363 }
364
367
368 StdMatrixKey masskey(eMass, DetShapeType(), *this);
369 MassMatrixOp(outarray, tmp0, masskey);
370 v_IProductWRTBase(inarray, tmp1);
371
372 Vmath::Vsub(m_ncoeffs, tmp1, 1, tmp0, 1, tmp1, 1);
373
374 // get Mass matrix inverse (only of interior DOF)
375 // use block (1,1) of the static condensed system
376 // note: this block alreay contains the inverse matrix
377 DNekMatSharedPtr matsys =
378 (m_stdStaticCondMatrixManager[masskey])->GetBlock(1, 1);
379
380 int nBoundaryDofs = v_NumBndryCoeffs();
381 int nInteriorDofs = m_ncoeffs - nBoundaryDofs;
382
383 Array<OneD, NekDouble> rhs(nInteriorDofs);
384 Array<OneD, NekDouble> result(nInteriorDofs);
385
386 v_GetInteriorMap(mapArray);
387
388 for (i = 0; i < nInteriorDofs; i++)
389 {
390 rhs[i] = tmp1[mapArray[i]];
391 }
392
393 Blas::Dgemv('N', nInteriorDofs, nInteriorDofs, 1.0, &(matsys->GetPtr())[0],
394 nInteriorDofs, rhs.get(), 1, 0.0, result.get(), 1);
395
396 for (i = 0; i < nInteriorDofs; i++)
397 {
398 outarray[mapArray[i]] = result[i];
399 }
400}
401
402//---------------------------------------
403// Inner product functions
404//---------------------------------------
405
406/**
407 * \brief Calculate the inner product of inarray with respect to the
408 * basis B=base0[p]*base1[pq] and put into outarray.
409 *
410 * \f$
411 * \begin{array}{rcl}
412 * I_{pq} = (\phi^A_q \phi^B_{pq}, u) &=&
413 * \sum_{i=0}^{nq_0}\sum_{j=0}^{nq_1}
414 * \phi^A_p(\eta_{0,i})\phi^B_{pq}(\eta_{1,j}) w^0_i w^1_j
415 * u(\xi_{0,i} \xi_{1,j}) \\
416 * & = & \sum_{i=0}^{nq_0} \phi^A_p(\eta_{0,i})
417 * \sum_{j=0}^{nq_1} \phi^B_{pq}(\eta_{1,j}) \tilde{u}_{i,j}
418 * \end{array}
419 * \f$
420 *
421 * where
422 *
423 * \f$ \tilde{u}_{i,j} = w^0_i w^1_j u(\xi_{0,i},\xi_{1,j}) \f$
424 *
425 * which can be implemented as
426 *
427 * \f$ f_{pj} = \sum_{i=0}^{nq_0} \phi^A_p(\eta_{0,i})
428 * \tilde{u}_{i,j}
429 * \rightarrow {\bf B_1 U} \f$
430 * \f$ I_{pq} = \sum_{j=0}^{nq_1} \phi^B_{pq}(\eta_{1,j}) f_{pj}
431 * \rightarrow {\bf B_2[p*skip] f[skip]} \f$
432 *
433 * \b Recall: \f$ \eta_{1} = \frac{2(1+\xi_1)}{(1-\xi_2)}-1, \,
434 * \eta_2 = \xi_2\f$
435 *
436 * \b Note: For the orthgonality of this expansion to be realised the
437 * 'q' ordering must run fastest in contrast to the Quad and Hex
438 * ordering where 'p' index runs fastest to be consistent with the
439 * quadrature ordering.
440 *
441 * In the triangular space the i (i.e. \f$\eta_1\f$ direction)
442 * ordering still runs fastest by convention.
443 */
445 Array<OneD, NekDouble> &outarray)
446{
447 StdTriExp::v_IProductWRTBase_SumFac(inarray, outarray);
448}
449
451 const Array<OneD, const NekDouble> &inarray,
452 Array<OneD, NekDouble> &outarray, bool multiplybyweights)
453{
454 int nquad0 = m_base[0]->GetNumPoints();
455 int nquad1 = m_base[1]->GetNumPoints();
456 int order0 = m_base[0]->GetNumModes();
457
458 if (multiplybyweights)
459 {
460 Array<OneD, NekDouble> tmp(nquad0 * nquad1 + nquad1 * order0);
461 Array<OneD, NekDouble> wsp(tmp + nquad0 * nquad1);
462
463 // multiply by integration constants
464 MultiplyByQuadratureMetric(inarray, tmp);
466 m_base[1]->GetBdata(), tmp, outarray, wsp);
467 }
468 else
469 {
470 Array<OneD, NekDouble> wsp(nquad1 * order0);
472 m_base[1]->GetBdata(), inarray, outarray,
473 wsp);
474 }
475}
476
478 const Array<OneD, const NekDouble> &base0,
479 const Array<OneD, const NekDouble> &base1,
480 const Array<OneD, const NekDouble> &inarray,
482 bool doCheckCollDir0, bool doCheckCollDir1)
483{
484 boost::ignore_unused(doCheckCollDir0, doCheckCollDir1);
485
486 int i;
487 int mode;
488 int nquad0 = m_base[0]->GetNumPoints();
489 int nquad1 = m_base[1]->GetNumPoints();
490 int nmodes0 = m_base[0]->GetNumModes();
491 int nmodes1 = m_base[1]->GetNumModes();
492
493 ASSERTL1(wsp.size() >= nquad1 * nmodes0,
494 "Workspace size is not sufficient");
495
496 Blas::Dgemm('T', 'N', nquad1, nmodes0, nquad0, 1.0, inarray.get(), nquad0,
497 base0.get(), nquad0, 0.0, wsp.get(), nquad1);
498
499 // Inner product with respect to 'b' direction
500 for (mode = i = 0; i < nmodes0; ++i)
501 {
502 Blas::Dgemv('T', nquad1, nmodes1 - i, 1.0, base1.get() + mode * nquad1,
503 nquad1, wsp.get() + i * nquad1, 1, 0.0,
504 outarray.get() + mode, 1);
505 mode += nmodes1 - i;
506 }
507
508 // fix for modified basis by splitting top vertex mode
510 {
511 outarray[1] +=
512 Blas::Ddot(nquad1, base1.get() + nquad1, 1, wsp.get() + nquad1, 1);
513 }
514}
515
517 const int dir, const Array<OneD, const NekDouble> &inarray,
518 Array<OneD, NekDouble> &outarray)
519{
520 StdTriExp::v_IProductWRTDerivBase_SumFac(dir, inarray, outarray);
521}
522
524 const int dir, const Array<OneD, const NekDouble> &inarray,
525 Array<OneD, NekDouble> &outarray)
526{
527 int i;
528 int nquad0 = m_base[0]->GetNumPoints();
529 int nquad1 = m_base[1]->GetNumPoints();
530 int nqtot = nquad0 * nquad1;
531 int nmodes0 = m_base[0]->GetNumModes();
532 int wspsize = max(max(nqtot, m_ncoeffs), nquad1 * nmodes0);
533
534 Array<OneD, NekDouble> gfac0(2 * wspsize);
535 Array<OneD, NekDouble> tmp0(gfac0 + wspsize);
536
537 const Array<OneD, const NekDouble> &z1 = m_base[1]->GetZ();
538
539 // set up geometric factor: 2/(1-z1)
540 for (i = 0; i < nquad1; ++i)
541 {
542 gfac0[i] = 2.0 / (1 - z1[i]);
543 }
544
545 for (i = 0; i < nquad1; ++i)
546 {
547 Vmath::Smul(nquad0, gfac0[i], &inarray[0] + i * nquad0, 1,
548 &tmp0[0] + i * nquad0, 1);
549 }
550
551 MultiplyByQuadratureMetric(tmp0, tmp0);
552
553 switch (dir)
554 {
555 case 0:
556 {
557 IProductWRTBase_SumFacKernel(m_base[0]->GetDbdata(),
558 m_base[1]->GetBdata(), tmp0, outarray,
559 gfac0);
560 break;
561 }
562 case 1:
563 {
565 const Array<OneD, const NekDouble> &z0 = m_base[0]->GetZ();
566
567 for (i = 0; i < nquad0; ++i)
568 {
569 gfac0[i] = 0.5 * (1 + z0[i]);
570 }
571
572 for (i = 0; i < nquad1; ++i)
573 {
574 Vmath::Vmul(nquad0, &gfac0[0], 1, &tmp0[0] + i * nquad0, 1,
575 &tmp0[0] + i * nquad0, 1);
576 }
577
578 IProductWRTBase_SumFacKernel(m_base[0]->GetDbdata(),
579 m_base[1]->GetBdata(), tmp0, tmp3,
580 gfac0);
581
582 MultiplyByQuadratureMetric(inarray, tmp0);
584 m_base[1]->GetDbdata(), tmp0, outarray,
585 gfac0);
586 Vmath::Vadd(m_ncoeffs, &tmp3[0], 1, &outarray[0], 1, &outarray[0],
587 1);
588 break;
589 }
590 default:
591 {
592 ASSERTL1(false, "input dir is out of range");
593 break;
594 }
595 }
596}
597
598//---------------------------------------
599// Evaluation functions
600//---------------------------------------
601
604{
605 NekDouble d1 = 1. - xi[1];
606 if (fabs(d1) < NekConstants::kNekZeroTol)
607 {
608 if (d1 >= 0.)
609 {
611 }
612 else
613 {
615 }
616 }
617 eta[0] = 2. * (1. + xi[0]) / d1 - 1.0;
618 eta[1] = xi[1];
619}
620
623{
624 xi[0] = (1.0 + eta[0]) * (1.0 - eta[1]) * 0.5 - 1.0;
625 xi[1] = eta[1];
626}
627
628void StdTriExp::v_FillMode(const int mode, Array<OneD, NekDouble> &outarray)
629{
630 int i, m;
631 int nquad0 = m_base[0]->GetNumPoints();
632 int nquad1 = m_base[1]->GetNumPoints();
633 int order0 = m_base[0]->GetNumModes();
634 int order1 = m_base[1]->GetNumModes();
635 int mode0 = 0;
636 Array<OneD, const NekDouble> base0 = m_base[0]->GetBdata();
637 Array<OneD, const NekDouble> base1 = m_base[1]->GetBdata();
638
639 ASSERTL2(mode <= m_ncoeffs, "calling argument mode is larger than "
640 "total expansion order");
641
642 m = order1;
643 for (i = 0; i < order0; ++i, m += order1 - i)
644 {
645 if (m > mode)
646 {
647 mode0 = i;
648 break;
649 }
650 }
651
652 // deal with top vertex mode in modified basis
653 if (mode == 1 && m_base[0]->GetBasisType() == LibUtilities::eModified_A)
654 {
655 Vmath::Fill(nquad0 * nquad1, 1.0, outarray, 1);
656 }
657 else
658 {
659 for (i = 0; i < nquad1; ++i)
660 {
661 Vmath::Vcopy(nquad0, (NekDouble *)(base0.get() + mode0 * nquad0), 1,
662 &outarray[0] + i * nquad0, 1);
663 }
664 }
665
666 for (i = 0; i < nquad0; ++i)
667 {
668 Vmath::Vmul(nquad1, (NekDouble *)(base1.get() + mode * nquad1), 1,
669 &outarray[0] + i, nquad0, &outarray[0] + i, nquad0);
670 }
671}
672
674 const Array<OneD, const NekDouble> &coords, int mode)
675{
677 LocCoordToLocCollapsed(coords, coll);
678
679 // From mode we need to determine mode0 and mode1 in the (p,q)
680 // direction. mode1 can be directly inferred from mode.
681 const int nm1 = m_base[1]->GetNumModes();
682 const double c = 1 + 2 * nm1;
683 const int mode0 = floor(0.5 * (c - sqrt(c * c - 8 * mode)));
684
685 if (mode == 1 && m_base[0]->GetBasisType() == LibUtilities::eModified_A)
686 {
687 // Account for collapsed vertex.
688 return StdExpansion::BaryEvaluateBasis<1>(coll[1], 1);
689 }
690 else
691 {
692 return StdExpansion::BaryEvaluateBasis<0>(coll[0], mode0) *
693 StdExpansion::BaryEvaluateBasis<1>(coll[1], mode);
694 }
695}
696
698 const Array<OneD, const NekDouble> &inarray,
699 std::array<NekDouble, 3> &firstOrderDerivs)
700{
701 // Collapse coordinates
702 Array<OneD, NekDouble> coll(2, 0.0);
703 LocCoordToLocCollapsed(coord, coll);
704
705 // If near singularity do the old interpolation matrix method
706 if ((1 - coll[1]) < 1e-5)
707 {
708 int totPoints = GetTotPoints();
709 Array<OneD, NekDouble> EphysDeriv0(totPoints), EphysDeriv1(totPoints);
710 PhysDeriv(inarray, EphysDeriv0, EphysDeriv1);
711
713 I[0] = GetBase()[0]->GetI(coll);
714 I[1] = GetBase()[1]->GetI(coll + 1);
715
716 firstOrderDerivs[0] = PhysEvaluate(I, EphysDeriv0);
717 firstOrderDerivs[1] = PhysEvaluate(I, EphysDeriv1);
718 return PhysEvaluate(I, inarray);
719 }
720
721 // set up geometric factor: 2.0/(1.0-z1)
722 NekDouble fac0 = 2 / (1 - coll[1]);
723
724 NekDouble val = BaryTensorDeriv(coll, inarray, firstOrderDerivs);
725
726 // Copy d0 into temp for d1
727 NekDouble temp;
728 temp = firstOrderDerivs[0];
729
730 // Multiply by geometric factor
731 firstOrderDerivs[0] = firstOrderDerivs[0] * fac0;
732
733 // set up geometric factor: (1+z0)/(1-z1)
734 NekDouble fac1 = fac0 * (coll[0] + 1) / 2;
735
736 // Multiply out_d0 by geometric factor and add to out_d1
737 firstOrderDerivs[1] += fac1 * temp;
738
739 return val;
740}
741
743{
744 return 3;
745}
746
748{
749 return 3;
750}
751
753{
755}
756
758{
760 "BasisType is not a boundary interior form");
762 "BasisType is not a boundary interior form");
763
764 return 3 + (GetBasisNumModes(0) - 2) + 2 * (GetBasisNumModes(1) - 2);
765}
766
768{
770 "BasisType is not a boundary interior form");
772 "BasisType is not a boundary interior form");
773
774 return GetBasisNumModes(0) + 2 * GetBasisNumModes(1);
775}
776
777int StdTriExp::v_GetTraceNcoeffs(const int i) const
778{
779 ASSERTL2(i >= 0 && i <= 2, "edge id is out of range");
780
781 if (i == 0)
782 {
783 return GetBasisNumModes(0);
784 }
785 else
786 {
787 return GetBasisNumModes(1);
788 }
789}
790
792{
793 ASSERTL2(i >= 0 && i <= 2, "edge id is out of range");
794
795 if (i == 0)
796 {
797 return GetBasisNumModes(0) - 2;
798 }
799 else
800 {
801 return GetBasisNumModes(1) - 2;
802 }
803}
804
805int StdTriExp::v_GetTraceNumPoints(const int i) const
806{
807 ASSERTL2((i >= 0) && (i <= 2), "edge id is out of range");
808
809 if (i == 0)
810 {
811 return GetNumPoints(0);
812 }
813 else
814 {
815 return GetNumPoints(1);
816 }
817}
818
820 const std::vector<unsigned int> &nummodes, int &modes_offset)
821{
823 nummodes[modes_offset], nummodes[modes_offset + 1]);
824 modes_offset += 2;
825
826 return nmodes;
827}
828
830 Array<OneD, NekDouble> &coords_1,
831 Array<OneD, NekDouble> &coords_2)
832{
833 boost::ignore_unused(coords_2);
834
835 Array<OneD, const NekDouble> z0 = m_base[0]->GetZ();
836 Array<OneD, const NekDouble> z1 = m_base[1]->GetZ();
837 int nq0 = GetNumPoints(0);
838 int nq1 = GetNumPoints(1);
839 int i, j;
840
841 for (i = 0; i < nq1; ++i)
842 {
843 for (j = 0; j < nq0; ++j)
844 {
845 coords_0[i * nq0 + j] = (1 + z0[j]) * (1 - z1[i]) / 2.0 - 1.0;
846 }
847 Vmath::Fill(nq0, z1[i], &coords_1[0] + i * nq0, 1);
848 }
849}
850
852{
853 return m_base[0]->GetBasisType() == LibUtilities::eModified_A &&
854 m_base[1]->GetBasisType() == LibUtilities::eModified_B;
855}
856
858 const int j) const
859{
860 boost::ignore_unused(j);
861 ASSERTL2(i >= 0 && i <= 2, "edge id is out of range");
862
863 // Get basiskey (0 or 1) according to edge id i
864 int dir = (i != 0);
865
866 switch (m_base[dir]->GetBasisType())
867 {
870 {
871 switch (m_base[dir]->GetPointsType())
872 {
874 {
875 return m_base[dir]->GetBasisKey();
876 }
877 break;
878 default:
879 {
881 "Unexpected points distribution " +
883 [m_base[dir]->GetPointsType()] +
884 " in StdTriExp::v_GetTraceBasisKey");
885 }
886 }
887 }
888 break;
890 {
891 switch (m_base[dir]->GetPointsType())
892 {
893 case LibUtilities::eGaussRadauMAlpha1Beta0:
894 {
896 m_base[dir]
897 ->GetBasisKey()
898 .GetPointsKey()
899 .GetNumPoints() +
900 1,
903 m_base[dir]->GetNumModes(),
904 pkey);
905 }
906 break;
907 // Currently this does not increase the points by
908 // 1 since when using this quadrature we are
909 // presuming it is already been increased by one
910 // when comopared to
911 // GaussRadauMAlpha1Beta0. Currently used in the
912 // GJP option
913 //
914 // Note have put down it back to numpoints +1 to
915 // test for use on tri faces and GJP.
917 {
919 m_base[dir]
920 ->GetBasisKey()
921 .GetPointsKey()
922 .GetNumPoints() +
923 1,
926 m_base[dir]->GetNumModes(),
927 pkey);
928 }
929 break;
931 {
933 m_base[dir]
934 ->GetBasisKey()
935 .GetPointsKey()
936 .GetNumPoints() +
937 1,
940 m_base[dir]->GetNumModes(),
941 pkey);
942 }
943 break;
944 default:
945 {
947 "Unexpected points distribution " +
949 [m_base[dir]->GetPointsType()] +
950 " in StdTriExp::v_GetTraceBasisKey");
951 }
952 }
953 }
954 break;
956 {
957 switch (m_base[dir]->GetPointsType())
958 {
959 case LibUtilities::eGaussRadauMAlpha1Beta0:
960 {
962 m_base[dir]
963 ->GetBasisKey()
964 .GetPointsKey()
965 .GetNumPoints() +
966 1,
969 m_base[dir]->GetNumModes(),
970 pkey);
971 }
972 break;
973 default:
974 {
976 "Unexpected points distribution " +
978 [m_base[dir]->GetPointsType()] +
979 " in StdTriExp::v_GetTraceBasisKey");
980 }
981 }
982 }
983 break;
984 default:
985 {
987 "Information not available to set edge key");
988 }
989 }
991}
992
993//--------------------------
994// Mappings
995//--------------------------
996
997int StdTriExp::v_GetVertexMap(const int localVertexId, bool useCoeffPacking)
998{
1001 "Mapping not defined for this type of basis");
1002
1003 int localDOF = 0;
1004 if (useCoeffPacking == true)
1005 {
1006 switch (localVertexId)
1007 {
1008 case 0:
1009 {
1010 localDOF = 0;
1011 break;
1012 }
1013 case 1:
1014 {
1015 localDOF = 1;
1016 break;
1017 }
1018 case 2:
1019 {
1020 localDOF = m_base[1]->GetNumModes();
1021 break;
1022 }
1023 default:
1024 {
1025 ASSERTL0(false, "eid must be between 0 and 2");
1026 break;
1027 }
1028 }
1029 }
1030 else // follow book format for vertex indexing.
1031 {
1032 switch (localVertexId)
1033 {
1034 case 0:
1035 {
1036 localDOF = 0;
1037 break;
1038 }
1039 case 1:
1040 {
1041 localDOF = m_base[1]->GetNumModes();
1042 break;
1043 }
1044 case 2:
1045 {
1046 localDOF = 1;
1047 break;
1048 }
1049 default:
1050 {
1051 ASSERTL0(false, "eid must be between 0 and 2");
1052 break;
1053 }
1054 }
1055 }
1056
1057 return localDOF;
1058}
1059
1061{
1064 "Expansion not of a proper type");
1065
1066 int i, j;
1067 int cnt = 0;
1068 int nummodes0, nummodes1;
1069 int startvalue;
1070 if (outarray.size() != GetNcoeffs() - NumBndryCoeffs())
1071 {
1073 }
1074
1075 nummodes0 = m_base[0]->GetNumModes();
1076 nummodes1 = m_base[1]->GetNumModes();
1077
1078 startvalue = 2 * nummodes1;
1079
1080 for (i = 0; i < nummodes0 - 2; i++)
1081 {
1082 for (j = 0; j < nummodes1 - 3 - i; j++)
1083 {
1084 outarray[cnt++] = startvalue + j;
1085 }
1086 startvalue += nummodes1 - 2 - i;
1087 }
1088}
1089
1091{
1094 "Expansion not of expected type");
1095 int i;
1096 int cnt;
1097 int nummodes0, nummodes1;
1098 int value;
1099
1100 if (outarray.size() != NumBndryCoeffs())
1101 {
1103 }
1104
1105 nummodes0 = m_base[0]->GetNumModes();
1106 nummodes1 = m_base[1]->GetNumModes();
1107
1108 value = 2 * nummodes1 - 1;
1109 for (i = 0; i < value; i++)
1110 {
1111 outarray[i] = i;
1112 }
1113 cnt = value;
1114
1115 for (i = 0; i < nummodes0 - 2; i++)
1116 {
1117 outarray[cnt++] = value;
1118 value += nummodes1 - 2 - i;
1119 }
1120}
1121
1122void StdTriExp::v_GetTraceCoeffMap(const unsigned int eid,
1123 Array<OneD, unsigned int> &maparray)
1124{
1125
1128 "Mapping not defined for this type of basis");
1129
1130 ASSERTL1(eid < 3, "eid must be between 0 and 2");
1131
1132 int i;
1133 int order0 = m_base[0]->GetNumModes();
1134 int order1 = m_base[1]->GetNumModes();
1135 int numModes = (eid == 0) ? order0 : order1;
1136
1137 if (maparray.size() != numModes)
1138 {
1139 maparray = Array<OneD, unsigned int>(numModes);
1140 }
1141
1142 switch (eid)
1143 {
1144 case 0:
1145 {
1146 int cnt = 0;
1147 for (i = 0; i < numModes; cnt += order1 - i, ++i)
1148 {
1149 maparray[i] = cnt;
1150 }
1151 break;
1152 }
1153 case 1:
1154 {
1155 maparray[0] = order1;
1156 maparray[1] = 1;
1157 for (i = 2; i < numModes; i++)
1158 {
1159 maparray[i] = order1 - 1 + i;
1160 }
1161 break;
1162 }
1163 case 2:
1164 {
1165 for (i = 0; i < numModes; i++)
1166 {
1167 maparray[i] = i;
1168 }
1169 break;
1170 }
1171 default:
1172 ASSERTL0(false, "eid must be between 0 and 2");
1173 break;
1174 }
1175}
1176
1178 const int eid, Array<OneD, unsigned int> &maparray,
1179 Array<OneD, int> &signarray, const Orientation edgeOrient)
1180{
1183 "Mapping not defined for this type of basis");
1184 int i;
1185 const int nummodes1 = m_base[1]->GetNumModes();
1186 const int nEdgeIntCoeffs = GetTraceNcoeffs(eid) - 2;
1187
1188 if (maparray.size() != nEdgeIntCoeffs)
1189 {
1190 maparray = Array<OneD, unsigned int>(nEdgeIntCoeffs);
1191 }
1192
1193 if (signarray.size() != nEdgeIntCoeffs)
1194 {
1195 signarray = Array<OneD, int>(nEdgeIntCoeffs, 1);
1196 }
1197 else
1198 {
1199 fill(signarray.get(), signarray.get() + nEdgeIntCoeffs, 1);
1200 }
1201
1202 switch (eid)
1203 {
1204 case 0:
1205 {
1206 int cnt = 2 * nummodes1 - 1;
1207 for (i = 0; i < nEdgeIntCoeffs; cnt += nummodes1 - 2 - i, ++i)
1208 {
1209 maparray[i] = cnt;
1210 }
1211 break;
1212 }
1213 case 1:
1214 {
1215 for (i = 0; i < nEdgeIntCoeffs; i++)
1216 {
1217 maparray[i] = nummodes1 + 1 + i;
1218 }
1219 break;
1220 }
1221 case 2:
1222 {
1223 for (i = 0; i < nEdgeIntCoeffs; i++)
1224 {
1225 maparray[i] = 2 + i;
1226 }
1227 break;
1228 }
1229 default:
1230 {
1231 ASSERTL0(false, "eid must be between 0 and 2");
1232 break;
1233 }
1234 }
1235
1236 if (edgeOrient == eBackwards)
1237 {
1238 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1239 {
1240 signarray[i] = -1;
1241 }
1242 }
1243}
1244
1245//---------------------------------------
1246// Wrapper functions
1247//---------------------------------------
1248
1250{
1251
1252 MatrixType mtype = mkey.GetMatrixType();
1253
1254 DNekMatSharedPtr Mat;
1255
1256 switch (mtype)
1257 {
1259 {
1260 int nq0, nq1, nq;
1261
1262 nq0 = m_base[0]->GetNumPoints();
1263 nq1 = m_base[1]->GetNumPoints();
1264
1265 // take definition from key
1267 {
1268 nq = (int)mkey.GetConstFactor(eFactorConst);
1269 }
1270 else
1271 {
1272 nq = max(nq0, nq1);
1273 }
1274
1277 Array<OneD, NekDouble> coll(2);
1279 Array<OneD, NekDouble> tmp(nq0);
1280
1281 Mat = MemoryManager<DNekMat>::AllocateSharedPtr(neq, nq0 * nq1);
1282 int cnt = 0;
1283
1284 for (int i = 0; i < nq; ++i)
1285 {
1286 for (int j = 0; j < nq - i; ++j, ++cnt)
1287 {
1288 coords[cnt] = Array<OneD, NekDouble>(2);
1289 coords[cnt][0] = -1.0 + 2 * j / (NekDouble)(nq - 1);
1290 coords[cnt][1] = -1.0 + 2 * i / (NekDouble)(nq - 1);
1291 }
1292 }
1293
1294 for (int i = 0; i < neq; ++i)
1295 {
1296 LocCoordToLocCollapsed(coords[i], coll);
1297
1298 I[0] = m_base[0]->GetI(coll);
1299 I[1] = m_base[1]->GetI(coll + 1);
1300
1301 // interpolate first coordinate direction
1302 for (int j = 0; j < nq1; ++j)
1303 {
1304 NekDouble fac = (I[1]->GetPtr())[j];
1305 Vmath::Smul(nq0, fac, I[0]->GetPtr(), 1, tmp, 1);
1306
1307 Vmath::Vcopy(nq0, &tmp[0], 1,
1308 Mat->GetRawPtr() + j * nq0 * neq + i, neq);
1309 }
1310 }
1311 break;
1312 }
1313 default:
1314 {
1316 break;
1317 }
1318 }
1319
1320 return Mat;
1321}
1322
1324{
1325 return v_GenMatrix(mkey);
1326}
1327
1328//---------------------------------------
1329// Operator evaluation functions
1330//---------------------------------------
1331
1333 Array<OneD, NekDouble> &outarray,
1334 const StdMatrixKey &mkey)
1335{
1336 StdExpansion::MassMatrixOp_MatFree(inarray, outarray, mkey);
1337}
1338
1340 Array<OneD, NekDouble> &outarray,
1341 const StdMatrixKey &mkey)
1342{
1343 StdTriExp::v_LaplacianMatrixOp_MatFree(inarray, outarray, mkey);
1344}
1345
1346void StdTriExp::v_LaplacianMatrixOp(const int k1, const int k2,
1347 const Array<OneD, const NekDouble> &inarray,
1348 Array<OneD, NekDouble> &outarray,
1349 const StdMatrixKey &mkey)
1350{
1351 StdExpansion::LaplacianMatrixOp_MatFree(k1, k2, inarray, outarray, mkey);
1352}
1353
1355 const Array<OneD, const NekDouble> &inarray,
1356 Array<OneD, NekDouble> &outarray,
1357 const StdMatrixKey &mkey)
1358{
1359 StdExpansion::WeakDerivMatrixOp_MatFree(i, inarray, outarray, mkey);
1360}
1361
1363 Array<OneD, NekDouble> &outarray,
1364 const StdMatrixKey &mkey)
1365{
1366 StdTriExp::v_HelmholtzMatrixOp_MatFree(inarray, outarray, mkey);
1367}
1368
1370 const StdMatrixKey &mkey)
1371{
1372 int qa = m_base[0]->GetNumPoints();
1373 int qb = m_base[1]->GetNumPoints();
1374 int nmodes_a = m_base[0]->GetNumModes();
1375 int nmodes_b = m_base[1]->GetNumModes();
1376
1377 // Declare orthogonal basis.
1380
1383 StdTriExp OrthoExp(Ba, Bb);
1384
1385 Array<OneD, NekDouble> orthocoeffs(OrthoExp.GetNcoeffs());
1386
1387 // project onto physical space.
1388 OrthoExp.FwdTrans(array, orthocoeffs);
1389
1390 if (mkey.ConstFactorExists(
1391 eFactorSVVPowerKerDiffCoeff)) // Rodrigo's power kern
1392 {
1394 NekDouble SvvDiffCoeff =
1397
1398 int cnt = 0;
1399 for (int j = 0; j < nmodes_a; ++j)
1400 {
1401 for (int k = 0; k < nmodes_b - j; ++k, ++cnt)
1402 {
1403 NekDouble fac = std::max(
1404 pow((1.0 * j) / (nmodes_a - 1), cutoff * nmodes_a),
1405 pow((1.0 * k) / (nmodes_b - 1), cutoff * nmodes_b));
1406
1407 orthocoeffs[cnt] *= (SvvDiffCoeff * fac);
1408 }
1409 }
1410 }
1411 else if (mkey.ConstFactorExists(
1412 eFactorSVVDGKerDiffCoeff)) // Rodrigo/mansoor's DG kernel
1413 {
1416 int max_ab = max(nmodes_a - kSVVDGFiltermodesmin,
1417 nmodes_b - kSVVDGFiltermodesmin);
1418 max_ab = max(max_ab, 0);
1419 max_ab = min(max_ab, kSVVDGFiltermodesmax - kSVVDGFiltermodesmin);
1420
1421 int cnt = 0;
1422 for (int j = 0; j < nmodes_a; ++j)
1423 {
1424 for (int k = 0; k < nmodes_b - j; ++k, ++cnt)
1425 {
1426 int maxjk = max(j, k);
1427 maxjk = min(maxjk, kSVVDGFiltermodesmax - 1);
1428
1429 orthocoeffs[cnt] *= SvvDiffCoeff * kSVVDGFilter[max_ab][maxjk];
1430 }
1431 }
1432 }
1433 else
1434 {
1435 NekDouble SvvDiffCoeff = mkey.GetConstFactor(eFactorSVVDiffCoeff);
1436
1437 int cutoff = (int)(mkey.GetConstFactor(eFactorSVVCutoffRatio) *
1438 min(nmodes_a, nmodes_b));
1439
1440 NekDouble epsilon = 1.0;
1441 int nmodes = min(nmodes_a, nmodes_b);
1442
1443 int cnt = 0;
1444
1445 // apply SVV filter (JEL)
1446 for (int j = 0; j < nmodes_a; ++j)
1447 {
1448 for (int k = 0; k < nmodes_b - j; ++k)
1449 {
1450 if (j + k >= cutoff)
1451 {
1452 orthocoeffs[cnt] *=
1453 (SvvDiffCoeff *
1454 exp(-(j + k - nmodes) * (j + k - nmodes) /
1455 ((NekDouble)((j + k - cutoff + epsilon) *
1456 (j + k - cutoff + epsilon)))));
1457 }
1458 else
1459 {
1460 orthocoeffs[cnt] *= 0.0;
1461 }
1462 cnt++;
1463 }
1464 }
1465 }
1466
1467 // backward transform to physical space
1468 OrthoExp.BwdTrans(orthocoeffs, array);
1469}
1470
1472 const Array<OneD, const NekDouble> &inarray,
1473 Array<OneD, NekDouble> &outarray)
1474{
1475 int n_coeffs = inarray.size();
1476 int nquad0 = m_base[0]->GetNumPoints();
1477 int nquad1 = m_base[1]->GetNumPoints();
1478 Array<OneD, NekDouble> coeff(n_coeffs);
1479 Array<OneD, NekDouble> coeff_tmp(n_coeffs, 0.0);
1482 int nqtot = nquad0 * nquad1;
1483 Array<OneD, NekDouble> phys_tmp(nqtot, 0.0);
1484
1485 int nmodes0 = m_base[0]->GetNumModes();
1486 int nmodes1 = m_base[1]->GetNumModes();
1487 int numMin2 = nmodes0;
1488 int i;
1489
1490 const LibUtilities::PointsKey Pkey0(nmodes0,
1492 const LibUtilities::PointsKey Pkey1(nmodes1,
1494
1495 LibUtilities::BasisKey b0(m_base[0]->GetBasisType(), nmodes0, Pkey0);
1496 LibUtilities::BasisKey b1(m_base[1]->GetBasisType(), nmodes1, Pkey1);
1497
1498 LibUtilities::BasisKey bortho0(LibUtilities::eOrtho_A, nmodes0, Pkey0);
1499 LibUtilities::BasisKey bortho1(LibUtilities::eOrtho_B, nmodes1, Pkey1);
1500
1501 StdRegions::StdTriExpSharedPtr m_OrthoTriExp;
1503
1506 bortho0, bortho1);
1507
1508 m_TriExp->BwdTrans(inarray, phys_tmp);
1509 m_OrthoTriExp->FwdTrans(phys_tmp, coeff);
1510
1511 for (i = 0; i < n_coeffs; i++)
1512 {
1513 if (i == numMin)
1514 {
1515 coeff[i] = 0.0;
1516 numMin += numMin2 - 1;
1517 numMin2 -= 1.0;
1518 }
1519 }
1520
1521 m_OrthoTriExp->BwdTrans(coeff, phys_tmp);
1522 m_TriExp->FwdTrans(phys_tmp, outarray);
1523}
1524
1525//---------------------------------------
1526// Private helper functions
1527//---------------------------------------
1528
1530 const Array<OneD, const NekDouble> &inarray,
1531 Array<OneD, NekDouble> &outarray)
1532{
1533 int i;
1534 int nquad0 = m_base[0]->GetNumPoints();
1535 int nquad1 = m_base[1]->GetNumPoints();
1536
1537 const Array<OneD, const NekDouble> &w0 = m_base[0]->GetW();
1538 const Array<OneD, const NekDouble> &w1 = m_base[1]->GetW();
1539 const Array<OneD, const NekDouble> &z1 = m_base[1]->GetZ();
1540
1541 // multiply by integration constants
1542 for (i = 0; i < nquad1; ++i)
1543 {
1544 Vmath::Vmul(nquad0, inarray.get() + i * nquad0, 1, w0.get(), 1,
1545 outarray.get() + i * nquad0, 1);
1546 }
1547
1548 switch (m_base[1]->GetPointsType())
1549 {
1550 // (1,0) Jacobi Inner product
1551 case LibUtilities::eGaussRadauMAlpha1Beta0:
1552 for (i = 0; i < nquad1; ++i)
1553 {
1554 Blas::Dscal(nquad0, 0.5 * w1[i], outarray.get() + i * nquad0,
1555 1);
1556 }
1557 break;
1558 // Legendre inner product
1559 default:
1560 for (i = 0; i < nquad1; ++i)
1561 {
1562 Blas::Dscal(nquad0, 0.5 * (1 - z1[i]) * w1[i],
1563 outarray.get() + i * nquad0, 1);
1564 }
1565 break;
1566 }
1567}
1568
1570 bool standard)
1571{
1572 boost::ignore_unused(standard);
1573
1574 int np1 = m_base[0]->GetNumPoints();
1575 int np2 = m_base[1]->GetNumPoints();
1576 int np = max(np1, np2);
1577
1578 conn = Array<OneD, int>(3 * (np - 1) * (np - 1));
1579
1580 int row = 0;
1581 int rowp1 = 0;
1582 int cnt = 0;
1583 for (int i = 0; i < np - 1; ++i)
1584 {
1585 rowp1 += np - i;
1586 for (int j = 0; j < np - i - 2; ++j)
1587 {
1588 conn[cnt++] = row + j;
1589 conn[cnt++] = row + j + 1;
1590 conn[cnt++] = rowp1 + j;
1591
1592 conn[cnt++] = rowp1 + j + 1;
1593 conn[cnt++] = rowp1 + j;
1594 conn[cnt++] = row + j + 1;
1595 }
1596
1597 conn[cnt++] = row + np - i - 2;
1598 conn[cnt++] = row + np - i - 1;
1599 conn[cnt++] = rowp1 + np - i - 2;
1600
1601 row += np - i;
1602 }
1603}
1604} // namespace StdRegions
1605} // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
Definition: ErrorUtil.hpp:272
#define sign(a, b)
return the sign(b)*a
Definition: Polylib.cpp:49
Describes the specification for a Basis.
Definition: Basis.h:47
int GetNumModes() const
Returns the order of the basis.
Definition: Basis.h:76
Defines a specification for a set of points.
Definition: Points.h:55
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.
virtual void v_HelmholtzMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey) override
NekDouble BaryTensorDeriv(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs)
NekDouble Integral(const Array< OneD, const NekDouble > &inarray, const Array< OneD, const NekDouble > &w0, const Array< OneD, const NekDouble > &w1)
void BwdTrans_SumFacKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp, bool doCheckCollDir0=true, bool doCheckCollDir1=true)
virtual void v_LaplacianMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey) override
void IProductWRTBase_SumFacKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp, bool doCheckCollDir0=true, bool doCheckCollDir1=true)
The base class for all shapes.
Definition: StdExpansion.h:71
int GetNcoeffs(void) const
This function returns the total number of coefficients used in the expansion.
Definition: StdExpansion.h:130
int GetTotPoints() const
This function returns the total number of quadrature points used in the element.
Definition: StdExpansion.h:140
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.
Definition: StdExpansion.h:162
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:609
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)
Definition: StdExpansion.h:758
const Array< OneD, const LibUtilities::BasisSharedPtr > & GetBase() const
This function gets the shared point to basis.
Definition: StdExpansion.h:106
DNekMatSharedPtr CreateGeneralMatrix(const StdMatrixKey &mkey)
this function generates the mass matrix
void LaplacianMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
NekDouble PhysEvaluate(const Array< OneD, const NekDouble > &coords, const Array< OneD, const NekDouble > &physvals)
This function evaluates the expansion at a single (arbitrary) point of the domain.
Definition: StdExpansion.h:925
void GetTraceToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, Orientation traceOrient=eForwards, int P=-1, int Q=-1)
Definition: StdExpansion.h:690
LibUtilities::ShapeType DetShapeType() const
This function returns the shape of the expansion domain.
Definition: StdExpansion.h:373
void BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function performs the Backward transformation from coefficient space to physical space.
Definition: StdExpansion.h:430
int GetTraceNcoeffs(const int i) const
This function returns the number of expansion coefficients belonging to the i-th trace.
Definition: StdExpansion.h:267
LibUtilities::PointsType GetPointsType(const int dir) const
This function returns the type of quadrature points used in the dir direction.
Definition: StdExpansion.h:211
void FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function performs the Forward transformation from physical space to coefficient space.
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.
Definition: StdExpansion.h:224
void MultiplyByQuadratureMetric(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: StdExpansion.h:729
int GetBasisNumModes(const int dir) const
This function returns the number of expansion modes in the dir direction.
Definition: StdExpansion.h:175
void PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1=NullNekDouble1DArray, Array< OneD, NekDouble > &out_d2=NullNekDouble1DArray)
Definition: StdExpansion.h:855
Array< OneD, LibUtilities::BasisSharedPtr > m_base
void MassMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
MatrixType GetMatrixType() const
Definition: StdMatrixKey.h:87
NekDouble GetConstFactor(const ConstFactorType &factor) const
Definition: StdMatrixKey.h:128
bool ConstFactorExists(const ConstFactorType &factor) const
Definition: StdMatrixKey.h:137
virtual void v_WeakDerivMatrixOp(const int i, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
Definition: StdTriExp.cpp:1354
virtual int v_GetTraceNumPoints(const int i) const override
Definition: StdTriExp.cpp:805
void v_BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Backward tranform for triangular elements.
Definition: StdTriExp.cpp:240
virtual void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition: StdTriExp.cpp:516
NekDouble v_PhysEvaluate(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs) override
Definition: StdTriExp.cpp:697
virtual LibUtilities::ShapeType v_DetShapeType() const final override
Definition: StdTriExp.cpp:752
virtual void v_LocCollapsedToLocCoord(const Array< OneD, const NekDouble > &eta, Array< OneD, NekDouble > &xi) override
Definition: StdTriExp.cpp:621
virtual int v_GetNverts() const final override
Definition: StdTriExp.cpp:742
virtual void v_GetCoords(Array< OneD, NekDouble > &coords_x, Array< OneD, NekDouble > &coords_y, Array< OneD, NekDouble > &coords_z) override
Definition: StdTriExp.cpp:829
virtual int v_CalcNumberOfCoefficients(const std::vector< unsigned int > &nummodes, int &modes_offset) override
Definition: StdTriExp.cpp:819
virtual void v_GetSimplexEquiSpacedConnectivity(Array< OneD, int > &conn, bool standard=true) override
Definition: StdTriExp.cpp:1569
void v_MassMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
Definition: StdTriExp.cpp:1332
virtual void v_GetBoundaryMap(Array< OneD, unsigned int > &outarray) override
Definition: StdTriExp.cpp:1090
virtual 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
Definition: StdTriExp.cpp:215
void v_GetTraceInteriorToElementMap(const int eid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation edgeOrient=eForwards) override
Definition: StdTriExp.cpp:1177
virtual int v_GetVertexMap(int localVertexId, bool useCoeffPacking=false) override
Definition: StdTriExp.cpp:997
virtual const LibUtilities::BasisKey v_GetTraceBasisKey(const int i, const int j) const override
Definition: StdTriExp.cpp:857
virtual int v_GetNtraces() const final override
Definition: StdTriExp.cpp:747
virtual DNekMatSharedPtr v_CreateStdMatrix(const StdMatrixKey &mkey) override
Definition: StdTriExp.cpp:1323
virtual void v_BwdTrans_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition: StdTriExp.cpp:246
virtual DNekMatSharedPtr v_GenMatrix(const StdMatrixKey &mkey) override
Definition: StdTriExp.cpp:1249
void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Calculate the inner product of inarray with respect to the basis B=base0[p]*base1[pq] and put into ou...
Definition: StdTriExp.cpp:444
virtual int v_GetTraceNcoeffs(const int i) const override
Definition: StdTriExp.cpp:777
void v_PhysDeriv(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.
Definition: StdTriExp.cpp:126
virtual void v_GetTraceCoeffMap(const unsigned int traceid, Array< OneD, unsigned int > &maparray) override
Definition: StdTriExp.cpp:1122
virtual void v_BwdTrans_SumFacKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp, bool doCheckCollDir0, bool doCheckCollDir1) override
Definition: StdTriExp.cpp:256
virtual bool v_IsBoundaryInteriorExpansion() const override
Definition: StdTriExp.cpp:851
virtual void v_FillMode(const int mode, Array< OneD, NekDouble > &outarray) override
Definition: StdTriExp.cpp:628
NekDouble v_PhysEvaluateBasis(const Array< OneD, const NekDouble > &coords, int mode) final override
Definition: StdTriExp.cpp:673
virtual void v_ReduceOrderCoeffs(int numMin, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition: StdTriExp.cpp:1471
virtual void v_FwdTransBndConstrained(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition: StdTriExp.cpp:313
virtual void v_IProductWRTDerivBase_SumFac(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition: StdTriExp.cpp:523
virtual int v_GetTraceIntNcoeffs(const int i) const override
Definition: StdTriExp.cpp:791
virtual int v_NumDGBndryCoeffs() const override
Definition: StdTriExp.cpp:767
virtual void v_LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta) override
Definition: StdTriExp.cpp:602
virtual void v_HelmholtzMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
Definition: StdTriExp.cpp:1362
virtual NekDouble v_Integral(const Array< OneD, const NekDouble > &inarray) override
Integrates the specified function over the domain.
Definition: StdTriExp.cpp:78
virtual void v_FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Transform a given function from physical quadrature space to coefficient space.
Definition: StdTriExp.cpp:297
virtual void v_GetInteriorMap(Array< OneD, unsigned int > &outarray) override
Definition: StdTriExp.cpp:1060
virtual ~StdTriExp() override
Definition: StdTriExp.cpp:71
virtual void v_LaplacianMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
Definition: StdTriExp.cpp:1339
virtual void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdMatrixKey &mkey) override
Definition: StdTriExp.cpp:1369
virtual void v_MultiplyByStdQuadratureMetric(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition: StdTriExp.cpp:1529
virtual int v_NumBndryCoeffs() const override
Definition: StdTriExp.cpp:757
virtual void v_IProductWRTBase_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool multiplybyweights=true) override
Definition: StdTriExp.cpp:450
virtual void v_IProductWRTBase_SumFacKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp, bool doCheckCollDir0, bool doCheckCollDir1) override
Definition: StdTriExp.cpp:477
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:213
static void Dscal(const int &n, const double &alpha, double *x, const int &incx)
BLAS level 1: x = alpha x.
Definition: Blas.hpp:151
static double Ddot(const int &n, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: output = .
Definition: Blas.hpp:165
static void Dgemm(const char &transa, const char &transb, const int &m, const int &n, const int &k, const double &alpha, const double *a, const int &lda, const double *b, const int &ldb, const double &beta, double *c, const int &ldc)
BLAS level 3: Matrix-matrix multiply C = A x B where op(A)[m x k], op(B)[k x n], C[m x n] DGEMM perfo...
Definition: Blas.hpp:385
static void Daxpy(const int &n, const double &alpha, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: y = alpha x plus y.
Definition: Blas.hpp:137
int getNumberOfCoefficients(int Na, int Nb)
Definition: ShapeType.hpp:114
static const BasisKey NullBasisKey(eNoBasisType, 0, NullPointsKey)
Defines a null basis with no type or points.
const std::string kPointsTypeStr[]
Definition: Foundations.hpp:54
@ eGaussRadauMLegendre
1D Gauss-Radau-Legendre quadrature points, pinned at x=-1
Definition: PointsType.h:49
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
Definition: PointsType.h:53
@ ePolyEvenlySpaced
1D Evenly-spaced points using Lagrange polynomial
Definition: PointsType.h:75
@ eModified_B
Principle Modified Functions .
Definition: BasisType.h:51
@ eOrtho_A
Principle Orthogonal Functions .
Definition: BasisType.h:44
@ eGLL_Lagrange
Lagrange for SEM basis .
Definition: BasisType.h:58
@ eOrtho_B
Principle Orthogonal Functions .
Definition: BasisType.h:46
@ eModified_A
Principle Modified Functions .
Definition: BasisType.h:50
static const NekDouble kNekZeroTol
const int kSVVDGFiltermodesmin
Definition: StdRegions.hpp:478
const int kSVVDGFiltermodesmax
Definition: StdRegions.hpp:479
const NekDouble kSVVDGFilter[9][11]
Definition: StdRegions.hpp:481
std::shared_ptr< StdTriExp > StdTriExpSharedPtr
Definition: StdTriExp.h:232
std::shared_ptr< StdSegExp > StdSegExpSharedPtr
Definition: StdSegExp.h:267
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
static Array< OneD, NekDouble > NullNekDouble1DArray
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:75
double NekDouble
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:207
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.cpp:569
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.cpp:354
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.cpp:245
void Sdiv(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha/x.
Definition: Vmath.cpp:319
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:43
void Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add scalar y = alpha + x.
Definition: Vmath.cpp:379
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1191
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.cpp:414
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294