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