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),
86  m_matrixManager(S.m_matrixManager),
87  m_staticCondMatrixManager(S.m_staticCondMatrixManager)
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.size())
182  {
183  Vmath::Vmul(nquad0,&gmat[0][0],1,&diff[0],1,
184  &out_d0[0],1);
185  }
186 
187  if(out_d1.size())
188  {
189  Vmath::Vmul(nquad0,&gmat[1][0],1,&diff[0],1,
190  &out_d1[0],1);
191  }
192 
193  if(out_d2.size())
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.size())
202  {
203  Vmath::Smul(nquad0, gmat[0][0], diff, 1,
204  out_d0, 1);
205  }
206 
207  if(out_d1.size())
208  {
209  Vmath::Smul(nquad0, gmat[1][0], diff, 1,
210  out_d1, 1);
211  }
212 
213  if(out_d2.size())
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 
632  // @TODO: This routine no longer makes sense as a normal is not unique to an edge
634  &normals =
637  Vmath::Vmul (nq, &Fx[0], 1, &normals[0][0], 1, &Fn[0], 1);
638  Vmath::Vvtvp(nq, &Fy[0], 1, &normals[1][0], 1, &Fn[0], 1, &Fn[0], 1);
639 
640  v_IProductWRTBase(Fn,outarray);
641  }
642 
644  const Array<OneD, const Array<OneD, NekDouble> > &Fvec,
645  Array<OneD, NekDouble> &outarray)
646  {
647  NormVectorIProductWRTBase(Fvec[0], Fvec[1], outarray);
648  }
649 
650  //-----------------------------
651  // Evaluation functions
652  //-----------------------------
653 
654 
655  /**
656  * Given the local cartesian coordinate \a Lcoord evaluate the
657  * value of physvals at this point by calling through to the
658  * StdExpansion method
659  */
661  const Array<OneD, const NekDouble> &Lcoord,
662  const Array<OneD, const NekDouble> &physvals)
663  {
664  // Evaluate point in local (eta) coordinates.
665  return StdSegExp::v_PhysEvaluate(Lcoord,physvals);
666  }
667 
669  const Array<OneD, const NekDouble>& coord,
670  const Array<OneD, const NekDouble> &physvals)
671  {
673 
674  ASSERTL0(m_geom,"m_geom not defined");
675  m_geom->GetLocCoords(coord,Lcoord);
676 
677  return StdSegExp::v_PhysEvaluate(Lcoord, physvals);
678  }
679 
680 
682  const Array<OneD, const NekDouble>& Lcoords,
683  Array<OneD,NekDouble> &coords)
684  {
685  int i;
686 
687  ASSERTL1(Lcoords[0] >= -1.0&& Lcoords[0] <= 1.0,
688  "Local coordinates are not in region [-1,1]");
689 
690  m_geom->FillGeom();
691  for(i = 0; i < m_geom->GetCoordim(); ++i)
692  {
693  coords[i] = m_geom->GetCoord(i,Lcoords);
694  }
695  }
696 
698  Array<OneD, NekDouble> &coords_0,
699  Array<OneD, NekDouble> &coords_1,
700  Array<OneD, NekDouble> &coords_2)
701  {
702  Expansion::v_GetCoords(coords_0, coords_1, coords_2);
703  }
704 
705  // Get vertex value from the 1D Phys space.
707  const int vertex,
708  const Array<OneD, const NekDouble> &inarray,
709  NekDouble &outarray)
710  {
711  int nquad = m_base[0]->GetNumPoints();
712 
714  {
715  switch (vertex)
716  {
717  case 0:
718  outarray = inarray[0];
719  break;
720  case 1:
721  outarray = inarray[nquad - 1];
722  break;
723  }
724  }
725  else
726  {
728  factors[StdRegions::eFactorGaussVertex] = vertex;
729 
732  DetShapeType(),*this,factors);
733 
734  DNekScalMatSharedPtr mat_gauss = m_matrixManager[key];
735 
736  outarray = Blas::Ddot(nquad, mat_gauss->GetOwnedMatrix()
737  ->GetPtr().get(), 1, &inarray[0], 1);
738  }
739  }
740 
741  // Add vertex value of the 1D Phys space to outarray.
743  const int vertex,
744  const NekDouble &inarray,
745  Array<OneD, NekDouble> &outarray)
746  {
747  size_t nquad = m_base[0]->GetNumPoints();
748 
750  {
751  switch (vertex)
752  {
753  case 0:
754  outarray[0] += inarray;
755  break;
756  case 1:
757  outarray[nquad - 1] += inarray;
758  break;
759  }
760  }
761  else
762  {
764  factors[StdRegions::eFactorGaussVertex] = vertex;
765 
768  DetShapeType(),*this,factors);
769 
770  DNekScalMatSharedPtr mat_gauss = m_matrixManager[key];
771 
772  Vmath::Svtvp(nquad,inarray,
773  mat_gauss->GetOwnedMatrix()->GetPtr().get(), 1,
774  &outarray[0], 1, &outarray[0], 1);
775  }
776  }
777  // Get vertex value from the 1D Phys space.
779  const int edge,
780  const StdRegions::StdExpansionSharedPtr &EdgeExp,
781  const Array<OneD, const NekDouble> &inarray,
782  Array<OneD, NekDouble> &outarray,
784  {
785  boost::ignore_unused(EdgeExp, orient);
786 
787  NekDouble result;
788  v_GetVertexPhysVals(edge, inarray, result);
789  outarray[0] = result;
790  }
791 
792  // Get vertex map from the 1D Phys space.
794  const int vertex,
795  Array<OneD, int> &map)
796  {
797  int nquad = m_base[0]->GetNumPoints();
798 
799  ASSERTL1(vertex == 0 || vertex == 1,
800  "Vertex value should be 0 or 1");
801 
802  map = Array<OneD, int>(1);
803 
804  map[0] = vertex == 0 ? 0: nquad - 1;
805  }
806 
807  //-----------------------------
808  // Helper functions
809  //-----------------------------
810 
814  Array<OneD, NekDouble> &outarray)
815  {
816 
817  if (dir == StdRegions::eBackwards)
818  {
819  if (&inarray[0] != &outarray[0])
820  {
821  Array<OneD,NekDouble> intmp (inarray);
822  ReverseCoeffsAndSign(intmp,outarray);
823  }
824  else
825  {
826  ReverseCoeffsAndSign(inarray,outarray);
827  }
828  }
829  }
830 
832  {
834  ::AllocateSharedPtr(m_base[0]->GetBasisKey());
835  }
836 
838  {
840  2, m_base[0]->GetPointsKey());
841 
843  ::AllocateSharedPtr( bkey0);
844  }
845 
847  {
848  return m_geom->GetCoordim();
849  }
850 
852  {
853  NEKERROR(ErrorUtil::efatal, "Got to SegExp");
854  return NullNekDouble1DArray;
855  }
856 
858  {
859  return m_metricinfo->GetGtype();
860  }
861 
862  int SegExp::v_GetNumPoints(const int dir) const
863  {
864  return GetNumPoints(dir);
865  }
866 
867  int SegExp::v_GetNcoeffs(void) const
868  {
869  return m_ncoeffs;
870  }
871 
873  {
874  return GetBasis(dir);
875  }
876 
877 
879  {
880  return 2;
881  }
882 
883 
885  {
886  return 2;
887  }
888 
889 
890  /// Unpack data from input file assuming it comes from
891  // the same expansion type
893  const NekDouble *data,
894  const std::vector<unsigned int > &nummodes,
895  const int mode_offset,
896  NekDouble *coeffs,
897  std::vector<LibUtilities::BasisType> &fromType)
898  {
899  boost::ignore_unused(fromType);
900 
901  switch(m_base[0]->GetBasisType())
902  {
904  {
905  int fillorder = min((int) nummodes[mode_offset],m_ncoeffs);
906 
907  Vmath::Zero(m_ncoeffs,coeffs,1);
908  Vmath::Vcopy(fillorder,&data[0],1,&coeffs[0],1);
909  }
910  break;
912  {
913  // Assume that input is also Gll_Lagrange
914  // but no way to check;
916  nummodes[mode_offset],
919  m_base[0]->GetNumModes(),
922  f0,data, t0, coeffs);
923  }
924  break;
926  {
927  // Assume that input is also Gauss_Lagrange
928  // but no way to check;
930  nummodes[mode_offset],
933  m_base[0]->GetNumModes(),
936  f0,data, t0, coeffs);
937  }
938  break;
939  default:
940  ASSERTL0(false,
941  "basis is either not set up or not hierarchicial");
942  }
943  }
944 
945  void SegExp::v_ComputeTraceNormal(const int vertex)
946  {
947  int i;
948  const SpatialDomains::GeomFactorsSharedPtr &geomFactors =
949  GetGeom()->GetMetricInfo();
950  SpatialDomains::GeomType type = geomFactors->GetGtype();
951  const Array<TwoD, const NekDouble> &gmat =
952  geomFactors->GetDerivFactors(GetPointsKeys());
953  int nqe = 1;
954  int vCoordDim = GetCoordim();
955 
956  m_vertexNormals[vertex] =
959  m_vertexNormals[vertex];
960  for (i = 0; i < vCoordDim; ++i)
961  {
962  normal[i] = Array<OneD, NekDouble>(nqe);
963  }
964 
965 
966  size_t nqb = nqe;
967  size_t nbnd= vertex;
970 
971  // Regular geometry case
972  if ((type == SpatialDomains::eRegular) ||
974  {
975  NekDouble vert;
976  // Set up normals
977  switch (vertex)
978  {
979  case 0:
980  for(i = 0; i < vCoordDim; ++i)
981  {
982  Vmath::Fill(nqe, -gmat[i][0], normal[i], 1);
983  }
984  break;
985  case 1:
986  for(i = 0; i < vCoordDim; ++i)
987  {
988  Vmath::Fill(nqe, gmat[i][0], normal[i], 1);
989  }
990  break;
991  default:
992  ASSERTL0(false,
993  "point is out of range (point < 2)");
994  }
995 
996  // normalise
997  vert = 0.0;
998  for (i =0 ; i < vCoordDim; ++i)
999  {
1000  vert += normal[i][0]*normal[i][0];
1001  }
1002  vert = 1.0/sqrt(vert);
1003 
1004  Vmath::Fill(nqb, vert, length, 1);
1005 
1006  for (i = 0; i < vCoordDim; ++i)
1007  {
1008  Vmath::Smul(nqe, vert, normal[i], 1, normal[i], 1);
1009  }
1010  }
1011  }
1012 
1013  //-----------------------------
1014  // Operator creation functions
1015  //-----------------------------
1016 
1017 
1019  const Array<OneD, const NekDouble> &inarray,
1020  Array<OneD, NekDouble> &outarray,
1021  const StdRegions::StdMatrixKey &mkey)
1022  {
1023  boost::ignore_unused(mkey);
1024 
1025  int nquad = m_base[0]->GetNumPoints();
1026  const Array<TwoD, const NekDouble>& gmat =
1027  m_metricinfo->GetDerivFactors(GetPointsKeys());
1028 
1029  Array<OneD,NekDouble> physValues(nquad);
1030  Array<OneD,NekDouble> dPhysValuesdx(nquad);
1031 
1032  BwdTrans(inarray,physValues);
1033 
1034  // Laplacian matrix operation
1035  switch (m_geom->GetCoordim())
1036  {
1037  case 1:
1038  {
1039  PhysDeriv(physValues,dPhysValuesdx);
1040 
1041  // multiply with the proper geometric factors
1042  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1043  {
1044  Vmath::Vmul(nquad,
1045  &gmat[0][0],1,dPhysValuesdx.get(),1,
1046  dPhysValuesdx.get(),1);
1047  }
1048  else
1049  {
1050  Blas::Dscal(nquad,
1051  gmat[0][0], dPhysValuesdx.get(), 1);
1052  }
1053  }
1054  break;
1055  case 2:
1056  {
1057  Array<OneD,NekDouble> dPhysValuesdy(nquad);
1058 
1059  PhysDeriv(physValues,dPhysValuesdx,dPhysValuesdy);
1060 
1061  // multiply with the proper geometric factors
1062  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1063  {
1064  Vmath::Vmul (nquad,
1065  &gmat[0][0],1,dPhysValuesdx.get(),1,
1066  dPhysValuesdx.get(),1);
1067  Vmath::Vvtvp(nquad,
1068  &gmat[1][0],1,dPhysValuesdy.get(),1,
1069  dPhysValuesdx.get(),1,
1070  dPhysValuesdx.get(),1);
1071  }
1072  else
1073  {
1074  Blas::Dscal(nquad,
1075  gmat[0][0], dPhysValuesdx.get(), 1);
1076  Blas::Daxpy(nquad,
1077  gmat[1][0], dPhysValuesdy.get(), 1,
1078  dPhysValuesdx.get(), 1);
1079  }
1080  }
1081  break;
1082  case 3:
1083  {
1084  Array<OneD,NekDouble> dPhysValuesdy(nquad);
1085  Array<OneD,NekDouble> dPhysValuesdz(nquad);
1086 
1087  PhysDeriv(physValues,dPhysValuesdx,
1088  dPhysValuesdy,dPhysValuesdz);
1089 
1090  // multiply with the proper geometric factors
1091  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1092  {
1093  Vmath::Vmul (nquad,
1094  &gmat[0][0], 1, dPhysValuesdx.get(), 1,
1095  dPhysValuesdx.get(),1);
1096  Vmath::Vvtvp(nquad,
1097  &gmat[1][0], 1, dPhysValuesdy.get(), 1,
1098  dPhysValuesdx.get(),1,
1099  dPhysValuesdx.get(),1);
1100  Vmath::Vvtvp(nquad,
1101  &gmat[2][0], 1, dPhysValuesdz.get(), 1,
1102  dPhysValuesdx.get(),1,
1103  dPhysValuesdx.get(),1);
1104  }
1105  else
1106  {
1107  Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.get(), 1);
1108  Blas::Daxpy(nquad,
1109  gmat[1][0], dPhysValuesdy.get(), 1,
1110  dPhysValuesdx.get(), 1);
1111  Blas::Daxpy(nquad,
1112  gmat[2][0], dPhysValuesdz.get(), 1,
1113  dPhysValuesdx.get(), 1);
1114  }
1115  }
1116  break;
1117  default:
1118  ASSERTL0(false,"Wrong number of dimensions");
1119  break;
1120  }
1121 
1122  v_IProductWRTBase(m_base[0]->GetDbdata(),dPhysValuesdx,outarray,1);
1123  }
1124 
1125 
1127  const Array<OneD, const NekDouble> &inarray,
1128  Array<OneD, NekDouble> &outarray,
1129  const StdRegions::StdMatrixKey &mkey)
1130  {
1131  int nquad = m_base[0]->GetNumPoints();
1132  const Array<TwoD, const NekDouble>& gmat =
1133  m_metricinfo->GetDerivFactors(GetPointsKeys());
1134  const NekDouble lambda =
1136 
1137  Array<OneD,NekDouble> physValues(nquad);
1138  Array<OneD,NekDouble> dPhysValuesdx(nquad);
1140 
1141  BwdTrans(inarray, physValues);
1142 
1143  // mass matrix operation
1144  v_IProductWRTBase((m_base[0]->GetBdata()),physValues,wsp,1);
1145 
1146  // Laplacian matrix operation
1147  switch (m_geom->GetCoordim())
1148  {
1149  case 1:
1150  {
1151  PhysDeriv(physValues,dPhysValuesdx);
1152 
1153  // multiply with the proper geometric factors
1154  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1155  {
1156  Vmath::Vmul(nquad,
1157  &gmat[0][0],1,dPhysValuesdx.get(),1,
1158  dPhysValuesdx.get(),1);
1159  }
1160  else
1161  {
1162  Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.get(), 1);
1163  }
1164  }
1165  break;
1166  case 2:
1167  {
1168  Array<OneD,NekDouble> dPhysValuesdy(nquad);
1169 
1170  PhysDeriv(physValues, dPhysValuesdx, dPhysValuesdy);
1171 
1172  // multiply with the proper geometric factors
1173  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1174  {
1175  Vmath::Vmul (nquad,
1176  &gmat[0][0], 1, dPhysValuesdx.get(), 1,
1177  dPhysValuesdx.get(), 1);
1178  Vmath::Vvtvp(nquad,
1179  &gmat[1][0], 1, dPhysValuesdy.get(), 1,
1180  dPhysValuesdx.get(), 1,
1181  dPhysValuesdx.get(), 1);
1182  }
1183  else
1184  {
1185  Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.get(), 1);
1186  Blas::Daxpy(nquad,
1187  gmat[1][0], dPhysValuesdy.get(), 1,
1188  dPhysValuesdx.get(), 1);
1189  }
1190  }
1191  break;
1192  case 3:
1193  {
1194  Array<OneD,NekDouble> dPhysValuesdy(nquad);
1195  Array<OneD,NekDouble> dPhysValuesdz(nquad);
1196 
1197  PhysDeriv(physValues, dPhysValuesdx,
1198  dPhysValuesdy, dPhysValuesdz);
1199 
1200  // multiply with the proper geometric factors
1201  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1202  {
1203  Vmath::Vmul (nquad,
1204  &gmat[0][0], 1, dPhysValuesdx.get(), 1,
1205  dPhysValuesdx.get(), 1);
1206  Vmath::Vvtvp(nquad,
1207  &gmat[1][0], 1, dPhysValuesdy.get(), 1,
1208  dPhysValuesdx.get(), 1,
1209  dPhysValuesdx.get(), 1);
1210  Vmath::Vvtvp(nquad,
1211  &gmat[2][0], 1, dPhysValuesdz.get(), 1,
1212  dPhysValuesdx.get(), 1,
1213  dPhysValuesdx.get(), 1);
1214  }
1215  else
1216  {
1217  Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.get(), 1);
1218  Blas::Daxpy(nquad,
1219  gmat[1][0], dPhysValuesdy.get(), 1,
1220  dPhysValuesdx.get(), 1);
1221  Blas::Daxpy(nquad,
1222  gmat[2][0], dPhysValuesdz.get(),
1223  1, dPhysValuesdx.get(), 1);
1224  }
1225  }
1226  break;
1227  default:
1228  ASSERTL0(false,"Wrong number of dimensions");
1229  break;
1230  }
1231 
1232  v_IProductWRTBase(m_base[0]->GetDbdata(),dPhysValuesdx,outarray,1);
1233  Blas::Daxpy(m_ncoeffs, lambda, wsp.get(), 1, outarray.get(), 1);
1234  }
1235 
1236  //-----------------------------
1237  // Matrix creation functions
1238  //-----------------------------
1239 
1240 
1242  const MatrixKey &mkey)
1243  {
1244  return m_staticCondMatrixManager[mkey];
1245  }
1246 
1248  {
1249  m_staticCondMatrixManager.DeleteObject(mkey);
1250  }
1251 
1253  {
1254  return m_matrixManager[mkey];
1255  }
1256 
1257 
1259  const StdRegions::StdMatrixKey &mkey)
1260  {
1261  LibUtilities::BasisKey bkey = m_base[0]->GetBasisKey();
1264 
1265  return tmp->GetStdMatrix(mkey);
1266  }
1267 
1268 
1270  {
1271  DNekScalMatSharedPtr returnval;
1272  NekDouble fac;
1274 
1275  ASSERTL2(m_metricinfo->GetGtype() !=
1277  "Geometric information is not set up");
1278 
1279  switch (mkey.GetMatrixType())
1280  {
1281  case StdRegions::eMass:
1282  {
1283  if ((m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1284  || (mkey.GetNVarCoeff()))
1285  {
1286  fac = 1.0;
1287  goto UseLocRegionsMatrix;
1288  }
1289  else
1290  {
1291  fac = (m_metricinfo->GetJac(ptsKeys))[0];
1292  goto UseStdRegionsMatrix;
1293  }
1294  }
1295  break;
1296  case StdRegions::eInvMass:
1297  {
1298  if ((m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1299  || (mkey.GetNVarCoeff()))
1300  {
1301  NekDouble one = 1.0;
1302  StdRegions::StdMatrixKey masskey(
1303  StdRegions::eMass,DetShapeType(), *this);
1304  DNekMatSharedPtr mat = GenMatrix(masskey);
1305  mat->Invert();
1306 
1307  returnval = MemoryManager<DNekScalMat>::
1308  AllocateSharedPtr(one,mat);
1309  }
1310  else
1311  {
1312  fac = 1.0/(m_metricinfo->GetJac(ptsKeys))[0];
1313  goto UseStdRegionsMatrix;
1314  }
1315  }
1316  break;
1320  {
1321  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed ||
1322  mkey.GetNVarCoeff())
1323  {
1324  fac = 1.0;
1325  goto UseLocRegionsMatrix;
1326  }
1327  else
1328  {
1329  int dir = 0;
1330  switch(mkey.GetMatrixType())
1331  {
1333  dir = 0;
1334  break;
1336  ASSERTL1(m_geom->GetCoordim() >= 2,
1337  "Cannot call eWeakDeriv2 in a "
1338  "coordinate system which is not at "
1339  "least two-dimensional");
1340  dir = 1;
1341  break;
1343  ASSERTL1(m_geom->GetCoordim() == 3,
1344  "Cannot call eWeakDeriv2 in a "
1345  "coordinate system which is not "
1346  "three-dimensional");
1347  dir = 2;
1348  break;
1349  default:
1350  break;
1351  }
1352 
1354  mkey.GetShapeType(), *this);
1355 
1356  DNekMatSharedPtr WeakDerivStd = GetStdMatrix(deriv0key);
1357  fac = m_metricinfo->GetDerivFactors(ptsKeys)[dir][0]*
1358  m_metricinfo->GetJac(ptsKeys)[0];
1359 
1360  returnval = MemoryManager<DNekScalMat>::
1361  AllocateSharedPtr(fac,WeakDerivStd);
1362  }
1363  }
1364  break;
1366  {
1367  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1368  {
1369  fac = 1.0;
1370  goto UseLocRegionsMatrix;
1371  }
1372  else
1373  {
1374  int coordim = m_geom->GetCoordim();
1375  fac = 0.0;
1376  for (int i = 0; i < coordim; ++i)
1377  {
1378  fac += m_metricinfo->GetDerivFactors(ptsKeys)[i][0]*
1379  m_metricinfo->GetDerivFactors(ptsKeys)[i][0];
1380  }
1381  fac *= m_metricinfo->GetJac(ptsKeys)[0];
1382  goto UseStdRegionsMatrix;
1383  }
1384  }
1385  break;
1387  {
1388  NekDouble factor =
1390  MatrixKey masskey(StdRegions::eMass,
1391  mkey.GetShapeType(), *this);
1392  DNekScalMat &MassMat = *(this->m_matrixManager[masskey]);
1394  *this, mkey.GetConstFactors(),
1395  mkey.GetVarCoeffs());
1396  DNekScalMat &LapMat = *(this->m_matrixManager[lapkey]);
1397 
1398  int rows = LapMat.GetRows();
1399  int cols = LapMat.GetColumns();
1400 
1401  DNekMatSharedPtr helm =
1403 
1404  NekDouble one = 1.0;
1405  (*helm) = LapMat + factor*MassMat;
1406 
1407  returnval =
1409  }
1410  break;
1415  {
1416  NekDouble one = 1.0;
1417 
1418  DNekMatSharedPtr mat = GenMatrix(mkey);
1419  returnval =
1421  }
1422  break;
1424  {
1425  NekDouble one = 1.0;
1426 
1427 // StdRegions::StdMatrixKey hkey(StdRegions::eHybridDGHelmholtz,
1428 // DetShapeType(),*this,
1429 // mkey.GetConstant(0),
1430 // mkey.GetConstant(1));
1432  DetShapeType(),
1433  *this, mkey.GetConstFactors(),
1434  mkey.GetVarCoeffs());
1435  DNekMatSharedPtr mat = GenMatrix(hkey);
1436 
1437  mat->Invert();
1438  returnval =
1440  }
1441  break;
1443  {
1444  DNekMatSharedPtr m_Ix;
1445  Array<OneD, NekDouble> coords(1, 0.0);
1447  int vertex = (int)factors[StdRegions::eFactorGaussVertex];
1448 
1449  coords[0] = (vertex == 0) ? -1.0 : 1.0;
1450 
1451  m_Ix = m_base[0]->GetI(coords);
1452  returnval =
1454  }
1455  break;
1456 
1457  UseLocRegionsMatrix:
1458  {
1459  DNekMatSharedPtr mat = GenMatrix(mkey);
1460  returnval =
1462  }
1463  break;
1464  UseStdRegionsMatrix:
1465  {
1466  DNekMatSharedPtr mat = GetStdMatrix(mkey);
1467  returnval =
1469  }
1470  break;
1471  default:
1472  NEKERROR(ErrorUtil::efatal, "Matrix creation not defined");
1473  break;
1474  }
1475 
1476  return returnval;
1477  }
1478 
1480  const StdRegions::StdMatrixKey &mkey)
1481  {
1482  DNekMatSharedPtr returnval;
1483 
1484  switch (mkey.GetMatrixType())
1485  {
1492  returnval = Expansion1D::v_GenMatrix(mkey);
1493  break;
1494  default:
1495  returnval = StdSegExp::v_GenMatrix(mkey);
1496  break;
1497  }
1498 
1499  return returnval;
1500  }
1501 
1502 
1504  const MatrixKey &mkey)
1505  {
1506  DNekScalBlkMatSharedPtr returnval;
1507 
1508  ASSERTL2(m_metricinfo->GetGtype() !=
1510  "Geometric information is not set up");
1511 
1512  // set up block matrix system
1513  int nbdry = NumBndryCoeffs();
1514  int nint = m_ncoeffs - nbdry;
1515  Array<OneD, unsigned int> exp_size(2);
1516  exp_size[0] = nbdry;
1517  exp_size[1] = nint;
1518 
1519  /// \todo Really need a constructor which takes Arrays
1521  AllocateSharedPtr(exp_size,exp_size);
1522  NekDouble factor = 1.0;
1523 
1524  switch (mkey.GetMatrixType())
1525  {
1527  case StdRegions::eHelmholtz: // special case since Helmholtz
1528  // not defined in StdRegions
1529 
1530  // use Deformed case for both regular and deformed geometries
1531  factor = 1.0;
1532  goto UseLocRegionsMatrix;
1533  break;
1534  default:
1535  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1536  {
1537  factor = 1.0;
1538  goto UseLocRegionsMatrix;
1539  }
1540  else
1541  {
1542  DNekScalMatSharedPtr mat = GetLocMatrix(mkey);
1543  factor = mat->Scale();
1544  goto UseStdRegionsMatrix;
1545  }
1546  break;
1547  UseStdRegionsMatrix:
1548  {
1549  NekDouble invfactor = 1.0/factor;
1550  NekDouble one = 1.0;
1552  DNekScalMatSharedPtr Atmp;
1553  DNekMatSharedPtr Asubmat;
1554 
1555  returnval->SetBlock(0,0,Atmp =
1557  factor,Asubmat = mat->GetBlock(0,0)));
1558  returnval->SetBlock(0,1,Atmp =
1560  one,Asubmat = mat->GetBlock(0,1)));
1561  returnval->SetBlock(1,0,Atmp =
1563  factor,Asubmat = mat->GetBlock(1,0)));
1564  returnval->SetBlock(1,1,Atmp =
1566  invfactor,Asubmat = mat->GetBlock(1,1)));
1567  }
1568  break;
1569  UseLocRegionsMatrix:
1570  {
1571  int i,j;
1572  NekDouble invfactor = 1.0/factor;
1573  NekDouble one = 1.0;
1574  DNekScalMat &mat = *GetLocMatrix(mkey);
1577  DNekMatSharedPtr B =
1579  DNekMatSharedPtr C =
1581  DNekMatSharedPtr D =
1583 
1584  Array<OneD,unsigned int> bmap(nbdry);
1585  Array<OneD,unsigned int> imap(nint);
1586  GetBoundaryMap(bmap);
1587  GetInteriorMap(imap);
1588 
1589  for (i = 0; i < nbdry; ++i)
1590  {
1591  for (j = 0; j < nbdry; ++j)
1592  {
1593  (*A)(i,j) = mat(bmap[i],bmap[j]);
1594  }
1595 
1596  for (j = 0; j < nint; ++j)
1597  {
1598  (*B)(i,j) = mat(bmap[i],imap[j]);
1599  }
1600  }
1601 
1602  for (i = 0; i < nint; ++i)
1603  {
1604  for (j = 0; j < nbdry; ++j)
1605  {
1606  (*C)(i,j) = mat(imap[i],bmap[j]);
1607  }
1608 
1609  for (j = 0; j < nint; ++j)
1610  {
1611  (*D)(i,j) = mat(imap[i],imap[j]);
1612  }
1613  }
1614 
1615  // Calculate static condensed system
1616  if (nint)
1617  {
1618  D->Invert();
1619  (*B) = (*B)*(*D);
1620  (*A) = (*A) - (*B)*(*C);
1621  }
1622 
1623  DNekScalMatSharedPtr Atmp;
1624 
1625  returnval->SetBlock(0,0,Atmp = MemoryManager<DNekScalMat>::
1626  AllocateSharedPtr(factor,A));
1627  returnval->SetBlock(0,1,Atmp = MemoryManager<DNekScalMat>::
1628  AllocateSharedPtr(one,B));
1629  returnval->SetBlock(1,0,Atmp = MemoryManager<DNekScalMat>::
1630  AllocateSharedPtr(factor,C));
1631  returnval->SetBlock(1,1,Atmp = MemoryManager<DNekScalMat>::
1632  AllocateSharedPtr(invfactor,D));
1633  }
1634  }
1635 
1636 
1637  return returnval;
1638  }
1639 
1640 
1641  //-----------------------------
1642  // Private methods
1643  //-----------------------------
1644 
1645 
1646  /// Reverse the coefficients in a boundary interior expansion
1647  /// this routine is of use when we need the segment
1648  /// coefficients corresponding to a expansion in the reverse
1649  /// coordinate direction
1651  const Array<OneD,NekDouble> &inarray,
1652  Array<OneD,NekDouble> &outarray)
1653  {
1654 
1655  int m;
1656  NekDouble sgn = 1;
1657 
1658  ASSERTL1(&inarray[0] != &outarray[0],
1659  "inarray and outarray can not be the same");
1660  switch(GetBasisType(0))
1661  {
1663  //Swap vertices
1664  outarray[0] = inarray[1];
1665  outarray[1] = inarray[0];
1666  // negate odd modes
1667  for(m = 2; m < m_ncoeffs; ++m)
1668  {
1669  outarray[m] = sgn*inarray[m];
1670  sgn = -sgn;
1671  }
1672  break;
1675  for(m = 0; m < m_ncoeffs; ++m)
1676  {
1677  outarray[m_ncoeffs-1-m] = inarray[m];
1678  }
1679  break;
1680  default:
1681  ASSERTL0(false,"This basis is not allowed in this method");
1682  break;
1683  }
1684  }
1685 
1686  /* \brief Mass inversion product from \a inarray to \a outarray
1687  *
1688  * Multiply by the inverse of the mass matrix
1689  * \f$ {\bf \hat{u}} = {\bf M}^{-1} {\bf I} \f$
1690  *
1691  **/
1693  const Array<OneD, const NekDouble>& inarray,
1694  Array<OneD,NekDouble> &outarray)
1695  {
1696  // get Mass matrix inverse
1698  DetShapeType(),*this);
1699  DNekScalMatSharedPtr matsys = m_matrixManager[masskey];
1700 
1701  NekVector<NekDouble> in(m_ncoeffs,inarray,eCopy);
1702  NekVector<NekDouble> out(m_ncoeffs,outarray,eWrapper);
1703 
1704  out = (*matsys)*in;
1705  }
1706 
1707 
1708  } // end of namespace
1709 }//end of namespace
1710 
#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
virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey)
Definition: Expansion1D.cpp:56
std::map< int, NormalVector > m_vertexNormals
Definition: Expansion1D.h:83
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
ExpansionSharedPtr GetLeftAdjacentElementExp() const
Definition: Expansion.h:438
const NormalVector & GetTraceNormal(const int id) const
Definition: Expansion.h:222
int GetLeftAdjacentElementTrace() const
Definition: Expansion.h:454
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
DNekScalBlkMatSharedPtr CreateStaticCondMatrix(const MatrixKey &mkey)
Definition: SegExp.cpp:1503
virtual void v_LaplacianMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey) override
Definition: SegExp.cpp:1018
virtual void v_FwdTrans_BndConstrained(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition: SegExp.cpp:401
virtual void v_FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Forward transform from physical quadrature space stored in inarray and evaluate the expansion coeffic...
Definition: SegExp.cpp:377
virtual StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const override
Definition: SegExp.cpp:837
virtual void v_GetTracePhysVals(const int edge, const StdRegions::StdExpansionSharedPtr &EdgeExp, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, StdRegions::Orientation orient) override
Definition: SegExp.cpp:778
virtual void v_PhysDeriv_s(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_ds) override
Evaluate the derivative along a line: . The derivative is calculated performing the product .
Definition: SegExp.cpp:229
virtual int v_GetNumPoints(const int dir) const
Definition: SegExp.cpp:862
virtual void v_GetVertexPhysVals(const int vertex, const Array< OneD, const NekDouble > &inarray, NekDouble &outarray) override
Definition: SegExp.cpp:706
virtual NekDouble v_StdPhysEvaluate(const Array< OneD, const NekDouble > &Lcoord, const Array< OneD, const NekDouble > &physvals) override
Definition: SegExp.cpp:660
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:1650
virtual void v_NormVectorIProductWRTBase(const Array< OneD, const NekDouble > &Fx, const Array< OneD, const NekDouble > &Fy, Array< OneD, NekDouble > &outarray) override
Definition: SegExp.cpp:624
DNekScalMatSharedPtr CreateMatrix(const MatrixKey &mkey)
Definition: SegExp.cpp:1269
virtual int v_GetCoordim() override
Definition: SegExp.cpp:846
virtual StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const override
Definition: SegExp.cpp:831
virtual void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Inner product of inarray over region with respect to the expansion basis (this)->_Base[0] and return ...
Definition: SegExp.cpp:506
virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey) override
Definition: SegExp.cpp:1479
LibUtilities::NekManager< MatrixKey, DNekScalBlkMat, MatrixKey::opLess > m_staticCondMatrixManager
Definition: SegExp.h:255
virtual NekDouble v_Integral(const Array< OneD, const NekDouble > &inarray) override
Integrate the physical point list inarray over region and return the value.
Definition: SegExp.cpp:118
virtual void v_HelmholtzMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey) override
Definition: SegExp.cpp:1126
virtual void v_PhysDeriv_n(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_dn) override
Evaluate the derivative normal to a line: . The derivative is calculated performing the product .
Definition: SegExp.cpp:269
virtual void v_ExtractDataToCoeffs(const NekDouble *data, const std::vector< unsigned int > &nummodes, const int mode_offset, NekDouble *coeffs, std::vector< LibUtilities::BasisType > &fromType) override
Unpack data from input file assuming it comes from.
Definition: SegExp.cpp:892
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) override
Evaluate the derivative at the physical quadrature points given by inarray and return in outarray.
Definition: SegExp.cpp:166
virtual void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3) override
Definition: SegExp.cpp:697
virtual DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix(const MatrixKey &mkey) override
Definition: SegExp.cpp:1241
void MultiplyByElmtInvMass(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: SegExp.cpp:1692
virtual int v_NumBndryCoeffs() const override
Definition: SegExp.cpp:878
LibUtilities::NekManager< MatrixKey, DNekScalMat, MatrixKey::opLess > m_matrixManager
Definition: SegExp.h:253
virtual NekDouble v_PhysEvaluate(const Array< OneD, const NekDouble > &coord, const Array< OneD, const NekDouble > &physvals) override
Definition: SegExp.cpp:668
virtual void v_GetTracePhysMap(const int vertex, Array< OneD, int > &map) override
Definition: SegExp.cpp:793
virtual int v_NumDGBndryCoeffs() const override
Definition: SegExp.cpp:884
virtual DNekMatSharedPtr v_CreateStdMatrix(const StdRegions::StdMatrixKey &mkey) override
Definition: SegExp.cpp:1258
virtual void v_SetCoeffsToOrientation(StdRegions::Orientation dir, Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition: SegExp.cpp:811
void v_DropLocStaticCondMatrix(const MatrixKey &mkey) override
Definition: SegExp.cpp:1247
virtual DNekScalMatSharedPtr v_GetLocMatrix(const MatrixKey &mkey) override
Definition: SegExp.cpp:1252
virtual void v_GetCoord(const Array< OneD, const NekDouble > &Lcoords, Array< OneD, NekDouble > &coords) override
Definition: SegExp.cpp:681
virtual void v_AddVertexPhysVals(const int vertex, const NekDouble &inarray, Array< OneD, NekDouble > &outarray)
Definition: SegExp.cpp:742
virtual int v_GetNcoeffs(void) const
Definition: SegExp.cpp:867
virtual const LibUtilities::BasisSharedPtr & v_GetBasis(int dir) const
Definition: SegExp.cpp:872
virtual SpatialDomains::GeomType v_MetricInfoType()
Definition: SegExp.cpp:857
virtual void v_ComputeTraceNormal(const int vertex) override
Definition: SegExp.cpp:945
virtual const Array< OneD, const NekDouble > & v_GetPhysNormals(void) override
Definition: SegExp.cpp:851
virtual void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition: SegExp.cpp:565
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 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 GetBoundaryMap(Array< OneD, unsigned int > &outarray)
Definition: StdExpansion.h:687
const LibUtilities::BasisSharedPtr & GetBasis(int dir) const
This function gets the shared point to basis in the dir direction.
Definition: StdExpansion.h:111
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
void MassMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
Definition: StdExpansion.h:762
int GetVertexMap(const int localVertexId, bool useCoeffPacking=false)
Definition: StdExpansion.h:697
void NormVectorIProductWRTBase(const Array< OneD, const NekDouble > &Fx, Array< OneD, NekDouble > &outarray)
Definition: StdExpansion.h:628
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
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:433
DNekMatSharedPtr GenMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:850
LibUtilities::PointsType GetPointsType(const int dir) const
This function returns the type of quadrature points used in the dir direction.
Definition: StdExpansion.h:208
int GetNumPoints(const int dir) const
This function returns the number of quadrature points in the dir direction.
Definition: StdExpansion.h:221
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)
Definition: StdExpansion.h:855
Array< OneD, LibUtilities::BasisSharedPtr > m_base
const ConstFactorMap & GetConstFactors() const
Definition: StdMatrixKey.h:135
LibUtilities::ShapeType GetShapeType() const
Definition: StdMatrixKey.h:86
const VarCoeffMap & GetVarCoeffs() const
Definition: StdMatrixKey.h:161
MatrixType GetMatrixType() const
Definition: StdMatrixKey.h:81
NekDouble GetConstFactor(const ConstFactorType &factor) const
Definition: StdMatrixKey.h:121
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 Dscal(const int &n, const double &alpha, double *x, const int &incx)
BLAS level 1: x = alpha x.
Definition: Blas.hpp:182
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:197
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
std::shared_ptr< Basis > BasisSharedPtr
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
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
Definition: PointsType.h:51
@ ePolyEvenlySpaced
1D Evenly-spaced points using Lagrange polynomial
Definition: PointsType.h:64
@ eGaussGaussLegendre
1D Gauss-Gauss-Legendre quadrature points
Definition: PointsType.h:48
@ eModified_B
Principle Modified Functions .
Definition: BasisType.h:49
@ eGauss_Lagrange
Lagrange Polynomials using the Gauss points .
Definition: BasisType.h:55
@ eGLL_Lagrange
Lagrange for SEM basis .
Definition: BasisType.h:54
@ eModified_A
Principle Modified Functions .
Definition: BasisType.h:48
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< Geometry1D > Geometry1DSharedPtr
Definition: Geometry.h:63
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
std::map< ConstFactorType, NekDouble > ConstFactorMap
Definition: StdRegions.hpp:314
std::shared_ptr< StdSegExp > StdSegExpSharedPtr
Definition: StdSegExp.h:46
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
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayOfArray
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
Definition: NekTypeDefs.hpp:73
static Array< OneD, NekDouble > NullNekDouble1DArray
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:69
double NekDouble
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 Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
svtvp (scalar times vector plus vector): z = alpha*x + y
Definition: Vmath.cpp:565
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 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:257
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 Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1199
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:372
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:267