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