55 :
StdExpansion(LibUtilities::StdTetData::getNumberOfCoefficients(
56 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
59 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
63 "order in 'a' direction is higher than order "
66 "order in 'a' direction is higher than order "
69 "order in 'b' direction is higher than order "
108 int Q0 =
m_base[0]->GetNumPoints();
109 int Q1 =
m_base[1]->GetNumPoints();
110 int Q2 =
m_base[2]->GetNumPoints();
111 int Qtot = Q0 * Q1 * Q2;
118 bool Do_2 = (out_dxi2.size() > 0) ?
true :
false;
119 bool Do_1 = (out_dxi1.size() > 0) ?
true :
false;
136 eta_0 =
m_base[0]->GetZ();
137 eta_1 =
m_base[1]->GetZ();
138 eta_2 =
m_base[2]->GetZ();
144 for (
int k = 0; k < Q2; ++k)
146 for (
int j = 0; j < Q1; ++j, dEta0 += Q0)
148 Vmath::Smul(Q0, 2.0 / (1.0 - eta_1[j]), dEta0, 1, dEta0, 1);
150 fac = 1.0 / (1.0 - eta_2[k]);
151 Vmath::Smul(Q0 * Q1, fac, &out_dEta0[0] + k * Q0 * Q1, 1,
152 &out_dEta0[0] + k * Q0 * Q1, 1);
155 if (out_dxi0.size() > 0)
167 for (
int k = 0; k < Q1 * Q2; ++k)
169 Vmath::Vmul(Q0, &Fac0[0], 1, &out_dEta0[0] + k * Q0, 1,
170 &out_dEta0[0] + k * Q0, 1);
173 for (
int k = 0; k < Q2; ++k)
176 &out_dEta1[0] + k * Q0 * Q1, 1,
177 &out_dEta1[0] + k * Q0 * Q1, 1);
184 Vmath::Vadd(Qtot, out_dEta0, 1, out_dEta1, 1, out_dxi1, 1);
191 for (
int k = 0; k < Q2; ++k)
193 for (
int j = 0; j < Q1; ++j, dEta1 += Q0)
195 Vmath::Smul(Q0, (1.0 + eta_1[j]) / 2.0, dEta1, 1, dEta1, 1);
202 Vmath::Vadd(Qtot, out_dEta0, 1, out_dEta1, 1, out_dxi2, 1);
203 Vmath::Vadd(Qtot, out_dEta2, 1, out_dxi2, 1, out_dxi2, 1);
238 "Basis[1] is not a general tensor type");
242 "Basis[2] is not a general tensor type");
248 int nquad0 =
m_base[0]->GetNumPoints();
249 int nquad1 =
m_base[1]->GetNumPoints();
250 int nquad2 =
m_base[2]->GetNumPoints();
252 int nmodes0 =
m_base[0]->GetNumModes();
253 int nmodes1 =
m_base[1]->GetNumModes();
254 int nmodes2 =
m_base[2]->GetNumModes();
258 std::vector<vec_t, tinysimd::allocator<vec_t>> wsp0(nmodes0 * nmodes1),
269#define BWDTRANS_DEF \
270 BwdTransTetKernel(nmodes0, nmodes1, nmodes2, nquad0, nquad1, nquad2, \
271 isModified, (const vec_t *)base0.data(), \
272 (const vec_t *)base1.data(), \
273 (const vec_t *)base2.data(), wsp0.data(), wsp1.data(), \
274 (const vec_t *)inarray.data(), (vec_t *)outarray.data())
278#define BWDTRANS_Q(r, i) \
281 NM(i), NM(i), NM(i), NQ(i), NQ_M1(i), NQ_M1(i), isModified, \
282 (const vec_t *)base0.data(), (const vec_t *)base1.data(), \
283 (const vec_t *)base2.data(), wsp0.data(), wsp1.data(), \
284 (const vec_t *)inarray.data(), (vec_t *)outarray.data()); \
289#define BWDTRANS_M(r, i) \
294 BOOST_PP_FOR_##r((NM(i), NM_P1(i), BOOST_PP_MUL(2, NM(i))), \
295 STDLEV2TEST1, STDLEV2UPDATE1, BWDTRANS_Q) default \
305 if ((nmodes0 == nmodes1) && (nmodes1 == nmodes2) &&
306 (nquad0 == nquad1 + 1) && (nquad1 == nquad2))
352 const bool Deformed, [[maybe_unused]]
bool CollDir0,
353 [[maybe_unused]]
bool CollDir1, [[maybe_unused]]
bool CollDir2)
357 "Basis[1] is not a general tensor type");
361 "Basis[2] is not a general tensor type");
363 int nquad0 =
m_base[0]->GetNumPoints();
364 int nquad1 =
m_base[1]->GetNumPoints();
365 int nquad2 =
m_base[2]->GetNumPoints();
367 int order0 =
m_base[0]->GetNumModes();
368 int order1 =
m_base[1]->GetNumModes();
369 int order2 =
m_base[2]->GetNumModes();
371 const bool isModified =
374 std::vector<vec_t, tinysimd::allocator<vec_t>> wsp0(nquad1 * nquad2),
386#undef IPRODUCTWRTBASE_DEF
387#define IPRODUCTWRTBASE_DEF \
388 IProductTetKernel<false, false, true>( \
389 order0, order1, order2, nquad0, nquad1, nquad2, isModified, \
390 (const vec_t *)inarray.data(), (const vec_t *)base0.data(), \
391 (const vec_t *)base1.data(), (const vec_t *)base2.data(), \
392 (const vec_t *)m_weights[0].data(), \
393 (const vec_t *)m_weights[1].data(), \
394 (const vec_t *)m_weights[2].data(), (const vec_t *)jac.data(), \
395 (vec_t *)wsp0.data(), (vec_t *)wsp1.data(), (vec_t *)outarray.data())
398#undef IPRODUCTWRTBASE_Q
399#define IPRODUCTWRTBASE_Q(r, i) \
401 IProductTetKernel<false, false, true>( \
402 NM(i), NM(i), NM(i), NQ(i), NQ_M1(i), NQ_M1(i), isModified, \
403 (const vec_t *)inarray.data(), (const vec_t *)base0.data(), \
404 (const vec_t *)base1.data(), (const vec_t *)base2.data(), \
405 (const vec_t *)m_weights[0].data(), \
406 (const vec_t *)m_weights[1].data(), \
407 (const vec_t *)m_weights[2].data(), (const vec_t *)jac.data(), \
408 (vec_t *)wsp0.data(), (vec_t *)wsp1.data(), \
409 (vec_t *)outarray.data()); \
413#undef IPRODUCTWRTBASE_M
414#define IPRODUCTWRTBASE_M(r, i) \
419 BOOST_PP_FOR_##r((NM(i), NM_P1(i), BOOST_PP_MUL(2, NM(i))), \
420 STDLEV2TEST1, STDLEV2UPDATE1, \
421 IPRODUCTWRTBASE_Q) default : IPRODUCTWRTBASE_DEF; \
429 if ((order0 == order1) && (order1 == order2) &&
430 (nquad0 == nquad1 + 1) && (nquad1 == nquad2))
449#undef IPRODUCTWRTBASE_DEF
450#define IPRODUCTWRTBASE_DEF \
451 IProductTetKernel<false, false, false>( \
452 order0, order1, order2, nquad0, nquad1, nquad2, isModified, \
453 (const vec_t *)inarray.data(), (const vec_t *)base0.data(), \
454 (const vec_t *)base1.data(), (const vec_t *)base2.data(), \
455 (const vec_t *)m_weights[0].data(), \
456 (const vec_t *)m_weights[1].data(), \
457 (const vec_t *)m_weights[2].data(), (const vec_t *)jac.data(), \
458 (vec_t *)wsp0.data(), (vec_t *)wsp1.data(), (vec_t *)outarray.data())
461#undef IPRODUCTWRTBASE_Q
462#define IPRODUCTWRTBASE_Q(r, i) \
464 IProductTetKernel<false, false, false>( \
465 NM(i), NM(i), NM(i), NQ(i), NQ_M1(i), NQ_M1(i), isModified, \
466 (const vec_t *)inarray.data(), (const vec_t *)base0.data(), \
467 (const vec_t *)base1.data(), (const vec_t *)base2.data(), \
468 (const vec_t *)m_weights[0].data(), \
469 (const vec_t *)m_weights[1].data(), \
470 (const vec_t *)m_weights[2].data(), (const vec_t *)jac.data(), \
471 (vec_t *)wsp0.data(), (vec_t *)wsp1.data(), \
472 (vec_t *)outarray.data()); \
476#undef IPRODUCTWRTBASE_M
477#define IPRODUCTWRTBASE_M(r, i) \
482 BOOST_PP_FOR_##r((NM(i), NM_P1(i), BOOST_PP_MUL(2, NM(i))), \
483 STDLEV2TEST1, STDLEV2UPDATE1, \
484 IPRODUCTWRTBASE_Q) default : IPRODUCTWRTBASE_DEF; \
492 if ((order0 == order1) && (order1 == order2) &&
493 (nquad0 == nquad1 + 1) && (nquad1 == nquad2))
522 int nquad0 =
m_base[0]->GetNumPoints();
523 int nquad1 =
m_base[1]->GetNumPoints();
524 int nquad2 =
m_base[2]->GetNumPoints();
525 int nqtot = nquad0 * nquad1 * nquad2;
526 int nmodes0 =
m_base[0]->GetNumModes();
527 int nmodes1 =
m_base[1]->GetNumModes();
531 nquad2 * nmodes0 * (2 * nmodes1 - nmodes0 + 1) /
542 for (i = 0; i < nquad1 * nquad2; ++i)
544 Vmath::Smul(nquad0, gfac1[i % nquad1], &inarray[0] + i * nquad0, 1,
545 &tmp0[0] + i * nquad0, 1);
547 for (i = 0; i < nquad2; ++i)
549 Vmath::Smul(nquad0 * nquad1, gfac2[i], &tmp0[0] + i * nquad0 * nquad1,
550 1, &tmp0[0] + i * nquad0 * nquad1, 1);
561 m_base[2]->GetBdata(), tmp0, outarray, one,
false);
568 for (i = 0; i < nquad1 * nquad2; ++i)
570 Vmath::Vmul(nquad0, &gfac0[0], 1, &tmp0[0] + i * nquad0, 1,
571 &tmp0[0] + i * nquad0, 1);
576 m_base[2]->GetBdata(), tmp0, tmp3, one,
false);
578 for (i = 0; i < nquad2; ++i)
581 &inarray[0] + i * nquad0 * nquad1, 1,
582 &tmp0[0] + i * nquad0 * nquad1, 1);
587 m_base[2]->GetBdata(), tmp0, outarray, one,
false);
599 for (i = 0; i < nquad1 * nquad2; ++i)
601 Vmath::Vmul(nquad0, &gfac0[0], 1, &tmp0[0] + i * nquad0, 1,
602 &tmp0[0] + i * nquad0, 1);
606 m_base[2]->GetBdata(), tmp0, tmp3, one,
false);
608 for (i = 0; i < nquad2; ++i)
611 &inarray[0] + i * nquad0 * nquad1, 1,
612 &tmp0[0] + i * nquad0 * nquad1, 1);
614 for (i = 0; i < nquad1 * nquad2; ++i)
616 Vmath::Smul(nquad0, gfac1[i % nquad1], &tmp0[0] + i * nquad0, 1,
617 &tmp0[0] + i * nquad0, 1);
622 m_base[2]->GetBdata(), tmp0, tmp4, one,
false);
626 m_base[2]->GetDbdata(), inarray, outarray, one,
false);
635 ASSERTL1(
false,
"input dir is out of range");
672 eta[0] = 2.0 * (1.0 + xi[0]) / d12 - 1.0;
673 eta[1] = 2.0 * (1.0 + xi[1]) / d2 - 1.0;
681 xi[1] = (1.0 + eta[1]) * (1.0 - xi[2]) * 0.5 - 1.0;
682 xi[0] = (1.0 + eta[0]) * (-xi[1] - xi[2]) * 0.5 - 1.0;
698 const int nm1 =
m_base[1]->GetNumModes();
699 const int nm2 =
m_base[2]->GetNumModes();
701 const int b = 2 * nm2 + 1;
702 const int mode0 = floor(0.5 * (b -
sqrt(b * b - 8.0 * mode / nm1)));
704 mode - nm1 * (mode0 * (nm2 - 1) + 1 - (mode0 - 2) * (mode0 - 1) / 2);
705 const int mode1 = tmp / (nm2 - mode0);
706 const int mode2 = tmp % (nm2 - mode0);
715 return StdExpansion::BaryEvaluateBasis<2>(coll[2], 1);
717 else if (mode0 == 0 && mode2 == 1)
719 return StdExpansion::BaryEvaluateBasis<1>(coll[1], 0) *
720 StdExpansion::BaryEvaluateBasis<2>(coll[2], 1);
722 else if (mode0 == 1 && mode1 == 1 && mode2 == 0)
724 return StdExpansion::BaryEvaluateBasis<0>(coll[0], 0) *
725 StdExpansion::BaryEvaluateBasis<1>(coll[1], 1);
729 return StdExpansion::BaryEvaluateBasis<0>(coll[0], mode0) *
730 StdExpansion::BaryEvaluateBasis<1>(coll[1], mode1) *
731 StdExpansion::BaryEvaluateBasis<2>(coll[2], mode2);
737 std::array<NekDouble, 3> &firstOrderDerivs)
744 if ((1 - coll[1]) < 1e-5 || (1 - coll[2]) < 1e-5)
748 EphysDeriv2(totPoints);
749 v_PhysDeriv(inarray, EphysDeriv0, EphysDeriv1, EphysDeriv2);
752 I[0] =
GetBase()[0]->GetI(coll);
753 I[1] =
GetBase()[1]->GetI(coll + 1);
754 I[2] =
GetBase()[2]->GetI(coll + 2);
762 std::array<NekDouble, 3> interDeriv;
766 NekDouble temp = 2.0 / ((1 - coll[1]) * (1 - coll[2]));
767 interDeriv[0] *= temp;
770 firstOrderDerivs[0] = 2 * interDeriv[0];
777 interDeriv[0] *= fac0;
780 fac0 = 2 / (1 - coll[2]);
781 interDeriv[1] *= fac0;
785 firstOrderDerivs[1] = interDeriv[0] + interDeriv[1];
788 fac0 = (1 + coll[1]) / 2;
789 interDeriv[1] *= fac0;
794 firstOrderDerivs[2] = interDeriv[0] + interDeriv[1] + interDeriv[2];
803 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
804 m_base[2]->GetNumModes()};
809 numModes0 = nummodes[0];
810 numModes1 = nummodes[1];
815 numModes0 = nummodes[0];
816 numModes1 = nummodes[2];
822 numModes0 = nummodes[1];
823 numModes1 = nummodes[2];
857 "BasisType is not a boundary interior form");
860 "BasisType is not a boundary interior form");
863 "BasisType is not a boundary interior form");
865 int P =
m_base[0]->GetNumModes();
866 int Q =
m_base[1]->GetNumModes();
867 int R =
m_base[2]->GetNumModes();
876 "BasisType is not a boundary interior form");
879 "BasisType is not a boundary interior form");
882 "BasisType is not a boundary interior form");
884 int P =
m_base[0]->GetNumModes() - 1;
885 int Q =
m_base[1]->GetNumModes() - 1;
886 int R =
m_base[2]->GetNumModes() - 1;
888 return (Q + 1) +
P * (1 + 2 * Q -
P) / 2
889 + (R + 1) +
P * (1 + 2 * R -
P) / 2
890 + 2 * (R + 1) + Q * (1 + 2 * R - Q);
895 ASSERTL2((i >= 0) && (i <= 3),
"face id is out of range");
897 int nummodesA, nummodesB,
P, Q;
903 else if ((i == 1) || (i == 2))
915 nFaceCoeffs = Q + 1 + (
P * (1 + 2 * Q -
P)) / 2;
921 ASSERTL2((i >= 0) && (i <= 3),
"face id is out of range");
922 int Pi =
m_base[0]->GetNumModes() - 2;
923 int Qi =
m_base[1]->GetNumModes() - 2;
924 int Ri =
m_base[2]->GetNumModes() - 2;
928 return Pi * (2 * Qi - Pi - 1) / 2;
932 return Pi * (2 * Ri - Pi - 1) / 2;
936 return Qi * (2 * Ri - Qi - 1) / 2;
942 ASSERTL2(i >= 0 && i <= 3,
"face id is out of range");
946 return m_base[0]->GetNumPoints() *
m_base[1]->GetNumPoints();
950 return m_base[0]->GetNumPoints() *
m_base[2]->GetNumPoints();
954 return m_base[1]->GetNumPoints() *
m_base[2]->GetNumPoints();
960 ASSERTL2((i >= 0) && (i <= 5),
"edge id is out of range");
961 int P =
m_base[0]->GetNumModes();
962 int Q =
m_base[1]->GetNumModes();
963 int R =
m_base[2]->GetNumModes();
969 else if (i == 1 || i == 2)
982 ASSERTL2(i >= 0 && i <= 3,
"face id is out of range");
983 ASSERTL2(j == 0 || j == 1,
"face direction is out of range");
987 return m_base[j]->GetPointsKey();
991 return m_base[2 * j]->GetPointsKey();
995 return m_base[j + 1]->GetPointsKey();
1000 const std::vector<unsigned int> &nummodes,
int &modes_offset)
1003 nummodes[modes_offset], nummodes[modes_offset + 1],
1004 nummodes[modes_offset + 2]);
1014 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
1015 ASSERTL2(k == 0 || k == 1,
"face direction out of range");
1048 for (
int k = 0; k < Qz; ++k)
1050 for (
int j = 0; j < Qy; ++j)
1052 for (
int i = 0; i < Qx; ++i)
1054 int s = i + Qx * (j + Qy * k);
1056 (eta_x[i] + 1.0) * (1.0 - eta_y[j]) * (1.0 - eta_z[k]) / 4 -
1058 xi_y[s] = (eta_y[j] + 1.0) * (1.0 - eta_z[k]) / 2 - 1.0;
1080 "Mapping not defined for this type of basis");
1083 if (useCoeffPacking ==
true)
1085 switch (localVertexId)
1109 ASSERTL0(
false,
"Vertex ID must be between 0 and 3");
1116 switch (localVertexId)
1140 ASSERTL0(
false,
"Vertex ID must be between 0 and 3");
1160 "BasisType is not a boundary interior form");
1163 "BasisType is not a boundary interior form");
1166 "BasisType is not a boundary interior form");
1168 int P =
m_base[0]->GetNumModes();
1169 int Q =
m_base[1]->GetNumModes();
1170 int R =
m_base[2]->GetNumModes();
1174 if (outarray.size() != nIntCoeffs)
1180 for (
int i = 2; i <
P; ++i)
1182 for (
int j = 1; j < Q - i; ++j)
1184 for (
int k = 1; k < R - i - j; ++k)
1186 outarray[idx++] =
GetMode(i, j, k);
1199 "BasisType is not a boundary interior form");
1202 "BasisType is not a boundary interior form");
1205 "BasisType is not a boundary interior form");
1207 int P =
m_base[0]->GetNumModes();
1208 int Q =
m_base[1]->GetNumModes();
1209 int R =
m_base[2]->GetNumModes();
1216 if (outarray.size() != nBnd)
1221 for (i = 0; i <
P; ++i)
1226 for (j = 0; j < Q - i; j++)
1228 for (k = 0; k < R - i - j; ++k)
1230 outarray[idx++] =
GetMode(i, j, k);
1238 for (k = 0; k < R - i; ++k)
1240 outarray[idx++] =
GetMode(i, 0, k);
1242 for (j = 1; j < Q - i; ++j)
1244 outarray[idx++] =
GetMode(i, j, 0);
1254 int P = 0, Q = 0, idx = 0;
1255 int nFaceCoeffs = 0;
1261 Q =
m_base[1]->GetNumModes();
1265 Q =
m_base[2]->GetNumModes();
1270 Q =
m_base[2]->GetNumModes();
1273 ASSERTL0(
false,
"fid must be between 0 and 3");
1276 nFaceCoeffs =
P * (2 * Q -
P + 1) / 2;
1278 if (maparray.size() != nFaceCoeffs)
1287 for (i = 0; i <
P; ++i)
1289 for (j = 0; j < Q - i; ++j)
1291 maparray[idx++] =
GetMode(i, j, 0);
1297 for (i = 0; i <
P; ++i)
1299 for (k = 0; k < Q - i; ++k)
1301 maparray[idx++] =
GetMode(i, 0, k);
1307 for (j = 0; j <
P - 1; ++j)
1309 for (k = 0; k < Q - 1 - j; ++k)
1311 maparray[idx++] =
GetMode(1, j, k);
1314 if (j == 0 && k == 0)
1316 maparray[idx++] =
GetMode(0, 0, 1);
1319 if (j == 0 && k == Q - 2)
1321 for (
int r = 0; r < Q - 1; ++r)
1323 maparray[idx++] =
GetMode(0, 1, r);
1331 for (j = 0; j <
P; ++j)
1333 for (k = 0; k < Q - j; ++k)
1335 maparray[idx++] =
GetMode(0, j, k);
1340 ASSERTL0(
false,
"Element map not available.");
1349 int nummodesA = 0, nummodesB = 0, i, j, k, idx;
1352 "Method only implemented for Modified_A BasisType (x "
1353 "direction), Modified_B BasisType (y direction), and "
1354 "Modified_C BasisType(z direction)");
1356 int nFaceCoeffs = 0;
1361 nummodesA =
m_base[0]->GetNumModes();
1362 nummodesB =
m_base[1]->GetNumModes();
1365 nummodesA =
m_base[0]->GetNumModes();
1366 nummodesB =
m_base[2]->GetNumModes();
1370 nummodesA =
m_base[1]->GetNumModes();
1371 nummodesB =
m_base[2]->GetNumModes();
1374 ASSERTL0(
false,
"fid must be between 0 and 3");
1383 nFaceCoeffs =
P * (2 * Q -
P + 1) / 2;
1386 if (maparray.size() != nFaceCoeffs)
1391 if (signarray.size() != nFaceCoeffs)
1397 fill(signarray.data(), signarray.data() + nFaceCoeffs, 1);
1404 int minPA =
min(nummodesA,
P);
1405 int minQB =
min(nummodesB, Q);
1407 for (j = 0; j < minPA; ++j)
1410 for (k = 0; k < minQB - j; ++k, ++cnt)
1412 maparray[idx++] = cnt;
1415 cnt += nummodesB - minQB;
1417 for (k = nummodesB - j; k < Q - j; ++k)
1419 signarray[idx] = 0.0;
1420 maparray[idx++] = maparray[0];
1424 for (j = nummodesA; j <
P; ++j)
1426 for (k = 0; k < Q - j; ++k)
1428 signarray[idx] = 0.0;
1429 maparray[idx++] = maparray[0];
1436 for (i = 0; i <
P; ++i)
1438 for (j = 0; j < Q - i; ++j, idx++)
1442 signarray[idx] = (i % 2 ? -1 : 1);
1447 swap(maparray[0], maparray[Q]);
1449 for (i = 1; i < Q - 1; ++i)
1451 swap(maparray[i + 1], maparray[Q + i]);
1464 const int P =
m_base[0]->GetNumModes();
1465 const int Q =
m_base[1]->GetNumModes();
1466 const int R =
m_base[2]->GetNumModes();
1470 if (maparray.size() != nEdgeIntCoeffs)
1476 fill(maparray.data(), maparray.data() + nEdgeIntCoeffs, 0);
1479 if (signarray.size() != nEdgeIntCoeffs)
1485 fill(signarray.data(), signarray.data() + nEdgeIntCoeffs, 1);
1491 for (i = 0; i <
P - 2; ++i)
1493 maparray[i] =
GetMode(i + 2, 0, 0);
1497 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1504 for (i = 0; i < Q - 2; ++i)
1506 maparray[i] =
GetMode(1, i + 1, 0);
1510 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1517 for (i = 0; i < Q - 2; ++i)
1519 maparray[i] =
GetMode(0, i + 2, 0);
1523 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1530 for (i = 0; i < R - 2; ++i)
1532 maparray[i] =
GetMode(0, 0, i + 2);
1536 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1543 for (i = 0; i < R - 2; ++i)
1545 maparray[i] =
GetMode(1, 0, i + 1);
1549 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1556 for (i = 0; i < R - 2; ++i)
1558 maparray[i] =
GetMode(0, 1, i + 1);
1562 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1569 ASSERTL0(
false,
"Edge not defined.");
1579 const int P =
m_base[0]->GetNumModes();
1580 const int Q =
m_base[1]->GetNumModes();
1581 const int R =
m_base[2]->GetNumModes();
1585 if (maparray.size() != nFaceIntCoeffs)
1590 if (signarray.size() != nFaceIntCoeffs)
1596 fill(signarray.data(), signarray.data() + nFaceIntCoeffs, 1);
1603 for (i = 2; i <
P; ++i)
1605 for (j = 1; j < Q - i; ++j)
1609 signarray[idx] = (i % 2 ? -1 : 1);
1611 maparray[idx++] =
GetMode(i, j, 0);
1617 for (i = 2; i <
P; ++i)
1619 for (k = 1; k < R - i; ++k)
1623 signarray[idx] = (i % 2 ? -1 : 1);
1625 maparray[idx++] =
GetMode(i, 0, k);
1631 for (j = 1; j < Q - 1; ++j)
1633 for (k = 1; k < R - 1 - j; ++k)
1637 signarray[idx] = ((j + 1) % 2 ? -1 : 1);
1639 maparray[idx++] =
GetMode(1, j, k);
1645 for (j = 2; j < Q; ++j)
1647 for (k = 1; k < R - j; ++k)
1651 signarray[idx] = (j % 2 ? -1 : 1);
1653 maparray[idx++] =
GetMode(0, j, k);
1658 ASSERTL0(
false,
"Face interior map not available.");
1676 int nq0 =
m_base[0]->GetNumPoints();
1677 int nq1 =
m_base[1]->GetNumPoints();
1678 int nq2 =
m_base[2]->GetNumPoints();
1688 nq =
max(nq0,
max(nq1, nq2));
1702 for (
int i = 0; i < nq; ++i)
1704 for (
int j = 0; j < nq - i; ++j)
1706 for (
int k = 0; k < nq - i - j; ++k, ++cnt)
1709 coords[cnt][0] = -1.0 + 2 * k / (
NekDouble)(nq - 1);
1710 coords[cnt][1] = -1.0 + 2 * j / (
NekDouble)(nq - 1);
1711 coords[cnt][2] = -1.0 + 2 * i / (
NekDouble)(nq - 1);
1716 for (
int i = 0; i < neq; ++i)
1720 I[0] =
m_base[0]->GetI(coll);
1721 I[1] =
m_base[1]->GetI(coll + 1);
1722 I[2] =
m_base[2]->GetI(coll + 2);
1726 for (
int k = 0; k < nq2; ++k)
1728 for (
int j = 0; j < nq1; ++j)
1731 fac = (I[1]->GetPtr())[j] * (I[2]->GetPtr())[k];
1735 Mat->GetRawPtr() + k * nq0 * nq1 * neq +
1745 int nq0 =
m_base[0]->GetNumPoints();
1746 int nq1 =
m_base[1]->GetNumPoints();
1747 int nq2 =
m_base[2]->GetNumPoints();
1757 nq =
max(nq0,
max(nq1, nq2));
1778 for (
int i = 0; i < neq; ++i)
1780 coords[0] = x[sorted[i]];
1781 coords[1] = y[sorted[i]];
1782 coords[2] = z[sorted[i]];
1786 I[0] =
m_base[0]->GetI(coll);
1787 I[1] =
m_base[1]->GetI(coll + 1);
1788 I[2] =
m_base[2]->GetI(coll + 2);
1792 for (
int k = 0; k < nq2; ++k)
1794 for (
int j = 0; j < nq1; ++j)
1797 fac = (I[1]->GetPtr())[j] * (I[2]->GetPtr())[k];
1801 Mat->GetRawPtr() + k * nq0 * nq1 * neq +
1866 const int Q =
m_base[1]->GetNumModes();
1867 const int R =
m_base[2]->GetNumModes();
1869 int i, j, q_hat, k_hat;
1873 for (i = 0; i < I; ++i)
1879 cnt += q_hat * (q_hat + 1) / 2 + k_hat * (Q - i);
1884 for (j = 0; j < J; ++j)
1907 int qa =
m_base[0]->GetNumPoints();
1908 int qb =
m_base[1]->GetNumPoints();
1909 int qc =
m_base[2]->GetNumPoints();
1910 int nmodes_a =
m_base[0]->GetNumModes();
1911 int nmodes_b =
m_base[1]->GetNumModes();
1912 int nmodes_c =
m_base[2]->GetNumModes();
1926 int i, j, k, cnt = 0;
1929 OrthoExp.
FwdTrans(array, orthocoeffs);
1939 for (i = 0; i < nmodes_a; ++i)
1941 for (j = 0; j < nmodes_b - j; ++j)
1944 pow((1.0 * i) / (nmodes_a - 1), cutoff * nmodes_a),
1945 pow((1.0 * j) / (nmodes_b - 1), cutoff * nmodes_b));
1947 for (k = 0; k < nmodes_c - i - j; ++k)
1950 std::max(fac1, pow((1.0 * k) / (nmodes_c - 1),
1951 cutoff * nmodes_c));
1953 orthocoeffs[cnt] *= SvvDiffCoeff * fac;
1969 max_abc =
max(max_abc, 0);
1972 for (i = 0; i < nmodes_a; ++i)
1974 for (j = 0; j < nmodes_b - j; ++j)
1976 int maxij =
max(i, j);
1978 for (k = 0; k < nmodes_c - i - j; ++k)
1980 int maxijk =
max(maxij, k);
2003 int cutoff_a = (int)(SVVCutOff * nmodes_a);
2004 int cutoff_b = (int)(SVVCutOff * nmodes_b);
2005 int cutoff_c = (int)(SVVCutOff * nmodes_c);
2006 int nmodes =
min(
min(nmodes_a, nmodes_b), nmodes_c);
2011 for (i = 0; i < nmodes_a; ++i)
2013 for (j = 0; j < nmodes_b - i; ++j)
2015 for (k = 0; k < nmodes_c - i - j; ++k)
2017 if (i + j + k >= cutoff)
2019 orthocoeffs[cnt] *= ((SvvDiffCoeff)*exp(
2020 -(i + j + k - nmodes) * (i + j + k - nmodes) /
2021 ((
NekDouble)((i + j + k - cutoff + epsilon) *
2022 (i + j + k - cutoff + epsilon)))));
2026 orthocoeffs[cnt] *= 0.0;
2035 OrthoExp.
BwdTrans(orthocoeffs, array);
2042 int nquad0 =
m_base[0]->GetNumPoints();
2043 int nquad1 =
m_base[1]->GetNumPoints();
2044 int nquad2 =
m_base[2]->GetNumPoints();
2045 int nqtot = nquad0 * nquad1 * nquad2;
2046 int nmodes0 =
m_base[0]->GetNumModes();
2047 int nmodes1 =
m_base[1]->GetNumModes();
2048 int nmodes2 =
m_base[2]->GetNumModes();
2049 int numMax = nmodes0;
2071 bortho0, bortho1, bortho2);
2074 OrthoTetExp->FwdTrans(phys_tmp, coeff);
2080 for (
int u = 0; u < numMin; ++u)
2082 for (
int i = 0; i < numMin - u; ++i)
2085 tmp2 = coeff_tmp1 + cnt, 1);
2086 cnt += numMax - u - i;
2088 for (
int i = numMin; i < numMax - u; ++i)
2090 cnt += numMax - u - i;
2094 OrthoTetExp->BwdTrans(coeff_tmp1, phys_tmp);
2101 int np0 =
m_base[0]->GetNumPoints();
2102 int np1 =
m_base[1]->GetNumPoints();
2103 int np2 =
m_base[2]->GetNumPoints();
2104 int np =
max(np0,
max(np1, np2));
2115 for (
int i = 0; i < np - 1; ++i)
2117 planep1 += (np - i) * (np - i + 1) / 2;
2122 for (
int j = 0; j < np - i - 1; ++j)
2124 rowp1 += np - i - j;
2125 row1p1 += np - i - j - 1;
2126 for (
int k = 0; k < np - i - j - 2; ++k)
2128 conn[cnt++] = plane + row + k + 1;
2129 conn[cnt++] = plane + row + k;
2130 conn[cnt++] = plane + rowp1 + k;
2131 conn[cnt++] = planep1 + row1 + k;
2133 conn[cnt++] = plane + row + k + 1;
2134 conn[cnt++] = plane + rowp1 + k + 1;
2135 conn[cnt++] = planep1 + row1 + k + 1;
2136 conn[cnt++] = planep1 + row1 + k;
2138 conn[cnt++] = plane + rowp1 + k + 1;
2139 conn[cnt++] = plane + row + k + 1;
2140 conn[cnt++] = plane + rowp1 + k;
2141 conn[cnt++] = planep1 + row1 + k;
2143 conn[cnt++] = planep1 + row1 + k;
2144 conn[cnt++] = planep1 + row1p1 + k;
2145 conn[cnt++] = plane + rowp1 + k;
2146 conn[cnt++] = plane + rowp1 + k + 1;
2148 conn[cnt++] = planep1 + row1 + k;
2149 conn[cnt++] = planep1 + row1p1 + k;
2150 conn[cnt++] = planep1 + row1 + k + 1;
2151 conn[cnt++] = plane + rowp1 + k + 1;
2153 if (k < np - i - j - 3)
2155 conn[cnt++] = plane + rowp1 + k + 1;
2156 conn[cnt++] = planep1 + row1p1 + k + 1;
2157 conn[cnt++] = planep1 + row1 + k + 1;
2158 conn[cnt++] = planep1 + row1p1 + k;
2162 conn[cnt++] = plane + row + np - i - j - 1;
2163 conn[cnt++] = plane + row + np - i - j - 2;
2164 conn[cnt++] = plane + rowp1 + np - i - j - 2;
2165 conn[cnt++] = planep1 + row1 + np - i - j - 2;
2168 row1 += np - i - j - 1;
2170 plane += (np - i) * (np - i + 1) / 2;
#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.
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
int v_GetNtraces() const override
int v_GetTraceNcoeffs(const int i) const override
NekDouble v_PhysEvalFirstDeriv(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs) override
void v_GetTraceNumModes(const int fid, int &numModes0, int &numModes1, Orientation traceOrient=eDir1FwdDir1_Dir2FwdDir2) override
int v_GetTraceIntNcoeffs(const int i) const override
void v_FillMode(const int mode, Array< OneD, NekDouble > &outarray) override
void v_GetInteriorMap(Array< OneD, unsigned int > &outarray) override
int v_GetNedges() const override
int GetMode(const int i, const int j, const int k)
Compute the mode number in the expansion for a particular tensorial combination.
int v_GetEdgeNcoeffs(const int i) const override
bool v_IsBoundaryInteriorExpansion() const override
LibUtilities::PointsKey v_GetTracePointsKey(const int i, const int j) const override
NekDouble v_PhysEvaluateBasis(const Array< OneD, const NekDouble > &coords, int mode) final
void v_GetEdgeInteriorToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation traceOrient=eDir1FwdDir1_Dir2FwdDir2) override
int v_GetTraceNumPoints(const int i) const override
void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdMatrixKey &mkey) override
DNekMatSharedPtr v_CreateStdMatrix(const StdMatrixKey &mkey) override
void v_LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta) override
void v_GetBoundaryMap(Array< OneD, unsigned int > &outarray) override
void v_GetSimplexEquiSpacedConnectivity(Array< OneD, int > &conn, bool standard=true) override
int v_NumBndryCoeffs() const override
void v_BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_ReduceOrderCoeffs(int numMin, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_GetCoords(Array< OneD, NekDouble > &coords_x, Array< OneD, NekDouble > &coords_y, Array< OneD, NekDouble > &coords_z) 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
void v_GetElmtTraceToTraceMap(const unsigned int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, Orientation traceOrient=eForwards, int P=-1, int Q=-1) override
int v_GetVertexMap(int localVertexId, bool useCoeffPacking=false) override
int v_GetNverts() const override
void v_StdPhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_dx, Array< OneD, NekDouble > &out_dy, Array< OneD, NekDouble > &out_dz) override
Calculate the derivative of the physical points.
const LibUtilities::BasisKey v_GetTraceBasisKey(const int i, const int k, bool UseGLL=false) const override
LibUtilities::ShapeType v_DetShapeType() const override
void v_LocCollapsedToLocCoord(const Array< OneD, const NekDouble > &eta, Array< OneD, NekDouble > &xi) override
int v_NumDGBndryCoeffs() const 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...
int v_CalcNumberOfCoefficients(const std::vector< unsigned int > &nummodes, int &modes_offset) override
DNekMatSharedPtr v_GenMatrix(const StdMatrixKey &mkey) override
constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
PointsManagerT & PointsManager(void)
@ eNodalTetElec
3D Nodal Electrostatic Points on a Tetrahedron
@ 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
@ eFactorSVVDGKerDiffCoeff
@ eFactorSVVPowerKerDiffCoeff
std::shared_ptr< StdTetExp > StdTetExpSharedPtr
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
@ eDir1BwdDir1_Dir2FwdDir2
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 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 Zero(int n, T *x, const int incx)
Zero vector.
void Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add vector 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)