36 #include <boost/core/ignore_unused.hpp>
46 StdTetExp::StdTetExp()
54 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
57 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
61 "order in 'a' direction is higher than order "
64 "order in 'a' direction is higher than order "
67 "order in 'b' direction is higher than order "
104 int Q0 =
m_base[0]->GetNumPoints();
105 int Q1 =
m_base[1]->GetNumPoints();
106 int Q2 =
m_base[2]->GetNumPoints();
107 int Qtot = Q0 * Q1 * Q2;
114 bool Do_2 = (out_dxi2.size() > 0) ?
true :
false;
115 bool Do_1 = (out_dxi1.size() > 0) ?
true :
false;
132 eta_0 =
m_base[0]->GetZ();
133 eta_1 =
m_base[1]->GetZ();
134 eta_2 =
m_base[2]->GetZ();
140 for (
int k = 0; k < Q2; ++k)
142 for (
int j = 0; j < Q1; ++j, dEta0 += Q0)
144 Vmath::Smul(Q0, 2.0 / (1.0 - eta_1[j]), dEta0, 1, dEta0, 1);
146 fac = 1.0 / (1.0 - eta_2[k]);
147 Vmath::Smul(Q0 * Q1, fac, &out_dEta0[0] + k * Q0 * Q1, 1,
148 &out_dEta0[0] + k * Q0 * Q1, 1);
151 if (out_dxi0.size() > 0)
163 for (
int k = 0; k < Q1 * Q2; ++k)
165 Vmath::Vmul(Q0, &Fac0[0], 1, &out_dEta0[0] + k * Q0, 1,
166 &out_dEta0[0] + k * Q0, 1);
169 for (
int k = 0; k < Q2; ++k)
172 &out_dEta1[0] + k * Q0 * Q1, 1,
173 &out_dEta1[0] + k * Q0 * Q1, 1);
180 Vmath::Vadd(Qtot, out_dEta0, 1, out_dEta1, 1, out_dxi1, 1);
187 for (
int k = 0; k < Q2; ++k)
189 for (
int j = 0; j < Q1; ++j, dEta1 += Q0)
191 Vmath::Smul(Q0, (1.0 + eta_1[j]) / 2.0, dEta1, 1, dEta1, 1);
198 Vmath::Vadd(Qtot, out_dEta0, 1, out_dEta1, 1, out_dxi2, 1);
199 Vmath::Vadd(Qtot, out_dEta2, 1, out_dxi2, 1, out_dxi2, 1);
236 ASSERTL1(
false,
"input dir is out of range");
287 "Basis[1] is not a general tensor type");
291 "Basis[2] is not a general tensor type");
293 if (
m_base[0]->Collocation() &&
m_base[1]->Collocation() &&
298 inarray, 1, outarray, 1);
312 int nquad1 =
m_base[1]->GetNumPoints();
313 int nquad2 =
m_base[2]->GetNumPoints();
314 int order0 =
m_base[0]->GetNumModes();
315 int order1 =
m_base[1]->GetNumModes();
318 nquad2 * nquad1 * order0);
321 m_base[2]->GetBdata(), inarray, outarray, wsp,
true,
344 bool doCheckCollDir0,
bool doCheckCollDir1,
bool doCheckCollDir2)
346 boost::ignore_unused(doCheckCollDir0, doCheckCollDir1, doCheckCollDir2);
348 int nquad0 =
m_base[0]->GetNumPoints();
349 int nquad1 =
m_base[1]->GetNumPoints();
350 int nquad2 =
m_base[2]->GetNumPoints();
352 int order0 =
m_base[0]->GetNumModes();
353 int order1 =
m_base[1]->GetNumModes();
354 int order2 =
m_base[2]->GetNumModes();
358 tmp + nquad2 * order0 * (2 * order1 - order0 + 1) / 2;
360 int i, j, mode, mode1, cnt;
363 mode = mode1 = cnt = 0;
364 for (i = 0; i < order0; ++i)
366 for (j = 0; j < order1 - i; ++j, ++cnt)
369 base2.get() + mode * nquad2, nquad2,
370 inarray.get() + mode1, 1, 0.0, tmp.get() + cnt * nquad2,
372 mode += order2 - i - j;
373 mode1 += order2 - i - j;
376 for (j = order1 - i; j < order2 - i; ++j)
378 mode += order2 - i - j;
388 Blas::Daxpy(nquad2, inarray[1], base2.get() + nquad2, 1,
389 &tmp[0] + nquad2, 1);
392 Blas::Daxpy(nquad2, inarray[1], base2.get() + nquad2, 1,
393 &tmp[0] + order1 * nquad2, 1);
398 for (i = 0; i < order0; ++i)
400 Blas::Dgemm(
'N',
'T', nquad1, nquad2, order1 - i, 1.0,
401 base1.get() + mode * nquad1, nquad1,
402 tmp.get() + mode * nquad2, nquad2, 0.0,
403 tmp1.get() + i * nquad1 * nquad2, nquad1);
414 for (i = 0; i < nquad2; ++i)
416 Blas::Daxpy(nquad1, tmp[nquad2 + i], base1.get() + nquad1, 1,
417 &tmp1[nquad1 * nquad2] + i * nquad1, 1);
422 Blas::Dgemm(
'N',
'T', nquad0, nquad1 * nquad2, order0, 1.0, base0.get(),
423 nquad0, tmp1.get(), nquad1 * nquad2, 0.0, outarray.get(),
445 out = (*matsys) * in;
487 "Basis[1] is not a general tensor type");
491 "Basis[2] is not a general tensor type");
493 if (
m_base[0]->Collocation() &&
m_base[1]->Collocation())
513 int nquad0 =
m_base[0]->GetNumPoints();
514 int nquad1 =
m_base[1]->GetNumPoints();
515 int nquad2 =
m_base[2]->GetNumPoints();
516 int order0 =
m_base[0]->GetNumModes();
517 int order1 =
m_base[1]->GetNumModes();
520 nquad2 * order0 * (2 * order1 - order0 + 1) / 2);
522 if (multiplybyweights)
529 tmp, outarray, wsp,
true,
true,
true);
535 inarray, outarray, wsp,
true,
true,
true);
545 bool doCheckCollDir0,
bool doCheckCollDir1,
bool doCheckCollDir2)
547 boost::ignore_unused(doCheckCollDir0, doCheckCollDir1, doCheckCollDir2);
549 int nquad0 =
m_base[0]->GetNumPoints();
550 int nquad1 =
m_base[1]->GetNumPoints();
551 int nquad2 =
m_base[2]->GetNumPoints();
553 int order0 =
m_base[0]->GetNumModes();
554 int order1 =
m_base[1]->GetNumModes();
555 int order2 =
m_base[2]->GetNumModes();
560 int i, j, mode, mode1, cnt;
563 Blas::Dgemm(
'T',
'N', nquad1 * nquad2, order0, nquad0, 1.0, inarray.get(),
564 nquad0, base0.get(), nquad0, 0.0, tmp1.get(), nquad1 * nquad2);
567 for (mode = i = 0; i < order0; ++i)
569 Blas::Dgemm(
'T',
'N', nquad2, order1 - i, nquad1, 1.0,
570 tmp1.get() + i * nquad1 * nquad2, nquad1,
571 base1.get() + mode * nquad1, nquad1, 0.0,
572 tmp2.get() + mode * nquad2, nquad2);
581 Blas::Dgemv(
'T', nquad1, nquad2, 1.0, tmp1.get() + nquad1 * nquad2,
582 nquad1, base1.get() + nquad1, 1, 1.0, tmp2.get() + nquad2,
587 mode = mode1 = cnt = 0;
588 for (i = 0; i < order0; ++i)
590 for (j = 0; j < order1 - i; ++j, ++cnt)
593 base2.get() + mode * nquad2, nquad2,
594 tmp2.get() + cnt * nquad2, 1, 0.0,
595 outarray.get() + mode1, 1);
596 mode += order2 - i - j;
597 mode1 += order2 - i - j;
600 for (j = order1 - i; j < order2 - i; ++j)
602 mode += order2 - i - j;
612 Blas::Ddot(nquad2, base2.get() + nquad2, 1, &tmp2[nquad2], 1);
615 outarray[1] +=
Blas::Ddot(nquad2, base2.get() + nquad2, 1,
616 &tmp2[nquad2 * order1], 1);
638 int nquad0 =
m_base[0]->GetNumPoints();
639 int nquad1 =
m_base[1]->GetNumPoints();
640 int nquad2 =
m_base[2]->GetNumPoints();
641 int nqtot = nquad0 * nquad1 * nquad2;
642 int nmodes0 =
m_base[0]->GetNumModes();
643 int nmodes1 =
m_base[1]->GetNumModes();
644 int wspsize = nquad0 + nquad1 + nquad2 + max(nqtot,
m_ncoeffs) +
645 nquad1 * nquad2 * nmodes0 +
646 nquad2 * nmodes0 * (2 * nmodes1 - nmodes0 + 1) / 2;
659 for (i = 0; i < nquad0; ++i)
661 gfac0[i] = 0.5 * (1 + z0[i]);
665 for (i = 0; i < nquad1; ++i)
667 gfac1[i] = 2.0 / (1 - z1[i]);
671 for (i = 0; i < nquad2; ++i)
673 gfac2[i] = 2.0 / (1 - z2[i]);
677 for (i = 0; i < nquad1 * nquad2; ++i)
679 Vmath::Smul(nquad0, gfac1[i % nquad1], &inarray[0] + i * nquad0, 1,
680 &tmp0[0] + i * nquad0, 1);
682 for (i = 0; i < nquad2; ++i)
684 Vmath::Smul(nquad0 * nquad1, gfac2[i], &tmp0[0] + i * nquad0 * nquad1,
685 1, &tmp0[0] + i * nquad0 * nquad1, 1);
696 m_base[2]->GetBdata(), tmp0, outarray, wsp,
false,
true,
true);
703 for (i = 0; i < nquad1 * nquad2; ++i)
705 Vmath::Vmul(nquad0, &gfac0[0], 1, &tmp0[0] + i * nquad0, 1,
706 &tmp0[0] + i * nquad0, 1);
711 m_base[2]->GetBdata(), tmp0, tmp3, wsp,
false,
true,
true);
713 for (i = 0; i < nquad2; ++i)
716 &inarray[0] + i * nquad0 * nquad1, 1,
717 &tmp0[0] + i * nquad0 * nquad1, 1);
722 m_base[2]->GetBdata(), tmp0, outarray, wsp,
true,
false,
true);
731 for (i = 0; i < nquad1; ++i)
733 gfac1[i] = (1 + z1[i]) / 2;
736 for (i = 0; i < nquad1 * nquad2; ++i)
738 Vmath::Vmul(nquad0, &gfac0[0], 1, &tmp0[0] + i * nquad0, 1,
739 &tmp0[0] + i * nquad0, 1);
743 m_base[2]->GetBdata(), tmp0, tmp3, wsp,
false,
true,
true);
745 for (i = 0; i < nquad2; ++i)
748 &inarray[0] + i * nquad0 * nquad1, 1,
749 &tmp0[0] + i * nquad0 * nquad1, 1);
751 for (i = 0; i < nquad1 * nquad2; ++i)
753 Vmath::Smul(nquad0, gfac1[i % nquad1], &tmp0[0] + i * nquad0, 1,
754 &tmp0[0] + i * nquad0, 1);
759 m_base[2]->GetBdata(), tmp0, tmp4, wsp,
true,
false,
true);
764 m_base[2]->GetDbdata(), tmp0, outarray, wsp,
true,
true,
false);
774 ASSERTL1(
false,
"input dir is out of range");
811 eta[0] = 2.0 * (1.0 + xi[0]) / d12 - 1.0;
812 eta[1] = 2.0 * (1.0 + xi[1]) / d2 - 1.0;
819 xi[1] = (1.0 + eta[0]) * (1.0 - eta[2]) * 0.5 - 1.0;
820 xi[0] = (1.0 + eta[0]) * (-xi[1] - eta[2]) * 0.5 - 1.0;
837 const int nm1 =
m_base[1]->GetNumModes();
838 const int nm2 =
m_base[2]->GetNumModes();
840 const int b = 2 * nm2 + 1;
841 const int mode0 = floor(0.5 * (b -
sqrt(b * b - 8.0 * mode / nm1)));
843 mode - nm1 * (mode0 * (nm2 - 1) + 1 - (mode0 - 2) * (mode0 - 1) / 2);
844 const int mode1 = tmp / (nm2 - mode0);
845 const int mode2 = tmp % (nm2 - mode0);
854 return StdExpansion::BaryEvaluateBasis<2>(coll[2], 1);
856 else if (mode0 == 0 && mode2 == 1)
858 return StdExpansion::BaryEvaluateBasis<1>(coll[1], 0) *
859 StdExpansion::BaryEvaluateBasis<2>(coll[2], 1);
861 else if (mode0 == 1 && mode1 == 1 && mode2 == 0)
863 return StdExpansion::BaryEvaluateBasis<0>(coll[0], 0) *
864 StdExpansion::BaryEvaluateBasis<1>(coll[1], 1);
868 return StdExpansion::BaryEvaluateBasis<0>(coll[0], mode0) *
869 StdExpansion::BaryEvaluateBasis<1>(coll[1], mode1) *
870 StdExpansion::BaryEvaluateBasis<2>(coll[2], mode2);
875 std::array<NekDouble, 3> &firstOrderDerivs)
882 if ((1 - coll[1]) < 1e-5 || (1 - coll[2]) < 1e-5)
886 EphysDeriv2(totPoints);
887 PhysDeriv(inarray, EphysDeriv0, EphysDeriv1, EphysDeriv2);
890 I[0] =
GetBase()[0]->GetI(coll);
891 I[1] =
GetBase()[1]->GetI(coll + 1);
892 I[2] =
GetBase()[2]->GetI(coll + 2);
900 std::array<NekDouble, 3> interDeriv;
904 NekDouble temp = 2.0 / ((1 - coll[1]) * (1 - coll[2]));
905 interDeriv[0] *= temp;
908 firstOrderDerivs[0] = 2 * interDeriv[0];
915 interDeriv[0] *= fac0;
918 fac0 = 2 / (1 - coll[2]);
919 interDeriv[1] *= fac0;
923 firstOrderDerivs[1] = interDeriv[0] + interDeriv[1];
926 fac0 = (1 + coll[1]) / 2;
927 interDeriv[1] *= fac0;
932 firstOrderDerivs[2] = interDeriv[0] + interDeriv[1] + interDeriv[2];
939 int &numModes0,
int &numModes1,
942 boost::ignore_unused(faceOrient);
944 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
945 m_base[2]->GetNumModes()};
950 numModes0 = nummodes[0];
951 numModes1 = nummodes[1];
956 numModes0 = nummodes[0];
957 numModes1 = nummodes[2];
963 numModes0 = nummodes[1];
964 numModes1 = nummodes[2];
998 "BasisType is not a boundary interior form");
1001 "BasisType is not a boundary interior form");
1004 "BasisType is not a boundary interior form");
1006 int P =
m_base[0]->GetNumModes();
1007 int Q =
m_base[1]->GetNumModes();
1008 int R =
m_base[2]->GetNumModes();
1017 "BasisType is not a boundary interior form");
1020 "BasisType is not a boundary interior form");
1023 "BasisType is not a boundary interior form");
1025 int P =
m_base[0]->GetNumModes() - 1;
1026 int Q =
m_base[1]->GetNumModes() - 1;
1027 int R =
m_base[2]->GetNumModes() - 1;
1029 return (Q + 1) +
P * (1 + 2 * Q -
P) / 2
1030 + (R + 1) +
P * (1 + 2 * R -
P) / 2
1031 + 2 * (R + 1) + Q * (1 + 2 * R - Q);
1036 ASSERTL2((i >= 0) && (i <= 3),
"face id is out of range");
1037 int nFaceCoeffs = 0;
1038 int nummodesA, nummodesB,
P, Q;
1044 else if ((i == 1) || (i == 2))
1056 nFaceCoeffs = Q + 1 + (
P * (1 + 2 * Q -
P)) / 2;
1062 ASSERTL2((i >= 0) && (i <= 3),
"face id is out of range");
1063 int Pi =
m_base[0]->GetNumModes() - 2;
1064 int Qi =
m_base[1]->GetNumModes() - 2;
1065 int Ri =
m_base[2]->GetNumModes() - 2;
1069 return Pi * (2 * Qi - Pi - 1) / 2;
1073 return Pi * (2 * Ri - Pi - 1) / 2;
1077 return Qi * (2 * Ri - Qi - 1) / 2;
1083 ASSERTL2(i >= 0 && i <= 3,
"face id is out of range");
1087 return m_base[0]->GetNumPoints() *
m_base[1]->GetNumPoints();
1091 return m_base[0]->GetNumPoints() *
m_base[2]->GetNumPoints();
1095 return m_base[1]->GetNumPoints() *
m_base[2]->GetNumPoints();
1101 ASSERTL2((i >= 0) && (i <= 5),
"edge id is out of range");
1102 int P =
m_base[0]->GetNumModes();
1103 int Q =
m_base[1]->GetNumModes();
1104 int R =
m_base[2]->GetNumModes();
1110 else if (i == 1 || i == 2)
1123 ASSERTL2(i >= 0 && i <= 3,
"face id is out of range");
1124 ASSERTL2(j == 0 || j == 1,
"face direction is out of range");
1128 return m_base[j]->GetPointsKey();
1132 return m_base[2 * j]->GetPointsKey();
1136 return m_base[j + 1]->GetPointsKey();
1141 const std::vector<unsigned int> &nummodes,
int &modes_offset)
1144 nummodes[modes_offset], nummodes[modes_offset + 1],
1145 nummodes[modes_offset + 2]);
1154 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
1155 ASSERTL2(k == 0 || k == 1,
"face direction out of range");
1174 m_base[dir]->GetNumModes());
1193 for (
int k = 0; k < Qz; ++k)
1195 for (
int j = 0; j < Qy; ++j)
1197 for (
int i = 0; i < Qx; ++i)
1199 int s = i + Qx * (j + Qy * k);
1201 (eta_x[i] + 1.0) * (1.0 - eta_y[j]) * (1.0 - eta_z[k]) / 4 -
1203 xi_y[s] = (eta_y[j] + 1.0) * (1.0 - eta_z[k]) / 2 - 1.0;
1225 "Mapping not defined for this type of basis");
1228 if (useCoeffPacking ==
true)
1230 switch (localVertexId)
1254 ASSERTL0(
false,
"Vertex ID must be between 0 and 3");
1261 switch (localVertexId)
1285 ASSERTL0(
false,
"Vertex ID must be between 0 and 3");
1305 "BasisType is not a boundary interior form");
1308 "BasisType is not a boundary interior form");
1311 "BasisType is not a boundary interior form");
1313 int P =
m_base[0]->GetNumModes();
1314 int Q =
m_base[1]->GetNumModes();
1315 int R =
m_base[2]->GetNumModes();
1319 if (outarray.size() != nIntCoeffs)
1325 for (
int i = 2; i <
P - 2; ++i)
1327 for (
int j = 1; j < Q - i - 1; ++j)
1329 for (
int k = 1; k < R - i - j; ++k)
1331 outarray[idx++] =
GetMode(i, j, k);
1344 "BasisType is not a boundary interior form");
1347 "BasisType is not a boundary interior form");
1350 "BasisType is not a boundary interior form");
1352 int P =
m_base[0]->GetNumModes();
1353 int Q =
m_base[1]->GetNumModes();
1354 int R =
m_base[2]->GetNumModes();
1361 if (outarray.size() != nBnd)
1366 for (i = 0; i <
P; ++i)
1371 for (j = 0; j < Q - i; j++)
1373 for (k = 0; k < R - i - j; ++k)
1375 outarray[idx++] =
GetMode(i, j, k);
1383 for (k = 0; k < R - i; ++k)
1385 outarray[idx++] =
GetMode(i, 0, k);
1387 for (j = 1; j < Q - i; ++j)
1389 outarray[idx++] =
GetMode(i, j, 0);
1399 int P = 0, Q = 0, idx = 0;
1400 int nFaceCoeffs = 0;
1406 Q =
m_base[1]->GetNumModes();
1410 Q =
m_base[2]->GetNumModes();
1415 Q =
m_base[2]->GetNumModes();
1418 ASSERTL0(
false,
"fid must be between 0 and 3");
1421 nFaceCoeffs =
P * (2 * Q -
P + 1) / 2;
1423 if (maparray.size() != nFaceCoeffs)
1432 for (i = 0; i <
P; ++i)
1434 for (j = 0; j < Q - i; ++j)
1436 maparray[idx++] =
GetMode(i, j, 0);
1442 for (i = 0; i <
P; ++i)
1444 for (k = 0; k < Q - i; ++k)
1446 maparray[idx++] =
GetMode(i, 0, k);
1452 for (j = 0; j <
P - 1; ++j)
1454 for (k = 0; k < Q - 1 - j; ++k)
1456 maparray[idx++] =
GetMode(1, j, k);
1458 if (j == 0 && k == 0)
1460 maparray[idx++] =
GetMode(0, 0, 1);
1462 if (j == 0 && k == Q - 2)
1464 for (
int r = 0; r < Q - 1; ++r)
1466 maparray[idx++] =
GetMode(0, 1, r);
1474 for (j = 0; j <
P; ++j)
1476 for (k = 0; k < Q - j; ++k)
1478 maparray[idx++] =
GetMode(0, j, k);
1483 ASSERTL0(
false,
"Element map not available.");
1492 int nummodesA = 0, nummodesB = 0, i, j, k, idx;
1495 "Method only implemented for Modified_A BasisType (x "
1496 "direction), Modified_B BasisType (y direction), and "
1497 "Modified_C BasisType(z direction)");
1499 int nFaceCoeffs = 0;
1504 nummodesA =
m_base[0]->GetNumModes();
1505 nummodesB =
m_base[1]->GetNumModes();
1508 nummodesA =
m_base[0]->GetNumModes();
1509 nummodesB =
m_base[2]->GetNumModes();
1513 nummodesA =
m_base[1]->GetNumModes();
1514 nummodesB =
m_base[2]->GetNumModes();
1517 ASSERTL0(
false,
"fid must be between 0 and 3");
1526 nFaceCoeffs =
P * (2 * Q -
P + 1) / 2;
1529 if (maparray.size() != nFaceCoeffs)
1534 if (signarray.size() != nFaceCoeffs)
1540 fill(signarray.get(), signarray.get() + nFaceCoeffs, 1);
1547 int minPA = min(nummodesA,
P);
1548 int minQB = min(nummodesB, Q);
1550 for (j = 0; j < minPA; ++j)
1553 for (k = 0; k < minQB - j; ++k, ++cnt)
1555 maparray[idx++] = cnt;
1558 cnt += nummodesB - minQB;
1560 for (k = nummodesB - j; k < Q - j; ++k)
1562 signarray[idx] = 0.0;
1563 maparray[idx++] = maparray[0];
1567 for (j = nummodesA; j <
P; ++j)
1569 for (k = 0; k < Q - j; ++k)
1571 signarray[idx] = 0.0;
1572 maparray[idx++] = maparray[0];
1579 for (i = 0; i <
P; ++i)
1581 for (j = 0; j < Q - i; ++j, idx++)
1585 signarray[idx] = (i % 2 ? -1 : 1);
1590 swap(maparray[0], maparray[Q]);
1592 for (i = 1; i < Q - 1; ++i)
1594 swap(maparray[i + 1], maparray[Q + i]);
1607 const int P =
m_base[0]->GetNumModes();
1608 const int Q =
m_base[1]->GetNumModes();
1609 const int R =
m_base[2]->GetNumModes();
1613 if (maparray.size() != nEdgeIntCoeffs)
1619 fill(maparray.get(), maparray.get() + nEdgeIntCoeffs, 0);
1622 if (signarray.size() != nEdgeIntCoeffs)
1628 fill(signarray.get(), signarray.get() + nEdgeIntCoeffs, 1);
1634 for (i = 0; i <
P - 2; ++i)
1636 maparray[i] =
GetMode(i + 2, 0, 0);
1640 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1647 for (i = 0; i < Q - 2; ++i)
1649 maparray[i] =
GetMode(1, i + 1, 0);
1653 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1660 for (i = 0; i < Q - 2; ++i)
1662 maparray[i] =
GetMode(0, i + 2, 0);
1666 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1673 for (i = 0; i < R - 2; ++i)
1675 maparray[i] =
GetMode(0, 0, i + 2);
1679 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1686 for (i = 0; i < R - 2; ++i)
1688 maparray[i] =
GetMode(1, 0, i + 1);
1692 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1699 for (i = 0; i < R - 2; ++i)
1701 maparray[i] =
GetMode(0, 1, i + 1);
1705 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1712 ASSERTL0(
false,
"Edge not defined.");
1722 const int P =
m_base[0]->GetNumModes();
1723 const int Q =
m_base[1]->GetNumModes();
1724 const int R =
m_base[2]->GetNumModes();
1728 if (maparray.size() != nFaceIntCoeffs)
1733 if (signarray.size() != nFaceIntCoeffs)
1739 fill(signarray.get(), signarray.get() + nFaceIntCoeffs, 1);
1746 for (i = 2; i <
P - 1; ++i)
1748 for (j = 1; j < Q - i; ++j)
1750 if ((
int)faceOrient == 7)
1752 signarray[idx] = (i % 2 ? -1 : 1);
1754 maparray[idx++] =
GetMode(i, j, 0);
1760 for (i = 2; i <
P; ++i)
1762 for (k = 1; k < R - i; ++k)
1764 if ((
int)faceOrient == 7)
1766 signarray[idx] = (i % 2 ? -1 : 1);
1768 maparray[idx++] =
GetMode(i, 0, k);
1774 for (j = 1; j < Q - 2; ++j)
1776 for (k = 1; k < R - 1 - j; ++k)
1778 if ((
int)faceOrient == 7)
1780 signarray[idx] = ((j + 1) % 2 ? -1 : 1);
1782 maparray[idx++] =
GetMode(1, j, k);
1788 for (j = 2; j < Q - 1; ++j)
1790 for (k = 1; k < R - j; ++k)
1792 if ((
int)faceOrient == 7)
1794 signarray[idx] = (j % 2 ? -1 : 1);
1796 maparray[idx++] =
GetMode(0, j, k);
1801 ASSERTL0(
false,
"Face interior map not available.");
1819 int nq0 =
m_base[0]->GetNumPoints();
1820 int nq1 =
m_base[1]->GetNumPoints();
1821 int nq2 =
m_base[2]->GetNumPoints();
1831 nq = max(nq0, max(nq1, nq2));
1845 for (
int i = 0; i < nq; ++i)
1847 for (
int j = 0; j < nq - i; ++j)
1849 for (
int k = 0; k < nq - i - j; ++k, ++cnt)
1852 coords[cnt][0] = -1.0 + 2 * k / (
NekDouble)(nq - 1);
1853 coords[cnt][1] = -1.0 + 2 * j / (
NekDouble)(nq - 1);
1854 coords[cnt][2] = -1.0 + 2 * i / (
NekDouble)(nq - 1);
1859 for (
int i = 0; i < neq; ++i)
1863 I[0] =
m_base[0]->GetI(coll);
1864 I[1] =
m_base[1]->GetI(coll + 1);
1865 I[2] =
m_base[2]->GetI(coll + 2);
1869 for (
int k = 0; k < nq2; ++k)
1871 for (
int j = 0; j < nq1; ++j)
1874 fac = (I[1]->GetPtr())[j] * (I[2]->GetPtr())[k];
1878 Mat->GetRawPtr() + k * nq0 * nq1 * neq +
1928 const int Q =
m_base[1]->GetNumModes();
1929 const int R =
m_base[2]->GetNumModes();
1931 int i, j, q_hat, k_hat;
1935 for (i = 0; i < I; ++i)
1938 q_hat = min(Q, R - i);
1940 k_hat = max(R - Q - i, 0);
1941 cnt += q_hat * (q_hat + 1) / 2 + k_hat * Q;
1946 for (j = 0; j < J; ++j)
1964 int nquad0 =
m_base[0]->GetNumPoints();
1965 int nquad1 =
m_base[1]->GetNumPoints();
1966 int nquad2 =
m_base[2]->GetNumPoints();
1976 for (i = 0; i < nquad1 * nquad2; ++i)
1979 1, &outarray[0] + i * nquad0, 1);
1985 case LibUtilities::eGaussRadauMAlpha1Beta0:
1986 for (j = 0; j < nquad2; ++j)
1988 for (i = 0; i < nquad1; ++i)
1991 &outarray[0] + i * nquad0 + j * nquad0 * nquad1,
1998 for (j = 0; j < nquad2; ++j)
2000 for (i = 0; i < nquad1; ++i)
2003 &outarray[0] + i * nquad0 + j * nquad0 * nquad1,
2013 case LibUtilities::eGaussRadauMAlpha2Beta0:
2014 for (i = 0; i < nquad2; ++i)
2017 &outarray[0] + i * nquad0 * nquad1, 1);
2021 case LibUtilities::eGaussRadauMAlpha1Beta0:
2022 for (i = 0; i < nquad2; ++i)
2024 Blas::Dscal(nquad0 * nquad1, 0.25 * (1 - z2[i]) * w2[i],
2025 &outarray[0] + i * nquad0 * nquad1, 1);
2029 for (i = 0; i < nquad2; ++i)
2032 0.25 * (1 - z2[i]) * (1 - z2[i]) * w2[i],
2033 &outarray[0] + i * nquad0 * nquad1, 1);
2050 int qa =
m_base[0]->GetNumPoints();
2051 int qb =
m_base[1]->GetNumPoints();
2052 int qc =
m_base[2]->GetNumPoints();
2053 int nmodes_a =
m_base[0]->GetNumModes();
2054 int nmodes_b =
m_base[1]->GetNumModes();
2055 int nmodes_c =
m_base[2]->GetNumModes();
2069 int i, j, k, cnt = 0;
2072 OrthoExp.
FwdTrans(array, orthocoeffs);
2082 for (
int i = 0; i < nmodes_a; ++i)
2084 for (
int j = 0; j < nmodes_b - j; ++j)
2087 pow((1.0 * i) / (nmodes_a - 1), cutoff * nmodes_a),
2088 pow((1.0 * j) / (nmodes_b - 1), cutoff * nmodes_b));
2090 for (
int k = 0; k < nmodes_c - i - j; ++k)
2093 std::max(fac1, pow((1.0 * k) / (nmodes_c - 1),
2094 cutoff * nmodes_c));
2096 orthocoeffs[cnt] *= SvvDiffCoeff * fac;
2112 max_abc = max(max_abc, 0);
2115 for (
int i = 0; i < nmodes_a; ++i)
2117 for (
int j = 0; j < nmodes_b - j; ++j)
2119 int maxij = max(i, j);
2121 for (
int k = 0; k < nmodes_c - i - j; ++k)
2123 int maxijk = max(maxij, k);
2146 int cutoff_a = (int)(SVVCutOff * nmodes_a);
2147 int cutoff_b = (int)(SVVCutOff * nmodes_b);
2148 int cutoff_c = (int)(SVVCutOff * nmodes_c);
2149 int nmodes = min(min(nmodes_a, nmodes_b), nmodes_c);
2150 NekDouble cutoff = min(min(cutoff_a, cutoff_b), cutoff_c);
2154 for (i = 0; i < nmodes_a; ++i)
2156 for (j = 0; j < nmodes_b - i; ++j)
2158 for (k = 0; k < nmodes_c - i - j; ++k)
2160 if (i + j + k >= cutoff)
2162 orthocoeffs[cnt] *= ((SvvDiffCoeff)*exp(
2163 -(i + j + k - nmodes) * (i + j + k - nmodes) /
2164 ((
NekDouble)((i + j + k - cutoff + epsilon) *
2165 (i + j + k - cutoff + epsilon)))));
2169 orthocoeffs[cnt] *= 0.0;
2178 OrthoExp.
BwdTrans(orthocoeffs, array);
2185 int nquad0 =
m_base[0]->GetNumPoints();
2186 int nquad1 =
m_base[1]->GetNumPoints();
2187 int nquad2 =
m_base[2]->GetNumPoints();
2188 int nqtot = nquad0 * nquad1 * nquad2;
2189 int nmodes0 =
m_base[0]->GetNumModes();
2190 int nmodes1 =
m_base[1]->GetNumModes();
2191 int nmodes2 =
m_base[2]->GetNumModes();
2192 int numMax = nmodes0;
2214 bortho0, bortho1, bortho2);
2217 OrthoTetExp->FwdTrans(phys_tmp, coeff);
2223 for (
int u = 0; u < numMin; ++u)
2225 for (
int i = 0; i < numMin - u; ++i)
2228 tmp2 = coeff_tmp1 + cnt, 1);
2229 cnt += numMax - u - i;
2231 for (
int i = numMin; i < numMax - u; ++i)
2233 cnt += numMax - u - i;
2237 OrthoTetExp->BwdTrans(coeff_tmp1, phys_tmp);
2244 boost::ignore_unused(standard);
2246 int np0 =
m_base[0]->GetNumPoints();
2247 int np1 =
m_base[1]->GetNumPoints();
2248 int np2 =
m_base[2]->GetNumPoints();
2249 int np = max(np0, max(np1, np2));
2260 for (
int i = 0; i < np - 1; ++i)
2262 planep1 += (np - i) * (np - i + 1) / 2;
2267 for (
int j = 0; j < np - i - 1; ++j)
2269 rowp1 += np - i - j;
2270 row1p1 += np - i - j - 1;
2271 for (
int k = 0; k < np - i - j - 2; ++k)
2273 conn[cnt++] = plane + row + k + 1;
2274 conn[cnt++] = plane + row + k;
2275 conn[cnt++] = plane + rowp1 + k;
2276 conn[cnt++] = planep1 + row1 + k;
2278 conn[cnt++] = plane + row + k + 1;
2279 conn[cnt++] = plane + rowp1 + k + 1;
2280 conn[cnt++] = planep1 + row1 + k + 1;
2281 conn[cnt++] = planep1 + row1 + k;
2283 conn[cnt++] = plane + rowp1 + k + 1;
2284 conn[cnt++] = plane + row + k + 1;
2285 conn[cnt++] = plane + rowp1 + k;
2286 conn[cnt++] = planep1 + row1 + k;
2288 conn[cnt++] = planep1 + row1 + k;
2289 conn[cnt++] = planep1 + row1p1 + k;
2290 conn[cnt++] = plane + rowp1 + k;
2291 conn[cnt++] = plane + rowp1 + k + 1;
2293 conn[cnt++] = planep1 + row1 + k;
2294 conn[cnt++] = planep1 + row1p1 + k;
2295 conn[cnt++] = planep1 + row1 + k + 1;
2296 conn[cnt++] = plane + rowp1 + k + 1;
2298 if (k < np - i - j - 3)
2300 conn[cnt++] = plane + rowp1 + k + 1;
2301 conn[cnt++] = planep1 + row1p1 + k + 1;
2302 conn[cnt++] = planep1 + row1 + k + 1;
2303 conn[cnt++] = planep1 + row1p1 + k;
2307 conn[cnt++] = plane + row + np - i - j - 1;
2308 conn[cnt++] = plane + row + np - i - j - 2;
2309 conn[cnt++] = plane + rowp1 + np - i - j - 2;
2310 conn[cnt++] = planep1 + row1 + np - i - j - 2;
2313 row1 += np - i - j - 1;
2315 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...
Describes the specification for a Basis.
int GetNumModes() const
Returns the order of the basis.
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.
void BwdTrans_SumFacKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp, bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2)
void IProductWRTBase_SumFacKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp, bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2)
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 > &outarray_d1, Array< OneD, NekDouble > &outarray_d2, Array< OneD, NekDouble > &outarray_d3)
Calculate the 3D derivative in the local tensor/collapsed coordinate at the physical points.
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
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
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)
This function performs the Forward transformation from physical space to coefficient space.
int GetNumPoints(const int dir) const
This function returns the number of quadrature points in the dir direction.
void MultiplyByQuadratureMetric(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
int GetBasisNumModes(const int dir) const
This function returns the number of expansion modes in the dir direction.
void PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1=NullNekDouble1DArray, Array< OneD, NekDouble > &out_d2=NullNekDouble1DArray)
Array< OneD, LibUtilities::BasisSharedPtr > m_base
MatrixType GetMatrixType() const
NekDouble GetConstFactor(const ConstFactorType &factor) const
bool ConstFactorExists(const ConstFactorType &factor) const
virtual int v_GetNtraces() const override
virtual int v_GetTraceNcoeffs(const int i) const override
void v_GetTraceNumModes(const int fid, int &numModes0, int &numModes1, Orientation traceOrient=eDir1FwdDir1_Dir2FwdDir2) override
NekDouble v_PhysEvaluate(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs) override
virtual int v_GetTraceIntNcoeffs(const int i) const override
virtual void v_FillMode(const int mode, Array< OneD, NekDouble > &outarray) override
virtual void v_FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
virtual void v_GetInteriorMap(Array< OneD, unsigned int > &outarray) override
virtual 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.
virtual int v_GetEdgeNcoeffs(const int i) const override
virtual bool v_IsBoundaryInteriorExpansion() const override
virtual LibUtilities::PointsKey v_GetTracePointsKey(const int i, const int j) const override
virtual const LibUtilities::BasisKey v_GetTraceBasisKey(const int i, const int k) const override
void v_GetEdgeInteriorToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation traceOrient=eDir1FwdDir1_Dir2FwdDir2) override
void v_MultiplyByStdQuadratureMetric(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
virtual int v_GetTraceNumPoints(const int i) const override
NekDouble v_PhysEvaluateBasis(const Array< OneD, const NekDouble > &coords, int mode) final override
virtual void v_IProductWRTDerivBase_SumFac(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
virtual void v_BwdTrans_SumFacKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp, bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2) override
virtual void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdMatrixKey &mkey) override
virtual DNekMatSharedPtr v_CreateStdMatrix(const StdMatrixKey &mkey) override
virtual void v_LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta) override
virtual void v_GetBoundaryMap(Array< OneD, unsigned int > &outarray) override
virtual void v_GetSimplexEquiSpacedConnectivity(Array< OneD, int > &conn, bool standard=true) override
void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
virtual int v_NumBndryCoeffs() const override
virtual void v_IProductWRTBase_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool multiplybyweights=true) override
void v_BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
virtual void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
virtual ~StdTetExp() override
void v_ReduceOrderCoeffs(int numMin, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
virtual 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
virtual void v_GetCoords(Array< OneD, NekDouble > &coords_x, Array< OneD, NekDouble > &coords_y, Array< OneD, NekDouble > &coords_z) override
virtual 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
virtual void v_BwdTrans_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) 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
virtual int v_GetVertexMap(int localVertexId, bool useCoeffPacking=false) override
virtual int v_GetNverts() const override
void v_PhysDeriv(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.
virtual LibUtilities::ShapeType v_DetShapeType() const override
virtual void v_LocCollapsedToLocCoord(const Array< OneD, const NekDouble > &eta, Array< OneD, NekDouble > &xi) override
LibUtilities::ShapeType DetShapeType() const
virtual int v_NumDGBndryCoeffs() const override
virtual void v_IProductWRTBase_SumFacKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp, bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2) override
virtual int v_CalcNumberOfCoefficients(const std::vector< unsigned int > &nummodes, int &modes_offset) override
virtual DNekMatSharedPtr v_GenMatrix(const StdMatrixKey &mkey) override
static void Dgemv(const char &trans, const int &m, const int &n, const double &alpha, const double *a, const int &lda, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = A x where A[m x n].
static void Dscal(const int &n, const double &alpha, double *x, const int &incx)
BLAS level 1: x = alpha x.
static double Ddot(const int &n, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: output = .
static void Dgemm(const char &transa, const char &transb, const int &m, const int &n, const int &k, const double &alpha, const double *a, const int &lda, const double *b, const int &ldb, const double &beta, double *c, const int &ldc)
BLAS level 3: Matrix-matrix multiply C = A x B where op(A)[m x k], op(B)[k x n], C[m x n] DGEMM perfo...
static void Daxpy(const int &n, const double &alpha, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: y = alpha x plus y.
int getNumberOfCoefficients(int Na)
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
int getNumberOfCoefficients(int Na, int Nb, int Nc)
static const BasisKey NullBasisKey(eNoBasisType, 0, NullPointsKey)
Defines a null basis with no type or points.
@ 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
LibUtilities::BasisKey EvaluateTriFaceBasisKey(const int facedir, const LibUtilities::BasisType faceDirBasisType, const int numpoints, const int nummodes)
@ eFactorSVVDGKerDiffCoeff
@ eFactorSVVPowerKerDiffCoeff
std::shared_ptr< StdTetExp > StdTetExpSharedPtr
const int kSVVDGFiltermodesmin
const int kSVVDGFiltermodesmax
const NekDouble kSVVDGFilter[9][11]
@ ePhysInterpToEquiSpaced
@ eDir1BwdDir1_Dir2FwdDir2
The above copyright notice and this permission notice shall be included.
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 scalar y = alpha + x.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
scalarT< T > sqrt(scalarT< T > in)