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