35 #include <boost/core/ignore_unused.hpp>
47 StdPrismExp::StdPrismExp()
56 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
59 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
63 "order in 'a' direction is higher than order in 'c' direction");
99 int Qx =
m_base[0]->GetNumPoints();
100 int Qy =
m_base[1]->GetNumPoints();
101 int Qz =
m_base[2]->GetNumPoints();
102 int Qtot = Qx * Qy * Qz;
107 eta_x =
m_base[0]->GetZ();
108 eta_z =
m_base[2]->GetZ();
112 bool Do_1 = (out_dxi1.size() > 0) ?
true :
false;
113 bool Do_3 = (out_dxi3.size() > 0) ?
true :
false;
132 for (k = 0; k < Qz; ++k)
135 &dEta_bar1[0] + k * Qx * Qy, 1,
136 &out_dxi1[0] + k * Qx * Qy, 1);
143 for (k = 0; k < Qz; ++k)
146 &dEta_bar1[0] + k * Qx * Qy, 1,
147 &dEta_bar1[0] + k * Qx * Qy, 1);
151 for (i = 0; i < Qx; ++i)
153 Vmath::Svtvp(Qz * Qy, 1.0 + eta_x[i], &dEta_bar1[0] + i, Qx,
154 &out_dxi3[0] + i, Qx, &out_dxi3[0] + i, Qx);
188 ASSERTL1(
false,
"input dir is out of range");
244 "Basis[1] is not a general tensor type");
248 "Basis[2] is not a general tensor type");
250 if (
m_base[0]->Collocation() &&
m_base[1]->Collocation() &&
255 inarray, 1, outarray, 1);
266 int nquad1 =
m_base[1]->GetNumPoints();
267 int nquad2 =
m_base[2]->GetNumPoints();
268 int order0 =
m_base[0]->GetNumModes();
269 int order1 =
m_base[1]->GetNumModes();
272 nquad1 * nquad2 * order0);
275 m_base[2]->GetBdata(), inarray, outarray, wsp,
true,
285 bool doCheckCollDir0,
bool doCheckCollDir1,
bool doCheckCollDir2)
287 boost::ignore_unused(doCheckCollDir0, doCheckCollDir1, doCheckCollDir2);
290 int nquad0 =
m_base[0]->GetNumPoints();
291 int nquad1 =
m_base[1]->GetNumPoints();
292 int nquad2 =
m_base[2]->GetNumPoints();
293 int nummodes0 =
m_base[0]->GetNumModes();
294 int nummodes1 =
m_base[1]->GetNumModes();
295 int nummodes2 =
m_base[2]->GetNumModes();
299 for (i = mode = 0; i < nummodes0; ++i)
301 Blas::Dgemm(
'N',
'N', nquad2, nummodes1, nummodes2 - i, 1.0,
302 base2.get() + mode * nquad2, nquad2,
303 inarray.get() + mode * nummodes1, nummodes2 - i, 0.0,
304 tmp0.get() + i * nquad2 * nummodes1, nquad2);
305 mode += nummodes2 - i;
310 for (i = 0; i < nummodes1; i++)
313 base2.get() + nquad2, 1,
314 tmp0.get() + nquad2 * (nummodes1 + i), 1);
318 for (i = 0; i < nummodes0; i++)
320 Blas::Dgemm(
'N',
'T', nquad1, nquad2, nummodes1, 1.0, base1.get(),
321 nquad1, tmp0.get() + i * nquad2 * nummodes1, nquad2, 0.0,
322 tmp1.get() + i * nquad2 * nquad1, nquad1);
325 Blas::Dgemm(
'N',
'T', nquad0, nquad2 * nquad1, nummodes0, 1.0, base0.get(),
326 nquad0, tmp1.get(), nquad2 * nquad1, 0.0, outarray.get(),
354 out = (*matsys) * in;
392 "Basis[1] is not a general tensor type");
396 "Basis[2] is not a general tensor type");
398 if (
m_base[0]->Collocation() &&
m_base[1]->Collocation())
420 inarray.get(), 1, 0.0, outarray.get(), 1);
427 int nquad1 =
m_base[1]->GetNumPoints();
428 int nquad2 =
m_base[2]->GetNumPoints();
429 int order0 =
m_base[0]->GetNumModes();
430 int order1 =
m_base[1]->GetNumModes();
434 if (multiplybyweights)
441 tmp, outarray, wsp,
true,
true,
true);
447 inarray, outarray, wsp,
true,
true,
true);
457 bool doCheckCollDir0,
bool doCheckCollDir1,
bool doCheckCollDir2)
459 boost::ignore_unused(doCheckCollDir0, doCheckCollDir1, doCheckCollDir2);
463 const int nquad0 =
m_base[0]->GetNumPoints();
464 const int nquad1 =
m_base[1]->GetNumPoints();
465 const int nquad2 =
m_base[2]->GetNumPoints();
466 const int order0 =
m_base[0]->GetNumModes();
467 const int order1 =
m_base[1]->GetNumModes();
468 const int order2 =
m_base[2]->GetNumModes();
472 ASSERTL1(wsp.size() >= nquad1 * nquad2 * order0 + nquad2 * order0 * order1,
473 "Insufficient workspace size");
479 Blas::Dgemm(
'T',
'N', nquad1 * nquad2, order0, nquad0, 1.0, inarray.get(),
480 nquad0, base0.get(), nquad0, 0.0, tmp0.get(), nquad1 * nquad2);
483 Blas::Dgemm(
'T',
'N', nquad2 * order0, order1, nquad1, 1.0, tmp0.get(),
484 nquad1, base1.get(), nquad1, 0.0, tmp1.get(), nquad2 * order0);
487 for (mode = i = 0; i < order0; ++i)
489 Blas::Dgemm(
'T',
'N', order2 - i, order1, nquad2, 1.0,
490 base2.get() + mode * nquad2, nquad2,
491 tmp1.get() + i * nquad2, nquad2 * order0, 0.0,
492 outarray.get() + mode * order1, order2 - i);
500 for (i = 0; i < order1; ++i)
505 tmp1.get() + i * order0 * nquad2 + nquad2, 1);
525 ASSERTL0(dir >= 0 && dir <= 2,
"input dir is out of range");
547 inarray.get(), 1, 0.0, outarray.get(), 1);
554 ASSERTL0(dir >= 0 && dir <= 2,
"input dir is out of range");
557 int order0 =
m_base[0]->GetNumModes();
558 int order1 =
m_base[1]->GetNumModes();
559 int nquad0 =
m_base[0]->GetNumPoints();
560 int nquad1 =
m_base[1]->GetNumPoints();
561 int nquad2 =
m_base[2]->GetNumPoints();
571 for (i = 0; i < nquad0; ++i)
573 gfac0[i] = 0.5 * (1 + z0[i]);
577 for (i = 0; i < nquad2; ++i)
579 gfac2[i] = 2.0 / (1 - z2[i]);
585 for (i = 0; i < nquad2; ++i)
588 &inarray[0] + i * nquad0 * nquad1, 1,
589 &tmp0[0] + i * nquad0 * nquad1, 1);
600 m_base[2]->GetBdata(), tmp0, outarray, wsp,
true,
true,
true);
609 m_base[2]->GetBdata(), tmp0, outarray, wsp,
true,
true,
true);
618 for (i = 0; i < nquad1 * nquad2; ++i)
620 Vmath::Vmul(nquad0, &gfac0[0], 1, &tmp0[0] + i * nquad0, 1,
621 &tmp0[0] + i * nquad0, 1);
626 m_base[2]->GetBdata(), tmp0, tmp1, wsp,
true,
true,
true);
631 m_base[2]->GetDbdata(), tmp0, outarray, wsp,
true,
true,
true);
661 eta[0] = 2.0 * (1.0 + xi[0]) / d2 - 1.0;
667 xi[0] = (1.0 + eta[0]) * (1.0 - eta[2]) * 0.5 - 1.0;
684 for (
int k = 0; k < Qz; ++k)
686 for (
int j = 0; j < Qy; ++j)
688 for (
int i = 0; i < Qx; ++i)
690 int s = i + Qx * (j + Qy * k);
691 xi_x[s] = (1.0 - eta_z[k]) * (1.0 + etaBar_x[i]) / 2.0 - 1.0;
712 const int nm1 =
m_base[1]->GetNumModes();
713 const int nm2 =
m_base[2]->GetNumModes();
714 const int b = 2 * nm2 + 1;
716 const int mode0 = floor(0.5 * (b -
sqrt(b * b - 8.0 * mode / nm1)));
718 mode - nm1 * (mode0 * (nm2 - 1) + 1 - (mode0 - 2) * (mode0 - 1) / 2);
719 const int mode1 = tmp / (nm2 - mode0);
720 const int mode2 = tmp % (nm2 - mode0);
722 if (mode0 == 0 && mode2 == 1 &&
726 return StdExpansion::BaryEvaluateBasis<1>(coll[1], mode1) *
727 StdExpansion::BaryEvaluateBasis<2>(coll[2], mode2);
731 return StdExpansion::BaryEvaluateBasis<0>(coll[0], mode0) *
732 StdExpansion::BaryEvaluateBasis<1>(coll[1], mode1) *
733 StdExpansion::BaryEvaluateBasis<2>(coll[2], mode2);
740 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
741 m_base[2]->GetNumModes()};
747 numModes0 = nummodes[0];
748 numModes1 = nummodes[1];
755 numModes0 = nummodes[1];
756 numModes1 = nummodes[2];
763 numModes0 = nummodes[0];
764 numModes1 = nummodes[2];
771 std::swap(numModes0, numModes1);
777 ASSERTL2(i >= 0 && i <= 8,
"edge id is out of range");
779 if (i == 0 || i == 2)
783 else if (i == 1 || i == 3 || i == 8)
825 "BasisType is not a boundary interior form");
828 "BasisType is not a boundary interior form");
831 "BasisType is not a boundary interior form");
833 int P =
m_base[0]->GetNumModes();
834 int Q =
m_base[1]->GetNumModes();
835 int R =
m_base[2]->GetNumModes();
844 "BasisType is not a boundary interior form");
847 "BasisType is not a boundary interior form");
850 "BasisType is not a boundary interior form");
852 int P =
m_base[0]->GetNumModes() - 1;
853 int Q =
m_base[1]->GetNumModes() - 1;
854 int R =
m_base[2]->GetNumModes() - 1;
856 return (
P + 1) * (Q + 1)
857 + 2 * (Q + 1) * (R + 1)
858 + 2 * (R + 1) +
P * (1 + 2 * R -
P);
863 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
868 else if (i == 1 || i == 3)
871 return Q + 1 + (
P * (1 + 2 * Q -
P)) / 2;
881 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
891 else if (i == 1 || i == 3)
893 return Pi * (2 * Ri - Pi - 1) / 2;
907 return Pi * Qi + Pi * (2 * Ri - Pi - 1) + 2 * Qi * Ri;
912 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
916 return m_base[0]->GetNumPoints() *
m_base[1]->GetNumPoints();
918 else if (i == 1 || i == 3)
920 return m_base[0]->GetNumPoints() *
m_base[2]->GetNumPoints();
924 return m_base[1]->GetNumPoints() *
m_base[2]->GetNumPoints();
931 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
932 ASSERTL2(j == 0 || j == 1,
"face direction is out of range");
936 return m_base[j]->GetPointsKey();
938 else if (i == 1 || i == 3)
940 return m_base[2 * j]->GetPointsKey();
944 return m_base[j + 1]->GetPointsKey();
951 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
952 ASSERTL2(k >= 0 && k <= 1,
"basis key id is out of range");
960 m_base[k]->GetNumModes());
967 m_base[k + 1]->GetNumModes());
974 m_base[2 * k]->GetNumModes());
984 const std::vector<unsigned int> &nummodes,
int &modes_offset)
987 nummodes[modes_offset], nummodes[modes_offset + 1],
988 nummodes[modes_offset + 2]);
1010 "Mapping not defined for this type of basis");
1014 if (useCoeffPacking ==
true)
1037 ASSERTL0(
false,
"local vertex id must be between 0 and 5");
1063 ASSERTL0(
false,
"local vertex id must be between 0 and 5");
1074 "BasisType is not a boundary interior form");
1077 "BasisType is not a boundary interior form");
1080 "BasisType is not a boundary interior form");
1082 int P =
m_base[0]->GetNumModes() - 1,
p;
1083 int Q =
m_base[1]->GetNumModes() - 1, q;
1084 int R =
m_base[2]->GetNumModes() - 1, r;
1088 if (outarray.size() != nIntCoeffs)
1096 for (
p = 2;
p <=
P; ++
p)
1098 for (q = 2; q <= Q; ++q)
1100 for (r = 1; r <= R -
p; ++r)
1102 outarray[idx++] =
GetMode(
p, q, r);
1112 "BasisType is not a boundary interior form");
1115 "BasisType is not a boundary interior form");
1118 "BasisType is not a boundary interior form");
1120 int P =
m_base[0]->GetNumModes() - 1,
p;
1121 int Q =
m_base[1]->GetNumModes() - 1, q;
1122 int R =
m_base[2]->GetNumModes() - 1, r;
1127 if (maparray.size() != nBnd)
1133 for (
p = 0;
p <=
P; ++
p)
1138 for (q = 0; q <= Q; ++q)
1140 for (r = 0; r <= R -
p; ++r)
1142 maparray[idx++] =
GetMode(
p, q, r);
1150 for (q = 0; q <= Q; ++q)
1154 for (r = 0; r <= R -
p; ++r)
1156 maparray[idx++] =
GetMode(
p, q, r);
1161 maparray[idx++] =
GetMode(
p, q, 0);
1172 "Method only implemented if BasisType is identical"
1173 "in x and y directions");
1176 "Method only implemented for Modified_A BasisType"
1177 "(x and y direction) and Modified_B BasisType (z "
1179 int p, q, r, idx = 0;
1186 Q =
m_base[1]->GetNumModes();
1191 Q =
m_base[2]->GetNumModes();
1196 Q =
m_base[2]->GetNumModes();
1199 ASSERTL0(
false,
"fid must be between 0 and 4");
1202 if (maparray.size() !=
P * Q)
1212 for (q = 0; q < Q; ++q)
1214 for (
p = 0;
p <
P; ++
p)
1221 for (
p = 0;
p <
P; ++
p)
1223 for (r = 0; r < Q -
p; ++r)
1225 maparray[idx++] =
GetMode(
p, 0, r);
1230 for (q = 0; q <
P; ++q)
1232 maparray[q] =
GetMode(1, q, 0);
1234 for (q = 0; q <
P; ++q)
1236 maparray[
P + q] =
GetMode(0, q, 1);
1238 for (r = 1; r < Q - 1; ++r)
1240 for (q = 0; q <
P; ++q)
1242 maparray[(r + 1) *
P + q] =
GetMode(1, q, r);
1247 for (
p = 0;
p <
P; ++
p)
1249 for (r = 0; r < Q -
p; ++r)
1251 maparray[idx++] =
GetMode(
p, 1, r);
1256 for (r = 0; r < Q; ++r)
1258 for (q = 0; q <
P; ++q)
1260 maparray[r *
P + q] =
GetMode(0, q, r);
1265 ASSERTL0(
false,
"Face to element map unavailable.");
1275 "Method only implemented if BasisType is identical"
1276 "in x and y directions");
1279 "Method only implemented for Modified_A BasisType"
1280 "(x and y direction) and Modified_B BasisType (z "
1283 int i, j, k,
p, r, nFaceCoeffs, idx = 0;
1284 int nummodesA = 0, nummodesB = 0;
1289 nummodesA =
m_base[0]->GetNumModes();
1290 nummodesB =
m_base[1]->GetNumModes();
1294 nummodesA =
m_base[0]->GetNumModes();
1295 nummodesB =
m_base[2]->GetNumModes();
1299 nummodesA =
m_base[1]->GetNumModes();
1300 nummodesB =
m_base[2]->GetNumModes();
1303 ASSERTL0(
false,
"fid must be between 0 and 4");
1312 else if (fid == 1 || fid == 3)
1314 nFaceCoeffs =
P * (2 * Q -
P + 1) / 2;
1318 nFaceCoeffs =
P * Q;
1322 if (maparray.size() != nFaceCoeffs)
1327 if (signarray.size() != nFaceCoeffs)
1333 fill(signarray.get(), signarray.get() + nFaceCoeffs, 1);
1336 int minPA = min(nummodesA,
P);
1337 int minQB = min(nummodesB, Q);
1339 if (fid == 1 || fid == 3)
1346 for (j = 0; j < minPA; ++j)
1349 for (k = 0; k < minQB - j; ++k, ++cnt)
1351 maparray[idx++] = cnt;
1354 cnt += nummodesB - minQB;
1357 for (k = nummodesB - j; k < Q - j; ++k)
1359 signarray[idx] = 0.0;
1360 maparray[idx++] = maparray[0];
1364 for (j = minPA; j < nummodesA; ++j)
1367 for (k = 0; k < minQB-j; ++k, ++cnt)
1369 maparray[idx++] = cnt;
1372 cnt += nummodesB-minQB;
1375 for (k = nummodesB-j; k < Q-j; ++k)
1377 signarray[idx] = 0.0;
1378 maparray[idx++] = maparray[0];
1382 for (j = nummodesA; j <
P; ++j)
1384 for (k = 0; k < Q - j; ++k)
1386 signarray[idx] = 0.0;
1387 maparray[idx++] = maparray[0];
1396 for (
p = 0;
p <
P; ++
p)
1398 for (r = 0; r < Q -
p; ++r, idx++)
1402 signarray[idx] =
p % 2 ? -1 : 1;
1407 swap(maparray[0], maparray[Q]);
1408 for (i = 1; i < Q - 1; ++i)
1410 swap(maparray[i + 1], maparray[Q + i]);
1420 for (i = 0; i < Q; i++)
1422 for (j = 0; j <
P; j++)
1426 arrayindx[i *
P + j] = i *
P + j;
1430 arrayindx[i *
P + j] = j * Q + i;
1437 for (j = 0; j <
P; ++j)
1440 for (k = 0; k < Q; k++)
1442 maparray[arrayindx[j + k *
P]] = j + k * nummodesA;
1445 for (k = nummodesB; k < Q; ++k)
1447 signarray[arrayindx[j + k *
P]] = 0.0;
1448 maparray[arrayindx[j + k *
P]] = maparray[0];
1452 for (j = nummodesA; j <
P; ++j)
1454 for (k = 0; k < Q; ++k)
1456 signarray[arrayindx[j + k *
P]] = 0.0;
1457 maparray[arrayindx[j + k *
P]] = maparray[0];
1472 for (i = 3; i < Q; i += 2)
1474 for (j = 0; j <
P; j++)
1476 signarray[arrayindx[i *
P + j]] *= -1;
1480 for (i = 0; i <
P; i++)
1482 swap(maparray[i], maparray[i +
P]);
1483 swap(signarray[i], signarray[i +
P]);
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], maparray[i + Q]);
1499 swap(signarray[i], signarray[i + Q]);
1511 for (i = 0; i < Q; i++)
1513 for (j = 3; j <
P; j += 2)
1515 signarray[arrayindx[i *
P + j]] *= -1;
1519 for (i = 0; i < Q; i++)
1521 swap(maparray[i *
P], maparray[i *
P + 1]);
1522 swap(signarray[i *
P], signarray[i *
P + 1]);
1527 for (i = 3; i < Q; i += 2)
1529 for (j = 0; j <
P; j++)
1531 signarray[arrayindx[i *
P + j]] *= -1;
1535 for (i = 0; i <
P; i++)
1537 swap(maparray[i * Q], maparray[i * Q + 1]);
1538 swap(signarray[i * Q], signarray[i * Q + 1]);
1551 const int P =
m_base[0]->GetNumModes() - 1;
1552 const int Q =
m_base[1]->GetNumModes() - 1;
1553 const int R =
m_base[2]->GetNumModes() - 1;
1556 if (maparray.size() != nEdgeIntCoeffs)
1561 if (signarray.size() != nEdgeIntCoeffs)
1567 fill(signarray.get(), signarray.get() + nEdgeIntCoeffs, 1);
1577 for (i = 2; i <=
P; ++i)
1579 maparray[i - 2] =
GetMode(i, 0, 0);
1584 for (i = 2; i <= Q; ++i)
1586 maparray[i - 2] =
GetMode(1, i, 0);
1593 for (i = 2; i <=
P; ++i)
1595 maparray[i - 2] =
GetMode(i, 1, 0);
1602 for (i = 2; i <= Q; ++i)
1604 maparray[i - 2] =
GetMode(0, i, 0);
1609 for (i = 2; i <= R; ++i)
1611 maparray[i - 2] =
GetMode(0, 0, i);
1616 for (i = 1; i <= R - 1; ++i)
1618 maparray[i - 1] =
GetMode(1, 0, i);
1623 for (i = 1; i <= R - 1; ++i)
1625 maparray[i - 1] =
GetMode(1, 1, i);
1630 for (i = 2; i <= R; ++i)
1632 maparray[i - 2] =
GetMode(0, 1, i);
1637 for (i = 2; i <= Q; ++i)
1639 maparray[i - 2] =
GetMode(0, i, 1);
1644 ASSERTL0(
false,
"Edge not defined.");
1650 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1661 const int P =
m_base[0]->GetNumModes() - 1;
1662 const int Q =
m_base[1]->GetNumModes() - 1;
1663 const int R =
m_base[2]->GetNumModes() - 1;
1665 int p, q, r, idx = 0;
1671 if (maparray.size() != nFaceIntCoeffs)
1676 if (signarray.size() != nFaceIntCoeffs)
1682 fill(signarray.get(), signarray.get() + nFaceIntCoeffs, 1);
1688 if (fid != 1 && fid != 3)
1701 for (i = 0; i < nummodesB; i++)
1703 for (j = 0; j < nummodesA; j++)
1707 arrayindx[i * nummodesA + j] = i * nummodesA + j;
1711 arrayindx[i * nummodesA + j] = j * nummodesB + i;
1720 for (q = 2; q <= Q; ++q)
1722 for (
p = 2;
p <=
P; ++
p)
1724 maparray[arrayindx[(q - 2) * nummodesA + (
p - 2)]] =
1731 for (
p = 2;
p <=
P; ++
p)
1733 for (r = 1; r <= R -
p; ++r)
1737 signarray[idx] =
p % 2 ? -1 : 1;
1739 maparray[idx++] =
GetMode(
p, 0, r);
1745 for (r = 1; r <= R - 1; ++r)
1747 for (q = 2; q <= Q; ++q)
1749 maparray[arrayindx[(r - 1) * nummodesA + (q - 2)]] =
1756 for (
p = 2;
p <=
P; ++
p)
1758 for (r = 1; r <= R -
p; ++r)
1762 signarray[idx] =
p % 2 ? -1 : 1;
1764 maparray[idx++] =
GetMode(
p, 1, r);
1770 for (r = 2; r <= R; ++r)
1772 for (q = 2; q <= Q; ++q)
1774 maparray[arrayindx[(r - 2) * nummodesA + (q - 2)]] =
1781 ASSERTL0(
false,
"Face interior map not available.");
1786 if (fid == 1 || fid == 3)
1796 for (i = 1; i < nummodesB; i += 2)
1798 for (j = 0; j < nummodesA; j++)
1800 signarray[arrayindx[i * nummodesA + j]] *= -1;
1806 for (i = 0; i < nummodesB; i++)
1808 for (j = 1; j < nummodesA; j += 2)
1810 signarray[arrayindx[i * nummodesA + j]] *= -1;
1823 for (i = 0; i < nummodesB; i++)
1825 for (j = 1; j < nummodesA; j += 2)
1827 signarray[arrayindx[i * nummodesA + j]] *= -1;
1833 for (i = 1; i < nummodesB; i += 2)
1835 for (j = 0; j < nummodesA; j++)
1837 signarray[arrayindx[i * nummodesA + j]] *= -1;
1859 int nq0 =
m_base[0]->GetNumPoints();
1860 int nq1 =
m_base[1]->GetNumPoints();
1861 int nq2 =
m_base[2]->GetNumPoints();
1871 nq = max(nq0, max(nq1, nq2));
1884 for (
int i = 0; i < nq; ++i)
1886 for (
int j = 0; j < nq; ++j)
1888 for (
int k = 0; k < nq - i; ++k, ++cnt)
1891 coords[cnt][0] = -1.0 + 2 * k / (
NekDouble)(nq - 1);
1892 coords[cnt][1] = -1.0 + 2 * j / (
NekDouble)(nq - 1);
1893 coords[cnt][2] = -1.0 + 2 * i / (
NekDouble)(nq - 1);
1898 for (
int i = 0; i < neq; ++i)
1902 I[0] =
m_base[0]->GetI(coll);
1903 I[1] =
m_base[1]->GetI(coll + 1);
1904 I[2] =
m_base[2]->GetI(coll + 2);
1908 for (
int k = 0; k < nq2; ++k)
1910 for (
int j = 0; j < nq1; ++j)
1913 fac = (I[1]->GetPtr())[j] * (I[2]->GetPtr())[k];
1917 Mat->GetRawPtr() + k * nq0 * nq1 * neq +
1960 int Q =
m_base[1]->GetNumModes() - 1;
1961 int R =
m_base[2]->GetNumModes() - 1;
1965 (Q + 1) * (
p * R + 1 -
1966 (
p - 2) * (
p - 1) / 2);
1974 int nquad0 =
m_base[0]->GetNumPoints();
1975 int nquad1 =
m_base[1]->GetNumPoints();
1976 int nquad2 =
m_base[2]->GetNumPoints();
1985 for (i = 0; i < nquad1 * nquad2; ++i)
1987 Vmath::Vmul(nquad0, inarray.get() + i * nquad0, 1, w0.get(), 1,
1988 outarray.get() + i * nquad0, 1);
1992 for (j = 0; j < nquad2; ++j)
1994 for (i = 0; i < nquad1; ++i)
1997 &outarray[0] + i * nquad0 + j * nquad0 * nquad1, 1);
2007 case LibUtilities::eGaussRadauMAlpha1Beta0:
2008 for (i = 0; i < nquad2; ++i)
2011 &outarray[0] + i * nquad0 * nquad1, 1);
2016 for (i = 0; i < nquad2; ++i)
2018 Blas::Dscal(nquad0 * nquad1, 0.5 * (1 - z2[i]) * w2[i],
2019 &outarray[0] + i * nquad0 * nquad1, 1);
2029 int qa =
m_base[0]->GetNumPoints();
2030 int qb =
m_base[1]->GetNumPoints();
2031 int qc =
m_base[2]->GetNumPoints();
2032 int nmodes_a =
m_base[0]->GetNumModes();
2033 int nmodes_b =
m_base[1]->GetNumModes();
2034 int nmodes_c =
m_base[2]->GetNumModes();
2046 int i, j, k, cnt = 0;
2049 OrthoExp.
FwdTrans(array, orthocoeffs);
2059 for (
int i = 0; i < nmodes_a; ++i)
2061 for (
int j = 0; j < nmodes_b; ++j)
2064 pow((1.0 * i) / (nmodes_a - 1), cutoff * nmodes_a),
2065 pow((1.0 * j) / (nmodes_b - 1), cutoff * nmodes_b));
2067 for (
int k = 0; k < nmodes_c - i; ++k)
2070 std::max(fac1, pow((1.0 * k) / (nmodes_c - 1),
2071 cutoff * nmodes_c));
2073 orthocoeffs[cnt] *= SvvDiffCoeff * fac;
2089 max_abc = max(max_abc, 0);
2092 for (
int i = 0; i < nmodes_a; ++i)
2094 for (
int j = 0; j < nmodes_b; ++j)
2096 int maxij = max(i, j);
2098 for (
int k = 0; k < nmodes_c - i; ++k)
2100 int maxijk = max(maxij, k);
2122 int cutoff_a = (int)(SVVCutOff * nmodes_a);
2123 int cutoff_b = (int)(SVVCutOff * nmodes_b);
2124 int cutoff_c = (int)(SVVCutOff * nmodes_c);
2128 int nmodes = min(min(nmodes_a, nmodes_b), nmodes_c);
2129 NekDouble cutoff = min(min(cutoff_a, cutoff_b), cutoff_c);
2132 for (i = 0; i < nmodes_a; ++i)
2134 for (j = 0; j < nmodes_b; ++j)
2136 for (k = 0; k < nmodes_c - i; ++k)
2138 if (j >= cutoff || i + k >= cutoff)
2142 exp(-(i + k - nmodes) * (i + k - nmodes) /
2143 ((
NekDouble)((i + k - cutoff + epsilon) *
2144 (i + k - cutoff + epsilon)))) *
2145 exp(-(j - nmodes) * (j - nmodes) /
2147 (j - cutoff + epsilon)))));
2151 orthocoeffs[cnt] *= 0.0;
2160 OrthoExp.
BwdTrans(orthocoeffs, array);
2167 int nquad0 =
m_base[0]->GetNumPoints();
2168 int nquad1 =
m_base[1]->GetNumPoints();
2169 int nquad2 =
m_base[2]->GetNumPoints();
2170 int nqtot = nquad0 * nquad1 * nquad2;
2171 int nmodes0 =
m_base[0]->GetNumModes();
2172 int nmodes1 =
m_base[1]->GetNumModes();
2173 int nmodes2 =
m_base[2]->GetNumModes();
2174 int numMax = nmodes0;
2195 bortho0, bortho1, bortho2);
2198 OrthoPrismExp->FwdTrans(phys_tmp, coeff);
2201 for (u = 0; u < numMin; ++u)
2203 for (i = 0; i < numMin; ++i)
2206 tmp2 = coeff_tmp1 + cnt, 1);
2210 for (i = numMin; i < numMax; ++i)
2216 OrthoPrismExp->BwdTrans(coeff_tmp1, phys_tmp);
#define ASSERTL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
Describes the specification for a Basis.
int GetNumModes() const
Returns the order of the basis.
Defines a specification for a set of points.
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
void BwdTrans_SumFacKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp, bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2)
void IProductWRTBase_SumFacKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp, bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2)
void PhysTensorDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray_d1, Array< OneD, NekDouble > &outarray_d2, Array< OneD, NekDouble > &outarray_d3)
Calculate the 3D derivative in the local tensor/collapsed coordinate at the physical points.
The base class for all shapes.
int GetNcoeffs(void) const
This function returns the total number of coefficients used in the expansion.
int GetTotPoints() const
This function returns the total number of quadrature points used in the element.
LibUtilities::BasisType GetBasisType(const int dir) const
This function returns the type of basis used in the dir direction.
int NumBndryCoeffs(void) const
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
void LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta)
Convert local cartesian coordinate xi into local collapsed coordinates eta.
DNekMatSharedPtr CreateGeneralMatrix(const StdMatrixKey &mkey)
this function generates the mass matrix
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.
int GetTraceNcoeffs(const int i) const
This function returns the number of expansion coefficients belonging to the i-th trace.
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.
Array< OneD, LibUtilities::BasisSharedPtr > m_base
MatrixType GetMatrixType() const
NekDouble GetConstFactor(const ConstFactorType &factor) const
bool ConstFactorExists(const ConstFactorType &factor) const
Class representing a prismatic element in reference space.
virtual void v_IProductWRTDerivBase_SumFac(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual const LibUtilities::BasisKey v_GetTraceBasisKey(const int i, const int k) 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_ReduceOrderCoeffs(int numMin, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual DNekMatSharedPtr v_GenMatrix(const StdMatrixKey &mkey)
virtual DNekMatSharedPtr v_CreateStdMatrix(const StdMatrixKey &mkey)
virtual LibUtilities::PointsKey v_GetTracePointsKey(const int i, const int j) const
virtual int v_GetTraceNumPoints(const int i) const
virtual void v_FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Forward transform from physical quadrature space stored in inarray and evaluate the expansion coeffic...
virtual int v_GetNedges() const
virtual void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Inner product of inarray over region with respect to the object's default expansion basis; output in ...
virtual void v_IProductWRTBase_MatOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual void v_GetCoords(Array< OneD, NekDouble > &xi_x, Array< OneD, NekDouble > &xi_y, Array< OneD, NekDouble > &xi_z)
virtual int v_GetTraceIntNcoeffs(const int i) const
virtual void v_BwdTrans(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 int v_GetTotalTraceIntNcoeffs() const
virtual int v_GetVertexMap(int localVertexId, bool useCoeffPacking=false)
void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdMatrixKey &mkey)
virtual int v_GetTraceNcoeffs(const int i) const
virtual int v_GetNtraces() const
NekDouble v_PhysEvaluateBasis(const Array< OneD, const NekDouble > &coords, int mode) final
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 void v_GetBoundaryMap(Array< OneD, unsigned int > &outarray)
virtual void v_GetInteriorMap(Array< OneD, unsigned int > &outarray)
virtual void v_GetTraceNumModes(const int fid, int &numModes0, int &numModes1, Orientation faceOrient=eDir1FwdDir1_Dir2FwdDir2)
virtual void v_GetTraceCoeffMap(const unsigned int fid, Array< OneD, unsigned int > &maparray)
virtual int v_GetNverts() const
int GetMode(int I, int J, int K)
Compute the local mode number in the expansion for a particular tensorial combination.
virtual void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Calculate the inner product of inarray with respect to the basis B=base0*base1*base2 and put into out...
virtual void v_FillMode(const int mode, Array< OneD, NekDouble > &outarray)
virtual int v_GetEdgeNcoeffs(const int i) const
virtual void v_BwdTrans_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
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 int v_NumDGBndryCoeffs() const
virtual int v_CalcNumberOfCoefficients(const std::vector< unsigned int > &nummodes, int &modes_offset)
virtual void v_MultiplyByStdQuadratureMetric(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
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)
Calculate the derivative of the physical points.
virtual void v_GetEdgeInteriorToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation traceOrient=eDir1FwdDir1_Dir2FwdDir2)
virtual bool v_IsBoundaryInteriorExpansion()
virtual void v_IProductWRTDerivBase_MatOp(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
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_NumBndryCoeffs() const
virtual void v_LocCollapsedToLocCoord(const Array< OneD, const NekDouble > &eta, Array< OneD, NekDouble > &xi)
virtual LibUtilities::ShapeType v_DetShapeType() const
Return Shape of region, using ShapeType enum list; i.e. prism.
virtual void v_IProductWRTBase_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool multiplybyweights=true)
virtual void v_LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta)
static void Dgemv(const char &trans, const int &m, const int &n, const double &alpha, const double *a, const int &lda, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = A x where A[m x n].
static void Dscal(const int &n, const double &alpha, double *x, const int &incx)
BLAS level 1: x = alpha x.
static double Ddot(const int &n, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: output = .
static void Dgemm(const char &transa, const char &transb, const int &m, const int &n, const int &k, const double &alpha, const double *a, const int &lda, const double *b, const int &ldb, const double &beta, double *c, const int &ldc)
BLAS level 3: Matrix-matrix multiply C = A x B where op(A)[m x k], op(B)[k x n], C[m x n] DGEMM perfo...
static void Daxpy(const int &n, const double &alpha, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: y = alpha x plus y.
int getNumberOfCoefficients(int Na, int Nb, int Nc)
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
int getNumberOfCoefficients(int Na)
static const BasisKey NullBasisKey(eNoBasisType, 0, NullPointsKey)
Defines a null basis with no type or points.
@ eModified_B
Principle Modified Functions .
@ eOrtho_A
Principle Orthogonal Functions .
@ eModified_C
Principle Modified Functions .
@ eGLL_Lagrange
Lagrange for SEM basis .
@ eOrtho_C
Principle Orthogonal Functions .
@ eOrtho_B
Principle Orthogonal Functions .
@ eModified_A
Principle Modified Functions .
static const NekDouble kNekZeroTol
std::shared_ptr< StdPrismExp > StdPrismExpSharedPtr
LibUtilities::BasisKey EvaluateTriFaceBasisKey(const int facedir, const LibUtilities::BasisType faceDirBasisType, const int numpoints, const int nummodes)
@ 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
@ 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 Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
svtvp (scalar times vector plus vector): z = alpha*x + y
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
scalarT< T > sqrt(scalarT< T > in)