55 :
StdExpansion(LibUtilities::StdPrismData::getNumberOfCoefficients(
56 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
58 StdExpansion3D(LibUtilities::StdPrismData::getNumberOfCoefficients(
59 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
63 "order in 'a' direction is higher than order in 'c' direction");
96 int Qx =
m_base[0]->GetNumPoints();
97 int Qy =
m_base[1]->GetNumPoints();
98 int Qz =
m_base[2]->GetNumPoints();
99 int Qtot = Qx * Qy * Qz;
104 eta_x =
m_base[0]->GetZ();
105 eta_z =
m_base[2]->GetZ();
109 bool Do_1 = (out_dxi1.size() > 0) ?
true :
false;
110 bool Do_3 = (out_dxi3.size() > 0) ?
true :
false;
129 for (k = 0; k < Qz; ++k)
132 &dEta_bar1[0] + k * Qx * Qy, 1,
133 &out_dxi1[0] + k * Qx * Qy, 1);
140 for (k = 0; k < Qz; ++k)
143 &dEta_bar1[0] + k * Qx * Qy, 1,
144 &dEta_bar1[0] + k * Qx * Qy, 1);
148 for (i = 0; i < Qx; ++i)
150 Vmath::Svtvp(Qz * Qy, 1.0 + eta_x[i], &dEta_bar1[0] + i, Qx,
151 &out_dxi3[0] + i, Qx, &out_dxi3[0] + i, Qx);
191 "Basis[1] is not a general tensor type");
195 "Basis[2] is not a general tensor type");
201 int nquad0 =
m_base[0]->GetNumPoints();
202 int nquad1 =
m_base[1]->GetNumPoints();
203 int nquad2 =
m_base[2]->GetNumPoints();
204 int nmodes0 =
m_base[0]->GetNumModes();
205 int nmodes1 =
m_base[1]->GetNumModes();
206 int nmodes2 =
m_base[2]->GetNumModes();
210 std::vector<vec_t, tinysimd::allocator<vec_t>> wsp0(nmodes0 * nmodes1),
221#define BWDTRANS_DEF \
222 BwdTransPrismKernel( \
223 nmodes0, nmodes1, nmodes2, nquad0, nquad1, nquad2, isModified, \
224 (const vec_t *)base0.data(), (const vec_t *)base1.data(), \
225 (const vec_t *)base2.data(), wsp0.data(), wsp1.data(), \
226 (const vec_t *)inarray.data(), (vec_t *)outarray.data())
230#define BWDTRANS_Q(r, i) \
232 BwdTransPrismKernel( \
233 NM(i), NM(i), NM(i), NQ(i), NQ(i), NQ_M1(i), isModified, \
234 (const vec_t *)base0.data(), (const vec_t *)base1.data(), \
235 (const vec_t *)base2.data(), wsp0.data(), wsp1.data(), \
236 (const vec_t *)inarray.data(), (vec_t *)outarray.data()); \
241#define BWDTRANS_M(r, i) \
246 BOOST_PP_FOR_##r((NM(i), NM_P1(i), BOOST_PP_MUL(2, NM(i))), \
247 STDLEV2TEST1, STDLEV2UPDATE1, BWDTRANS_Q) default \
257 if ((nmodes0 == nmodes1) && (nmodes1 == nmodes2) && (nquad0 == nquad1) &&
258 (nquad1 == nquad2 + 1))
304 const bool Deformed, [[maybe_unused]]
bool CollDir0,
305 [[maybe_unused]]
bool CollDir1, [[maybe_unused]]
bool CollDir2)
309 "Basis[1] is not a general tensor type");
313 "Basis[2] is not a general tensor type");
315 int nquad0 =
m_base[0]->GetNumPoints();
316 int nquad1 =
m_base[1]->GetNumPoints();
317 int nquad2 =
m_base[2]->GetNumPoints();
319 int order0 =
m_base[0]->GetNumModes();
320 int order1 =
m_base[1]->GetNumModes();
321 int order2 =
m_base[2]->GetNumModes();
323 const bool isModified =
326 std::vector<vec_t, tinysimd::allocator<vec_t>> wsp0(nquad1 * nquad2),
327 wsp1(nquad2), wsp2(order1);
338#undef IPRODUCTWRTBASE_DEF
339#define IPRODUCTWRTBASE_DEF \
340 IProductPrismKernel<false, false, true>( \
341 order0, order1, order2, nquad0, nquad1, nquad2, isModified, \
342 (const vec_t *)inarray.data(), (const vec_t *)base0.data(), \
343 (const vec_t *)base1.data(), (const vec_t *)base2.data(), \
344 (const vec_t *)m_weights[0].data(), \
345 (const vec_t *)m_weights[1].data(), \
346 (const vec_t *)m_weights[2].data(), (const vec_t *)jac.data(), \
347 (vec_t *)wsp0.data(), (vec_t *)wsp1.data(), (vec_t *)wsp2.data(), \
348 (vec_t *)outarray.data())
351#undef IPRODUCTWRTBASE_Q
352#define IPRODUCTWRTBASE_Q(r, i) \
354 IProductPrismKernel<false, false, true>( \
355 NM(i), NM(i), NM(i), NQ(i), NQ(i), NQ_M1(i), isModified, \
356 (const vec_t *)inarray.data(), (const vec_t *)base0.data(), \
357 (const vec_t *)base1.data(), (const vec_t *)base2.data(), \
358 (const vec_t *)m_weights[0].data(), \
359 (const vec_t *)m_weights[1].data(), \
360 (const vec_t *)m_weights[2].data(), (const vec_t *)jac.data(), \
361 (vec_t *)wsp0.data(), (vec_t *)wsp1.data(), (vec_t *)wsp2.data(), \
362 (vec_t *)outarray.data()); \
366#undef IPRODUCTWRTBASE_M
367#define IPRODUCTWRTBASE_M(r, i) \
372 BOOST_PP_FOR_##r((NM(i), NM_P1(i), BOOST_PP_MUL(2, NM(i))), \
373 STDLEV2TEST1, STDLEV2UPDATE1, \
374 IPRODUCTWRTBASE_Q) default : IPRODUCTWRTBASE_DEF; \
382 if ((order0 == order1) && (order1 == order2) && (nquad0 == nquad1) &&
383 (nquad1 == nquad2 + 1))
402#undef IPRODUCTWRTBASE_DEF
403#define IPRODUCTWRTBASE_DEF \
404 IProductPrismKernel<false, false, false>( \
405 order0, order1, order2, nquad0, nquad1, nquad2, isModified, \
406 (const vec_t *)inarray.data(), (const vec_t *)base0.data(), \
407 (const vec_t *)base1.data(), (const vec_t *)base2.data(), \
408 (const vec_t *)m_weights[0].data(), \
409 (const vec_t *)m_weights[1].data(), \
410 (const vec_t *)m_weights[2].data(), (const vec_t *)jac.data(), \
411 (vec_t *)wsp0.data(), (vec_t *)wsp1.data(), (vec_t *)wsp2.data(), \
412 (vec_t *)outarray.data())
415#undef IPRODUCTWRTBASE_Q
416#define IPRODUCTWRTBASE_Q(r, i) \
418 IProductPrismKernel<false, false, false>( \
419 NM(i), NM(i), NM(i), NQ(i), NQ(i), NQ_M1(i), isModified, \
420 (const vec_t *)inarray.data(), (const vec_t *)base0.data(), \
421 (const vec_t *)base1.data(), (const vec_t *)base2.data(), \
422 (const vec_t *)m_weights[0].data(), \
423 (const vec_t *)m_weights[1].data(), \
424 (const vec_t *)m_weights[2].data(), (const vec_t *)jac.data(), \
425 (vec_t *)wsp0.data(), (vec_t *)wsp1.data(), (vec_t *)wsp2.data(), \
426 (vec_t *)outarray.data()); \
430#undef IPRODUCTWRTBASE_M
431#define IPRODUCTWRTBASE_M(r, i) \
436 BOOST_PP_FOR_##r((NM(i), NM_P1(i), BOOST_PP_MUL(2, NM(i))), \
437 STDLEV2TEST1, STDLEV2UPDATE1, \
438 IPRODUCTWRTBASE_Q) default : IPRODUCTWRTBASE_DEF; \
446 if ((order0 == order1) && (order1 == order2) && (nquad0 == nquad1) &&
447 (nquad1 == nquad2 + 1))
473 ASSERTL0(dir >= 0 && dir <= 2,
"input dir is out of range");
476 int nquad0 =
m_base[0]->GetNumPoints();
477 int nquad1 =
m_base[1]->GetNumPoints();
478 int nquad2 =
m_base[2]->GetNumPoints();
490 for (i = 0; i < nquad2; ++i)
493 &inarray[0] + i * nquad0 * nquad1, 1,
494 &tmp0[0] + i * nquad0 * nquad1, 1);
504 m_base[2]->GetBdata(), tmp0, outarray, one,
false);
511 m_base[2]->GetBdata(), inarray, outarray, one,
false);
522 for (i = 0; i < nquad1 * nquad2; ++i)
524 Vmath::Vmul(nquad0, &gfac0[0], 1, &tmp0[0] + i * nquad0, 1,
525 &tmp0[0] + i * nquad0, 1);
530 m_base[2]->GetBdata(), tmp0, tmp1, one,
false);
534 m_base[2]->GetDbdata(), inarray, outarray, one,
false);
564 eta[0] = 2.0 * (1.0 + xi[0]) / d2 - 1.0;
570 xi[0] = (1.0 + eta[0]) * (1.0 - eta[2]) * 0.5 - 1.0;
587 for (
int k = 0; k < Qz; ++k)
589 for (
int j = 0; j < Qy; ++j)
591 for (
int i = 0; i < Qx; ++i)
593 int s = i + Qx * (j + Qy * k);
594 xi_x[s] = (1.0 - eta_z[k]) * (1.0 + etaBar_x[i]) / 2.0 - 1.0;
608 const int nm1 =
m_base[1]->GetNumModes();
609 const int nm2 =
m_base[2]->GetNumModes();
610 const int b = 2 * nm2 + 1;
612 const int mode0 = floor(0.5 * (b -
sqrt(b * b - 8.0 * mode / nm1)));
614 mode - nm1 * (mode0 * (nm2 - 1) + 1 - (mode0 - 2) * (mode0 - 1) / 2);
615 const int mode1 = tmp / (nm2 - mode0);
616 const int mode2 = tmp % (nm2 - mode0);
618 if (mode0 == 0 && mode2 == 1 &&
622 return StdExpansion::BaryEvaluateBasis<1>(coll[1], mode1) *
623 StdExpansion::BaryEvaluateBasis<2>(coll[2], mode2);
627 return StdExpansion::BaryEvaluateBasis<0>(coll[0], mode0) *
628 StdExpansion::BaryEvaluateBasis<1>(coll[1], mode1) *
629 StdExpansion::BaryEvaluateBasis<2>(coll[2], mode2);
636 std::array<NekDouble, 3> &firstOrderDerivs)
645 if ((1 - coll[2]) < 1e-5)
649 EphysDeriv2(totPoints);
650 v_PhysDeriv(inarray, EphysDeriv0, EphysDeriv1, EphysDeriv2);
653 I[0] =
GetBase()[0]->GetI(coll);
654 I[1] =
GetBase()[1]->GetI(coll + 1);
655 I[2] =
GetBase()[2]->GetI(coll + 2);
665 NekDouble dEta_bar1 = firstOrderDerivs[0];
668 firstOrderDerivs[0] = fac * dEta_bar1;
671 fac = 1.0 / (1.0 - coll[2]);
672 dEta_bar1 = fac * dEta_bar1;
676 firstOrderDerivs[2] += fac * dEta_bar1;
691 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
692 m_base[2]->GetNumModes()};
698 numModes0 = nummodes[0];
699 numModes1 = nummodes[1];
706 numModes0 = nummodes[1];
707 numModes1 = nummodes[2];
714 numModes0 = nummodes[0];
715 numModes1 = nummodes[2];
722 std::swap(numModes0, numModes1);
728 ASSERTL2(i >= 0 && i <= 8,
"edge id is out of range");
730 if (i == 0 || i == 2)
734 else if (i == 1 || i == 3 || i == 8)
776 "BasisType is not a boundary interior form");
779 "BasisType is not a boundary interior form");
782 "BasisType is not a boundary interior form");
784 int P =
m_base[0]->GetNumModes();
785 int Q =
m_base[1]->GetNumModes();
786 int R =
m_base[2]->GetNumModes();
795 "BasisType is not a boundary interior form");
798 "BasisType is not a boundary interior form");
801 "BasisType is not a boundary interior form");
803 int P =
m_base[0]->GetNumModes() - 1;
804 int Q =
m_base[1]->GetNumModes() - 1;
805 int R =
m_base[2]->GetNumModes() - 1;
807 return (
P + 1) * (Q + 1)
808 + 2 * (Q + 1) * (R + 1)
809 + 2 * (R + 1) +
P * (1 + 2 * R -
P);
814 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
819 else if (i == 1 || i == 3)
822 return Q + 1 + (
P * (1 + 2 * Q -
P)) / 2;
832 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
842 else if (i == 1 || i == 3)
844 return Pi * (2 * Ri - Pi - 1) / 2;
854 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
858 return m_base[0]->GetNumPoints() *
m_base[1]->GetNumPoints();
860 else if (i == 1 || i == 3)
862 return m_base[0]->GetNumPoints() *
m_base[2]->GetNumPoints();
866 return m_base[1]->GetNumPoints() *
m_base[2]->GetNumPoints();
873 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
874 ASSERTL2(j == 0 || j == 1,
"face direction is out of range");
878 return m_base[j]->GetPointsKey();
880 else if (i == 1 || i == 3)
882 return m_base[2 * j]->GetPointsKey();
886 return m_base[j + 1]->GetPointsKey();
894 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
895 ASSERTL2(k >= 0 && k <= 1,
"basis key id is out of range");
921 const std::vector<unsigned int> &nummodes,
int &modes_offset)
924 nummodes[modes_offset], nummodes[modes_offset + 1],
925 nummodes[modes_offset + 2]);
947 "Mapping not defined for this type of basis");
951 if (useCoeffPacking ==
true)
974 ASSERTL0(
false,
"local vertex id must be between 0 and 5");
1000 ASSERTL0(
false,
"local vertex id must be between 0 and 5");
1011 "BasisType is not a boundary interior form");
1014 "BasisType is not a boundary interior form");
1017 "BasisType is not a boundary interior form");
1019 int P =
m_base[0]->GetNumModes() - 1, p;
1020 int Q =
m_base[1]->GetNumModes() - 1, q;
1021 int R =
m_base[2]->GetNumModes() - 1, r;
1025 if (outarray.size() != nIntCoeffs)
1033 for (p = 2; p <=
P; ++p)
1035 for (q = 2; q <= Q; ++q)
1037 for (r = 1; r <= R - p; ++r)
1039 outarray[idx++] =
GetMode(p, q, r);
1049 "BasisType is not a boundary interior form");
1052 "BasisType is not a boundary interior form");
1055 "BasisType is not a boundary interior form");
1057 int P =
m_base[0]->GetNumModes() - 1, p;
1058 int Q =
m_base[1]->GetNumModes() - 1, q;
1059 int R =
m_base[2]->GetNumModes() - 1, r;
1064 if (maparray.size() != nBnd)
1070 for (p = 0; p <=
P; ++p)
1075 for (q = 0; q <= Q; ++q)
1077 for (r = 0; r <= R - p; ++r)
1079 maparray[idx++] =
GetMode(p, q, r);
1087 for (q = 0; q <= Q; ++q)
1091 for (r = 0; r <= R - p; ++r)
1093 maparray[idx++] =
GetMode(p, q, r);
1098 maparray[idx++] =
GetMode(p, q, 0);
1109 "Method only implemented if BasisType is identical"
1110 "in x and y directions");
1113 "Method only implemented for Modified_A BasisType"
1114 "(x and y direction) and Modified_B BasisType (z "
1116 int p, q, r, idx = 0;
1123 Q =
m_base[1]->GetNumModes();
1128 Q =
m_base[2]->GetNumModes();
1133 Q =
m_base[2]->GetNumModes();
1136 ASSERTL0(
false,
"fid must be between 0 and 4");
1139 if (maparray.size() !=
P * Q)
1149 for (q = 0; q < Q; ++q)
1151 for (p = 0; p <
P; ++p)
1153 maparray[q *
P + p] =
GetMode(p, q, 0);
1158 for (p = 0; p <
P; ++p)
1160 for (r = 0; r < Q - p; ++r)
1162 maparray[idx++] =
GetMode(p, 0, r);
1167 for (q = 0; q <
P; ++q)
1169 maparray[q] =
GetMode(1, q, 0);
1171 for (q = 0; q <
P; ++q)
1173 maparray[
P + q] =
GetMode(0, q, 1);
1175 for (r = 1; r < Q - 1; ++r)
1177 for (q = 0; q <
P; ++q)
1179 maparray[(r + 1) *
P + q] =
GetMode(1, q, r);
1184 for (p = 0; p <
P; ++p)
1186 for (r = 0; r < Q - p; ++r)
1188 maparray[idx++] =
GetMode(p, 1, r);
1193 for (r = 0; r < Q; ++r)
1195 for (q = 0; q <
P; ++q)
1197 maparray[r *
P + q] =
GetMode(0, q, r);
1202 ASSERTL0(
false,
"Face to element map unavailable.");
1212 "Method only implemented if BasisType is identical"
1213 "in x and y directions");
1216 "Method only implemented for Modified_A BasisType"
1217 "(x and y direction) and Modified_B BasisType (z "
1220 int i, j, k, p, r, nFaceCoeffs, idx = 0;
1221 int nummodesA = 0, nummodesB = 0;
1226 nummodesA =
m_base[0]->GetNumModes();
1227 nummodesB =
m_base[1]->GetNumModes();
1231 nummodesA =
m_base[0]->GetNumModes();
1232 nummodesB =
m_base[2]->GetNumModes();
1236 nummodesA =
m_base[1]->GetNumModes();
1237 nummodesB =
m_base[2]->GetNumModes();
1240 ASSERTL0(
false,
"fid must be between 0 and 4");
1249 else if (fid == 1 || fid == 3)
1251 nFaceCoeffs =
P * (2 * Q -
P + 1) / 2;
1255 nFaceCoeffs =
P * Q;
1259 if (maparray.size() != nFaceCoeffs)
1264 if (signarray.size() != nFaceCoeffs)
1270 fill(signarray.data(), signarray.data() + nFaceCoeffs, 1);
1273 int minPA =
min(nummodesA,
P);
1274 int minQB =
min(nummodesB, Q);
1276 if (fid == 1 || fid == 3)
1283 for (j = 0; j < minPA; ++j)
1286 for (k = 0; k < minQB - j; ++k, ++cnt)
1288 maparray[idx++] = cnt;
1291 cnt += nummodesB - minQB;
1294 for (k = nummodesB - j; k < Q - j; ++k)
1296 signarray[idx] = 0.0;
1297 maparray[idx++] = maparray[0];
1301 for (j = nummodesA; j <
P; ++j)
1303 for (k = 0; k < Q - j; ++k)
1305 signarray[idx] = 0.0;
1306 maparray[idx++] = maparray[0];
1315 for (p = 0; p <
P; ++p)
1317 for (r = 0; r < Q - p; ++r, idx++)
1321 signarray[idx] = p % 2 ? -1 : 1;
1326 swap(maparray[0], maparray[Q]);
1327 for (i = 1; i < Q - 1; ++i)
1329 swap(maparray[i + 1], maparray[Q + i]);
1339 for (i = 0; i < Q; i++)
1341 for (j = 0; j <
P; j++)
1345 arrayindx[i *
P + j] = i *
P + j;
1349 arrayindx[i *
P + j] = j * Q + i;
1356 for (j = 0; j <
P; ++j)
1359 for (k = 0; k < Q; k++)
1361 maparray[arrayindx[j + k *
P]] = j + k * nummodesA;
1364 for (k = nummodesB; k < Q; ++k)
1366 signarray[arrayindx[j + k *
P]] = 0.0;
1367 maparray[arrayindx[j + k *
P]] = maparray[0];
1371 for (j = nummodesA; j <
P; ++j)
1373 for (k = 0; k < Q; ++k)
1375 signarray[arrayindx[j + k *
P]] = 0.0;
1376 maparray[arrayindx[j + k *
P]] = maparray[0];
1391 for (i = 3; i < Q; i += 2)
1393 for (j = 0; j <
P; j++)
1395 signarray[arrayindx[i *
P + j]] *= -1;
1399 for (i = 0; i <
P; i++)
1401 swap(maparray[i], maparray[i +
P]);
1402 swap(signarray[i], signarray[i +
P]);
1407 for (i = 0; i < Q; i++)
1409 for (j = 3; j <
P; j += 2)
1411 signarray[arrayindx[i *
P + j]] *= -1;
1415 for (i = 0; i < Q; i++)
1417 swap(maparray[i], maparray[i + Q]);
1418 swap(signarray[i], signarray[i + Q]);
1430 for (i = 0; i < Q; i++)
1432 for (j = 3; j <
P; j += 2)
1434 signarray[arrayindx[i *
P + j]] *= -1;
1438 for (i = 0; i < Q; i++)
1440 swap(maparray[i *
P], maparray[i *
P + 1]);
1441 swap(signarray[i *
P], signarray[i *
P + 1]);
1446 for (i = 3; i < Q; i += 2)
1448 for (j = 0; j <
P; j++)
1450 signarray[arrayindx[i *
P + j]] *= -1;
1454 for (i = 0; i <
P; i++)
1456 swap(maparray[i * Q], maparray[i * Q + 1]);
1457 swap(signarray[i * Q], signarray[i * Q + 1]);
1470 const int P =
m_base[0]->GetNumModes() - 1;
1471 const int Q =
m_base[1]->GetNumModes() - 1;
1472 const int R =
m_base[2]->GetNumModes() - 1;
1475 if (maparray.size() != nEdgeIntCoeffs)
1480 if (signarray.size() != nEdgeIntCoeffs)
1486 fill(signarray.data(), signarray.data() + nEdgeIntCoeffs, 1);
1496 for (i = 2; i <=
P; ++i)
1498 maparray[i - 2] =
GetMode(i, 0, 0);
1503 for (i = 2; i <= Q; ++i)
1505 maparray[i - 2] =
GetMode(1, i, 0);
1512 for (i = 2; i <=
P; ++i)
1514 maparray[i - 2] =
GetMode(i, 1, 0);
1521 for (i = 2; i <= Q; ++i)
1523 maparray[i - 2] =
GetMode(0, i, 0);
1528 for (i = 2; i <= R; ++i)
1530 maparray[i - 2] =
GetMode(0, 0, i);
1535 for (i = 1; i <= R - 1; ++i)
1537 maparray[i - 1] =
GetMode(1, 0, i);
1542 for (i = 1; i <= R - 1; ++i)
1544 maparray[i - 1] =
GetMode(1, 1, i);
1549 for (i = 2; i <= R; ++i)
1551 maparray[i - 2] =
GetMode(0, 1, i);
1556 for (i = 2; i <= Q; ++i)
1558 maparray[i - 2] =
GetMode(0, i, 1);
1563 ASSERTL0(
false,
"Edge not defined.");
1569 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1580 const int P =
m_base[0]->GetNumModes() - 1;
1581 const int Q =
m_base[1]->GetNumModes() - 1;
1582 const int R =
m_base[2]->GetNumModes() - 1;
1584 int p, q, r, idx = 0;
1590 if (maparray.size() != nFaceIntCoeffs)
1595 if (signarray.size() != nFaceIntCoeffs)
1601 fill(signarray.data(), signarray.data() + nFaceIntCoeffs, 1);
1607 if (fid != 1 && fid != 3)
1620 for (i = 0; i < nummodesB; i++)
1622 for (j = 0; j < nummodesA; j++)
1626 arrayindx[i * nummodesA + j] = i * nummodesA + j;
1630 arrayindx[i * nummodesA + j] = j * nummodesB + i;
1639 for (q = 2; q <= Q; ++q)
1641 for (p = 2; p <=
P; ++p)
1643 maparray[arrayindx[(q - 2) * nummodesA + (p - 2)]] =
1650 for (p = 2; p <=
P; ++p)
1652 for (r = 1; r <= R - p; ++r)
1656 signarray[idx] = p % 2 ? -1 : 1;
1658 maparray[idx++] =
GetMode(p, 0, r);
1664 for (r = 1; r <= R - 1; ++r)
1666 for (q = 2; q <= Q; ++q)
1668 maparray[arrayindx[(r - 1) * nummodesA + (q - 2)]] =
1675 for (p = 2; p <=
P; ++p)
1677 for (r = 1; r <= R - p; ++r)
1681 signarray[idx] = p % 2 ? -1 : 1;
1683 maparray[idx++] =
GetMode(p, 1, r);
1689 for (r = 2; r <= R; ++r)
1691 for (q = 2; q <= Q; ++q)
1693 maparray[arrayindx[(r - 2) * nummodesA + (q - 2)]] =
1700 ASSERTL0(
false,
"Face interior map not available.");
1705 if (fid == 1 || fid == 3)
1717 for (i = 1; i < nummodesB; i += 2)
1719 for (j = 0; j < nummodesA; j++)
1721 signarray[arrayindx[i * nummodesA + j]] *= -1;
1727 for (i = 0; i < nummodesB; i++)
1729 for (j = 1; j < nummodesA; j += 2)
1731 signarray[arrayindx[i * nummodesA + j]] *= -1;
1744 for (i = 0; i < nummodesB; i++)
1746 for (j = 1; j < nummodesA; j += 2)
1748 signarray[arrayindx[i * nummodesA + j]] *= -1;
1754 for (i = 1; i < nummodesB; i += 2)
1756 for (j = 0; j < nummodesA; j++)
1758 signarray[arrayindx[i * nummodesA + j]] *= -1;
1780 int nq0 =
m_base[0]->GetNumPoints();
1781 int nq1 =
m_base[1]->GetNumPoints();
1782 int nq2 =
m_base[2]->GetNumPoints();
1792 nq =
max(nq0,
max(nq1, nq2));
1805 for (
int i = 0; i < nq; ++i)
1807 for (
int j = 0; j < nq; ++j)
1809 for (
int k = 0; k < nq - i; ++k, ++cnt)
1812 coords[cnt][0] = -1.0 + 2 * k / (
NekDouble)(nq - 1);
1813 coords[cnt][1] = -1.0 + 2 * j / (
NekDouble)(nq - 1);
1814 coords[cnt][2] = -1.0 + 2 * i / (
NekDouble)(nq - 1);
1819 for (
int i = 0; i < neq; ++i)
1823 I[0] =
m_base[0]->GetI(coll);
1824 I[1] =
m_base[1]->GetI(coll + 1);
1825 I[2] =
m_base[2]->GetI(coll + 2);
1829 for (
int k = 0; k < nq2; ++k)
1831 for (
int j = 0; j < nq1; ++j)
1834 fac = (I[1]->GetPtr())[j] * (I[2]->GetPtr())[k];
1838 Mat->GetRawPtr() + k * nq0 * nq1 * neq +
1848 int nq0 =
m_base[0]->GetNumPoints();
1849 int nq1 =
m_base[1]->GetNumPoints();
1850 int nq2 =
m_base[2]->GetNumPoints();
1860 nq =
max(nq0,
max(nq1, nq2));
1882 for (
int i = 0; i < neq; ++i)
1884 coords[0] = x[sorted[i]];
1885 coords[1] = y[sorted[i]];
1886 coords[2] = z[sorted[i]];
1890 I[0] =
m_base[0]->GetI(coll);
1891 I[1] =
m_base[1]->GetI(coll + 1);
1892 I[2] =
m_base[2]->GetI(coll + 2);
1896 for (
int k = 0; k < nq2; ++k)
1898 for (
int j = 0; j < nq1; ++j)
1901 fac = (I[1]->GetPtr())[j] * (I[2]->GetPtr())[k];
1905 Mat->GetRawPtr() + k * nq0 * nq1 * neq +
1949 int Q =
m_base[1]->GetNumModes() - 1;
1950 int R =
m_base[2]->GetNumModes() - 1;
1954 (Q + 1) * (p * R + 1 -
1955 (p - 2) * (p - 1) / 2);
1962 int qa =
m_base[0]->GetNumPoints();
1963 int qb =
m_base[1]->GetNumPoints();
1964 int qc =
m_base[2]->GetNumPoints();
1965 int nmodes_a =
m_base[0]->GetNumModes();
1966 int nmodes_b =
m_base[1]->GetNumModes();
1967 int nmodes_c =
m_base[2]->GetNumModes();
1979 int i, j, k, cnt = 0;
1982 OrthoExp.
FwdTrans(array, orthocoeffs);
1992 for (i = 0; i < nmodes_a; ++i)
1994 for (j = 0; j < nmodes_b; ++j)
1997 pow((1.0 * i) / (nmodes_a - 1), cutoff * nmodes_a),
1998 pow((1.0 * j) / (nmodes_b - 1), cutoff * nmodes_b));
2000 for (k = 0; k < nmodes_c - i; ++k)
2003 std::max(fac1, pow((1.0 * k) / (nmodes_c - 1),
2004 cutoff * nmodes_c));
2006 orthocoeffs[cnt] *= SvvDiffCoeff * fac;
2022 max_abc =
max(max_abc, 0);
2025 for (i = 0; i < nmodes_a; ++i)
2027 for (j = 0; j < nmodes_b; ++j)
2029 int maxij =
max(i, j);
2031 for (k = 0; k < nmodes_c - i; ++k)
2033 int maxijk =
max(maxij, k);
2055 int cutoff_a = (int)(SVVCutOff * nmodes_a);
2056 int cutoff_b = (int)(SVVCutOff * nmodes_b);
2057 int cutoff_c = (int)(SVVCutOff * nmodes_c);
2061 int nmodes =
min(
min(nmodes_a, nmodes_b), nmodes_c);
2065 for (i = 0; i < nmodes_a; ++i)
2067 for (j = 0; j < nmodes_b; ++j)
2069 for (k = 0; k < nmodes_c - i; ++k)
2071 if (j >= cutoff || i + k >= cutoff)
2075 exp(-(i + k - nmodes) * (i + k - nmodes) /
2076 ((
NekDouble)((i + k - cutoff + epsilon) *
2077 (i + k - cutoff + epsilon)))) *
2078 exp(-(j - nmodes) * (j - nmodes) /
2080 (j - cutoff + epsilon)))));
2084 orthocoeffs[cnt] *= 0.0;
2093 OrthoExp.
BwdTrans(orthocoeffs, array);
2100 int nquad0 =
m_base[0]->GetNumPoints();
2101 int nquad1 =
m_base[1]->GetNumPoints();
2102 int nquad2 =
m_base[2]->GetNumPoints();
2103 int nqtot = nquad0 * nquad1 * nquad2;
2104 int nmodes0 =
m_base[0]->GetNumModes();
2105 int nmodes1 =
m_base[1]->GetNumModes();
2106 int nmodes2 =
m_base[2]->GetNumModes();
2107 int numMax = nmodes0;
2128 bortho0, bortho1, bortho2);
2131 OrthoPrismExp->FwdTrans(phys_tmp, coeff);
2134 for (u = 0; u < numMin; ++u)
2136 for (i = 0; i < numMin; ++i)
2139 tmp2 = coeff_tmp1 + cnt, 1);
2143 for (i = numMin; i < numMax; ++i)
2149 OrthoPrismExp->BwdTrans(coeff_tmp1, phys_tmp);
#define ASSERTL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
#define IPRODUCTWRTBASE_DEF
#define IPRODUCTWRTBASE_M(r, i)
#define STDLEV2TEST(r, state)
#define STDLEV2UPDATE(r, state)
Describes the specification for a Basis.
int GetNumModes() const
Returns the order of the basis.
static void CartesianOrdering(const int nq, Array< OneD, int > &sorted)
Defines a specification for a set of points.
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
NekDouble BaryTensorDeriv(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs)
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.
void v_PhysDeriv(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Calculate the derivative of the physical points in a given direction.
The base class for all shapes.
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.
int NumBndryCoeffs(void) const
void LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta)
Convert local cartesian coordinate xi into local collapsed coordinates eta.
const Array< OneD, const LibUtilities::BasisSharedPtr > & GetBase() const
This function gets the shared point to basis.
DNekMatSharedPtr CreateGeneralMatrix(const StdMatrixKey &mkey)
this function generates the mass matrix
NekDouble PhysEvaluate(const Array< OneD, const NekDouble > &coords, const Array< OneD, const NekDouble > &physvals)
This function evaluates the expansion at a single (arbitrary) point of the 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.
int GetTraceNcoeffs(const int i) const
This function returns the number of expansion coefficients belonging to the i-th trace.
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)
int GetNumPoints(const int dir) const
This function returns the number of quadrature points in the dir direction.
Array< OneD, const NekDouble > GetStdFac(const StdFacKey &mkey)
int GetBasisNumModes(const int dir) const
This function returns the number of expansion modes in the dir direction.
Array< OneD, LibUtilities::BasisSharedPtr > m_base
std::vector< Array< OneD, const NekDouble > > m_weights
MatrixType GetMatrixType() const
NekDouble GetConstFactor(const ConstFactorType &factor) const
bool ConstFactorExists(const ConstFactorType &factor) const
Class representing a prismatic element in reference space.
void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdMatrixKey &mkey) override
void v_GetElmtTraceToTraceMap(const unsigned int fid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, Orientation faceOrient, int P, int Q) override
void v_ReduceOrderCoeffs(int numMin, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_GetEdgeInteriorToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation traceOrient=eDir1FwdDir1_Dir2FwdDir2) override
LibUtilities::PointsKey v_GetTracePointsKey(const int i, const int j) const override
const LibUtilities::BasisKey v_GetTraceBasisKey(const int i, const int k, bool UseGLL=false) const override
NekDouble v_PhysEvalFirstDeriv(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs) override
int v_GetVertexMap(int localVertexId, bool useCoeffPacking=false) override
int v_CalcNumberOfCoefficients(const std::vector< unsigned int > &nummodes, int &modes_offset) override
int v_GetTraceIntNcoeffs(const int i) const override
int v_NumBndryCoeffs() const override
void v_FillMode(const int mode, Array< OneD, NekDouble > &outarray) override
NekDouble v_PhysEvaluateBasis(const Array< OneD, const NekDouble > &coords, int mode) final
void v_BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
LibUtilities::ShapeType v_DetShapeType() const override
Return Shape of region, using ShapeType enum list; i.e. prism.
int v_GetNtraces() const final
int v_NumDGBndryCoeffs() const override
void v_GetTraceNumModes(const int fid, int &numModes0, int &numModes1, Orientation faceOrient=eDir1FwdDir1_Dir2FwdDir2) override
void v_GetCoords(Array< OneD, NekDouble > &xi_x, Array< OneD, NekDouble > &xi_y, Array< OneD, NekDouble > &xi_z) override
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...
void v_GetBoundaryMap(Array< OneD, unsigned int > &outarray) override
DNekMatSharedPtr v_CreateStdMatrix(const StdMatrixKey &mkey) override
void v_StdPhysDeriv(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.
int GetMode(int I, int J, int K)
Compute the local mode number in the expansion for a particular tensorial combination.
int v_GetTraceNcoeffs(const int i) const override
int v_GetNedges() const final
int v_GetNverts() const final
int v_GetEdgeNcoeffs(const int i) const override
void v_LocCollapsedToLocCoord(const Array< OneD, const NekDouble > &eta, Array< OneD, NekDouble > &xi) override
void v_GetInteriorMap(Array< OneD, unsigned int > &outarray) override
void v_GetTraceCoeffMap(const unsigned int fid, Array< OneD, unsigned int > &maparray) override
void v_GetTraceInteriorToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation traceOrient=eDir1FwdDir1_Dir2FwdDir2) override
DNekMatSharedPtr v_GenMatrix(const StdMatrixKey &mkey) override
int v_GetTraceNumPoints(const int i) const override
bool v_IsBoundaryInteriorExpansion() const override
void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Inner product of inarray over region with respect to the object's default expansion basis; output in ...
void v_LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta) override
constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
static const BasisKey NullBasisKey(eNoBasisType, 0, NullPointsKey)
Defines a null basis with no type or points.
PointsManagerT & PointsManager(void)
@ eNodalPrismElec
3D electrostatically spaced points on a Prism
@ eModified_B
Principle Modified Functions .
@ eOrtho_A
Principle Orthogonal Functions .
@ eModified_C
Principle Modified Functions .
@ eGLL_Lagrange
Lagrange for SEM basis .
@ eOrtho_C
Principle Orthogonal Functions .
@ eOrtho_B
Principle Orthogonal Functions .
@ eModified_A
Principle Modified Functions .
static const NekDouble kNekZeroTol
std::shared_ptr< StdPrismExp > StdPrismExpSharedPtr
LibUtilities::BasisKey EvaluateQuadFaceBasisKey(const int facedir, const LibUtilities::BasisSharedPtr &faceDirBasis)
@ eFactorSVVDGKerDiffCoeff
@ eFactorSVVPowerKerDiffCoeff
LibUtilities::BasisKey EvaluateTriFaceBasisKey(const int facedir, const LibUtilities::BasisSharedPtr &faceDirBasis, bool UseGLL)
const int kSVVDGFiltermodesmin
tinysimd::scalarT< double > vec_t
const int kSVVDGFiltermodesmax
const NekDouble kSVVDGFilter[9][11]
@ ePhysInterpToEquiSpaced
@ eDir1BwdDir2_Dir2BwdDir1
@ eDir1BwdDir1_Dir2BwdDir2
@ eDir1BwdDir2_Dir2FwdDir1
@ eDir1FwdDir1_Dir2BwdDir2
@ eDir1BwdDir1_Dir2FwdDir2
@ eDir1FwdDir2_Dir2FwdDir1
@ eDir1FwdDir2_Dir2BwdDir1
static Array< OneD, NekDouble > NullNekDouble1DArray
std::shared_ptr< DNekMat > DNekMatSharedPtr
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.
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.
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.
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
scalarT< T > max(scalarT< T > lhs, scalarT< T > rhs)
scalarT< T > min(scalarT< T > lhs, scalarT< T > rhs)
scalarT< T > sqrt(scalarT< T > in)