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