35#include <boost/core/ignore_unused.hpp>
51 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
54 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
59 "order in 'a' direction is higher "
60 "than order in 'c' direction");
62 "order in 'b' direction is higher "
63 "than order in 'c' direction");
66 "Expected basis type in 'c' direction to be ModifiedPyr_C or "
97 int Qx =
m_base[0]->GetNumPoints();
98 int Qy =
m_base[1]->GetNumPoints();
99 int Qz =
m_base[2]->GetNumPoints();
107 eta_x =
m_base[0]->GetZ();
108 eta_y =
m_base[1]->GetZ();
109 eta_z =
m_base[2]->GetZ();
113 if (out_dxi1.size() > 0)
115 for (k = 0, n = 0; k < Qz; ++k)
118 for (j = 0; j < Qy; ++j)
120 for (i = 0; i < Qx; ++i, ++n)
122 out_dxi1[n] = fac * dEta_bar1[n];
128 if (out_dxi2.size() > 0)
130 for (k = 0, n = 0; k < Qz; ++k)
133 for (j = 0; j < Qy; ++j)
135 for (i = 0; i < Qx; ++i, ++n)
137 out_dxi2[n] = fac * dXi2[n];
143 if (out_dxi3.size() > 0)
145 for (k = 0, n = 0; k < Qz; ++k)
148 for (j = 0; j < Qy; ++j)
151 for (i = 0; i < Qx; ++i, ++n)
153 out_dxi3[n] = (1.0 + eta_x[i]) * fac * dEta_bar1[n] +
154 fac1 * fac * dXi2[n] + dEta3[n];
190 ASSERTL1(
false,
"input dir is out of range");
239 if (
m_base[0]->Collocation() &&
m_base[1]->Collocation() &&
244 inarray, 1, outarray, 1);
258 int nquad0 =
m_base[0]->GetNumPoints();
259 int nquad1 =
m_base[1]->GetNumPoints();
260 int nquad2 =
m_base[2]->GetNumPoints();
261 int order0 =
m_base[0]->GetNumModes();
262 int order1 =
m_base[1]->GetNumModes();
265 nquad2 * nquad1 * nquad0);
268 m_base[2]->GetBdata(), inarray, outarray, wsp,
true,
278 bool doCheckCollDir0,
bool doCheckCollDir1,
bool doCheckCollDir2)
280 boost::ignore_unused(doCheckCollDir0, doCheckCollDir1, doCheckCollDir2);
282 int nquad0 =
m_base[0]->GetNumPoints();
283 int nquad1 =
m_base[1]->GetNumPoints();
284 int nquad2 =
m_base[2]->GetNumPoints();
286 int order0 =
m_base[0]->GetNumModes();
287 int order1 =
m_base[1]->GetNumModes();
288 int order2 =
m_base[2]->GetNumModes();
293 int i, j, mode, mode1, cnt;
296 mode = mode1 = cnt = 0;
297 for (i = 0; i < order0; ++i)
299 for (j = 0; j < order1; ++j, ++cnt)
301 int ijmax = max(i, j);
303 base2.get() + mode * nquad2, nquad2,
304 inarray.get() + mode1, 1, 0.0, tmp.get() + cnt * nquad2,
306 mode += order2 - ijmax;
307 mode1 += order2 - ijmax;
310 for (j = order1; j < order2 - i; ++j)
312 int ijmax = max(i, j);
313 mode += order2 - ijmax;
325 Blas::Daxpy(nquad2, inarray[1], base2.get() + nquad2, 1,
326 &tmp[0] + nquad2, 1);
329 Blas::Daxpy(nquad2, inarray[1], base2.get() + nquad2, 1,
330 &tmp[0] + order1 * nquad2, 1);
333 Blas::Daxpy(nquad2, inarray[1], base2.get() + nquad2, 1,
334 &tmp[0] + order1 * nquad2 + nquad2, 1);
339 for (i = 0; i < order0; ++i)
341 Blas::Dgemm(
'N',
'T', nquad1, nquad2, order1, 1.0, base1.get(), nquad1,
342 tmp.get() + mode * nquad2, nquad2, 0.0,
343 tmp1.get() + i * nquad1 * nquad2, nquad1);
348 Blas::Dgemm(
'N',
'T', nquad0, nquad1 * nquad2, order0, 1.0, base0.get(),
349 nquad0, tmp1.get(), nquad1 * nquad2, 0.0, outarray.get(),
379 out = (*imatsys) * in;
404 if (
m_base[0]->Collocation() &&
m_base[1]->Collocation() &&
420 int nquad1 =
m_base[1]->GetNumPoints();
421 int nquad2 =
m_base[2]->GetNumPoints();
422 int order0 =
m_base[0]->GetNumModes();
423 int order1 =
m_base[1]->GetNumModes();
427 if (multiplybyweights)
435 tmp, outarray, wsp,
true,
true,
true);
441 inarray, outarray, wsp,
true,
true,
true);
451 bool doCheckCollDir0,
bool doCheckCollDir1,
bool doCheckCollDir2)
453 boost::ignore_unused(doCheckCollDir0, doCheckCollDir1, doCheckCollDir2);
455 int nquad0 =
m_base[0]->GetNumPoints();
456 int nquad1 =
m_base[1]->GetNumPoints();
457 int nquad2 =
m_base[2]->GetNumPoints();
459 int order0 =
m_base[0]->GetNumModes();
460 int order1 =
m_base[1]->GetNumModes();
461 int order2 =
m_base[2]->GetNumModes();
463 ASSERTL1(wsp.size() >= nquad1 * nquad2 * order0 + nquad2 * order0 * order1,
464 "Insufficient workspace size");
469 int i, j, mode, mode1, cnt;
472 Blas::Dgemm(
'T',
'N', nquad1 * nquad2, order0, nquad0, 1.0, inarray.get(),
473 nquad0, base0.get(), nquad0, 0.0, tmp1.get(), nquad1 * nquad2);
476 for (mode = i = 0; i < order0; ++i)
479 tmp1.get() + i * nquad1 * nquad2, nquad1, base1.get(),
480 nquad1, 0.0, tmp2.get() + mode * nquad2, nquad2);
485 mode = mode1 = cnt = 0;
486 for (i = 0; i < order0; ++i)
488 for (j = 0; j < order1; ++j, ++cnt)
490 int ijmax = max(i, j);
493 base2.get() + mode * nquad2, nquad2,
494 tmp2.get() + cnt * nquad2, 1, 0.0,
495 outarray.get() + mode1, 1);
496 mode += order2 - ijmax;
497 mode1 += order2 - ijmax;
501 for (j = order1; j < order2; ++j)
503 int ijmax = max(i, j);
504 mode += order2 - ijmax;
514 Blas::Ddot(nquad2, base2.get() + nquad2, 1, &tmp2[nquad2], 1);
517 outarray[1] +=
Blas::Ddot(nquad2, base2.get() + nquad2, 1,
518 &tmp2[nquad2 * order1], 1);
521 outarray[1] +=
Blas::Ddot(nquad2, base2.get() + nquad2, 1,
522 &tmp2[nquad2 * order1 + nquad2], 1);
544 int nquad0 =
m_base[0]->GetNumPoints();
545 int nquad1 =
m_base[1]->GetNumPoints();
546 int nquad2 =
m_base[2]->GetNumPoints();
547 int nqtot = nquad0 * nquad1 * nquad2;
554 int order0 =
m_base[0]->GetNumModes();
555 int order1 =
m_base[1]->GetNumModes();
558 nquad2 * order0 * order1);
565 for (i = 0; i < nquad0; ++i)
567 gfac0[i] = 0.5 * (1 + z0[i]);
571 for (i = 0; i < nquad1; ++i)
573 gfac1[i] = 0.5 * (1 + z1[i]);
577 for (i = 0; i < nquad2; ++i)
579 gfac2[i] = 2.0 / (1 - z2[i]);
583 const int nq01 = nquad0 * nquad1;
584 for (i = 0; i < nquad2; ++i)
586 Vmath::Smul(nq01, gfac2[i], &inarray[0] + i * nq01, 1,
587 &tmp0[0] + i * nq01, 1);
598 m_base[2]->GetBdata(), tmp0, outarray, wsp,
false,
true,
true);
605 m_base[2]->GetBdata(), tmp0, outarray, wsp,
true,
false,
true);
614 for (i = 0; i < nquad1 * nquad2; ++i)
616 Vmath::Vmul(nquad0, tmp0.get() + i * nquad0, 1, gfac0.get(), 1,
617 tmp0.get() + i * nquad0, 1);
621 m_base[2]->GetBdata(), tmp0, tmp3, wsp,
false,
true,
true);
624 for (i = 0; i < nquad2; ++i)
626 Vmath::Smul(nq01, gfac2[i], &inarray[0] + i * nq01, 1,
627 &tmp0[0] + i * nq01, 1);
629 for (i = 0; i < nquad1 * nquad2; ++i)
631 Vmath::Smul(nquad0, gfac1[i % nquad1], &tmp0[0] + i * nquad0, 1,
632 &tmp0[0] + i * nquad0, 1);
638 m_base[2]->GetBdata(), tmp0, tmp4, wsp,
true,
false,
true);
643 m_base[2]->GetDbdata(), tmp0, outarray, wsp,
true,
true,
false);
653 ASSERTL1(
false,
"input dir is out of range");
679 eta[1] = 2.0 * (1.0 + xi[1]) / d2 - 1.0;
680 eta[0] = 2.0 * (1.0 + xi[0]) / d2 - 1.0;
686 xi[0] = (1.0 + eta[0]) * (1.0 - eta[2]) * 0.5 - 1.0;
687 xi[1] = (1.0 + eta[1]) * (1.0 - eta[2]) * 0.5 - 1.0;
703 for (
int k = 0; k < Qz; ++k)
705 for (
int j = 0; j < Qy; ++j)
707 for (
int i = 0; i < Qx; ++i)
709 int s = i + Qx * (j + Qy * k);
712 xi_y[s] = (1.0 + eta_y[j]) * (1.0 - eta_z[k]) / 2.0 - 1.0;
713 xi_x[s] = (1.0 + etaBar_x[i]) * (1.0 - eta_z[k]) / 2.0 - 1.0;
721 std::array<NekDouble, 3> &firstOrderDerivs)
728 if ((1 - coll[2]) < 1e-5)
732 EphysDeriv2(totPoints);
733 PhysDeriv(inarray, EphysDeriv0, EphysDeriv1, EphysDeriv2);
736 I[0] =
GetBase()[0]->GetI(coll);
737 I[1] =
GetBase()[1]->GetI(coll + 1);
738 I[2] =
GetBase()[2]->GetI(coll + 2);
746 std::array<NekDouble, 3> interDeriv;
751 firstOrderDerivs[0] = fac * interDeriv[0];
752 firstOrderDerivs[1] = fac * interDeriv[1];
753 firstOrderDerivs[2] = ((1.0 + coll[0]) / (1.0 - coll[2])) * interDeriv[0] +
754 ((1.0 + coll[1]) / (1.0 - coll[2])) * interDeriv[1] +
770 int nummodes[3] = {
m_base[0]->GetNumModes(),
m_base[1]->GetNumModes(),
771 m_base[2]->GetNumModes()};
777 numModes0 = nummodes[0];
778 numModes1 = nummodes[1];
784 numModes0 = nummodes[0];
785 numModes1 = nummodes[2];
791 numModes0 = nummodes[1];
792 numModes1 = nummodes[2];
799 std::swap(numModes0, numModes1);
809 const int nm0 =
m_base[0]->GetNumModes();
810 const int nm1 =
m_base[1]->GetNumModes();
811 const int nm2 =
m_base[2]->GetNumModes();
813 int mode0 = 0, mode1 = 0, mode2 = 0, cnt = 0;
816 for (mode0 = 0; mode0 < nm0; ++mode0)
818 for (mode1 = 0; mode1 < nm1; ++mode1)
820 int maxpq = max(mode0, mode1);
821 for (mode2 = 0; mode2 < nm2 - maxpq; ++mode2, ++cnt)
841 for (
int j = nm1; j < nm2; ++j)
843 int ijmax = max(mode0, j);
844 mode2 += nm2 - ijmax;
850 return StdExpansion::BaryEvaluateBasis<2>(coll[2], 1);
854 return StdExpansion::BaryEvaluateBasis<0>(coll[0], mode0) *
855 StdExpansion::BaryEvaluateBasis<1>(coll[1], mode1) *
856 StdExpansion::BaryEvaluateBasis<2>(coll[2], mode2);
888 "BasisType is not a boundary interior form");
891 "BasisType is not a boundary interior form");
894 "BasisType is not a boundary interior form");
896 int P =
m_base[0]->GetNumModes();
897 int Q =
m_base[1]->GetNumModes();
898 int R =
m_base[2]->GetNumModes();
907 "BasisType is not a boundary interior form");
910 "BasisType is not a boundary interior form");
913 "BasisType is not a boundary interior form");
915 int P =
m_base[0]->GetNumModes() - 1;
916 int Q =
m_base[1]->GetNumModes() - 1;
917 int R =
m_base[2]->GetNumModes() - 1;
919 return (
P + 1) * (Q + 1)
920 + 2 * (R + 1) +
P * (1 + 2 * R -
P)
921 + 2 * (R + 1) + Q * (1 + 2 * R - Q);
926 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
932 else if (i == 1 || i == 3)
935 return Q + 1 + (
P * (1 + 2 * Q -
P)) / 2;
940 return Q + 1 + (
P * (1 + 2 * Q -
P)) / 2;
946 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
948 int P =
m_base[0]->GetNumModes() - 1;
949 int Q =
m_base[1]->GetNumModes() - 1;
950 int R =
m_base[2]->GetNumModes() - 1;
954 return (
P - 1) * (Q - 1);
956 else if (i == 1 || i == 3)
958 return (
P - 1) * (2 * (R - 1) - (
P - 1) - 1) / 2;
962 return (Q - 1) * (2 * (R - 1) - (Q - 1) - 1) / 2;
968 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
972 return m_base[0]->GetNumPoints() *
m_base[1]->GetNumPoints();
974 else if (i == 1 || i == 3)
976 return m_base[0]->GetNumPoints() *
m_base[2]->GetNumPoints();
980 return m_base[1]->GetNumPoints() *
m_base[2]->GetNumPoints();
986 ASSERTL2(i >= 0 && i <= 7,
"edge id is out of range");
988 if (i == 0 || i == 2)
992 else if (i == 1 || i == 3)
1005 ASSERTL2(i >= 0 && i <= 4,
"face id is out of range");
1006 ASSERTL2(k >= 0 && k <= 1,
"basis key id is out of range");
1014 m_base[k]->GetNumModes());
1021 m_base[2 * k]->GetNumModes());
1028 m_base[k + 1]->GetNumModes());
1037 const std::vector<unsigned int> &nummodes,
int &modes_offset)
1040 nummodes[modes_offset], nummodes[modes_offset + 1],
1041 nummodes[modes_offset + 2]);
1052 "Mapping not defined for this type of basis");
1056 if (useCoeffPacking ==
true)
1076 ASSERTL0(
false,
"local vertex id must be between 0 and 4");
1099 ASSERTL0(
false,
"local vertex id must be between 0 and 4");
1110 "BasisType is not a boundary interior form");
1113 "BasisType is not a boundary interior form");
1116 "BasisType is not a boundary interior form");
1118 int P =
m_base[0]->GetNumModes() - 1,
p;
1119 int Q =
m_base[1]->GetNumModes() - 1,
q;
1120 int R =
m_base[2]->GetNumModes() - 1, r;
1124 if (outarray.size() != nIntCoeffs)
1132 for (
p = 2;
p <=
P; ++
p)
1134 for (
q = 2;
q <= Q; ++
q)
1136 int maxpq = max(
p,
q);
1137 for (r = 1; r <= R - maxpq; ++r)
1149 "BasisType is not a boundary interior form");
1152 "BasisType is not a boundary interior form");
1155 "BasisType is not a boundary interior form");
1157 int P =
m_base[0]->GetNumModes() - 1,
p;
1158 int Q =
m_base[1]->GetNumModes() - 1,
q;
1159 int R =
m_base[2]->GetNumModes() - 1, r;
1164 if (maparray.size() != nBnd)
1170 for (
p = 0;
p <=
P; ++
p)
1175 for (
q = 0;
q <= Q; ++
q)
1177 int maxpq = max(
p,
q);
1178 for (r = 0; r <= R - maxpq; ++r)
1188 for (
q = 0;
q <= Q; ++
q)
1192 for (r = 0; r <= R -
p; ++r)
1210 "Method only implemented if BasisType is identical"
1211 "in x and y directions");
1214 "Method only implemented for Modified_A BasisType"
1215 "(x and y direction) and ModifiedPyr_C BasisType (z "
1218 int p,
q, r,
P = 0, Q = 0, idx = 0;
1220 int order0 =
m_base[0]->GetNumModes();
1221 int order1 =
m_base[1]->GetNumModes();
1222 int order2 =
m_base[2]->GetNumModes();
1241 ASSERTL0(
false,
"fid must be between 0 and 4");
1244 if (maparray.size() !=
P * Q)
1255 for (
q = 0;
q < Q; ++
q)
1257 for (
p = 0;
p <
P; ++
p)
1265 for (
p = 0;
p <
P; ++
p)
1267 for (r = 0; r < Q -
p; ++r)
1269 maparray[idx++] =
GetMode(
p, 0, r);
1275 maparray[idx++] =
GetMode(1, 0, 0);
1276 maparray[idx++] =
GetMode(0, 0, 1);
1277 for (r = 1; r < Q - 1; ++r)
1279 maparray[idx++] =
GetMode(1, 0, r);
1282 for (
q = 1;
q <
P; ++
q)
1284 for (r = 0; r < Q -
q; ++r)
1286 maparray[idx++] =
GetMode(1,
q, r);
1292 maparray[idx++] =
GetMode(0, 1, 0);
1293 maparray[idx++] =
GetMode(0, 0, 1);
1294 for (r = 1; r < Q - 1; ++r)
1296 maparray[idx++] =
GetMode(0, 1, r);
1299 for (
p = 1;
p <
P; ++
p)
1301 for (r = 0; r < Q -
p; ++r)
1303 maparray[idx++] =
GetMode(
p, 1, r);
1309 for (
q = 0;
q <
P; ++
q)
1311 for (r = 0; r < Q -
q; ++r)
1313 maparray[idx++] =
GetMode(0,
q, r);
1319 ASSERTL0(
false,
"Face to element map unavailable.");
1329 "Method only implemented if BasisType is identical"
1330 "in x and y directions");
1333 "Method only implemented for Modified_A BasisType"
1334 "(x and y direction) and ModifiedPyr_C BasisType (z "
1337 int i, j, k,
p, r, nFaceCoeffs;
1338 int nummodesA = 0, nummodesB = 0;
1340 int order0 =
m_base[0]->GetNumModes();
1341 int order1 =
m_base[1]->GetNumModes();
1342 int order2 =
m_base[2]->GetNumModes();
1361 ASSERTL0(
false,
"fid must be between 0 and 4");
1372 nFaceCoeffs =
P * (2 * Q -
P + 1) / 2;
1376 nFaceCoeffs =
P * Q;
1380 if (maparray.size() != nFaceCoeffs)
1385 if (signarray.size() != nFaceCoeffs)
1391 fill(signarray.get(), signarray.get() + nFaceCoeffs, 1);
1401 int minPA = min(nummodesA,
P);
1402 int minQB = min(nummodesB, Q);
1404 for (j = 0; j < minPA; ++j)
1407 for (k = 0; k < minQB - j; ++k, ++cnt)
1409 maparray[idx++] = cnt;
1412 cnt += nummodesB - minQB;
1414 for (k = nummodesB - j; k < Q - j; ++k)
1416 signarray[idx] = 0.0;
1417 maparray[idx++] = maparray[0];
1422 for (j = minPA; j < nummodesA; ++j)
1425 for (k = 0; k < minQB-j; ++k, ++cnt)
1427 maparray[idx++] = cnt;
1430 cnt += nummodesB-minQB;
1432 for (k = nummodesB-j; k < Q-j; ++k)
1434 signarray[idx] = 0.0;
1435 maparray[idx++] = maparray[0];
1439 for (j = nummodesA; j <
P; ++j)
1441 for (k = 0; k < Q - j; ++k)
1443 signarray[idx] = 0.0;
1444 maparray[idx++] = maparray[0];
1452 swap(maparray[0], maparray[Q]);
1453 for (i = 1; i < Q - 1; ++i)
1455 swap(maparray[i + 1], maparray[Q + i]);
1459 for (
p = 0;
p <
P; ++
p)
1461 for (r = 0; r < Q -
p; ++r, idx++)
1465 signarray[idx] =
p % 2 ? -1 : 1;
1478 for (i = 0; i < Q; i++)
1480 for (j = 0; j <
P; j++)
1484 arrayindx[i *
P + j] = i *
P + j;
1488 arrayindx[i *
P + j] = j * Q + i;
1495 for (j = 0; j <
P; ++j)
1498 for (k = 0; k < Q; k++)
1500 maparray[arrayindx[j + k *
P]] = j + k * nummodesA;
1503 for (k = nummodesB; k < Q; ++k)
1505 signarray[arrayindx[j + k *
P]] = 0.0;
1506 maparray[arrayindx[j + k *
P]] = maparray[0];
1510 for (j = nummodesA; j <
P; ++j)
1512 for (k = 0; k < Q; ++k)
1514 signarray[arrayindx[j + k *
P]] = 0.0;
1515 maparray[arrayindx[j + k *
P]] = maparray[0];
1530 for (i = 3; i < Q; i += 2)
1532 for (j = 0; j <
P; j++)
1534 signarray[arrayindx[i *
P + j]] *= -1;
1538 for (i = 0; i <
P; i++)
1540 swap(maparray[i], maparray[i +
P]);
1541 swap(signarray[i], signarray[i +
P]);
1546 for (i = 0; i < Q; i++)
1548 for (j = 3; j <
P; j += 2)
1550 signarray[arrayindx[i *
P + j]] *= -1;
1554 for (i = 0; i < Q; i++)
1556 swap(maparray[i], maparray[i + Q]);
1557 swap(signarray[i], signarray[i + Q]);
1569 for (i = 0; i < Q; i++)
1571 for (j = 3; j <
P; j += 2)
1573 signarray[arrayindx[i *
P + j]] *= -1;
1577 for (i = 0; i < Q; i++)
1579 swap(maparray[i *
P], maparray[i *
P + 1]);
1580 swap(signarray[i *
P], signarray[i *
P + 1]);
1585 for (i = 3; i < Q; i += 2)
1587 for (j = 0; j <
P; j++)
1589 signarray[arrayindx[i *
P + j]] *= -1;
1593 for (i = 0; i <
P; i++)
1595 swap(maparray[i * Q], maparray[i * Q + 1]);
1596 swap(signarray[i * Q], signarray[i * Q + 1]);
1609 const int P =
m_base[0]->GetNumModes() - 1;
1610 const int Q =
m_base[1]->GetNumModes() - 1;
1611 const int R =
m_base[2]->GetNumModes() - 1;
1614 if (maparray.size() != nEdgeIntCoeffs)
1619 if (signarray.size() != nEdgeIntCoeffs)
1625 fill(signarray.get(), signarray.get() + nEdgeIntCoeffs, 1);
1635 for (i = 2; i <=
P; ++i)
1637 maparray[i - 2] =
GetMode(i, 0, 0);
1642 for (i = 2; i <= Q; ++i)
1644 maparray[i - 2] =
GetMode(1, i, 0);
1648 for (i = 2; i <=
P; ++i)
1650 maparray[i - 2] =
GetMode(i, 1, 0);
1655 for (i = 2; i <= Q; ++i)
1657 maparray[i - 2] =
GetMode(0, i, 0);
1661 for (i = 2; i <= R; ++i)
1663 maparray[i - 2] =
GetMode(0, 0, i);
1668 for (i = 1; i <= R - 1; ++i)
1670 maparray[i - 1] =
GetMode(1, 0, i);
1674 for (i = 1; i <= R - 1; ++i)
1676 maparray[i - 1] =
GetMode(1, 1, i);
1681 for (i = 1; i <= R - 1; ++i)
1683 maparray[i - 1] =
GetMode(0, 1, i);
1687 ASSERTL0(
false,
"Edge not defined.");
1693 for (i = 1; i < nEdgeIntCoeffs; i += 2)
1704 const int P =
m_base[0]->GetNumModes() - 1;
1705 const int Q =
m_base[1]->GetNumModes() - 1;
1706 const int R =
m_base[2]->GetNumModes() - 1;
1708 int p,
q, r, idx = 0;
1713 if (maparray.size() != nFaceIntCoeffs)
1718 if (signarray.size() != nFaceIntCoeffs)
1724 fill(signarray.get(), signarray.get() + nFaceIntCoeffs, 1);
1735 for (i = 0; i < nummodesB; i++)
1737 for (j = 0; j < nummodesA; j++)
1741 arrayindx[i * nummodesA + j] = i * nummodesA + j;
1745 arrayindx[i * nummodesA + j] = j * nummodesB + i;
1754 for (
q = 2;
q <= Q; ++
q)
1756 for (
p = 2;
p <=
P; ++
p)
1758 maparray[arrayindx[(
q - 2) * nummodesA + (
p - 2)]] =
1764 for (
p = 2;
p <=
P; ++
p)
1766 for (r = 1; r <= R -
p; ++r)
1768 if ((
int)faceOrient == 7)
1770 signarray[idx] =
p % 2 ? -1 : 1;
1772 maparray[idx++] =
GetMode(
p, 0, r);
1777 for (
q = 2;
q <= Q; ++
q)
1779 for (r = 1; r <= R -
q; ++r)
1781 if ((
int)faceOrient == 7)
1783 signarray[idx] =
q % 2 ? -1 : 1;
1785 maparray[idx++] =
GetMode(1,
q, r);
1791 for (
p = 2;
p <=
P; ++
p)
1793 for (r = 1; r <= R -
p; ++r)
1795 if ((
int)faceOrient == 7)
1797 signarray[idx] =
p % 2 ? -1 : 1;
1799 maparray[idx++] =
GetMode(
p, 1, r);
1805 for (
q = 2;
q <= Q; ++
q)
1807 for (r = 1; r <= R -
q; ++r)
1809 if ((
int)faceOrient == 7)
1811 signarray[idx] =
q % 2 ? -1 : 1;
1813 maparray[idx++] =
GetMode(0,
q, r);
1818 ASSERTL0(
false,
"Face interior map not available.");
1828 if (faceOrient == 6 || faceOrient == 8 || faceOrient == 11 ||
1833 for (i = 1; i < nummodesB; i += 2)
1835 for (j = 0; j < nummodesA; j++)
1837 signarray[arrayindx[i * nummodesA + j]] *= -1;
1843 for (i = 0; i < nummodesB; i++)
1845 for (j = 1; j < nummodesA; j += 2)
1847 signarray[arrayindx[i * nummodesA + j]] *= -1;
1853 if (faceOrient == 7 || faceOrient == 8 || faceOrient == 10 ||
1858 for (i = 0; i < nummodesB; i++)
1860 for (j = 1; j < nummodesA; j += 2)
1862 signarray[arrayindx[i * nummodesA + j]] *= -1;
1868 for (i = 1; i < nummodesB; i += 2)
1870 for (j = 0; j < nummodesA; j++)
1872 signarray[arrayindx[i * nummodesA + j]] *= -1;
1919 const int Q =
m_base[1]->GetNumModes() - 1;
1920 const int R =
m_base[2]->GetNumModes() - 1;
1926 for (i = 0; i < I; ++i)
1932 cnt += (R + 1 - i) * (Q + 1) - l * (l + 1) / 2;
1936 l = max(0, J - 1 - I);
1937 cnt += (R + 1 - I) * J - l * (l + 1) / 2;
1951 int nquad0 =
m_base[0]->GetNumPoints();
1952 int nquad1 =
m_base[1]->GetNumPoints();
1953 int nquad2 =
m_base[2]->GetNumPoints();
1962 for (i = 0; i < nquad1 * nquad2; ++i)
1964 Vmath::Vmul(nquad0, inarray.get() + i * nquad0, 1, w0.get(), 1,
1965 outarray.get() + i * nquad0, 1);
1969 for (j = 0; j < nquad2; ++j)
1971 for (i = 0; i < nquad1; ++i)
1974 &outarray[0] + i * nquad0 + j * nquad0 * nquad1, 1);
1984 case LibUtilities::eGaussRadauMAlpha2Beta0:
1985 for (i = 0; i < nquad2; ++i)
1988 &outarray[0] + i * nquad0 * nquad1, 1);
1993 for (i = 0; i < nquad2; ++i)
1996 0.25 * (1 - z2[i]) * (1 - z2[i]) * w2[i],
1997 &outarray[0] + i * nquad0 * nquad1, 1);
2007 int qa =
m_base[0]->GetNumPoints();
2008 int qb =
m_base[1]->GetNumPoints();
2009 int qc =
m_base[2]->GetNumPoints();
2010 int nmodes_a =
m_base[0]->GetNumModes();
2011 int nmodes_b =
m_base[1]->GetNumModes();
2012 int nmodes_c =
m_base[2]->GetNumModes();
2024 int i, j, k, cnt = 0;
2027 OrthoExp.
FwdTrans(array, orthocoeffs);
2037 for (
int i = 0; i < nmodes_a; ++i)
2039 for (
int j = 0; j < nmodes_b; ++j)
2041 int maxij = max(i, j);
2043 pow((1.0 * i) / (nmodes_a - 1), cutoff * nmodes_a),
2044 pow((1.0 * j) / (nmodes_b - 1), cutoff * nmodes_b));
2046 for (
int k = 0; k < nmodes_c - maxij; ++k)
2049 std::max(fac1, pow((1.0 * k) / (nmodes_c - 1),
2050 cutoff * nmodes_c));
2052 orthocoeffs[cnt] *= SvvDiffCoeff * fac;
2068 max_abc = max(max_abc, 0);
2071 for (
int i = 0; i < nmodes_a; ++i)
2073 for (
int j = 0; j < nmodes_b; ++j)
2075 int maxij = max(i, j);
2077 for (
int k = 0; k < nmodes_c - maxij; ++k)
2079 int maxijk = max(maxij, k);
2101 int cutoff_a = (int)(SVVCutOff * nmodes_a);
2102 int cutoff_b = (int)(SVVCutOff * nmodes_b);
2103 int cutoff_c = (int)(SVVCutOff * nmodes_c);
2107 int nmodes = min(min(nmodes_a, nmodes_b), nmodes_c);
2108 NekDouble cutoff = min(min(cutoff_a, cutoff_b), cutoff_c);
2110 for (i = 0; i < nmodes_a; ++i)
2112 for (j = 0; j < nmodes_b; ++j)
2114 int maxij = max(i, j);
2115 for (k = 0; k < nmodes_c - maxij; ++k)
2117 if (j + k >= cutoff || i + k >= cutoff)
2121 exp(-(i + k - nmodes) * (i + k - nmodes) /
2122 ((
NekDouble)((i + k - cutoff + epsilon) *
2123 (i + k - cutoff + epsilon)))) *
2124 exp(-(j - nmodes) * (j - nmodes) /
2126 (j - cutoff + epsilon)))));
2130 orthocoeffs[cnt] *= 0.0;
2139 OrthoExp.
BwdTrans(orthocoeffs, array);
2146 int nquad0 =
m_base[0]->GetNumPoints();
2147 int nquad1 =
m_base[1]->GetNumPoints();
2148 int nquad2 =
m_base[2]->GetNumPoints();
2149 int nqtot = nquad0 * nquad1 * nquad2;
2150 int nmodes0 =
m_base[0]->GetNumModes();
2151 int nmodes1 =
m_base[1]->GetNumModes();
2152 int nmodes2 =
m_base[2]->GetNumModes();
2153 int numMax = nmodes0;
2174 bortho0, bortho1, bortho2);
2177 OrthoPyrExp->FwdTrans(phys_tmp, coeff);
2180 for (u = 0; u < numMin; ++u)
2182 for (i = 0; i < numMin; ++i)
2185 int maxui = max(u, i);
2187 tmp2 = coeff_tmp1 + cnt, 1);
2188 cnt += nmodes2 - maxui;
2191 for (i = numMin; i < nmodes1; ++i)
2193 int maxui = max(u, i);
2194 cnt += numMax - maxui;
2198 OrthoPyrExp->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.
BasisType GetBasisType() const
Return type of expansion 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 IProductWRTBase_SumFacKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp, bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2)
NekDouble BaryTensorDeriv(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs)
void PhysTensorDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray_d1, Array< OneD, NekDouble > &outarray_d2, Array< OneD, NekDouble > &outarray_d3)
Calculate the 3D derivative in the local tensor/collapsed coordinate at the physical points.
The base class for all shapes.
int GetNcoeffs(void) const
This function returns the total number of coefficients used in the expansion.
int GetTotPoints() const
This function returns the total number of quadrature points used in the element.
LibUtilities::BasisType GetBasisType(const int dir) const
This function returns the type of basis used in the dir direction.
int NumBndryCoeffs(void) const
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
void LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta)
Convert local cartesian coordinate xi into local collapsed coordinates eta.
const Array< OneD, const LibUtilities::BasisSharedPtr > & GetBase() const
This function gets the shared point to basis.
DNekMatSharedPtr CreateGeneralMatrix(const StdMatrixKey &mkey)
this function generates the mass matrix
NekDouble PhysEvaluate(const Array< OneD, const NekDouble > &coords, const Array< OneD, const NekDouble > &physvals)
This function evaluates the expansion at a single (arbitrary) point of the domain.
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.
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
NekDouble GetConstFactor(const ConstFactorType &factor) const
bool ConstFactorExists(const ConstFactorType &factor) const
void v_IProductWRTDerivBase_SumFac(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
DNekMatSharedPtr v_GenMatrix(const StdMatrixKey &mkey) override
int v_NumBndryCoeffs() const override
NekDouble v_PhysEvaluateBasis(const Array< OneD, const NekDouble > &coords, int mode) final
void v_ReduceOrderCoeffs(int numMin, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
int v_NumDGBndryCoeffs() const override
void v_FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Forward transform from physical quadrature space stored in inarray and evaluate the expansion coeffic...
void v_GetElmtTraceToTraceMap(const unsigned int fid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, Orientation faceOrient, int P, int Q) override
int v_GetTraceNcoeffs(const int i) const override
void v_LocCollapsedToLocCoord(const Array< OneD, const NekDouble > &eta, Array< OneD, NekDouble > &xi) override
void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdMatrixKey &mkey) override
int v_GetEdgeNcoeffs(const int i) const 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
int v_GetNtraces() const override
void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_FillMode(const int mode, Array< OneD, NekDouble > &outarray) override
void v_IProductWRTBase_SumFac(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool multiplybyweights=true) override
int v_GetNedges() const override
int v_CalcNumberOfCoefficients(const std::vector< unsigned int > &nummodes, int &modes_offset) override
int GetMode(int I, int J, int K)
Compute the mode number in the expansion for a particular tensorial combination.
int v_GetVertexMap(int localVertexId, bool useCoeffPacking=false) override
int v_GetTraceNumPoints(const int i) const override
void v_BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Backward transformation is evaluated at the quadrature points.
void v_GetBoundaryMap(Array< OneD, unsigned int > &outarray) override
void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Inner product of inarray over region with respect to the expansion basis m_base[0]->GetBdata(),...
void v_GetInteriorMap(Array< OneD, unsigned int > &outarray) override
void v_GetEdgeInteriorToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation traceOrient=eDir1FwdDir1_Dir2FwdDir2) override
void v_LocCoordToLocCollapsed(const Array< OneD, const NekDouble > &xi, Array< OneD, NekDouble > &eta) override
DNekMatSharedPtr v_CreateStdMatrix(const StdMatrixKey &mkey) override
int v_GetNverts() const override
void v_MultiplyByStdQuadratureMetric(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
void v_GetTraceInteriorToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation traceOrient=eDir1FwdDir1_Dir2FwdDir2) override
void v_BwdTrans_SumFac(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
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
const LibUtilities::BasisKey v_GetTraceBasisKey(const int i, const int k) const override
LibUtilities::ShapeType v_DetShapeType() const 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
Calculate the derivative of the physical points.
void v_GetTraceNumModes(const int fid, int &numModes0, int &numModes1, Orientation faceOrient=eDir1FwdDir1_Dir2FwdDir2) override
NekDouble v_PhysEvaluate(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs) override
void v_GetTraceCoeffMap(const unsigned int fid, Array< OneD, unsigned int > &maparray) override
void v_GetCoords(Array< OneD, NekDouble > &xi_x, Array< OneD, NekDouble > &xi_y, Array< OneD, NekDouble > &xi_z) override
int v_GetTraceIntNcoeffs(const int i) const override
static void Dgemv(const char &trans, const int &m, const int &n, const double &alpha, const double *a, const int &lda, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = alpha A x plus beta y 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.
@ P
Monomial polynomials .
@ eOrtho_A
Principle Orthogonal Functions .
@ eGLL_Lagrange
Lagrange for SEM basis .
@ eModifiedPyr_C
Principle Modified Functions.
@ eModified_A
Principle Modified Functions .
@ eOrthoPyr_C
Principle Orthogonal Functions .
static const NekDouble kNekZeroTol
LibUtilities::BasisKey EvaluateTriFaceBasisKey(const int facedir, const LibUtilities::BasisType faceDirBasisType, const int numpoints, const int nummodes)
@ eFactorSVVDGKerDiffCoeff
@ eFactorSVVPowerKerDiffCoeff
const int kSVVDGFiltermodesmin
std::shared_ptr< StdPyrExp > StdPyrExpSharedPtr
const int kSVVDGFiltermodesmax
LibUtilities::BasisKey EvaluateQuadFaceBasisKey(const int facedir, const LibUtilities::BasisType faceDirBasisType, const int numpoints, const int nummodes)
const NekDouble kSVVDGFilter[9][11]
@ eDir1BwdDir2_Dir2BwdDir1
@ 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 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)