Nektar++
Loading...
Searching...
No Matches
PrismExp.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: PrismExp.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: PrismExp routines
32//
33///////////////////////////////////////////////////////////////////////////////
34
39
40using namespace std;
41
43{
44
46 const LibUtilities::BasisKey &Bb,
47 const LibUtilities::BasisKey &Bc,
49 : StdExpansion(LibUtilities::StdPrismData::getNumberOfCoefficients(
50 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
51 3, Ba, Bb, Bc),
52 StdExpansion3D(LibUtilities::StdPrismData::getNumberOfCoefficients(
53 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
54 Ba, Bb, Bc),
55 StdPrismExp(Ba, Bb, Bc), Expansion(geom), Expansion3D(geom),
56 m_matrixManager(
57 std::bind(&Expansion3D::CreateMatrix, this, std::placeholders::_1)),
58 m_staticCondMatrixManager(std::bind(&Expansion::CreateStaticCondMatrix,
59 this, std::placeholders::_1))
60{
61}
62
64 : StdExpansion(T), StdExpansion3D(T), StdPrismExp(T), Expansion(T),
65 Expansion3D(T), m_matrixManager(T.m_matrixManager),
66 m_staticCondMatrixManager(T.m_staticCondMatrixManager)
67{
68}
69
70//---------------------------------------
71// Inner product functions
72//---------------------------------------
73/**
74 * @brief Calculates the inner product \f$ I_{pqr} = (u,
75 * \partial_{x_i} \phi_{pqr}) \f$.
76 *
77 * The derivative of the basis functions is performed using the chain
78 * rule in order to incorporate the geometric factors. Assuming that
79 * the basis functions are a tensor product
80 * \f$\phi_{pqr}(\eta_1,\eta_2,\eta_3) =
81 * \phi_1(\eta_1)\phi_2(\eta_2)\phi_3(\eta_3)\f$, this yields the
82 * result
83 *
84 * \f[
85 * I_{pqr} = \sum_{j=1}^3 \left(u, \frac{\partial u}{\partial \eta_j}
86 * \frac{\partial \eta_j}{\partial x_i}\right)
87 * \f]
88 *
89 * In the tetrahedral element, we must also incorporate a second set
90 * of geometric factors which incorporate the collapsed co-ordinate
91 * system, so that
92 *
93 * \f[ \frac{\partial\eta_j}{\partial x_i} = \sum_{k=1}^3
94 * \frac{\partial\eta_j}{\partial\xi_k}\frac{\partial\xi_k}{\partial
95 * x_i} \f]
96 *
97 * These derivatives can be found on p152 of Sherwin & Karniadakis.
98 *
99 * @param dir Direction in which to take the derivative.
100 * @param inarray The function \f$ u \f$.
101 * @param outarray Value of the inner product.
102 */
104 const int dir, const Array<OneD, const NekDouble> &inarray,
105 Array<OneD, NekDouble> &outarray)
106{
107 const int nquad0 = m_base[0]->GetNumPoints();
108 const int nquad1 = m_base[1]->GetNumPoints();
109 const int nquad2 = m_base[2]->GetNumPoints();
110 const int nqtot = nquad0 * nquad1 * nquad2;
111
112 Array<OneD, NekDouble> tmp2(nqtot);
113 Array<OneD, NekDouble> tmp3(nqtot);
114 Array<OneD, NekDouble> tmp4(nqtot);
116
118 tmp2D[0] = tmp2;
119 tmp2D[1] = tmp3;
120 tmp2D[2] = tmp4;
121
122 const Array<OneD, const NekDouble> &jac = m_geomFactors->GetJac();
123 bool Deformed = (m_geomFactors->GetGtype() == SpatialDomains::eDeformed);
124
125 v_AlignVectorToCollapsedDir(dir, inarray, tmp2D);
126
127 v_IProductWRTBaseKernel(m_base[0]->GetDbdata(), m_base[1]->GetBdata(),
128 m_base[2]->GetBdata(), tmp2, outarray, jac,
129 Deformed);
130
131 v_IProductWRTBaseKernel(m_base[0]->GetBdata(), m_base[1]->GetDbdata(),
132 m_base[2]->GetBdata(), tmp3, tmp6, jac, Deformed);
133 Vmath::Vadd(m_ncoeffs, tmp6, 1, outarray, 1, outarray, 1);
134
135 v_IProductWRTBaseKernel(m_base[0]->GetBdata(), m_base[1]->GetBdata(),
136 m_base[2]->GetDbdata(), tmp4, tmp6, jac, Deformed);
137 Vmath::Vadd(m_ncoeffs, tmp6, 1, outarray, 1, outarray, 1);
138}
139
141 const int dir, const Array<OneD, const NekDouble> &inarray,
143{
144 const int nquad0 = m_base[0]->GetNumPoints();
145 const int nquad1 = m_base[1]->GetNumPoints();
146 const int nquad2 = m_base[2]->GetNumPoints();
147 const int nqtot = nquad0 * nquad1 * nquad2;
148
149 const Array<OneD, const NekDouble> &z0 = m_base[0]->GetZ();
150 const Array<OneD, const NekDouble> &z2 = m_base[2]->GetZ();
151
152 Array<OneD, NekDouble> tmp1(nqtot);
153
154 Array<OneD, NekDouble> tmp2 = outarray[0];
155 Array<OneD, NekDouble> tmp3 = outarray[1];
156 Array<OneD, NekDouble> tmp4 = outarray[2];
157
158 const Array<TwoD, const NekDouble> &df = m_geomFactors->GetDerivFactors();
159
160 Vmath::Vcopy(nqtot, inarray, 1, tmp1, 1); // Dir3 metric
161
162 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed)
163 {
164 Vmath::Vmul(nqtot, &df[3 * dir][0], 1, tmp1.data(), 1, tmp2.data(), 1);
165 Vmath::Vmul(nqtot, &df[3 * dir + 1][0], 1, tmp1.data(), 1, tmp3.data(),
166 1);
167 Vmath::Vmul(nqtot, &df[3 * dir + 2][0], 1, tmp1.data(), 1, tmp4.data(),
168 1);
169 }
170 else
171 {
172 Vmath::Smul(nqtot, df[3 * dir][0], tmp1.data(), 1, tmp2.data(), 1);
173 Vmath::Smul(nqtot, df[3 * dir + 1][0], tmp1.data(), 1, tmp3.data(), 1);
174 Vmath::Smul(nqtot, df[3 * dir + 2][0], tmp1.data(), 1, tmp4.data(), 1);
175 }
176
177 int cnt = 0;
178 int i, j;
179
180 NekDouble g0, g2, g02;
181 for (int k = 0; k < nquad2; ++k)
182 {
183 g2 = 2.0 / (1.0 - z2[k]);
184
185 for (j = 0; j < nquad1; ++j)
186 {
187 for (i = 0; i < nquad0; ++i, ++cnt)
188 {
189 g0 = 0.5 * (1.0 + z0[i]);
190 g02 = g0 * g2;
191 tmp2[cnt] = g2 * tmp2[cnt] + g02 * tmp4[cnt];
192 }
193 }
194 }
195}
196
197//---------------------------------------
198// Evaluation functions
199//---------------------------------------
200
202{
204 m_base[0]->GetBasisKey(), m_base[1]->GetBasisKey(),
205 m_base[2]->GetBasisKey());
206}
207
209{
211 m_base[0]->GetPointsKey());
213 m_base[1]->GetPointsKey());
215 m_base[2]->GetPointsKey());
216
218 bkey0, bkey1, bkey2);
219}
220
221/**
222 * @brief Get the coordinates #coords at the local coordinates
223 * #Lcoords.
224 */
227{
228 int i;
229
230 ASSERTL1(Lcoords[0] <= -1.0 && Lcoords[0] >= 1.0 && Lcoords[1] <= -1.0 &&
231 Lcoords[1] >= 1.0 && Lcoords[2] <= -1.0 && Lcoords[2] >= 1.0,
232 "Local coordinates are not in region [-1,1]");
233
234 m_geom->FillGeom();
235
236 for (i = 0; i < m_geom->GetCoordim(); ++i)
237 {
238 coords[i] = m_geom->GetCoord(i, Lcoords);
239 }
240}
241
243 Array<OneD, NekDouble> &coords_1,
244 Array<OneD, NekDouble> &coords_2)
245{
246 Expansion::v_GetCoords(coords_0, coords_1, coords_2);
247}
248
250 const Array<OneD, NekDouble> &coord,
251 const Array<OneD, const NekDouble> &inarray,
252 std::array<NekDouble, 3> &firstOrderDerivs)
253{
254 Array<OneD, NekDouble> Lcoord(3);
255 ASSERTL0(m_geom, "m_geom not defined");
256 m_geom->GetLocCoords(coord, Lcoord);
257 return StdPrismExp::v_PhysEvalFirstDeriv(Lcoord, inarray, firstOrderDerivs);
258}
259
260//---------------------------------------
261// Helper functions
262//---------------------------------------
263
265 const NekDouble *data, const std::vector<unsigned int> &nummodes,
266 const int mode_offset, NekDouble *coeffs,
267 [[maybe_unused]] std::vector<LibUtilities::BasisType> &fromType)
268{
269 int data_order0 = nummodes[mode_offset];
270 int fillorder0 = min(m_base[0]->GetNumModes(), data_order0);
271 int data_order1 = nummodes[mode_offset + 1];
272 int order1 = m_base[1]->GetNumModes();
273 int fillorder1 = min(order1, data_order1);
274 int data_order2 = nummodes[mode_offset + 2];
275 int order2 = m_base[2]->GetNumModes();
276 int fillorder2 = min(order2, data_order2);
277
278 switch (m_base[0]->GetBasisType())
279 {
281 {
282 int i, j;
283 int cnt = 0;
284 int cnt1 = 0;
285
287 "Extraction routine not set up for this basis");
289 "Extraction routine not set up for this basis");
290
291 Vmath::Zero(m_ncoeffs, coeffs, 1);
292 for (j = 0; j < fillorder0; ++j)
293 {
294 for (i = 0; i < fillorder1; ++i)
295 {
296 Vmath::Vcopy(fillorder2 - j, &data[cnt], 1, &coeffs[cnt1],
297 1);
298 cnt += data_order2 - j;
299 cnt1 += order2 - j;
300 }
301
302 // count out data for j iteration
303 for (i = fillorder1; i < data_order1; ++i)
304 {
305 cnt += data_order2 - j;
306 }
307
308 for (i = fillorder1; i < order1; ++i)
309 {
310 cnt1 += order2 - j;
311 }
312 }
313 }
314 break;
315 default:
316 ASSERTL0(false, "basis is either not set up or not "
317 "hierarchicial");
318 }
319}
320
321void PrismExp::v_GetTracePhysMap(const int face, Array<OneD, int> &outarray)
322{
323 int nquad0 = m_base[0]->GetNumPoints();
324 int nquad1 = m_base[1]->GetNumPoints();
325 int nquad2 = m_base[2]->GetNumPoints();
326 int nq0 = 0;
327 int nq1 = 0;
328
329 switch (face)
330 {
331 case 0:
332 nq0 = nquad0;
333 nq1 = nquad1;
334 if (outarray.size() != nq0 * nq1)
335 {
336 outarray = Array<OneD, int>(nq0 * nq1);
337 }
338
339 // Directions A and B positive
340 for (int i = 0; i < nquad0 * nquad1; ++i)
341 {
342 outarray[i] = i;
343 }
344 break;
345 case 1:
346
347 nq0 = nquad0;
348 nq1 = nquad2;
349 if (outarray.size() != nq0 * nq1)
350 {
351 outarray = Array<OneD, int>(nq0 * nq1);
352 }
353
354 // Direction A and B positive
355 for (int k = 0; k < nquad2; k++)
356 {
357 for (int i = 0; i < nquad0; ++i)
358 {
359 outarray[k * nquad0 + i] = (nquad0 * nquad1 * k) + i;
360 }
361 }
362
363 break;
364 case 2:
365
366 nq0 = nquad1;
367 nq1 = nquad2;
368 if (outarray.size() != nq0 * nq1)
369 {
370 outarray = Array<OneD, int>(nq0 * nq1);
371 }
372
373 // Directions A and B positive
374 for (int j = 0; j < nquad1 * nquad2; ++j)
375 {
376 outarray[j] = nquad0 - 1 + j * nquad0;
377 }
378 break;
379 case 3:
380 nq0 = nquad0;
381 nq1 = nquad2;
382 if (outarray.size() != nq0 * nq1)
383 {
384 outarray = Array<OneD, int>(nq0 * nq1);
385 }
386
387 // Direction A and B positive
388 for (int k = 0; k < nquad2; k++)
389 {
390 for (int i = 0; i < nquad0; ++i)
391 {
392 outarray[k * nquad0 + i] =
393 nquad0 * (nquad1 - 1) + (nquad0 * nquad1 * k) + i;
394 }
395 }
396 break;
397 case 4:
398
399 nq0 = nquad1;
400 nq1 = nquad2;
401 if (outarray.size() != nq0 * nq1)
402 {
403 outarray = Array<OneD, int>(nq0 * nq1);
404 }
405
406 // Directions A and B positive
407 for (int j = 0; j < nquad1 * nquad2; ++j)
408 {
409 outarray[j] = j * nquad0;
410 }
411 break;
412 default:
413 ASSERTL0(false, "face value (> 4) is out of range");
414 break;
415 }
416}
417
418/** \brief Get the normals along specficied face
419 * Get the face normals interplated to a points0 x points 0
420 * type distribution
421 **/
423{
425 for (int i = 0; i < ptsKeys.size(); ++i)
426 {
427 // Need at least 2 points for computing normals
428 if (ptsKeys[i].GetNumPoints() == 1)
429 {
430 LibUtilities::PointsKey pKey(2, ptsKeys[i].GetPointsType());
431 ptsKeys[i] = pKey;
432 }
433 }
434
435 SpatialDomains::GeomType type = m_geomFactors->GetGtype();
437 m_geomFactors->ComputeDerivFactors(ptsKeys);
439 m_geomFactors->ComputeJac(ptsKeys);
440
441 int nq0 = ptsKeys[0].GetNumPoints();
442 int nq1 = ptsKeys[1].GetNumPoints();
443 int nq2 = ptsKeys[2].GetNumPoints();
444 int nq01 = nq0 * nq1;
445 int nqtot;
446
447 LibUtilities::BasisKey tobasis0 = GetTraceBasisKey(face, 0);
448 LibUtilities::BasisKey tobasis1 = GetTraceBasisKey(face, 1);
449
450 // Number of quadrature points in face expansion.
451 int nq_face = tobasis0.GetNumPoints() * tobasis1.GetNumPoints();
452
453 int vCoordDim = GetCoordim();
454 int i;
455
458 for (i = 0; i < vCoordDim; ++i)
459 {
460 normal[i] = Array<OneD, NekDouble>(nq_face);
461 }
462
463 size_t nqb = nq_face;
464 size_t nbnd = face;
467
468 // Regular geometry case
469 if (type == SpatialDomains::eRegular ||
471 {
472 NekDouble fac;
473 // Set up normals
474 switch (face)
475 {
476 case 0:
477 {
478 for (i = 0; i < vCoordDim; ++i)
479 {
480 normal[i][0] = -df[3 * i + 2][0];
481 }
482 break;
483 }
484 case 1:
485 {
486 for (i = 0; i < vCoordDim; ++i)
487 {
488 normal[i][0] = -df[3 * i + 1][0];
489 }
490 break;
491 }
492 case 2:
493 {
494 for (i = 0; i < vCoordDim; ++i)
495 {
496 normal[i][0] = df[3 * i][0] + df[3 * i + 2][0];
497 }
498 break;
499 }
500 case 3:
501 {
502 for (i = 0; i < vCoordDim; ++i)
503 {
504 normal[i][0] = df[3 * i + 1][0];
505 }
506 break;
507 }
508 case 4:
509 {
510 for (i = 0; i < vCoordDim; ++i)
511 {
512 normal[i][0] = -df[3 * i][0];
513 }
514 break;
515 }
516 default:
517 ASSERTL0(false, "face is out of range (face < 4)");
518 }
519
520 // Normalise resulting vector.
521 fac = 0.0;
522 for (i = 0; i < vCoordDim; ++i)
523 {
524 fac += normal[i][0] * normal[i][0];
525 }
526 fac = 1.0 / sqrt(fac);
527
528 Vmath::Fill(nqb, fac, length, 1);
529
530 for (i = 0; i < vCoordDim; ++i)
531 {
532 Vmath::Fill(nq_face, fac * normal[i][0], normal[i], 1);
533 }
534 }
535 else
536 {
537 // Set up deformed normals.
538 int j, k;
539
540 // Determine number of quadrature points on the face of 3D elmt
541 if (face == 0)
542 {
543 nqtot = nq0 * nq1;
544 }
545 else if (face == 1 || face == 3)
546 {
547 nqtot = nq0 * nq2;
548 }
549 else
550 {
551 nqtot = nq1 * nq2;
552 }
553
556
557 Array<OneD, NekDouble> faceJac(nqtot);
558 Array<OneD, NekDouble> normals(vCoordDim * nqtot, 0.0);
559
560 // Extract Jacobian along face and recover local derivatives
561 // (dx/dr) for polynomial interpolation by multiplying m_gmat by
562 // jacobian
563 switch (face)
564 {
565 case 0:
566 {
567 for (j = 0; j < nq01; ++j)
568 {
569 normals[j] = -df[2][j] * jac[j];
570 normals[nqtot + j] = -df[5][j] * jac[j];
571 normals[2 * nqtot + j] = -df[8][j] * jac[j];
572 faceJac[j] = jac[j];
573 }
574
575 points0 = ptsKeys[0];
576 points1 = ptsKeys[1];
577 break;
578 }
579
580 case 1:
581 {
582 for (j = 0; j < nq0; ++j)
583 {
584 for (k = 0; k < nq2; ++k)
585 {
586 int tmp = j + nq01 * k;
587 normals[j + k * nq0] = -df[1][tmp] * jac[tmp];
588 normals[nqtot + j + k * nq0] = -df[4][tmp] * jac[tmp];
589 normals[2 * nqtot + j + k * nq0] =
590 -df[7][tmp] * jac[tmp];
591 faceJac[j + k * nq0] = jac[tmp];
592 }
593 }
594
595 points0 = ptsKeys[0];
596 points1 = ptsKeys[2];
597 break;
598 }
599
600 case 2:
601 {
602 for (j = 0; j < nq1; ++j)
603 {
604 for (k = 0; k < nq2; ++k)
605 {
606 int tmp = nq0 - 1 + nq0 * j + nq01 * k;
607 normals[j + k * nq1] =
608 (df[0][tmp] + df[2][tmp]) * jac[tmp];
609 normals[nqtot + j + k * nq1] =
610 (df[3][tmp] + df[5][tmp]) * jac[tmp];
611 normals[2 * nqtot + j + k * nq1] =
612 (df[6][tmp] + df[8][tmp]) * jac[tmp];
613 faceJac[j + k * nq1] = jac[tmp];
614 }
615 }
616
617 points0 = ptsKeys[1];
618 points1 = ptsKeys[2];
619 break;
620 }
621
622 case 3:
623 {
624 for (j = 0; j < nq0; ++j)
625 {
626 for (k = 0; k < nq2; ++k)
627 {
628 int tmp = nq0 * (nq1 - 1) + j + nq01 * k;
629 normals[j + k * nq0] = df[1][tmp] * jac[tmp];
630 normals[nqtot + j + k * nq0] = df[4][tmp] * jac[tmp];
631 normals[2 * nqtot + j + k * nq0] =
632 df[7][tmp] * jac[tmp];
633 faceJac[j + k * nq0] = jac[tmp];
634 }
635 }
636
637 points0 = ptsKeys[0];
638 points1 = ptsKeys[2];
639 break;
640 }
641
642 case 4:
643 {
644 for (j = 0; j < nq1; ++j)
645 {
646 for (k = 0; k < nq2; ++k)
647 {
648 int tmp = j * nq0 + nq01 * k;
649 normals[j + k * nq1] = -df[0][tmp] * jac[tmp];
650 normals[nqtot + j + k * nq1] = -df[3][tmp] * jac[tmp];
651 normals[2 * nqtot + j + k * nq1] =
652 -df[6][tmp] * jac[tmp];
653 faceJac[j + k * nq1] = jac[tmp];
654 }
655 }
656
657 points0 = ptsKeys[1];
658 points1 = ptsKeys[2];
659 break;
660 }
661
662 default:
663 ASSERTL0(false, "face is out of range (face < 4)");
664 }
665
666 Array<OneD, NekDouble> work(nq_face, 0.0);
667 // Interpolate Jacobian and invert
668 LibUtilities::Interp2D(points0, points1, faceJac,
669 tobasis0.GetPointsKey(), tobasis1.GetPointsKey(),
670 work);
671 Vmath::Sdiv(nq_face, 1.0, &work[0], 1, &work[0], 1);
672
673 // Interpolate normal and multiply by inverse Jacobian.
674 for (i = 0; i < vCoordDim; ++i)
675 {
676 LibUtilities::Interp2D(points0, points1, &normals[i * nqtot],
677 tobasis0.GetPointsKey(),
678 tobasis1.GetPointsKey(), &normal[i][0]);
679 Vmath::Vmul(nq_face, work, 1, normal[i], 1, normal[i], 1);
680 }
681
682 // Normalise to obtain unit normals.
683 Vmath::Zero(nq_face, work, 1);
684 for (i = 0; i < GetCoordim(); ++i)
685 {
686 Vmath::Vvtvp(nq_face, normal[i], 1, normal[i], 1, work, 1, work, 1);
687 }
688
689 Vmath::Vsqrt(nq_face, work, 1, work, 1);
690 Vmath::Sdiv(nq_face, 1.0, work, 1, work, 1);
691
692 Vmath::Vcopy(nqb, work, 1, length, 1);
693
694 for (i = 0; i < GetCoordim(); ++i)
695 {
696 Vmath::Vmul(nq_face, normal[i], 1, work, 1, normal[i], 1);
697 }
698 }
699}
700
702 Array<OneD, NekDouble> &outarray,
703 const StdRegions::StdMatrixKey &mkey)
704{
705 StdExpansion::MassMatrixOp_MatFree(inarray, outarray, mkey);
706}
707
709 Array<OneD, NekDouble> &outarray,
710 const StdRegions::StdMatrixKey &mkey)
711{
712 PrismExp::LaplacianMatrixOp_MatFree(inarray, outarray, mkey);
713}
714
715void PrismExp::v_LaplacianMatrixOp(const int k1, const int k2,
716 const Array<OneD, const NekDouble> &inarray,
717 Array<OneD, NekDouble> &outarray,
718 const StdRegions::StdMatrixKey &mkey)
719{
720 StdExpansion::LaplacianMatrixOp_MatFree(k1, k2, inarray, outarray, mkey);
721}
722
724 Array<OneD, NekDouble> &outarray,
725 const StdRegions::StdMatrixKey &mkey)
726{
727 PrismExp::v_HelmholtzMatrixOp_MatFree(inarray, outarray, mkey);
728}
729
731 const StdRegions::StdMatrixKey &mkey)
732{
733 int nq = GetTotPoints();
734
735 // Calculate sqrt of the Jacobian
737 Array<OneD, NekDouble> sqrt_jac(nq);
738 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed)
739 {
740 Vmath::Vsqrt(nq, jac, 1, sqrt_jac, 1);
741 }
742 else
743 {
744 Vmath::Fill(nq, sqrt(jac[0]), sqrt_jac, 1);
745 }
746
747 // Multiply array by sqrt(Jac)
748 Vmath::Vmul(nq, sqrt_jac, 1, array, 1, array, 1);
749
750 // Apply std region filter
751 StdPrismExp::v_SVVLaplacianFilter(array, mkey);
752
753 // Divide by sqrt(Jac)
754 Vmath::Vdiv(nq, array, 1, sqrt_jac, 1, array, 1);
755}
756
757//---------------------------------------
758// Matrix creation functions
759//---------------------------------------
760
762{
763 DNekMatSharedPtr returnval;
764
765 switch (mkey.GetMatrixType())
766 {
774 returnval = Expansion3D::v_GenMatrix(mkey);
775 break;
776 default:
777 returnval = StdPrismExp::v_GenMatrix(mkey);
778 break;
779 }
780
781 return returnval;
782}
783
785 const StdRegions::StdMatrixKey &mkey)
786{
787 LibUtilities::BasisKey bkey0 = m_base[0]->GetBasisKey();
788 LibUtilities::BasisKey bkey1 = m_base[1]->GetBasisKey();
789 LibUtilities::BasisKey bkey2 = m_base[2]->GetBasisKey();
792
793 return tmp->GetStdMatrix(mkey);
794}
795
800
802{
803 m_matrixManager.DeleteObject(mkey);
804}
805
811
813{
814 m_staticCondMatrixManager.DeleteObject(mkey);
815}
816
817/**
818 * @brief Calculate the Laplacian multiplication in a matrix-free
819 * manner.
820 *
821 * This function is the kernel of the Laplacian matrix-free operator,
822 * and is used in #v_HelmholtzMatrixOp_MatFree to determine the effect
823 * of the Helmholtz operator in a similar fashion.
824 *
825 * The majority of the calculation is precisely the same as in the
826 * hexahedral expansion; however the collapsed co-ordinate system must
827 * be taken into account when constructing the geometric factors. How
828 * this is done is detailed more exactly in the tetrahedral expansion.
829 * On entry to this function, the input #inarray must be in its
830 * backwards-transformed state (i.e. \f$\mathbf{u} =
831 * \mathbf{B}\hat{\mathbf{u}}\f$). The output is in coefficient space.
832 *
833 * @see %TetExp::v_HelmholtzMatrixOp_MatFree
834 *
835 * Note: Not currently using wsp for memory input as in other methods
836 * for different shapes. Also seems that the _MatFree_Kernel extension
837 * to the name might be redundant?
838 */
840 const Array<OneD, const NekDouble> &inarray,
841 Array<OneD, NekDouble> &outarray,
842 [[maybe_unused]] Array<OneD, NekDouble> &wsp)
843{
844 int nquad0 = m_base[0]->GetNumPoints();
845 int nquad1 = m_base[1]->GetNumPoints();
846 int nquad2 = m_base[2]->GetNumPoints();
847 int nqtot = nquad0 * nquad1 * nquad2;
848 int i;
849
850 // Set up temporary storage. -> not sure why this is not as compact as other
851 // shapes
852 Array<OneD, NekDouble> alloc(11 * nqtot, 0.0);
853 Array<OneD, NekDouble> wsp1(alloc); // TensorDeriv 1
854 Array<OneD, NekDouble> wsp2(alloc + 1 * nqtot); // TensorDeriv 2
855 Array<OneD, NekDouble> wsp3(alloc + 2 * nqtot); // TensorDeriv 3
856 Array<OneD, NekDouble> g0(alloc + 3 * nqtot); // g0
857 Array<OneD, NekDouble> g1(alloc + 4 * nqtot); // g1
858 Array<OneD, NekDouble> g2(alloc + 5 * nqtot); // g2
859 Array<OneD, NekDouble> g3(alloc + 6 * nqtot); // g3
860 Array<OneD, NekDouble> g4(alloc + 7 * nqtot); // g4
861 Array<OneD, NekDouble> g5(alloc + 8 * nqtot); // g5
862 Array<OneD, NekDouble> h0(alloc + 3 * nqtot); // h0 == g0
863 Array<OneD, NekDouble> h1(alloc + 6 * nqtot); // h1 == g3
864 Array<OneD, NekDouble> wsp4(alloc + 4 * nqtot); // wsp4 == g1
865 Array<OneD, NekDouble> wsp5(alloc + 5 * nqtot); // wsp5 == g2
866 Array<OneD, NekDouble> wsp6(alloc + 8 * nqtot); // wsp6 == g5
867 Array<OneD, NekDouble> wsp7(alloc + 3 * nqtot); // wsp7 == g0
868 Array<OneD, NekDouble> wsp8(alloc + 9 * nqtot); // wsp8
869 Array<OneD, NekDouble> wsp9(alloc + 10 * nqtot); // wsp9
870
871 const Array<OneD, const NekDouble> &base0 = m_base[0]->GetBdata();
872 const Array<OneD, const NekDouble> &base1 = m_base[1]->GetBdata();
873 const Array<OneD, const NekDouble> &base2 = m_base[2]->GetBdata();
874 const Array<OneD, const NekDouble> &dbase0 = m_base[0]->GetDbdata();
875 const Array<OneD, const NekDouble> &dbase1 = m_base[1]->GetDbdata();
876 const Array<OneD, const NekDouble> &dbase2 = m_base[2]->GetDbdata();
877
878 // Step 1. LAPLACIAN MATRIX OPERATION
879 // wsp1 = du_dxi1 = D_xi1 * wsp0 = D_xi1 * u
880 // wsp2 = du_dxi2 = D_xi2 * wsp0 = D_xi2 * u
881 // wsp3 = du_dxi3 = D_xi3 * wsp0 = D_xi3 * u
882 PhysTensorDeriv(inarray, wsp1, wsp2, wsp3);
883
884 const Array<TwoD, const NekDouble> &df = m_geomFactors->GetDerivFactors();
885 const Array<OneD, const NekDouble> &z0 = m_base[0]->GetZ();
886 const Array<OneD, const NekDouble> &z2 = m_base[2]->GetZ();
887
888 // Step 2. Calculate the metric terms of the collapsed
889 // coordinate transformation (Spencer's book P152)
890 for (i = 0; i < nquad2; ++i)
891 {
892 Vmath::Fill(nquad0 * nquad1, 2.0 / (1.0 - z2[i]),
893 &h0[0] + i * nquad0 * nquad1, 1);
894 Vmath::Fill(nquad0 * nquad1, 2.0 / (1.0 - z2[i]),
895 &h1[0] + i * nquad0 * nquad1, 1);
896 }
897 for (i = 0; i < nquad0; i++)
898 {
899 Blas::Dscal(nquad1 * nquad2, 0.5 * (1 + z0[i]), &h1[0] + i, nquad0);
900 }
901
902 // Step 3. Construct combined metric terms for physical space to
903 // collapsed coordinate system. Order of construction optimised
904 // to minimise temporary storage
905 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed)
906 {
907 // wsp4 = d eta_1/d x_1
908 Vmath::Vvtvvtp(nqtot, &df[0][0], 1, &h0[0], 1, &df[2][0], 1, &h1[0], 1,
909 &wsp4[0], 1);
910 // wsp5 = d eta_2/d x_1
911 Vmath::Vvtvvtp(nqtot, &df[3][0], 1, &h0[0], 1, &df[5][0], 1, &h1[0], 1,
912 &wsp5[0], 1);
913 // wsp6 = d eta_3/d x_1d
914 Vmath::Vvtvvtp(nqtot, &df[6][0], 1, &h0[0], 1, &df[8][0], 1, &h1[0], 1,
915 &wsp6[0], 1);
916
917 // g0 (overwrites h0)
918 Vmath::Vvtvvtp(nqtot, &wsp4[0], 1, &wsp4[0], 1, &wsp5[0], 1, &wsp5[0],
919 1, &g0[0], 1);
920 Vmath::Vvtvp(nqtot, &wsp6[0], 1, &wsp6[0], 1, &g0[0], 1, &g0[0], 1);
921
922 // g3 (overwrites h1)
923 Vmath::Vvtvvtp(nqtot, &df[1][0], 1, &wsp4[0], 1, &df[4][0], 1, &wsp5[0],
924 1, &g3[0], 1);
925 Vmath::Vvtvp(nqtot, &df[7][0], 1, &wsp6[0], 1, &g3[0], 1, &g3[0], 1);
926
927 // g4
928 Vmath::Vvtvvtp(nqtot, &df[2][0], 1, &wsp4[0], 1, &df[5][0], 1, &wsp5[0],
929 1, &g4[0], 1);
930 Vmath::Vvtvp(nqtot, &df[8][0], 1, &wsp6[0], 1, &g4[0], 1, &g4[0], 1);
931
932 // Overwrite wsp4/5/6 with g1/2/5
933 // g1
934 Vmath::Vvtvvtp(nqtot, &df[1][0], 1, &df[1][0], 1, &df[4][0], 1,
935 &df[4][0], 1, &g1[0], 1);
936 Vmath::Vvtvp(nqtot, &df[7][0], 1, &df[7][0], 1, &g1[0], 1, &g1[0], 1);
937
938 // g2
939 Vmath::Vvtvvtp(nqtot, &df[2][0], 1, &df[2][0], 1, &df[5][0], 1,
940 &df[5][0], 1, &g2[0], 1);
941 Vmath::Vvtvp(nqtot, &df[8][0], 1, &df[8][0], 1, &g2[0], 1, &g2[0], 1);
942
943 // g5
944 Vmath::Vvtvvtp(nqtot, &df[1][0], 1, &df[2][0], 1, &df[4][0], 1,
945 &df[5][0], 1, &g5[0], 1);
946 Vmath::Vvtvp(nqtot, &df[7][0], 1, &df[8][0], 1, &g5[0], 1, &g5[0], 1);
947 }
948 else
949 {
950 // wsp4 = d eta_1/d x_1
951 Vmath::Svtsvtp(nqtot, df[0][0], &h0[0], 1, df[2][0], &h1[0], 1,
952 &wsp4[0], 1);
953 // wsp5 = d eta_2/d x_1
954 Vmath::Svtsvtp(nqtot, df[3][0], &h0[0], 1, df[5][0], &h1[0], 1,
955 &wsp5[0], 1);
956 // wsp6 = d eta_3/d x_1
957 Vmath::Svtsvtp(nqtot, df[6][0], &h0[0], 1, df[8][0], &h1[0], 1,
958 &wsp6[0], 1);
959
960 // g0 (overwrites h0)
961 Vmath::Vvtvvtp(nqtot, &wsp4[0], 1, &wsp4[0], 1, &wsp5[0], 1, &wsp5[0],
962 1, &g0[0], 1);
963 Vmath::Vvtvp(nqtot, &wsp6[0], 1, &wsp6[0], 1, &g0[0], 1, &g0[0], 1);
964
965 // g3 (overwrites h1)
966 Vmath::Svtsvtp(nqtot, df[1][0], &wsp4[0], 1, df[4][0], &wsp5[0], 1,
967 &g3[0], 1);
968 Vmath::Svtvp(nqtot, df[7][0], &wsp6[0], 1, &g3[0], 1, &g3[0], 1);
969
970 // g4
971 Vmath::Svtsvtp(nqtot, df[2][0], &wsp4[0], 1, df[5][0], &wsp5[0], 1,
972 &g4[0], 1);
973 Vmath::Svtvp(nqtot, df[8][0], &wsp6[0], 1, &g4[0], 1, &g4[0], 1);
974
975 // Overwrite wsp4/5/6 with g1/2/5
976 // g1
977 Vmath::Fill(nqtot,
978 df[1][0] * df[1][0] + df[4][0] * df[4][0] +
979 df[7][0] * df[7][0],
980 &g1[0], 1);
981
982 // g2
983 Vmath::Fill(nqtot,
984 df[2][0] * df[2][0] + df[5][0] * df[5][0] +
985 df[8][0] * df[8][0],
986 &g2[0], 1);
987
988 // g5
989 Vmath::Fill(nqtot,
990 df[1][0] * df[2][0] + df[4][0] * df[5][0] +
991 df[7][0] * df[8][0],
992 &g5[0], 1);
993 }
994 // Compute component derivatives into wsp7, 8, 9 (wsp7 overwrites
995 // g0).
996 Vmath::Vvtvvtp(nqtot, &g0[0], 1, &wsp1[0], 1, &g3[0], 1, &wsp2[0], 1,
997 &wsp7[0], 1);
998 Vmath::Vvtvp(nqtot, &g4[0], 1, &wsp3[0], 1, &wsp7[0], 1, &wsp7[0], 1);
999 Vmath::Vvtvvtp(nqtot, &g1[0], 1, &wsp2[0], 1, &g3[0], 1, &wsp1[0], 1,
1000 &wsp8[0], 1);
1001 Vmath::Vvtvp(nqtot, &g5[0], 1, &wsp3[0], 1, &wsp8[0], 1, &wsp8[0], 1);
1002 Vmath::Vvtvvtp(nqtot, &g2[0], 1, &wsp3[0], 1, &g4[0], 1, &wsp1[0], 1,
1003 &wsp9[0], 1);
1004 Vmath::Vvtvp(nqtot, &g5[0], 1, &wsp2[0], 1, &wsp9[0], 1, &wsp9[0], 1);
1005
1006 // Step 4.
1007 // Perform inner product w.r.t derivative bases.
1008 const Array<OneD, const NekDouble> &jac = m_geomFactors->GetJac();
1009 bool Deformed = (m_geomFactors->GetGtype() == SpatialDomains::eDeformed);
1010
1011 v_IProductWRTBaseKernel(dbase0, base1, base2, wsp7, wsp1, jac, Deformed);
1012 v_IProductWRTBaseKernel(base0, dbase1, base2, wsp8, wsp2, jac, Deformed);
1013 v_IProductWRTBaseKernel(base0, base1, dbase2, wsp9, outarray, jac,
1014 Deformed);
1015
1016 // Step 5.
1017 // Sum contributions from wsp1, wsp2 and outarray.
1018 Vmath::Vadd(m_ncoeffs, wsp1.data(), 1, outarray.data(), 1, outarray.data(),
1019 1);
1020 Vmath::Vadd(m_ncoeffs, wsp2.data(), 1, outarray.data(), 1, outarray.data(),
1021 1);
1022}
1023
1025 Array<OneD, int> &conn, [[maybe_unused]] bool oldstandard)
1026{
1027 int np0 = m_base[0]->GetNumPoints();
1028 int np1 = m_base[1]->GetNumPoints();
1029 int np2 = m_base[2]->GetNumPoints();
1030 int np = max(np0, max(np1, np2));
1031 Array<OneD, int> prismpt(6);
1032 bool standard = true;
1033
1034 int vid0 = m_geom->GetVid(0);
1035 int vid1 = m_geom->GetVid(1);
1036 int vid2 = m_geom->GetVid(4);
1037 int rotate = 0;
1038
1039 // sort out prism rotation according to
1040 if ((vid2 < vid1) && (vid2 < vid0)) // top triangle vertex is lowest id
1041 {
1042 rotate = 0;
1043 if (vid0 > vid1)
1044 {
1045 standard = false; // reverse base direction
1046 }
1047 }
1048 else if ((vid1 < vid2) && (vid1 < vid0))
1049 {
1050 rotate = 1;
1051 if (vid2 > vid0)
1052 {
1053 standard = false; // reverse base direction
1054 }
1055 }
1056 else if ((vid0 < vid2) && (vid0 < vid1))
1057 {
1058 rotate = 2;
1059 if (vid1 > vid2)
1060 {
1061 standard = false; // reverse base direction
1062 }
1063 }
1064
1065 conn = Array<OneD, int>(12 * (np - 1) * (np - 1) * (np - 1));
1066
1067 int row = 0;
1068 int rowp1 = 0;
1069 int plane = 0;
1070 int row1 = 0;
1071 int row1p1 = 0;
1072 int planep1 = 0;
1073 int cnt = 0;
1074
1075 Array<OneD, int> rot(3);
1076
1077 rot[0] = (0 + rotate) % 3;
1078 rot[1] = (1 + rotate) % 3;
1079 rot[2] = (2 + rotate) % 3;
1080
1081 // lower diagonal along 1-3 on base
1082 for (int i = 0; i < np - 1; ++i)
1083 {
1084 planep1 += (np - i) * np;
1085 row = 0; // current plane row offset
1086 rowp1 = 0; // current plane row plus one offset
1087 row1 = 0; // next plane row offset
1088 row1p1 = 0; // nex plane row plus one offset
1089 if (standard == false)
1090 {
1091 for (int j = 0; j < np - 1; ++j)
1092 {
1093 rowp1 += np - i;
1094 row1p1 += np - i - 1;
1095 for (int k = 0; k < np - i - 2; ++k)
1096 {
1097 // bottom prism block
1098 prismpt[rot[0]] = plane + row + k;
1099 prismpt[rot[1]] = plane + row + k + 1;
1100 prismpt[rot[2]] = planep1 + row1 + k;
1101
1102 prismpt[3 + rot[0]] = plane + rowp1 + k;
1103 prismpt[3 + rot[1]] = plane + rowp1 + k + 1;
1104 prismpt[3 + rot[2]] = planep1 + row1p1 + k;
1105
1106 conn[cnt++] = prismpt[0];
1107 conn[cnt++] = prismpt[1];
1108 conn[cnt++] = prismpt[3];
1109 conn[cnt++] = prismpt[2];
1110
1111 conn[cnt++] = prismpt[5];
1112 conn[cnt++] = prismpt[2];
1113 conn[cnt++] = prismpt[3];
1114 conn[cnt++] = prismpt[4];
1115
1116 conn[cnt++] = prismpt[3];
1117 conn[cnt++] = prismpt[1];
1118 conn[cnt++] = prismpt[4];
1119 conn[cnt++] = prismpt[2];
1120
1121 // upper prism block.
1122 prismpt[rot[0]] = planep1 + row1 + k + 1;
1123 prismpt[rot[1]] = planep1 + row1 + k;
1124 prismpt[rot[2]] = plane + row + k + 1;
1125
1126 prismpt[3 + rot[0]] = planep1 + row1p1 + k + 1;
1127 prismpt[3 + rot[1]] = planep1 + row1p1 + k;
1128 prismpt[3 + rot[2]] = plane + rowp1 + k + 1;
1129
1130 conn[cnt++] = prismpt[0];
1131 conn[cnt++] = prismpt[1];
1132 conn[cnt++] = prismpt[2];
1133 conn[cnt++] = prismpt[5];
1134
1135 conn[cnt++] = prismpt[5];
1136 conn[cnt++] = prismpt[0];
1137 conn[cnt++] = prismpt[4];
1138 conn[cnt++] = prismpt[1];
1139
1140 conn[cnt++] = prismpt[3];
1141 conn[cnt++] = prismpt[4];
1142 conn[cnt++] = prismpt[0];
1143 conn[cnt++] = prismpt[5];
1144 }
1145
1146 // bottom prism block
1147 prismpt[rot[0]] = plane + row + np - i - 2;
1148 prismpt[rot[1]] = plane + row + np - i - 1;
1149 prismpt[rot[2]] = planep1 + row1 + np - i - 2;
1150
1151 prismpt[3 + rot[0]] = plane + rowp1 + np - i - 2;
1152 prismpt[3 + rot[1]] = plane + rowp1 + np - i - 1;
1153 prismpt[3 + rot[2]] = planep1 + row1p1 + np - i - 2;
1154
1155 conn[cnt++] = prismpt[0];
1156 conn[cnt++] = prismpt[1];
1157 conn[cnt++] = prismpt[3];
1158 conn[cnt++] = prismpt[2];
1159
1160 conn[cnt++] = prismpt[5];
1161 conn[cnt++] = prismpt[2];
1162 conn[cnt++] = prismpt[3];
1163 conn[cnt++] = prismpt[4];
1164
1165 conn[cnt++] = prismpt[3];
1166 conn[cnt++] = prismpt[1];
1167 conn[cnt++] = prismpt[4];
1168 conn[cnt++] = prismpt[2];
1169
1170 row += np - i;
1171 row1 += np - i - 1;
1172 }
1173 }
1174 else
1175 { // lower diagonal along 0-4 on base
1176 for (int j = 0; j < np - 1; ++j)
1177 {
1178 rowp1 += np - i;
1179 row1p1 += np - i - 1;
1180 for (int k = 0; k < np - i - 2; ++k)
1181 {
1182 // bottom prism block
1183 prismpt[rot[0]] = plane + row + k;
1184 prismpt[rot[1]] = plane + row + k + 1;
1185 prismpt[rot[2]] = planep1 + row1 + k;
1186
1187 prismpt[3 + rot[0]] = plane + rowp1 + k;
1188 prismpt[3 + rot[1]] = plane + rowp1 + k + 1;
1189 prismpt[3 + rot[2]] = planep1 + row1p1 + k;
1190
1191 conn[cnt++] = prismpt[0];
1192 conn[cnt++] = prismpt[1];
1193 conn[cnt++] = prismpt[4];
1194 conn[cnt++] = prismpt[2];
1195
1196 conn[cnt++] = prismpt[4];
1197 conn[cnt++] = prismpt[3];
1198 conn[cnt++] = prismpt[0];
1199 conn[cnt++] = prismpt[2];
1200
1201 conn[cnt++] = prismpt[3];
1202 conn[cnt++] = prismpt[4];
1203 conn[cnt++] = prismpt[5];
1204 conn[cnt++] = prismpt[2];
1205
1206 // upper prism block.
1207 prismpt[rot[0]] = planep1 + row1 + k + 1;
1208 prismpt[rot[1]] = planep1 + row1 + k;
1209 prismpt[rot[2]] = plane + row + k + 1;
1210
1211 prismpt[3 + rot[0]] = planep1 + row1p1 + k + 1;
1212 prismpt[3 + rot[1]] = planep1 + row1p1 + k;
1213 prismpt[3 + rot[2]] = plane + rowp1 + k + 1;
1214
1215 conn[cnt++] = prismpt[0];
1216 conn[cnt++] = prismpt[2];
1217 conn[cnt++] = prismpt[1];
1218 conn[cnt++] = prismpt[5];
1219
1220 conn[cnt++] = prismpt[3];
1221 conn[cnt++] = prismpt[5];
1222 conn[cnt++] = prismpt[0];
1223 conn[cnt++] = prismpt[1];
1224
1225 conn[cnt++] = prismpt[5];
1226 conn[cnt++] = prismpt[3];
1227 conn[cnt++] = prismpt[4];
1228 conn[cnt++] = prismpt[1];
1229 }
1230
1231 // bottom prism block
1232 prismpt[rot[0]] = plane + row + np - i - 2;
1233 prismpt[rot[1]] = plane + row + np - i - 1;
1234 prismpt[rot[2]] = planep1 + row1 + np - i - 2;
1235
1236 prismpt[3 + rot[0]] = plane + rowp1 + np - i - 2;
1237 prismpt[3 + rot[1]] = plane + rowp1 + np - i - 1;
1238 prismpt[3 + rot[2]] = planep1 + row1p1 + np - i - 2;
1239
1240 conn[cnt++] = prismpt[0];
1241 conn[cnt++] = prismpt[1];
1242 conn[cnt++] = prismpt[4];
1243 conn[cnt++] = prismpt[2];
1244
1245 conn[cnt++] = prismpt[4];
1246 conn[cnt++] = prismpt[3];
1247 conn[cnt++] = prismpt[0];
1248 conn[cnt++] = prismpt[2];
1249
1250 conn[cnt++] = prismpt[3];
1251 conn[cnt++] = prismpt[4];
1252 conn[cnt++] = prismpt[5];
1253 conn[cnt++] = prismpt[2];
1254
1255 row += np - i;
1256 row1 += np - i - 1;
1257 }
1258 }
1259 plane += (np - i) * np;
1260 }
1261}
1262} // 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:309
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:319
SpatialDomains::Geometry * m_geom
Definition Expansion.h:306
void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3) override
SpatialDomains::GeomFactorsUniquePtr m_geomFactors
Definition Expansion.h:307
PrismExp(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 PrismExp.cpp:45
DNekMatSharedPtr v_CreateStdMatrix(const StdRegions::StdMatrixKey &mkey) override
Definition PrismExp.cpp:784
DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey) override
Definition PrismExp.cpp:761
StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const override
Definition PrismExp.cpp:201
void v_LaplacianMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey) override
Definition PrismExp.cpp:708
void v_DropLocStaticCondMatrix(const MatrixKey &mkey) override
Definition PrismExp.cpp:812
void v_HelmholtzMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey) override
Definition PrismExp.cpp:723
NekDouble v_PhysEvalFirstDeriv(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs) override
Definition PrismExp.cpp:249
void v_GetSimplexEquiSpacedConnectivity(Array< OneD, int > &conn, bool standard=true) override
DNekScalMatSharedPtr v_GetLocMatrix(const MatrixKey &mkey) override
Definition PrismExp.cpp:796
void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Calculates the inner product .
Definition PrismExp.cpp:103
LibUtilities::NekManager< MatrixKey, DNekScalBlkMat, MatrixKey::opLess > m_staticCondMatrixManager
Definition PrismExp.h:156
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 PrismExp.cpp:264
void v_GetCoord(const Array< OneD, const NekDouble > &Lcoords, Array< OneD, NekDouble > &coords) override
Get the coordinates #coords at the local coordinates #Lcoords.
Definition PrismExp.cpp:225
void v_AlignVectorToCollapsedDir(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray) override
Definition PrismExp.cpp:140
StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const override
Definition PrismExp.cpp:208
void v_ComputeTraceNormal(const int face) override
Get the normals along specficied face Get the face normals interplated to a points0 x points 0 type d...
Definition PrismExp.cpp:422
void v_MassMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey) override
Definition PrismExp.cpp:701
void v_LaplacianMatrixOp_MatFree_Kernel(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp) override
Calculate the Laplacian multiplication in a matrix-free manner.
Definition PrismExp.cpp:839
void v_GetTracePhysMap(const int face, Array< OneD, int > &outarray) override
Definition PrismExp.cpp:321
void v_DropLocMatrix(const MatrixKey &mkey) override
Definition PrismExp.cpp:801
void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdRegions::StdMatrixKey &mkey) override
Definition PrismExp.cpp:730
LibUtilities::NekManager< MatrixKey, DNekScalMat, MatrixKey::opLess > m_matrixManager
Definition PrismExp.h:154
DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix(const MatrixKey &mkey) override
Definition PrismExp.cpp:806
void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3) override
Definition PrismExp.cpp:242
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:559
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:549
int GetVid(int i) const
Returns global id of vertex i of this object.
Definition Geometry.h:345
int GetCoordim() const
Return the coordinate dimension of this object (i.e. the dimension of the space in which this object ...
Definition Geometry.h:277
void FillGeom()
Populate the coordinate mapping Geometry::m_coeffs information from any children geometry elements.
Definition Geometry.h:461
void PhysTensorDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1, Array< OneD, NekDouble > &out_d2)
Calculate the 3D derivative in the local tensor/collapsed coordinate at the physical points.
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
virtual void v_HelmholtzMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
void LaplacianMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
LibUtilities::PointsType GetPointsType(const int dir) const
This function returns the type of quadrature points used in the dir direction.
int GetNumPoints(const int dir) const
This function returns the number of quadrature points in the dir direction.
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
void v_IProductWRTBaseKernel(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, const Array< OneD, NekDouble > &jac, const bool Deformed, bool CollDir0=false, bool CollDir1=false, bool CollDir2=false) override
Inner product of inarray over region with respect to the expansion basis (this)->m_base[0] and return...
static void Dscal(const int &n, const double &alpha, double *x, const int &incx)
BLAS level 1: x = alpha x.
Definition Blas.hpp:124
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:313
@ eModified_B
Principle Modified Functions .
Definition BasisType.h:49
@ eModified_A
Principle Modified Functions .
Definition BasisType.h:48
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< StdPrismExp > StdPrismExpSharedPtr
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
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 > max(scalarT< T > lhs, scalarT< T > rhs)
Definition scalar.hpp:305
scalarT< T > min(scalarT< T > lhs, scalarT< T > rhs)
Definition scalar.hpp:300
scalarT< T > sqrt(scalarT< T > in)
Definition scalar.hpp:290