Nektar++
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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),
68  m_matrixManager(T.m_matrixManager),
69  m_staticCondMatrixManager(T.m_staticCondMatrixManager)
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  int nquad0 = m_base[0]->GetNumPoints();
164  int nquad1 = m_base[1]->GetNumPoints();
165  int nqtot = nquad0*nquad1;
166  int wspsize = max(nqtot,m_ncoeffs);
167 
168  Array<OneD, NekDouble> tmp0 (4*wspsize);
169  Array<OneD, NekDouble> tmp1 (tmp0 + wspsize);
170  Array<OneD, NekDouble> tmp2 (tmp0 + 2*wspsize);
171  Array<OneD, NekDouble> tmp3 (tmp0 + 3*wspsize);
172 
174  tmp2D[0] = tmp1;
175  tmp2D[1] = tmp2;
176 
177  AlignVectorToCollapsedDir(dir, inarray, tmp2D);
178 
179  MultiplyByQuadratureMetric(tmp1,tmp1);
180  MultiplyByQuadratureMetric(tmp2,tmp2);
181 
182  IProductWRTBase_SumFacKernel(m_base[0]->GetDbdata(),m_base[1]->GetBdata() ,tmp1,tmp3 ,tmp0);
183  IProductWRTBase_SumFacKernel(m_base[0]->GetBdata() ,m_base[1]->GetDbdata(),tmp2,outarray,tmp0);
184  Vmath::Vadd(m_ncoeffs, tmp3, 1, outarray, 1, outarray, 1);
185 
186  NodalToModalTranspose(outarray,outarray);
187  }
188 
190  const int dir,
191  const Array<OneD, const NekDouble> &inarray,
192  Array<OneD, Array<OneD, NekDouble> > &outarray)
193  {
194  ASSERTL1((dir==0)||(dir==1)||(dir==2),"Invalid direction.");
195  ASSERTL1((dir==2)?(m_geom->GetCoordim()==3):true,
196  "Invalid direction.");
197 
198  int nquad0 = m_base[0]->GetNumPoints();
199  int nquad1 = m_base[1]->GetNumPoints();
200  int nqtot = nquad0*nquad1;
201  int wspsize = max(nqtot,m_ncoeffs);
202 
203  const Array<TwoD, const NekDouble>& df =
204  m_metricinfo->GetDerivFactors(GetPointsKeys());
205 
206  Array<OneD, NekDouble> tmp0 (4*wspsize);
207  Array<OneD, NekDouble> tmp3 (tmp0 + wspsize);
208  Array<OneD, NekDouble> gfac0(tmp0 + 2*wspsize);
209  Array<OneD, NekDouble> gfac1(tmp0 + 3*wspsize);
210 
211  Array<OneD, NekDouble> tmp1 = outarray[0];
212  Array<OneD, NekDouble> tmp2 = outarray[1];
213 
214  const Array<OneD, const NekDouble>& z0 = m_base[0]->GetZ();
215  const Array<OneD, const NekDouble>& z1 = m_base[1]->GetZ();
216 
217  // set up geometric factor: 2/(1-z1)
218  for (int i = 0; i < nquad1; ++i)
219  {
220  gfac0[i] = 2.0/(1-z1[i]);
221  }
222  for (int i = 0; i < nquad0; ++i)
223  {
224  gfac1[i] = 0.5*(1+z0[i]);
225  }
226 
227  for (int i = 0; i < nquad1; ++i)
228  {
229  Vmath::Smul(nquad0, gfac0[i], &inarray[0]+i*nquad0, 1,
230  &tmp0[0]+i*nquad0, 1);
231  }
232 
233  for (int i = 0; i < nquad1; ++i)
234  {
235  Vmath::Vmul(nquad0, &gfac1[0], 1, &tmp0[0]+i*nquad0, 1,
236  &tmp1[0]+i*nquad0, 1);
237  }
238 
239  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
240  {
241  Vmath::Vmul(nqtot,&df[2*dir][0], 1,&tmp0[0], 1,&tmp0[0],1);
242  Vmath::Vmul(nqtot,&df[2*dir+1][0],1,&tmp1[0], 1,&tmp1[0],1);
243  Vmath::Vmul(nqtot,&df[2*dir+1][0],1,&inarray[0],1,&tmp2[0],1);
244  }
245  else
246  {
247  Vmath::Smul(nqtot, df[2*dir][0], tmp0, 1, tmp0, 1);
248  Vmath::Smul(nqtot, df[2*dir+1][0], tmp1, 1, tmp1, 1);
249  Vmath::Smul(nqtot, df[2*dir+1][0], inarray, 1, tmp2, 1);
250  }
251  Vmath::Vadd(nqtot, tmp0, 1, tmp1, 1, tmp1, 1);
252  }
253 
255  const Array<OneD, const NekDouble>& inarray,
256  Array<OneD, NekDouble> &outarray)
257  {
258  int nq = GetTotPoints();
260 
261  switch(dir)
262  {
263  case 0:
264  {
266  }
267  break;
268  case 1:
269  {
271  }
272  break;
273  case 2:
274  {
276  }
277  break;
278  default:
279  {
280  ASSERTL1(false,"input dir is out of range");
281  }
282  break;
283  }
284 
285  MatrixKey iprodmatkey(mtype,DetShapeType(),*this);
286  DNekScalMatSharedPtr iprodmat = m_matrixManager[iprodmatkey];
287 
288  Blas::Dgemv('N',m_ncoeffs,nq,iprodmat->Scale(),(iprodmat->GetOwnedMatrix())->GetPtr().get(),
289  m_ncoeffs, inarray.get(), 1, 0.0, outarray.get(), 1);
290 
291  }
292 
293  ///////////////////////////////
294  /// Differentiation Methods
295  ///////////////////////////////
296 
297  /**
298  \brief Calculate the deritive of the physical points
299  **/
301  Array<OneD,NekDouble> &out_d0,
302  Array<OneD,NekDouble> &out_d1,
303  Array<OneD,NekDouble> &out_d2)
304  {
305  int nquad0 = m_base[0]->GetNumPoints();
306  int nquad1 = m_base[1]->GetNumPoints();
307  int nqtot = nquad0*nquad1;
309  = m_metricinfo->GetDerivFactors(GetPointsKeys());
310 
311  Array<OneD,NekDouble> diff0(2*nqtot);
312  Array<OneD,NekDouble> diff1(diff0+nqtot);
313 
314  StdNodalTriExp::v_PhysDeriv(inarray, diff0, diff1);
315 
316  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
317  {
318  if(out_d0.size())
319  {
320  Vmath::Vmul (nqtot,df[0],1,diff0,1, out_d0, 1);
321  Vmath::Vvtvp (nqtot,df[1],1,diff1,1, out_d0, 1, out_d0,1);
322  }
323 
324  if(out_d1.size())
325  {
326  Vmath::Vmul (nqtot,df[2],1,diff0,1, out_d1, 1);
327  Vmath::Vvtvp (nqtot,df[3],1,diff1,1, out_d1, 1, out_d1,1);
328  }
329 
330  if(out_d2.size())
331  {
332  Vmath::Vmul (nqtot,df[4],1,diff0,1, out_d2, 1);
333  Vmath::Vvtvp (nqtot,df[5],1,diff1,1, out_d2, 1, out_d2,1);
334  }
335  }
336  else // regular geometry
337  {
338  if(out_d0.size())
339  {
340  Vmath::Smul (nqtot, df[0][0], diff0, 1, out_d0, 1);
341  Blas::Daxpy (nqtot, df[1][0], diff1, 1, out_d0, 1);
342  }
343 
344  if(out_d1.size())
345  {
346  Vmath::Smul (nqtot, df[2][0], diff0, 1, out_d1, 1);
347  Blas::Daxpy (nqtot, df[3][0], diff1, 1, out_d1, 1);
348  }
349 
350  if(out_d2.size())
351  {
352  Vmath::Smul (nqtot, df[4][0], diff0, 1, out_d2, 1);
353  Blas::Daxpy (nqtot, df[5][0], diff1, 1, out_d2, 1);
354  }
355  }
356  }
357 
358  /** \brief Forward transform from physical quadrature space
359  stored in \a inarray and evaluate the expansion coefficients and
360  store in \a (this)->m_coeffs
361 
362  Inputs:\n
363 
364  - \a inarray: array of physical quadrature points to be transformed
365 
366  Outputs:\n
367 
368  - (this)->_coeffs: updated array of expansion coefficients.
369 
370  */
372  Array<OneD,NekDouble> &outarray)
373  {
374  IProductWRTBase(inarray,outarray);
375 
376  // get Mass matrix inverse
378  DNekScalMatSharedPtr matsys = m_matrixManager[masskey];
379 
380  // copy inarray in case inarray == outarray
381  NekVector<NekDouble> in(m_ncoeffs,outarray,eCopy);
383 
384  out = (*matsys)*in;
385  }
386 
388  Array<OneD,NekDouble> &outarray,
389  const StdRegions::StdMatrixKey &mkey)
390  {
392 
393  if(inarray.get() == outarray.get())
394  {
396  Vmath::Vcopy(m_ncoeffs,inarray.get(),1,tmp.get(),1);
397 
398  Blas::Dgemv('N',m_ncoeffs,m_ncoeffs,mat->Scale(),(mat->GetOwnedMatrix())->GetPtr().get(),
399  m_ncoeffs, tmp.get(), 1, 0.0, outarray.get(), 1);
400  }
401  else
402  {
403  Blas::Dgemv('N',m_ncoeffs,m_ncoeffs,mat->Scale(),(mat->GetOwnedMatrix())->GetPtr().get(),
404  m_ncoeffs, inarray.get(), 1, 0.0, outarray.get(), 1);
405  }
406  }
407 
409  Array<OneD,NekDouble> &coords_1,
410  Array<OneD,NekDouble> &coords_2)
411  {
412  Expansion::v_GetCoords(coords_0, coords_1, coords_2);
413  }
414 
415  // get the coordinates "coords" at the local coordinates "Lcoords"
417  Array<OneD,NekDouble> &coords)
418  {
419  int i;
420 
421  ASSERTL1(Lcoords[0] >= -1.0 && Lcoords[1] <= 1.0 &&
422  Lcoords[1] >= -1.0 && Lcoords[1] <=1.0,
423  "Local coordinates are not in region [-1,1]");
424 
425  m_geom->FillGeom();
426 
427  for(i = 0; i < m_geom->GetCoordim(); ++i)
428  {
429  coords[i] = m_geom->GetCoord(i,Lcoords);
430  }
431  }
432 
434  {
435  LibUtilities::BasisKey bkey0 = m_base[0]->GetBasisKey();
436  LibUtilities::BasisKey bkey1 = m_base[1]->GetBasisKey();
439  AllocateSharedPtr(bkey0,bkey1,ntype);
440 
441  return tmp->GetStdMatrix(mkey);
442  }
443 
445  const Array<OneD, const NekDouble> &coord,
446  const Array<OneD, const NekDouble> &physvals)
447 
448  {
450 
451  ASSERTL0(m_geom,"m_geom not defined");
452  m_geom->GetLocCoords(coord,Lcoord);
453 
454  return StdNodalTriExp::v_PhysEvaluate(Lcoord, physvals);
455  }
456 
458  {
459  DNekScalMatSharedPtr returnval;
461 
462  ASSERTL2(m_metricinfo->GetGtype() != SpatialDomains::eNoGeomType,"Geometric information is not set up");
463 
464  StdRegions::MatrixType mtype = mkey.GetMatrixType();
465 
466  switch(mtype)
467  {
468  case StdRegions::eMass:
469  {
470  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
471  {
472  NekDouble one = 1.0;
473  DNekMatSharedPtr mat = GenMatrix(mkey);
475  }
476  else
477  {
478  NekDouble jac = (m_metricinfo->GetJac(ptsKeys))[0];
479  DNekMatSharedPtr mat = GetStdMatrix(mkey);
481  }
482  }
483  break;
485  {
486  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
487  {
488  NekDouble one = 1.0;
490  *this);
491  DNekMatSharedPtr mat = GenMatrix(masskey);
492  mat->Invert();
493 
495  }
496  else
497  {
498  NekDouble fac = 1.0/(m_metricinfo->GetJac(ptsKeys))[0];
499  DNekMatSharedPtr mat = GetStdMatrix(mkey);
501  }
502  }
503  break;
505  {
506  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
507  {
508  NekDouble one = 1.0;
509  DNekMatSharedPtr mat = GenMatrix(mkey);
510 
512  }
513  else
514  {
515  ASSERTL1(m_geom->GetCoordim() == 2,"Standard Region Laplacian is only set up for Quads in two-dimensional");
517  mkey.GetShapeType(), *this);
519  mkey.GetShapeType(), *this);
521  mkey.GetShapeType(), *this);
522 
523  DNekMat &lap00 = *GetStdMatrix(lap00key);
524  DNekMat &lap01 = *GetStdMatrix(lap01key);
525  DNekMat &lap11 = *GetStdMatrix(lap11key);
526 
527  NekDouble jac = (m_metricinfo->GetJac(ptsKeys))[0];
529  m_metricinfo->GetGmat(ptsKeys);
530 
531  int rows = lap00.GetRows();
532  int cols = lap00.GetColumns();
533 
535 
536  (*lap) = gmat[0][0] * lap00 +
537  gmat[1][0] * (lap01 + Transpose(lap01)) +
538  gmat[3][0] * lap11;
539 
541  }
542  }
543  break;
545  {
548  mkey.GetShapeType(), *this);
549  DNekScalMat &MassMat = *(this->m_matrixManager[masskey]);
551  mkey.GetShapeType(), *this);
552  DNekScalMat &LapMat = *(this->m_matrixManager[lapkey]);
553 
554  int rows = LapMat.GetRows();
555  int cols = LapMat.GetColumns();
556 
558 
559  NekDouble one = 1.0;
560  (*helm) = LapMat + factor*MassMat;
561 
562  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,helm);
563  }
564  break;
565  default:
566  NEKERROR(ErrorUtil::efatal, "Matrix creation not defined");
567  break;
568  }
569 
570  return returnval;
571  }
572 
574  {
575  DNekScalBlkMatSharedPtr returnval;
576 
577  ASSERTL2(m_metricinfo->GetGtype() != SpatialDomains::eNoGeomType,"Geometric information is not set up");
578 
579  // set up block matrix system
580  unsigned int nbdry = NumBndryCoeffs();
581  unsigned int nint = (unsigned int)(m_ncoeffs - nbdry);
582  unsigned int exp_size[] = {nbdry,nint};
583  unsigned int nblks = 2;
584  returnval = MemoryManager<DNekScalBlkMat>::AllocateSharedPtr(nblks,nblks,exp_size,exp_size); //Really need a constructor which takes Arrays
585  NekDouble factor = 1.0;
586 
587  switch(mkey.GetMatrixType())
588  {
590  case StdRegions::eHelmholtz: // special case since Helmholtz not defined in StdRegions
591 
592  // use Deformed case for both regular and deformed geometries
593  factor = 1.0;
594  goto UseLocRegionsMatrix;
595  break;
596  default:
597  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
598  {
599  factor = 1.0;
600  goto UseLocRegionsMatrix;
601  }
602  else
603  {
605  factor = mat->Scale();
606  goto UseStdRegionsMatrix;
607  }
608  break;
609  UseStdRegionsMatrix:
610  {
611  NekDouble invfactor = 1.0/factor;
612  NekDouble one = 1.0;
615  DNekMatSharedPtr Asubmat;
616 
617  returnval->SetBlock(0,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,Asubmat = mat->GetBlock(0,0)));
618  returnval->SetBlock(0,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,Asubmat = mat->GetBlock(0,1)));
619  returnval->SetBlock(1,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,Asubmat = mat->GetBlock(1,0)));
620  returnval->SetBlock(1,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(invfactor,Asubmat = mat->GetBlock(1,1)));
621  }
622  break;
623  UseLocRegionsMatrix:
624  {
625  int i,j;
626  NekDouble invfactor = 1.0/factor;
627  NekDouble one = 1.0;
628  DNekScalMat &mat = *GetLocMatrix(mkey);
633 
634  Array<OneD,unsigned int> bmap(nbdry);
635  Array<OneD,unsigned int> imap(nint);
636  GetBoundaryMap(bmap);
637  GetInteriorMap(imap);
638 
639  for(i = 0; i < nbdry; ++i)
640  {
641  for(j = 0; j < nbdry; ++j)
642  {
643  (*A)(i,j) = mat(bmap[i],bmap[j]);
644  }
645 
646  for(j = 0; j < nint; ++j)
647  {
648  (*B)(i,j) = mat(bmap[i],imap[j]);
649  }
650  }
651 
652  for(i = 0; i < nint; ++i)
653  {
654  for(j = 0; j < nbdry; ++j)
655  {
656  (*C)(i,j) = mat(imap[i],bmap[j]);
657  }
658 
659  for(j = 0; j < nint; ++j)
660  {
661  (*D)(i,j) = mat(imap[i],imap[j]);
662  }
663  }
664 
665  // Calculate static condensed system
666  if(nint)
667  {
668  D->Invert();
669  (*B) = (*B)*(*D);
670  (*A) = (*A) - (*B)*(*C);
671  }
672 
674 
675  returnval->SetBlock(0,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,A));
676  returnval->SetBlock(0,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,B));
677  returnval->SetBlock(1,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,C));
678  returnval->SetBlock(1,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(invfactor,D));
679 
680  }
681  }
682 
683  return returnval;
684  }
685 
686 
688  {
689 
691  ::AllocateSharedPtr(m_base[0]->GetBasisKey(),
692  m_base[1]->GetBasisKey(),
694  }
695 
697  {
699  2, m_base[0]->GetPointsKey());
701  2, m_base[1]->GetPointsKey());
702 
705  }
706 
708  {
709  DNekMatSharedPtr returnval;
710 
711  switch(mkey.GetMatrixType())
712  {
719  returnval = Expansion2D::v_GenMatrix(mkey);
720  break;
721  default:
722  returnval = StdNodalTriExp::v_GenMatrix(mkey);
723  break;
724  }
725  return returnval;
726  }
727 
729  {
730  int i;
731  const SpatialDomains::GeomFactorsSharedPtr & geomFactors = GetGeom()->GetMetricInfo();
732  const SpatialDomains::GeomType type = geomFactors->GetGtype();
733 
735  const Array<TwoD, const NekDouble> & df = geomFactors->GetDerivFactors(ptsKeys);
736  const Array<OneD, const NekDouble> & jac = geomFactors->GetJac(ptsKeys);
737  int nqe = m_base[0]->GetNumPoints();
738  int dim = GetCoordim();
739 
742  for (i = 0; i < dim; ++i)
743  {
744  normal[i] = Array<OneD, NekDouble>(nqe);
745  }
746 
747  size_t nqb = nqe;
748  size_t nbnd= edge;
751 
752  // Regular geometry case
754  {
755  NekDouble fac;
756  // Set up normals
757  switch(edge)
758  {
759  case 0:
760  for(i = 0; i < GetCoordim(); ++i)
761  {
762  Vmath::Fill(nqe,-df[2*i+1][0],normal[i],1);
763  }
764  break;
765  case 1:
766  for(i = 0; i < GetCoordim(); ++i)
767  {
768  Vmath::Fill(nqe,df[2*i+1][0] + df[2*i][0],normal[i],1);
769  }
770  break;
771  case 2:
772  for(i = 0; i < GetCoordim(); ++i)
773  {
774  Vmath::Fill(nqe,-df[2*i][0],normal[i],1);
775  }
776  break;
777  default:
778  ASSERTL0(false,"Edge is out of range (edge < 3)");
779  }
780 
781  // normalise
782  fac = 0.0;
783  for(i =0 ; i < GetCoordim(); ++i)
784  {
785  fac += normal[i][0]*normal[i][0];
786  }
787  fac = 1.0/sqrt(fac);
788 
789  Vmath::Fill(nqb, fac, length, 1);
790 
791  for (i = 0; i < GetCoordim(); ++i)
792  {
793  Vmath::Smul(nqe,fac,normal[i],1,normal[i],1);
794  }
795  }
796  else // Set up deformed normals
797  {
798  int j;
799 
800  int nquad0 = ptsKeys[0].GetNumPoints();
801  int nquad1 = ptsKeys[1].GetNumPoints();
802 
803  LibUtilities::PointsKey from_key;
804 
805  Array<OneD,NekDouble> normals(GetCoordim()*max(nquad0,nquad1),0.0);
806  Array<OneD,NekDouble> edgejac(GetCoordim()*max(nquad0,nquad1),0.0);
807 
808  // Extract Jacobian along edges and recover local
809  // derivates (dx/dr) for polynomial interpolation by
810  // multiplying m_gmat by jacobian
811  switch(edge)
812  {
813  case 0:
814  for(j = 0; j < nquad0; ++j)
815  {
816  edgejac[j] = jac[j];
817  for(i = 0; i < GetCoordim(); ++i)
818  {
819  normals[i*nquad0+j] = -df[2*i+1][j]*edgejac[j];
820  }
821  }
822  from_key = ptsKeys[0];
823  break;
824  case 1:
825  for(j = 0; j < nquad1; ++j)
826  {
827  edgejac[j] = jac[nquad0*j+nquad0-1];
828  for(i = 0; i < GetCoordim(); ++i)
829  {
830  normals[i*nquad1+j] = (df[2*i][nquad0*j + nquad0-1] + df[2*i+1][nquad0*j + nquad0-1])*edgejac[j];
831  }
832  }
833  from_key = ptsKeys[1];
834  break;
835  case 2:
836  for(j = 0; j < nquad1; ++j)
837  {
838  edgejac[j] = jac[nquad0*j];
839  for(i = 0; i < GetCoordim(); ++i)
840  {
841  normals[i*nquad1+j] = -df[2*i][nquad0*j]*edgejac[j];
842  }
843  }
844  from_key = ptsKeys[1];
845  break;
846  default:
847  ASSERTL0(false,"edge is out of range (edge < 3)");
848 
849  }
850 
851  int nq = from_key.GetNumPoints();
852  Array<OneD,NekDouble> work(nqe,0.0);
853 
854  // interpolate Jacobian and invert
855  LibUtilities::Interp1D(from_key,jac,m_base[0]->GetPointsKey(),work);
856  Vmath::Sdiv(nq,1.0,&work[0],1,&work[0],1);
857 
858  // interpolate
859  for(i = 0; i < GetCoordim(); ++i)
860  {
861  LibUtilities::Interp1D(from_key,&normals[i*nq],m_base[0]->GetPointsKey(),&normal[i][0]);
862  Vmath::Vmul(nqe,work,1,normal[i],1,normal[i],1);
863  }
864 
865  //normalise normal vectors
866  Vmath::Zero(nqe,work,1);
867  for(i = 0; i < GetCoordim(); ++i)
868  {
869  Vmath::Vvtvp(nqe,normal[i],1, normal[i],1,work,1,work,1);
870  }
871 
872  Vmath::Vsqrt(nqe,work,1,work,1);
873  Vmath::Sdiv(nqe,1.0,work,1,work,1);
874 
875  Vmath::Vcopy(nqb, work, 1, length, 1);
876 
877  for(i = 0; i < GetCoordim(); ++i)
878  {
879  Vmath::Vmul(nqe,normal[i],1,work,1,normal[i],1);
880  }
881 
882  // Reverse direction so that points are in
883  // anticlockwise direction if edge >=2
884  if(edge >= 2)
885  {
886  for(i = 0; i < GetCoordim(); ++i)
887  {
888  Vmath::Reverse(nqe,normal[i],1, normal[i],1);
889  }
890  }
891  }
892  }
893 
894  }//end of namespace
895 }//end of namespace
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:250
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
Definition: ErrorUtil.hpp:274
Describes the specification for a Basis.
Definition: Basis.h:50
Defines a specification for a set of points.
Definition: Points.h:60
PointsType GetPointsType() const
Definition: Points.h:112
unsigned int GetNumPoints() const
Definition: Points.h:107
virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey)
std::map< int, NormalVector > m_edgeNormals
Definition: Expansion2D.h:121
std::map< int, Array< OneD, NekDouble > > m_elmtBndNormDirElmtLen
the element length in each element boundary(Vertex, edge or face) normal direction calculated based o...
Definition: Expansion.h:284
SpatialDomains::GeometrySharedPtr GetGeom() const
Definition: Expansion.cpp:172
SpatialDomains::GeometrySharedPtr m_geom
Definition: Expansion.h:272
void AlignVectorToCollapsedDir(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
Definition: Expansion.h:144
SpatialDomains::GeomFactorsSharedPtr m_metricinfo
Definition: Expansion.h:273
virtual void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3)
Definition: Expansion.cpp:318
DNekScalMatSharedPtr GetLocMatrix(const LocalRegions::MatrixKey &mkey)
Definition: Expansion.cpp:90
LibUtilities::NekManager< MatrixKey, DNekScalMat, MatrixKey::opLess > m_matrixManager
Definition: NodalTriExp.h:188
DNekScalMatSharedPtr CreateMatrix(const MatrixKey &mkey)
void GetCoord(const Array< OneD, const NekDouble > &Lcoords, Array< OneD, NekDouble > &coords)
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.
DNekMatSharedPtr CreateStdMatrix(const StdRegions::StdMatrixKey &mkey)
void GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3=NullNekDouble1DArray)
void GeneralMatrixOp_MatOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey)
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
void IProductWRTDerivBase_MatOp(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
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...
DNekScalBlkMatSharedPtr CreateStaticCondMatrix(const MatrixKey &mkey)
void IProductWRTDerivBase_SumFac(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
NekDouble PhysEvaluate(const Array< OneD, const NekDouble > &coord, const Array< OneD, const NekDouble > &physvals)
NekDouble Integral(const Array< OneD, const NekDouble > &inarray)
Integrate the physical point list inarray over region.
Definition: NodalTriExp.cpp:98
void IProductWRTBase_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool multiplybyweights=true)
virtual void v_AlignVectorToCollapsedDir(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
void v_ComputeTraceNormal(const int edge)
void IProductWRTBase_MatOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const
virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey)
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
virtual StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
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)
void GetBoundaryMap(Array< OneD, unsigned int > &outarray)
Definition: StdExpansion.h:687
int GetTotPoints() const
This function returns the total number of quadrature points used in the element.
Definition: StdExpansion.h:134
LibUtilities::BasisType GetBasisType(const int dir) const
This function returns the type of basis used in the dir direction.
Definition: StdExpansion.h:158
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:617
const LibUtilities::PointsKeyVector GetPointsKeys() const
DNekBlkMatSharedPtr GetStdStaticCondMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:622
LibUtilities::ShapeType DetShapeType() const
This function returns the shape of the expansion domain.
Definition: StdExpansion.h:376
void GetInteriorMap(Array< OneD, unsigned int > &outarray)
Definition: StdExpansion.h:692
DNekMatSharedPtr GenMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:850
void MultiplyByQuadratureMetric(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: StdExpansion.h:733
Array< OneD, LibUtilities::BasisSharedPtr > m_base
LibUtilities::ShapeType GetShapeType() const
Definition: StdMatrixKey.h:86
MatrixType GetMatrixType() const
Definition: StdMatrixKey.h:81
NekDouble GetConstFactor(const ConstFactorType &factor) const
Definition: StdMatrixKey.h:121
void NodalToModalTranspose(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
LibUtilities::PointsKey m_nodalPointsKey
static void Dgemv(const char &trans, const int &m, const int &n, const double &alpha, const double *a, const int &lda, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = A x where A[m x n].
Definition: Blas.hpp:265
static void Daxpy(const int &n, const double &alpha, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: y = alpha x plus y.
Definition: Blas.hpp:167
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
std::vector< PointsKey > PointsKeyVector
Definition: Points.h:246
std::shared_ptr< GeomFactors > GeomFactorsSharedPtr
Pointer to a GeomFactors object.
Definition: GeomFactors.h:62
GeomType
Indicates the type of element geometry.
@ eRegular
Geometry is straight-sided with constant geometric factors.
@ eNoGeomType
No type defined.
@ eMovingRegular
Currently unused.
@ eDeformed
Geometry is curved or has non-constant factors.
std::shared_ptr< TriGeom > TriGeomSharedPtr
Definition: TriGeom.h:58
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
std::shared_ptr< StdNodalTriExp > StdNodalTriExpSharedPtr
static ConstFactorMap NullConstFactorMap
Definition: StdRegions.hpp:315
static VarCoeffMap NullVarCoeffMap
Definition: StdRegions.hpp:273
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
std::shared_ptr< DNekBlkMat > DNekBlkMatSharedPtr
Definition: NekTypeDefs.hpp:71
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
Definition: NekTypeDefs.hpp:73
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:69
double NekDouble
void Vsqrt(int n, const T *x, const int incx, T *y, const int incy)
sqrt y = sqrt(x)
Definition: Vmath.cpp:475
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:192
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
Definition: Vmath.cpp:513
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.cpp:322
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.cpp:225
void Sdiv(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha/y.
Definition: Vmath.cpp:291
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:436
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:45
void Reverse(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1226
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1199
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:267