49 :
StdExpansion(Ba.GetNumModes() * Bb.GetNumModes() * Bc.GetNumModes(), 3,
51 StdExpansion3D(Ba.GetNumModes() * Bb.GetNumModes() * Bc.GetNumModes(), Ba,
113 ASSERTL1(
false,
"input dir is out of range");
152 "Basis[1] is not a general tensor type");
156 "Basis[2] is not a general tensor type");
158 if (
m_base[0]->Collocation() &&
m_base[1]->Collocation() &&
163 inarray, 1, outarray, 1);
182 m_base[2]->GetBdata(), inarray, outarray, wsp,
true,
205 bool doCheckCollDir0,
bool doCheckCollDir1,
bool doCheckCollDir2)
207 int nquad0 =
m_base[0]->GetNumPoints();
208 int nquad1 =
m_base[1]->GetNumPoints();
209 int nquad2 =
m_base[2]->GetNumPoints();
210 int nmodes0 =
m_base[0]->GetNumModes();
211 int nmodes1 =
m_base[1]->GetNumModes();
212 int nmodes2 =
m_base[2]->GetNumModes();
215 bool colldir0 = doCheckCollDir0 ? (
m_base[0]->Collocation()) :
false;
216 bool colldir1 = doCheckCollDir1 ? (
m_base[1]->Collocation()) :
false;
217 bool colldir2 = doCheckCollDir2 ? (
m_base[2]->Collocation()) :
false;
221 if (colldir0 && colldir1 && colldir2)
228 ASSERTL1(wsp.size() >= nquad0 * nmodes2 * (nmodes1 + nquad1),
229 "Workspace size is not sufficient");
235 Blas::Dgemm(
'T',
'T', nmodes1 * nmodes2, nquad0, nmodes0, 1.0,
236 &inarray[0], nmodes0, base0.data(), nquad0, 0.0, &wsp[0],
238 Blas::Dgemm(
'T',
'T', nquad0 * nmodes2, nquad1, nmodes1, 1.0, &wsp[0],
239 nmodes1, base1.data(), nquad1, 0.0, &wsp2[0],
241 Blas::Dgemm(
'T',
'T', nquad0 * nquad1, nquad2, nmodes2, 1.0, &wsp2[0],
242 nmodes2, base2.data(), nquad2, 0.0, &outarray[0],
261 if ((
m_base[0]->Collocation()) && (
m_base[1]->Collocation()) &&
262 (
m_base[2]->Collocation()))
280 out = (*matsys) * in;
317 if (
m_base[0]->Collocation() &&
m_base[1]->Collocation() &&
335 int nquad0 =
m_base[0]->GetNumPoints();
336 int nquad1 =
m_base[1]->GetNumPoints();
337 int nquad2 =
m_base[2]->GetNumPoints();
338 int order0 =
m_base[0]->GetNumModes();
339 int order1 =
m_base[1]->GetNumModes();
342 order0 * order1 * nquad2);
344 if (multiplybyweights)
351 tmp, outarray, wsp,
true,
true,
true);
357 inarray, outarray, wsp,
true,
true,
true);
371 bool doCheckCollDir0,
bool doCheckCollDir1,
bool doCheckCollDir2)
373 int nquad0 =
m_base[0]->GetNumPoints();
374 int nquad1 =
m_base[1]->GetNumPoints();
375 int nquad2 =
m_base[2]->GetNumPoints();
376 int nmodes0 =
m_base[0]->GetNumModes();
377 int nmodes1 =
m_base[1]->GetNumModes();
378 int nmodes2 =
m_base[2]->GetNumModes();
380 bool colldir0 = doCheckCollDir0 ? (
m_base[0]->Collocation()) :
false;
381 bool colldir1 = doCheckCollDir1 ? (
m_base[1]->Collocation()) :
false;
382 bool colldir2 = doCheckCollDir2 ? (
m_base[2]->Collocation()) :
false;
384 if (colldir0 && colldir1 && colldir2)
390 ASSERTL1(wsp.size() >= nmodes0 * nquad2 * (nquad1 + nmodes1),
391 "Insufficient workspace size");
399 for (
int n = 0; n < nmodes0; ++n)
401 Vmath::Vcopy(nquad1 * nquad2, inarray.data() + n, nquad0,
402 tmp0.data() + nquad1 * nquad2 * n, 1);
407 Blas::Dgemm(
'T',
'N', nquad1 * nquad2, nmodes0, nquad0, 1.0,
408 inarray.data(), nquad0, base0.data(), nquad0, 0.0,
409 tmp0.data(), nquad1 * nquad2);
415 for (
int n = 0; n < nmodes1; ++n)
418 tmp1.data() + nquad2 * nmodes0 * n, 1);
423 Blas::Dgemm(
'T',
'N', nquad2 * nmodes0, nmodes1, nquad1, 1.0,
424 tmp0.data(), nquad1, base1.data(), nquad1, 0.0,
425 tmp1.data(), nquad2 * nmodes0);
431 for (
int n = 0; n < nmodes2; ++n)
433 Vmath::Vcopy(nmodes0 * nmodes1, tmp1.data() + n, nquad2,
434 outarray.data() + nmodes0 * nmodes1 * n, 1);
439 Blas::Dgemm(
'T',
'N', nmodes0 * nmodes1, nmodes2, nquad2, 1.0,
440 tmp1.data(), nquad2, base2.data(), nquad2, 0.0,
441 outarray.data(), nmodes0 * nmodes1);
457 ASSERTL0((dir == 0) || (dir == 1) || (dir == 2),
458 "input dir is out of range");
460 int nquad1 =
m_base[1]->GetNumPoints();
461 int nquad2 =
m_base[2]->GetNumPoints();
462 int order0 =
m_base[0]->GetNumModes();
463 int order1 =
m_base[1]->GetNumModes();
467 if (outarray.size() < inarray.size())
484 m_base[2]->GetBdata(), tmp, outarray, wsp,
false,
true,
true);
489 m_base[2]->GetBdata(), tmp, outarray, wsp,
true,
false,
true);
494 m_base[2]->GetDbdata(), tmp, outarray, wsp,
true,
true,
false);
520 int nquad0 =
m_base[0]->GetNumPoints();
521 int nquad1 =
m_base[1]->GetNumPoints();
522 int nquad2 =
m_base[2]->GetNumPoints();
528 int btmp0 =
m_base[0]->GetNumModes();
529 int btmp1 =
m_base[1]->GetNumModes();
530 int mode2 = mode / (btmp0 * btmp1);
531 int mode1 = (mode - mode2 * btmp0 * btmp1) / btmp0;
532 int mode0 = (mode - mode2 * btmp0 * btmp1) % btmp0;
534 ASSERTL2(mode == mode2 * btmp0 * btmp1 + mode1 * btmp0 + mode0,
535 "Mode lookup failed.");
537 "Calling argument mode is larger than total expansion "
540 for (
int i = 0; i < nquad1 * nquad2; ++i)
543 &outarray[0] + i * nquad0, 1);
546 for (
int j = 0; j < nquad2; ++j)
548 for (
int i = 0; i < nquad0; ++i)
551 &outarray[0] + i + j * nquad0 * nquad1, nquad0,
552 &outarray[0] + i + j * nquad0 * nquad1, nquad0);
556 for (
int i = 0; i < nquad2; i++)
558 Blas::Dscal(nquad0 * nquad1, base2[mode2 * nquad2 + i],
559 &outarray[0] + i * nquad0 * nquad1, 1);
573 const int nm0 =
m_base[0]->GetNumModes();
574 const int nm1 =
m_base[1]->GetNumModes();
575 const int mode2 = mode / (nm0 * nm1);
576 const int mode1 = (mode - mode2 * nm0 * nm1) / nm0;
577 const int mode0 = (mode - mode2 * nm0 * nm1) % nm0;
579 return StdExpansion::BaryEvaluateBasis<0>(coords[0], mode0) *
580 StdExpansion::BaryEvaluateBasis<1>(coords[1], mode1) *
581 StdExpansion::BaryEvaluateBasis<2>(coords[2], mode2);
608 "BasisType is not a boundary interior form");
611 "BasisType is not a boundary interior form");
614 "BasisType is not a boundary interior form");
616 int nmodes0 =
m_base[0]->GetNumModes();
617 int nmodes1 =
m_base[1]->GetNumModes();
618 int nmodes2 =
m_base[2]->GetNumModes();
620 return (2 * (nmodes0 * nmodes1 + nmodes0 * nmodes2 + nmodes1 * nmodes2) -
621 4 * (nmodes0 + nmodes1 + nmodes2) + 8);
628 "BasisType is not a boundary interior form");
631 "BasisType is not a boundary interior form");
634 "BasisType is not a boundary interior form");
636 int nmodes0 =
m_base[0]->GetNumModes();
637 int nmodes1 =
m_base[1]->GetNumModes();
638 int nmodes2 =
m_base[2]->GetNumModes();
640 return 2 * (nmodes0 * nmodes1 + nmodes0 * nmodes2 + nmodes1 * nmodes2);
645 ASSERTL2((i >= 0) && (i <= 5),
"face id is out of range");
646 if ((i == 0) || (i == 5))
650 else if ((i == 1) || (i == 3))
662 ASSERTL2((i >= 0) && (i <= 5),
"face id is out of range");
663 if ((i == 0) || (i == 5))
667 else if ((i == 1) || (i == 3))
679 ASSERTL2(i >= 0 && i <= 5,
"face id is out of range");
681 if (i == 0 || i == 5)
683 return m_base[0]->GetNumPoints() *
m_base[1]->GetNumPoints();
685 else if (i == 1 || i == 3)
687 return m_base[0]->GetNumPoints() *
m_base[2]->GetNumPoints();
691 return m_base[1]->GetNumPoints() *
m_base[2]->GetNumPoints();
698 ASSERTL2(i >= 0 && i <= 5,
"face id is out of range");
699 ASSERTL2(j == 0 || j == 1,
"face direction is out of range");
701 if (i == 0 || i == 5)
703 return m_base[j]->GetPointsKey();
705 else if (i == 1 || i == 3)
707 return m_base[2 * j]->GetPointsKey();
711 return m_base[j + 1]->GetPointsKey();
716 const std::vector<unsigned int> &nummodes,
int &modes_offset)
718 int nmodes = nummodes[modes_offset] * nummodes[modes_offset + 1] *
719 nummodes[modes_offset + 2];
726 const int i,
const int k, [[maybe_unused]]
bool UseGLL)
const
728 ASSERTL2(i >= 0 && i <= 5,
"face id is out of range");
729 ASSERTL2(k >= 0 && k <= 1,
"basis key id is out of range");
764 for (
int k = 0; k < Qz; ++k)
766 for (
int j = 0; j < Qy; ++j)
768 for (
int i = 0; i < Qx; ++i)
770 int s = i + Qx * (j + Qy * k);
782 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
783 m_base[2]->GetNumModes()};
789 numModes0 = nummodes[0];
790 numModes1 = nummodes[1];
796 numModes0 = nummodes[0];
797 numModes1 = nummodes[2];
803 numModes0 = nummodes[1];
804 numModes1 = nummodes[2];
809 ASSERTL0(
false,
"fid out of range");
816 std::swap(numModes0, numModes1);
831 "BasisType is not a boundary interior form");
834 "BasisType is not a boundary interior form");
837 "BasisType is not a boundary interior form");
839 ASSERTL1((localVertexId >= 0) && (localVertexId < 8),
840 "local vertex id must be between 0 and 7");
847 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
848 m_base[2]->GetNumModes()};
850 if (useCoeffPacking ==
true)
852 if (localVertexId > 3)
864 switch (localVertexId % 4)
911 if ((localVertexId % 4) % 3 > 0)
923 if (localVertexId % 4 > 1)
936 if (localVertexId > 3)
949 return r * nummodes[0] * nummodes[1] + q * nummodes[0] + p;
959 "BasisType is not a boundary interior form");
962 "BasisType is not a boundary interior form");
965 "BasisType is not a boundary interior form");
968 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
969 m_base[2]->GetNumModes()};
973 if (outarray.size() != nIntCoeffs)
986 for (i = 0; i < 3; i++)
991 IntIdx[i][1] = nummodes[i];
996 IntIdx[i][1] = nummodes[i] - 1;
1000 for (r = IntIdx[2][0]; r < IntIdx[2][1]; r++)
1002 for (q = IntIdx[1][0]; q < IntIdx[1][1]; q++)
1004 for (p = IntIdx[0][0]; p < IntIdx[0][1]; p++)
1007 r * nummodes[0] * nummodes[1] + q * nummodes[0] + p;
1020 "BasisType is not a boundary interior form");
1023 "BasisType is not a boundary interior form");
1026 "BasisType is not a boundary interior form");
1029 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
1030 m_base[2]->GetNumModes()};
1034 if (outarray.size() != nBndCoeffs)
1048 for (i = 0; i < 3; i++)
1056 IntIdx[i][1] = nummodes[i];
1060 BndIdx[i][1] = nummodes[i] - 1;
1062 IntIdx[i][1] = nummodes[i] - 1;
1066 for (i = 0; i < 2; i++)
1069 for (q = 0; q < nummodes[1]; q++)
1071 for (p = 0; p < nummodes[0]; p++)
1074 r * nummodes[0] * nummodes[1] + q * nummodes[0] + p;
1079 for (r = IntIdx[2][0]; r < IntIdx[2][1]; r++)
1081 for (i = 0; i < 2; i++)
1084 for (p = 0; p < nummodes[0]; p++)
1087 r * nummodes[0] * nummodes[1] + q * nummodes[0] + p;
1091 for (q = IntIdx[1][0]; q < IntIdx[1][1]; q++)
1093 for (i = 0; i < 2; i++)
1097 r * nummodes[0] * nummodes[1] + q * nummodes[0] + p;
1102 sort(outarray.data(), outarray.data() + nBndCoeffs);
1108 std::array<NekDouble, 3> &firstOrderDerivs)
1120 int nummodesA = 0, nummodesB = 0;
1124 "Method only implemented if BasisType is indentical in "
1128 "Method only implemented for Modified_A or "
1129 "GLL_Lagrange BasisType");
1131 const int nummodes0 =
m_base[0]->GetNumModes();
1132 const int nummodes1 =
m_base[1]->GetNumModes();
1133 const int nummodes2 =
m_base[2]->GetNumModes();
1139 nummodesA = nummodes0;
1140 nummodesB = nummodes1;
1144 nummodesA = nummodes0;
1145 nummodesB = nummodes2;
1149 nummodesA = nummodes1;
1150 nummodesB = nummodes2;
1153 ASSERTL0(
false,
"fid must be between 0 and 5");
1156 int nFaceCoeffs = nummodesA * nummodesB;
1158 if (maparray.size() != nFaceCoeffs)
1175 offset = nummodes0 * nummodes1;
1179 offset = (nummodes2 - 1) * nummodes0 * nummodes1;
1197 offset = nummodes0 * (nummodes1 - 1);
1198 jump1 = nummodes0 * nummodes1;
1204 jump1 = nummodes0 * nummodes1;
1215 offset = nummodes0 - 1;
1216 jump1 = nummodes0 * nummodes1;
1223 jump1 = nummodes0 * nummodes1;
1228 ASSERTL0(
false,
"fid must be between 0 and 5");
1231 for (i = 0; i < nummodesB; i++)
1233 for (j = 0; j < nummodesA; j++)
1235 maparray[i * nummodesA + j] = i * jump1 + j * jump2 + offset;
1246 int nummodesA = 0, nummodesB = 0;
1250 "Method only implemented if BasisType is indentical in "
1254 "Method only implemented for Modified_A or "
1255 "GLL_Lagrange BasisType");
1257 const int nummodes0 =
m_base[0]->GetNumModes();
1258 const int nummodes1 =
m_base[1]->GetNumModes();
1259 const int nummodes2 =
m_base[2]->GetNumModes();
1265 nummodesA = nummodes0;
1266 nummodesB = nummodes1;
1270 nummodesA = nummodes0;
1271 nummodesB = nummodes2;
1275 nummodesA = nummodes1;
1276 nummodesB = nummodes2;
1279 ASSERTL0(
false,
"fid must be between 0 and 5");
1291 if (modified ==
false)
1293 ASSERTL1((
P == nummodesA) || (Q == nummodesB),
1294 "Different trace space face dimention "
1295 "and element face dimention not possible for "
1296 "GLL-Lagrange bases");
1299 int nFaceCoeffs =
P * Q;
1301 if (maparray.size() != nFaceCoeffs)
1307 for (i = 0; i < nFaceCoeffs; ++i)
1312 if (signarray.size() != nFaceCoeffs)
1318 fill(signarray.data(), signarray.data() + nFaceCoeffs, 1);
1323 for (i = 0; i < Q; i++)
1325 for (j = 0; j <
P; j++)
1329 arrayindx[i *
P + j] = i *
P + j;
1333 arrayindx[i *
P + j] = j * Q + i;
1340 for (i = 0; i < nummodesB; i++)
1342 for (j = nummodesA; j <
P; j++)
1344 signarray[arrayindx[i *
P + j]] = 0.0;
1345 maparray[arrayindx[i *
P + j]] = maparray[0];
1349 for (i = nummodesB; i < Q; i++)
1351 for (j = 0; j <
P; j++)
1353 signarray[arrayindx[i *
P + j]] = 0.0;
1354 maparray[arrayindx[i *
P + j]] = maparray[0];
1360 for (i = 0; i < Q; i++)
1364 for (j = 0; j <
P; j++)
1366 maparray[arrayindx[i *
P + j]] = i * nummodesA + j;
1370 for (j = nummodesA; j <
P; j++)
1372 signarray[arrayindx[i *
P + j]] = 0.0;
1373 maparray[arrayindx[i *
P + j]] = maparray[0];
1378 for (i = nummodesB; i < Q; i++)
1380 for (j = 0; j <
P; j++)
1382 signarray[arrayindx[i *
P + j]] = 0.0;
1383 maparray[arrayindx[i *
P + j]] = maparray[0];
1397 for (i = 3; i < Q; i += 2)
1399 for (j = 0; j <
P; j++)
1401 signarray[arrayindx[i *
P + j]] *= -1;
1405 for (i = 0; i <
P; i++)
1407 swap(maparray[i], maparray[i +
P]);
1408 swap(signarray[i], signarray[i +
P]);
1413 for (i = 0; i <
P; i++)
1415 for (j = 0; j < Q / 2; j++)
1417 swap(maparray[i + j *
P],
1418 maparray[i +
P * Q -
P - j *
P]);
1419 swap(signarray[i + j *
P],
1420 signarray[i +
P * Q -
P - j *
P]);
1429 for (i = 0; i < Q; i++)
1431 for (j = 3; j <
P; j += 2)
1433 signarray[arrayindx[i *
P + j]] *= -1;
1437 for (i = 0; i < Q; i++)
1439 swap(maparray[i], maparray[i + Q]);
1440 swap(signarray[i], signarray[i + Q]);
1445 for (i = 0; i <
P; i++)
1447 for (j = 0; j < Q / 2; j++)
1449 swap(maparray[i * Q + j], maparray[i * Q + Q - 1 - j]);
1450 swap(signarray[i * Q + j],
1451 signarray[i * Q + Q - 1 - j]);
1467 for (i = 0; i < Q; i++)
1469 for (j = 3; j <
P; j += 2)
1471 signarray[arrayindx[i *
P + j]] *= -1;
1475 for (i = 0; i < Q; i++)
1477 swap(maparray[i *
P], maparray[i *
P + 1]);
1478 swap(signarray[i *
P], signarray[i *
P + 1]);
1483 for (i = 0; i < Q; i++)
1485 for (j = 0; j <
P / 2; j++)
1487 swap(maparray[i *
P + j], maparray[i *
P +
P - 1 - j]);
1488 swap(signarray[i *
P + j],
1489 signarray[i *
P +
P - 1 - j]);
1498 for (i = 3; i < Q; i += 2)
1500 for (j = 0; j <
P; j++)
1502 signarray[arrayindx[i *
P + j]] *= -1;
1506 for (i = 0; i <
P; i++)
1508 swap(maparray[i * Q], maparray[i * Q + 1]);
1509 swap(signarray[i * Q], signarray[i * Q + 1]);
1514 for (i = 0; i < Q; i++)
1516 for (j = 0; j <
P / 2; j++)
1518 swap(maparray[i + j * Q],
1519 maparray[i +
P * Q - Q - j * Q]);
1520 swap(signarray[i + j * Q],
1521 signarray[i +
P * Q - Q - j * Q]);
1541 "BasisType is not a boundary interior form");
1544 "BasisType is not a boundary interior form");
1547 "BasisType is not a boundary interior form");
1550 "local edge id must be between 0 and 11");
1554 if (maparray.size() != nEdgeIntCoeffs)
1559 if (signarray.size() != nEdgeIntCoeffs)
1565 fill(signarray.data(), signarray.data() + nEdgeIntCoeffs, 1);
1568 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
1569 m_base[2]->GetNumModes()};
1574 bool reverseOrdering =
false;
1575 bool signChange =
false;
1577 int IdxRange[3][2] = {{0, 0}, {0, 0}, {0, 0}};
1597 IdxRange[2][0] = nummodes[2] - 1;
1598 IdxRange[2][1] = nummodes[2];
1615 IdxRange[2][1] = nummodes[2] - 1;
1619 reverseOrdering =
true;
1625 IdxRange[2][1] = nummodes[2];
1654 IdxRange[1][0] = nummodes[1] - 1;
1655 IdxRange[1][1] = nummodes[1];
1670 IdxRange[1][1] = nummodes[1] - 1;
1674 reverseOrdering =
true;
1680 IdxRange[1][1] = nummodes[1];
1695 IdxRange[1][1] = nummodes[1] - 1;
1699 reverseOrdering =
true;
1705 IdxRange[1][1] = nummodes[1];
1734 IdxRange[0][0] = nummodes[0] - 1;
1735 IdxRange[0][1] = nummodes[0];
1750 IdxRange[0][1] = nummodes[0] - 1;
1754 reverseOrdering =
true;
1760 IdxRange[0][1] = nummodes[0];
1775 IdxRange[0][1] = nummodes[0] - 1;
1779 reverseOrdering =
true;
1785 IdxRange[0][1] = nummodes[0];
1798 for (
int r = IdxRange[2][0]; r < IdxRange[2][1]; r++)
1800 for (
int q = IdxRange[1][0]; q < IdxRange[1][1]; q++)
1802 for (
int p = IdxRange[0][0]; p < IdxRange[0][1]; p++)
1805 r * nummodes[0] * nummodes[1] + q * nummodes[0] + p;
1810 if (reverseOrdering)
1812 reverse(maparray.data(), maparray.data() + nEdgeIntCoeffs);
1817 for (
int p = 1; p < nEdgeIntCoeffs; p += 2)
1834 "BasisType is not a boundary interior form");
1837 "BasisType is not a boundary interior form");
1840 "BasisType is not a boundary interior form");
1842 ASSERTL1((fid >= 0) && (fid < 6),
"local face id must be between 0 and 5");
1846 if (maparray.size() != nFaceIntCoeffs)
1851 if (signarray.size() != nFaceIntCoeffs)
1857 fill(signarray.data(), signarray.data() + nFaceIntCoeffs, 1);
1860 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
1861 m_base[2]->GetNumModes()};
1876 nummodesA = nummodes[0];
1877 nummodesB = nummodes[1];
1883 nummodesA = nummodes[0];
1884 nummodesB = nummodes[2];
1890 nummodesA = nummodes[1];
1891 nummodesB = nummodes[2];
1899 for (
int i = 0; i < (nummodesB - 2); i++)
1901 for (
int j = 0; j < (nummodesA - 2); j++)
1905 arrayindx[i * (nummodesA - 2) + j] = i * (nummodesA - 2) + j;
1909 arrayindx[i * (nummodesA - 2) + j] = j * (nummodesB - 2) + i;
1936 IdxRange[2][0] = nummodes[2] - 1;
1937 IdxRange[2][1] = nummodes[2];
1954 IdxRange[2][0] = nummodes[2] - 2;
1961 IdxRange[2][1] = nummodes[2] - 1;
1968 IdxRange[2][1] = nummodes[2];
1973 for (
int i = 3; i < nummodes[2]; i += 2)
1997 IdxRange[1][0] = nummodes[1] - 1;
1998 IdxRange[1][1] = nummodes[1];
2016 IdxRange[1][0] = nummodes[1] - 2;
2023 IdxRange[1][1] = nummodes[1] - 1;
2030 IdxRange[1][1] = nummodes[1];
2035 for (
int i = 3; i < nummodes[1]; i += 2)
2049 IdxRange[1][0] = nummodes[1] - 2;
2056 IdxRange[1][1] = nummodes[1] - 1;
2063 IdxRange[1][1] = nummodes[1];
2068 for (
int i = 3; i < nummodes[1]; i += 2)
2090 IdxRange[0][0] = nummodes[0] - 1;
2091 IdxRange[0][1] = nummodes[0];
2108 IdxRange[0][0] = nummodes[0] - 2;
2115 IdxRange[0][1] = nummodes[0] - 1;
2122 IdxRange[0][1] = nummodes[0];
2127 for (
int i = 3; i < nummodes[0]; i += 2)
2138 for (
int r = IdxRange[2][0]; r != IdxRange[2][1]; r += Incr[2])
2140 for (
int q = IdxRange[1][0]; q != IdxRange[1][1]; q += Incr[1])
2142 for (
int p = IdxRange[0][0]; p != IdxRange[0][1]; p += Incr[0])
2144 maparray[arrayindx[cnt]] =
2145 r * nummodes[0] * nummodes[1] + q * nummodes[0] + p;
2146 signarray[arrayindx[cnt++]] = sign0[p] * sign1[q] * sign2[r];
2154 ASSERTL2((i >= 0) && (i <= 11),
"edge id is out of range");
2156 if ((i == 0) || (i == 2) || (i == 8) || (i == 10))
2160 else if ((i == 1) || (i == 3) || (i == 9) || (i == 11))
2181 int nq0 =
m_base[0]->GetNumPoints();
2182 int nq1 =
m_base[1]->GetNumPoints();
2183 int nq2 =
m_base[2]->GetNumPoints();
2193 nq =
max(nq0,
max(nq1, nq2));
2207 for (
int i = 0; i < nq; ++i)
2209 for (
int j = 0; j < nq; ++j)
2211 for (
int k = 0; k < nq; ++k, ++cnt)
2214 coords[cnt][0] = -1.0 + 2 * k / (
NekDouble)(nq - 1);
2215 coords[cnt][1] = -1.0 + 2 * j / (
NekDouble)(nq - 1);
2216 coords[cnt][2] = -1.0 + 2 * i / (
NekDouble)(nq - 1);
2221 for (
int i = 0; i < neq; ++i)
2225 I[0] =
m_base[0]->GetI(coll);
2226 I[1] =
m_base[1]->GetI(coll + 1);
2227 I[2] =
m_base[2]->GetI(coll + 2);
2231 for (
int k = 0; k < nq2; ++k)
2233 for (
int j = 0; j < nq1; ++j)
2236 fac = (I[1]->GetPtr())[j] * (I[2]->GetPtr())[k];
2240 Mat->GetRawPtr() + k * nq0 * nq1 * neq +
2304 int nquad0 =
m_base[0]->GetNumPoints();
2305 int nquad1 =
m_base[1]->GetNumPoints();
2306 int nquad2 =
m_base[2]->GetNumPoints();
2307 int nq01 = nquad0 * nquad1;
2308 int nq12 = nquad1 * nquad2;
2314 for (
int i = 0; i < nq12; ++i)
2316 Vmath::Vmul(nquad0, inarray.data() + i * nquad0, 1, w0.data(), 1,
2317 outarray.data() + i * nquad0, 1);
2320 for (
int i = 0; i < nq12; ++i)
2322 Vmath::Smul(nquad0, w1[i % nquad1], outarray.data() + i * nquad0, 1,
2323 outarray.data() + i * nquad0, 1);
2326 for (
int i = 0; i < nquad2; ++i)
2328 Vmath::Smul(nq01, w2[i], outarray.data() + i * nq01, 1,
2329 outarray.data() + i * nq01, 1);
2337 int qa =
m_base[0]->GetNumPoints();
2338 int qb =
m_base[1]->GetNumPoints();
2339 int qc =
m_base[2]->GetNumPoints();
2340 int nmodes_a =
m_base[0]->GetNumModes();
2341 int nmodes_b =
m_base[1]->GetNumModes();
2342 int nmodes_c =
m_base[2]->GetNumModes();
2357 OrthoExp.
FwdTrans(array, orthocoeffs);
2367 for (
int i = 0; i < nmodes_a; ++i)
2369 for (
int j = 0; j < nmodes_b; ++j)
2372 pow((1.0 * i) / (nmodes_a - 1), cutoff * nmodes_a),
2373 pow((1.0 * j) / (nmodes_b - 1), cutoff * nmodes_b));
2375 for (
int k = 0; k < nmodes_c; ++k)
2378 std::max(fac1, pow((1.0 * k) / (nmodes_c - 1),
2379 cutoff * nmodes_c));
2381 orthocoeffs[cnt] *= SvvDiffCoeff * fac;
2397 max_abc =
max(max_abc, 0);
2400 for (
int i = 0; i < nmodes_a; ++i)
2402 for (
int j = 0; j < nmodes_b; ++j)
2404 int maxij =
max(i, j);
2406 for (
int k = 0; k < nmodes_c; ++k)
2408 int maxijk =
max(maxij, k);
2422 min(nmodes_a, nmodes_b));
2425 int nmodes =
max(nmodes_a, nmodes_b);
2426 nmodes =
max(nmodes, nmodes_c);
2429 for (
int j = cutoff; j < nmodes; ++j)
2431 fac[j] = fabs((j - nmodes) / ((
NekDouble)(j - cutoff + 1.0)));
2435 for (
int i = 0; i < nmodes_a; ++i)
2437 for (
int j = 0; j < nmodes_b; ++j)
2439 for (
int k = 0; k < nmodes_c; ++k)
2441 if ((i >= cutoff) || (j >= cutoff) || (k >= cutoff))
2443 orthocoeffs[i * nmodes_a * nmodes_b + j * nmodes_c +
2445 (SvvDiffCoeff * exp(-(fac[i] + fac[j] + fac[k])));
2449 orthocoeffs[i * nmodes_a * nmodes_b + j * nmodes_c +
2458 OrthoExp.
BwdTrans(orthocoeffs, array);
2467 int qa =
m_base[0]->GetNumPoints();
2468 int qb =
m_base[1]->GetNumPoints();
2469 int qc =
m_base[2]->GetNumPoints();
2470 int nmodesA =
m_base[0]->GetNumModes();
2471 int nmodesB =
m_base[1]->GetNumModes();
2472 int nmodesC =
m_base[2]->GetNumModes();
2473 int P = nmodesA - 1;
2474 int Q = nmodesB - 1;
2475 int R = nmodesC - 1;
2488 int Pcut = cutoff *
P;
2489 int Qcut = cutoff * Q;
2490 int Rcut = cutoff * R;
2494 OrthoExp.
FwdTrans(array, orthocoeffs);
2499 for (
int i = 0; i < nmodesA; ++i)
2501 for (
int j = 0; j < nmodesB; ++j)
2503 for (
int k = 0; k < nmodesC; ++k, ++index)
2506 if (i > Pcut || j > Qcut || k > Rcut)
2511 fac =
max(
max(fac1, fac2), fac3);
2512 fac = pow(fac, exponent);
2513 orthocoeffs[index] *= exp(-alpha * fac);
2520 OrthoExp.
BwdTrans(orthocoeffs, array);
2526 int np0 =
m_base[0]->GetNumPoints();
2527 int np1 =
m_base[1]->GetNumPoints();
2528 int np2 =
m_base[2]->GetNumPoints();
2529 int np =
max(np0,
max(np1, np2));
2537 for (
int i = 0; i < np - 1; ++i)
2539 for (
int j = 0; j < np - 1; ++j)
2542 for (
int k = 0; k < np - 1; ++k)
2544 conn[cnt++] = plane + row + k;
2545 conn[cnt++] = plane + row + k + 1;
2546 conn[cnt++] = plane + rowp1 + k;
2548 conn[cnt++] = plane + rowp1 + k + 1;
2549 conn[cnt++] = plane + rowp1 + k;
2550 conn[cnt++] = plane + row + k + 1;
#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.
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)
int GetEdgeNcoeffs(const int i) const
This function returns the number of expansion coefficients belonging to the i-th edge.
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.
virtual void v_LaplacianMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
int GetNcoeffs(void) const
This function returns the total number of coefficients used in the expansion.
void WeakDerivMatrixOp_MatFree(const int i, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
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.
virtual void v_HelmholtzMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
void BwdTrans_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
void IProductWRTDerivBase_SumFac(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
DNekMatSharedPtr CreateGeneralMatrix(const StdMatrixKey &mkey)
this function generates the mass matrix
void IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
this function calculates the inner product of a given function f with the different modes of the expa...
void LaplacianMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
LibUtilities::ShapeType DetShapeType() const
This function returns the shape of the expansion domain.
void BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function performs the Backward transformation from coefficient space to physical space.
LibUtilities::PointsType GetPointsType(const int dir) const
This function returns the type of quadrature points used in the dir direction.
void FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function performs the Forward transformation from physical space to coefficient space.
int GetNumPoints(const int dir) const
This function returns the number of quadrature points in the dir direction.
void MultiplyByQuadratureMetric(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
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
void MassMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
Class representing a hexehedral element in reference space.
int v_NumDGBndryCoeffs() const override
void v_MassMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
void v_MultiplyByStdQuadratureMetric(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1, Array< OneD, NekDouble > &out_d2) override
Differentiation Methods.
void v_ExponentialFilter(Array< OneD, NekDouble > &array, const NekDouble alpha, const NekDouble exponent, const NekDouble cutoff) override
int v_GetVertexMap(int localVertexId, bool useCoeffPacking=false) override
void v_LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta) override
int v_CalcNumberOfCoefficients(const std::vector< unsigned int > &nummodes, int &modes_offset) 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_GetTraceInteriorToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation traceOrient=eDir1FwdDir1_Dir2FwdDir2) override
void v_IProductWRTDerivBase_SumFac(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
DNekMatSharedPtr v_CreateStdMatrix(const StdMatrixKey &mkey) override
int v_GetEdgeNcoeffs(const int i) const override
void v_IProductWRTBase_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool multbyweights=true) override
StdHexExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::BasisKey &Bc)
int v_GetTraceNumPoints(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_GetTraceCoeffMap(const unsigned int fid, Array< OneD, unsigned int > &maparray) override
LibUtilities::ShapeType v_DetShapeType() const override
void v_GetTraceNumModes(const int fid, int &numModes0, int &numModes1, Orientation faceOrient=eDir1FwdDir1_Dir2FwdDir2) override
void v_LocCollapsedToLocCoord(const Array< OneD, const NekDouble > &eta, Array< OneD, NekDouble > &xi) override
void v_LaplacianMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
int v_NumBndryCoeffs() const override
int v_GetNedges() const override
void v_FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
int v_GetNtraces() const override
void v_HelmholtzMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
int v_GetNverts() const override
bool v_IsBoundaryInteriorExpansion() const override
void v_GetInteriorMap(Array< OneD, unsigned int > &outarray) override
void v_GetBoundaryMap(Array< OneD, unsigned int > &outarray) override
void v_FillMode(const int mode, Array< OneD, NekDouble > &outarray) override
void v_GetSimplexEquiSpacedConnectivity(Array< OneD, int > &conn, bool standard=true) override
void v_WeakDerivMatrixOp(const int i, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
int v_GetTraceIntNcoeffs(const int i) const 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
void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) 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_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
void v_GetEdgeInteriorToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation traceOrient=eDir1FwdDir1_Dir2FwdDir2) override
void v_BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdMatrixKey &mkey) override
const LibUtilities::BasisKey v_GetTraceBasisKey(const int i, const int k, bool useGLL=false) const override
void v_GetCoords(Array< OneD, NekDouble > &coords_x, Array< OneD, NekDouble > &coords_y, Array< OneD, NekDouble > &coords_z) override
DNekMatSharedPtr v_GenMatrix(const StdMatrixKey &mkey) override
void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
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
int v_GetTraceNcoeffs(const int i) const override
void v_BwdTrans_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
MatrixType GetMatrixType() const
NekDouble GetConstFactor(const ConstFactorType &factor) const
bool ConstFactorExists(const ConstFactorType &factor) const
static void Dscal(const int &n, const double &alpha, double *x, const int &incx)
BLAS level 1: x = alpha x.
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...
int getNumberOfCoefficients(int Na, int Nb, int Nc)
@ eModified_B
Principle Modified Functions .
@ P
Monomial polynomials .
@ 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 EvaluateQuadFaceBasisKey(const int facedir, const LibUtilities::BasisSharedPtr &faceDirBasis)
@ eFactorSVVDGKerDiffCoeff
@ eFactorSVVPowerKerDiffCoeff
const int kSVVDGFiltermodesmin
const int kSVVDGFiltermodesmax
const NekDouble kSVVDGFilter[9][11]
@ ePhysInterpToEquiSpaced
@ eDir1BwdDir2_Dir2BwdDir1
@ eDir1FwdDir1_Dir2FwdDir2
@ 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 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)