48 StdHexExp::StdHexExp()
55 :
StdExpansion(Ba.GetNumModes() * Bb.GetNumModes() * Bc.GetNumModes(), 3,
57 StdExpansion3D(Ba.GetNumModes() * Bb.GetNumModes() * Bc.GetNumModes(), Ba,
127 ASSERTL1(
false,
"input dir is out of range");
173 "Basis[1] is not a general tensor type");
177 "Basis[2] is not a general tensor type");
179 if (
m_base[0]->Collocation() &&
m_base[1]->Collocation() &&
184 inarray, 1, outarray, 1);
203 m_base[2]->GetBdata(), inarray, outarray, wsp,
true,
226 bool doCheckCollDir0,
bool doCheckCollDir1,
bool doCheckCollDir2)
228 int nquad0 =
m_base[0]->GetNumPoints();
229 int nquad1 =
m_base[1]->GetNumPoints();
230 int nquad2 =
m_base[2]->GetNumPoints();
231 int nmodes0 =
m_base[0]->GetNumModes();
232 int nmodes1 =
m_base[1]->GetNumModes();
233 int nmodes2 =
m_base[2]->GetNumModes();
236 bool colldir0 = doCheckCollDir0 ? (
m_base[0]->Collocation()) :
false;
237 bool colldir1 = doCheckCollDir1 ? (
m_base[1]->Collocation()) :
false;
238 bool colldir2 = doCheckCollDir2 ? (
m_base[2]->Collocation()) :
false;
242 if (colldir0 && colldir1 && colldir2)
249 ASSERTL1(wsp.size() >= nquad0 * nmodes2 * (nmodes1 + nquad1),
250 "Workspace size is not sufficient");
256 Blas::Dgemm(
'T',
'T', nmodes1 * nmodes2, nquad0, nmodes0, 1.0,
257 &inarray[0], nmodes0, base0.get(), nquad0, 0.0, &wsp[0],
259 Blas::Dgemm(
'T',
'T', nquad0 * nmodes2, nquad1, nmodes1, 1.0, &wsp[0],
260 nmodes1, base1.get(), nquad1, 0.0, &wsp2[0],
262 Blas::Dgemm(
'T',
'T', nquad0 * nquad1, nquad2, nmodes2, 1.0, &wsp2[0],
263 nmodes2, base2.get(), nquad2, 0.0, &outarray[0],
282 if ((
m_base[0]->Collocation()) && (
m_base[1]->Collocation()) &&
283 (
m_base[2]->Collocation()))
301 out = (*matsys) * in;
338 if (
m_base[0]->Collocation() &&
m_base[1]->Collocation() &&
361 inarray.get(), 1, 0.0, outarray.get(), 1);
371 int nquad0 =
m_base[0]->GetNumPoints();
372 int nquad1 =
m_base[1]->GetNumPoints();
373 int nquad2 =
m_base[2]->GetNumPoints();
374 int order0 =
m_base[0]->GetNumModes();
375 int order1 =
m_base[1]->GetNumModes();
378 order0 * order1 * nquad2);
380 if (multiplybyweights)
387 tmp, outarray, wsp,
true,
true,
true);
393 inarray, outarray, wsp,
true,
true,
true);
407 bool doCheckCollDir0,
bool doCheckCollDir1,
bool doCheckCollDir2)
409 int nquad0 =
m_base[0]->GetNumPoints();
410 int nquad1 =
m_base[1]->GetNumPoints();
411 int nquad2 =
m_base[2]->GetNumPoints();
412 int nmodes0 =
m_base[0]->GetNumModes();
413 int nmodes1 =
m_base[1]->GetNumModes();
414 int nmodes2 =
m_base[2]->GetNumModes();
416 bool colldir0 = doCheckCollDir0 ? (
m_base[0]->Collocation()) :
false;
417 bool colldir1 = doCheckCollDir1 ? (
m_base[1]->Collocation()) :
false;
418 bool colldir2 = doCheckCollDir2 ? (
m_base[2]->Collocation()) :
false;
420 if (colldir0 && colldir1 && colldir2)
426 ASSERTL1(wsp.size() >= nmodes0 * nquad2 * (nquad1 + nmodes1),
427 "Insufficient workspace size");
435 for (
int n = 0; n < nmodes0; ++n)
437 Vmath::Vcopy(nquad1 * nquad2, inarray.get() + n, nquad0,
438 tmp0.get() + nquad1 * nquad2 * n, 1);
443 Blas::Dgemm(
'T',
'N', nquad1 * nquad2, nmodes0, nquad0, 1.0,
444 inarray.get(), nquad0, base0.get(), nquad0, 0.0,
445 tmp0.get(), nquad1 * nquad2);
451 for (
int n = 0; n < nmodes1; ++n)
454 tmp1.get() + nquad2 * nmodes0 * n, 1);
459 Blas::Dgemm(
'T',
'N', nquad2 * nmodes0, nmodes1, nquad1, 1.0,
460 tmp0.get(), nquad1, base1.get(), nquad1, 0.0,
461 tmp1.get(), nquad2 * nmodes0);
467 for (
int n = 0; n < nmodes2; ++n)
470 outarray.get() + nmodes0 * nmodes1 * n, 1);
475 Blas::Dgemm(
'T',
'N', nmodes0 * nmodes1, nmodes2, nquad2, 1.0,
476 tmp1.get(), nquad2, base2.get(), nquad2, 0.0,
477 outarray.get(), nmodes0 * nmodes1);
493 ASSERTL0((dir == 0) || (dir == 1) || (dir == 2),
494 "input dir is out of range");
516 inarray.get(), 1, 0.0, outarray.get(), 1);
523 ASSERTL0((dir == 0) || (dir == 1) || (dir == 2),
524 "input dir is out of range");
526 int nquad1 =
m_base[1]->GetNumPoints();
527 int nquad2 =
m_base[2]->GetNumPoints();
528 int order0 =
m_base[0]->GetNumModes();
529 int order1 =
m_base[1]->GetNumModes();
533 if (outarray.size() < inarray.size())
550 m_base[2]->GetBdata(), tmp, outarray, wsp,
false,
true,
true);
555 m_base[2]->GetBdata(), tmp, outarray, wsp,
true,
false,
true);
560 m_base[2]->GetDbdata(), tmp, outarray, wsp,
true,
true,
false);
586 int nquad0 =
m_base[0]->GetNumPoints();
587 int nquad1 =
m_base[1]->GetNumPoints();
588 int nquad2 =
m_base[2]->GetNumPoints();
594 int btmp0 =
m_base[0]->GetNumModes();
595 int btmp1 =
m_base[1]->GetNumModes();
596 int mode2 = mode / (btmp0 * btmp1);
597 int mode1 = (mode - mode2 * btmp0 * btmp1) / btmp0;
598 int mode0 = (mode - mode2 * btmp0 * btmp1) % btmp0;
600 ASSERTL2(mode == mode2 * btmp0 * btmp1 + mode1 * btmp0 + mode0,
601 "Mode lookup failed.");
603 "Calling argument mode is larger than total expansion "
606 for (
int i = 0; i < nquad1 * nquad2; ++i)
609 &outarray[0] + i * nquad0, 1);
612 for (
int j = 0; j < nquad2; ++j)
614 for (
int i = 0; i < nquad0; ++i)
617 &outarray[0] + i + j * nquad0 * nquad1, nquad0,
618 &outarray[0] + i + j * nquad0 * nquad1, nquad0);
622 for (
int i = 0; i < nquad2; i++)
624 Blas::Dscal(nquad0 * nquad1, base2[mode2 * nquad2 + i],
625 &outarray[0] + i * nquad0 * nquad1, 1);
639 const int nm0 =
m_base[0]->GetNumModes();
640 const int nm1 =
m_base[1]->GetNumModes();
641 const int mode2 = mode / (nm0 * nm1);
642 const int mode1 = (mode - mode2 * nm0 * nm1) / nm0;
643 const int mode0 = (mode - mode2 * nm0 * nm1) % nm0;
645 return StdExpansion::BaryEvaluateBasis<0>(coords[0], mode0) *
646 StdExpansion::BaryEvaluateBasis<1>(coords[1], mode1) *
647 StdExpansion::BaryEvaluateBasis<2>(coords[2], mode2);
674 "BasisType is not a boundary interior form");
677 "BasisType is not a boundary interior form");
680 "BasisType is not a boundary interior form");
682 int nmodes0 =
m_base[0]->GetNumModes();
683 int nmodes1 =
m_base[1]->GetNumModes();
684 int nmodes2 =
m_base[2]->GetNumModes();
686 return (2 * (nmodes0 * nmodes1 + nmodes0 * nmodes2 + nmodes1 * nmodes2) -
687 4 * (nmodes0 + nmodes1 + nmodes2) + 8);
694 "BasisType is not a boundary interior form");
697 "BasisType is not a boundary interior form");
700 "BasisType is not a boundary interior form");
702 int nmodes0 =
m_base[0]->GetNumModes();
703 int nmodes1 =
m_base[1]->GetNumModes();
704 int nmodes2 =
m_base[2]->GetNumModes();
706 return 2 * (nmodes0 * nmodes1 + nmodes0 * nmodes2 + nmodes1 * nmodes2);
711 ASSERTL2((i >= 0) && (i <= 5),
"face id is out of range");
712 if ((i == 0) || (i == 5))
716 else if ((i == 1) || (i == 3))
728 ASSERTL2((i >= 0) && (i <= 5),
"face id is out of range");
729 if ((i == 0) || (i == 5))
733 else if ((i == 1) || (i == 3))
752 ASSERTL2(i >= 0 && i <= 5,
"face id is out of range");
754 if (i == 0 || i == 5)
756 return m_base[0]->GetNumPoints() *
m_base[1]->GetNumPoints();
758 else if (i == 1 || i == 3)
760 return m_base[0]->GetNumPoints() *
m_base[2]->GetNumPoints();
764 return m_base[1]->GetNumPoints() *
m_base[2]->GetNumPoints();
771 ASSERTL2(i >= 0 && i <= 5,
"face id is out of range");
772 ASSERTL2(j == 0 || j == 1,
"face direction is out of range");
774 if (i == 0 || i == 5)
776 return m_base[j]->GetPointsKey();
778 else if (i == 1 || i == 3)
780 return m_base[2 * j]->GetPointsKey();
784 return m_base[j + 1]->GetPointsKey();
789 const std::vector<unsigned int> &nummodes,
int &modes_offset)
791 int nmodes = nummodes[modes_offset] * nummodes[modes_offset + 1] *
792 nummodes[modes_offset + 2];
801 ASSERTL2(i >= 0 && i <= 5,
"face id is out of range");
802 ASSERTL2(k >= 0 && k <= 1,
"basis key id is out of range");
823 m_base[dir]->GetNumModes());
839 for (
int k = 0; k < Qz; ++k)
841 for (
int j = 0; j < Qy; ++j)
843 for (
int i = 0; i < Qx; ++i)
845 int s = i + Qx * (j + Qy * k);
857 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
858 m_base[2]->GetNumModes()};
864 numModes0 = nummodes[0];
865 numModes1 = nummodes[1];
871 numModes0 = nummodes[0];
872 numModes1 = nummodes[2];
878 numModes0 = nummodes[1];
879 numModes1 = nummodes[2];
884 ASSERTL0(
false,
"fid out of range");
891 std::swap(numModes0, numModes1);
906 "BasisType is not a boundary interior form");
909 "BasisType is not a boundary interior form");
912 "BasisType is not a boundary interior form");
914 ASSERTL1((localVertexId >= 0) && (localVertexId < 8),
915 "local vertex id must be between 0 and 7");
922 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
923 m_base[2]->GetNumModes()};
925 if (useCoeffPacking ==
true)
927 if (localVertexId > 3)
939 switch (localVertexId % 4)
986 if ((localVertexId % 4) % 3 > 0)
998 if (localVertexId % 4 > 1)
1002 q = nummodes[1] - 1;
1011 if (localVertexId > 3)
1015 r = nummodes[2] - 1;
1024 return r * nummodes[0] * nummodes[1] + q * nummodes[0] +
p;
1034 "BasisType is not a boundary interior form");
1037 "BasisType is not a boundary interior form");
1040 "BasisType is not a boundary interior form");
1043 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
1044 m_base[2]->GetNumModes()};
1048 if (outarray.size() != nIntCoeffs)
1061 for (i = 0; i < 3; i++)
1066 IntIdx[i][1] = nummodes[i];
1071 IntIdx[i][1] = nummodes[i] - 1;
1075 for (r = IntIdx[2][0]; r < IntIdx[2][1]; r++)
1077 for (q = IntIdx[1][0]; q < IntIdx[1][1]; q++)
1079 for (
p = IntIdx[0][0];
p < IntIdx[0][1];
p++)
1082 r * nummodes[0] * nummodes[1] + q * nummodes[0] +
p;
1095 "BasisType is not a boundary interior form");
1098 "BasisType is not a boundary interior form");
1101 "BasisType is not a boundary interior form");
1104 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
1105 m_base[2]->GetNumModes()};
1109 if (outarray.size() != nBndCoeffs)
1123 for (i = 0; i < 3; i++)
1131 IntIdx[i][1] = nummodes[i];
1135 BndIdx[i][1] = nummodes[i] - 1;
1137 IntIdx[i][1] = nummodes[i] - 1;
1141 for (i = 0; i < 2; i++)
1144 for (q = 0; q < nummodes[1]; q++)
1146 for (
p = 0;
p < nummodes[0];
p++)
1149 r * nummodes[0] * nummodes[1] + q * nummodes[0] +
p;
1154 for (r = IntIdx[2][0]; r < IntIdx[2][1]; r++)
1156 for (i = 0; i < 2; i++)
1159 for (
p = 0;
p < nummodes[0];
p++)
1162 r * nummodes[0] * nummodes[1] + q * nummodes[0] +
p;
1166 for (q = IntIdx[1][0]; q < IntIdx[1][1]; q++)
1168 for (i = 0; i < 2; i++)
1172 r * nummodes[0] * nummodes[1] + q * nummodes[0] +
p;
1177 sort(outarray.get(), outarray.get() + nBndCoeffs);
1187 int nummodesA = 0, nummodesB = 0;
1191 "Method only implemented if BasisType is indentical in "
1195 "Method only implemented for Modified_A or "
1196 "GLL_Lagrange BasisType");
1198 const int nummodes0 =
m_base[0]->GetNumModes();
1199 const int nummodes1 =
m_base[1]->GetNumModes();
1200 const int nummodes2 =
m_base[2]->GetNumModes();
1206 nummodesA = nummodes0;
1207 nummodesB = nummodes1;
1211 nummodesA = nummodes0;
1212 nummodesB = nummodes2;
1216 nummodesA = nummodes1;
1217 nummodesB = nummodes2;
1220 ASSERTL0(
false,
"fid must be between 0 and 5");
1223 int nFaceCoeffs = nummodesA * nummodesB;
1225 if (maparray.size() != nFaceCoeffs)
1242 offset = nummodes0 * nummodes1;
1246 offset = (nummodes2 - 1) * nummodes0 * nummodes1;
1264 offset = nummodes0 * (nummodes1 - 1);
1265 jump1 = nummodes0 * nummodes1;
1271 jump1 = nummodes0 * nummodes1;
1282 offset = nummodes0 - 1;
1283 jump1 = nummodes0 * nummodes1;
1290 jump1 = nummodes0 * nummodes1;
1295 ASSERTL0(
false,
"fid must be between 0 and 5");
1298 for (i = 0; i < nummodesB; i++)
1300 for (j = 0; j < nummodesA; j++)
1302 maparray[i * nummodesA + j] = i * jump1 + j * jump2 + offset;
1313 int nummodesA = 0, nummodesB = 0;
1317 "Method only implemented if BasisType is indentical in "
1321 "Method only implemented for Modified_A or "
1322 "GLL_Lagrange BasisType");
1324 const int nummodes0 =
m_base[0]->GetNumModes();
1325 const int nummodes1 =
m_base[1]->GetNumModes();
1326 const int nummodes2 =
m_base[2]->GetNumModes();
1332 nummodesA = nummodes0;
1333 nummodesB = nummodes1;
1337 nummodesA = nummodes0;
1338 nummodesB = nummodes2;
1342 nummodesA = nummodes1;
1343 nummodesB = nummodes2;
1346 ASSERTL0(
false,
"fid must be between 0 and 5");
1358 if (modified ==
false)
1360 ASSERTL1((
P == nummodesA) || (Q == nummodesB),
1361 "Different trace space face dimention "
1362 "and element face dimention not possible for "
1363 "GLL-Lagrange bases");
1366 int nFaceCoeffs =
P * Q;
1368 if (maparray.size() != nFaceCoeffs)
1374 for (i = 0; i < nFaceCoeffs; ++i)
1379 if (signarray.size() != nFaceCoeffs)
1385 fill(signarray.get(), signarray.get() + nFaceCoeffs, 1);
1390 for (i = 0; i < Q; i++)
1392 for (j = 0; j <
P; j++)
1396 arrayindx[i *
P + j] = i *
P + j;
1400 arrayindx[i *
P + j] = j * Q + i;
1407 for (i = 0; i < nummodesB; i++)
1409 for (j = nummodesA; j <
P; j++)
1411 signarray[arrayindx[i *
P + j]] = 0.0;
1412 maparray[arrayindx[i *
P + j]] = maparray[0];
1416 for (i = nummodesB; i < Q; i++)
1418 for (j = 0; j <
P; j++)
1420 signarray[arrayindx[i *
P + j]] = 0.0;
1421 maparray[arrayindx[i *
P + j]] = maparray[0];
1427 for (i = 0; i < Q; i++)
1431 for (j = 0; j <
P; j++)
1433 maparray[arrayindx[i *
P + j]] = i * nummodesA + j;
1437 for (j = nummodesA; j <
P; j++)
1439 signarray[arrayindx[i *
P + j]] = 0.0;
1440 maparray[arrayindx[i *
P + j]] = maparray[0];
1445 for (i = nummodesB; i < Q; i++)
1447 for (j = 0; j <
P; j++)
1449 signarray[arrayindx[i *
P + j]] = 0.0;
1450 maparray[arrayindx[i *
P + j]] = maparray[0];
1464 for (
int i = 3; i < Q; i += 2)
1466 for (
int j = 0; j <
P; j++)
1468 signarray[arrayindx[i *
P + j]] *= -1;
1472 for (
int i = 0; i <
P; i++)
1474 swap(maparray[i], maparray[i +
P]);
1475 swap(signarray[i], signarray[i +
P]);
1480 for (
int i = 0; i <
P; i++)
1482 for (
int j = 0; j < Q / 2; j++)
1484 swap(maparray[i + j *
P],
1485 maparray[i +
P * Q -
P - j *
P]);
1486 swap(signarray[i + j *
P],
1487 signarray[i +
P * Q -
P - j *
P]);
1496 for (
int i = 0; i < Q; i++)
1498 for (
int j = 3; j <
P; j += 2)
1500 signarray[arrayindx[i *
P + j]] *= -1;
1504 for (
int i = 0; i < Q; i++)
1506 swap(maparray[i], maparray[i + Q]);
1507 swap(signarray[i], signarray[i + Q]);
1512 for (
int i = 0; i <
P; i++)
1514 for (
int j = 0; j < Q / 2; j++)
1516 swap(maparray[i * Q + j], maparray[i * Q + Q - 1 - j]);
1517 swap(signarray[i * Q + j],
1518 signarray[i * Q + Q - 1 - j]);
1534 for (i = 0; i < Q; i++)
1536 for (j = 3; j <
P; j += 2)
1538 signarray[arrayindx[i *
P + j]] *= -1;
1542 for (i = 0; i < Q; i++)
1544 swap(maparray[i *
P], maparray[i *
P + 1]);
1545 swap(signarray[i *
P], signarray[i *
P + 1]);
1550 for (i = 0; i < Q; i++)
1552 for (j = 0; j <
P / 2; j++)
1554 swap(maparray[i *
P + j], maparray[i *
P +
P - 1 - j]);
1555 swap(signarray[i *
P + j],
1556 signarray[i *
P +
P - 1 - j]);
1565 for (i = 3; i < Q; i += 2)
1567 for (j = 0; j <
P; j++)
1569 signarray[arrayindx[i *
P + j]] *= -1;
1573 for (i = 0; i <
P; i++)
1575 swap(maparray[i * Q], maparray[i * Q + 1]);
1576 swap(signarray[i * Q], signarray[i * Q + 1]);
1581 for (i = 0; i < Q; i++)
1583 for (j = 0; j <
P / 2; j++)
1585 swap(maparray[i + j * Q],
1586 maparray[i +
P * Q - Q - j * Q]);
1587 swap(signarray[i + j * Q],
1588 signarray[i +
P * Q - Q - j * Q]);
1608 "BasisType is not a boundary interior form");
1611 "BasisType is not a boundary interior form");
1614 "BasisType is not a boundary interior form");
1617 "local edge id must be between 0 and 11");
1621 if (maparray.size() != nEdgeIntCoeffs)
1626 if (signarray.size() != nEdgeIntCoeffs)
1632 fill(signarray.get(), signarray.get() + nEdgeIntCoeffs, 1);
1635 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
1636 m_base[2]->GetNumModes()};
1641 bool reverseOrdering =
false;
1642 bool signChange =
false;
1644 int IdxRange[3][2] = {{0, 0}, {0, 0}, {0, 0}};
1664 IdxRange[2][0] = nummodes[2] - 1;
1665 IdxRange[2][1] = nummodes[2];
1682 IdxRange[2][1] = nummodes[2] - 1;
1686 reverseOrdering =
true;
1692 IdxRange[2][1] = nummodes[2];
1721 IdxRange[1][0] = nummodes[1] - 1;
1722 IdxRange[1][1] = nummodes[1];
1737 IdxRange[1][1] = nummodes[1] - 1;
1741 reverseOrdering =
true;
1747 IdxRange[1][1] = nummodes[1];
1762 IdxRange[1][1] = nummodes[1] - 1;
1766 reverseOrdering =
true;
1772 IdxRange[1][1] = nummodes[1];
1801 IdxRange[0][0] = nummodes[0] - 1;
1802 IdxRange[0][1] = nummodes[0];
1817 IdxRange[0][1] = nummodes[0] - 1;
1821 reverseOrdering =
true;
1827 IdxRange[0][1] = nummodes[0];
1842 IdxRange[0][1] = nummodes[0] - 1;
1846 reverseOrdering =
true;
1852 IdxRange[0][1] = nummodes[0];
1865 for (
int r = IdxRange[2][0]; r < IdxRange[2][1]; r++)
1867 for (
int q = IdxRange[1][0]; q < IdxRange[1][1]; q++)
1869 for (
int p = IdxRange[0][0];
p < IdxRange[0][1];
p++)
1872 r * nummodes[0] * nummodes[1] + q * nummodes[0] +
p;
1877 if (reverseOrdering)
1879 reverse(maparray.get(), maparray.get() + nEdgeIntCoeffs);
1884 for (
int p = 1;
p < nEdgeIntCoeffs;
p += 2)
1901 "BasisType is not a boundary interior form");
1904 "BasisType is not a boundary interior form");
1907 "BasisType is not a boundary interior form");
1909 ASSERTL1((fid >= 0) && (fid < 6),
"local face id must be between 0 and 5");
1913 if (maparray.size() != nFaceIntCoeffs)
1918 if (signarray.size() != nFaceIntCoeffs)
1924 fill(signarray.get(), signarray.get() + nFaceIntCoeffs, 1);
1927 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
1928 m_base[2]->GetNumModes()};
1943 nummodesA = nummodes[0];
1944 nummodesB = nummodes[1];
1950 nummodesA = nummodes[0];
1951 nummodesB = nummodes[2];
1957 nummodesA = nummodes[1];
1958 nummodesB = nummodes[2];
1966 for (
int i = 0; i < (nummodesB - 2); i++)
1968 for (
int j = 0; j < (nummodesA - 2); j++)
1972 arrayindx[i * (nummodesA - 2) + j] = i * (nummodesA - 2) + j;
1976 arrayindx[i * (nummodesA - 2) + j] = j * (nummodesB - 2) + i;
2003 IdxRange[2][0] = nummodes[2] - 1;
2004 IdxRange[2][1] = nummodes[2];
2021 IdxRange[2][0] = nummodes[2] - 2;
2028 IdxRange[2][1] = nummodes[2] - 1;
2035 IdxRange[2][1] = nummodes[2];
2040 for (
int i = 3; i < nummodes[2]; i += 2)
2064 IdxRange[1][0] = nummodes[1] - 1;
2065 IdxRange[1][1] = nummodes[1];
2083 IdxRange[1][0] = nummodes[1] - 2;
2090 IdxRange[1][1] = nummodes[1] - 1;
2097 IdxRange[1][1] = nummodes[1];
2102 for (
int i = 3; i < nummodes[1]; i += 2)
2116 IdxRange[1][0] = nummodes[1] - 2;
2123 IdxRange[1][1] = nummodes[1] - 1;
2130 IdxRange[1][1] = nummodes[1];
2135 for (
int i = 3; i < nummodes[1]; i += 2)
2157 IdxRange[0][0] = nummodes[0] - 1;
2158 IdxRange[0][1] = nummodes[0];
2175 IdxRange[0][0] = nummodes[0] - 2;
2182 IdxRange[0][1] = nummodes[0] - 1;
2189 IdxRange[0][1] = nummodes[0];
2194 for (
int i = 3; i < nummodes[0]; i += 2)
2205 for (
int r = IdxRange[2][0]; r != IdxRange[2][1]; r += Incr[2])
2207 for (
int q = IdxRange[1][0]; q != IdxRange[1][1]; q += Incr[1])
2209 for (
int p = IdxRange[0][0];
p != IdxRange[0][1];
p += Incr[0])
2211 maparray[arrayindx[cnt]] =
2212 r * nummodes[0] * nummodes[1] + q * nummodes[0] +
p;
2213 signarray[arrayindx[cnt++]] = sign0[
p] * sign1[q] * sign2[r];
2221 ASSERTL2((i >= 0) && (i <= 11),
"edge id is out of range");
2223 if ((i == 0) || (i == 2) || (i == 8) || (i == 10))
2227 else if ((i == 1) || (i == 3) || (i == 9) || (i == 11))
2248 int nq0 =
m_base[0]->GetNumPoints();
2249 int nq1 =
m_base[1]->GetNumPoints();
2250 int nq2 =
m_base[2]->GetNumPoints();
2260 nq = max(nq0, max(nq1, nq2));
2274 for (
int i = 0; i < nq; ++i)
2276 for (
int j = 0; j < nq; ++j)
2278 for (
int k = 0; k < nq; ++k, ++cnt)
2281 coords[cnt][0] = -1.0 + 2 * k / (
NekDouble)(nq - 1);
2282 coords[cnt][1] = -1.0 + 2 * j / (
NekDouble)(nq - 1);
2283 coords[cnt][2] = -1.0 + 2 * i / (
NekDouble)(nq - 1);
2288 for (
int i = 0; i < neq; ++i)
2292 I[0] =
m_base[0]->GetI(coll);
2293 I[1] =
m_base[1]->GetI(coll + 1);
2294 I[2] =
m_base[2]->GetI(coll + 2);
2298 for (
int k = 0; k < nq2; ++k)
2300 for (
int j = 0; j < nq1; ++j)
2303 fac = (I[1]->GetPtr())[j] * (I[2]->GetPtr())[k];
2307 Mat->GetRawPtr() + k * nq0 * nq1 * neq +
2373 if (inarray.get() == outarray.get())
2379 m_ncoeffs, tmp.get(), 1, 0.0, outarray.get(), 1);
2384 m_ncoeffs, inarray.get(), 1, 0.0, outarray.get(), 1);
2392 int nquad0 =
m_base[0]->GetNumPoints();
2393 int nquad1 =
m_base[1]->GetNumPoints();
2394 int nquad2 =
m_base[2]->GetNumPoints();
2395 int nq01 = nquad0 * nquad1;
2396 int nq12 = nquad1 * nquad2;
2402 for (
int i = 0; i < nq12; ++i)
2404 Vmath::Vmul(nquad0, inarray.get() + i * nquad0, 1, w0.get(), 1,
2405 outarray.get() + i * nquad0, 1);
2408 for (
int i = 0; i < nq12; ++i)
2410 Vmath::Smul(nquad0, w1[i % nquad1], outarray.get() + i * nquad0, 1,
2411 outarray.get() + i * nquad0, 1);
2414 for (
int i = 0; i < nquad2; ++i)
2416 Vmath::Smul(nq01, w2[i], outarray.get() + i * nq01, 1,
2417 outarray.get() + i * nq01, 1);
2425 int qa =
m_base[0]->GetNumPoints();
2426 int qb =
m_base[1]->GetNumPoints();
2427 int qc =
m_base[2]->GetNumPoints();
2428 int nmodes_a =
m_base[0]->GetNumModes();
2429 int nmodes_b =
m_base[1]->GetNumModes();
2430 int nmodes_c =
m_base[2]->GetNumModes();
2445 OrthoExp.
FwdTrans(array, orthocoeffs);
2455 for (
int i = 0; i < nmodes_a; ++i)
2457 for (
int j = 0; j < nmodes_b; ++j)
2460 pow((1.0 * i) / (nmodes_a - 1), cutoff * nmodes_a),
2461 pow((1.0 * j) / (nmodes_b - 1), cutoff * nmodes_b));
2463 for (
int k = 0; k < nmodes_c; ++k)
2466 std::max(fac1, pow((1.0 * k) / (nmodes_c - 1),
2467 cutoff * nmodes_c));
2469 orthocoeffs[cnt] *= SvvDiffCoeff * fac;
2485 max_abc = max(max_abc, 0);
2488 for (
int i = 0; i < nmodes_a; ++i)
2490 for (
int j = 0; j < nmodes_b; ++j)
2492 int maxij = max(i, j);
2494 for (
int k = 0; k < nmodes_c; ++k)
2496 int maxijk = max(maxij, k);
2510 min(nmodes_a, nmodes_b));
2513 int nmodes = max(nmodes_a, nmodes_b);
2514 nmodes = max(nmodes, nmodes_c);
2517 for (
int j = cutoff; j < nmodes; ++j)
2519 fac[j] = fabs((j - nmodes) / ((
NekDouble)(j - cutoff + 1.0)));
2523 for (
int i = 0; i < nmodes_a; ++i)
2525 for (
int j = 0; j < nmodes_b; ++j)
2527 for (
int k = 0; k < nmodes_c; ++k)
2529 if ((i >= cutoff) || (j >= cutoff) || (k >= cutoff))
2531 orthocoeffs[i * nmodes_a * nmodes_b + j * nmodes_c +
2533 (SvvDiffCoeff * exp(-(fac[i] + fac[j] + fac[k])));
2537 orthocoeffs[i * nmodes_a * nmodes_b + j * nmodes_c +
2546 OrthoExp.
BwdTrans(orthocoeffs, array);
2555 int qa =
m_base[0]->GetNumPoints();
2556 int qb =
m_base[1]->GetNumPoints();
2557 int qc =
m_base[2]->GetNumPoints();
2558 int nmodesA =
m_base[0]->GetNumModes();
2559 int nmodesB =
m_base[1]->GetNumModes();
2560 int nmodesC =
m_base[2]->GetNumModes();
2561 int P = nmodesA - 1;
2562 int Q = nmodesB - 1;
2563 int R = nmodesC - 1;
2576 int Pcut = cutoff *
P;
2577 int Qcut = cutoff * Q;
2578 int Rcut = cutoff * R;
2582 OrthoExp.
FwdTrans(array, orthocoeffs);
2587 for (
int i = 0; i < nmodesA; ++i)
2589 for (
int j = 0; j < nmodesB; ++j)
2591 for (
int k = 0; k < nmodesC; ++k, ++index)
2594 if (i > Pcut || j > Qcut || k > Rcut)
2599 fac = max(max(fac1, fac2), fac3);
2600 fac = pow(fac, exponent);
2601 orthocoeffs[index] *= exp(-alpha * fac);
2608 OrthoExp.
BwdTrans(orthocoeffs, array);
2614 boost::ignore_unused(standard);
2616 int np0 =
m_base[0]->GetNumPoints();
2617 int np1 =
m_base[1]->GetNumPoints();
2618 int np2 =
m_base[2]->GetNumPoints();
2619 int np = max(np0, max(np1, np2));
2627 for (
int i = 0; i < np - 1; ++i)
2629 for (
int j = 0; j < np - 1; ++j)
2632 for (
int k = 0; k < np - 1; ++k)
2634 conn[cnt++] = plane + row + k;
2635 conn[cnt++] = plane + row + k + 1;
2636 conn[cnt++] = plane + rowp1 + k;
2638 conn[cnt++] = plane + rowp1 + k + 1;
2639 conn[cnt++] = plane + rowp1 + k;
2640 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.
virtual void v_LaplacianMatrixOp_MatFree(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey)
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)
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.
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)
LibUtilities::NekManager< StdMatrixKey, DNekMat, StdMatrixKey::opLess > m_stdMatrixManager
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 void v_IProductWRTBase_MatOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual void v_ExponentialFilter(Array< OneD, NekDouble > &array, const NekDouble alpha, const NekDouble exponent, const NekDouble cutoff)
virtual void v_PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1, Array< OneD, NekDouble > &out_d2)
Differentiation Methods.
virtual int v_NumBndryCoeffs() const
virtual void v_HelmholtzMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
virtual void v_GetTraceNumModes(const int fid, int &numModes0, int &numModes1, Orientation faceOrient=eDir1FwdDir1_Dir2FwdDir2)
virtual void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdMatrixKey &mkey)
NekDouble v_PhysEvaluateBasis(const Array< OneD, const NekDouble > &coords, int mode) final
virtual const LibUtilities::BasisKey v_GetTraceBasisKey(const int i, const int k) const
virtual int v_GetTraceNumPoints(const int i) const
virtual void v_LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta)
virtual void v_FillMode(const int mode, Array< OneD, NekDouble > &outarray)
virtual int v_GetTraceNcoeffs(const int i) const
virtual void v_BwdTrans_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual int v_GetEdgeNcoeffs(const int i) const
virtual void v_GetBoundaryMap(Array< OneD, unsigned int > &outarray)
virtual void v_IProductWRTBase_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool multbyweights=true)
virtual DNekMatSharedPtr v_GenMatrix(const StdMatrixKey &mkey)
virtual int v_GetTraceIntNcoeffs(const int i) const
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)
virtual void v_GeneralMatrixOp_MatOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
virtual void v_IProductWRTDerivBase_SumFac(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual int v_GetVertexMap(int localVertexId, bool useCoeffPacking=false)
virtual int v_GetNverts() const
virtual void v_GetTraceInteriorToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation traceOrient=eDir1FwdDir1_Dir2FwdDir2)
virtual void v_LocCollapsedToLocCoord(const Array< OneD, const NekDouble > &eta, Array< OneD, NekDouble > &xi)
virtual void v_GetTraceCoeffMap(const unsigned int fid, Array< OneD, unsigned int > &maparray)
virtual LibUtilities::PointsKey v_GetTracePointsKey(const int i, const int j) const
virtual void v_MassMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
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)
virtual int v_GetTotalTraceIntNcoeffs() const
virtual int v_GetNedges() const
virtual void v_GetCoords(Array< OneD, NekDouble > &coords_x, Array< OneD, NekDouble > &coords_y, Array< OneD, NekDouble > &coords_z)
virtual void v_LaplacianMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
virtual bool v_IsBoundaryInteriorExpansion()
virtual void v_BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual DNekMatSharedPtr v_CreateStdMatrix(const StdMatrixKey &mkey)
virtual void v_MultiplyByStdQuadratureMetric(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual void v_GetInteriorMap(Array< OneD, unsigned int > &outarray)
virtual int v_NumDGBndryCoeffs() const
virtual int v_CalcNumberOfCoefficients(const std::vector< unsigned int > &nummodes, int &modes_offset)
virtual int v_GetNtraces() const
virtual void v_FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual void v_GetSimplexEquiSpacedConnectivity(Array< OneD, int > &conn, bool standard=true)
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)
virtual LibUtilities::ShapeType v_DetShapeType() const
virtual void v_WeakDerivMatrixOp(const int i, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
virtual void v_IProductWRTDerivBase_MatOp(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual void v_GetElmtTraceToTraceMap(const unsigned int fid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, Orientation faceOrient, int P, int Q)
virtual void v_GetEdgeInteriorToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation traceOrient=eDir1FwdDir1_Dir2FwdDir2)
virtual void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
MatrixType GetMatrixType() const
NekDouble GetConstFactor(const ConstFactorType &factor) const
bool ConstFactorExists(const ConstFactorType &factor) const
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 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 .
@ 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
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)