Nektar++
NodalTriExp.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File NodalTriExp.cpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: NodalTriExp routines
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
37 
38 using namespace std;
39 
40 namespace Nektar
41 {
42  namespace LocalRegions
43  {
44  NodalTriExp::NodalTriExp(const LibUtilities::BasisKey &Ba,
45  const LibUtilities::BasisKey &Bb,
46  const LibUtilities::PointsType Ntype,
48  StdExpansion (LibUtilities::StdTriData::getNumberOfCoefficients(Ba.GetNumModes(),(Bb.GetNumModes())),2,Ba,Bb),
49  StdExpansion2D(LibUtilities::StdTriData::getNumberOfCoefficients(Ba.GetNumModes(),(Bb.GetNumModes())),Ba,Bb),
50  StdNodalTriExp(Ba,Bb,Ntype),
51  Expansion (geom),
52  Expansion2D (geom),
53  m_matrixManager(
54  std::bind(&NodalTriExp::CreateMatrix, this, std::placeholders::_1),
55  std::string("NodalTriExpMatrix")),
56  m_staticCondMatrixManager(
57  std::bind(&NodalTriExp::CreateStaticCondMatrix, this, std::placeholders::_1),
58  std::string("NodalTriExpStaticCondMatrix"))
59  {
60  }
61 
63  StdExpansion(T),
64  StdExpansion2D(T),
65  StdRegions::StdNodalTriExp(T),
66  Expansion (T),
67  Expansion2D (T),
70  {
71  }
72 
74  {
75  }
76 
77  //----------------------------
78  // Integration Methods
79  //----------------------------
80 
81  /** \brief Integrate the physical point list \a inarray over region
82  and return the value
83 
84  Inputs:\n
85 
86  - \a inarray: definition of function to be returned at quadrature point
87  of expansion.
88 
89  Outputs:\n
90 
91  - returns \f$\int^1_{-1}\int^1_{-1} u(\xi_1, \xi_2) J[i,j] d
92  \xi_1 d \xi_2 \f$ where \f$inarray[i,j] = u(\xi_{1i},\xi_{2j})
93  \f$ and \f$ J[i,j] \f$ is the Jacobian evaluated at the
94  quadrature point.
95  */
96 
97 
99  {
100  int nquad0 = m_base[0]->GetNumPoints();
101  int nquad1 = m_base[1]->GetNumPoints();
103  NekDouble ival;
104  Array<OneD,NekDouble> tmp(nquad0*nquad1);
105 
106  // multiply inarray with Jacobian
107  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
108  {
109  Vmath::Vmul(nquad0*nquad1, jac, 1, inarray, 1,tmp, 1);
110  }
111  else
112  {
113  Vmath::Smul(nquad0*nquad1, jac[0], inarray, 1, tmp, 1);
114  }
115 
116  // call StdQuadExp version;
117  ival = StdNodalTriExp::v_Integral(tmp);
118  return ival;
119  }
120 
121 
123  Array<OneD, NekDouble> &outarray,
124  bool multiplybyweights)
125  {
126  int nquad0 = m_base[0]->GetNumPoints();
127  int nquad1 = m_base[1]->GetNumPoints();
128  int order1 = m_base[1]->GetNumModes();
129 
130  if(multiplybyweights)
131  {
132  Array<OneD,NekDouble> tmp(nquad0*nquad1+nquad0*order1);
133  Array<OneD,NekDouble> wsp(tmp+nquad0*nquad1);
134 
135  MultiplyByQuadratureMetric(inarray,tmp);
136  StdTriExp::IProductWRTBase_SumFacKernel(m_base[0]->GetBdata(),m_base[1]->GetBdata(),tmp,outarray,wsp);
137  NodalToModalTranspose(outarray,outarray);
138  }
139  else
140  {
141  Array<OneD,NekDouble> wsp(nquad0*order1);
142 
143  StdTriExp::IProductWRTBase_SumFacKernel(m_base[0]->GetBdata(),m_base[1]->GetBdata(),inarray,outarray,wsp);
144  NodalToModalTranspose(outarray,outarray);
145  }
146  }
147 
149  Array<OneD, NekDouble> &outarray)
150  {
151  int nq = GetTotPoints();
153  DNekScalMatSharedPtr iprodmat = m_matrixManager[iprodmatkey];
154 
155  Blas::Dgemv('N',m_ncoeffs,nq,iprodmat->Scale(),(iprodmat->GetOwnedMatrix())->GetPtr().get(),
156  m_ncoeffs, inarray.get(), 1, 0.0, outarray.get(), 1);
157  }
158 
160  const Array<OneD, const NekDouble>& inarray,
161  Array<OneD, NekDouble> & outarray)
162  {
163  ASSERTL1((dir==0)||(dir==1)||(dir==2),"Invalid direction.");
164  ASSERTL1((dir==2)?(m_geom->GetCoordim()==3):true,"Invalid direction.");
165 
166  int i;
167  int nquad0 = m_base[0]->GetNumPoints();
168  int nquad1 = m_base[1]->GetNumPoints();
169  int nqtot = nquad0*nquad1;
170  int wspsize = max(nqtot,m_ncoeffs);
171 
172  const Array<TwoD, const NekDouble>& df =
173  m_metricinfo->GetDerivFactors(GetPointsKeys());
174 
175  Array<OneD, NekDouble> tmp0 (6*wspsize);
176  Array<OneD, NekDouble> tmp1 (tmp0 + wspsize);
177  Array<OneD, NekDouble> tmp2 (tmp0 + 2*wspsize);
178  Array<OneD, NekDouble> tmp3 (tmp0 + 3*wspsize);
179  Array<OneD, NekDouble> gfac0(tmp0 + 4*wspsize);
180  Array<OneD, NekDouble> gfac1(tmp0 + 5*wspsize);
181 
182  const Array<OneD, const NekDouble>& z0 = m_base[0]->GetZ();
183  const Array<OneD, const NekDouble>& z1 = m_base[1]->GetZ();
184 
185  // set up geometric factor: 2/(1-z1)
186  for(i = 0; i < nquad1; ++i)
187  {
188  gfac0[i] = 2.0/(1-z1[i]);
189  }
190  for(i = 0; i < nquad0; ++i)
191  {
192  gfac1[i] = 0.5*(1+z0[i]);
193  }
194 
195  for(i = 0; i < nquad1; ++i)
196  {
197  Vmath::Smul(nquad0,gfac0[i],&inarray[0]+i*nquad0,1,&tmp0[0]+i*nquad0,1);
198  }
199 
200  for(i = 0; i < nquad1; ++i)
201  {
202  Vmath::Vmul(nquad0,&gfac1[0],1,&tmp0[0]+i*nquad0,1,&tmp1[0]+i*nquad0,1);
203  }
204 
205  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
206  {
207  Vmath::Vmul(nqtot,&df[2*dir][0], 1,&tmp0[0], 1,&tmp0[0],1);
208  Vmath::Vmul(nqtot,&df[2*dir+1][0],1,&tmp1[0], 1,&tmp1[0],1);
209  Vmath::Vmul(nqtot,&df[2*dir+1][0],1,&inarray[0],1,&tmp2[0],1);
210  }
211  else
212  {
213  Vmath::Smul(nqtot, df[2*dir][0], tmp0, 1, tmp0, 1);
214  Vmath::Smul(nqtot, df[2*dir+1][0], tmp1, 1, tmp1, 1);
215  Vmath::Smul(nqtot, df[2*dir+1][0], inarray, 1, tmp2, 1);
216  }
217  Vmath::Vadd(nqtot, tmp0, 1, tmp1, 1, tmp1, 1);
218 
219  MultiplyByQuadratureMetric(tmp1,tmp1);
220  MultiplyByQuadratureMetric(tmp2,tmp2);
221 
222  IProductWRTBase_SumFacKernel(m_base[0]->GetDbdata(),m_base[1]->GetBdata() ,tmp1,tmp3 ,tmp0);
223  IProductWRTBase_SumFacKernel(m_base[0]->GetBdata() ,m_base[1]->GetDbdata(),tmp2,outarray,tmp0);
224  Vmath::Vadd(m_ncoeffs, tmp3, 1, outarray, 1, outarray, 1);
225 
226  NodalToModalTranspose(outarray,outarray);
227  }
228 
230  const Array<OneD, const NekDouble>& inarray,
231  Array<OneD, NekDouble> &outarray)
232  {
233  int nq = GetTotPoints();
235 
236  switch(dir)
237  {
238  case 0:
239  {
241  }
242  break;
243  case 1:
244  {
246  }
247  break;
248  case 2:
249  {
251  }
252  break;
253  default:
254  {
255  ASSERTL1(false,"input dir is out of range");
256  }
257  break;
258  }
259 
260  MatrixKey iprodmatkey(mtype,DetShapeType(),*this);
261  DNekScalMatSharedPtr iprodmat = m_matrixManager[iprodmatkey];
262 
263  Blas::Dgemv('N',m_ncoeffs,nq,iprodmat->Scale(),(iprodmat->GetOwnedMatrix())->GetPtr().get(),
264  m_ncoeffs, inarray.get(), 1, 0.0, outarray.get(), 1);
265 
266  }
267 
268  ///////////////////////////////
269  /// Differentiation Methods
270  ///////////////////////////////
271 
272  /**
273  \brief Calculate the deritive of the physical points
274  **/
276  Array<OneD,NekDouble> &out_d0,
277  Array<OneD,NekDouble> &out_d1,
278  Array<OneD,NekDouble> &out_d2)
279  {
280  int nquad0 = m_base[0]->GetNumPoints();
281  int nquad1 = m_base[1]->GetNumPoints();
282  int nqtot = nquad0*nquad1;
284  = m_metricinfo->GetDerivFactors(GetPointsKeys());
285 
286  Array<OneD,NekDouble> diff0(2*nqtot);
287  Array<OneD,NekDouble> diff1(diff0+nqtot);
288 
289  StdNodalTriExp::v_PhysDeriv(inarray, diff0, diff1);
290 
291  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
292  {
293  if(out_d0.num_elements())
294  {
295  Vmath::Vmul (nqtot,df[0],1,diff0,1, out_d0, 1);
296  Vmath::Vvtvp (nqtot,df[1],1,diff1,1, out_d0, 1, out_d0,1);
297  }
298 
299  if(out_d1.num_elements())
300  {
301  Vmath::Vmul (nqtot,df[2],1,diff0,1, out_d1, 1);
302  Vmath::Vvtvp (nqtot,df[3],1,diff1,1, out_d1, 1, out_d1,1);
303  }
304 
305  if(out_d2.num_elements())
306  {
307  Vmath::Vmul (nqtot,df[4],1,diff0,1, out_d2, 1);
308  Vmath::Vvtvp (nqtot,df[5],1,diff1,1, out_d2, 1, out_d2,1);
309  }
310  }
311  else // regular geometry
312  {
313  if(out_d0.num_elements())
314  {
315  Vmath::Smul (nqtot, df[0][0], diff0, 1, out_d0, 1);
316  Blas::Daxpy (nqtot, df[1][0], diff1, 1, out_d0, 1);
317  }
318 
319  if(out_d1.num_elements())
320  {
321  Vmath::Smul (nqtot, df[2][0], diff0, 1, out_d1, 1);
322  Blas::Daxpy (nqtot, df[3][0], diff1, 1, out_d1, 1);
323  }
324 
325  if(out_d2.num_elements())
326  {
327  Vmath::Smul (nqtot, df[4][0], diff0, 1, out_d2, 1);
328  Blas::Daxpy (nqtot, df[5][0], diff1, 1, out_d2, 1);
329  }
330  }
331  }
332 
333  /** \brief Forward transform from physical quadrature space
334  stored in \a inarray and evaluate the expansion coefficients and
335  store in \a (this)->m_coeffs
336 
337  Inputs:\n
338 
339  - \a inarray: array of physical quadrature points to be transformed
340 
341  Outputs:\n
342 
343  - (this)->_coeffs: updated array of expansion coefficients.
344 
345  */
347  Array<OneD,NekDouble> &outarray)
348  {
349  IProductWRTBase(inarray,outarray);
350 
351  // get Mass matrix inverse
353  DNekScalMatSharedPtr matsys = m_matrixManager[masskey];
354 
355  // copy inarray in case inarray == outarray
356  NekVector<NekDouble> in(m_ncoeffs,outarray,eCopy);
358 
359  out = (*matsys)*in;
360  }
361 
363  Array<OneD,NekDouble> &outarray,
364  const StdRegions::StdMatrixKey &mkey)
365  {
367 
368  if(inarray.get() == outarray.get())
369  {
371  Vmath::Vcopy(m_ncoeffs,inarray.get(),1,tmp.get(),1);
372 
373  Blas::Dgemv('N',m_ncoeffs,m_ncoeffs,mat->Scale(),(mat->GetOwnedMatrix())->GetPtr().get(),
374  m_ncoeffs, tmp.get(), 1, 0.0, outarray.get(), 1);
375  }
376  else
377  {
378  Blas::Dgemv('N',m_ncoeffs,m_ncoeffs,mat->Scale(),(mat->GetOwnedMatrix())->GetPtr().get(),
379  m_ncoeffs, inarray.get(), 1, 0.0, outarray.get(), 1);
380  }
381  }
382 
384  Array<OneD,NekDouble> &coords_1,
385  Array<OneD,NekDouble> &coords_2)
386  {
387  Expansion::v_GetCoords(coords_0, coords_1, coords_2);
388  }
389 
390  // get the coordinates "coords" at the local coordinates "Lcoords"
392  Array<OneD,NekDouble> &coords)
393  {
394  int i;
395 
396  ASSERTL1(Lcoords[0] >= -1.0 && Lcoords[1] <= 1.0 &&
397  Lcoords[1] >= -1.0 && Lcoords[1] <=1.0,
398  "Local coordinates are not in region [-1,1]");
399 
400  m_geom->FillGeom();
401 
402  for(i = 0; i < m_geom->GetCoordim(); ++i)
403  {
404  coords[i] = m_geom->GetCoord(i,Lcoords);
405  }
406  }
407 
409  {
410  LibUtilities::BasisKey bkey0 = m_base[0]->GetBasisKey();
411  LibUtilities::BasisKey bkey1 = m_base[1]->GetBasisKey();
414  AllocateSharedPtr(bkey0,bkey1,ntype);
415 
416  return tmp->GetStdMatrix(mkey);
417  }
418 
420  const Array<OneD, const NekDouble> &coord,
421  const Array<OneD, const NekDouble> &physvals)
422 
423  {
425 
426  ASSERTL0(m_geom,"m_geom not defined");
427  m_geom->GetLocCoords(coord,Lcoord);
428 
429  return StdNodalTriExp::v_PhysEvaluate(Lcoord, physvals);
430  }
431 
433  {
434  DNekScalMatSharedPtr returnval;
436 
437  ASSERTL2(m_metricinfo->GetGtype() != SpatialDomains::eNoGeomType,"Geometric information is not set up");
438 
439  StdRegions::MatrixType mtype = mkey.GetMatrixType();
440 
441  switch(mtype)
442  {
443  case StdRegions::eMass:
444  {
445  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
446  {
447  NekDouble one = 1.0;
448  DNekMatSharedPtr mat = GenMatrix(mkey);
450  }
451  else
452  {
453  NekDouble jac = (m_metricinfo->GetJac(ptsKeys))[0];
454  DNekMatSharedPtr mat = GetStdMatrix(mkey);
456  }
457  }
458  break;
460  {
461  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
462  {
463  NekDouble one = 1.0;
465  *this);
466  DNekMatSharedPtr mat = GenMatrix(masskey);
467  mat->Invert();
468 
470  }
471  else
472  {
473  NekDouble fac = 1.0/(m_metricinfo->GetJac(ptsKeys))[0];
474  DNekMatSharedPtr mat = GetStdMatrix(mkey);
476  }
477  }
478  break;
480  {
481  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
482  {
483  NekDouble one = 1.0;
484  DNekMatSharedPtr mat = GenMatrix(mkey);
485 
487  }
488  else
489  {
490  ASSERTL1(m_geom->GetCoordim() == 2,"Standard Region Laplacian is only set up for Quads in two-dimensional");
492  mkey.GetShapeType(), *this);
494  mkey.GetShapeType(), *this);
496  mkey.GetShapeType(), *this);
497 
498  DNekMat &lap00 = *GetStdMatrix(lap00key);
499  DNekMat &lap01 = *GetStdMatrix(lap01key);
500  DNekMat &lap11 = *GetStdMatrix(lap11key);
501 
502  NekDouble jac = (m_metricinfo->GetJac(ptsKeys))[0];
504  m_metricinfo->GetGmat(ptsKeys);
505 
506  int rows = lap00.GetRows();
507  int cols = lap00.GetColumns();
508 
510 
511  (*lap) = gmat[0][0] * lap00 +
512  gmat[1][0] * (lap01 + Transpose(lap01)) +
513  gmat[3][0] * lap11;
514 
516  }
517  }
518  break;
520  {
523  mkey.GetShapeType(), *this);
524  DNekScalMat &MassMat = *(this->m_matrixManager[masskey]);
526  mkey.GetShapeType(), *this);
527  DNekScalMat &LapMat = *(this->m_matrixManager[lapkey]);
528 
529  int rows = LapMat.GetRows();
530  int cols = LapMat.GetColumns();
531 
533 
534  NekDouble one = 1.0;
535  (*helm) = LapMat + factor*MassMat;
536 
537  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,helm);
538  }
539  break;
540  default:
541  NEKERROR(ErrorUtil::efatal, "Matrix creation not defined");
542  break;
543  }
544 
545  return returnval;
546  }
547 
549  {
550  DNekScalBlkMatSharedPtr returnval;
551 
552  ASSERTL2(m_metricinfo->GetGtype() != SpatialDomains::eNoGeomType,"Geometric information is not set up");
553 
554  // set up block matrix system
555  unsigned int nbdry = NumBndryCoeffs();
556  unsigned int nint = (unsigned int)(m_ncoeffs - nbdry);
557  unsigned int exp_size[] = {nbdry,nint};
558  unsigned int nblks = 2;
559  returnval = MemoryManager<DNekScalBlkMat>::AllocateSharedPtr(nblks,nblks,exp_size,exp_size); //Really need a constructor which takes Arrays
560  NekDouble factor = 1.0;
561 
562  switch(mkey.GetMatrixType())
563  {
565  case StdRegions::eHelmholtz: // special case since Helmholtz not defined in StdRegions
566 
567  // use Deformed case for both regular and deformed geometries
568  factor = 1.0;
569  goto UseLocRegionsMatrix;
570  break;
571  default:
572  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
573  {
574  factor = 1.0;
575  goto UseLocRegionsMatrix;
576  }
577  else
578  {
580  factor = mat->Scale();
581  goto UseStdRegionsMatrix;
582  }
583  break;
584  UseStdRegionsMatrix:
585  {
586  NekDouble invfactor = 1.0/factor;
587  NekDouble one = 1.0;
590  DNekMatSharedPtr Asubmat;
591 
592  returnval->SetBlock(0,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,Asubmat = mat->GetBlock(0,0)));
593  returnval->SetBlock(0,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,Asubmat = mat->GetBlock(0,1)));
594  returnval->SetBlock(1,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,Asubmat = mat->GetBlock(1,0)));
595  returnval->SetBlock(1,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(invfactor,Asubmat = mat->GetBlock(1,1)));
596  }
597  break;
598  UseLocRegionsMatrix:
599  {
600  int i,j;
601  NekDouble invfactor = 1.0/factor;
602  NekDouble one = 1.0;
603  DNekScalMat &mat = *GetLocMatrix(mkey);
608 
609  Array<OneD,unsigned int> bmap(nbdry);
610  Array<OneD,unsigned int> imap(nint);
611  GetBoundaryMap(bmap);
612  GetInteriorMap(imap);
613 
614  for(i = 0; i < nbdry; ++i)
615  {
616  for(j = 0; j < nbdry; ++j)
617  {
618  (*A)(i,j) = mat(bmap[i],bmap[j]);
619  }
620 
621  for(j = 0; j < nint; ++j)
622  {
623  (*B)(i,j) = mat(bmap[i],imap[j]);
624  }
625  }
626 
627  for(i = 0; i < nint; ++i)
628  {
629  for(j = 0; j < nbdry; ++j)
630  {
631  (*C)(i,j) = mat(imap[i],bmap[j]);
632  }
633 
634  for(j = 0; j < nint; ++j)
635  {
636  (*D)(i,j) = mat(imap[i],imap[j]);
637  }
638  }
639 
640  // Calculate static condensed system
641  if(nint)
642  {
643  D->Invert();
644  (*B) = (*B)*(*D);
645  (*A) = (*A) - (*B)*(*C);
646  }
647 
649 
650  returnval->SetBlock(0,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,A));
651  returnval->SetBlock(0,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,B));
652  returnval->SetBlock(1,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,C));
653  returnval->SetBlock(1,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(invfactor,D));
654 
655  }
656  }
657 
658  return returnval;
659  }
660 
661 
663  {
664 
666  ::AllocateSharedPtr(m_base[0]->GetBasisKey(),
667  m_base[1]->GetBasisKey(),
669  }
670 
672  {
674  2, m_base[0]->GetPointsKey());
676  2, m_base[1]->GetPointsKey());
677 
680  }
681 
683  {
684  DNekMatSharedPtr returnval;
685 
686  switch(mkey.GetMatrixType())
687  {
694  returnval = Expansion2D::v_GenMatrix(mkey);
695  break;
696  default:
697  returnval = StdNodalTriExp::v_GenMatrix(mkey);
698  break;
699  }
700  return returnval;
701  }
702 
703  void NodalTriExp::v_ComputeEdgeNormal(const int edge)
704  {
705  int i;
706  const SpatialDomains::GeomFactorsSharedPtr & geomFactors = GetGeom()->GetMetricInfo();
707  const SpatialDomains::GeomType type = geomFactors->GetGtype();
708 
710  const Array<TwoD, const NekDouble> & df = geomFactors->GetDerivFactors(ptsKeys);
711  const Array<OneD, const NekDouble> & jac = geomFactors->GetJac(ptsKeys);
712  int nqe = m_base[0]->GetNumPoints();
713  int dim = GetCoordim();
714 
717  for (i = 0; i < dim; ++i)
718  {
719  normal[i] = Array<OneD, NekDouble>(nqe);
720  }
721 
722  // Regular geometry case
724  {
725  NekDouble fac;
726  // Set up normals
727  switch(edge)
728  {
729  case 0:
730  for(i = 0; i < GetCoordim(); ++i)
731  {
732  Vmath::Fill(nqe,-df[2*i+1][0],normal[i],1);
733  }
734  break;
735  case 1:
736  for(i = 0; i < GetCoordim(); ++i)
737  {
738  Vmath::Fill(nqe,df[2*i+1][0] + df[2*i][0],normal[i],1);
739  }
740  break;
741  case 2:
742  for(i = 0; i < GetCoordim(); ++i)
743  {
744  Vmath::Fill(nqe,-df[2*i][0],normal[i],1);
745  }
746  break;
747  default:
748  ASSERTL0(false,"Edge is out of range (edge < 3)");
749  }
750 
751  // normalise
752  fac = 0.0;
753  for(i =0 ; i < GetCoordim(); ++i)
754  {
755  fac += normal[i][0]*normal[i][0];
756  }
757  fac = 1.0/sqrt(fac);
758  for (i = 0; i < GetCoordim(); ++i)
759  {
760  Vmath::Smul(nqe,fac,normal[i],1,normal[i],1);
761  }
762  }
763  else // Set up deformed normals
764  {
765  int j;
766 
767  int nquad0 = ptsKeys[0].GetNumPoints();
768  int nquad1 = ptsKeys[1].GetNumPoints();
769 
770  LibUtilities::PointsKey from_key;
771 
772  Array<OneD,NekDouble> normals(GetCoordim()*max(nquad0,nquad1),0.0);
773  Array<OneD,NekDouble> edgejac(GetCoordim()*max(nquad0,nquad1),0.0);
774 
775  // Extract Jacobian along edges and recover local
776  // derivates (dx/dr) for polynomial interpolation by
777  // multiplying m_gmat by jacobian
778  switch(edge)
779  {
780  case 0:
781  for(j = 0; j < nquad0; ++j)
782  {
783  edgejac[j] = jac[j];
784  for(i = 0; i < GetCoordim(); ++i)
785  {
786  normals[i*nquad0+j] = -df[2*i+1][j]*edgejac[j];
787  }
788  }
789  from_key = ptsKeys[0];
790  break;
791  case 1:
792  for(j = 0; j < nquad1; ++j)
793  {
794  edgejac[j] = jac[nquad0*j+nquad0-1];
795  for(i = 0; i < GetCoordim(); ++i)
796  {
797  normals[i*nquad1+j] = (df[2*i][nquad0*j + nquad0-1] + df[2*i+1][nquad0*j + nquad0-1])*edgejac[j];
798  }
799  }
800  from_key = ptsKeys[1];
801  break;
802  case 2:
803  for(j = 0; j < nquad1; ++j)
804  {
805  edgejac[j] = jac[nquad0*j];
806  for(i = 0; i < GetCoordim(); ++i)
807  {
808  normals[i*nquad1+j] = -df[2*i][nquad0*j]*edgejac[j];
809  }
810  }
811  from_key = ptsKeys[1];
812  break;
813  default:
814  ASSERTL0(false,"edge is out of range (edge < 3)");
815 
816  }
817 
818  int nq = from_key.GetNumPoints();
819  Array<OneD,NekDouble> work(nqe,0.0);
820 
821  // interpolate Jacobian and invert
822  LibUtilities::Interp1D(from_key,jac,m_base[0]->GetPointsKey(),work);
823  Vmath::Sdiv(nq,1.0,&work[0],1,&work[0],1);
824 
825  // interpolate
826  for(i = 0; i < GetCoordim(); ++i)
827  {
828  LibUtilities::Interp1D(from_key,&normals[i*nq],m_base[0]->GetPointsKey(),&normal[i][0]);
829  Vmath::Vmul(nqe,work,1,normal[i],1,normal[i],1);
830  }
831 
832  //normalise normal vectors
833  Vmath::Zero(nqe,work,1);
834  for(i = 0; i < GetCoordim(); ++i)
835  {
836  Vmath::Vvtvp(nqe,normal[i],1, normal[i],1,work,1,work,1);
837  }
838 
839  Vmath::Vsqrt(nqe,work,1,work,1);
840  Vmath::Sdiv(nqe,1.0,work,1,work,1);
841 
842  for(i = 0; i < GetCoordim(); ++i)
843  {
844  Vmath::Vmul(nqe,normal[i],1,work,1,normal[i],1);
845  }
846 
847  // Reverse direction so that points are in
848  // anticlockwise direction if edge >=2
849  if(edge >= 2)
850  {
851  for(i = 0; i < GetCoordim(); ++i)
852  {
853  Vmath::Reverse(nqe,normal[i],1, normal[i],1);
854  }
855  }
856  }
857  }
858 
859  }//end of namespace
860 }//end of namespace
virtual StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const
DNekMatSharedPtr GenMatrix(const StdMatrixKey &mkey)
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
std::shared_ptr< StdNodalTriExp > StdNodalTriExpSharedPtr
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:209
PointsType GetPointsType() const
Definition: Points.h:112
std::vector< PointsKey > PointsKeyVector
Definition: Points.h:246
NodalTriExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::PointsType Ntype, const SpatialDomains::TriGeomSharedPtr &geom)
Constructor using BasisKey class for quadrature points and order definition.
Definition: NodalTriExp.cpp:44
void v_ComputeEdgeNormal(const int edge)
LibUtilities::ShapeType DetShapeType() const
This function returns the shape of the expansion domain.
Definition: StdExpansion.h:469
void Vsqrt(int n, const T *x, const int incx, T *y, const int incy)
sqrt y = sqrt(x)
Definition: Vmath.cpp:411
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
void MultiplyByQuadratureMetric(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: StdExpansion.h:945
void GetCoord(const Array< OneD, const NekDouble > &Lcoords, Array< OneD, NekDouble > &coords)
SpatialDomains::GeometrySharedPtr GetGeom() const
Definition: Expansion.cpp:167
void IProductWRTBase_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool multiplybyweights=true)
void IProductWRTDerivBase_SumFac(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
std::shared_ptr< GeomFactors > GeomFactorsSharedPtr
Pointer to a GeomFactors object.
Definition: GeomFactors.h:62
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
Definition: NekTypeDefs.hpp:73
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:45
void IProductWRTBase_MatOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
void PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1, Array< OneD, NekDouble > &out_d2=NullNekDouble1DArray)
Differentiation Methods.
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:445
std::map< int, StdRegions::NormalVector > m_edgeNormals
Definition: Expansion2D.h:134
SpatialDomains::GeomFactorsSharedPtr m_metricinfo
Definition: Expansion.h:128
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:274
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:69
SpatialDomains::GeometrySharedPtr m_geom
Definition: Expansion.h:127
MatrixType GetMatrixType() const
Definition: StdMatrixKey.h:81
void GeneralMatrixOp_MatOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey)
std::shared_ptr< DNekBlkMat > DNekBlkMatSharedPtr
Definition: NekTypeDefs.hpp:71
NekDouble PhysEvaluate(const Array< OneD, const NekDouble > &coord, const Array< OneD, const NekDouble > &physvals)
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:714
void NodalToModalTranspose(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
LibUtilities::NekManager< MatrixKey, DNekScalMat, MatrixKey::opLess > m_matrixManager
Definition: NodalTriExp.h:188
const LibUtilities::PointsKeyVector GetPointsKeys() const
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
DNekBlkMatSharedPtr GetStdStaticCondMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:719
std::shared_ptr< TriGeom > TriGeomSharedPtr
Definition: TriGeom.h:58
LibUtilities::PointsKey m_nodalPointsKey
virtual StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const
void Reverse(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1088
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:216
void IProductWRTDerivBase_MatOp(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3)
Definition: Expansion.cpp:231
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
void GetInteriorMap(Array< OneD, unsigned int > &outarray)
Definition: StdExpansion.h:817
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
Defines a specification for a set of points.
Definition: Points.h:59
void FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Forward transform from physical quadrature space stored in inarray and evaluate the expansion coeffic...
double NekDouble
static void Dgemv(const char &trans, const int &m, const int &n, const double &alpha, const double *a, const int &lda, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = A x where A[m x n].
Definition: Blas.hpp:168
virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey)
virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey)
NekDouble GetConstFactor(const ConstFactorType &factor) const
Definition: StdMatrixKey.h:121
NekDouble Integral(const Array< OneD, const NekDouble > &inarray)
Integrate the physical point list inarray over region.
Definition: NodalTriExp.cpp:98
LibUtilities::NekManager< MatrixKey, DNekScalBlkMat, MatrixKey::opLess > m_staticCondMatrixManager
Definition: NodalTriExp.h:189
DNekScalMatSharedPtr GetLocMatrix(const LocalRegions::MatrixKey &mkey)
Definition: Expansion.cpp:85
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed t...
Definition: ErrorUtil.hpp:274
Geometry is straight-sided with constant geometric factors.
LibUtilities::BasisType GetBasisType(const int dir) const
This function returns the type of basis used in the dir direction.
Definition: StdExpansion.h:164
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:53
DNekScalBlkMatSharedPtr CreateStaticCondMatrix(const MatrixKey &mkey)
StdExpansion()
Default Constructor.
int GetTotPoints() const
This function returns the total number of quadrature points used in the element.
Definition: StdExpansion.h:140
void GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3=NullNekDouble1DArray)
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.
unsigned int GetNumPoints() const
Definition: Points.h:107
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:376
DNekScalMatSharedPtr CreateMatrix(const MatrixKey &mkey)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250
Array< OneD, LibUtilities::BasisSharedPtr > m_base
static void Daxpy(const int &n, const double &alpha, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: y = alpha x plus y.
Definition: Blas.hpp:110
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1064
Geometry is curved or has non-constant factors.
void IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Inner product of inarray over region with respect to the expansion basis (this)->_Base[0] and return ...
Definition: NodalTriExp.h:84
LibUtilities::ShapeType GetShapeType() const
Definition: StdMatrixKey.h:86
void GetBoundaryMap(Array< OneD, unsigned int > &outarray)
Definition: StdExpansion.h:812
Describes the specification for a Basis.
Definition: Basis.h:49
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:302
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:186
DNekMatSharedPtr CreateStdMatrix(const StdRegions::StdMatrixKey &mkey)
static VarCoeffMap NullVarCoeffMap
Definition: StdRegions.hpp:265
static ConstFactorMap NullConstFactorMap
Definition: StdRegions.hpp:295