Nektar++
SegExp.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File SegExp.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: SegExp routines
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include <boost/core/ignore_unused.hpp>
36 
38 #include <LocalRegions/SegExp.h>
40 
41 using namespace std;
42 
43 namespace Nektar
44 {
45  namespace LocalRegions
46  {
47 
48  /**
49  * @class SegExp
50  * Defines a Segment local expansion.
51  */
52 
53  /// Constructor using BasisKey class for quadrature points and
54  /// order definition.
55  /**
56  * @param Ba Basis key of segment expansion.
57  * @param geom Description of geometry.
58  */
59  SegExp::SegExp( const LibUtilities::BasisKey &Ba,
61  StdExpansion(Ba.GetNumModes(), 1, Ba),
62  StdExpansion1D(Ba.GetNumModes(), Ba),
63  StdRegions::StdSegExp(Ba),
64  Expansion(geom),
65  Expansion1D(geom),
66  m_matrixManager(
67  std::bind(&SegExp::CreateMatrix, this, std::placeholders::_1),
68  std::string("SegExpMatrix")),
69  m_staticCondMatrixManager(
70  std::bind(&SegExp::CreateStaticCondMatrix, this, std::placeholders::_1),
71  std::string("SegExpStaticCondMatrix"))
72  {
73  }
74 
75 
76  /// Copy Constructor
77  /**
78  * @param S Existing segment to duplicate.
79  */
81  StdExpansion(S),
82  StdExpansion1D(S),
83  StdRegions::StdSegExp(S),
84  Expansion(S),
85  Expansion1D(S),
88  {
89  }
90 
91 
92  /**
93  *
94  */
96  {
97  }
98 
99 
100  //----------------------------
101  // Integration Methods
102  //----------------------------
103 
104  /** \brief Integrate the physical point list \a inarray over region
105  and return the value
106 
107  Inputs:\n
108 
109  - \a inarray: definition of function to be returned at
110  quadrature point of expansion.
111 
112  Outputs:\n
113 
114  - returns \f$\int^1_{-1} u(\xi_1)d \xi_1 \f$ where \f$inarray[i]
115  = u(\xi_{1i}) \f$
116  */
117 
119  const Array<OneD, const NekDouble>& inarray)
120  {
121  int nquad0 = m_base[0]->GetNumPoints();
123  NekDouble ival;
124  Array<OneD,NekDouble> tmp(nquad0);
125 
126  // multiply inarray with Jacobian
127  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
128  {
129  Vmath::Vmul(nquad0, jac, 1, inarray, 1, tmp,1);
130  }
131  else
132  {
133  Vmath::Smul(nquad0, jac[0], inarray, 1, tmp, 1);
134  }
135 
136  // call StdSegExp version;
137  ival = StdSegExp::v_Integral(tmp);
138  //ival = StdSegExp::Integral(tmp);
139  return ival;
140  }
141 
142  //-----------------------------
143  // Differentiation Methods
144  //-----------------------------
145 
146  /** \brief Evaluate the derivative \f$ d/d{\xi_1} \f$ at the
147  physical quadrature points given by \a inarray and return in \a
148  outarray.
149 
150  This is a wrapper around StdExpansion1D::Tensor_Deriv
151 
152  Input:\n
153 
154  - \a n: number of derivatives to be evaluated where \f$ n \leq dim\f$
155 
156  - \a inarray: array of function evaluated at the quadrature points
157 
158  Output: \n
159 
160  - \a outarray: array of the derivatives \f$
161  du/d_{\xi_1}|_{\xi_{1i}} d\xi_1/dx,
162  du/d_{\xi_1}|_{\xi_{1i}} d\xi_1/dy,
163  du/d_{\xi_1}|_{\xi_{1i}} d\xi_1/dz,
164  \f$ depending on value of \a dim
165  */
167  const Array<OneD, const NekDouble>& inarray,
168  Array<OneD,NekDouble> &out_d0,
169  Array<OneD,NekDouble> &out_d1,
170  Array<OneD,NekDouble> &out_d2)
171  {
172  int nquad0 = m_base[0]->GetNumPoints();
174  m_metricinfo->GetDerivFactors(GetPointsKeys());
175  Array<OneD,NekDouble> diff(nquad0);
176 
177  //StdExpansion1D::PhysTensorDeriv(inarray,diff);
178  PhysTensorDeriv(inarray,diff);
179  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
180  {
181  if(out_d0.num_elements())
182  {
183  Vmath::Vmul(nquad0,&gmat[0][0],1,&diff[0],1,
184  &out_d0[0],1);
185  }
186 
187  if(out_d1.num_elements())
188  {
189  Vmath::Vmul(nquad0,&gmat[1][0],1,&diff[0],1,
190  &out_d1[0],1);
191  }
192 
193  if(out_d2.num_elements())
194  {
195  Vmath::Vmul(nquad0,&gmat[2][0],1,&diff[0],1,
196  &out_d2[0],1);
197  }
198  }
199  else
200  {
201  if(out_d0.num_elements())
202  {
203  Vmath::Smul(nquad0, gmat[0][0], diff, 1,
204  out_d0, 1);
205  }
206 
207  if(out_d1.num_elements())
208  {
209  Vmath::Smul(nquad0, gmat[1][0], diff, 1,
210  out_d1, 1);
211  }
212 
213  if(out_d2.num_elements())
214  {
215  Vmath::Smul(nquad0, gmat[2][0], diff, 1,
216  out_d2, 1);
217  }
218  }
219  }
220 
221  /**
222  *\brief Evaluate the derivative along a line:
223  * \f$ d/ds=\frac{spacedim}{||tangent||}d/d{\xi} \f$.
224  * The derivative is calculated performing
225  *the product \f$ du/d{s}=\nabla u \cdot tangent \f$.
226  *\param inarray function to derive
227  *\param out_ds result of the derivative operation
228  **/
230  const Array<OneD, const NekDouble>& inarray,
231  Array<OneD,NekDouble> &out_ds)
232  {
233  int nquad0 = m_base[0]->GetNumPoints();
234  int coordim = m_geom->GetCoordim();
235  Array<OneD, NekDouble> diff (nquad0);
236  //this operation is needed if you put out_ds==inarray
237  Vmath::Zero(nquad0,out_ds,1);
238  switch(coordim)
239  {
240  case 2:
241  //diff= dU/de
242  Array<OneD,NekDouble> diff(nquad0);
243 
244  PhysTensorDeriv(inarray,diff);
245 
246  //get dS/de= (Jac)^-1
248  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
249  {
250  //calculate the derivative as (dU/de)*(Jac)^-1
251  Vmath::Vdiv(nquad0,diff,1,Jac ,1,out_ds,1);
252  }
253  else
254  {
255  NekDouble invJac = 1/Jac[0];
256  Vmath::Smul(nquad0, invJac,diff,1,out_ds,1);
257  }
258  }
259  }
260 
261  /**
262  *\brief Evaluate the derivative normal to a line:
263  * \f$ d/dn=\frac{spacedim}{||normal||}d/d{\xi} \f$.
264  * The derivative is calculated performing
265  *the product \f$ du/d{s}=\nabla u \cdot normal \f$.
266  *\param inarray function to derive
267  *\param out_dn result of the derivative operation
268  **/
270  const Array<OneD, const NekDouble>& inarray,
271  Array<OneD, NekDouble>& out_dn)
272  {
273  int nquad0 = m_base[0]->GetNumPoints();
275  m_metricinfo->GetDerivFactors(GetPointsKeys());
276  int coordim = m_geom->GetCoordim();
277  Array<OneD, NekDouble> out_dn_tmp(nquad0,0.0);
278  switch(coordim)
279  {
280  case 2:
281 
282  Array<OneD, NekDouble> inarray_d0(nquad0);
283  Array<OneD, NekDouble> inarray_d1(nquad0);
284 
285  v_PhysDeriv(inarray,inarray_d0,inarray_d1);
287  normals = Array<OneD, Array<OneD, NekDouble> >(coordim);
288  cout<<"der_n"<<endl;
289  for(int k=0; k<coordim; ++k)
290  {
291  normals[k]= Array<OneD, NekDouble>(nquad0);
292  }
293 // @TODO: this routine no longer makes sense, since normals are not unique on
294 // an edge
295 // normals = GetMetricInfo()->GetNormal();
296  for(int i=0; i<nquad0; i++)
297  {
298 cout<<"nx= "<<normals[0][i]<<" ny="<<normals[1][i]<<endl;
299  }
301  "normal vectors do not exist: check if a"
302  "boundary region is defined as I ");
303  // \nabla u \cdot normal
304  Vmath::Vmul(nquad0,normals[0],1,inarray_d0,1,out_dn_tmp,1);
305  Vmath::Vadd(nquad0,out_dn_tmp,1,out_dn,1,out_dn,1);
306  Vmath::Zero(nquad0,out_dn_tmp,1);
307  Vmath::Vmul(nquad0,normals[1],1,inarray_d1,1,out_dn_tmp,1);
308  Vmath::Vadd(nquad0,out_dn_tmp,1,out_dn,1,out_dn,1);
309 
310  for(int i=0; i<nquad0; i++)
311  {
312 cout<<"deps/dx ="<<inarray_d0[i]<<" deps/dy="<<inarray_d1[i]<<endl;
313  }
314 
315 
316  }
317 
318  }
319  void SegExp::v_PhysDeriv(const int dir,
320  const Array<OneD, const NekDouble>& inarray,
321  Array<OneD, NekDouble> &outarray)
322  {
323  switch(dir)
324  {
325  case 0:
326  {
327  PhysDeriv(inarray, outarray, NullNekDouble1DArray,
329  }
330  break;
331  case 1:
332  {
333  PhysDeriv(inarray, NullNekDouble1DArray, outarray,
335  }
336  break;
337  case 2:
338  {
340  NullNekDouble1DArray, outarray);
341  }
342  break;
343  default:
344  {
345  ASSERTL1(false,"input dir is out of range");
346  }
347  break;
348  }
349  }
350 
351 
352  //-----------------------------
353  // Transforms
354  //-----------------------------
355 
356  /** \brief Forward transform from physical quadrature space
357  stored in \a inarray and evaluate the expansion coefficients and
358  store in \a outarray
359 
360  Perform a forward transform using a Galerkin projection by
361  taking the inner product of the physical points and multiplying
362  by the inverse of the mass matrix using the Solve method of the
363  standard matrix container holding the local mass matrix, i.e.
364  \f$ {\bf \hat{u}} = {\bf M}^{-1} {\bf I} \f$ where \f$ {\bf I}[p] =
365  \int^1_{-1} \phi_p(\xi_1) u(\xi_1) d\xi_1 \f$
366 
367  Inputs:\n
368 
369  - \a inarray: array of physical quadrature points to be transformed
370 
371  Outputs:\n
372 
373  - \a outarray: updated array of expansion coefficients.
374 
375  */
376  // need to sort out family of matrices
378  const Array<OneD, const NekDouble>& inarray,
379  Array<OneD,NekDouble> &outarray)
380  {
381  if (m_base[0]->Collocation())
382  {
383  Vmath::Vcopy(m_ncoeffs, inarray, 1, outarray, 1);
384  }
385  else
386  {
387  v_IProductWRTBase(inarray,outarray);
388 
389  // get Mass matrix inverse
390  MatrixKey masskey(StdRegions::eInvMass, DetShapeType(), *this);
391  DNekScalMatSharedPtr matsys = m_matrixManager[masskey];
392 
393  // copy inarray in case inarray == outarray
394  NekVector<NekDouble> in(m_ncoeffs,outarray,eCopy);
396 
397  out = (*matsys)*in;
398  }
399  }
400 
402  const Array<OneD, const NekDouble>& inarray,
403  Array<OneD, NekDouble> &outarray)
404  {
405  if(m_base[0]->Collocation())
406  {
407  Vmath::Vcopy(m_ncoeffs, inarray, 1, outarray, 1);
408  }
409  else
410  {
411  int nInteriorDofs = m_ncoeffs-2;
412  int offset = 0;
413 
414  switch (m_base[0]->GetBasisType())
415  {
417  {
418  offset = 1;
419  }
420  break;
422  {
423  nInteriorDofs = m_ncoeffs;
424  offset = 0;
425  }
426  break;
429  {
432  "Cannot use FwdTrans_BndConstrained with these points.");
433  offset = 2;
434  }
435  break;
436  default:
437  ASSERTL0(false,"This type of FwdTrans is not defined"
438  "for this expansion type");
439  }
440 
441  fill(outarray.get(), outarray.get()+m_ncoeffs, 0.0 );
442 
444  {
445 
446  outarray[GetVertexMap(0)] = inarray[0];
447  outarray[GetVertexMap(1)] =
448  inarray[m_base[0]->GetNumPoints()-1];
449 
450  if (m_ncoeffs>2)
451  {
452  // ideally, we would like to have tmp0 to be replaced
453  // by outarray (currently MassMatrixOp does not allow
454  // aliasing)
457 
458  StdRegions::StdMatrixKey stdmasskey(
460  MassMatrixOp(outarray,tmp0,stdmasskey);
461  v_IProductWRTBase(inarray,tmp1);
462 
463  Vmath::Vsub(m_ncoeffs, tmp1, 1, tmp0, 1, tmp1, 1);
464 
465  // get Mass matrix inverse (only of interior DOF)
466  MatrixKey masskey(
468  DNekScalMatSharedPtr matsys =
469  (m_staticCondMatrixManager[masskey])->GetBlock(1,1);
470 
471  Blas::Dgemv('N',nInteriorDofs,nInteriorDofs,
472  matsys->Scale(),
473  &((matsys->GetOwnedMatrix())->GetPtr())[0],
474  nInteriorDofs,tmp1.get()+offset,1,0.0,
475  outarray.get()+offset,1);
476  }
477  }
478  else
479  {
480  SegExp::v_FwdTrans(inarray, outarray);
481 
482  }
483  }
484  }
485 
486 
487  //-----------------------------
488  // Inner product functions
489  //-----------------------------
490 
491  /** \brief Inner product of \a inarray over region with respect to
492  the expansion basis (this)->_Base[0] and return in \a outarray
493 
494  Wrapper call to SegExp::IProduct_WRT_B
495 
496  Input:\n
497 
498  - \a inarray: array of function evaluated at the physical
499  collocation points
500 
501  Output:\n
502 
503  - \a outarray: array of inner product with respect to each
504  basis over region
505  */
507  const Array<OneD, const NekDouble>& inarray,
508  Array<OneD, NekDouble> &outarray)
509  {
510  v_IProductWRTBase(m_base[0]->GetBdata(),inarray,outarray,1);
511  }
512 
513 
514  /**
515  \brief Inner product of \a inarray over region with respect to
516  expansion basis \a base and return in \a outarray
517 
518  Calculate \f$ I[p] = \int^{1}_{-1} \phi_p(\xi_1) u(\xi_1) d\xi_1
519  = \sum_{i=0}^{nq-1} \phi_p(\xi_{1i}) u(\xi_{1i}) w_i \f$ where
520  \f$ outarray[p] = I[p], inarray[i] = u(\xi_{1i}), base[p*nq+i] =
521  \phi_p(\xi_{1i}) \f$.
522 
523  Inputs: \n
524 
525  - \a base: an array definiing the local basis for the inner
526  product usually passed from Basis->get_bdata() or
527  Basis->get_Dbdata()
528  - \a inarray: physical point array of function to be integrated
529  \f$ u(\xi_1) \f$
530  - \a coll_check: Flag to identify when a Basis->collocation()
531  call should be performed to see if this is a GLL_Lagrange basis
532  with a collocation property. (should be set to 0 if taking the
533  inner product with respect to the derivative of basis)
534 
535  Output: \n
536 
537  - \a outarray: array of coefficients representing the inner
538  product of function with ever mode in the exapnsion
539 
540  **/
542  const Array<OneD, const NekDouble>& base,
543  const Array<OneD, const NekDouble>& inarray,
544  Array<OneD, NekDouble> &outarray,
545  int coll_check)
546  {
547  int nquad0 = m_base[0]->GetNumPoints();
549  Array<OneD,NekDouble> tmp(nquad0);
550 
551 
552  // multiply inarray with Jacobian
553  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
554  {
555  Vmath::Vmul(nquad0, jac, 1, inarray, 1, tmp, 1);
556  }
557  else
558  {
559  Vmath::Smul(nquad0, jac[0], inarray, 1, tmp, 1);
560  }
561  StdSegExp::v_IProductWRTBase(base,tmp,outarray,coll_check);
562  }
563 
564 
566  const int dir,
567  const Array<OneD, const NekDouble>& inarray,
568  Array<OneD, NekDouble> & outarray)
569  {
570  int nquad = m_base[0]->GetNumPoints();
571  const Array<TwoD, const NekDouble>& gmat =
572  m_metricinfo->GetDerivFactors(GetPointsKeys());
573 
574  Array<OneD, NekDouble> tmp1(nquad);
575 
576  switch(dir)
577  {
578  case 0:
579  {
580  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
581  {
582  Vmath::Vmul(nquad,gmat[0],1,inarray,1,tmp1,1);
583  }
584  else
585  {
586  Vmath::Smul(nquad, gmat[0][0], inarray, 1, tmp1, 1);
587  }
588  }
589  break;
590  case 1:
591  {
592  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
593  {
594  Vmath::Vmul(nquad,gmat[1],1,inarray,1,tmp1,1);
595  }
596  else
597  {
598  Vmath::Smul(nquad, gmat[1][0], inarray, 1, tmp1, 1);
599  }
600  }
601  break;
602  case 2:
603  {
604  ASSERTL1(m_geom->GetCoordim() == 3,"input dir is out of range");
605  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
606  {
607  Vmath::Vmul(nquad,gmat[2],1,inarray,1,tmp1,1);
608  }
609  else
610  {
611  Vmath::Smul(nquad, gmat[2][0], inarray, 1, tmp1, 1);
612  }
613  }
614  break;
615  default:
616  {
617  ASSERTL1(false,"input dir is out of range");
618  }
619  break;
620  }
621  v_IProductWRTBase(m_base[0]->GetDbdata(),tmp1,outarray,1);
622  }
623 
627  Array<OneD, NekDouble> &outarray)
628  {
629  int nq = m_base[0]->GetNumPoints();
631 // cout << "I am segment " << GetGeom()->GetGlobalID() << endl;
632 // cout << "I want edge " << GetLeftAdjacentElementEdge() << endl;
633 // @TODO: This routine no longer makes sense as a normal is not unique to an edge
635  &normals =
638  Vmath::Vmul (nq, &Fx[0], 1, &normals[0][0], 1, &Fn[0], 1);
639  Vmath::Vvtvp(nq, &Fy[0], 1, &normals[1][0], 1, &Fn[0], 1, &Fn[0], 1);
640 
641  v_IProductWRTBase(Fn,outarray);
642  }
643 
645  const Array<OneD, const Array<OneD, NekDouble> > &Fvec,
646  Array<OneD, NekDouble> &outarray)
647  {
648  NormVectorIProductWRTBase(Fvec[0], Fvec[1], outarray);
649  }
650 
651  //-----------------------------
652  // Evaluation functions
653  //-----------------------------
654 
655 
656  /**
657  * Given the local cartesian coordinate \a Lcoord evaluate the
658  * value of physvals at this point by calling through to the
659  * StdExpansion method
660  */
662  const Array<OneD, const NekDouble> &Lcoord,
663  const Array<OneD, const NekDouble> &physvals)
664  {
665  // Evaluate point in local (eta) coordinates.
666  return StdSegExp::v_PhysEvaluate(Lcoord,physvals);
667  }
668 
670  const Array<OneD, const NekDouble>& coord,
671  const Array<OneD, const NekDouble> &physvals)
672  {
674 
675  ASSERTL0(m_geom,"m_geom not defined");
676  m_geom->GetLocCoords(coord,Lcoord);
677 
678  return StdSegExp::v_PhysEvaluate(Lcoord, physvals);
679  }
680 
681 
683  const Array<OneD, const NekDouble>& Lcoords,
684  Array<OneD,NekDouble> &coords)
685  {
686  int i;
687 
688  ASSERTL1(Lcoords[0] >= -1.0&& Lcoords[0] <= 1.0,
689  "Local coordinates are not in region [-1,1]");
690 
691  m_geom->FillGeom();
692  for(i = 0; i < m_geom->GetCoordim(); ++i)
693  {
694  coords[i] = m_geom->GetCoord(i,Lcoords);
695  }
696  }
697 
699  Array<OneD, NekDouble> &coords_0,
700  Array<OneD, NekDouble> &coords_1,
701  Array<OneD, NekDouble> &coords_2)
702  {
703  Expansion::v_GetCoords(coords_0, coords_1, coords_2);
704  }
705 
706  // Get vertex value from the 1D Phys space.
708  const int vertex,
709  const Array<OneD, const NekDouble> &inarray,
710  NekDouble &outarray)
711  {
712  int nquad = m_base[0]->GetNumPoints();
713 
715  {
716  switch (vertex)
717  {
718  case 0:
719  outarray = inarray[0];
720  break;
721  case 1:
722  outarray = inarray[nquad - 1];
723  break;
724  }
725  }
726  else
727  {
729  factors[StdRegions::eFactorGaussVertex] = vertex;
730 
733  DetShapeType(),*this,factors);
734 
735  DNekScalMatSharedPtr mat_gauss = m_matrixManager[key];
736 
737  outarray = Blas::Ddot(nquad, mat_gauss->GetOwnedMatrix()
738  ->GetPtr().get(), 1, &inarray[0], 1);
739  }
740  }
741 
742  // Get vertex value from the 1D Phys space.
744  const int edge,
745  const StdRegions::StdExpansionSharedPtr &EdgeExp,
746  const Array<OneD, const NekDouble> &inarray,
747  Array<OneD, NekDouble> &outarray,
749  {
750  boost::ignore_unused(EdgeExp, orient);
751 
752  NekDouble result;
753  v_GetVertexPhysVals(edge, inarray, result);
754  outarray[0] = result;
755  }
756 
757  //-----------------------------
758  // Helper functions
759  //-----------------------------
760 
762  Array<OneD, NekDouble> &coeffs,
764  {
765  v_SetCoeffsToOrientation(dir,coeffs,coeffs);
766  }
767 
771  Array<OneD, NekDouble> &outarray)
772  {
773 
774  if (dir == StdRegions::eBackwards)
775  {
776  if (&inarray[0] != &outarray[0])
777  {
778  Array<OneD,NekDouble> intmp (inarray);
779  ReverseCoeffsAndSign(intmp,outarray);
780  }
781  else
782  {
783  ReverseCoeffsAndSign(inarray,outarray);
784  }
785  }
786  }
787 
789  {
791  ::AllocateSharedPtr(m_base[0]->GetBasisKey());
792  }
793 
795  {
797  2, m_base[0]->GetPointsKey());
798 
800  ::AllocateSharedPtr( bkey0);
801  }
802 
804  {
805  return m_geom->GetCoordim();
806  }
807 
809  {
810  NEKERROR(ErrorUtil::efatal, "Got to SegExp");
811  return NullNekDouble1DArray;
812  }
813 
815  {
816  return m_metricinfo->GetGtype();
817  }
818 
819  int SegExp::v_GetNumPoints(const int dir) const
820  {
821  return GetNumPoints(dir);
822  }
823 
824  int SegExp::v_GetNcoeffs(void) const
825  {
826  return m_ncoeffs;
827  }
828 
830  {
831  return GetBasis(dir);
832  }
833 
834 
836  {
837  return 2;
838  }
839 
840 
842  {
843  return 2;
844  }
845 
846 
847  /// Unpack data from input file assuming it comes from
848  // the same expansion type
850  const NekDouble *data,
851  const std::vector<unsigned int > &nummodes,
852  const int mode_offset,
853  NekDouble *coeffs,
854  std::vector<LibUtilities::BasisType> &fromType)
855  {
856  boost::ignore_unused(fromType);
857 
858  switch(m_base[0]->GetBasisType())
859  {
861  {
862  int fillorder = min((int) nummodes[mode_offset],m_ncoeffs);
863 
864  Vmath::Zero(m_ncoeffs,coeffs,1);
865  Vmath::Vcopy(fillorder,&data[0],1,&coeffs[0],1);
866  }
867  break;
869  {
870  // Assume that input is also Gll_Lagrange
871  // but no way to check;
873  nummodes[mode_offset],
876  m_base[0]->GetNumModes(),
879  f0,data, t0, coeffs);
880  }
881  break;
883  {
884  // Assume that input is also Gauss_Lagrange
885  // but no way to check;
887  nummodes[mode_offset],
890  m_base[0]->GetNumModes(),
893  f0,data, t0, coeffs);
894  }
895  break;
896  default:
897  ASSERTL0(false,
898  "basis is either not set up or not hierarchicial");
899  }
900  }
901 
902  void SegExp::v_ComputeVertexNormal(const int vertex)
903  {
904  int i;
905  const SpatialDomains::GeomFactorsSharedPtr &geomFactors =
906  GetGeom()->GetMetricInfo();
907  SpatialDomains::GeomType type = geomFactors->GetGtype();
908  const Array<TwoD, const NekDouble> &gmat =
909  geomFactors->GetDerivFactors(GetPointsKeys());
910  int nqe = 1;
911  int vCoordDim = GetCoordim();
912 
913  m_vertexNormals[vertex] =
916  m_vertexNormals[vertex];
917  for (i = 0; i < vCoordDim; ++i)
918  {
919  normal[i] = Array<OneD, NekDouble>(nqe);
920  }
921 
922  // Regular geometry case
923  if ((type == SpatialDomains::eRegular) ||
925  {
926  NekDouble vert;
927  // Set up normals
928  switch (vertex)
929  {
930  case 0:
931  for(i = 0; i < vCoordDim; ++i)
932  {
933  Vmath::Fill(nqe, -gmat[i][0], normal[i], 1);
934  }
935  break;
936  case 1:
937  for(i = 0; i < vCoordDim; ++i)
938  {
939  Vmath::Fill(nqe, gmat[i][0], normal[i], 1);
940  }
941  break;
942  default:
943  ASSERTL0(false,
944  "point is out of range (point < 2)");
945  }
946 
947  // normalise
948  vert = 0.0;
949  for (i =0 ; i < vCoordDim; ++i)
950  {
951  vert += normal[i][0]*normal[i][0];
952  }
953  vert = 1.0/sqrt(vert);
954  for (i = 0; i < vCoordDim; ++i)
955  {
956  Vmath::Smul(nqe, vert, normal[i], 1, normal[i], 1);
957  }
958  }
959  }
960 
961  //-----------------------------
962  // Operator creation functions
963  //-----------------------------
964 
965 
967  const Array<OneD, const NekDouble> &inarray,
968  Array<OneD, NekDouble> &outarray,
969  const StdRegions::StdMatrixKey &mkey)
970  {
971  boost::ignore_unused(mkey);
972 
973  int nquad = m_base[0]->GetNumPoints();
974  const Array<TwoD, const NekDouble>& gmat =
975  m_metricinfo->GetDerivFactors(GetPointsKeys());
976 
977  Array<OneD,NekDouble> physValues(nquad);
978  Array<OneD,NekDouble> dPhysValuesdx(nquad);
979 
980  BwdTrans(inarray,physValues);
981 
982  // Laplacian matrix operation
983  switch (m_geom->GetCoordim())
984  {
985  case 1:
986  {
987  PhysDeriv(physValues,dPhysValuesdx);
988 
989  // multiply with the proper geometric factors
990  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
991  {
992  Vmath::Vmul(nquad,
993  &gmat[0][0],1,dPhysValuesdx.get(),1,
994  dPhysValuesdx.get(),1);
995  }
996  else
997  {
998  Blas::Dscal(nquad,
999  gmat[0][0], dPhysValuesdx.get(), 1);
1000  }
1001  }
1002  break;
1003  case 2:
1004  {
1005  Array<OneD,NekDouble> dPhysValuesdy(nquad);
1006 
1007  PhysDeriv(physValues,dPhysValuesdx,dPhysValuesdy);
1008 
1009  // multiply with the proper geometric factors
1010  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1011  {
1012  Vmath::Vmul (nquad,
1013  &gmat[0][0],1,dPhysValuesdx.get(),1,
1014  dPhysValuesdx.get(),1);
1015  Vmath::Vvtvp(nquad,
1016  &gmat[1][0],1,dPhysValuesdy.get(),1,
1017  dPhysValuesdx.get(),1,
1018  dPhysValuesdx.get(),1);
1019  }
1020  else
1021  {
1022  Blas::Dscal(nquad,
1023  gmat[0][0], dPhysValuesdx.get(), 1);
1024  Blas::Daxpy(nquad,
1025  gmat[1][0], dPhysValuesdy.get(), 1,
1026  dPhysValuesdx.get(), 1);
1027  }
1028  }
1029  break;
1030  case 3:
1031  {
1032  Array<OneD,NekDouble> dPhysValuesdy(nquad);
1033  Array<OneD,NekDouble> dPhysValuesdz(nquad);
1034 
1035  PhysDeriv(physValues,dPhysValuesdx,
1036  dPhysValuesdy,dPhysValuesdz);
1037 
1038  // multiply with the proper geometric factors
1039  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1040  {
1041  Vmath::Vmul (nquad,
1042  &gmat[0][0], 1, dPhysValuesdx.get(), 1,
1043  dPhysValuesdx.get(),1);
1044  Vmath::Vvtvp(nquad,
1045  &gmat[1][0], 1, dPhysValuesdy.get(), 1,
1046  dPhysValuesdx.get(),1,
1047  dPhysValuesdx.get(),1);
1048  Vmath::Vvtvp(nquad,
1049  &gmat[2][0], 1, dPhysValuesdz.get(), 1,
1050  dPhysValuesdx.get(),1,
1051  dPhysValuesdx.get(),1);
1052  }
1053  else
1054  {
1055  Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.get(), 1);
1056  Blas::Daxpy(nquad,
1057  gmat[1][0], dPhysValuesdy.get(), 1,
1058  dPhysValuesdx.get(), 1);
1059  Blas::Daxpy(nquad,
1060  gmat[2][0], dPhysValuesdz.get(), 1,
1061  dPhysValuesdx.get(), 1);
1062  }
1063  }
1064  break;
1065  default:
1066  ASSERTL0(false,"Wrong number of dimensions");
1067  break;
1068  }
1069 
1070  v_IProductWRTBase(m_base[0]->GetDbdata(),dPhysValuesdx,outarray,1);
1071  }
1072 
1073 
1075  const Array<OneD, const NekDouble> &inarray,
1076  Array<OneD, NekDouble> &outarray,
1077  const StdRegions::StdMatrixKey &mkey)
1078  {
1079  int nquad = m_base[0]->GetNumPoints();
1080  const Array<TwoD, const NekDouble>& gmat =
1081  m_metricinfo->GetDerivFactors(GetPointsKeys());
1082  const NekDouble lambda =
1084 
1085  Array<OneD,NekDouble> physValues(nquad);
1086  Array<OneD,NekDouble> dPhysValuesdx(nquad);
1088 
1089  BwdTrans(inarray, physValues);
1090 
1091  // mass matrix operation
1092  v_IProductWRTBase((m_base[0]->GetBdata()),physValues,wsp,1);
1093 
1094  // Laplacian matrix operation
1095  switch (m_geom->GetCoordim())
1096  {
1097  case 1:
1098  {
1099  PhysDeriv(physValues,dPhysValuesdx);
1100 
1101  // multiply with the proper geometric factors
1102  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1103  {
1104  Vmath::Vmul(nquad,
1105  &gmat[0][0],1,dPhysValuesdx.get(),1,
1106  dPhysValuesdx.get(),1);
1107  }
1108  else
1109  {
1110  Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.get(), 1);
1111  }
1112  }
1113  break;
1114  case 2:
1115  {
1116  Array<OneD,NekDouble> dPhysValuesdy(nquad);
1117 
1118  PhysDeriv(physValues, dPhysValuesdx, dPhysValuesdy);
1119 
1120  // multiply with the proper geometric factors
1121  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1122  {
1123  Vmath::Vmul (nquad,
1124  &gmat[0][0], 1, dPhysValuesdx.get(), 1,
1125  dPhysValuesdx.get(), 1);
1126  Vmath::Vvtvp(nquad,
1127  &gmat[1][0], 1, dPhysValuesdy.get(), 1,
1128  dPhysValuesdx.get(), 1,
1129  dPhysValuesdx.get(), 1);
1130  }
1131  else
1132  {
1133  Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.get(), 1);
1134  Blas::Daxpy(nquad,
1135  gmat[1][0], dPhysValuesdy.get(), 1,
1136  dPhysValuesdx.get(), 1);
1137  }
1138  }
1139  break;
1140  case 3:
1141  {
1142  Array<OneD,NekDouble> dPhysValuesdy(nquad);
1143  Array<OneD,NekDouble> dPhysValuesdz(nquad);
1144 
1145  PhysDeriv(physValues, dPhysValuesdx,
1146  dPhysValuesdy, dPhysValuesdz);
1147 
1148  // multiply with the proper geometric factors
1149  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1150  {
1151  Vmath::Vmul (nquad,
1152  &gmat[0][0], 1, dPhysValuesdx.get(), 1,
1153  dPhysValuesdx.get(), 1);
1154  Vmath::Vvtvp(nquad,
1155  &gmat[1][0], 1, dPhysValuesdy.get(), 1,
1156  dPhysValuesdx.get(), 1,
1157  dPhysValuesdx.get(), 1);
1158  Vmath::Vvtvp(nquad,
1159  &gmat[2][0], 1, dPhysValuesdz.get(), 1,
1160  dPhysValuesdx.get(), 1,
1161  dPhysValuesdx.get(), 1);
1162  }
1163  else
1164  {
1165  Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.get(), 1);
1166  Blas::Daxpy(nquad,
1167  gmat[1][0], dPhysValuesdy.get(), 1,
1168  dPhysValuesdx.get(), 1);
1169  Blas::Daxpy(nquad,
1170  gmat[2][0], dPhysValuesdz.get(),
1171  1, dPhysValuesdx.get(), 1);
1172  }
1173  }
1174  break;
1175  default:
1176  ASSERTL0(false,"Wrong number of dimensions");
1177  break;
1178  }
1179 
1180  v_IProductWRTBase(m_base[0]->GetDbdata(),dPhysValuesdx,outarray,1);
1181  Blas::Daxpy(m_ncoeffs, lambda, wsp.get(), 1, outarray.get(), 1);
1182  }
1183 
1184  //-----------------------------
1185  // Matrix creation functions
1186  //-----------------------------
1187 
1188 
1190  const MatrixKey &mkey)
1191  {
1192  return m_staticCondMatrixManager[mkey];
1193  }
1194 
1196  {
1197  m_staticCondMatrixManager.DeleteObject(mkey);
1198  }
1199 
1201  {
1202  return m_matrixManager[mkey];
1203  }
1204 
1205 
1207  const StdRegions::StdMatrixKey &mkey)
1208  {
1209  LibUtilities::BasisKey bkey = m_base[0]->GetBasisKey();
1212 
1213  return tmp->GetStdMatrix(mkey);
1214  }
1215 
1216 
1218  {
1219  DNekScalMatSharedPtr returnval;
1220  NekDouble fac;
1222 
1223  ASSERTL2(m_metricinfo->GetGtype() !=
1225  "Geometric information is not set up");
1226 
1227  switch (mkey.GetMatrixType())
1228  {
1229  case StdRegions::eMass:
1230  {
1231  if ((m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1232  || (mkey.GetNVarCoeff()))
1233  {
1234  fac = 1.0;
1235  goto UseLocRegionsMatrix;
1236  }
1237  else
1238  {
1239  fac = (m_metricinfo->GetJac(ptsKeys))[0];
1240  goto UseStdRegionsMatrix;
1241  }
1242  }
1243  break;
1244  case StdRegions::eInvMass:
1245  {
1246  if ((m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1247  || (mkey.GetNVarCoeff()))
1248  {
1249  NekDouble one = 1.0;
1250  StdRegions::StdMatrixKey masskey(
1251  StdRegions::eMass,DetShapeType(), *this);
1252  DNekMatSharedPtr mat = GenMatrix(masskey);
1253  mat->Invert();
1254 
1255  returnval = MemoryManager<DNekScalMat>::
1256  AllocateSharedPtr(one,mat);
1257  }
1258  else
1259  {
1260  fac = 1.0/(m_metricinfo->GetJac(ptsKeys))[0];
1261  goto UseStdRegionsMatrix;
1262  }
1263  }
1264  break;
1268  {
1269  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed ||
1270  mkey.GetNVarCoeff())
1271  {
1272  fac = 1.0;
1273  goto UseLocRegionsMatrix;
1274  }
1275  else
1276  {
1277  int dir = 0;
1278  switch(mkey.GetMatrixType())
1279  {
1281  dir = 0;
1282  break;
1284  ASSERTL1(m_geom->GetCoordim() >= 2,
1285  "Cannot call eWeakDeriv2 in a "
1286  "coordinate system which is not at "
1287  "least two-dimensional");
1288  dir = 1;
1289  break;
1291  ASSERTL1(m_geom->GetCoordim() == 3,
1292  "Cannot call eWeakDeriv2 in a "
1293  "coordinate system which is not "
1294  "three-dimensional");
1295  dir = 2;
1296  break;
1297  default:
1298  break;
1299  }
1300 
1302  mkey.GetShapeType(), *this);
1303 
1304  DNekMatSharedPtr WeakDerivStd = GetStdMatrix(deriv0key);
1305  fac = m_metricinfo->GetDerivFactors(ptsKeys)[dir][0]*
1306  m_metricinfo->GetJac(ptsKeys)[0];
1307 
1308  returnval = MemoryManager<DNekScalMat>::
1309  AllocateSharedPtr(fac,WeakDerivStd);
1310  }
1311  }
1312  break;
1314  {
1315  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1316  {
1317  fac = 1.0;
1318  goto UseLocRegionsMatrix;
1319  }
1320  else
1321  {
1322  int coordim = m_geom->GetCoordim();
1323  fac = 0.0;
1324  for (int i = 0; i < coordim; ++i)
1325  {
1326  fac += m_metricinfo->GetDerivFactors(ptsKeys)[i][0]*
1327  m_metricinfo->GetDerivFactors(ptsKeys)[i][0];
1328  }
1329  fac *= m_metricinfo->GetJac(ptsKeys)[0];
1330  goto UseStdRegionsMatrix;
1331  }
1332  }
1333  break;
1335  {
1336  NekDouble factor =
1338  MatrixKey masskey(StdRegions::eMass,
1339  mkey.GetShapeType(), *this);
1340  DNekScalMat &MassMat = *(this->m_matrixManager[masskey]);
1342  *this, mkey.GetConstFactors(),
1343  mkey.GetVarCoeffs());
1344  DNekScalMat &LapMat = *(this->m_matrixManager[lapkey]);
1345 
1346  int rows = LapMat.GetRows();
1347  int cols = LapMat.GetColumns();
1348 
1349  DNekMatSharedPtr helm =
1351 
1352  NekDouble one = 1.0;
1353  (*helm) = LapMat + factor*MassMat;
1354 
1355  returnval =
1357  }
1358  break;
1363  {
1364  NekDouble one = 1.0;
1365 
1366  DNekMatSharedPtr mat = GenMatrix(mkey);
1367  returnval =
1369  }
1370  break;
1372  {
1373  NekDouble one = 1.0;
1374 
1375 // StdRegions::StdMatrixKey hkey(StdRegions::eHybridDGHelmholtz,
1376 // DetShapeType(),*this,
1377 // mkey.GetConstant(0),
1378 // mkey.GetConstant(1));
1380  DetShapeType(),
1381  *this, mkey.GetConstFactors(),
1382  mkey.GetVarCoeffs());
1383  DNekMatSharedPtr mat = GenMatrix(hkey);
1384 
1385  mat->Invert();
1386  returnval =
1388  }
1389  break;
1391  {
1392  DNekMatSharedPtr m_Ix;
1393  Array<OneD, NekDouble> coords(1, 0.0);
1395  int vertex = (int)factors[StdRegions::eFactorGaussVertex];
1396 
1397  coords[0] = (vertex == 0) ? -1.0 : 1.0;
1398 
1399  m_Ix = m_base[0]->GetI(coords);
1400  returnval =
1402  }
1403  break;
1404 
1405  UseLocRegionsMatrix:
1406  {
1407  DNekMatSharedPtr mat = GenMatrix(mkey);
1408  returnval =
1410  }
1411  break;
1412  UseStdRegionsMatrix:
1413  {
1414  DNekMatSharedPtr mat = GetStdMatrix(mkey);
1415  returnval =
1417  }
1418  break;
1419  default:
1420  NEKERROR(ErrorUtil::efatal, "Matrix creation not defined");
1421  break;
1422  }
1423 
1424  return returnval;
1425  }
1426 
1428  const StdRegions::StdMatrixKey &mkey)
1429  {
1430  DNekMatSharedPtr returnval;
1431 
1432  switch (mkey.GetMatrixType())
1433  {
1440  returnval = Expansion1D::v_GenMatrix(mkey);
1441  break;
1442  default:
1443  returnval = StdSegExp::v_GenMatrix(mkey);
1444  break;
1445  }
1446 
1447  return returnval;
1448  }
1449 
1450 
1452  const MatrixKey &mkey)
1453  {
1454  DNekScalBlkMatSharedPtr returnval;
1455 
1456  ASSERTL2(m_metricinfo->GetGtype() !=
1458  "Geometric information is not set up");
1459 
1460  // set up block matrix system
1461  int nbdry = NumBndryCoeffs();
1462  int nint = m_ncoeffs - nbdry;
1463  Array<OneD, unsigned int> exp_size(2);
1464  exp_size[0] = nbdry;
1465  exp_size[1] = nint;
1466 
1467  /// \todo Really need a constructor which takes Arrays
1469  AllocateSharedPtr(exp_size,exp_size);
1470  NekDouble factor = 1.0;
1471 
1472  switch (mkey.GetMatrixType())
1473  {
1475  case StdRegions::eHelmholtz: // special case since Helmholtz
1476  // not defined in StdRegions
1477 
1478  // use Deformed case for both regular and deformed geometries
1479  factor = 1.0;
1480  goto UseLocRegionsMatrix;
1481  break;
1482  default:
1483  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1484  {
1485  factor = 1.0;
1486  goto UseLocRegionsMatrix;
1487  }
1488  else
1489  {
1490  DNekScalMatSharedPtr mat = GetLocMatrix(mkey);
1491  factor = mat->Scale();
1492  goto UseStdRegionsMatrix;
1493  }
1494  break;
1495  UseStdRegionsMatrix:
1496  {
1497  NekDouble invfactor = 1.0/factor;
1498  NekDouble one = 1.0;
1500  DNekScalMatSharedPtr Atmp;
1501  DNekMatSharedPtr Asubmat;
1502 
1503  returnval->SetBlock(0,0,Atmp =
1505  factor,Asubmat = mat->GetBlock(0,0)));
1506  returnval->SetBlock(0,1,Atmp =
1508  one,Asubmat = mat->GetBlock(0,1)));
1509  returnval->SetBlock(1,0,Atmp =
1511  factor,Asubmat = mat->GetBlock(1,0)));
1512  returnval->SetBlock(1,1,Atmp =
1514  invfactor,Asubmat = mat->GetBlock(1,1)));
1515  }
1516  break;
1517  UseLocRegionsMatrix:
1518  {
1519  int i,j;
1520  NekDouble invfactor = 1.0/factor;
1521  NekDouble one = 1.0;
1522  DNekScalMat &mat = *GetLocMatrix(mkey);
1525  DNekMatSharedPtr B =
1527  DNekMatSharedPtr C =
1529  DNekMatSharedPtr D =
1531 
1532  Array<OneD,unsigned int> bmap(nbdry);
1533  Array<OneD,unsigned int> imap(nint);
1534  GetBoundaryMap(bmap);
1535  GetInteriorMap(imap);
1536 
1537  for (i = 0; i < nbdry; ++i)
1538  {
1539  for (j = 0; j < nbdry; ++j)
1540  {
1541  (*A)(i,j) = mat(bmap[i],bmap[j]);
1542  }
1543 
1544  for (j = 0; j < nint; ++j)
1545  {
1546  (*B)(i,j) = mat(bmap[i],imap[j]);
1547  }
1548  }
1549 
1550  for (i = 0; i < nint; ++i)
1551  {
1552  for (j = 0; j < nbdry; ++j)
1553  {
1554  (*C)(i,j) = mat(imap[i],bmap[j]);
1555  }
1556 
1557  for (j = 0; j < nint; ++j)
1558  {
1559  (*D)(i,j) = mat(imap[i],imap[j]);
1560  }
1561  }
1562 
1563  // Calculate static condensed system
1564  if (nint)
1565  {
1566  D->Invert();
1567  (*B) = (*B)*(*D);
1568  (*A) = (*A) - (*B)*(*C);
1569  }
1570 
1571  DNekScalMatSharedPtr Atmp;
1572 
1573  returnval->SetBlock(0,0,Atmp = MemoryManager<DNekScalMat>::
1574  AllocateSharedPtr(factor,A));
1575  returnval->SetBlock(0,1,Atmp = MemoryManager<DNekScalMat>::
1576  AllocateSharedPtr(one,B));
1577  returnval->SetBlock(1,0,Atmp = MemoryManager<DNekScalMat>::
1578  AllocateSharedPtr(factor,C));
1579  returnval->SetBlock(1,1,Atmp = MemoryManager<DNekScalMat>::
1580  AllocateSharedPtr(invfactor,D));
1581  }
1582  }
1583 
1584 
1585  return returnval;
1586  }
1587 
1588 
1589  //-----------------------------
1590  // Private methods
1591  //-----------------------------
1592 
1593 
1594  /// Reverse the coefficients in a boundary interior expansion
1595  /// this routine is of use when we need the segment
1596  /// coefficients corresponding to a expansion in the reverse
1597  /// coordinate direction
1599  const Array<OneD,NekDouble> &inarray,
1600  Array<OneD,NekDouble> &outarray)
1601  {
1602 
1603  int m;
1604  NekDouble sgn = 1;
1605 
1606  ASSERTL1(&inarray[0] != &outarray[0],
1607  "inarray and outarray can not be the same");
1608  switch(GetBasisType(0))
1609  {
1611  //Swap vertices
1612  outarray[0] = inarray[1];
1613  outarray[1] = inarray[0];
1614  // negate odd modes
1615  for(m = 2; m < m_ncoeffs; ++m)
1616  {
1617  outarray[m] = sgn*inarray[m];
1618  sgn = -sgn;
1619  }
1620  break;
1623  for(m = 0; m < m_ncoeffs; ++m)
1624  {
1625  outarray[m_ncoeffs-1-m] = inarray[m];
1626  }
1627  break;
1628  default:
1629  ASSERTL0(false,"This basis is not allowed in this method");
1630  break;
1631  }
1632  }
1633 
1634  /* \brief Mass inversion product from \a inarray to \a outarray
1635  *
1636  * Multiply by the inverse of the mass matrix
1637  * \f$ {\bf \hat{u}} = {\bf M}^{-1} {\bf I} \f$
1638  *
1639  **/
1641  const Array<OneD, const NekDouble>& inarray,
1642  Array<OneD,NekDouble> &outarray)
1643  {
1644  // get Mass matrix inverse
1646  DetShapeType(),*this);
1647  DNekScalMatSharedPtr matsys = m_matrixManager[masskey];
1648 
1649  NekVector<NekDouble> in(m_ncoeffs,inarray,eCopy);
1650  NekVector<NekDouble> out(m_ncoeffs,outarray,eWrapper);
1651 
1652  out = (*matsys)*in;
1653  }
1654 
1655 
1656  } // end of namespace
1657 }//end of namespace
1658 
virtual int v_GetNcoeffs(void) const
Definition: SegExp.cpp:824
virtual DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix(const MatrixKey &mkey)
Definition: SegExp.cpp:1189
const VarCoeffMap & GetVarCoeffs() const
Definition: StdMatrixKey.h:161
DNekMatSharedPtr GenMatrix(const StdMatrixKey &mkey)
#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 mod...
Definition: ErrorUtil.hpp:209
virtual void v_GetCoord(const Array< OneD, const NekDouble > &Lcoords, Array< OneD, NekDouble > &coords)
Definition: SegExp.cpp:682
std::vector< PointsKey > PointsKeyVector
Definition: Points.h:246
void v_DropLocStaticCondMatrix(const MatrixKey &mkey)
Definition: SegExp.cpp:1195
void MassMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
Definition: StdExpansion.h:974
static Array< OneD, NekDouble > NullNekDouble1DArray
LibUtilities::ShapeType DetShapeType() const
This function returns the shape of the expansion domain.
Definition: StdExpansion.h:469
LibUtilities::NekManager< MatrixKey, DNekScalBlkMat, MatrixKey::opLess > m_staticCondMatrixManager
Definition: SegExp.h:249
int GetNumPoints(const int dir) const
This function returns the number of quadrature points in the dir direction.
Definition: StdExpansion.h:228
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey)
Definition: Expansion1D.cpp:61
virtual NekDouble v_StdPhysEvaluate(const Array< OneD, const NekDouble > &Lcoord, const Array< OneD, const NekDouble > &physvals)
Definition: SegExp.cpp:661
virtual int v_NumDGBndryCoeffs() const
Definition: SegExp.cpp:841
std::map< int, NormalVector > m_vertexNormals
SpatialDomains::GeometrySharedPtr GetGeom() const
Definition: Expansion.cpp:167
std::shared_ptr< GeomFactors > GeomFactorsSharedPtr
Pointer to a GeomFactors object.
Definition: GeomFactors.h:62
virtual void v_HelmholtzMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey)
Definition: SegExp.cpp:1074
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
virtual void v_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...
Definition: SegExp.cpp:377
virtual void v_PhysDeriv_n(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_dn)
Evaluate the derivative normal to a line: . The derivative is calculated performing the product ...
Definition: SegExp.cpp:269
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
Principle Modified Functions .
Definition: BasisType.h:48
void NormVectorIProductWRTBase(const Array< OneD, const NekDouble > &Fx, Array< OneD, NekDouble > &outarray)
Definition: StdExpansion.h:741
SpatialDomains::GeomFactorsSharedPtr m_metricinfo
Definition: Expansion.h:128
Lagrange Polynomials using the Gauss points .
Definition: BasisType.h:55
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: SegExp.cpp:743
STL namespace.
virtual void v_ExtractDataToCoeffs(const NekDouble *data, const std::vector< unsigned int > &nummodes, const int mode_offset, NekDouble *coeffs, std::vector< LibUtilities::BasisType > &fromType)
Unpack data from input file assuming it comes from.
Definition: SegExp.cpp:849
std::map< ConstFactorType, NekDouble > ConstFactorMap
Definition: StdRegions.hpp:294
StdSegExp()
Default constructor.
Definition: StdSegExp.cpp:50
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:69
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:244
SpatialDomains::GeometrySharedPtr m_geom
Definition: Expansion.h:127
virtual void v_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: SegExp.cpp:506
MatrixType GetMatrixType() const
Definition: StdMatrixKey.h:81
virtual void v_PhysDeriv_s(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_ds)
Evaluate the derivative along a line: . The derivative is calculated performing the product ...
Definition: SegExp.cpp:229
std::shared_ptr< Basis > BasisSharedPtr
std::shared_ptr< DNekBlkMat > DNekBlkMatSharedPtr
Definition: NekTypeDefs.hpp:71
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)
virtual void v_NormVectorIProductWRTBase(const Array< OneD, const NekDouble > &Fx, const Array< OneD, const NekDouble > &Fy, Array< OneD, NekDouble > &outarray)
Definition: SegExp.cpp:624
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:714
1D Gauss-Gauss-Legendre quadrature points
Definition: PointsType.h:48
1D Evenly-spaced points using Lagrange polynomial
Definition: PointsType.h:64
const LibUtilities::PointsKeyVector GetPointsKeys() const
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
DNekBlkMatSharedPtr GetStdStaticCondMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:719
int GetVertexMap(const int localVertexId, bool useCoeffPacking=false)
Definition: StdExpansion.h:822
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
virtual StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const
Definition: SegExp.cpp:794
void ReverseCoeffsAndSign(const Array< OneD, NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Reverse the coefficients in a boundary interior expansion this routine is of use when we need the seg...
Definition: SegExp.cpp:1598
const LibUtilities::BasisSharedPtr & GetBasis(int dir) const
This function gets the shared point to basis in the dir direction.
Definition: StdExpansion.h:117
virtual SpatialDomains::GeomType v_MetricInfoType()
Definition: SegExp.cpp:814
virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey)
Definition: SegExp.cpp:1427
Principle Modified Functions .
Definition: BasisType.h:49
virtual void v_ComputeVertexNormal(const int vertex)
Definition: SegExp.cpp:902
virtual void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3)
Definition: Expansion.cpp:231
virtual StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const
Definition: SegExp.cpp:788
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
virtual int v_NumBndryCoeffs() const
Definition: SegExp.cpp:835
Defines a specification for a set of points.
Definition: Points.h:59
double NekDouble
virtual const LibUtilities::BasisSharedPtr & v_GetBasis(int dir) const
Definition: SegExp.cpp:829
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 const Array< OneD, const NekDouble > & v_GetPhysNormals(void)
Definition: SegExp.cpp:808
DNekScalBlkMatSharedPtr CreateStaticCondMatrix(const MatrixKey &mkey)
Definition: SegExp.cpp:1451
virtual void v_FwdTrans_BndConstrained(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: SegExp.cpp:401
virtual void v_LaplacianMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey)
Definition: SegExp.cpp:966
DNekScalMatSharedPtr CreateMatrix(const MatrixKey &mkey)
Definition: SegExp.cpp:1217
NekDouble GetConstFactor(const ConstFactorType &factor) const
Definition: StdMatrixKey.h:121
virtual int v_GetNumPoints(const int dir) const
Definition: SegExp.cpp:819
virtual DNekScalMatSharedPtr v_GetLocMatrix(const MatrixKey &mkey)
Definition: SegExp.cpp:1200
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:346
virtual void v_GetVertexPhysVals(const int vertex, const Array< OneD, const NekDouble > &inarray, NekDouble &outarray)
Definition: SegExp.cpp:707
DNekScalMatSharedPtr GetLocMatrix(const LocalRegions::MatrixKey &mkey)
Definition: Expansion.cpp:85
static void Dscal(const int &n, const double &alpha, double *x, const int &incx)
BLAS level 1: x = alpha x.
Definition: Blas.hpp:125
const NormalVector & GetEdgeNormal(const int edge) const
const ConstFactorMap & GetConstFactors() const
Definition: StdMatrixKey.h:135
static double Ddot(const int &n, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: output = .
Definition: Blas.hpp:140
virtual void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3)
Definition: SegExp.cpp:698
LibUtilities::PointsType GetPointsType(const int dir) const
This function returns the type of quadrature points used in the dir direction.
Definition: StdExpansion.h:215
virtual void v_SetCoeffsToOrientation(Array< OneD, NekDouble > &coeffs, StdRegions::Orientation dir)
Definition: SegExp.cpp:761
void PhysTensorDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Evaluate the derivative at the physical quadrature points given by inarray and return in outarray...
void MultiplyByElmtInvMass(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: SegExp.cpp:1640
#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
virtual void v_PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1=NullNekDouble1DArray, Array< OneD, NekDouble > &out_d2=NullNekDouble1DArray)
Evaluate the derivative at the physical quadrature points given by inarray and return in outarray...
Definition: SegExp.cpp:166
void BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function performs the Backward transformation from coefficient space to physical space...
Definition: StdExpansion.h:530
virtual int v_GetCoordim()
Definition: SegExp.cpp:803
virtual NekDouble v_Integral(const Array< OneD, const NekDouble > &inarray)
Integrate the physical point list inarray over region and return the value.
Definition: SegExp.cpp:118
std::shared_ptr< Geometry1D > Geometry1DSharedPtr
Definition: Geometry.h:63
StdExpansion()
Default Constructor.
virtual DNekMatSharedPtr v_CreateStdMatrix(const StdRegions::StdMatrixKey &mkey)
Definition: SegExp.cpp:1206
GeomType
Indicates the type of element geometry.
Expansion2DSharedPtr GetLeftAdjacentElementExp() const
Definition: Expansion1D.h:127
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayofArray
Lagrange for SEM basis .
Definition: BasisType.h:54
std::shared_ptr< StdSegExp > StdSegExpSharedPtr
Definition: StdSegExp.h:46
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:376
virtual void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: SegExp.cpp:565
#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.
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
virtual NekDouble v_PhysEvaluate(const Array< OneD, const NekDouble > &coord, const Array< OneD, const NekDouble > &physvals)
Definition: SegExp.cpp:669
1D Gauss-Lobatto-Legendre quadrature points
Definition: PointsType.h:51
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
LibUtilities::NekManager< MatrixKey, DNekScalMat, MatrixKey::opLess > m_matrixManager
Definition: SegExp.h:247