54 :
StdExpansion(Ba.GetNumModes() * Bb.GetNumModes() * Bc.GetNumModes(), 3,
56 StdExpansion3D(Ba.GetNumModes() * Bb.GetNumModes() * Bc.GetNumModes(), Ba,
126 ASSERTL1(
false,
"input dir is out of range");
172 "Basis[1] is not a general tensor type");
176 "Basis[2] is not a general tensor type");
178 if (
m_base[0]->Collocation() &&
m_base[1]->Collocation() &&
183 inarray, 1, outarray, 1);
202 m_base[2]->GetBdata(), inarray, outarray, wsp,
true,
225 bool doCheckCollDir0,
bool doCheckCollDir1,
bool doCheckCollDir2)
227 int nquad0 =
m_base[0]->GetNumPoints();
228 int nquad1 =
m_base[1]->GetNumPoints();
229 int nquad2 =
m_base[2]->GetNumPoints();
230 int nmodes0 =
m_base[0]->GetNumModes();
231 int nmodes1 =
m_base[1]->GetNumModes();
232 int nmodes2 =
m_base[2]->GetNumModes();
235 bool colldir0 = doCheckCollDir0 ? (
m_base[0]->Collocation()) :
false;
236 bool colldir1 = doCheckCollDir1 ? (
m_base[1]->Collocation()) :
false;
237 bool colldir2 = doCheckCollDir2 ? (
m_base[2]->Collocation()) :
false;
241 if (colldir0 && colldir1 && colldir2)
248 ASSERTL1(wsp.size() >= nquad0 * nmodes2 * (nmodes1 + nquad1),
249 "Workspace size is not sufficient");
255 Blas::Dgemm(
'T',
'T', nmodes1 * nmodes2, nquad0, nmodes0, 1.0,
256 &inarray[0], nmodes0, base0.get(), nquad0, 0.0, &wsp[0],
258 Blas::Dgemm(
'T',
'T', nquad0 * nmodes2, nquad1, nmodes1, 1.0, &wsp[0],
259 nmodes1, base1.get(), nquad1, 0.0, &wsp2[0],
261 Blas::Dgemm(
'T',
'T', nquad0 * nquad1, nquad2, nmodes2, 1.0, &wsp2[0],
262 nmodes2, base2.get(), nquad2, 0.0, &outarray[0],
281 if ((
m_base[0]->Collocation()) && (
m_base[1]->Collocation()) &&
282 (
m_base[2]->Collocation()))
300 out = (*matsys) * in;
337 if (
m_base[0]->Collocation() &&
m_base[1]->Collocation() &&
355 int nquad0 =
m_base[0]->GetNumPoints();
356 int nquad1 =
m_base[1]->GetNumPoints();
357 int nquad2 =
m_base[2]->GetNumPoints();
358 int order0 =
m_base[0]->GetNumModes();
359 int order1 =
m_base[1]->GetNumModes();
362 order0 * order1 * nquad2);
364 if (multiplybyweights)
371 tmp, outarray, wsp,
true,
true,
true);
377 inarray, outarray, wsp,
true,
true,
true);
391 bool doCheckCollDir0,
bool doCheckCollDir1,
bool doCheckCollDir2)
393 int nquad0 =
m_base[0]->GetNumPoints();
394 int nquad1 =
m_base[1]->GetNumPoints();
395 int nquad2 =
m_base[2]->GetNumPoints();
396 int nmodes0 =
m_base[0]->GetNumModes();
397 int nmodes1 =
m_base[1]->GetNumModes();
398 int nmodes2 =
m_base[2]->GetNumModes();
400 bool colldir0 = doCheckCollDir0 ? (
m_base[0]->Collocation()) :
false;
401 bool colldir1 = doCheckCollDir1 ? (
m_base[1]->Collocation()) :
false;
402 bool colldir2 = doCheckCollDir2 ? (
m_base[2]->Collocation()) :
false;
404 if (colldir0 && colldir1 && colldir2)
410 ASSERTL1(wsp.size() >= nmodes0 * nquad2 * (nquad1 + nmodes1),
411 "Insufficient workspace size");
419 for (
int n = 0; n < nmodes0; ++n)
421 Vmath::Vcopy(nquad1 * nquad2, inarray.get() + n, nquad0,
422 tmp0.get() + nquad1 * nquad2 * n, 1);
427 Blas::Dgemm(
'T',
'N', nquad1 * nquad2, nmodes0, nquad0, 1.0,
428 inarray.get(), nquad0, base0.get(), nquad0, 0.0,
429 tmp0.get(), nquad1 * nquad2);
435 for (
int n = 0; n < nmodes1; ++n)
438 tmp1.get() + nquad2 * nmodes0 * n, 1);
443 Blas::Dgemm(
'T',
'N', nquad2 * nmodes0, nmodes1, nquad1, 1.0,
444 tmp0.get(), nquad1, base1.get(), nquad1, 0.0,
445 tmp1.get(), nquad2 * nmodes0);
451 for (
int n = 0; n < nmodes2; ++n)
454 outarray.get() + nmodes0 * nmodes1 * n, 1);
459 Blas::Dgemm(
'T',
'N', nmodes0 * nmodes1, nmodes2, nquad2, 1.0,
460 tmp1.get(), nquad2, base2.get(), nquad2, 0.0,
461 outarray.get(), nmodes0 * nmodes1);
477 ASSERTL0((dir == 0) || (dir == 1) || (dir == 2),
478 "input dir is out of range");
480 int nquad1 =
m_base[1]->GetNumPoints();
481 int nquad2 =
m_base[2]->GetNumPoints();
482 int order0 =
m_base[0]->GetNumModes();
483 int order1 =
m_base[1]->GetNumModes();
487 if (outarray.size() < inarray.size())
504 m_base[2]->GetBdata(), tmp, outarray, wsp,
false,
true,
true);
509 m_base[2]->GetBdata(), tmp, outarray, wsp,
true,
false,
true);
514 m_base[2]->GetDbdata(), tmp, outarray, wsp,
true,
true,
false);
540 int nquad0 =
m_base[0]->GetNumPoints();
541 int nquad1 =
m_base[1]->GetNumPoints();
542 int nquad2 =
m_base[2]->GetNumPoints();
548 int btmp0 =
m_base[0]->GetNumModes();
549 int btmp1 =
m_base[1]->GetNumModes();
550 int mode2 = mode / (btmp0 * btmp1);
551 int mode1 = (mode - mode2 * btmp0 * btmp1) / btmp0;
552 int mode0 = (mode - mode2 * btmp0 * btmp1) % btmp0;
554 ASSERTL2(mode == mode2 * btmp0 * btmp1 + mode1 * btmp0 + mode0,
555 "Mode lookup failed.");
557 "Calling argument mode is larger than total expansion "
560 for (
int i = 0; i < nquad1 * nquad2; ++i)
563 &outarray[0] + i * nquad0, 1);
566 for (
int j = 0; j < nquad2; ++j)
568 for (
int i = 0; i < nquad0; ++i)
571 &outarray[0] + i + j * nquad0 * nquad1, nquad0,
572 &outarray[0] + i + j * nquad0 * nquad1, nquad0);
576 for (
int i = 0; i < nquad2; i++)
578 Blas::Dscal(nquad0 * nquad1, base2[mode2 * nquad2 + i],
579 &outarray[0] + i * nquad0 * nquad1, 1);
593 const int nm0 =
m_base[0]->GetNumModes();
594 const int nm1 =
m_base[1]->GetNumModes();
595 const int mode2 = mode / (nm0 * nm1);
596 const int mode1 = (mode - mode2 * nm0 * nm1) / nm0;
597 const int mode0 = (mode - mode2 * nm0 * nm1) % nm0;
599 return StdExpansion::BaryEvaluateBasis<0>(coords[0], mode0) *
600 StdExpansion::BaryEvaluateBasis<1>(coords[1], mode1) *
601 StdExpansion::BaryEvaluateBasis<2>(coords[2], mode2);
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) -
641 4 * (nmodes0 + nmodes1 + nmodes2) + 8);
648 "BasisType is not a boundary interior form");
651 "BasisType is not a boundary interior form");
654 "BasisType is not a boundary interior form");
656 int nmodes0 =
m_base[0]->GetNumModes();
657 int nmodes1 =
m_base[1]->GetNumModes();
658 int nmodes2 =
m_base[2]->GetNumModes();
660 return 2 * (nmodes0 * nmodes1 + nmodes0 * nmodes2 + nmodes1 * nmodes2);
665 ASSERTL2((i >= 0) && (i <= 5),
"face id is out of range");
666 if ((i == 0) || (i == 5))
670 else if ((i == 1) || (i == 3))
682 ASSERTL2((i >= 0) && (i <= 5),
"face id is out of range");
683 if ((i == 0) || (i == 5))
687 else if ((i == 1) || (i == 3))
699 ASSERTL2(i >= 0 && i <= 5,
"face id is out of range");
701 if (i == 0 || i == 5)
703 return m_base[0]->GetNumPoints() *
m_base[1]->GetNumPoints();
705 else if (i == 1 || i == 3)
707 return m_base[0]->GetNumPoints() *
m_base[2]->GetNumPoints();
711 return m_base[1]->GetNumPoints() *
m_base[2]->GetNumPoints();
718 ASSERTL2(i >= 0 && i <= 5,
"face id is out of range");
719 ASSERTL2(j == 0 || j == 1,
"face direction is out of range");
721 if (i == 0 || i == 5)
723 return m_base[j]->GetPointsKey();
725 else if (i == 1 || i == 3)
727 return m_base[2 * j]->GetPointsKey();
731 return m_base[j + 1]->GetPointsKey();
736 const std::vector<unsigned int> &nummodes,
int &modes_offset)
738 int nmodes = nummodes[modes_offset] * nummodes[modes_offset + 1] *
739 nummodes[modes_offset + 2];
748 ASSERTL2(i >= 0 && i <= 5,
"face id is out of range");
749 ASSERTL2(k >= 0 && k <= 1,
"basis key id is out of range");
770 m_base[dir]->GetNumModes());
786 for (
int k = 0; k < Qz; ++k)
788 for (
int j = 0; j < Qy; ++j)
790 for (
int i = 0; i < Qx; ++i)
792 int s = i + Qx * (j + Qy * k);
804 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
805 m_base[2]->GetNumModes()};
811 numModes0 = nummodes[0];
812 numModes1 = nummodes[1];
818 numModes0 = nummodes[0];
819 numModes1 = nummodes[2];
825 numModes0 = nummodes[1];
826 numModes1 = nummodes[2];
831 ASSERTL0(
false,
"fid out of range");
838 std::swap(numModes0, numModes1);
853 "BasisType is not a boundary interior form");
856 "BasisType is not a boundary interior form");
859 "BasisType is not a boundary interior form");
861 ASSERTL1((localVertexId >= 0) && (localVertexId < 8),
862 "local vertex id must be between 0 and 7");
869 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
870 m_base[2]->GetNumModes()};
872 if (useCoeffPacking ==
true)
874 if (localVertexId > 3)
886 switch (localVertexId % 4)
933 if ((localVertexId % 4) % 3 > 0)
945 if (localVertexId % 4 > 1)
958 if (localVertexId > 3)
971 return r * nummodes[0] * nummodes[1] +
q * nummodes[0] +
p;
981 "BasisType is not a boundary interior form");
984 "BasisType is not a boundary interior form");
987 "BasisType is not a boundary interior form");
990 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
991 m_base[2]->GetNumModes()};
995 if (outarray.size() != nIntCoeffs)
1008 for (i = 0; i < 3; i++)
1013 IntIdx[i][1] = nummodes[i];
1018 IntIdx[i][1] = nummodes[i] - 1;
1022 for (r = IntIdx[2][0]; r < IntIdx[2][1]; r++)
1024 for (
q = IntIdx[1][0];
q < IntIdx[1][1];
q++)
1026 for (
p = IntIdx[0][0];
p < IntIdx[0][1];
p++)
1029 r * nummodes[0] * nummodes[1] +
q * nummodes[0] +
p;
1042 "BasisType is not a boundary interior form");
1045 "BasisType is not a boundary interior form");
1048 "BasisType is not a boundary interior form");
1051 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
1052 m_base[2]->GetNumModes()};
1056 if (outarray.size() != nBndCoeffs)
1070 for (i = 0; i < 3; i++)
1078 IntIdx[i][1] = nummodes[i];
1082 BndIdx[i][1] = nummodes[i] - 1;
1084 IntIdx[i][1] = nummodes[i] - 1;
1088 for (i = 0; i < 2; i++)
1091 for (
q = 0;
q < nummodes[1];
q++)
1093 for (
p = 0;
p < nummodes[0];
p++)
1096 r * nummodes[0] * nummodes[1] +
q * nummodes[0] +
p;
1101 for (r = IntIdx[2][0]; r < IntIdx[2][1]; r++)
1103 for (i = 0; i < 2; i++)
1106 for (
p = 0;
p < nummodes[0];
p++)
1109 r * nummodes[0] * nummodes[1] +
q * nummodes[0] +
p;
1113 for (
q = IntIdx[1][0];
q < IntIdx[1][1];
q++)
1115 for (i = 0; i < 2; i++)
1119 r * nummodes[0] * nummodes[1] +
q * nummodes[0] +
p;
1124 sort(outarray.get(), outarray.get() + nBndCoeffs);
1129 std::array<NekDouble, 3> &firstOrderDerivs)
1141 int nummodesA = 0, nummodesB = 0;
1145 "Method only implemented if BasisType is indentical in "
1149 "Method only implemented for Modified_A or "
1150 "GLL_Lagrange BasisType");
1152 const int nummodes0 =
m_base[0]->GetNumModes();
1153 const int nummodes1 =
m_base[1]->GetNumModes();
1154 const int nummodes2 =
m_base[2]->GetNumModes();
1160 nummodesA = nummodes0;
1161 nummodesB = nummodes1;
1165 nummodesA = nummodes0;
1166 nummodesB = nummodes2;
1170 nummodesA = nummodes1;
1171 nummodesB = nummodes2;
1174 ASSERTL0(
false,
"fid must be between 0 and 5");
1177 int nFaceCoeffs = nummodesA * nummodesB;
1179 if (maparray.size() != nFaceCoeffs)
1196 offset = nummodes0 * nummodes1;
1200 offset = (nummodes2 - 1) * nummodes0 * nummodes1;
1218 offset = nummodes0 * (nummodes1 - 1);
1219 jump1 = nummodes0 * nummodes1;
1225 jump1 = nummodes0 * nummodes1;
1236 offset = nummodes0 - 1;
1237 jump1 = nummodes0 * nummodes1;
1244 jump1 = nummodes0 * nummodes1;
1249 ASSERTL0(
false,
"fid must be between 0 and 5");
1252 for (i = 0; i < nummodesB; i++)
1254 for (j = 0; j < nummodesA; j++)
1256 maparray[i * nummodesA + j] = i * jump1 + j * jump2 + offset;
1267 int nummodesA = 0, nummodesB = 0;
1271 "Method only implemented if BasisType is indentical in "
1275 "Method only implemented for Modified_A or "
1276 "GLL_Lagrange BasisType");
1278 const int nummodes0 =
m_base[0]->GetNumModes();
1279 const int nummodes1 =
m_base[1]->GetNumModes();
1280 const int nummodes2 =
m_base[2]->GetNumModes();
1286 nummodesA = nummodes0;
1287 nummodesB = nummodes1;
1291 nummodesA = nummodes0;
1292 nummodesB = nummodes2;
1296 nummodesA = nummodes1;
1297 nummodesB = nummodes2;
1300 ASSERTL0(
false,
"fid must be between 0 and 5");
1312 if (modified ==
false)
1314 ASSERTL1((
P == nummodesA) || (Q == nummodesB),
1315 "Different trace space face dimention "
1316 "and element face dimention not possible for "
1317 "GLL-Lagrange bases");
1320 int nFaceCoeffs =
P * Q;
1322 if (maparray.size() != nFaceCoeffs)
1328 for (i = 0; i < nFaceCoeffs; ++i)
1333 if (signarray.size() != nFaceCoeffs)
1339 fill(signarray.get(), signarray.get() + nFaceCoeffs, 1);
1344 for (i = 0; i < Q; i++)
1346 for (j = 0; j <
P; j++)
1350 arrayindx[i *
P + j] = i *
P + j;
1354 arrayindx[i *
P + j] = j * Q + i;
1361 for (i = 0; i < nummodesB; i++)
1363 for (j = nummodesA; j <
P; j++)
1365 signarray[arrayindx[i *
P + j]] = 0.0;
1366 maparray[arrayindx[i *
P + j]] = maparray[0];
1370 for (i = nummodesB; i < Q; i++)
1372 for (j = 0; j <
P; j++)
1374 signarray[arrayindx[i *
P + j]] = 0.0;
1375 maparray[arrayindx[i *
P + j]] = maparray[0];
1381 for (i = 0; i < Q; i++)
1385 for (j = 0; j <
P; j++)
1387 maparray[arrayindx[i *
P + j]] = i * nummodesA + j;
1391 for (j = nummodesA; j <
P; j++)
1393 signarray[arrayindx[i *
P + j]] = 0.0;
1394 maparray[arrayindx[i *
P + j]] = maparray[0];
1399 for (i = nummodesB; i < Q; i++)
1401 for (j = 0; j <
P; j++)
1403 signarray[arrayindx[i *
P + j]] = 0.0;
1404 maparray[arrayindx[i *
P + j]] = maparray[0];
1418 for (
int i = 3; i < Q; i += 2)
1420 for (
int j = 0; j <
P; j++)
1422 signarray[arrayindx[i *
P + j]] *= -1;
1426 for (
int i = 0; i <
P; i++)
1428 swap(maparray[i], maparray[i +
P]);
1429 swap(signarray[i], signarray[i +
P]);
1434 for (
int i = 0; i <
P; i++)
1436 for (
int j = 0; j < Q / 2; j++)
1438 swap(maparray[i + j *
P],
1439 maparray[i +
P * Q -
P - j *
P]);
1440 swap(signarray[i + j *
P],
1441 signarray[i +
P * Q -
P - j *
P]);
1450 for (
int i = 0; i < Q; i++)
1452 for (
int j = 3; j <
P; j += 2)
1454 signarray[arrayindx[i *
P + j]] *= -1;
1458 for (
int i = 0; i < Q; i++)
1460 swap(maparray[i], maparray[i + Q]);
1461 swap(signarray[i], signarray[i + Q]);
1466 for (
int i = 0; i <
P; i++)
1468 for (
int j = 0; j < Q / 2; j++)
1470 swap(maparray[i * Q + j], maparray[i * Q + Q - 1 - j]);
1471 swap(signarray[i * Q + j],
1472 signarray[i * Q + Q - 1 - j]);
1488 for (i = 0; i < Q; i++)
1490 for (j = 3; j <
P; j += 2)
1492 signarray[arrayindx[i *
P + j]] *= -1;
1496 for (i = 0; i < Q; i++)
1498 swap(maparray[i *
P], maparray[i *
P + 1]);
1499 swap(signarray[i *
P], signarray[i *
P + 1]);
1504 for (i = 0; i < Q; i++)
1506 for (j = 0; j <
P / 2; j++)
1508 swap(maparray[i *
P + j], maparray[i *
P +
P - 1 - j]);
1509 swap(signarray[i *
P + j],
1510 signarray[i *
P +
P - 1 - j]);
1519 for (i = 3; i < Q; i += 2)
1521 for (j = 0; j <
P; j++)
1523 signarray[arrayindx[i *
P + j]] *= -1;
1527 for (i = 0; i <
P; i++)
1529 swap(maparray[i * Q], maparray[i * Q + 1]);
1530 swap(signarray[i * Q], signarray[i * Q + 1]);
1535 for (i = 0; i < Q; i++)
1537 for (j = 0; j <
P / 2; j++)
1539 swap(maparray[i + j * Q],
1540 maparray[i +
P * Q - Q - j * Q]);
1541 swap(signarray[i + j * Q],
1542 signarray[i +
P * Q - Q - j * Q]);
1562 "BasisType is not a boundary interior form");
1565 "BasisType is not a boundary interior form");
1568 "BasisType is not a boundary interior form");
1571 "local edge id must be between 0 and 11");
1575 if (maparray.size() != nEdgeIntCoeffs)
1580 if (signarray.size() != nEdgeIntCoeffs)
1586 fill(signarray.get(), signarray.get() + nEdgeIntCoeffs, 1);
1589 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
1590 m_base[2]->GetNumModes()};
1595 bool reverseOrdering =
false;
1596 bool signChange =
false;
1598 int IdxRange[3][2] = {{0, 0}, {0, 0}, {0, 0}};
1618 IdxRange[2][0] = nummodes[2] - 1;
1619 IdxRange[2][1] = nummodes[2];
1636 IdxRange[2][1] = nummodes[2] - 1;
1640 reverseOrdering =
true;
1646 IdxRange[2][1] = nummodes[2];
1675 IdxRange[1][0] = nummodes[1] - 1;
1676 IdxRange[1][1] = nummodes[1];
1691 IdxRange[1][1] = nummodes[1] - 1;
1695 reverseOrdering =
true;
1701 IdxRange[1][1] = nummodes[1];
1716 IdxRange[1][1] = nummodes[1] - 1;
1720 reverseOrdering =
true;
1726 IdxRange[1][1] = nummodes[1];
1755 IdxRange[0][0] = nummodes[0] - 1;
1756 IdxRange[0][1] = nummodes[0];
1771 IdxRange[0][1] = nummodes[0] - 1;
1775 reverseOrdering =
true;
1781 IdxRange[0][1] = nummodes[0];
1796 IdxRange[0][1] = nummodes[0] - 1;
1800 reverseOrdering =
true;
1806 IdxRange[0][1] = nummodes[0];
1819 for (
int r = IdxRange[2][0]; r < IdxRange[2][1]; r++)
1821 for (
int q = IdxRange[1][0];
q < IdxRange[1][1];
q++)
1823 for (
int p = IdxRange[0][0];
p < IdxRange[0][1];
p++)
1826 r * nummodes[0] * nummodes[1] +
q * nummodes[0] +
p;
1831 if (reverseOrdering)
1833 reverse(maparray.get(), maparray.get() + nEdgeIntCoeffs);
1838 for (
int p = 1;
p < nEdgeIntCoeffs;
p += 2)
1855 "BasisType is not a boundary interior form");
1858 "BasisType is not a boundary interior form");
1861 "BasisType is not a boundary interior form");
1863 ASSERTL1((fid >= 0) && (fid < 6),
"local face id must be between 0 and 5");
1867 if (maparray.size() != nFaceIntCoeffs)
1872 if (signarray.size() != nFaceIntCoeffs)
1878 fill(signarray.get(), signarray.get() + nFaceIntCoeffs, 1);
1881 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
1882 m_base[2]->GetNumModes()};
1897 nummodesA = nummodes[0];
1898 nummodesB = nummodes[1];
1904 nummodesA = nummodes[0];
1905 nummodesB = nummodes[2];
1911 nummodesA = nummodes[1];
1912 nummodesB = nummodes[2];
1920 for (
int i = 0; i < (nummodesB - 2); i++)
1922 for (
int j = 0; j < (nummodesA - 2); j++)
1926 arrayindx[i * (nummodesA - 2) + j] = i * (nummodesA - 2) + j;
1930 arrayindx[i * (nummodesA - 2) + j] = j * (nummodesB - 2) + i;
1957 IdxRange[2][0] = nummodes[2] - 1;
1958 IdxRange[2][1] = nummodes[2];
1975 IdxRange[2][0] = nummodes[2] - 2;
1982 IdxRange[2][1] = nummodes[2] - 1;
1989 IdxRange[2][1] = nummodes[2];
1994 for (
int i = 3; i < nummodes[2]; i += 2)
2018 IdxRange[1][0] = nummodes[1] - 1;
2019 IdxRange[1][1] = nummodes[1];
2037 IdxRange[1][0] = nummodes[1] - 2;
2044 IdxRange[1][1] = nummodes[1] - 1;
2051 IdxRange[1][1] = nummodes[1];
2056 for (
int i = 3; i < nummodes[1]; i += 2)
2070 IdxRange[1][0] = nummodes[1] - 2;
2077 IdxRange[1][1] = nummodes[1] - 1;
2084 IdxRange[1][1] = nummodes[1];
2089 for (
int i = 3; i < nummodes[1]; i += 2)
2111 IdxRange[0][0] = nummodes[0] - 1;
2112 IdxRange[0][1] = nummodes[0];
2129 IdxRange[0][0] = nummodes[0] - 2;
2136 IdxRange[0][1] = nummodes[0] - 1;
2143 IdxRange[0][1] = nummodes[0];
2148 for (
int i = 3; i < nummodes[0]; i += 2)
2159 for (
int r = IdxRange[2][0]; r != IdxRange[2][1]; r += Incr[2])
2161 for (
int q = IdxRange[1][0];
q != IdxRange[1][1];
q += Incr[1])
2163 for (
int p = IdxRange[0][0];
p != IdxRange[0][1];
p += Incr[0])
2165 maparray[arrayindx[cnt]] =
2166 r * nummodes[0] * nummodes[1] +
q * nummodes[0] +
p;
2167 signarray[arrayindx[cnt++]] = sign0[
p] * sign1[
q] * sign2[r];
2175 ASSERTL2((i >= 0) && (i <= 11),
"edge id is out of range");
2177 if ((i == 0) || (i == 2) || (i == 8) || (i == 10))
2181 else if ((i == 1) || (i == 3) || (i == 9) || (i == 11))
2202 int nq0 =
m_base[0]->GetNumPoints();
2203 int nq1 =
m_base[1]->GetNumPoints();
2204 int nq2 =
m_base[2]->GetNumPoints();
2214 nq = max(nq0, max(nq1, nq2));
2228 for (
int i = 0; i < nq; ++i)
2230 for (
int j = 0; j < nq; ++j)
2232 for (
int k = 0; k < nq; ++k, ++cnt)
2235 coords[cnt][0] = -1.0 + 2 * k / (
NekDouble)(nq - 1);
2236 coords[cnt][1] = -1.0 + 2 * j / (
NekDouble)(nq - 1);
2237 coords[cnt][2] = -1.0 + 2 * i / (
NekDouble)(nq - 1);
2242 for (
int i = 0; i < neq; ++i)
2246 I[0] =
m_base[0]->GetI(coll);
2247 I[1] =
m_base[1]->GetI(coll + 1);
2248 I[2] =
m_base[2]->GetI(coll + 2);
2252 for (
int k = 0; k < nq2; ++k)
2254 for (
int j = 0; j < nq1; ++j)
2257 fac = (I[1]->GetPtr())[j] * (I[2]->GetPtr())[k];
2261 Mat->GetRawPtr() + k * nq0 * nq1 * neq +
2325 int nquad0 =
m_base[0]->GetNumPoints();
2326 int nquad1 =
m_base[1]->GetNumPoints();
2327 int nquad2 =
m_base[2]->GetNumPoints();
2328 int nq01 = nquad0 * nquad1;
2329 int nq12 = nquad1 * nquad2;
2335 for (
int i = 0; i < nq12; ++i)
2337 Vmath::Vmul(nquad0, inarray.get() + i * nquad0, 1, w0.get(), 1,
2338 outarray.get() + i * nquad0, 1);
2341 for (
int i = 0; i < nq12; ++i)
2343 Vmath::Smul(nquad0, w1[i % nquad1], outarray.get() + i * nquad0, 1,
2344 outarray.get() + i * nquad0, 1);
2347 for (
int i = 0; i < nquad2; ++i)
2349 Vmath::Smul(nq01, w2[i], outarray.get() + i * nq01, 1,
2350 outarray.get() + i * nq01, 1);
2358 int qa =
m_base[0]->GetNumPoints();
2359 int qb =
m_base[1]->GetNumPoints();
2360 int qc =
m_base[2]->GetNumPoints();
2361 int nmodes_a =
m_base[0]->GetNumModes();
2362 int nmodes_b =
m_base[1]->GetNumModes();
2363 int nmodes_c =
m_base[2]->GetNumModes();
2378 OrthoExp.
FwdTrans(array, orthocoeffs);
2388 for (
int i = 0; i < nmodes_a; ++i)
2390 for (
int j = 0; j < nmodes_b; ++j)
2393 pow((1.0 * i) / (nmodes_a - 1), cutoff * nmodes_a),
2394 pow((1.0 * j) / (nmodes_b - 1), cutoff * nmodes_b));
2396 for (
int k = 0; k < nmodes_c; ++k)
2399 std::max(fac1, pow((1.0 * k) / (nmodes_c - 1),
2400 cutoff * nmodes_c));
2402 orthocoeffs[cnt] *= SvvDiffCoeff * fac;
2418 max_abc = max(max_abc, 0);
2421 for (
int i = 0; i < nmodes_a; ++i)
2423 for (
int j = 0; j < nmodes_b; ++j)
2425 int maxij = max(i, j);
2427 for (
int k = 0; k < nmodes_c; ++k)
2429 int maxijk = max(maxij, k);
2443 min(nmodes_a, nmodes_b));
2446 int nmodes = max(nmodes_a, nmodes_b);
2447 nmodes = max(nmodes, nmodes_c);
2450 for (
int j = cutoff; j < nmodes; ++j)
2452 fac[j] = fabs((j - nmodes) / ((
NekDouble)(j - cutoff + 1.0)));
2456 for (
int i = 0; i < nmodes_a; ++i)
2458 for (
int j = 0; j < nmodes_b; ++j)
2460 for (
int k = 0; k < nmodes_c; ++k)
2462 if ((i >= cutoff) || (j >= cutoff) || (k >= cutoff))
2464 orthocoeffs[i * nmodes_a * nmodes_b + j * nmodes_c +
2466 (SvvDiffCoeff * exp(-(fac[i] + fac[j] + fac[k])));
2470 orthocoeffs[i * nmodes_a * nmodes_b + j * nmodes_c +
2479 OrthoExp.
BwdTrans(orthocoeffs, array);
2488 int qa =
m_base[0]->GetNumPoints();
2489 int qb =
m_base[1]->GetNumPoints();
2490 int qc =
m_base[2]->GetNumPoints();
2491 int nmodesA =
m_base[0]->GetNumModes();
2492 int nmodesB =
m_base[1]->GetNumModes();
2493 int nmodesC =
m_base[2]->GetNumModes();
2494 int P = nmodesA - 1;
2495 int Q = nmodesB - 1;
2496 int R = nmodesC - 1;
2509 int Pcut = cutoff *
P;
2510 int Qcut = cutoff * Q;
2511 int Rcut = cutoff * R;
2515 OrthoExp.
FwdTrans(array, orthocoeffs);
2520 for (
int i = 0; i < nmodesA; ++i)
2522 for (
int j = 0; j < nmodesB; ++j)
2524 for (
int k = 0; k < nmodesC; ++k, ++index)
2527 if (i > Pcut || j > Qcut || k > Rcut)
2532 fac = max(max(fac1, fac2), fac3);
2533 fac = pow(fac, exponent);
2534 orthocoeffs[index] *= exp(-alpha * fac);
2541 OrthoExp.
BwdTrans(orthocoeffs, array);
2547 boost::ignore_unused(standard);
2549 int np0 =
m_base[0]->GetNumPoints();
2550 int np1 =
m_base[1]->GetNumPoints();
2551 int np2 =
m_base[2]->GetNumPoints();
2552 int np = max(np0, max(np1, np2));
2560 for (
int i = 0; i < np - 1; ++i)
2562 for (
int j = 0; j < np - 1; ++j)
2565 for (
int k = 0; k < np - 1; ++k)
2567 conn[cnt++] = plane + row + k;
2568 conn[cnt++] = plane + row + k + 1;
2569 conn[cnt++] = plane + rowp1 + k;
2571 conn[cnt++] = plane + rowp1 + k + 1;
2572 conn[cnt++] = plane + rowp1 + k;
2573 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.
virtual void v_HelmholtzMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey) override
NekDouble BaryTensorDeriv(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs)
virtual void v_LaplacianMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey) override
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.
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.
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.
virtual int v_NumDGBndryCoeffs() const override
virtual ~StdHexExp() 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
virtual int v_GetVertexMap(int localVertexId, bool useCoeffPacking=false) override
virtual void v_LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta) override
virtual int v_CalcNumberOfCoefficients(const std::vector< unsigned int > &nummodes, int &modes_offset) override
virtual LibUtilities::PointsKey v_GetTracePointsKey(const int i, const int j) const override
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
virtual DNekMatSharedPtr v_CreateStdMatrix(const StdMatrixKey &mkey) override
virtual NekDouble v_PhysEvaluate(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs) override
virtual 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
virtual int v_GetTraceNumPoints(const int i) const override
virtual const LibUtilities::BasisKey v_GetTraceBasisKey(const int i, const int k) const override
virtual void v_GetTraceCoeffMap(const unsigned int fid, Array< OneD, unsigned int > &maparray) override
virtual LibUtilities::ShapeType v_DetShapeType() const override
virtual void v_GetTraceNumModes(const int fid, int &numModes0, int &numModes1, Orientation faceOrient=eDir1FwdDir1_Dir2FwdDir2) override
virtual 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
virtual int v_NumBndryCoeffs() const override
virtual int v_GetNedges() const override
void v_FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
virtual int v_GetNtraces() const override
NekDouble v_PhysEvaluateBasis(const Array< OneD, const NekDouble > &coords, int mode) final override
void v_HelmholtzMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey) override
virtual int v_GetNverts() const override
virtual bool v_IsBoundaryInteriorExpansion() const override
virtual void v_GetInteriorMap(Array< OneD, unsigned int > &outarray) override
virtual void v_GetBoundaryMap(Array< OneD, unsigned int > &outarray) override
virtual void v_FillMode(const int mode, Array< OneD, NekDouble > &outarray) override
virtual 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
virtual int v_GetTraceIntNcoeffs(const int i) const 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
void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
virtual 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
virtual 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
virtual void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdMatrixKey &mkey) override
virtual void v_GetCoords(Array< OneD, NekDouble > &coords_x, Array< OneD, NekDouble > &coords_y, Array< OneD, NekDouble > &coords_z) override
virtual 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
virtual 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
@ eFactorSVVDGKerDiffCoeff
@ eFactorSVVPowerKerDiffCoeff
const int kSVVDGFiltermodesmin
const int kSVVDGFiltermodesmax
LibUtilities::BasisKey EvaluateQuadFaceBasisKey(const int facedir, const LibUtilities::BasisType faceDirBasisType, const int numpoints, const int nummodes)
const NekDouble kSVVDGFilter[9][11]
@ ePhysInterpToEquiSpaced
@ eDir1BwdDir2_Dir2BwdDir1
@ eDir1FwdDir1_Dir2FwdDir2
@ eDir1BwdDir1_Dir2BwdDir2
@ eDir1BwdDir2_Dir2FwdDir1
@ eDir1FwdDir1_Dir2BwdDir2
@ eDir1BwdDir1_Dir2FwdDir2
@ eDir1FwdDir2_Dir2FwdDir1
@ eDir1FwdDir2_Dir2BwdDir1
std::vector< double > q(NPUPPER *NPUPPER)
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 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)