Nektar++
PyrExp.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File PyrExp.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: PyrExp routines
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include <LocalRegions/PyrExp.h>
37 
38 using namespace std;
39 
40 namespace Nektar
41 {
42  namespace LocalRegions
43  {
44 
45  PyrExp::PyrExp(const LibUtilities::BasisKey &Ba,
46  const LibUtilities::BasisKey &Bb,
47  const LibUtilities::BasisKey &Bc,
49  StdExpansion (LibUtilities::StdPyrData::getNumberOfCoefficients(
50  Ba.GetNumModes(),
51  Bb.GetNumModes(),
52  Bc.GetNumModes()),
53  3, Ba, Bb, Bc),
54  StdExpansion3D(LibUtilities::StdPyrData::getNumberOfCoefficients(
55  Ba.GetNumModes(),
56  Bb.GetNumModes(),
57  Bc.GetNumModes()),
58  Ba, Bb, Bc),
59  StdPyrExp (Ba,Bb,Bc),
60  Expansion (geom),
61  Expansion3D (geom),
62  m_matrixManager(
63  std::bind(&PyrExp::CreateMatrix, this, std::placeholders::_1),
64  std::string("PyrExpMatrix")),
65  m_staticCondMatrixManager(
66  std::bind(&PyrExp::CreateStaticCondMatrix, this, std::placeholders::_1),
67  std::string("PyrExpStaticCondMatrix"))
68  {
69  }
70 
72  StdExpansion (T),
73  StdExpansion3D(T),
74  StdPyrExp (T),
75  Expansion (T),
76  Expansion3D (T),
77  m_matrixManager(T.m_matrixManager),
78  m_staticCondMatrixManager(T.m_staticCondMatrixManager)
79  {
80  }
81 
83  {
84  }
85 
86 
87  //----------------------------
88  // Integration Methods
89  //----------------------------
90 
91  /**
92  * \brief Integrate the physical point list \a inarray over pyramidic
93  * region and return the value.
94  *
95  * Inputs:\n
96  *
97  * - \a inarray: definition of function to be returned at quadrature
98  * point of expansion.
99  *
100  * Outputs:\n
101  *
102  * - returns \f$\int^1_{-1}\int^1_{-1}\int^1_{-1} u(\bar \eta_1,
103  * \eta_2, \eta_3) J[i,j,k] d \bar \eta_1 d \eta_2 d \eta_3\f$ \n \f$=
104  * \sum_{i=0}^{Q_1 - 1} \sum_{j=0}^{Q_2 - 1} \sum_{k=0}^{Q_3 - 1}
105  * u(\bar \eta_{1i}^{0,0}, \eta_{2j}^{0,0},\eta_{3k}^{2,0})w_{i}^{0,0}
106  * w_{j}^{0,0} \hat w_{k}^{2,0} \f$ \n where \f$inarray[i,j, k] =
107  * u(\bar \eta_{1i},\eta_{2j}, \eta_{3k}) \f$, \n \f$\hat w_{k}^{2,0}
108  * = \frac {w^{2,0}} {2} \f$ \n and \f$ J[i,j,k] \f$ is the Jacobian
109  * evaluated at the quadrature point.
110  */
112  {
113  int nquad0 = m_base[0]->GetNumPoints();
114  int nquad1 = m_base[1]->GetNumPoints();
115  int nquad2 = m_base[2]->GetNumPoints();
117  Array<OneD, NekDouble> tmp(nquad0*nquad1*nquad2);
118 
119  // multiply inarray with Jacobian
120  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
121  {
122  Vmath::Vmul(nquad0*nquad1*nquad2,&jac[0],1,(NekDouble*)&inarray[0],1, &tmp[0],1);
123  }
124  else
125  {
126  Vmath::Smul(nquad0*nquad1*nquad2,(NekDouble) jac[0], (NekDouble*)&inarray[0],1,&tmp[0],1);
127  }
128 
129  // call StdPyrExp version;
130  return StdPyrExp::v_Integral(tmp);
131  }
132 
133 
134  //----------------------------
135  // Differentiation Methods
136  //----------------------------
137 
139  Array<OneD, NekDouble>& out_d0,
140  Array<OneD, NekDouble>& out_d1,
141  Array<OneD, NekDouble>& out_d2)
142  {
143  int nquad0 = m_base[0]->GetNumPoints();
144  int nquad1 = m_base[1]->GetNumPoints();
145  int nquad2 = m_base[2]->GetNumPoints();
147  m_metricinfo->GetDerivFactors(GetPointsKeys());
148  Array<OneD,NekDouble> diff0(nquad0*nquad1*nquad2);
149  Array<OneD,NekDouble> diff1(nquad0*nquad1*nquad2);
150  Array<OneD,NekDouble> diff2(nquad0*nquad1*nquad2);
151 
152  StdPyrExp::v_PhysDeriv(inarray, diff0, diff1, diff2);
153 
154  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
155  {
156  if(out_d0.size())
157  {
158  Vmath::Vmul (nquad0*nquad1*nquad2,&gmat[0][0],1,&diff0[0],1, &out_d0[0], 1);
159  Vmath::Vvtvp (nquad0*nquad1*nquad2,&gmat[1][0],1,&diff1[0],1, &out_d0[0], 1,&out_d0[0],1);
160  Vmath::Vvtvp (nquad0*nquad1*nquad2,&gmat[2][0],1,&diff2[0],1, &out_d0[0], 1,&out_d0[0],1);
161  }
162 
163  if(out_d1.size())
164  {
165  Vmath::Vmul (nquad0*nquad1*nquad2,&gmat[3][0],1,&diff0[0],1, &out_d1[0], 1);
166  Vmath::Vvtvp (nquad0*nquad1*nquad2,&gmat[4][0],1,&diff1[0],1, &out_d1[0], 1,&out_d1[0],1);
167  Vmath::Vvtvp (nquad0*nquad1*nquad2,&gmat[5][0],1,&diff2[0],1, &out_d1[0], 1,&out_d1[0],1);
168  }
169 
170  if(out_d2.size())
171  {
172  Vmath::Vmul (nquad0*nquad1*nquad2,&gmat[6][0],1,&diff0[0],1, &out_d2[0], 1);
173  Vmath::Vvtvp (nquad0*nquad1*nquad2,&gmat[7][0],1,&diff1[0],1, &out_d2[0], 1, &out_d2[0],1);
174  Vmath::Vvtvp (nquad0*nquad1*nquad2,&gmat[8][0],1,&diff2[0],1, &out_d2[0], 1, &out_d2[0],1);
175  }
176  }
177  else // regular geometry
178  {
179  if(out_d0.size())
180  {
181  Vmath::Smul (nquad0*nquad1*nquad2,gmat[0][0],&diff0[0],1, &out_d0[0], 1);
182  Blas::Daxpy (nquad0*nquad1*nquad2,gmat[1][0],&diff1[0],1, &out_d0[0], 1);
183  Blas::Daxpy (nquad0*nquad1*nquad2,gmat[2][0],&diff2[0],1, &out_d0[0], 1);
184  }
185 
186  if(out_d1.size())
187  {
188  Vmath::Smul (nquad0*nquad1*nquad2,gmat[3][0],&diff0[0],1, &out_d1[0], 1);
189  Blas::Daxpy (nquad0*nquad1*nquad2,gmat[4][0],&diff1[0],1, &out_d1[0], 1);
190  Blas::Daxpy (nquad0*nquad1*nquad2,gmat[5][0],&diff2[0],1, &out_d1[0], 1);
191  }
192 
193  if(out_d2.size())
194  {
195  Vmath::Smul (nquad0*nquad1*nquad2,gmat[6][0],&diff0[0],1, &out_d2[0], 1);
196  Blas::Daxpy (nquad0*nquad1*nquad2,gmat[7][0],&diff1[0],1, &out_d2[0], 1);
197  Blas::Daxpy (nquad0*nquad1*nquad2,gmat[8][0],&diff2[0],1, &out_d2[0], 1);
198  }
199  }
200  }
201 
202 
203  //---------------------------------------
204  // Transforms
205  //---------------------------------------
206 
207  /**
208  * \brief Forward transform from physical quadrature space stored in
209  * \a inarray and evaluate the expansion coefficients and store in \a
210  * (this)->m_coeffs
211  *
212  * Inputs:\n
213  *
214  * - \a inarray: array of physical quadrature points to be transformed
215  *
216  * Outputs:\n
217  *
218  * - (this)->_coeffs: updated array of expansion coefficients.
219  */
221  Array<OneD, NekDouble>& outarray)
222  {
223  if(m_base[0]->Collocation() &&
224  m_base[1]->Collocation() &&
225  m_base[2]->Collocation())
226  {
227  Vmath::Vcopy(GetNcoeffs(),&inarray[0],1,&outarray[0],1);
228  }
229  else
230  {
231  v_IProductWRTBase(inarray,outarray);
232 
233  // get Mass matrix inverse
235  DetShapeType(),*this);
236  DNekScalMatSharedPtr matsys = m_matrixManager[masskey];
237 
238  // copy inarray in case inarray == outarray
239  DNekVec in (m_ncoeffs,outarray);
240  DNekVec out(m_ncoeffs,outarray,eWrapper);
241 
242  out = (*matsys)*in;
243  }
244  }
245 
246 
247  //---------------------------------------
248  // Inner product functions
249  //---------------------------------------
250 
251  /**
252  * \brief Calculate the inner product of inarray with respect to the
253  * basis B=base0*base1*base2 and put into outarray:
254  *
255  * \f$ \begin{array}{rcl} I_{pqr} = (\phi_{pqr}, u)_{\delta} & = &
256  * \sum_{i=0}^{nq_0} \sum_{j=0}^{nq_1} \sum_{k=0}^{nq_2} \psi_{p}^{a}
257  * (\bar \eta_{1i}) \psi_{q}^{a} (\eta_{2j}) \psi_{pqr}^{c}
258  * (\eta_{3k}) w_i w_j w_k u(\bar \eta_{1,i} \eta_{2,j} \eta_{3,k})
259  * J_{i,j,k}\\ & = & \sum_{i=0}^{nq_0} \psi_p^a(\bar \eta_{1,i})
260  * \sum_{j=0}^{nq_1} \psi_{q}^a(\eta_{2,j}) \sum_{k=0}^{nq_2}
261  * \psi_{pqr}^c u(\bar \eta_{1i},\eta_{2j},\eta_{3k}) J_{i,j,k}
262  * \end{array} \f$ \n
263  *
264  * where
265  *
266  * \f$\phi_{pqr} (\xi_1 , \xi_2 , \xi_3) = \psi_p^a (\bar \eta_1)
267  * \psi_{q}^a (\eta_2) \psi_{pqr}^c (\eta_3) \f$ \n
268  *
269  * which can be implemented as \n \f$f_{pqr} (\xi_{3k}) =
270  * \sum_{k=0}^{nq_3} \psi_{pqr}^c u(\bar
271  * \eta_{1i},\eta_{2j},\eta_{3k}) J_{i,j,k} = {\bf B_3 U} \f$ \n \f$
272  * g_{pq} (\xi_{3k}) = \sum_{j=0}^{nq_1} \psi_{q}^a (\xi_{2j}) f_{pqr}
273  * (\xi_{3k}) = {\bf B_2 F} \f$ \n \f$ (\phi_{pqr}, u)_{\delta} =
274  * \sum_{k=0}^{nq_0} \psi_{p}^a (\xi_{3k}) g_{pq} (\xi_{3k}) = {\bf
275  * B_1 G} \f$
276  */
277 
279  const Array<OneD, const NekDouble>& inarray,
280  Array<OneD, NekDouble>& outarray)
281  {
282  v_IProductWRTBase_SumFac(inarray, outarray);
283  }
284 
286  const Array<OneD, const NekDouble>& inarray,
287  Array<OneD, NekDouble>& outarray,
288  bool multiplybyweights)
289  {
290  const int nquad0 = m_base[0]->GetNumPoints();
291  const int nquad1 = m_base[1]->GetNumPoints();
292  const int nquad2 = m_base[2]->GetNumPoints();
293  const int order0 = m_base[0]->GetNumModes();
294  const int order1 = m_base[1]->GetNumModes();
295 
296  Array<OneD, NekDouble> wsp(order0*nquad2*(nquad1+order1));
297 
298  if(multiplybyweights)
299  {
300  Array<OneD, NekDouble> tmp(nquad0*nquad1*nquad2);
301 
302  MultiplyByQuadratureMetric(inarray, tmp);
303 
304  IProductWRTBase_SumFacKernel(m_base[0]->GetBdata(),
305  m_base[1]->GetBdata(),
306  m_base[2]->GetBdata(),
307  tmp,outarray,wsp,
308  true,true,true);
309  }
310  else
311  {
312  IProductWRTBase_SumFacKernel(m_base[0]->GetBdata(),
313  m_base[1]->GetBdata(),
314  m_base[2]->GetBdata(),
315  inarray,outarray,wsp,
316  true,true,true);
317  }
318  }
319 
320 
321  /**
322  * @brief Calculates the inner product \f$ I_{pqr} = (u,
323  * \partial_{x_i} \phi_{pqr}) \f$.
324  *
325  * The derivative of the basis functions is performed using the chain
326  * rule in order to incorporate the geometric factors. Assuming that
327  * the basis functions are a tensor product
328  * \f$\phi_{pqr}(\eta_1,\eta_2,\eta_3) =
329  * \phi_1(\eta_1)\phi_2(\eta_2)\phi_3(\eta_3)\f$, this yields the
330  * result
331  *
332  * \f[
333  * I_{pqr} = \sum_{j=1}^3 \left(u, \frac{\partial u}{\partial \eta_j}
334  * \frac{\partial \eta_j}{\partial x_i}\right)
335  * \f]
336  *
337  * In the pyramid element, we must also incorporate a second set
338  * of geometric factors which incorporate the collapsed co-ordinate
339  * system, so that
340  *
341  * \f[ \frac{\partial\eta_j}{\partial x_i} = \sum_{k=1}^3
342  * \frac{\partial\eta_j}{\partial\xi_k}\frac{\partial\xi_k}{\partial
343  * x_i} \f]
344  *
345  * These derivatives can be found on p152 of Sherwin & Karniadakis.
346  *
347  * @param dir Direction in which to take the derivative.
348  * @param inarray The function \f$ u \f$.
349  * @param outarray Value of the inner product.
350  */
352  const int dir,
353  const Array<OneD, const NekDouble> &inarray,
354  Array<OneD, NekDouble> &outarray)
355  {
356  v_IProductWRTDerivBase_SumFac(dir, inarray, outarray);
357  }
358 
360  const int dir,
361  const Array<OneD, const NekDouble> &inarray,
362  Array<OneD, NekDouble> &outarray)
363  {
364  const int nquad0 = m_base[0]->GetNumPoints();
365  const int nquad1 = m_base[1]->GetNumPoints();
366  const int nquad2 = m_base[2]->GetNumPoints();
367  const int order0 = m_base[0]->GetNumModes ();
368  const int order1 = m_base[1]->GetNumModes ();
369  const int nqtot = nquad0*nquad1*nquad2;
370 
371  Array<OneD, NekDouble> tmp1 (nqtot );
372  Array<OneD, NekDouble> tmp2 (nqtot );
373  Array<OneD, NekDouble> tmp3 (nqtot );
374  Array<OneD, NekDouble> tmp4 (nqtot );
376  Array<OneD, NekDouble> wsp (std::max(nqtot,order0*nquad2*(nquad1+order1)));
377 
378  MultiplyByQuadratureMetric(inarray, tmp1);
379 
381  tmp2D[0] = tmp2;
382  tmp2D[1] = tmp3;
383  tmp2D[2] = tmp4;
384 
385  PyrExp::v_AlignVectorToCollapsedDir(dir, tmp1, tmp2D);
386 
387  IProductWRTBase_SumFacKernel(m_base[0]->GetDbdata(),
388  m_base[1]->GetBdata (),
389  m_base[2]->GetBdata (),
390  tmp2,outarray,wsp,
391  false,true,true);
392 
393  IProductWRTBase_SumFacKernel(m_base[0]->GetBdata (),
394  m_base[1]->GetDbdata(),
395  m_base[2]->GetBdata (),
396  tmp3,tmp6,wsp,
397  true,false,true);
398 
399  Vmath::Vadd(m_ncoeffs, tmp6, 1, outarray, 1, outarray, 1);
400 
401  IProductWRTBase_SumFacKernel(m_base[0]->GetBdata (),
402  m_base[1]->GetBdata (),
403  m_base[2]->GetDbdata(),
404  tmp4,tmp6,wsp,
405  true,true,false);
406 
407  Vmath::Vadd(m_ncoeffs, tmp6, 1, outarray, 1, outarray, 1);
408  }
409 
411  const int dir,
412  const Array<OneD, const NekDouble> &inarray,
413  Array<OneD, Array<OneD, NekDouble> > &outarray)
414  {
415  const int nquad0 = m_base[0]->GetNumPoints();
416  const int nquad1 = m_base[1]->GetNumPoints();
417  const int nquad2 = m_base[2]->GetNumPoints();
418  const int order0 = m_base[0]->GetNumModes ();
419  const int order1 = m_base[1]->GetNumModes ();
420  const int nqtot = nquad0*nquad1*nquad2;
421 
422  const Array<OneD, const NekDouble> &z0 = m_base[0]->GetZ();
423  const Array<OneD, const NekDouble> &z1 = m_base[1]->GetZ();
424  const Array<OneD, const NekDouble> &z2 = m_base[2]->GetZ();
425 
426  Array<OneD, NekDouble> gfac0(nquad0 );
427  Array<OneD, NekDouble> gfac1(nquad1 );
428  Array<OneD, NekDouble> gfac2(nquad2 );
429  Array<OneD, NekDouble> tmp5 (nqtot );
430  Array<OneD, NekDouble> wsp (std::max(nqtot,
431  order0*nquad2*(nquad1+order1)));
432 
433  Array<OneD, NekDouble> tmp2 = outarray[0];
434  Array<OneD, NekDouble> tmp3 = outarray[1];
435  Array<OneD, NekDouble> tmp4 = outarray[2];
436 
437  const Array<TwoD, const NekDouble>& df =
438  m_metricinfo->GetDerivFactors(GetPointsKeys());
439 
441  tmp1 = inarray;
442 
443  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
444  {
445  Vmath::Vmul(nqtot,&df[3*dir][0], 1,tmp1.get(),1,tmp2.get(),1);
446  Vmath::Vmul(nqtot,&df[3*dir+1][0],1,tmp1.get(),1,tmp3.get(),1);
447  Vmath::Vmul(nqtot,&df[3*dir+2][0],1,tmp1.get(),1,tmp4.get(),1);
448  }
449  else
450  {
451  Vmath::Smul(nqtot, df[3*dir][0], tmp1.get(),1,tmp2.get(), 1);
452  Vmath::Smul(nqtot, df[3*dir+1][0],tmp1.get(),1,tmp3.get(), 1);
453  Vmath::Smul(nqtot, df[3*dir+2][0],tmp1.get(),1,tmp4.get(), 1);
454  }
455 
456  // set up geometric factor: (1+z0)/2
457  for (int i = 0; i < nquad0; ++i)
458  {
459  gfac0[i] = 0.5*(1+z0[i]);
460  }
461 
462  // set up geometric factor: (1+z1)/2
463  for(int i = 0; i < nquad1; ++i)
464  {
465  gfac1[i] = 0.5*(1+z1[i]);
466  }
467 
468  // Set up geometric factor: 2/(1-z2)
469  for (int i = 0; i < nquad2; ++i)
470  {
471  gfac2[i] = 2.0/(1-z2[i]);
472  }
473 
474  const int nq01 = nquad0*nquad1;
475 
476  for (int i = 0; i < nquad2; ++i)
477  {
478  Vmath::Smul(nq01,gfac2[i],&tmp2[0]+i*nq01,1,&tmp2[0]+i*nq01,1); // 2/(1-z2) for d/dxi_0
479  Vmath::Smul(nq01,gfac2[i],&tmp3[0]+i*nq01,1,&tmp3[0]+i*nq01,1); // 2/(1-z2) for d/dxi_1
480  Vmath::Smul(nq01,gfac2[i],&tmp4[0]+i*nq01,1,&tmp5[0]+i*nq01,1); // 2/(1-z2) for d/dxi_2
481  }
482 
483  // (1+z0)/(1-z2) for d/d eta_0
484  for (int i = 0; i < nquad1*nquad2; ++i)
485  {
486  Vmath::Vmul(nquad0,&gfac0[0],1,
487  &tmp5[0]+i*nquad0,1,
488  &wsp[0]+i*nquad0,1);
489  }
490 
491  Vmath::Vadd(nqtot, &tmp2[0], 1, &wsp[0], 1, &tmp2[0], 1);
492 
493  // (1+z1)/(1-z2) for d/d eta_1
494  for (int i = 0; i < nquad1*nquad2; ++i)
495  {
496  Vmath::Smul(nquad0,gfac1[i%nquad1],
497  &tmp5[0]+i*nquad0,1,
498  &tmp5[0]+i*nquad0,1);
499  }
500  Vmath::Vadd(nqtot, &tmp3[0], 1, &tmp5[0], 1, &tmp3[0], 1);
501  }
502 
503  //---------------------------------------
504  // Evaluation functions
505  //---------------------------------------
506 
508  {
510  ::AllocateSharedPtr(m_base[0]->GetBasisKey(),
511  m_base[1]->GetBasisKey(),
512  m_base[2]->GetBasisKey());
513  }
514 
516  {
518  2, m_base[0]->GetPointsKey());
520  2, m_base[1]->GetPointsKey());
522  2, m_base[2]->GetPointsKey());
523 
525  ::AllocateSharedPtr( bkey0, bkey1, bkey2);
526  }
527 
528  /*
529  * @brief Get the coordinates #coords at the local coordinates
530  * #Lcoords
531  */
533  Array<OneD, NekDouble>& coords)
534  {
535  int i;
536 
537  ASSERTL1(Lcoords[0] <= -1.0 && Lcoords[0] >= 1.0 &&
538  Lcoords[1] <= -1.0 && Lcoords[1] >= 1.0 &&
539  Lcoords[2] <= -1.0 && Lcoords[2] >= 1.0,
540  "Local coordinates are not in region [-1,1]");
541 
542  // m_geom->FillGeom(); // TODO: implement FillGeom()
543 
544  for(i = 0; i < m_geom->GetCoordim(); ++i)
545  {
546  coords[i] = m_geom->GetCoord(i,Lcoords);
547  }
548  }
549 
551  Array<OneD, NekDouble> &coords_1,
552  Array<OneD, NekDouble> &coords_2,
553  Array<OneD, NekDouble> &coords_3)
554  {
555  Expansion::v_GetCoords(coords_1, coords_2, coords_3);
556  }
557 
558 
560  const NekDouble *data,
561  const std::vector<unsigned int > &nummodes,
562  const int mode_offset,
563  NekDouble * coeffs,
564  std::vector<LibUtilities::BasisType> &fromType)
565  {
566  int data_order0 = nummodes[mode_offset];
567  int fillorder0 = min(m_base[0]->GetNumModes(),data_order0);
568  int data_order1 = nummodes[mode_offset+1];
569  int order1 = m_base[1]->GetNumModes();
570  int fillorder1 = min(order1,data_order1);
571  int data_order2 = nummodes[mode_offset+2];
572  int order2 = m_base[2]->GetNumModes();
573  int fillorder2 = min(order2,data_order2);
574 
575  // Check if not same order or basis and if not make temp
576  // element to read in data
577  if (fromType[0] != m_base[0]->GetBasisType() ||
578  fromType[1] != m_base[1]->GetBasisType() ||
579  fromType[2] != m_base[2]->GetBasisType() ||
580  data_order0 != fillorder0 ||
581  data_order1 != fillorder1 ||
582  data_order2 != fillorder2)
583  {
584  // Construct a pyr with the appropriate basis type at our
585  // quadrature points, and one more to do a forwards
586  // transform. We can then copy the output to coeffs.
587  StdRegions::StdPyrExp tmpPyr(
589  fromType[0], data_order0, m_base[0]->GetPointsKey()),
591  fromType[1], data_order1, m_base[1]->GetPointsKey()),
593  fromType[2], data_order2, m_base[2]->GetPointsKey()));
594 
595  StdRegions::StdPyrExp tmpPyr2(m_base[0]->GetBasisKey(),
596  m_base[1]->GetBasisKey(),
597  m_base[2]->GetBasisKey());
598 
599  Array<OneD, const NekDouble> tmpData(tmpPyr.GetNcoeffs(), data);
600  Array<OneD, NekDouble> tmpBwd(tmpPyr2.GetTotPoints());
601  Array<OneD, NekDouble> tmpOut(tmpPyr2.GetNcoeffs());
602 
603  tmpPyr.BwdTrans(tmpData, tmpBwd);
604  tmpPyr2.FwdTrans(tmpBwd, tmpOut);
605  Vmath::Vcopy(tmpOut.size(), &tmpOut[0], 1, coeffs, 1);
606 
607  }
608  else
609  {
610  Vmath::Vcopy(m_ncoeffs,&data[0],1,coeffs,1);
611  }
612  }
613 
614  /**
615  * Given the local cartesian coordinate \a Lcoord evaluate the
616  * value of physvals at this point by calling through to the
617  * StdExpansion method
618  */
620  const Array<OneD, const NekDouble> &Lcoord,
621  const Array<OneD, const NekDouble> &physvals)
622  {
623  // Evaluate point in local coordinates.
624  return StdPyrExp::v_PhysEvaluate(Lcoord,physvals);
625  }
626 
628  const Array<OneD, const NekDouble>& physvals)
629  {
630  Array<OneD,NekDouble> Lcoord(3);
631 
632  ASSERTL0(m_geom,"m_geom not defined");
633 
634  //TODO: check GetLocCoords()
635  m_geom->GetLocCoords(coord, Lcoord);
636 
637  return StdPyrExp::v_PhysEvaluate(Lcoord, physvals);
638  }
639 
640 
641  //---------------------------------------
642  // Helper functions
643  //---------------------------------------
644 
646  {
647  return m_geom->GetCoordim();
648  }
649 
650  void PyrExp::v_GetTracePhysMap(const int face,
651  Array<OneD, int> &outarray)
652  {
653  int nquad0 = m_base[0]->GetNumPoints();
654  int nquad1 = m_base[1]->GetNumPoints();
655  int nquad2 = m_base[2]->GetNumPoints();
656 
657  int nq0 = 0;
658  int nq1 = 0;
659 
660  switch(face)
661  {
662  case 0:
663  nq0 = nquad0;
664  nq1 = nquad1;
665  if(outarray.size()!=nq0*nq1)
666  {
667  outarray = Array<OneD, int>(nq0*nq1);
668  }
669 
670  //Directions A and B positive
671  for(int i = 0; i < nquad0*nquad1; ++i)
672  {
673  outarray[i] = i;
674  }
675 
676  break;
677  case 1:
678  nq0 = nquad0;
679  nq1 = nquad2;
680  if(outarray.size()!=nq0*nq1)
681  {
682  outarray = Array<OneD, int>(nq0*nq1);
683  }
684 
685  //Direction A and B positive
686  for (int k=0; k<nquad2; k++)
687  {
688  for(int i = 0; i < nquad0; ++i)
689  {
690  outarray[k*nquad0+i] = (nquad0*nquad1*k)+i;
691  }
692  }
693 
694  break;
695  case 2:
696  nq0 = nquad1;
697  nq1 = nquad2;
698  if(outarray.size()!=nq0*nq1)
699  {
700  outarray = Array<OneD, int>(nq0*nq1);
701  }
702 
703  //Directions A and B positive
704  for(int j = 0; j < nquad1*nquad2; ++j)
705  {
706  outarray[j] = nquad0-1 + j*nquad0;
707 
708  }
709  break;
710  case 3:
711 
712  nq0 = nquad0;
713  nq1 = nquad2;
714  if(outarray.size()!=nq0*nq1)
715  {
716  outarray = Array<OneD, int>(nq0*nq1);
717  }
718 
719  //Direction A and B positive
720  for (int k=0; k<nquad2; k++)
721  {
722  for(int i = 0; i < nquad0; ++i)
723  {
724  outarray[k*nquad0+i] = nquad0*(nquad1-1) + (nquad0*nquad1*k)+i;
725  }
726  }
727  break;
728  case 4:
729  nq0 = nquad1;
730  nq1 = nquad2;
731 
732  if(outarray.size()!=nq0*nq1)
733  {
734  outarray = Array<OneD, int>(nq0*nq1);
735  }
736 
737  //Directions A and B positive
738  for(int j = 0; j < nquad1*nquad2; ++j)
739  {
740  outarray[j] = j*nquad0;
741 
742  }
743  break;
744  default:
745  ASSERTL0(false,"face value (> 4) is out of range");
746  break;
747  }
748  }
749 
750  void PyrExp::v_ComputeTraceNormal(const int face)
751  {
752  const SpatialDomains::GeomFactorsSharedPtr &geomFactors =
753  GetGeom()->GetMetricInfo();
754 
756  for(int i = 0; i < ptsKeys.size(); ++i)
757  {
758  // Need at least 2 points for computing normals
759  if (ptsKeys[i].GetNumPoints() == 1)
760  {
761  LibUtilities::PointsKey pKey(2, ptsKeys[i].GetPointsType());
762  ptsKeys[i] = pKey;
763  }
764  }
765 
766  SpatialDomains::GeomType type = geomFactors->GetGtype();
767  const Array<TwoD, const NekDouble> &df = geomFactors->GetDerivFactors(ptsKeys);
768  const Array<OneD, const NekDouble> &jac = geomFactors->GetJac(ptsKeys);
769 
770  LibUtilities::BasisKey tobasis0 = GetTraceBasisKey(face,0);
771  LibUtilities::BasisKey tobasis1 = GetTraceBasisKey(face,1);
772 
773  // Number of quadrature points in face expansion.
774  int nq_face = tobasis0.GetNumPoints()*tobasis1.GetNumPoints();
775 
776  int vCoordDim = GetCoordim();
777  int i;
778 
781  for (i = 0; i < vCoordDim; ++i)
782  {
783  normal[i] = Array<OneD, NekDouble>(nq_face);
784  }
785 
786  size_t nqb = nq_face;
787  size_t nbnd= face;
790 
791  // Regular geometry case
792  if (type == SpatialDomains::eRegular ||
794  {
795  NekDouble fac;
796  // Set up normals
797  switch(face)
798  {
799  case 0:
800  {
801  for(i = 0; i < vCoordDim; ++i)
802  {
803  normal[i][0] = -df[3*i+2][0];
804  }
805  break;
806  }
807  case 1:
808  {
809  for(i = 0; i < vCoordDim; ++i)
810  {
811  normal[i][0] = -df[3*i+1][0];
812  }
813  break;
814  }
815  case 2:
816  {
817  for(i = 0; i < vCoordDim; ++i)
818  {
819  normal[i][0] = df[3*i][0]+df[3*i+2][0];
820  }
821  break;
822  }
823  case 3:
824  {
825  for(i = 0; i < vCoordDim; ++i)
826  {
827  normal[i][0] = df[3*i+1][0]+df[3*i+2][0];
828  }
829  break;
830  }
831  case 4:
832  {
833  for(i = 0; i < vCoordDim; ++i)
834  {
835  normal[i][0] = -df[3*i][0];
836  }
837  break;
838  }
839  default:
840  ASSERTL0(false,"face is out of range (face < 4)");
841  }
842 
843  // Normalise resulting vector.
844  fac = 0.0;
845  for(i = 0; i < vCoordDim; ++i)
846  {
847  fac += normal[i][0]*normal[i][0];
848  }
849  fac = 1.0/sqrt(fac);
850 
851  Vmath::Fill(nqb, fac, length, 1);
852 
853  for (i = 0; i < vCoordDim; ++i)
854  {
855  Vmath::Fill(nq_face,fac*normal[i][0],normal[i],1);
856  }
857  }
858  else
859  {
860  // Set up deformed normals.
861  int j, k;
862 
863  int nq0 = ptsKeys[0].GetNumPoints();
864  int nq1 = ptsKeys[1].GetNumPoints();
865  int nq2 = ptsKeys[2].GetNumPoints();
866  int nq01 = nq0*nq1;
867  int nqtot;
868 
869  // Determine number of quadrature points on the face.
870  if (face == 0)
871  {
872  nqtot = nq0*nq1;
873  }
874  else if (face == 1 || face == 3)
875  {
876  nqtot = nq0*nq2;
877  }
878  else
879  {
880  nqtot = nq1*nq2;
881  }
882 
883  LibUtilities::PointsKey points0;
884  LibUtilities::PointsKey points1;
885 
886  Array<OneD, NekDouble> faceJac(nqtot);
887  Array<OneD, NekDouble> normals(vCoordDim*nqtot,0.0);
888 
889  // Extract Jacobian along face and recover local derivatives
890  // (dx/dr) for polynomial interpolation by multiplying m_gmat by
891  // jacobian
892  switch(face)
893  {
894  case 0:
895  {
896  for(j = 0; j < nq01; ++j)
897  {
898  normals[j] = -df[2][j]*jac[j];
899  normals[nqtot+j] = -df[5][j]*jac[j];
900  normals[2*nqtot+j] = -df[8][j]*jac[j];
901  faceJac[j] = jac[j];
902  }
903 
904  points0 = ptsKeys[0];
905  points1 = ptsKeys[1];
906  break;
907  }
908 
909  case 1:
910  {
911  for (j = 0; j < nq0; ++j)
912  {
913  for(k = 0; k < nq2; ++k)
914  {
915  int tmp = j+nq01*k;
916  normals[j+k*nq0] =
917  -df[1][tmp]*jac[tmp];
918  normals[nqtot+j+k*nq0] =
919  -df[4][tmp]*jac[tmp];
920  normals[2*nqtot+j+k*nq0] =
921  -df[7][tmp]*jac[tmp];
922  faceJac[j+k*nq0] = jac[tmp];
923  }
924  }
925 
926  points0 = ptsKeys[0];
927  points1 = ptsKeys[2];
928  break;
929  }
930 
931  case 2:
932  {
933  for (j = 0; j < nq1; ++j)
934  {
935  for(k = 0; k < nq2; ++k)
936  {
937  int tmp = nq0-1+nq0*j+nq01*k;
938  normals[j+k*nq1] =
939  (df[0][tmp]+df[2][tmp])*jac[tmp];
940  normals[nqtot+j+k*nq1] =
941  (df[3][tmp]+df[5][tmp])*jac[tmp];
942  normals[2*nqtot+j+k*nq1] =
943  (df[6][tmp]+df[8][tmp])*jac[tmp];
944  faceJac[j+k*nq1] = jac[tmp];
945  }
946  }
947 
948  points0 = ptsKeys[1];
949  points1 = ptsKeys[2];
950  break;
951  }
952 
953  case 3:
954  {
955  for (j = 0; j < nq0; ++j)
956  {
957  for(k = 0; k < nq2; ++k)
958  {
959  int tmp = nq0*(nq1-1) + j + nq01*k;
960  normals[j+k*nq0] =
961  (df[1][tmp]+df[2][tmp])*jac[tmp];
962  normals[nqtot+j+k*nq0] =
963  (df[4][tmp]+df[5][tmp])*jac[tmp];
964  normals[2*nqtot+j+k*nq0] =
965  (df[7][tmp]+df[8][tmp])*jac[tmp];
966  faceJac[j+k*nq0] = jac[tmp];
967  }
968  }
969 
970  points0 = ptsKeys[0];
971  points1 = ptsKeys[2];
972  break;
973  }
974 
975  case 4:
976  {
977  for (j = 0; j < nq1; ++j)
978  {
979  for(k = 0; k < nq2; ++k)
980  {
981  int tmp = j*nq0+nq01*k;
982  normals[j+k*nq1] =
983  -df[0][tmp]*jac[tmp];
984  normals[nqtot+j+k*nq1] =
985  -df[3][tmp]*jac[tmp];
986  normals[2*nqtot+j+k*nq1] =
987  -df[6][tmp]*jac[tmp];
988  faceJac[j+k*nq1] = jac[tmp];
989  }
990  }
991 
992  points0 = ptsKeys[1];
993  points1 = ptsKeys[2];
994  break;
995  }
996 
997  default:
998  ASSERTL0(false,"face is out of range (face < 4)");
999  }
1000 
1001  Array<OneD, NekDouble> work (nq_face, 0.0);
1002  // Interpolate Jacobian and invert
1003  LibUtilities::Interp2D(points0, points1, faceJac,
1004  tobasis0.GetPointsKey(),
1005  tobasis1.GetPointsKey(),
1006  work);
1007  Vmath::Sdiv(nq_face, 1.0, &work[0], 1, &work[0], 1);
1008 
1009  // Interpolate normal and multiply by inverse Jacobian.
1010  for(i = 0; i < vCoordDim; ++i)
1011  {
1012  LibUtilities::Interp2D(points0, points1,
1013  &normals[i*nqtot],
1014  tobasis0.GetPointsKey(),
1015  tobasis1.GetPointsKey(),
1016  &normal[i][0]);
1017  Vmath::Vmul(nq_face,work,1,normal[i],1,normal[i],1);
1018  }
1019 
1020  // Normalise to obtain unit normals.
1021  Vmath::Zero(nq_face,work,1);
1022  for(i = 0; i < GetCoordim(); ++i)
1023  {
1024  Vmath::Vvtvp(nq_face,normal[i],1,normal[i],1,work,1,work,1);
1025  }
1026 
1027  Vmath::Vsqrt(nq_face,work,1,work,1);
1028  Vmath::Sdiv (nq_face,1.0,work,1,work,1);
1029 
1030  Vmath::Vcopy(nqb, work, 1, length, 1);
1031 
1032  for(i = 0; i < GetCoordim(); ++i)
1033  {
1034  Vmath::Vmul(nq_face,normal[i],1,work,1,normal[i],1);
1035  }
1036  }
1037  }
1038 
1040  Array<OneD, NekDouble> &array,
1041  const StdRegions::StdMatrixKey &mkey)
1042  {
1043  int nq = GetTotPoints();
1044 
1045  // Calculate sqrt of the Jacobian
1047  m_metricinfo->GetJac(GetPointsKeys());
1048  Array<OneD, NekDouble> sqrt_jac(nq);
1049  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1050  {
1051  Vmath::Vsqrt(nq,jac,1,sqrt_jac,1);
1052  }
1053  else
1054  {
1055  Vmath::Fill(nq,sqrt(jac[0]),sqrt_jac,1);
1056  }
1057 
1058  // Multiply array by sqrt(Jac)
1059  Vmath::Vmul(nq,sqrt_jac,1,array,1,array,1);
1060 
1061  // Apply std region filter
1062  StdPyrExp::v_SVVLaplacianFilter( array, mkey);
1063 
1064  // Divide by sqrt(Jac)
1065  Vmath::Vdiv(nq,array,1,sqrt_jac,1,array,1);
1066  }
1067 
1068 
1069  //---------------------------------------
1070  // Matrix creation functions
1071  //---------------------------------------
1072 
1074  {
1075  DNekMatSharedPtr returnval;
1076 
1077  switch(mkey.GetMatrixType())
1078  {
1085  returnval = Expansion3D::v_GenMatrix(mkey);
1086  break;
1087  default:
1088  returnval = StdPyrExp::v_GenMatrix(mkey);
1089  }
1090 
1091  return returnval;
1092  }
1093 
1095  {
1096  LibUtilities::BasisKey bkey0 = m_base[0]->GetBasisKey();
1097  LibUtilities::BasisKey bkey1 = m_base[1]->GetBasisKey();
1098  LibUtilities::BasisKey bkey2 = m_base[2]->GetBasisKey();
1100  MemoryManager<StdPyrExp>::AllocateSharedPtr(bkey0, bkey1, bkey2);
1101 
1102  return tmp->GetStdMatrix(mkey);
1103  }
1104 
1106  {
1107  return m_matrixManager[mkey];
1108  }
1109 
1111  {
1112  return m_staticCondMatrixManager[mkey];
1113  }
1114 
1116  {
1117  m_staticCondMatrixManager.DeleteObject(mkey);
1118  }
1119 
1121  {
1122  DNekScalMatSharedPtr returnval;
1124 
1125  ASSERTL2(m_metricinfo->GetGtype() != SpatialDomains::eNoGeomType,"Geometric information is not set up");
1126 
1127  switch(mkey.GetMatrixType())
1128  {
1129  case StdRegions::eMass:
1130  {
1131  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1132  {
1133  NekDouble one = 1.0;
1134  DNekMatSharedPtr mat = GenMatrix(mkey);
1135  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,mat);
1136  }
1137  else
1138  {
1139  NekDouble jac = (m_metricinfo->GetJac(ptsKeys))[0];
1140  DNekMatSharedPtr mat = GetStdMatrix(mkey);
1141  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(jac,mat);
1142  }
1143  }
1144  break;
1145  case StdRegions::eInvMass:
1146  {
1147  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1148  {
1149  NekDouble one = 1.0;
1151  *this);
1152  DNekMatSharedPtr mat = GenMatrix(masskey);
1153  mat->Invert();
1154  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,mat);
1155  }
1156  else
1157  {
1158  NekDouble fac = 1.0/(m_metricinfo->GetJac(ptsKeys))[0];
1159  DNekMatSharedPtr mat = GetStdMatrix(mkey);
1160  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(fac,mat);
1161  }
1162  }
1163  break;
1165  {
1166  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed ||
1167  mkey.GetNVarCoeff() > 0 ||
1168  mkey.ConstFactorExists(
1170  {
1171  NekDouble one = 1.0;
1172  DNekMatSharedPtr mat = GenMatrix(mkey);
1173 
1174  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,mat);
1175  }
1176  else
1177  {
1179  mkey.GetShapeType(), *this);
1181  mkey.GetShapeType(), *this);
1183  mkey.GetShapeType(), *this);
1185  mkey.GetShapeType(), *this);
1187  mkey.GetShapeType(), *this);
1189  mkey.GetShapeType(), *this);
1190 
1191  DNekMat &lap00 = *GetStdMatrix(lap00key);
1192  DNekMat &lap01 = *GetStdMatrix(lap01key);
1193  DNekMat &lap02 = *GetStdMatrix(lap02key);
1194  DNekMat &lap11 = *GetStdMatrix(lap11key);
1195  DNekMat &lap12 = *GetStdMatrix(lap12key);
1196  DNekMat &lap22 = *GetStdMatrix(lap22key);
1197 
1198  NekDouble jac = (m_metricinfo->GetJac(ptsKeys))[0];
1200  m_metricinfo->GetGmat(ptsKeys);
1201 
1202  int rows = lap00.GetRows();
1203  int cols = lap00.GetColumns();
1204 
1206  ::AllocateSharedPtr(rows,cols);
1207 
1208  (*lap) = gmat[0][0]*lap00
1209  + gmat[4][0]*lap11
1210  + gmat[8][0]*lap22
1211  + gmat[3][0]*(lap01 + Transpose(lap01))
1212  + gmat[6][0]*(lap02 + Transpose(lap02))
1213  + gmat[7][0]*(lap12 + Transpose(lap12));
1214 
1215  returnval = MemoryManager<DNekScalMat>
1216  ::AllocateSharedPtr(jac, lap);
1217  }
1218  }
1219  break;
1221  {
1223  MatrixKey masskey(StdRegions::eMass, mkey.GetShapeType(), *this);
1224  DNekScalMat &MassMat = *(this->m_matrixManager[masskey]);
1225  MatrixKey lapkey(StdRegions::eLaplacian, mkey.GetShapeType(), *this, mkey.GetConstFactors(), mkey.GetVarCoeffs());
1226  DNekScalMat &LapMat = *(this->m_matrixManager[lapkey]);
1227 
1228  int rows = LapMat.GetRows();
1229  int cols = LapMat.GetColumns();
1230 
1232 
1233  (*helm) = LapMat + factor*MassMat;
1234 
1235  returnval = MemoryManager<DNekScalMat>::AllocateSharedPtr(1.0, helm);
1236  }
1237  break;
1239  {
1240  NekDouble one = 1.0;
1241  MatrixKey helmkey(StdRegions::eHelmholtz, mkey.GetShapeType(), *this, mkey.GetConstFactors(), mkey.GetVarCoeffs());
1242  DNekScalBlkMatSharedPtr helmStatCond = GetLocStaticCondMatrix(helmkey);
1243  DNekScalMatSharedPtr A =helmStatCond->GetBlock(0,0);
1245 
1247  }
1248  break;
1250  {
1251  NekDouble one = 1.0;
1252  MatrixKey masskey(StdRegions::eMass, mkey.GetShapeType(), *this);
1253  DNekScalBlkMatSharedPtr massStatCond = GetLocStaticCondMatrix(masskey);
1254  DNekScalMatSharedPtr A =massStatCond->GetBlock(0,0);
1256 
1258  }
1259  break;
1260  default:
1261  NEKERROR(ErrorUtil::efatal, "Matrix creation not defined");
1262  break;
1263  }
1264 
1265  return returnval;
1266  }
1267 
1269  {
1270  DNekScalBlkMatSharedPtr returnval;
1271 
1272  ASSERTL2(m_metricinfo->GetGtype() != SpatialDomains::eNoGeomType,"Geometric information is not set up");
1273 
1274  // set up block matrix system
1275  unsigned int nbdry = NumBndryCoeffs();
1276  unsigned int nint = (unsigned int)(m_ncoeffs - nbdry);
1277  unsigned int exp_size[] = {nbdry, nint};
1278  unsigned int nblks = 2;
1279  returnval = MemoryManager<DNekScalBlkMat>::AllocateSharedPtr(nblks, nblks, exp_size, exp_size); //Really need a constructor which takes Arrays
1280  NekDouble factor = 1.0;
1281 
1282  switch(mkey.GetMatrixType())
1283  {
1285  case StdRegions::eHelmholtz: // special case since Helmholtz not defined in StdRegions
1286 
1287  // use Deformed case for both regular and deformed geometries
1288  factor = 1.0;
1289  goto UseLocRegionsMatrix;
1290  break;
1291  default:
1292  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1293  {
1294  factor = 1.0;
1295  goto UseLocRegionsMatrix;
1296  }
1297  else
1298  {
1299  DNekScalMatSharedPtr mat = GetLocMatrix(mkey);
1300  factor = mat->Scale();
1301  goto UseStdRegionsMatrix;
1302  }
1303  break;
1304  UseStdRegionsMatrix:
1305  {
1306  NekDouble invfactor = 1.0/factor;
1307  NekDouble one = 1.0;
1309  DNekScalMatSharedPtr Atmp;
1310  DNekMatSharedPtr Asubmat;
1311 
1312  //TODO: check below
1313  returnval->SetBlock(0,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,Asubmat = mat->GetBlock(0,0)));
1314  returnval->SetBlock(0,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,Asubmat = mat->GetBlock(0,1)));
1315  returnval->SetBlock(1,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,Asubmat = mat->GetBlock(1,0)));
1316  returnval->SetBlock(1,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(invfactor,Asubmat = mat->GetBlock(1,1)));
1317  }
1318  break;
1319  UseLocRegionsMatrix:
1320  {
1321  int i,j;
1322  NekDouble invfactor = 1.0/factor;
1323  NekDouble one = 1.0;
1324  DNekScalMat &mat = *GetLocMatrix(mkey);
1329 
1330  Array<OneD,unsigned int> bmap(nbdry);
1331  Array<OneD,unsigned int> imap(nint);
1332  GetBoundaryMap(bmap);
1333  GetInteriorMap(imap);
1334 
1335  for(i = 0; i < nbdry; ++i)
1336  {
1337  for(j = 0; j < nbdry; ++j)
1338  {
1339  (*A)(i,j) = mat(bmap[i],bmap[j]);
1340  }
1341 
1342  for(j = 0; j < nint; ++j)
1343  {
1344  (*B)(i,j) = mat(bmap[i],imap[j]);
1345  }
1346  }
1347 
1348  for(i = 0; i < nint; ++i)
1349  {
1350  for(j = 0; j < nbdry; ++j)
1351  {
1352  (*C)(i,j) = mat(imap[i],bmap[j]);
1353  }
1354 
1355  for(j = 0; j < nint; ++j)
1356  {
1357  (*D)(i,j) = mat(imap[i],imap[j]);
1358  }
1359  }
1360 
1361  // Calculate static condensed system
1362  if(nint)
1363  {
1364  D->Invert();
1365  (*B) = (*B)*(*D);
1366  (*A) = (*A) - (*B)*(*C);
1367  }
1368 
1369  DNekScalMatSharedPtr Atmp;
1370 
1371  returnval->SetBlock(0,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,A));
1372  returnval->SetBlock(0,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(one,B));
1373  returnval->SetBlock(1,0,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(factor,C));
1374  returnval->SetBlock(1,1,Atmp = MemoryManager<DNekScalMat>::AllocateSharedPtr(invfactor,D));
1375  }
1376  }
1377  return returnval;
1378  }
1379 
1381  {
1382  if (m_metrics.count(eMetricQuadrature) == 0)
1383  {
1385  }
1386 
1387  int i, j;
1388  const unsigned int nqtot = GetTotPoints();
1389  const unsigned int dim = 3;
1390  const MetricType m[3][3] = {
1394  };
1395 
1396  for (unsigned int i = 0; i < dim; ++i)
1397  {
1398  for (unsigned int j = i; j < dim; ++j)
1399  {
1400  m_metrics[m[i][j]] = Array<OneD, NekDouble>(nqtot);
1401  }
1402  }
1403 
1404  // Define shorthand synonyms for m_metrics storage
1405  Array<OneD,NekDouble> g0 (m_metrics[m[0][0]]);
1406  Array<OneD,NekDouble> g1 (m_metrics[m[1][1]]);
1407  Array<OneD,NekDouble> g2 (m_metrics[m[2][2]]);
1408  Array<OneD,NekDouble> g3 (m_metrics[m[0][1]]);
1409  Array<OneD,NekDouble> g4 (m_metrics[m[0][2]]);
1410  Array<OneD,NekDouble> g5 (m_metrics[m[1][2]]);
1411 
1412  // Allocate temporary storage
1413  Array<OneD,NekDouble> alloc(9*nqtot,0.0);
1414  Array<OneD,NekDouble> h0 (nqtot, alloc);
1415  Array<OneD,NekDouble> h1 (nqtot, alloc+ 1*nqtot);
1416  Array<OneD,NekDouble> h2 (nqtot, alloc+ 2*nqtot);
1417  Array<OneD,NekDouble> wsp1 (nqtot, alloc+ 3*nqtot);
1418  Array<OneD,NekDouble> wsp2 (nqtot, alloc+ 4*nqtot);
1419  Array<OneD,NekDouble> wsp3 (nqtot, alloc+ 5*nqtot);
1420  Array<OneD,NekDouble> wsp4 (nqtot, alloc+ 6*nqtot);
1421  Array<OneD,NekDouble> wsp5 (nqtot, alloc+ 7*nqtot);
1422  Array<OneD,NekDouble> wsp6 (nqtot, alloc+ 8*nqtot);
1423 
1424  const Array<TwoD, const NekDouble>& df =
1425  m_metricinfo->GetDerivFactors(GetPointsKeys());
1426  const Array<OneD, const NekDouble>& z0 = m_base[0]->GetZ();
1427  const Array<OneD, const NekDouble>& z1 = m_base[1]->GetZ();
1428  const Array<OneD, const NekDouble>& z2 = m_base[2]->GetZ();
1429  const unsigned int nquad0 = m_base[0]->GetNumPoints();
1430  const unsigned int nquad1 = m_base[1]->GetNumPoints();
1431  const unsigned int nquad2 = m_base[2]->GetNumPoints();
1432 
1433  // Populate collapsed coordinate arrays h0, h1 and h2.
1434  for(j = 0; j < nquad2; ++j)
1435  {
1436  for(i = 0; i < nquad1; ++i)
1437  {
1438  Vmath::Fill(nquad0, 2.0/(1.0-z2[j]), &h0[0]+i*nquad0 + j*nquad0*nquad1,1);
1439  Vmath::Fill(nquad0, 1.0/(1.0-z2[j]), &h1[0]+i*nquad0 + j*nquad0*nquad1,1);
1440  Vmath::Fill(nquad0, (1.0+z1[i])/(1.0-z2[j]), &h2[0]+i*nquad0 + j*nquad0*nquad1,1);
1441  }
1442  }
1443  for(i = 0; i < nquad0; i++)
1444  {
1445  Blas::Dscal(nquad1*nquad2, 1+z0[i], &h1[0]+i, nquad0);
1446  }
1447 
1448  // Step 3. Construct combined metric terms for physical space to
1449  // collapsed coordinate system.
1450  // Order of construction optimised to minimise temporary storage
1451  if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1452  {
1453  // f_{1k}
1454  Vmath::Vvtvvtp(nqtot, &df[0][0], 1, &h0[0], 1, &df[2][0], 1, &h1[0], 1, &wsp1[0], 1);
1455  Vmath::Vvtvvtp(nqtot, &df[3][0], 1, &h0[0], 1, &df[5][0], 1, &h1[0], 1, &wsp2[0], 1);
1456  Vmath::Vvtvvtp(nqtot, &df[6][0], 1, &h0[0], 1, &df[8][0], 1, &h1[0], 1, &wsp3[0], 1);
1457 
1458  // g0
1459  Vmath::Vvtvvtp(nqtot, &wsp1[0], 1, &wsp1[0], 1, &wsp2[0], 1, &wsp2[0], 1, &g0[0], 1);
1460  Vmath::Vvtvp (nqtot, &wsp3[0], 1, &wsp3[0], 1, &g0[0], 1, &g0[0], 1);
1461 
1462  // g4
1463  Vmath::Vvtvvtp(nqtot, &df[2][0], 1, &wsp1[0], 1, &df[5][0], 1, &wsp2[0], 1, &g4[0], 1);
1464  Vmath::Vvtvp (nqtot, &df[8][0], 1, &wsp3[0], 1, &g4[0], 1, &g4[0], 1);
1465 
1466  // f_{2k}
1467  Vmath::Vvtvvtp(nqtot, &df[1][0], 1, &h0[0], 1, &df[2][0], 1, &h2[0], 1, &wsp4[0], 1);
1468  Vmath::Vvtvvtp(nqtot, &df[4][0], 1, &h0[0], 1, &df[5][0], 1, &h2[0], 1, &wsp5[0], 1);
1469  Vmath::Vvtvvtp(nqtot, &df[7][0], 1, &h0[0], 1, &df[8][0], 1, &h2[0], 1, &wsp6[0], 1);
1470 
1471  // g1
1472  Vmath::Vvtvvtp(nqtot, &wsp4[0], 1, &wsp4[0], 1, &wsp5[0], 1, &wsp5[0], 1, &g1[0], 1);
1473  Vmath::Vvtvp (nqtot, &wsp6[0], 1, &wsp6[0], 1, &g1[0], 1, &g1[0], 1);
1474 
1475  // g3
1476  Vmath::Vvtvvtp(nqtot, &wsp1[0], 1, &wsp4[0], 1, &wsp2[0], 1, &wsp5[0], 1, &g3[0], 1);
1477  Vmath::Vvtvp (nqtot, &wsp3[0], 1, &wsp6[0], 1, &g3[0], 1, &g3[0], 1);
1478 
1479  // g5
1480  Vmath::Vvtvvtp(nqtot, &df[2][0], 1, &wsp4[0], 1, &df[5][0], 1, &wsp5[0], 1, &g5[0], 1);
1481  Vmath::Vvtvp (nqtot, &df[8][0], 1, &wsp6[0], 1, &g5[0], 1, &g5[0], 1);
1482 
1483  // g2
1484  Vmath::Vvtvvtp(nqtot, &df[2][0], 1, &df[2][0], 1, &df[5][0], 1, &df[5][0], 1, &g2[0], 1);
1485  Vmath::Vvtvp (nqtot, &df[8][0], 1, &df[8][0], 1, &g2[0], 1, &g2[0], 1);
1486  }
1487  else
1488  {
1489  // f_{1k}
1490  Vmath::Svtsvtp(nqtot, df[0][0], &h0[0], 1, df[2][0], &h1[0], 1, &wsp1[0], 1);
1491  Vmath::Svtsvtp(nqtot, df[3][0], &h0[0], 1, df[5][0], &h1[0], 1, &wsp2[0], 1);
1492  Vmath::Svtsvtp(nqtot, df[6][0], &h0[0], 1, df[8][0], &h1[0], 1, &wsp3[0], 1);
1493 
1494  // g0
1495  Vmath::Vvtvvtp(nqtot, &wsp1[0], 1, &wsp1[0], 1, &wsp2[0], 1, &wsp2[0], 1, &g0[0], 1);
1496  Vmath::Vvtvp (nqtot, &wsp3[0], 1, &wsp3[0], 1, &g0[0], 1, &g0[0], 1);
1497 
1498  // g4
1499  Vmath::Svtsvtp(nqtot, df[2][0], &wsp1[0], 1, df[5][0], &wsp2[0], 1, &g4[0], 1);
1500  Vmath::Svtvp (nqtot, df[8][0], &wsp3[0], 1, &g4[0], 1, &g4[0], 1);
1501 
1502  // f_{2k}
1503  Vmath::Svtsvtp(nqtot, df[1][0], &h0[0], 1, df[2][0], &h2[0], 1, &wsp4[0], 1);
1504  Vmath::Svtsvtp(nqtot, df[4][0], &h0[0], 1, df[5][0], &h2[0], 1, &wsp5[0], 1);
1505  Vmath::Svtsvtp(nqtot, df[7][0], &h0[0], 1, df[8][0], &h2[0], 1, &wsp6[0], 1);
1506 
1507  // g1
1508  Vmath::Vvtvvtp(nqtot, &wsp4[0], 1, &wsp4[0], 1, &wsp5[0], 1, &wsp5[0], 1, &g1[0], 1);
1509  Vmath::Vvtvp (nqtot, &wsp6[0], 1, &wsp6[0], 1, &g1[0], 1, &g1[0], 1);
1510 
1511  // g3
1512  Vmath::Vvtvvtp(nqtot, &wsp1[0], 1, &wsp4[0], 1, &wsp2[0], 1, &wsp5[0], 1, &g3[0], 1);
1513  Vmath::Vvtvp (nqtot, &wsp3[0], 1, &wsp6[0], 1, &g3[0], 1, &g3[0], 1);
1514 
1515  // g5
1516  Vmath::Svtsvtp(nqtot, df[2][0], &wsp4[0], 1, df[5][0], &wsp5[0], 1, &g5[0], 1);
1517  Vmath::Svtvp (nqtot, df[8][0], &wsp6[0], 1, &g5[0], 1, &g5[0], 1);
1518 
1519  // g2
1520  Vmath::Fill(nqtot, df[2][0]*df[2][0] + df[5][0]*df[5][0] + df[8][0]*df[8][0], &g2[0], 1);
1521  }
1522 
1523  for (unsigned int i = 0; i < dim; ++i)
1524  {
1525  for (unsigned int j = i; j < dim; ++j)
1526  {
1528  m_metrics[m[i][j]]);
1529 
1530  }
1531  }
1532  }
1533 
1535  const Array<OneD, const NekDouble> &inarray,
1536  Array<OneD, NekDouble> &outarray,
1538  {
1539  // This implementation is only valid when there are no coefficients
1540  // associated to the Laplacian operator
1541  if (m_metrics.count(eMetricLaplacian00) == 0)
1542  {
1544  }
1545 
1546  int nquad0 = m_base[0]->GetNumPoints();
1547  int nquad1 = m_base[1]->GetNumPoints();
1548  int nq2 = m_base[2]->GetNumPoints();
1549  int nqtot = nquad0*nquad1*nq2;
1550 
1551  ASSERTL1(wsp.size() >= 6*nqtot,
1552  "Insufficient workspace size.");
1553  ASSERTL1(m_ncoeffs <= nqtot,
1554  "Workspace not set up for ncoeffs > nqtot");
1555 
1556  const Array<OneD, const NekDouble>& base0 = m_base[0]->GetBdata();
1557  const Array<OneD, const NekDouble>& base1 = m_base[1]->GetBdata();
1558  const Array<OneD, const NekDouble>& base2 = m_base[2]->GetBdata();
1559  const Array<OneD, const NekDouble>& dbase0 = m_base[0]->GetDbdata();
1560  const Array<OneD, const NekDouble>& dbase1 = m_base[1]->GetDbdata();
1561  const Array<OneD, const NekDouble>& dbase2 = m_base[2]->GetDbdata();
1568 
1569  // Allocate temporary storage
1570  Array<OneD,NekDouble> wsp0 (2*nqtot, wsp);
1571  Array<OneD,NekDouble> wsp1 ( nqtot, wsp+1*nqtot);
1572  Array<OneD,NekDouble> wsp2 ( nqtot, wsp+2*nqtot);
1573  Array<OneD,NekDouble> wsp3 ( nqtot, wsp+3*nqtot);
1574  Array<OneD,NekDouble> wsp4 ( nqtot, wsp+4*nqtot);
1575  Array<OneD,NekDouble> wsp5 ( nqtot, wsp+5*nqtot);
1576 
1577  // LAPLACIAN MATRIX OPERATION
1578  // wsp1 = du_dxi1 = D_xi1 * inarray = D_xi1 * u
1579  // wsp2 = du_dxi2 = D_xi2 * inarray = D_xi2 * u
1580  // wsp2 = du_dxi3 = D_xi3 * inarray = D_xi3 * u
1581  StdExpansion3D::PhysTensorDeriv(inarray,wsp0,wsp1,wsp2);
1582 
1583  // wsp0 = k = g0 * wsp1 + g1 * wsp2 = g0 * du_dxi1 + g1 * du_dxi2
1584  // wsp2 = l = g1 * wsp1 + g2 * wsp2 = g0 * du_dxi1 + g1 * du_dxi2
1585  // where g0, g1 and g2 are the metric terms set up in the GeomFactors class
1586  // especially for this purpose
1587  Vmath::Vvtvvtp(nqtot,&metric00[0],1,&wsp0[0],1,&metric01[0],1,&wsp1[0],1,&wsp3[0],1);
1588  Vmath::Vvtvp (nqtot,&metric02[0],1,&wsp2[0],1,&wsp3[0],1,&wsp3[0],1);
1589  Vmath::Vvtvvtp(nqtot,&metric01[0],1,&wsp0[0],1,&metric11[0],1,&wsp1[0],1,&wsp4[0],1);
1590  Vmath::Vvtvp (nqtot,&metric12[0],1,&wsp2[0],1,&wsp4[0],1,&wsp4[0],1);
1591  Vmath::Vvtvvtp(nqtot,&metric02[0],1,&wsp0[0],1,&metric12[0],1,&wsp1[0],1,&wsp5[0],1);
1592  Vmath::Vvtvp (nqtot,&metric22[0],1,&wsp2[0],1,&wsp5[0],1,&wsp5[0],1);
1593 
1594  // outarray = m = (D_xi1 * B)^T * k
1595  // wsp1 = n = (D_xi2 * B)^T * l
1596  IProductWRTBase_SumFacKernel(dbase0,base1,base2,wsp3,outarray,wsp0,false,true,true);
1597  IProductWRTBase_SumFacKernel(base0,dbase1,base2,wsp4,wsp2, wsp0,true,false,true);
1598  Vmath::Vadd(m_ncoeffs,wsp2.get(),1,outarray.get(),1,outarray.get(),1);
1599  IProductWRTBase_SumFacKernel(base0,base1,dbase2,wsp5,wsp2, wsp0,true,true,false);
1600  Vmath::Vadd(m_ncoeffs,wsp2.get(),1,outarray.get(),1,outarray.get(),1);
1601  }
1602  }//end of namespace
1603 }//end of namespace
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:250
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
Definition: ErrorUtil.hpp:274
Describes the specification for a Basis.
Definition: Basis.h:50
int GetNumPoints() const
Return points order at which basis is defined.
Definition: Basis.h:133
PointsKey GetPointsKey() const
Return distribution of points.
Definition: Basis.h:150
Defines a specification for a set of points.
Definition: Points.h:60
std::map< int, NormalVector > m_faceNormals
Definition: Expansion3D.h:123
virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey)
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
DNekMatSharedPtr BuildVertexMatrix(const DNekScalMatSharedPtr &r_bnd)
Definition: Expansion.cpp:103
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
virtual int v_GetCoordim()
Definition: PyrExp.cpp:645
virtual StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const
Definition: PyrExp.cpp:515
virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey)
Definition: PyrExp.cpp:1073
LibUtilities::NekManager< MatrixKey, DNekScalMat, MatrixKey::opLess > m_matrixManager
Definition: PyrExp.h:186
virtual void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdRegions::StdMatrixKey &mkey)
Definition: PyrExp.cpp:1039
virtual DNekScalMatSharedPtr v_GetLocMatrix(const MatrixKey &mkey)
Definition: PyrExp.cpp:1105
void v_DropLocStaticCondMatrix(const MatrixKey &mkey)
Definition: PyrExp.cpp:1115
virtual void v_PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1, Array< OneD, NekDouble > &out_d2)
Calculate the derivative of the physical points.
Definition: PyrExp.cpp:138
virtual void v_GetTracePhysMap(const int face, Array< OneD, int > &outarray)
Definition: PyrExp.cpp:650
virtual DNekMatSharedPtr v_CreateStdMatrix(const StdRegions::StdMatrixKey &mkey)
Definition: PyrExp.cpp:1094
virtual void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Calculate the inner product of inarray with respect to the basis B=base0*base1*base2 and put into out...
Definition: PyrExp.cpp:278
void v_IProductWRTDerivBase_SumFac(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: PyrExp.cpp:359
virtual NekDouble v_PhysEvaluate(const Array< OneD, const NekDouble > &coord, const Array< OneD, const NekDouble > &physvals)
This function evaluates the expansion at a single (arbitrary) point of the domain.
Definition: PyrExp.cpp:627
LibUtilities::NekManager< MatrixKey, DNekScalBlkMat, MatrixKey::opLess > m_staticCondMatrixManager
Definition: PyrExp.h:187
NekDouble v_StdPhysEvaluate(const Array< OneD, const NekDouble > &Lcoord, const Array< OneD, const NekDouble > &physvals)
Definition: PyrExp.cpp:619
void v_ComputeTraceNormal(const int face)
Definition: PyrExp.cpp:750
virtual void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3)
Definition: PyrExp.cpp:550
virtual void v_ComputeLaplacianMetric()
Definition: PyrExp.cpp:1380
virtual StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const
Definition: PyrExp.cpp:507
PyrExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::BasisKey &Bc, const SpatialDomains::PyrGeomSharedPtr &geom)
Constructor using BasisKey class for quadrature points and order definition.
Definition: PyrExp.cpp:45
virtual DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix(const MatrixKey &mkey)
Definition: PyrExp.cpp:1110
virtual void v_GetCoord(const Array< OneD, const NekDouble > &Lcoords, Array< OneD, NekDouble > &coords)
Definition: PyrExp.cpp:532
virtual NekDouble v_Integral(const Array< OneD, const NekDouble > &inarray)
Integrate the physical point list inarray over pyramidic region and return the value.
Definition: PyrExp.cpp:111
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: PyrExp.cpp:220
virtual void v_ExtractDataToCoeffs(const NekDouble *data, const std::vector< unsigned int > &nummodes, const int mode_offset, NekDouble *coeffs, std::vector< LibUtilities::BasisType > &fromType)
Definition: PyrExp.cpp:559
void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Calculates the inner product .
Definition: PyrExp.cpp:351
virtual void v_IProductWRTBase_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool multiplybyweights=true)
Definition: PyrExp.cpp:285
DNekScalMatSharedPtr CreateMatrix(const MatrixKey &mkey)
Definition: PyrExp.cpp:1120
virtual void v_LaplacianMatrixOp_MatFree_Kernel(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp)
Definition: PyrExp.cpp:1534
virtual void v_AlignVectorToCollapsedDir(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
Definition: PyrExp.cpp:410
DNekScalBlkMatSharedPtr CreateStaticCondMatrix(const MatrixKey &mkey)
Definition: PyrExp.cpp:1268
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
void IProductWRTBase_SumFacKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp, bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2)
void GetBoundaryMap(Array< OneD, unsigned int > &outarray)
Definition: StdExpansion.h:687
int GetNcoeffs(void) const
This function returns the total number of coefficients used in the expansion.
Definition: StdExpansion.h:124
int GetTotPoints() const
This function returns the total number of quadrature points used in the element.
Definition: StdExpansion.h:134
LibUtilities::BasisType GetBasisType(const int dir) const
This function returns the type of basis used in the dir direction.
Definition: StdExpansion.h:158
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:617
const LibUtilities::PointsKeyVector GetPointsKeys() const
DNekBlkMatSharedPtr GetStdStaticCondMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:622
DNekScalBlkMatSharedPtr GetLocStaticCondMatrix(const LocalRegions::MatrixKey &mkey)
Definition: StdExpansion.h:660
const LibUtilities::BasisKey GetTraceBasisKey(const int i, int k=-1) const
This function returns the basis key belonging to the i-th trace.
Definition: StdExpansion.h:304
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
void FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function performs the Forward transformation from physical space to coefficient space.
int GetNumPoints(const int dir) const
This function returns the number of quadrature points in the dir direction.
Definition: StdExpansion.h:221
void MultiplyByQuadratureMetric(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition: StdExpansion.h:733
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
bool ConstFactorExists(const ConstFactorType &factor) const
Definition: StdMatrixKey.h:130
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 void Daxpy(const int &n, const double &alpha, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: y = alpha x plus y.
Definition: Blas.hpp:167
void Interp2D(const BasisKey &fbasis0, const BasisKey &fbasis1, const Array< OneD, const NekDouble > &from, const BasisKey &tbasis0, const BasisKey &tbasis1, Array< OneD, NekDouble > &to)
this function interpolates a 2D function evaluated at the quadrature points of the 2D basis,...
Definition: Interp.cpp:115
std::vector< PointsKey > PointsKeyVector
Definition: Points.h:246
std::shared_ptr< GeomFactors > GeomFactorsSharedPtr
Pointer to a GeomFactors object.
Definition: GeomFactors.h:62
GeomType
Indicates the type of element geometry.
@ eRegular
Geometry is straight-sided with constant geometric factors.
@ eNoGeomType
No type defined.
@ eMovingRegular
Currently unused.
@ eDeformed
Geometry is curved or has non-constant factors.
std::shared_ptr< PyrGeom > PyrGeomSharedPtr
Definition: PyrGeom.h:74
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
std::shared_ptr< StdPyrExp > StdPyrExpSharedPtr
Definition: StdPyrExp.h:278
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
std::shared_ptr< DNekBlkMat > DNekBlkMatSharedPtr
Definition: NekTypeDefs.hpp:71
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
Definition: NekTypeDefs.hpp:73
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:69
double NekDouble
void Vsqrt(int n, const T *x, const int incx, T *y, const int incy)
sqrt y = sqrt(x)
Definition: Vmath.cpp:475
void Svtsvtp(int n, const T alpha, const T *x, int incx, const T beta, const T *y, int incy, T *z, int incz)
vvtvvtp (scalar times vector plus scalar times vector):
Definition: Vmath.cpp:691
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 Sdiv(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha/y.
Definition: Vmath.cpp:291
void 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 Vvtvvtp(int n, const T *v, int incv, const T *w, int incw, const T *x, int incx, const T *y, int incy, T *z, int incz)
vvtvvtp (vector times vector plus vector times vector):
Definition: Vmath.cpp:625
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1199
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:267