Nektar++
TriExp.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File TriExp.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 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
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: Expasion for triangular elements.
32 //
33 ///////////////////////////////////////////////////////////////////////////////
35 #include <LocalRegions/TriExp.h>
36 #include <LocalRegions/SegExp.h>
40 
41 
42 namespace Nektar
43 {
44  namespace LocalRegions
45  {
47  const LibUtilities::BasisKey &Bb,
49  StdExpansion (LibUtilities::StdTriData::getNumberOfCoefficients(Ba.GetNumModes(),(Bb.GetNumModes())),2,Ba,Bb),
50  StdExpansion2D(LibUtilities::StdTriData::getNumberOfCoefficients(Ba.GetNumModes(),(Bb.GetNumModes())),Ba,Bb),
51  StdTriExp(Ba,Bb),
52  Expansion (geom),
53  Expansion2D (geom),
54  m_matrixManager(
55  boost::bind(&TriExp::CreateMatrix, this, _1),
56  std::string("TriExpMatrix")),
57  m_staticCondMatrixManager(
58  boost::bind(&TriExp::CreateStaticCondMatrix, this, _1),
59  std::string("TriExpStaticCondMatrix"))
60  {
61  }
62 
63 
65  StdExpansion(T),
66  StdExpansion2D(T),
67  StdTriExp(T),
68  Expansion(T),
69  Expansion2D(T),
70  m_matrixManager(T.m_matrixManager),
71  m_staticCondMatrixManager(T.m_staticCondMatrixManager)
72  {
73  }
74 
75 
77  {
78  }
79 
80 
81 
83  {
84  int nquad0 = m_base[0]->GetNumPoints();
85  int nquad1 = m_base[1]->GetNumPoints();
87  NekDouble ival;
88  Array<OneD,NekDouble> tmp(nquad0*nquad1);
89 
90  // multiply inarray with Jacobian
91  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
92  {
93  Vmath::Vmul(nquad0*nquad1, jac, 1, inarray, 1,tmp, 1);
94  }
95  else
96  {
97  Vmath::Smul(nquad0*nquad1, jac[0], inarray, 1, tmp, 1);
98  }
99 
100  // call StdQuadExp version;
101  ival = StdTriExp::v_Integral(tmp);
102  return ival;
103  }
104 
105 
107  Array<OneD,NekDouble> &out_d0,
108  Array<OneD,NekDouble> &out_d1,
109  Array<OneD,NekDouble> &out_d2)
110  {
111  int nquad0 = m_base[0]->GetNumPoints();
112  int nquad1 = m_base[1]->GetNumPoints();
113  int nqtot = nquad0*nquad1;
115  = m_metricinfo->GetDerivFactors(GetPointsKeys());
116 
117  Array<OneD,NekDouble> diff0(2*nqtot);
118  Array<OneD,NekDouble> diff1(diff0+nqtot);
119 
120  StdTriExp::v_PhysDeriv(inarray, diff0, diff1);
121 
122  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
123  {
124  if(out_d0.num_elements())
125  {
126  Vmath::Vmul (nqtot,df[0],1,diff0,1, out_d0, 1);
127  Vmath::Vvtvp (nqtot,df[1],1,diff1,1, out_d0, 1, out_d0,1);
128  }
129 
130  if(out_d1.num_elements())
131  {
132  Vmath::Vmul (nqtot,df[2],1,diff0,1, out_d1, 1);
133  Vmath::Vvtvp (nqtot,df[3],1,diff1,1, out_d1, 1, out_d1,1);
134  }
135 
136  if(out_d2.num_elements())
137  {
138  Vmath::Vmul (nqtot,df[4],1,diff0,1, out_d2, 1);
139  Vmath::Vvtvp (nqtot,df[5],1,diff1,1, out_d2, 1, out_d2,1);
140  }
141  }
142  else // regular geometry
143  {
144  if(out_d0.num_elements())
145  {
146  Vmath::Smul (nqtot, df[0][0], diff0, 1, out_d0, 1);
147  Blas::Daxpy (nqtot, df[1][0], diff1, 1, out_d0, 1);
148  }
149 
150  if(out_d1.num_elements())
151  {
152  Vmath::Smul (nqtot, df[2][0], diff0, 1, out_d1, 1);
153  Blas::Daxpy (nqtot, df[3][0], diff1, 1, out_d1, 1);
154  }
155 
156  if(out_d2.num_elements())
157  {
158  Vmath::Smul (nqtot, df[4][0], diff0, 1, out_d2, 1);
159  Blas::Daxpy (nqtot, df[5][0], diff1, 1, out_d2, 1);
160  }
161  }
162  }
163 
164 
165  void TriExp::v_PhysDeriv(const int dir,
166  const Array<OneD, const NekDouble>& inarray,
167  Array<OneD, NekDouble> &outarray)
168  {
169  switch(dir)
170  {
171  case 0:
172  {
174  }
175  break;
176  case 1:
177  {
179  }
180  break;
181  case 2:
182  {
184  }
185  break;
186  default:
187  {
188  ASSERTL1(false,"input dir is out of range");
189  }
190  break;
191  }
192  }
193 
195  const Array<OneD, const NekDouble> &inarray,
196  const Array<OneD, const NekDouble> &direction,
198  {
199  if(! out.num_elements())
200  {
201  return;
202  }
203 
204  int nquad0 = m_base[0]->GetNumPoints();
205  int nquad1 = m_base[1]->GetNumPoints();
206  int nqtot = nquad0*nquad1;
207 
208  const Array<TwoD, const NekDouble>& df =
209  m_metricinfo->GetDerivFactors(GetPointsKeys());
210 
211  Array<OneD,NekDouble> diff0(2*nqtot);
212  Array<OneD,NekDouble> diff1(diff0+nqtot);
213 
214  // diff0 = du/d_xi, diff1 = du/d_eta
215  StdTriExp::v_PhysDeriv(inarray, diff0, diff1);
216 
217  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
218  {
220 
221 
222  // D^v_xi = v_x*d_xi/dx + v_y*d_xi/dy + v_z*d_xi/dz
223  // D^v_eta = v_x*d_eta/dx + v_y*d_eta/dy + v_z*d_eta/dz
224  for (int i=0; i< 2; ++i)
225  {
226  tangmat[i] = Array<OneD, NekDouble>(nqtot,0.0);
227  for (int k=0; k<(m_geom->GetCoordim()); ++k)
228  {
229  Vmath::Vvtvp(nqtot,&df[2*k+i][0],1,&direction[k*nqtot],1,&tangmat[i][0],1,&tangmat[i][0],1);
230  }
231  }
232 
233  /// D_v = D^v_xi * du/d_xi + D^v_eta * du/d_eta
234  Vmath::Vmul (nqtot,&tangmat[0][0],1,&diff0[0],1, &out[0], 1);
235  Vmath::Vvtvp (nqtot,&tangmat[1][0],1,&diff1[0],1, &out[0], 1, &out[0],1);
236  }
237  else
238  {
239  ASSERTL1(m_metricinfo->GetGtype() == SpatialDomains::eDeformed,"Wrong route");
240  }
241  }
242 
243 
245  Array<OneD,NekDouble> &outarray)
246  {
247  IProductWRTBase(inarray,outarray);
248 
249  // get Mass matrix inverse
251  DetShapeType(),*this);
252  DNekScalMatSharedPtr matsys = m_matrixManager[masskey];
253 
254  // copy inarray in case inarray == outarray
255  NekVector<NekDouble> in (m_ncoeffs,outarray,eCopy);
257 
258  out = (*matsys)*in;
259  }
260 
261 
263  Array<OneD, NekDouble> &outarray)
264  {
265  int i,j;
266  int npoints[2] = {m_base[0]->GetNumPoints(),
267  m_base[1]->GetNumPoints()};
268  int nmodes[2] = {m_base[0]->GetNumModes(),
269  m_base[1]->GetNumModes()};
270 
271  fill(outarray.get(), outarray.get()+m_ncoeffs, 0.0 );
272 
273  Array<OneD, NekDouble> physEdge[3];
274  Array<OneD, NekDouble> coeffEdge[3];
275  StdRegions::Orientation orient[3];
276  for(i = 0; i < 3; i++)
277  {
278  physEdge[i] = Array<OneD, NekDouble>(npoints[i!=0]);
279  coeffEdge[i] = Array<OneD, NekDouble>(nmodes[i!=0]);
280  orient[i] = GetEorient(i);
281  }
282 
283  for(i = 0; i < npoints[0]; i++)
284  {
285  physEdge[0][i] = inarray[i];
286  }
287 
288  for(i = 0; i < npoints[1]; i++)
289  {
290  physEdge[1][i] = inarray[npoints[0]-1+i*npoints[0]];
291  physEdge[2][i] = inarray[(npoints[1]-1)*npoints[0]-i*npoints[0]];
292  }
293 
294  for(i = 0; i < 3; i++)
295  {
296  if( orient[i] == StdRegions::eBackwards )
297  {
298  reverse( (physEdge[i]).get() , (physEdge[i]).get() + npoints[i!=0] );
299  }
300  }
301 
302  SegExpSharedPtr segexp[3];
303  for(i = 0; i < 3; i++)
304  {
305  segexp[i] = MemoryManager<LocalRegions::SegExp>::AllocateSharedPtr(m_base[i!=0]->GetBasisKey(),GetGeom2D()->GetEdge(i));
306  }
307 
308  Array<OneD, unsigned int> mapArray;
309  Array<OneD, int> signArray;
310  NekDouble sign;
311 
312  for(i = 0; i < 3; i++)
313  {
314  segexp[i!=0]->FwdTrans_BndConstrained(physEdge[i],coeffEdge[i]);
315 
316  GetEdgeToElementMap(i,orient[i],mapArray,signArray);
317  for(j=0; j < nmodes[i!=0]; j++)
318  {
319  sign = (NekDouble) signArray[j];
320  outarray[ mapArray[j] ] = sign * coeffEdge[i][j];
321  }
322  }
323 
324  int nBoundaryDofs = NumBndryCoeffs();
325  int nInteriorDofs = m_ncoeffs - nBoundaryDofs;
326 
327  if (nInteriorDofs > 0) {
330 
332  MassMatrixOp(outarray,tmp0,stdmasskey);
333  IProductWRTBase(inarray,tmp1);
334 
335  Vmath::Vsub(m_ncoeffs, tmp1, 1, tmp0, 1, tmp1, 1);
336 
337  // get Mass matrix inverse (only of interior DOF)
338  // use block (1,1) of the static condensed system
339  // note: this block alreay contains the inverse matrix
340  MatrixKey masskey(StdRegions::eMass,DetShapeType(),*this);
341  DNekScalMatSharedPtr matsys = (m_staticCondMatrixManager[masskey])->GetBlock(1,1);
342 
343  Array<OneD, NekDouble> rhs(nInteriorDofs);
344  Array<OneD, NekDouble> result(nInteriorDofs);
345 
346  GetInteriorMap(mapArray);
347 
348  for(i = 0; i < nInteriorDofs; i++)
349  {
350  rhs[i] = tmp1[ mapArray[i] ];
351  }
352 
353  Blas::Dgemv('N', nInteriorDofs, nInteriorDofs, matsys->Scale(), &((matsys->GetOwnedMatrix())->GetPtr())[0],
354  nInteriorDofs,rhs.get(),1,0.0,result.get(),1);
355 
356  for(i = 0; i < nInteriorDofs; i++)
357  {
358  outarray[ mapArray[i] ] = result[i];
359  }
360  }
361  }
362 
363 
365  Array<OneD, NekDouble> &outarray)
366  {
367  IProductWRTBase_SumFac(inarray,outarray);
368  }
369 
370 
371  void TriExp::v_IProductWRTDerivBase(const int dir,
372  const Array<OneD, const NekDouble>& inarray,
373  Array<OneD, NekDouble> & outarray)
374  {
375  IProductWRTDerivBase_SumFac(dir,inarray,outarray);
376  }
377 
378 
380  Array<OneD, NekDouble> &outarray,
381  bool multiplybyweights)
382  {
383  int nquad0 = m_base[0]->GetNumPoints();
384  int nquad1 = m_base[1]->GetNumPoints();
385  int order0 = m_base[0]->GetNumModes();
386 
387  if(multiplybyweights)
388  {
389  Array<OneD,NekDouble> tmp(nquad0*nquad1+nquad1*order0);
390  Array<OneD,NekDouble> wsp(tmp+nquad0*nquad1);
391 
392  MultiplyByQuadratureMetric(inarray,tmp);
393  IProductWRTBase_SumFacKernel(m_base[0]->GetBdata(),m_base[1]->GetBdata(),tmp,outarray,wsp);
394  }
395  else
396  {
397  Array<OneD,NekDouble> wsp(+nquad1*order0);
398 
399  IProductWRTBase_SumFacKernel(m_base[0]->GetBdata(),m_base[1]->GetBdata(),
400  inarray,outarray,wsp);
401  }
402  }
403 
404 
406  Array<OneD, NekDouble> &outarray)
407  {
408  int nq = GetTotPoints();
410  DNekScalMatSharedPtr iprodmat = m_matrixManager[iprodmatkey];
411 
412  Blas::Dgemv('N',m_ncoeffs,nq,iprodmat->Scale(),(iprodmat->GetOwnedMatrix())->GetPtr().get(),
413  m_ncoeffs, inarray.get(), 1, 0.0, outarray.get(), 1);
414 
415  }
416 
417 
419  const Array<OneD, const NekDouble>& inarray,
420  Array<OneD, NekDouble> & outarray)
421  {
422  ASSERTL1((dir==0)||(dir==1)||(dir==2),"Invalid direction.");
423  ASSERTL1((dir==2)?(m_geom->GetCoordim()==3):true,"Invalid direction.");
424 
425  int i;
426  int nquad0 = m_base[0]->GetNumPoints();
427  int nquad1 = m_base[1]->GetNumPoints();
428  int nqtot = nquad0*nquad1;
429  int nmodes0 = m_base[0]->GetNumModes();
430  int wspsize = max(max(nqtot,m_ncoeffs),nquad1*nmodes0);
431 
432  const Array<TwoD, const NekDouble>& df =
433  m_metricinfo->GetDerivFactors(GetPointsKeys());
434 
435  Array<OneD, NekDouble> tmp0 (6*wspsize);
436  Array<OneD, NekDouble> tmp1 (tmp0 + wspsize);
437  Array<OneD, NekDouble> tmp2 (tmp0 + 2*wspsize);
438  Array<OneD, NekDouble> tmp3 (tmp0 + 3*wspsize);
439  Array<OneD, NekDouble> gfac0(tmp0 + 4*wspsize);
440  Array<OneD, NekDouble> gfac1(tmp0 + 5*wspsize);
441 
442  const Array<OneD, const NekDouble>& z0 = m_base[0]->GetZ();
443  const Array<OneD, const NekDouble>& z1 = m_base[1]->GetZ();
444 
445  // set up geometric factor: 2/(1-z1)
446  for(i = 0; i < nquad1; ++i)
447  {
448  gfac0[i] = 2.0/(1-z1[i]);
449  }
450  for(i = 0; i < nquad0; ++i)
451  {
452  gfac1[i] = 0.5*(1+z0[i]);
453  }
454 
455  for(i = 0; i < nquad1; ++i)
456  {
457  Vmath::Smul(nquad0,gfac0[i],&inarray[0]+i*nquad0,1,&tmp0[0]+i*nquad0,1);
458  }
459 
460  for(i = 0; i < nquad1; ++i)
461  {
462  Vmath::Vmul(nquad0,&gfac1[0],1,&tmp0[0]+i*nquad0,1,&tmp1[0]+i*nquad0,1);
463  }
464 
465  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
466  {
467  Vmath::Vmul(nqtot,&df[2*dir][0], 1,&tmp0[0], 1,&tmp0[0],1);
468  Vmath::Vmul(nqtot,&df[2*dir+1][0],1,&tmp1[0], 1,&tmp1[0],1);
469  Vmath::Vmul(nqtot,&df[2*dir+1][0],1,&inarray[0],1,&tmp2[0],1);
470  }
471  else
472  {
473  Vmath::Smul(nqtot, df[2*dir][0], tmp0, 1, tmp0, 1);
474  Vmath::Smul(nqtot, df[2*dir+1][0], tmp1, 1, tmp1, 1);
475  Vmath::Smul(nqtot, df[2*dir+1][0], inarray, 1, tmp2, 1);
476  }
477  Vmath::Vadd(nqtot, tmp0, 1, tmp1, 1, tmp1, 1);
478 
479  MultiplyByQuadratureMetric(tmp1,tmp1);
480  MultiplyByQuadratureMetric(tmp2,tmp2);
481 
482  IProductWRTBase_SumFacKernel(m_base[0]->GetDbdata(),m_base[1]->GetBdata() ,tmp1,tmp3 ,tmp0);
483  IProductWRTBase_SumFacKernel(m_base[0]->GetBdata() ,m_base[1]->GetDbdata(),tmp2,outarray,tmp0);
484  Vmath::Vadd(m_ncoeffs, tmp3, 1, outarray, 1, outarray, 1);
485  }
486 
487 
489  const Array<OneD, const NekDouble>& inarray,
490  Array<OneD, NekDouble> &outarray)
491  {
492  int nq = GetTotPoints();
494 
495  switch(dir)
496  {
497  case 0:
498  {
500  }
501  break;
502  case 1:
503  {
505  }
506  break;
507  case 2:
508  {
510  }
511  break;
512  default:
513  {
514  ASSERTL1(false,"input dir is out of range");
515  }
516  break;
517  }
518 
519  MatrixKey iprodmatkey(mtype,DetShapeType(),*this);
520  DNekScalMatSharedPtr iprodmat = m_matrixManager[iprodmatkey];
521 
522  Blas::Dgemv('N',m_ncoeffs,nq,iprodmat->Scale(),(iprodmat->GetOwnedMatrix())->GetPtr().get(),
523  m_ncoeffs, inarray.get(), 1, 0.0, outarray.get(), 1);
524 
525  }
526 
531  Array<OneD, NekDouble> &outarray)
532  {
533  int nq = m_base[0]->GetNumPoints()*m_base[1]->GetNumPoints();
535 
536  const Array<OneD, const Array<OneD, NekDouble> > &normals =
537  GetLeftAdjacentElementExp()->GetFaceNormal(
539 
540  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
541  {
542  Vmath::Vvtvvtp(nq,&normals[0][0],1,&Fx[0],1,
543  &normals[1][0],1,&Fy[0],1,&Fn[0],1);
544  Vmath::Vvtvp (nq,&normals[2][0],1,&Fz[0],1,&Fn[0],1,&Fn[0],1);
545  }
546  else
547  {
548  Vmath::Svtsvtp(nq,normals[0][0],&Fx[0],1,
549  normals[1][0],&Fy[0],1,&Fn[0],1);
550  Vmath::Svtvp (nq,normals[2][0],&Fz[0],1,&Fn[0],1,&Fn[0],1);
551  }
552 
553  IProductWRTBase(Fn,outarray);
554  }
555 
557  {
558 
560  ::AllocateSharedPtr(m_base[0]->GetBasisKey(),
561  m_base[1]->GetBasisKey());
562  }
563 
565  Array<OneD,NekDouble> &coords)
566  {
567  int i;
568 
569  ASSERTL1(Lcoords[0] >= -1.0 && Lcoords[1] <= 1.0 &&
570  Lcoords[1] >= -1.0 && Lcoords[1] <=1.0,
571  "Local coordinates are not in region [-1,1]");
572 
573  m_geom->FillGeom();
574 
575  for(i = 0; i < m_geom->GetCoordim(); ++i)
576  {
577  coords[i] = m_geom->GetCoord(i,Lcoords);
578  }
579  }
580 
582  Array<OneD, NekDouble> &coords_0,
583  Array<OneD, NekDouble> &coords_1,
584  Array<OneD, NekDouble> &coords_2)
585  {
586  Expansion::v_GetCoords(coords_0, coords_1, coords_2);
587  }
588 
589 
590  /**
591  * Given the local cartesian coordinate \a Lcoord evaluate the
592  * value of physvals at this point by calling through to the
593  * StdExpansion method
594  */
596  const Array<OneD, const NekDouble> &Lcoord,
597  const Array<OneD, const NekDouble> &physvals)
598  {
599  // Evaluate point in local (eta) coordinates.
600  return StdTriExp::v_PhysEvaluate(Lcoord,physvals);
601  }
602 
604  {
606 
607  ASSERTL0(m_geom,"m_geom not defined");
608  m_geom->GetLocCoords(coord,Lcoord);
609 
610  return StdTriExp::v_PhysEvaluate(Lcoord, physvals);
611  }
612 
613 
615  const int edge,
616  const StdRegions::StdExpansionSharedPtr &EdgeExp,
617  const Array<OneD, const NekDouble> &inarray,
618  Array<OneD,NekDouble> &outarray,
620  {
621  v_GetEdgePhysVals(edge,EdgeExp,inarray,outarray);
622  }
623 
625  const int edge,
626  const Array<OneD, const NekDouble> &inarray,
627  Array<OneD,NekDouble> &outarray)
628  {
629  int nquad0 = m_base[0]->GetNumPoints();
630  int nquad1 = m_base[1]->GetNumPoints();
631 
632  StdRegions::Orientation edgedir = GetEorient(edge);
633  switch(edge)
634  {
635  case 0:
636  if (edgedir == StdRegions::eForwards)
637  {
638  Vmath::Vcopy(nquad0,&(inarray[0]),1,&(outarray[0]),1);
639  }
640  else
641  {
642  Vmath::Vcopy(nquad0,&(inarray[0])+(nquad0-1),-1,
643  &(outarray[0]),1);
644  }
645  break;
646  case 1:
647  if (edgedir == StdRegions::eForwards)
648  {
649  Vmath::Vcopy(nquad1,&(inarray[0])+(nquad0-1),nquad0,
650  &(outarray[0]),1);
651  }
652  else
653  {
654  Vmath::Vcopy(nquad1,&(inarray[0])+(nquad0*nquad1-1),
655  -nquad0, &(outarray[0]),1);
656  }
657  break;
658  case 2:
659  if (edgedir == StdRegions::eForwards)
660  {
661  Vmath::Vcopy(nquad1,&(inarray[0]) + nquad0*(nquad1-1),
662  -nquad0,&(outarray[0]),1);
663  }
664  else
665  {
666  Vmath::Vcopy(nquad1,&(inarray[0]),nquad0,
667  &(outarray[0]),1);
668  }
669  break;
670  default:
671  ASSERTL0(false,"edge value (< 3) is out of range");
672  break;
673  }
674  }
675 
677  const Array<OneD, const NekDouble> &inarray,
678  Array<OneD,NekDouble> &outarray)
679  {
680  int nquad0 = m_base[0]->GetNumPoints();
681  int nquad1 = m_base[1]->GetNumPoints();
682 
683  // get points in Cartesian orientation
684  switch(edge)
685  {
686  case 0:
687  Vmath::Vcopy(nquad0,&(inarray[0]),1,&(outarray[0]),1);
688  break;
689  case 1:
690  Vmath::Vcopy(nquad1,&(inarray[0])+(nquad0-1),nquad0,&(outarray[0]),1);
691  break;
692  case 2:
693  Vmath::Vcopy(nquad1,&(inarray[0]),nquad0,&(outarray[0]),1);
694  break;
695  default:
696  ASSERTL0(false,"edge value (< 3) is out of range");
697  break;
698  }
699 
700  // Interpolate if required
701  if(m_base[edge?1:0]->GetPointsKey() != EdgeExp->GetBasis(0)->GetPointsKey())
702  {
703  Array<OneD,NekDouble> outtmp(max(nquad0,nquad1));
704 
705  outtmp = outarray;
706 
707  LibUtilities::Interp1D(m_base[edge?1:0]->GetPointsKey(),outtmp,
708  EdgeExp->GetBasis(0)->GetPointsKey(),outarray);
709  }
710 
711  //Reverse data if necessary
713  {
714  Vmath::Reverse(EdgeExp->GetNumPoints(0),&outarray[0],1,
715  &outarray[0],1);
716  }
717 
718  }
719 
720 
722  const int edge,const Array<OneD, const NekDouble> &inarray,
723  Array<OneD, NekDouble> &outarray)
724  {
725  ASSERTL0(false,
726  "Routine not implemented for triangular elements");
727  }
728 
730  const int edge,
731  Array<OneD, NekDouble> &outarray)
732  {
733  ASSERTL0(false,
734  "Routine not implemented for triangular elements");
735  }
736 
737 
738  void TriExp::v_ComputeEdgeNormal(const int edge)
739  {
740  int i;
741  const SpatialDomains::GeomFactorsSharedPtr & geomFactors = GetGeom()->GetMetricInfo();
743  const SpatialDomains::GeomType type = geomFactors->GetGtype();
744  const Array<TwoD, const NekDouble> & df = geomFactors->GetDerivFactors(ptsKeys);
745  const Array<OneD, const NekDouble> & jac = geomFactors->GetJac(ptsKeys);
746  int nqe = m_base[0]->GetNumPoints();
747  int dim = GetCoordim();
748 
751  for (i = 0; i < dim; ++i)
752  {
753  normal[i] = Array<OneD, NekDouble>(nqe);
754  }
755 
756  // Regular geometry case
758  {
759  NekDouble fac;
760  // Set up normals
761  switch(edge)
762  {
763  case 0:
764  for(i = 0; i < GetCoordim(); ++i)
765  {
766  Vmath::Fill(nqe,-df[2*i+1][0],normal[i],1);
767  }
768  break;
769  case 1:
770  for(i = 0; i < GetCoordim(); ++i)
771  {
772  Vmath::Fill(nqe,df[2*i+1][0] + df[2*i][0],normal[i],1);
773  }
774  break;
775  case 2:
776  for(i = 0; i < GetCoordim(); ++i)
777  {
778  Vmath::Fill(nqe,-df[2*i][0],normal[i],1);
779  }
780  break;
781  default:
782  ASSERTL0(false,"Edge is out of range (edge < 3)");
783  }
784 
785  // normalise
786  fac = 0.0;
787  for(i =0 ; i < GetCoordim(); ++i)
788  {
789  fac += normal[i][0]*normal[i][0];
790  }
791  fac = 1.0/sqrt(fac);
792  for (i = 0; i < GetCoordim(); ++i)
793  {
794  Vmath::Smul(nqe,fac,normal[i],1,normal[i],1);
795  }
796  }
797  else // Set up deformed normals
798  {
799  int j;
800 
801  int nquad0 = ptsKeys[0].GetNumPoints();
802  int nquad1 = ptsKeys[1].GetNumPoints();
803 
804  LibUtilities::PointsKey from_key;
805 
806  Array<OneD,NekDouble> normals(GetCoordim()*max(nquad0,nquad1),0.0);
807  Array<OneD,NekDouble> edgejac(GetCoordim()*max(nquad0,nquad1),0.0);
808 
809  // Extract Jacobian along edges and recover local
810  // derivates (dx/dr) for polynomial interpolation by
811  // multiplying m_gmat by jacobian
812  switch(edge)
813  {
814  case 0:
815  for(j = 0; j < nquad0; ++j)
816  {
817  edgejac[j] = jac[j];
818  for(i = 0; i < GetCoordim(); ++i)
819  {
820  normals[i*nquad0+j] = -df[2*i+1][j]*edgejac[j];
821  }
822  }
823  from_key = ptsKeys[0];
824  break;
825  case 1:
826  for(j = 0; j < nquad1; ++j)
827  {
828  edgejac[j] = jac[nquad0*j+nquad0-1];
829  for(i = 0; i < GetCoordim(); ++i)
830  {
831  normals[i*nquad1+j] = (df[2*i][nquad0*j + nquad0-1] + df[2*i+1][nquad0*j + nquad0-1])*edgejac[j];
832  }
833  }
834  from_key = ptsKeys[1];
835  break;
836  case 2:
837  for(j = 0; j < nquad1; ++j)
838  {
839  edgejac[j] = jac[nquad0*j];
840  for(i = 0; i < GetCoordim(); ++i)
841  {
842  normals[i*nquad1+j] = -df[2*i][nquad0*j]*edgejac[j];
843  }
844  }
845  from_key = ptsKeys[1];
846  break;
847  default:
848  ASSERTL0(false,"edge is out of range (edge < 3)");
849 
850  }
851 
852  int nq = from_key.GetNumPoints();
853  Array<OneD,NekDouble> work(nqe,0.0);
854 
855  // interpolate Jacobian and invert
856  LibUtilities::Interp1D(from_key,jac,m_base[0]->GetPointsKey(),work);
857  Vmath::Sdiv(nq,1.0,&work[0],1,&work[0],1);
858 
859  // interpolate
860  for(i = 0; i < GetCoordim(); ++i)
861  {
862  LibUtilities::Interp1D(from_key,&normals[i*nq],m_base[0]->GetPointsKey(),&normal[i][0]);
863  Vmath::Vmul(nqe,work,1,normal[i],1,normal[i],1);
864  }
865 
866  //normalise normal vectors
867  Vmath::Zero(nqe,work,1);
868  for(i = 0; i < GetCoordim(); ++i)
869  {
870  Vmath::Vvtvp(nqe,normal[i],1, normal[i],1,work,1,work,1);
871  }
872 
873  Vmath::Vsqrt(nqe,work,1,work,1);
874  Vmath::Sdiv(nqe,1.0,work,1,work,1);
875 
876  for(i = 0; i < GetCoordim(); ++i)
877  {
878  Vmath::Vmul(nqe,normal[i],1,work,1,normal[i],1);
879  }
880 
881  // Reverse direction so that points are in
882  // anticlockwise direction if edge >=2
883  if(edge >= 2)
884  {
885  for(i = 0; i < GetCoordim(); ++i)
886  {
887  Vmath::Reverse(nqe,normal[i],1, normal[i],1);
888  }
889  }
890  }
892  {
893  for(i = 0; i < GetCoordim(); ++i)
894  {
895  if(geomFactors->GetGtype() == SpatialDomains::eDeformed)
896  {
897  Vmath::Reverse(nqe, normal[i], 1, normal[i],1);
898  }
899  }
900  }
901  }
902 
904  {
905  return m_geom->GetCoordim();
906  }
907 
908 
910  const std::vector<unsigned int > &nummodes, const int mode_offset, NekDouble * coeffs)
911  {
912  int data_order0 = nummodes[mode_offset];
913  int fillorder0 = min(m_base[0]->GetNumModes(),data_order0);
914  int data_order1 = nummodes[mode_offset+1];
915  int order1 = m_base[1]->GetNumModes();
916  int fillorder1 = min(order1,data_order1);
917 
918  switch(m_base[0]->GetBasisType())
919  {
921  {
922  int i;
923  int cnt = 0;
924  int cnt1 = 0;
925 
927  "Extraction routine not set up for this basis");
928 
929  Vmath::Zero(m_ncoeffs,coeffs,1);
930  for(i = 0; i < fillorder0; ++i)
931  {
932  Vmath::Vcopy(fillorder1-i,&data[cnt],1,&coeffs[cnt1],1);
933  cnt += data_order1-i;
934  cnt1 += order1-i;
935  }
936  }
937  break;
938  default:
939  ASSERTL0(false,"basis is either not set up or not hierarchicial");
940  }
941  }
942 
943 
945  {
946  return GetGeom2D()->GetEorient(edge);
947  }
948 
949 
951  {
952  return GetGeom2D()->GetCartesianEorient(edge);
953  }
954 
955 
957  {
958  ASSERTL1(dir >= 0 &&dir <= 1,"input dir is out of range");
959  return m_base[dir];
960  }
961 
962 
963  int TriExp::v_GetNumPoints(const int dir) const
964  {
965  return GetNumPoints(dir);
966  }
967 
968 
970  {
971  DNekMatSharedPtr returnval;
972  switch(mkey.GetMatrixType())
973  {
981  returnval = Expansion2D::v_GenMatrix(mkey);
982  break;
983  default:
984  returnval = StdTriExp::v_GenMatrix(mkey);
985  break;
986  }
987 
988  return returnval;
989  }
990 
991 
993  {
994  LibUtilities::BasisKey bkey0 = m_base[0]->GetBasisKey();
995  LibUtilities::BasisKey bkey1 = m_base[1]->GetBasisKey();
997  AllocateSharedPtr(bkey0,bkey1);
998 
999  return tmp->GetStdMatrix(mkey);
1000  }
1001 
1002 
1004  {
1005  DNekScalMatSharedPtr returnval;
1007 
1008  ASSERTL2(m_metricinfo->GetGtype() != SpatialDomains::eNoGeomType,"Geometric information is not set up");
1009 
1010  switch(mkey.GetMatrixType())
1011  {
1012  case StdRegions::eMass:
1013  {
1014  if((m_metricinfo->GetGtype() == SpatialDomains::eDeformed)||
1015  (mkey.GetNVarCoeff()))
1016  {
1017  NekDouble one = 1.0;
1018  DNekMatSharedPtr mat = GenMatrix(mkey);
1019  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,mat);
1020  }
1021  else
1022  {
1023  NekDouble jac = (m_metricinfo->GetJac(ptsKeys))[0];
1024  DNekMatSharedPtr mat = GetStdMatrix(mkey);
1025  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(jac,mat);
1026  }
1027  }
1028  break;
1029  case StdRegions::eInvMass:
1030  {
1031  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1032  {
1033  NekDouble one = 1.0;
1035  *this);
1036  DNekMatSharedPtr mat = GenMatrix(masskey);
1037  mat->Invert();
1038 
1039  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,mat);
1040  }
1041  else
1042  {
1043  NekDouble fac = 1.0/(m_metricinfo->GetJac(ptsKeys))[0];
1044  DNekMatSharedPtr mat = GetStdMatrix(mkey);
1045  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(fac,mat);
1046 
1047  }
1048  }
1049  break;
1053  {
1054  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed || mkey.GetNVarCoeff())
1055  {
1056  NekDouble one = 1.0;
1057  DNekMatSharedPtr mat = GenMatrix(mkey);
1058 
1059  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,mat);
1060  }
1061  else
1062  {
1063  NekDouble jac = (m_metricinfo->GetJac(ptsKeys))[0];
1064  Array<TwoD, const NekDouble> df = m_metricinfo->GetDerivFactors(ptsKeys);
1065  int dir = 0;
1066  switch(mkey.GetMatrixType())
1067  {
1069  dir = 0;
1070  break;
1072  dir = 1;
1073  break;
1075  dir = 2;
1076  break;
1077  default:
1078  break;
1079  }
1080 
1082  mkey.GetShapeType(), *this);
1084  mkey.GetShapeType(), *this);
1085 
1086  DNekMat &deriv0 = *GetStdMatrix(deriv0key);
1087  DNekMat &deriv1 = *GetStdMatrix(deriv1key);
1088 
1089  int rows = deriv0.GetRows();
1090  int cols = deriv1.GetColumns();
1091 
1093  (*WeakDeriv) = df[2*dir][0]*deriv0 + df[2*dir+1][0]*deriv1;
1094 
1095  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(jac,WeakDeriv);
1096  }
1097  }
1098  break;
1100  {
1101  if( (m_metricinfo->GetGtype() == SpatialDomains::eDeformed) ||
1103  {
1104  NekDouble one = 1.0;
1105  DNekMatSharedPtr mat = GenMatrix(mkey);
1106 
1107  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,mat);
1108  }
1109  else
1110  {
1112  mkey.GetShapeType(), *this);
1114  mkey.GetShapeType(), *this);
1116  mkey.GetShapeType(), *this);
1117 
1118  DNekMat &lap00 = *GetStdMatrix(lap00key);
1119  DNekMat &lap01 = *GetStdMatrix(lap01key);
1120  DNekMat &lap11 = *GetStdMatrix(lap11key);
1121 
1122  NekDouble jac = (m_metricinfo->GetJac(ptsKeys))[0];
1124  m_metricinfo->GetGmat(ptsKeys);
1125 
1126  int rows = lap00.GetRows();
1127  int cols = lap00.GetColumns();
1128 
1130 
1131  (*lap) = gmat[0][0] * lap00 +
1132  gmat[1][0] * (lap01 + Transpose(lap01)) +
1133  gmat[3][0] * lap11;
1134 
1135  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(jac,lap);
1136  }
1137  }
1138  break;
1140  {
1141  DNekMatSharedPtr mat = GenMatrix(mkey);
1142  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(1.0,mat);
1143  }
1144  break;
1146  {
1148 
1149  MatrixKey masskey(mkey, StdRegions::eMass);
1150  DNekScalMat &MassMat = *(this->m_matrixManager[masskey]);
1151 
1152  MatrixKey lapkey(mkey, StdRegions::eLaplacian);
1153  DNekScalMat &LapMat = *(this->m_matrixManager[lapkey]);
1154 
1155  int rows = LapMat.GetRows();
1156  int cols = LapMat.GetColumns();
1157 
1159 
1160  NekDouble one = 1.0;
1161  (*helm) = LapMat + factor*MassMat;
1162 
1163  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,helm);
1164  }
1165  break;
1167  {
1168  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1169  {
1170  NekDouble one = 1.0;
1171  DNekMatSharedPtr mat = GenMatrix(mkey);
1172  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,mat);
1173  }
1174  else
1175  {
1176  NekDouble jac = (m_metricinfo->GetJac(ptsKeys))[0];
1177  DNekMatSharedPtr mat = GetStdMatrix(mkey);
1178  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(jac,mat);
1179  }
1180  }
1181  break;
1185  {
1186  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1187  {
1188  NekDouble one = 1.0;
1189  DNekMatSharedPtr mat = GenMatrix(mkey);
1190  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,mat);
1191  }
1192  else
1193  {
1194  NekDouble jac = (m_metricinfo->GetJac(ptsKeys))[0];
1195 
1196  const Array<TwoD, const NekDouble>& df = m_metricinfo->GetDerivFactors(ptsKeys);
1197  int dir = 0;
1198 
1199  switch(mkey.GetMatrixType())
1200  {
1202  dir = 0;
1203  break;
1205  dir = 1;
1206  break;
1208  dir = 2;
1209  break;
1210  default:
1211  break;
1212  }
1213 
1215  mkey.GetShapeType(), *this);
1217  mkey.GetShapeType(), *this);
1218 
1219  DNekMat &stdiprod0 = *GetStdMatrix(iProdDeriv0Key);
1220  DNekMat &stdiprod1 = *GetStdMatrix(iProdDeriv0Key);
1221 
1222  int rows = stdiprod0.GetRows();
1223  int cols = stdiprod1.GetColumns();
1224 
1226  (*mat) = df[2*dir][0]*stdiprod0 + df[2*dir+1][0]*stdiprod1;
1227 
1228  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(jac,mat);
1229  }
1230  }
1231  break;
1232 
1234  {
1235  NekDouble one = 1.0;
1236 
1238 
1239  DNekMatSharedPtr mat = GenMatrix(hkey);
1240 
1241  mat->Invert();
1242  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,mat);
1243  }
1244  break;
1246  {
1247  NekDouble one = 1.0;
1248  MatrixKey helmkey(StdRegions::eHelmholtz, mkey.GetShapeType(), *this, mkey.GetConstFactors(), mkey.GetVarCoeffs());
1249  DNekScalBlkMatSharedPtr helmStatCond = GetLocStaticCondMatrix(helmkey);
1250  DNekScalMatSharedPtr A =helmStatCond->GetBlock(0,0);
1252 
1254  }
1255  break;
1256  default:
1257  {
1258  NekDouble one = 1.0;
1259  DNekMatSharedPtr mat = GenMatrix(mkey);
1260 
1261  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,mat);
1262  }
1263  break;
1264  }
1265 
1266  return returnval;
1267  }
1268 
1269 
1271  {
1272  DNekScalBlkMatSharedPtr returnval;
1274 
1275  ASSERTL2(m_metricinfo->GetGtype() != SpatialDomains::eNoGeomType,"Geometric information is not set up");
1276 
1277  // set up block matrix system
1278  unsigned int nbdry = NumBndryCoeffs();
1279  unsigned int nint = (unsigned int)(m_ncoeffs - nbdry);
1280  unsigned int exp_size[] = {nbdry,nint};
1281  unsigned int nblks = 2;
1282  returnval = MemoryManager<DNekScalBlkMat>::AllocateSharedPtr(nblks,nblks,exp_size,exp_size); //Really need a constructor which takes Arrays
1283  NekDouble factor = 1.0;
1284 
1285  switch(mkey.GetMatrixType())
1286  {
1287  // this can only use stdregions statically condensed system for mass matrix
1288  case StdRegions::eMass:
1289  if((m_metricinfo->GetGtype() == SpatialDomains::eDeformed)||(mkey.GetNVarCoeff()))
1290  {
1291  factor = 1.0;
1292  goto UseLocRegionsMatrix;
1293  }
1294  else
1295  {
1296  factor = (m_metricinfo->GetJac(ptsKeys))[0];
1297  goto UseStdRegionsMatrix;
1298  }
1299  break;
1300  default: // use Deformed case for both regular and deformed geometries
1301  factor = 1.0;
1302  goto UseLocRegionsMatrix;
1303  break;
1304  UseStdRegionsMatrix:
1305  {
1306  NekDouble invfactor = 1.0/factor;
1307  NekDouble one = 1.0;
1309  DNekScalMatSharedPtr Atmp;
1310  DNekMatSharedPtr Asubmat;
1311 
1312  returnval->SetBlock(0,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,Asubmat = mat->GetBlock(0,0)));
1313  returnval->SetBlock(0,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,Asubmat = mat->GetBlock(0,1)));
1314  returnval->SetBlock(1,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,Asubmat = mat->GetBlock(1,0)));
1315  returnval->SetBlock(1,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(invfactor,Asubmat = mat->GetBlock(1,1)));
1316  }
1317  break;
1318 
1319  UseLocRegionsMatrix:
1320  {
1321  int i,j;
1322  NekDouble invfactor = 1.0/factor;
1323  NekDouble one = 1.0;
1324 
1325  DNekScalMat &mat = *GetLocMatrix(mkey);
1326 
1331 
1332  Array<OneD,unsigned int> bmap(nbdry);
1333  Array<OneD,unsigned int> imap(nint);
1334  GetBoundaryMap(bmap);
1335  GetInteriorMap(imap);
1336 
1337  for(i = 0; i < nbdry; ++i)
1338  {
1339  for(j = 0; j < nbdry; ++j)
1340  {
1341  (*A)(i,j) = mat(bmap[i],bmap[j]);
1342  }
1343 
1344  for(j = 0; j < nint; ++j)
1345  {
1346  (*B)(i,j) = mat(bmap[i],imap[j]);
1347  }
1348  }
1349 
1350  for(i = 0; i < nint; ++i)
1351  {
1352  for(j = 0; j < nbdry; ++j)
1353  {
1354  (*C)(i,j) = mat(imap[i],bmap[j]);
1355  }
1356 
1357  for(j = 0; j < nint; ++j)
1358  {
1359  (*D)(i,j) = mat(imap[i],imap[j]);
1360  }
1361  }
1362 
1363  // Calculate static condensed system
1364  if(nint)
1365  {
1366  D->Invert();
1367  (*B) = (*B)*(*D);
1368  (*A) = (*A) - (*B)*(*C);
1369  }
1370 
1371  DNekScalMatSharedPtr Atmp;
1372 
1373  returnval->SetBlock(0,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,A));
1374  returnval->SetBlock(0,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,B));
1375  returnval->SetBlock(1,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,C));
1376  returnval->SetBlock(1,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(invfactor,D));
1377 
1378  }
1379  }
1380 
1381  return returnval;
1382  }
1383 
1384 
1386  {
1387  return m_matrixManager[mkey];
1388  }
1389 
1390 
1392  {
1393  return m_staticCondMatrixManager[mkey];
1394  }
1395 
1397  {
1398  m_staticCondMatrixManager.DeleteObject(mkey);
1399  }
1400 
1401 
1402 
1404  Array<OneD,NekDouble> &outarray,
1405  const StdRegions::StdMatrixKey &mkey)
1406  {
1407  StdExpansion::MassMatrixOp_MatFree(inarray,outarray,mkey);
1408  }
1409 
1410 
1412  Array<OneD,NekDouble> &outarray,
1413  const StdRegions::StdMatrixKey &mkey)
1414  {
1415  TriExp::LaplacianMatrixOp_MatFree(inarray,outarray,mkey);
1416  }
1417 
1418 
1419  void TriExp::v_LaplacianMatrixOp(const int k1, const int k2,
1420  const Array<OneD, const NekDouble> &inarray,
1421  Array<OneD,NekDouble> &outarray,
1422  const StdRegions::StdMatrixKey &mkey)
1423  {
1424  StdExpansion::LaplacianMatrixOp_MatFree(k1,k2,inarray,outarray,mkey);
1425  }
1426 
1427 
1429  const Array<OneD, const NekDouble> &inarray,
1430  Array<OneD,NekDouble> &outarray,
1431  const StdRegions::StdMatrixKey &mkey)
1432  {
1433  StdExpansion::WeakDerivMatrixOp_MatFree(i,inarray,outarray,mkey);
1434  }
1435 
1436 
1438  Array<OneD,NekDouble> &outarray,
1439  const StdRegions::StdMatrixKey &mkey)
1440  {
1441  StdExpansion::WeakDirectionalDerivMatrixOp_MatFree(inarray,outarray,mkey);
1442  }
1443 
1444 
1446  Array<OneD,NekDouble> &outarray,
1447  const StdRegions::StdMatrixKey &mkey)
1448  {
1449  StdExpansion::MassLevelCurvatureMatrixOp_MatFree(inarray,outarray,mkey);
1450  }
1451 
1452 
1454  Array<OneD,NekDouble> &outarray,
1455  const StdRegions::StdMatrixKey &mkey)
1456  {
1457  TriExp::HelmholtzMatrixOp_MatFree(inarray,outarray,mkey);
1458  }
1459 
1460 
1462  Array<OneD,NekDouble> &outarray,
1463  const StdRegions::StdMatrixKey &mkey)
1464  {
1465  DNekScalMatSharedPtr mat = GetLocMatrix(mkey);
1466 
1467  if(inarray.get() == outarray.get())
1468  {
1470  Vmath::Vcopy(m_ncoeffs,inarray.get(),1,tmp.get(),1);
1471 
1472  Blas::Dgemv('N',m_ncoeffs,m_ncoeffs,mat->Scale(),(mat->GetOwnedMatrix())->GetPtr().get(),
1473  m_ncoeffs, tmp.get(), 1, 0.0, outarray.get(), 1);
1474  }
1475  else
1476  {
1477  Blas::Dgemv('N',m_ncoeffs,m_ncoeffs,mat->Scale(),(mat->GetOwnedMatrix())->GetPtr().get(),
1478  m_ncoeffs, inarray.get(), 1, 0.0, outarray.get(), 1);
1479  }
1480  }
1481 
1482 
1484  const Array<OneD, const NekDouble> &inarray,
1485  Array<OneD, NekDouble> &outarray,
1487  {
1488  if (m_metrics.count(eMetricLaplacian00) == 0)
1489  {
1491  }
1492 
1493  int nquad0 = m_base[0]->GetNumPoints();
1494  int nquad1 = m_base[1]->GetNumPoints();
1495  int nqtot = nquad0*nquad1;
1496  int nmodes0 = m_base[0]->GetNumModes();
1497  int nmodes1 = m_base[1]->GetNumModes();
1498  int wspsize = max(max(max(nqtot,m_ncoeffs),nquad1*nmodes0),nquad0*nmodes1);
1499 
1500  ASSERTL1(wsp.num_elements() >= 3*wspsize,
1501  "Workspace is of insufficient size.");
1502 
1503  const Array<OneD, const NekDouble>& base0 = m_base[0]->GetBdata();
1504  const Array<OneD, const NekDouble>& base1 = m_base[1]->GetBdata();
1505  const Array<OneD, const NekDouble>& dbase0 = m_base[0]->GetDbdata();
1506  const Array<OneD, const NekDouble>& dbase1 = m_base[1]->GetDbdata();
1510 
1511  // Allocate temporary storage
1512  Array<OneD,NekDouble> wsp0(wsp);
1513  Array<OneD,NekDouble> wsp1(wsp+wspsize);
1514  Array<OneD,NekDouble> wsp2(wsp+2*wspsize);
1515 
1516  StdExpansion2D::PhysTensorDeriv(inarray,wsp1,wsp2);
1517 
1518  // wsp0 = k = g0 * wsp1 + g1 * wsp2 = g0 * du_dxi1 + g1 * du_dxi2
1519  // wsp2 = l = g1 * wsp1 + g2 * wsp2 = g0 * du_dxi1 + g1 * du_dxi2
1520  // where g0, g1 and g2 are the metric terms set up in the GeomFactors class
1521  // especially for this purpose
1522  Vmath::Vvtvvtp(nqtot,&metric00[0],1,&wsp1[0],1,&metric01[0],1,&wsp2[0],1,&wsp0[0],1);
1523  Vmath::Vvtvvtp(nqtot,&metric01[0],1,&wsp1[0],1,&metric11[0],1,&wsp2[0],1,&wsp2[0],1);
1524 
1525  // outarray = m = (D_xi1 * B)^T * k
1526  // wsp1 = n = (D_xi2 * B)^T * l
1527  IProductWRTBase_SumFacKernel(dbase0,base1,wsp0,outarray,wsp1);
1528  IProductWRTBase_SumFacKernel(base0,dbase1,wsp2,wsp1, wsp0);
1529 
1530  // outarray = outarray + wsp1
1531  // = L * u_hat
1532  Vmath::Vadd(m_ncoeffs,wsp1.get(),1,outarray.get(),1,outarray.get(),1);
1533  }
1534 
1535 
1537  {
1538  if (m_metrics.count(eMetricQuadrature) == 0)
1539  {
1541  }
1542 
1543  unsigned int i, j;
1544  const SpatialDomains::GeomType type = m_metricinfo->GetGtype();
1545  const unsigned int nqtot = GetTotPoints();
1546  const unsigned int dim = 2;
1550  };
1551 
1552  Array<OneD, NekDouble> dEta_dXi[2] = {Array<OneD, NekDouble>(nqtot,1.0),
1553  Array<OneD, NekDouble>(nqtot,1.0)};
1554 
1555  for (i = 0; i < dim; ++i)
1556  {
1557  for (j = i; j < dim; ++j)
1558  {
1559  m_metrics[m[i][j]] = Array<OneD, NekDouble>(nqtot);
1560  }
1561  }
1562 
1563  const Array<OneD, const NekDouble>& z0 = m_base[0]->GetZ();
1564  const Array<OneD, const NekDouble>& z1 = m_base[1]->GetZ();
1565  const unsigned int nquad0 = m_base[0]->GetNumPoints();
1566  const unsigned int nquad1 = m_base[1]->GetNumPoints();
1567  const Array<TwoD, const NekDouble>& df =
1568  m_metricinfo->GetDerivFactors(GetPointsKeys());
1569 
1570  for(i = 0; i < nquad1; i++)
1571  {
1572  Blas::Dscal(nquad0,2.0/(1-z1[i]),&dEta_dXi[0][0]+i*nquad0,1);
1573  Blas::Dscal(nquad0,2.0/(1-z1[i]),&dEta_dXi[1][0]+i*nquad0,1);
1574  }
1575  for(i = 0; i < nquad0; i++)
1576  {
1577  Blas::Dscal(nquad1,0.5*(1+z0[i]),&dEta_dXi[1][0]+i,nquad0);
1578  }
1579 
1580  Array<OneD, NekDouble> tmp(nqtot);
1581  if((type == SpatialDomains::eRegular ||
1583  {
1584  Vmath::Smul (nqtot,df[0][0],&dEta_dXi[0][0],1,&tmp[0],1);
1585  Vmath::Svtvp(nqtot,df[1][0],&dEta_dXi[1][0],1,&tmp[0],1,&tmp[0],1);
1586 
1587  Vmath::Vmul (nqtot,&tmp[0],1, &tmp[0],1,&m_metrics[eMetricLaplacian00][0],1);
1588  Vmath::Smul (nqtot,df[1][0],&tmp[0],1,&m_metrics[eMetricLaplacian01][0],1);
1589 
1590 
1591  Vmath::Smul (nqtot,df[2][0],&dEta_dXi[0][0],1,&tmp[0],1);
1592  Vmath::Svtvp(nqtot,df[3][0],&dEta_dXi[1][0],1,&tmp[0],1,&tmp[0],1);
1593 
1594  Vmath::Vvtvp(nqtot,&tmp[0],1, &tmp[0],1,&m_metrics[eMetricLaplacian00][0],1,&m_metrics[eMetricLaplacian00][0],1);
1595  Vmath::Svtvp(nqtot,df[3][0],&tmp[0],1,&m_metrics[eMetricLaplacian01][0],1,&m_metrics[eMetricLaplacian01][0],1);
1596 
1597  if(GetCoordim() == 3)
1598  {
1599  Vmath::Smul (nqtot,df[4][0],&dEta_dXi[0][0],1,&tmp[0],1);
1600  Vmath::Svtvp(nqtot,df[5][0],&dEta_dXi[1][0],1,&tmp[0],1,&tmp[0],1);
1601 
1602  Vmath::Vvtvp(nqtot,&tmp[0],1, &tmp[0],1,&m_metrics[eMetricLaplacian00][0],1,&m_metrics[eMetricLaplacian00][0],1);
1603  Vmath::Svtvp(nqtot,df[5][0],&tmp[0],1,&m_metrics[eMetricLaplacian01][0],1,&m_metrics[eMetricLaplacian01][0],1);
1604  }
1605 
1606  NekDouble g2 = df[1][0]*df[1][0] + df[3][0]*df[3][0];
1607  if(GetCoordim() == 3)
1608  {
1609  g2 += df[5][0]*df[5][0];
1610  }
1611  Vmath::Fill(nqtot,g2,&m_metrics[eMetricLaplacian11][0],1);
1612  }
1613  else
1614  {
1615 
1616  Vmath::Vmul (nqtot,&df[0][0],1,&dEta_dXi[0][0],1,&tmp[0],1);
1617  Vmath::Vvtvp(nqtot,&df[1][0],1,&dEta_dXi[1][0],1,&tmp[0],1,&tmp[0],1);
1618 
1619  Vmath::Vmul (nqtot,&tmp[0], 1,&tmp[0], 1,&m_metrics[eMetricLaplacian00][0],1);
1620  Vmath::Vmul (nqtot,&df[1][0],1,&tmp[0], 1,&m_metrics[eMetricLaplacian01][0],1);
1621  Vmath::Vmul (nqtot,&df[1][0],1,&df[1][0],1,&m_metrics[eMetricLaplacian11][0],1);
1622 
1623 
1624  Vmath::Vmul (nqtot,&df[2][0],1,&dEta_dXi[0][0],1,&tmp[0],1);
1625  Vmath::Vvtvp(nqtot,&df[3][0],1,&dEta_dXi[1][0],1,&tmp[0],1,&tmp[0],1);
1626 
1627  Vmath::Vvtvp(nqtot,&tmp[0], 1,&tmp[0], 1,&m_metrics[eMetricLaplacian00][0],1,&m_metrics[eMetricLaplacian00][0],1);
1628  Vmath::Vvtvp(nqtot,&df[3][0],1,&tmp[0], 1,&m_metrics[eMetricLaplacian01][0],1,&m_metrics[eMetricLaplacian01][0],1);
1629  Vmath::Vvtvp(nqtot,&df[3][0],1,&df[3][0],1,&m_metrics[eMetricLaplacian11][0],1,&m_metrics[eMetricLaplacian11][0],1);
1630 
1631  if(GetCoordim() == 3)
1632  {
1633  Vmath::Vmul (nqtot,&df[4][0],1,&dEta_dXi[0][0],1,&tmp[0],1);
1634  Vmath::Vvtvp(nqtot,&df[5][0],1,&dEta_dXi[1][0],1,&tmp[0],1,&tmp[0],1);
1635 
1636  Vmath::Vvtvp(nqtot,&tmp[0], 1,&tmp[0], 1,&m_metrics[eMetricLaplacian00][0],1,&m_metrics[eMetricLaplacian00][0],1);
1637  Vmath::Vvtvp(nqtot,&df[5][0],1,&tmp[0], 1,&m_metrics[eMetricLaplacian01][0],1,&m_metrics[eMetricLaplacian01][0],1);
1638  Vmath::Vvtvp(nqtot,&df[5][0],1,&df[5][0],1,&m_metrics[eMetricLaplacian11][0],1,&m_metrics[eMetricLaplacian11][0],1);
1639  }
1640  }
1641 
1642  for (unsigned int i = 0; i < dim; ++i)
1643  {
1644  for (unsigned int j = i; j < dim; ++j)
1645  {
1647  m_metrics[m[i][j]]);
1648 
1649  }
1650  }
1651  }
1652 
1653  /**
1654  * Function is used to compute exactly the advective numerical flux on
1655  * theinterface of two elements with different expansions, hence an
1656  * appropriate number of Gauss points has to be used. The number of
1657  * Gauss points has to be equal to the number used by the highest
1658  * polynomial degree of the two adjacent elements. Furthermore, this
1659  * function is used to compute the sensor value in each element.
1660  *
1661  * @param numMin Is the reduced polynomial order
1662  * @param inarray Input array of coefficients
1663  * @param dumpVar Output array of reduced coefficients.
1664  */
1666  int numMin,
1667  const Array<OneD, const NekDouble> &inarray,
1668  Array<OneD, NekDouble> &outarray)
1669  {
1670  int n_coeffs = inarray.num_elements();
1671  int nquad0 = m_base[0]->GetNumPoints();
1672  int nquad1 = m_base[1]->GetNumPoints();
1673  int nqtot = nquad0*nquad1;
1674  int nmodes0 = m_base[0]->GetNumModes();
1675  int nmodes1 = m_base[1]->GetNumModes();
1676  int numMin2 = nmodes0, i;
1677 
1678  Array<OneD, NekDouble> coeff(n_coeffs,0.0);
1679  Array<OneD, NekDouble> phys_tmp(nqtot,0.0);
1680  Array<OneD, NekDouble> tmp, tmp2;
1681 
1682  const LibUtilities::PointsKey Pkey0 = m_base[0]->GetPointsKey();
1683  const LibUtilities::PointsKey Pkey1 = m_base[1]->GetPointsKey();
1684 
1686  m_base[0]->GetBasisType(), nmodes0, Pkey0);
1688  m_base[1]->GetBasisType(), nmodes1, Pkey1);
1689  LibUtilities::BasisKey bortho0(
1690  LibUtilities::eOrtho_A, nmodes0, Pkey0);
1691  LibUtilities::BasisKey bortho1(
1692  LibUtilities::eOrtho_B, nmodes1, Pkey1);
1693 
1694  // Check if it is also possible to use the same InterCoeff routine
1695  // which is also used for Quadrilateral and Hexagonal shaped
1696  // elements
1697 
1698  // For now, set up the used basis on the standard element to
1699  // calculate the phys values, set up the orthogonal basis to do a
1700  // forward transform, to obtain the coefficients in orthogonal
1701  // coefficient space
1702  StdRegions::StdTriExpSharedPtr m_OrthoTriExp;
1704 
1706  ::AllocateSharedPtr(b0, b1);
1707  m_OrthoTriExp = MemoryManager<StdRegions::StdTriExp>
1708  ::AllocateSharedPtr(bortho0, bortho1);
1709 
1710  m_TriExp ->BwdTrans(inarray,phys_tmp);
1711  m_OrthoTriExp->FwdTrans(phys_tmp, coeff);
1712 
1713  for (i = 0; i < n_coeffs; i++)
1714  {
1715  if (i == numMin)
1716  {
1717  coeff[i] = 0.0;
1718  numMin += numMin2 - 1;
1719  numMin2 -= 1.0;
1720  }
1721  }
1722 
1723  m_OrthoTriExp->BwdTrans(coeff,phys_tmp);
1724  m_TriExp ->FwdTrans(phys_tmp, outarray);
1725  }
1726 
1728  Array<OneD, NekDouble> &array,
1729  const StdRegions::StdMatrixKey &mkey)
1730  {
1731  int nq = GetTotPoints();
1732 
1733  // Calculate sqrt of the Jacobian
1735  m_metricinfo->GetJac(GetPointsKeys());
1736  Array<OneD, NekDouble> sqrt_jac(nq);
1737  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1738  {
1739  Vmath::Vsqrt(nq,jac,1,sqrt_jac,1);
1740  }
1741  else
1742  {
1743  Vmath::Fill(nq,sqrt(jac[0]),sqrt_jac,1);
1744  }
1745 
1746  // Multiply array by sqrt(Jac)
1747  Vmath::Vmul(nq,sqrt_jac,1,array,1,array,1);
1748 
1749  // Apply std region filter
1750  StdTriExp::v_SVVLaplacianFilter( array, mkey);
1751 
1752  // Divide by sqrt(Jac)
1753  Vmath::Vdiv(nq,array,1,sqrt_jac,1,array,1);
1754  }
1755 
1756  }
1757 }
1758 
LibUtilities::NekManager< MatrixKey, DNekScalMat, MatrixKey::opLess > m_matrixManager
Definition: TriExp.h:276
const LibUtilities::PointsKeyVector GetPointsKeys() const
boost::shared_ptr< StdTriExp > StdTriExpSharedPtr
Definition: StdTriExp.h:266
virtual NekDouble v_StdPhysEvaluate(const Array< OneD, const NekDouble > &Lcoord, const Array< OneD, const NekDouble > &physvals)
Definition: TriExp.cpp:595
LibUtilities::ShapeType DetShapeType() const
This function returns the shape of the expansion domain.
Definition: StdExpansion.h:454
NekDouble GetConstFactor(const ConstFactorType &factor) const
Definition: StdMatrixKey.h:122
DNekMatSharedPtr GenMatrix(const StdMatrixKey &mkey)
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
StdRegions::Orientation GetCartesianEorient(int edge)
Definition: StdExpansion.h:746
const ConstFactorMap & GetConstFactors() const
Definition: StdMatrixKey.h:142
const VarCoeffMap & GetVarCoeffs() const
Definition: StdMatrixKey.h:168
std::vector< PointsKey > PointsKeyVector
Definition: Points.h:220
virtual int v_GetCoordim()
Definition: TriExp.cpp:903
MatrixType GetMatrixType() const
Definition: StdMatrixKey.h:82
virtual DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix(const MatrixKey &mkey)
Definition: TriExp.cpp:1391
void MassMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
Definition: StdExpansion.h:931
static Array< OneD, NekDouble > NullNekDouble1DArray
LibUtilities::NekManager< MatrixKey, DNekScalBlkMat, MatrixKey::opLess > m_staticCondMatrixManager
Definition: TriExp.h:277
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
#define sign(a, b)
return the sign(b)*a
Definition: Polylib.cpp:22
void IProductWRTDerivBase_SumFac(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
void Vsqrt(int n, const T *x, const int incx, T *y, const int incy)
sqrt y = sqrt(x)
Definition: Vmath.cpp:394
virtual int v_GetNumPoints(const int dir) const
Definition: TriExp.cpp:963
void MultiplyByQuadratureMetric(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: StdExpansion.h:902
virtual void v_MassLevelCurvatureMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey)
Definition: TriExp.cpp:1445
void GetEdgeToElementMap(const int eid, const Orientation edgeOrient, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray)
Definition: StdExpansion.h:820
virtual void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: TriExp.cpp:371
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
void IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
this function calculates the inner product of a given function f with the different modes of the expa...
Definition: StdExpansion.h:613
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:46
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: TriExp.cpp:106
void LaplacianMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
virtual void v_WeakDirectionalDerivMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey)
Definition: TriExp.cpp:1437
int GetNumPoints(const int dir) const
This function returns the number of quadrature points in the dir direction.
Definition: StdExpansion.h:229
void Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
svtvp (scalar times vector plus vector): z = alpha*x + y
Definition: Vmath.cpp:471
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:428
Principle Modified Functions .
Definition: BasisType.h:49
std::map< int, StdRegions::NormalVector > m_edgeNormals
Definition: Expansion2D.h:124
SpatialDomains::GeomFactorsSharedPtr m_metricinfo
Definition: Expansion.h:126
StdRegions::Orientation GetEorient(int edge)
Definition: StdExpansion.h:736
STL namespace.
virtual void v_ExtractDataToCoeffs(const NekDouble *data, const std::vector< unsigned int > &nummodes, const int mode_offset, NekDouble *coeffs)
Unpack data from input file assuming it comes from the same expansion type.
Definition: TriExp.cpp:909
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:257
DNekMatSharedPtr BuildVertexMatrix(const DNekScalMatSharedPtr &r_bnd)
Definition: Expansion.cpp:96
LibUtilities::ShapeType GetShapeType() const
Definition: StdMatrixKey.h:87
virtual void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3)
Definition: TriExp.cpp:581
void Vdiv(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:227
SpatialDomains::GeometrySharedPtr m_geom
Definition: Expansion.h:125
virtual void v_PhysDirectionalDeriv(const Array< OneD, const NekDouble > &inarray, const Array< OneD, const NekDouble > &direction, Array< OneD, NekDouble > &out)
Physical derivative along a direction vector.
Definition: TriExp.cpp:194
DNekScalBlkMatSharedPtr GetLocStaticCondMatrix(const LocalRegions::MatrixKey &mkey)
Definition: StdExpansion.h:721
boost::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:70
virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey)
Definition: TriExp.cpp:969
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: TriExp.cpp:244
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)
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:684
boost::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
void IProductWRTBase_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool multiplybyweights=true)
virtual void v_GetEdgePhysVals(const int edge, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Extract the physical values along edge edge from inarray into outarray following the local edge orien...
Definition: TriExp.cpp:624
virtual void v_HelmholtzMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey)
Definition: TriExp.cpp:1453
Principle Orthogonal Functions .
Definition: BasisType.h:47
bool ConstFactorExists(const ConstFactorType &factor) const
Definition: StdMatrixKey.h:131
int GetTotPoints() const
This function returns the total number of quadrature points used in the element.
Definition: StdExpansion.h:141
virtual void v_IProductWRTDerivBase_MatOp(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: TriExp.cpp:488
virtual void v_IProductWRTDerivBase_SumFac(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: TriExp.cpp:418
virtual void v_ComputeEdgeNormal(const int edge)
Definition: TriExp.cpp:738
virtual void v_NormVectorIProductWRTBase(const Array< OneD, const NekDouble > &Fx, const Array< OneD, const NekDouble > &Fy, const Array< OneD, const NekDouble > &Fz, Array< OneD, NekDouble > &outarray)
Definition: TriExp.cpp:527
DNekBlkMatSharedPtr GetStdStaticCondMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:689
boost::shared_ptr< SegExp > SegExpSharedPtr
Definition: SegExp.h:255
virtual void v_ComputeLaplacianMetric()
Definition: TriExp.cpp:1536
SpatialDomains::Geometry2DSharedPtr GetGeom2D() const
Definition: Expansion2D.h:231
void Reverse(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1062
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*y.
Definition: Vmath.cpp:199
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: TriExp.cpp:364
virtual void v_IProductWRTBase_MatOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: TriExp.cpp:405
virtual NekDouble v_Integral(const Array< OneD, const NekDouble > &inarray)
Integrates the specified function over the domain.
Definition: TriExp.cpp:82
virtual void v_GetTracePhysVals(const int edge, const StdRegions::StdExpansionSharedPtr &EdgeExp, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, StdRegions::Orientation orient)
Definition: TriExp.cpp:614
Principle Modified Functions .
Definition: BasisType.h:50
virtual void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3)
Definition: Expansion.cpp:211
virtual void v_GetEdgeQFactors(const int edge, Array< OneD, NekDouble > &outarray)
Definition: TriExp.cpp:729
boost::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
Definition: NekTypeDefs.hpp:74
virtual DNekScalBlkMatSharedPtr CreateStaticCondMatrix(const MatrixKey &mkey)
Definition: TriExp.cpp:1270
void GetInteriorMap(Array< OneD, unsigned int > &outarray)
Definition: StdExpansion.h:795
Principle Orthogonal Functions .
Definition: BasisType.h:46
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
Defines a specification for a set of points.
Definition: Points.h:58
double NekDouble
Expansion3DSharedPtr GetLeftAdjacentElementExp() const
Definition: Expansion2D.h:193
virtual StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const
Definition: TriExp.cpp:556
virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey)
LibUtilities::BasisType GetBasisType(const int dir) const
This function returns the type of basis used in the dir direction.
Definition: StdExpansion.h:165
virtual const LibUtilities::BasisSharedPtr & v_GetBasis(int dir) const
Definition: TriExp.cpp:956
virtual void v_GeneralMatrixOp_MatOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey)
Definition: TriExp.cpp:1461
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:329
boost::shared_ptr< DNekBlkMat > DNekBlkMatSharedPtr
Definition: NekTypeDefs.hpp:72
DNekScalMatSharedPtr GetLocMatrix(const LocalRegions::MatrixKey &mkey)
Definition: Expansion.cpp:83
virtual void v_FwdTrans_BndConstrained(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: TriExp.cpp:262
virtual NekDouble v_PhysEvaluate(const Array< OneD, const NekDouble > &coord, const Array< OneD, const NekDouble > &physvals)
This function evaluates the expansion at a single (arbitrary) point of the domain.
Definition: TriExp.cpp:603
virtual void v_ReduceOrderCoeffs(int numMin, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: TriExp.cpp:1665
virtual StdRegions::Orientation v_GetCartesianEorient(int edge)
Definition: TriExp.cpp:950
SpatialDomains::GeometrySharedPtr GetGeom() const
Definition: Expansion.cpp:148
boost::shared_ptr< GeomFactors > GeomFactorsSharedPtr
Pointer to a GeomFactors object.
Definition: GeomFactors.h:62
void Vvtvvtp(int n, const T *v, int incv, const T *w, int incw, const T *x, int incx, const T *y, int incy, T *z, int incz)
vvtvvtp (vector times vector plus vector times vector):
Definition: Vmath.cpp:523
virtual DNekScalMatSharedPtr v_GetLocMatrix(const MatrixKey &mkey)
Definition: TriExp.cpp:1385
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed t...
Definition: ErrorUtil.hpp:213
Geometry is straight-sided with constant geometric factors.
void Interp1D(const BasisKey &fbasis0, const Array< OneD, const NekDouble > &from, const BasisKey &tbasis0, Array< OneD, NekDouble > &to)
this function interpolates a 1D function evaluated at the quadrature points of the basis fbasis0 to ...
Definition: Interp.cpp:54
void HelmholtzMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
unsigned int GetNumPoints() const
Definition: Points.h:106
virtual void v_WeakDerivMatrixOp(const int i, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey)
Definition: TriExp.cpp:1428
virtual void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdRegions::StdMatrixKey &mkey)
Definition: TriExp.cpp:1727
virtual void v_MassMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey)
Definition: TriExp.cpp:1403
boost::shared_ptr< TriGeom > TriGeomSharedPtr
Definition: TriGeom.h:58
virtual void v_GetCoord(const Array< OneD, const NekDouble > &Lcoords, Array< OneD, NekDouble > &coords)
Definition: TriExp.cpp:564
virtual StdRegions::Orientation v_GetEorient(int edge)
Definition: TriExp.cpp:944
void Svtsvtp(int n, const T alpha, const T *x, int incx, const T beta, const T *y, int incy, T *z, int incz)
vvtvvtp (scalar times vector plus scalar times vector):
Definition: Vmath.cpp:577
virtual void v_IProductWRTBase_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool multiplybyweights=true)
Definition: TriExp.cpp:379
virtual void v_LaplacianMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey)
Definition: TriExp.cpp:1411
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)
GeomType
Indicates the type of element geometry.
boost::shared_ptr< Basis > BasisSharedPtr
virtual void v_LaplacianMatrixOp_MatFree_Kernel(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp)
Definition: TriExp.cpp:1483
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:359
void v_DropLocStaticCondMatrix(const MatrixKey &mkey)
Definition: TriExp.cpp:1396
boost::shared_ptr< StdExpansion > StdExpansionSharedPtr
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:191
Array< OneD, LibUtilities::BasisSharedPtr > m_base
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1038
Geometry is curved or has non-constant factors.
void GetBoundaryMap(Array< OneD, unsigned int > &outarray)
Definition: StdExpansion.h:790
virtual DNekMatSharedPtr v_CreateStdMatrix(const StdRegions::StdMatrixKey &mkey)
Definition: TriExp.cpp:992
Describes the specification for a Basis.
Definition: Basis.h:50
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:285
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:169
virtual void v_GetEdgeInterpVals(const int edge, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: TriExp.cpp:721
virtual DNekScalMatSharedPtr CreateMatrix(const MatrixKey &mkey)
Definition: TriExp.cpp:1003