49 namespace MultiRegions
62 LocTraceToTraceMap::LocTraceToTraceMap(
66 const vector<bool> &LeftAdjacents)
71 m_expdim = locExpVector[0]->GetShapeDimension();
74 Setup(locExp, trace, elmtToTrace, LeftAdjacents);
77 LocTraceToTraceMap::~LocTraceToTraceMap()
89 void LocTraceToTraceMap::Setup(
93 const vector<bool> &LeftAdjacents)
116 const std::shared_ptr<LocalRegions::ExpansionVector> exp = locExp.
GetExp();
118 int cnt, n, e, phys_offset;
120 int nexp = exp->size();
121 m_nTracePts = trace->GetTotPoints();
128 m_nFwdLocTracePts = 0;
131 for (cnt = n = 0; n < nexp; ++n)
135 for (
int i = 0; i < elmt->GetNtraces(); ++i, ++cnt)
137 int nLocPts = elmt->GetTraceNumPoints(i);
138 m_nLocTracePts += nLocPts;
140 if (LeftAdjacents[cnt])
142 nFwdPts += elmtToTrace[n][i]->GetTotPoints();
143 nFwdCoeffs += elmtToTrace[n][i]->GetNcoeffs();
144 m_nFwdLocTracePts += nLocPts;
148 nBwdPts += elmtToTrace[n][i]->GetTotPoints();
149 nBwdCoeffs += elmtToTrace[n][i]->GetNcoeffs();
157 m_locTraceToElmtTraceMap[1] =
163 m_nTraceCoeffs[0] = nFwdCoeffs;
164 m_nTraceCoeffs[1] = nBwdCoeffs;
167 m_traceCoeffsToElmtMap[1] = m_traceCoeffsToElmtMap[0] + nFwdCoeffs;
169 m_traceCoeffsToElmtTrace[1] = m_traceCoeffsToElmtTrace[0] + nFwdCoeffs;
171 m_traceCoeffsToElmtSign[1] = m_traceCoeffsToElmtSign[0] + nFwdCoeffs;
174 map<TraceInterpPoints, vector<pair<int, int>>,
cmpop> TraceInterpMap;
176 vector<vector<int>> TraceOrder;
177 TraceOrder.resize(nexp);
178 vector<vector<int>> ElmtPhysTraceOffset;
179 ElmtPhysTraceOffset.resize(nexp);
187 for (cnt = n = 0; n < nexp; ++n)
190 ntrace = elmt->GetNtraces();
191 TraceOrder[n].resize(ntrace);
192 ElmtPhysTraceOffset[n].resize(ntrace);
195 for (e = 0; e < ntrace; ++e, ++cnt)
208 fromPointsKey0 = elmt->GetBasis(0)->GetPointsKey();
221 int dir0 = elmt->GetGeom()->GetDir(e, 0);
223 fromPointsKey0 = elmt->GetBasis(dir0)->GetPointsKey();
227 toPointsKey0 = elmttrace->GetBasis(0)->GetPointsKey();
231 P[0] = elmttrace->GetBasisNumModes(0);
236 int dir0 = elmt->GetGeom()->GetDir(e, 0);
237 int dir1 = elmt->GetGeom()->GetDir(e, 1);
239 fromPointsKey0 = elmt->GetBasis(dir0)->GetPointsKey();
240 fromPointsKey1 = elmt->GetBasis(dir1)->GetPointsKey();
244 toPointsKey0 = elmttrace->GetBasis(0)->GetPointsKey();
245 toPointsKey1 = elmttrace->GetBasis(1)->GetPointsKey();
249 toPointsKey0 = elmttrace->GetBasis(1)->GetPointsKey();
250 toPointsKey1 = elmttrace->GetBasis(0)->GetPointsKey();
253 P[0] = elmttrace->GetBasisNumModes(0);
254 P[1] = elmttrace->GetBasisNumModes(1);
260 toPointsKey0, toPointsKey1);
262 pair<int, int> epf(n, e);
263 TraceInterpMap[fpoint].push_back(epf);
264 TraceOrder[n][e] = cnt;
266 ElmtPhysTraceOffset[n][e] = neoffset;
267 neoffset += elmt->GetTraceNumPoints(e);
274 elmt->GetTraceToElementMap(e, map,
sign, orient,
P[0],
P[1]);
276 int order_t = elmttrace->GetNcoeffs();
277 int t_offset = trace->GetCoeff_Offset(elmttrace->GetElmtId());
281 if (elmt->GetTraceExp(e)->GetRightAdjacentElementExp())
283 if (elmttrace->GetRightAdjacentElementExp()
285 ->GetGlobalID() == elmt->GetGeom()->GetGlobalID())
291 if (LeftAdjacents[cnt])
293 for (
int i = 0; i < order_t; ++i)
295 m_traceCoeffsToElmtMap[0][fwdcnt] = coeffoffset + map[i];
296 m_traceCoeffsToElmtTrace[0][fwdcnt] = t_offset + i;
297 m_traceCoeffsToElmtSign[0][fwdcnt++] = fac *
sign[i];
302 for (
int i = 0; i < order_t; ++i)
304 m_traceCoeffsToElmtMap[1][bwdcnt] = coeffoffset + map[i];
305 m_traceCoeffsToElmtTrace[1][bwdcnt] = t_offset + i;
306 m_traceCoeffsToElmtSign[1][bwdcnt++] = fac *
sign[i];
312 int nInterpType = TraceInterpMap.size();
315 for (
int i = 0; i < 2; ++i)
327 for (
int i = 0; i < 2; ++i)
336 int ntracepts, ntracepts1;
348 for (
auto it = TraceInterpMap.begin(); it != TraceInterpMap.end();
359 for (
int f = 0; f < it->second.size(); ++f, ++cnt2)
361 n = it->second[f].first;
362 e = it->second[f].second;
371 elmt->GetTracePhysMap(e, traceids);
373 ntracepts = elmt->GetTraceNumPoints(e);
374 ntracepts1 = elmttrace->GetTotPoints();
378 elmt->ReOrientTracePhysMap(orient, locTraceToTraceMap,
382 int offset = trace->GetPhys_Offset(elmtToTrace[n][e]->GetElmtId());
384 if (LeftAdjacents[TraceOrder[n][e]])
386 for (
int i = 0; i < ntracepts; ++i)
388 m_locTraceToFieldMap[cntFwd + i] =
389 phys_offset + traceids[i];
392 for (
int i = 0; i < ntracepts; ++i)
394 m_locTraceToElmtTraceMap[0][cntFwd + i] =
395 ElmtPhysTraceOffset[n][e] + i;
398 for (
int i = 0; i < ntracepts1; ++i)
400 m_locInterpTraceToTraceMap[0][cntFwd1 + i] =
401 offset + locTraceToTraceMap[i];
405 cntFwd1 += ntracepts1;
410 for (
int i = 0; i < ntracepts; ++i)
412 m_locTraceToFieldMap[m_nFwdLocTracePts + cntBwd + i] =
413 phys_offset + traceids[i];
416 for (
int i = 0; i < ntracepts; ++i)
418 m_locTraceToElmtTraceMap[1][cntBwd + i] =
419 ElmtPhysTraceOffset[n][e] + i;
422 for (
int i = 0; i < ntracepts1; ++i)
424 m_locInterpTraceToTraceMap[1][cntBwd1 + i] =
425 offset + locTraceToTraceMap[i];
429 cntBwd1 += ntracepts1;
433 m_interpNtraces[set][cnt1] += 1;
435 if ((fwdSet ==
false && set == 0) || (bwdSet ==
false && set == 1))
437 m_interpPoints[set][cnt1] = it->first;
449 if (fromPointsKey0 == toPointsKey0)
456 m_interpTraceI0[set][cnt1] =
458 ->GetI(toPointsKey0);
463 LibUtilities::eGaussRadauMAlpha1Beta0) &&
475 m_interpEndPtI0[set][cnt1] =
479 m_interpTraceI0[set][cnt1]
484 &m_interpEndPtI0[set][cnt1][0],
491 m_interpTraceI0[set][cnt1] =
494 ->GetI(toPointsKey0);
495 m_interpFromTraceI0[set][cnt1] =
497 ->GetI(fromPointsKey0);
504 if (fromPointsKey0 == toPointsKey0)
506 if (fromPointsKey1 == toPointsKey1)
513 m_interpTraceI1[set][cnt1] =
516 ->GetI(toPointsKey1);
517 m_interpFromTraceI1[set][cnt1] =
519 ->GetI(fromPointsKey1);
524 LibUtilities::eGaussRadauMAlpha1Beta0) &&
531 m_interpTrace[set][cnt1] =
536 m_interpEndPtI1[set][cnt1] =
540 m_interpTraceI1[set][cnt1]
545 &m_interpEndPtI1[set][cnt1][0], 1);
552 if (fromPointsKey1 == toPointsKey1)
555 m_interpTraceI0[set][cnt1] =
558 ->GetI(toPointsKey0);
559 m_interpFromTraceI0[set][cnt1] =
561 ->GetI(fromPointsKey0);
566 LibUtilities::eGaussRadauMAlpha1Beta0) &&
573 m_interpTrace[set][cnt1] =
578 m_interpEndPtI0[set][cnt1] =
582 m_interpTraceI0[set][cnt1]
587 &m_interpEndPtI0[set][cnt1][0], 1);
594 m_interpTraceI0[set][cnt1] =
597 ->GetI(toPointsKey0);
598 m_interpFromTraceI0[set][cnt1] =
600 ->GetI(fromPointsKey0);
601 m_interpTraceI1[set][cnt1] =
604 ->GetI(toPointsKey1);
605 m_interpFromTraceI1[set][cnt1] =
607 ->GetI(fromPointsKey1);
612 LibUtilities::eGaussRadauMAlpha1Beta0) &&
619 m_interpTrace[set][cnt1] =
624 m_interpEndPtI0[set][cnt1] =
628 m_interpTraceI0[set][cnt1]
633 &m_interpEndPtI0[set][cnt1][0], 1);
653 TraceLocToElmtLocCoeffMap(locExp, trace);
654 FindElmtNeighbors(locExp, trace);
657 void LocTraceToTraceMap::CalcLocTracePhysToTraceIDMap(
663 CalcLocTracePhysToTraceIDMap_2D(tracelist);
666 CalcLocTracePhysToTraceIDMap_3D(tracelist);
670 "CalcLocTracePhysToTraceIDMap not coded");
674 void LocTraceToTraceMap::CalcLocTracePhysToTraceIDMap_2D(
677 std::shared_ptr<LocalRegions::ExpansionVector> traceExp =
679 int ntotTrace = (*traceExp).size();
684 m_LocTracephysToTraceIDMap[1] =
688 for (
int nt = 0; nt < ntotTrace; nt++)
690 ntPnts = tracelist->GetTotPoints(nt);
691 noffset = tracelist->GetPhys_Offset(nt);
692 for (
int i = 0; i < ntPnts; i++)
703 for (
int dir = 0; dir < 2; dir++)
709 Vmath::Gathr((
int)m_locInterpTraceToTraceMap[dir].size(),
710 tracePnts.get(), m_locInterpTraceToTraceMap[dir].get(),
713 for (
int i = 0; i < m_interpTrace[dir].size(); ++i)
715 if (m_interpNtraces[dir][i])
718 std::get<0>(m_interpPoints[dir][i]);
720 std::get<2>(m_interpPoints[dir][i]);
724 int nedges = m_interpNtraces[dir][i];
726 for (
int ne = 0; ne < nedges; ne++)
728 Vmath::Fill(fnp, tmp[cnt1], &loctracePntsLR[dir][cnt], 1);
737 for (
int nlr = 0; nlr < 2; nlr++)
739 for (
int i = 0; i < loctracePntsLR[nlr].size(); i++)
741 m_LocTracephysToTraceIDMap[nlr][i] =
742 std::round(loctracePntsLR[nlr][i]);
743 error +=
abs(loctracePntsLR[nlr][i] -
744 NekDouble(m_LocTracephysToTraceIDMap[nlr][i]));
747 error = error /
NekDouble(m_nLocTracePts);
749 "m_LocTracephysToTraceIDMap may not be integer !!");
752 void LocTraceToTraceMap::CalcLocTracePhysToTraceIDMap_3D(
755 std::shared_ptr<LocalRegions::ExpansionVector> traceExp =
757 int ntotTrace = (*traceExp).size();
762 m_LocTracephysToTraceIDMap[1] =
766 for (
int nt = 0; nt < ntotTrace; nt++)
768 ntPnts = tracelist->GetTotPoints(nt);
769 noffset = tracelist->GetPhys_Offset(nt);
770 for (
int i = 0; i < ntPnts; i++)
781 for (
int dir = 0; dir < 2; dir++)
788 Vmath::Gathr((
int)m_locInterpTraceToTraceMap[dir].size(),
789 tracePnts.get(), m_locInterpTraceToTraceMap[dir].get(),
792 for (
int i = 0; i < m_interpTrace[dir].size(); ++i)
794 if (m_interpNtraces[dir][i])
797 std::get<0>(m_interpPoints[dir][i]);
799 std::get<1>(m_interpPoints[dir][i]);
801 std::get<2>(m_interpPoints[dir][i]);
803 std::get<3>(m_interpPoints[dir][i]);
810 int nfttl = fnp0 * fnp1;
812 for (
int ne = 0; ne < m_interpNtraces[dir][i]; ne++)
814 Vmath::Fill(nfttl, tmp[cnt1], &loctracePntsLR[dir][cnt], 1);
823 for (
int nlr = 0; nlr < 2; nlr++)
825 for (
int i = 0; i < loctracePntsLR[nlr].size(); i++)
827 m_LocTracephysToTraceIDMap[nlr][i] =
828 std::round(loctracePntsLR[nlr][i]);
829 error +=
abs(loctracePntsLR[nlr][i] -
830 NekDouble(m_LocTracephysToTraceIDMap[nlr][i]));
833 error = error /
NekDouble(m_nLocTracePts);
835 "m_LocTracephysToTraceIDMap may not be integer !!");
844 void LocTraceToTraceMap::TraceLocToElmtLocCoeffMap(
847 const std::shared_ptr<LocalRegions::ExpansionVector> exptrac =
849 size_t ntrace = exptrac->size();
857 for (
int lr = 0; lr < 2; ++lr)
863 for (
int i = 0; i < ntrace; ++i)
865 size_t ncoeff = trace->GetNcoeffs(i);
874 trace->GetCoeffsToElmt();
876 for (
int lr = 0; lr < 2; ++lr)
878 int ntotcoeffs = m_nTraceCoeffs[lr];
879 for (
int i = 0; i < ntotcoeffs; ++i)
881 int ncoeffField = m_traceCoeffsToElmtMap[lr][i];
882 int ncoeffTrace = m_traceCoeffsToElmtTrace[lr][i];
883 int sign = m_traceCoeffsToElmtSign[lr][i];
885 int ntraceelmt = trace_coeffToElmt[ncoeffTrace].first;
886 int ntracelocN = trace_coeffToElmt[ncoeffTrace].second;
888 int nfieldelmt = field_coeffToElmt[ncoeffField].first;
889 int nfieldlocN = field_coeffToElmt[ncoeffField].second;
891 LRAdjflag[lr][ntraceelmt] =
true;
892 LRAdjExpid[lr][ntraceelmt] = nfieldelmt;
894 elmtLRMap[lr][ntraceelmt][ntracelocN] = nfieldlocN;
895 elmtLRSign[lr][ntraceelmt][ntracelocN] =
sign;
898 m_leftRightAdjacentExpId = LRAdjExpid;
899 m_leftRightAdjacentExpFlag = LRAdjflag;
900 m_traceCoeffToLeftRightExpCoeffMap = elmtLRMap;
901 m_traceCoeffToLeftRightExpCoeffSign = elmtLRSign;
904 void LocTraceToTraceMap::FindElmtNeighbors(
const ExpList &locExp,
907 const std::shared_ptr<LocalRegions::ExpansionVector> exptrac =
909 int ntrace = exptrac->size();
911 const std::shared_ptr<LocalRegions::ExpansionVector> exp = locExp.
GetExp();
912 int nexp = exp->size();
916 LRAdjExpid = m_leftRightAdjacentExpId;
917 LRAdjflag = m_leftRightAdjacentExpFlag;
919 std::set<std::pair<int, int>> neighborSet;
921 for (
int nt = 0; nt < ntrace; nt++)
923 if (LRAdjflag[0][nt] && LRAdjflag[1][nt])
925 ntmp0 = LRAdjExpid[0][nt];
926 ntmp1 = LRAdjExpid[1][nt];
929 " ntmp0==ntmp1, trace inside a element?? ");
931 std::set<std::pair<int, int>>::iterator it = neighborSet.begin();
932 neighborSet.insert(it, std::make_pair(ntmp0, ntmp1));
933 neighborSet.insert(it, std::make_pair(ntmp1, ntmp0));
938 for (std::set<std::pair<int, int>>::iterator it = neighborSet.begin();
939 it != neighborSet.end(); ++it)
941 int ncurrent = it->first;
942 ElemIndex[ncurrent]++;
949 for (
int ne = 0; ne < nexp; ne++)
951 int neighb = ElemNeighbsNumb[ne];
956 for (
int ne = 0; ne < nexp; ne++)
960 for (std::set<std::pair<int, int>>::iterator it = neighborSet.begin();
961 it != neighborSet.end(); ++it)
963 int ncurrent = it->first;
964 int neighbor = it->second;
965 ElemNeighbsId[ncurrent][ElemIndex[ncurrent]] = neighbor;
966 ElemIndex[ncurrent]++;
970 for (
int ne = 0; ne < nexp; ne++)
973 for (
int nb = 0; nb < ElemNeighbsNumb[ne]; nb++)
975 int neighbId = ElemNeighbsId[ne][nb];
977 for (
int nc = 0; nc < ElemIndex[ne]; nc++)
979 if (ElemNeighbsId[ne][nb] == tmpId[ne][nc])
986 tmpId[ne][ElemIndex[ne]] = neighbId;
991 ElemNeighbsNumb = ElemIndex;
992 for (
int ne = 0; ne < nexp; ne++)
994 int neighb = ElemNeighbsNumb[ne];
998 Vmath::Vcopy(neighb, tmpId[ne], 1, ElemNeighbsId[ne], 1);
1003 for (
int ne = 0; ne < nexp; ne++)
1005 for (
int nb = 0; nb < ElemNeighbsNumb[ne]; nb++)
1007 ASSERTL0((ElemNeighbsId[ne][nb] >= 0) &&
1008 (ElemNeighbsId[ne][nb] <= nexp),
1009 "Element id <0 or >number of total elements")
1013 m_ElemNeighbsNumb = ElemNeighbsNumb;
1014 m_ElemNeighbsId = ElemNeighbsId;
1025 void LocTraceToTraceMap::LocTracesFromField(
1031 Vmath::Gathr(
static_cast<int>(m_locTraceToFieldMap.size()), field,
1032 m_locTraceToFieldMap, faces);
1043 void LocTraceToTraceMap::AddLocTracesToField(
1046 size_t nfield = field.size();
1048 Vmath::Assmb(m_locTraceToFieldMap.size(), faces.data(),
1049 m_locTraceToFieldMap.data(), tmp.data());
1060 void LocTraceToTraceMap::FwdLocTracesFromField(
1063 Vmath::Gathr(m_nFwdLocTracePts, field, m_locTraceToFieldMap, faces);
1074 void LocTraceToTraceMap::ReshuffleLocTracesForInterp(
1078 ASSERTL1(dir < 2,
"option dir out of range, "
1079 " dir=0 is fwd, dir=1 is bwd");
1081 Vmath::Gathr(
static_cast<int>(m_locTraceToElmtTraceMap[dir].size()),
1082 loctraces, m_locTraceToElmtTraceMap[dir], reshuffle);
1092 void LocTraceToTraceMap::UnshuffleLocTraces(
1096 ASSERTL1(dir < 2,
"option dir out of range, "
1097 " dir=0 is fwd, dir=1 is bwd");
1099 if (m_locTraceToElmtTraceMap[dir].size())
1101 Vmath::Scatr(m_locTraceToElmtTraceMap[dir].size(), loctraces,
1102 m_locTraceToElmtTraceMap[dir], unshuffle);
1106 void LocTraceToTraceMap::InterpLocTracesToTrace(
1114 loctraces.get(), m_locInterpTraceToTraceMap[dir].get(),
1118 InterpLocEdgesToTrace(dir, loctraces, traces);
1121 InterpLocFacesToTrace(dir, loctraces, traces);
1124 NEKERROR(ErrorUtil::efatal,
"Not set up");
1137 void LocTraceToTraceMap::InterpLocEdgesToTrace(
1141 ASSERTL1(dir < 2,
"option dir out of range, "
1142 " dir=0 is fwd, dir=1 is bwd");
1150 for (
int i = 0; i < m_interpTrace[dir].size(); ++i)
1153 if (m_interpNtraces[dir][i])
1157 std::get<0>(m_interpPoints[dir][i]);
1159 std::get<2>(m_interpPoints[dir][i]);
1163 int nedges = m_interpNtraces[dir][i];
1166 switch (m_interpTrace[dir][i])
1171 tmp.get() + cnt1, 1);
1178 I0->GetPtr().get(), tnp, locedges.get() + cnt,
1179 fnp, 0.0, tmp.get() + cnt1, tnp);
1186 for (
int k = 0; k < nedges; ++k)
1189 &tmp[cnt1 + k * tnp], 1);
1192 fnp, locedges.get() + cnt + k * fnp, 1, &I0[0], 1);
1198 "Invalid interpolation type for 2D elements");
1202 cnt += nedges * fnp;
1203 cnt1 += nedges * tnp;
1207 Vmath::Scatr(m_locInterpTraceToTraceMap[dir].size(), tmp.get(),
1208 m_locInterpTraceToTraceMap[dir].get(), edges.get());
1219 void LocTraceToTraceMap::InterpLocFacesToTrace(
1223 ASSERTL1(dir < 2,
"option dir out of range, "
1224 " dir=0 is fwd, dir=1 is bwd");
1232 for (
int i = 0; i < m_interpTrace[dir].size(); ++i)
1235 if (m_interpNtraces[dir][i])
1239 std::get<0>(m_interpPoints[dir][i]);
1241 std::get<1>(m_interpPoints[dir][i]);
1243 std::get<2>(m_interpPoints[dir][i]);
1245 std::get<3>(m_interpPoints[dir][i]);
1251 int nfaces = m_interpNtraces[dir][i];
1252 int nfromfacepts = nfaces * fnp0 * fnp1;
1255 switch (m_interpTrace[dir][i])
1260 tmp.get() + cnt1, 1);
1267 I0->GetPtr().get(), tnp0, locfaces.get() + cnt,
1268 fnp0, 0.0, tmp.get() + cnt1, tnp0);
1273 int nfaces = m_interpNtraces[dir][i];
1274 for (
int k = 0; k < fnp0; ++k)
1277 fnp0, tmp.get() + cnt1 + k, tnp0);
1281 Blas::Dgemv(
'T', fnp0, tnp1 * nfaces, 1.0, tmp.get() + cnt1,
1282 tnp0, I0.get(), 1, 0.0,
1283 tmp.get() + cnt1 + tnp0 - 1, tnp0);
1289 for (
int j = 0; j < m_interpNtraces[dir][i]; ++j)
1292 locfaces.get() + cnt + j * fnp0 * fnp1,
1293 tnp0, I1->GetPtr().get(), tnp1, 0.0,
1294 tmp.get() + cnt1 + j * tnp0 * tnp1, tnp0);
1301 for (
int j = 0; j < m_interpNtraces[dir][i]; ++j)
1305 locfaces.get() + cnt + j * fnp0 * fnp1, 1,
1306 tmp.get() + cnt1 + j * tnp0 * tnp1, 1);
1309 for (
int k = 0; k < tnp0; ++k)
1311 tmp[cnt1 + k + (j + 1) * tnp0 * tnp1 - tnp0] =
1313 locfaces.get() + cnt +
1314 j * fnp0 * fnp1 + k,
1327 for (
int j = 0; j < m_interpNtraces[dir][i]; ++j)
1330 locfaces.get() + cnt + j * fnp0 * fnp1,
1331 fnp0, I1->GetPtr().get(), tnp1, 0.0,
1332 wsp.get() + j * fnp0 * tnp1, fnp0);
1334 Blas::Dgemm(
'N',
'N', tnp0, tnp1 * m_interpNtraces[dir][i],
1335 fnp0, 1.0, I0->GetPtr().get(), tnp0, wsp.get(),
1336 fnp0, 0.0, tmp.get() + cnt1, tnp0);
1344 for (
int j = 0; j < m_interpNtraces[dir][i]; ++j)
1347 locfaces.get() + cnt + j * fnp0 * fnp1,
1348 fnp0, I1->GetPtr().get(), tnp1, 0.0,
1349 tmp.get() + cnt1 + j * tnp0 * tnp1, tnp0);
1352 Blas::Dgemv(
'T', fnp0, tnp1 * m_interpNtraces[dir][i], 1.0,
1353 tmp.get() + cnt1, tnp0, I0.get(), 1, 0.0,
1354 tmp.get() + cnt1 + tnp0 - 1, tnp0);
1358 ASSERTL0(
false,
"Interplation case needs implementing");
1361 cnt += nfromfacepts;
1362 cnt1 += m_interpNtraces[dir][i] * tnp0 * tnp1;
1366 Vmath::Scatr(m_locInterpTraceToTraceMap[dir].size(), tmp.get(),
1367 m_locInterpTraceToTraceMap[dir].get(), faces.get());
1370 void LocTraceToTraceMap::InterpLocTracesToTraceTranspose(
1377 InterpLocEdgesToTraceTranspose(dir, trace, loctrace);
1380 InterpLocFacesToTraceTranspose(dir, trace, loctrace);
1383 NEKERROR(ErrorUtil::efatal,
"Not set up");
1395 void LocTraceToTraceMap::InterpLocEdgesToTraceTranspose(
1399 ASSERTL1(dir < 2,
"option dir out of range, "
1400 " dir=0 is fwd, dir=1 is bwd");
1407 Vmath::Gathr((
int)m_locInterpTraceToTraceMap[dir].size(), edges.get(),
1408 m_locInterpTraceToTraceMap[dir].get(), tmp.get());
1410 for (
int i = 0; i < m_interpTrace[dir].size(); ++i)
1413 if (m_interpNtraces[dir][i])
1417 std::get<0>(m_interpPoints[dir][i]);
1419 std::get<2>(m_interpPoints[dir][i]);
1423 int nedges = m_interpNtraces[dir][i];
1426 switch (m_interpTrace[dir][i])
1431 locedges.get() + cnt, 1);
1438 I0->GetPtr().get(), tnp, tmp.get() + cnt1, tnp,
1439 0.0, locedges.get() + cnt, fnp);
1446 for (
int k = 0; k < nedges; ++k)
1449 &locedges[cnt + k * fnp], 1);
1451 Vmath::Svtvp(fnp, tmp[cnt1 + k * tnp + tnp - 1], &I0[0],
1452 1, locedges.get() + cnt + k * fnp, 1,
1453 locedges.get() + cnt + k * fnp, 1);
1459 "Invalid interpolation type for 2D elements");
1463 cnt += nedges * fnp;
1464 cnt1 += nedges * tnp;
1476 void LocTraceToTraceMap::InterpLocFacesToTraceTranspose(
1480 ASSERTL1(dir < 2,
"option dir out of range, "
1481 " dir=0 is fwd, dir=1 is bwd");
1491 Vmath::Gathr(
static_cast<int>(m_locInterpTraceToTraceMap[dir].size()),
1492 traces.data(), m_locInterpTraceToTraceMap[dir].data(),
1495 for (
int i = 0; i < m_interpTrace[dir].size(); ++i)
1498 if (m_interpNtraces[dir][i])
1502 std::get<0>(m_interpPoints[dir][i]);
1504 std::get<1>(m_interpPoints[dir][i]);
1506 std::get<2>(m_interpPoints[dir][i]);
1508 std::get<3>(m_interpPoints[dir][i]);
1515 int nfromfacepts = m_interpNtraces[dir][i] * fnp0 * fnp1;
1518 switch (m_interpTrace[dir][i])
1523 loctraces.get() + cnt, 1);
1530 I0->GetPtr().get(), tnp0, tmp.get() + cnt1,
1531 tnp0, 0.0, loctraces.get() + cnt, fnp0);
1536 int nfaces = m_interpNtraces[dir][i];
1537 for (
int k = 0; k < fnp0; ++k)
1539 Vmath::Vcopy(nfaces * fnp1, tmp.get() + cnt1 + k, tnp0,
1540 loctraces.get() + cnt + k, fnp0);
1544 for (
int k = 0; k < tnp1 * nfaces; k++)
1548 loctraces.get() + cnt + k * fnp0, 1,
1549 loctraces.get() + cnt + k * fnp0, 1);
1557 for (
int j = 0; j < m_interpNtraces[dir][i]; ++j)
1560 tmp.get() + cnt1 + j * tnp0 * tnp1, tnp0,
1561 I1->GetPtr().get(), tnp1, 0.0,
1562 loctraces.get() + cnt + j * fnp0 * fnp1,
1570 for (
int j = 0; j < m_interpNtraces[dir][i]; ++j)
1573 fnp0 * fnp1, tmp.get() + cnt1 + j * tnp0 * tnp1, 1,
1574 loctraces.get() + cnt + j * fnp0 * fnp1, 1);
1576 for (
int k = 0; k < fnp1; k++)
1580 &tmp[cnt1 + (j + 1) * tnp0 * tnp1 - tnp0], 1,
1581 &loctraces[cnt + j * fnp0 * fnp1 + k * fnp0], 1,
1582 &loctraces[cnt + j * fnp0 * fnp1 + k * fnp0],
1594 size_t(m_interpNtraces[dir][i] * fnp0 * tnp1)};
1596 Blas::Dgemm(
'T',
'N', fnp0, tnp1 * m_interpNtraces[dir][i],
1597 tnp0, 1.0, I0->GetPtr().get(), tnp0,
1598 tmp.get() + cnt1, tnp0, 0.0, wsp.get(), fnp0);
1600 for (
int j = 0; j < m_interpNtraces[dir][i]; ++j)
1603 wsp.get() + j * fnp0 * tnp1, fnp0,
1604 I1->GetPtr().get(), tnp1, 0.0,
1605 loctraces.get() + cnt + j * fnp0 * fnp1,
1616 size_t(m_interpNtraces[dir][i] * fnp0 * tnp1)};
1618 for (
int k = 0; k < tnp1 * m_interpNtraces[dir][i]; k++)
1621 &I0[0], 1, tmp.get() + cnt1 + k * tnp0, 1,
1622 wsp.get() + k * fnp0, 1);
1625 for (
int j = 0; j < m_interpNtraces[dir][i]; ++j)
1628 wsp.get() + j * fnp0 * tnp1, fnp0,
1629 I1->GetPtr().get(), tnp1, 0.0,
1630 loctraces.get() + cnt + j * fnp0 * fnp1,
1636 cnt += nfromfacepts;
1637 cnt1 += m_interpNtraces[dir][i] * tnp0 * tnp1;
1642 void LocTraceToTraceMap::InterpTraceToLocTrace(
1650 static_cast<int>(m_locInterpTraceToTraceMap[dir].size()),
1651 traces.get(), m_locInterpTraceToTraceMap[dir].get(),
1655 InterpTraceToLocEdges(dir, traces, loctraces);
1658 InterpTraceToLocFaces(dir, traces, loctraces);
1674 void LocTraceToTraceMap::InterpTraceToLocEdges(
1678 ASSERTL1(dir < 2,
"option dir out of range, "
1679 " dir=0 is fwd, dir=1 is bwd");
1687 Vmath::Gathr(
static_cast<int>(m_locInterpTraceToTraceMap[dir].size()),
1688 edges.get(), m_locInterpTraceToTraceMap[dir].get(), tmp.get());
1690 for (
int i = 0; i < m_interpTrace[dir].size(); ++i)
1693 if (m_interpNtraces[dir][i])
1697 std::get<2>(m_interpPoints[dir][i]);
1699 std::get<0>(m_interpPoints[dir][i]);
1703 int nedges = m_interpNtraces[dir][i];
1706 switch (m_interpTrace[dir][i])
1711 locedges.get() + cnt1, 1);
1718 I0->GetPtr().get(), tnp, tmp.get() + cnt, fnp,
1719 0.0, locedges.get() + cnt1, tnp);
1725 for (
int k = 0; k < nedges; ++k)
1729 &locedges[cnt1 + k * tnp], 1);
1735 "Invalid interpolation type for 2D elements");
1739 cnt += nedges * fnp;
1740 cnt1 += nedges * tnp;
1753 void LocTraceToTraceMap::InterpTraceToLocFaces(
1757 ASSERTL1(dir < 2,
"option dir out of range, "
1758 " dir=0 is fwd, dir=1 is bwd");
1766 Vmath::Gathr(
static_cast<int>(m_locInterpTraceToTraceMap[dir].size()),
1767 faces.get(), m_locInterpTraceToTraceMap[dir].get(), tmp.get());
1769 for (
int i = 0; i < m_interpTrace[dir].size(); ++i)
1772 if (m_interpNtraces[dir][i])
1776 std::get<2>(m_interpPoints[dir][i]);
1778 std::get<3>(m_interpPoints[dir][i]);
1780 std::get<0>(m_interpPoints[dir][i]);
1782 std::get<1>(m_interpPoints[dir][i]);
1788 int nfaces = m_interpNtraces[dir][i];
1789 int nfromfacepts = nfaces * fnp0 * fnp1;
1792 switch (m_interpTrace[dir][i])
1797 locfaces.get() + cnt1, 1);
1803 Blas::Dgemm(
'N',
'N', tnp0, tnp1 * nfaces, fnp0, 1.0,
1804 I0->GetPtr().get(), tnp0, tmp.get() + cnt, fnp0,
1805 0.0, locfaces.get() + cnt1, tnp0);
1811 for (
int j = 0; j < nfaces; ++j)
1814 tmp.get() + cnt + j * fnp0 * fnp1, tnp0,
1815 I1->GetPtr().get(), tnp1, 0.0,
1816 locfaces.get() + cnt1 + j * tnp0 * tnp1,
1823 for (
int j = 0; j < nfaces; ++j)
1827 tnp0 * tnp1, tmp.get() + cnt + j * fnp0 * fnp1, 1,
1828 locfaces.get() + cnt1 + j * tnp0 * tnp1, 1);
1838 for (
int j = 0; j < nfaces; ++j)
1841 tmp.get() + cnt + j * fnp0 * fnp1, fnp0,
1842 I1->GetPtr().get(), tnp1, 0.0,
1843 wsp.get() + j * fnp0 * tnp1, fnp0);
1846 Blas::Dgemm(
'N',
'N', tnp0, tnp1 * nfaces, fnp0, 1.0,
1847 I0->GetPtr().get(), tnp0, wsp.get(), fnp0, 0.0,
1848 locfaces.get() + cnt1, tnp0);
1854 for (
int j = 0; j < nfaces; ++j)
1857 tmp.get() + cnt + j * fnp0 * fnp1, fnp0,
1858 I1->GetPtr().get(), tnp1, 0.0,
1859 locfaces.get() + cnt1 + j * tnp0 * tnp1,
1865 ASSERTL0(
false,
"Interpolation case not implemneted (yet)");
1868 cnt += nfromfacepts;
1869 cnt1 += m_interpNtraces[dir][i] * tnp0 * tnp1;
1881 void LocTraceToTraceMap::AddTraceCoeffsToFieldCoeffs(
1884 int nvals = m_nTraceCoeffs[0] + m_nTraceCoeffs[1];
1885 for (
int i = 0; i < nvals; ++i)
1887 field[m_traceCoeffsToElmtMap[0][i]] +=
1888 m_traceCoeffsToElmtSign[0][i] *
1889 trace[m_traceCoeffsToElmtTrace[0][i]];
1901 void LocTraceToTraceMap::AddTraceCoeffsToFieldCoeffs(
1905 int nvals = m_nTraceCoeffs[dir];
1906 for (
int i = 0; i < nvals; ++i)
1908 field[m_traceCoeffsToElmtMap[dir][i]] +=
1909 m_traceCoeffsToElmtSign[dir][i] *
1910 trace[m_traceCoeffsToElmtTrace[dir][i]];
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define sign(a, b)
return the sign(b)*a
Defines a specification for a set of points.
PointsType GetPointsType() const
unsigned int GetNumPoints() const
Base class for all multi-elemental spectral/hp expansions.
const Array< OneD, const std::pair< int, int > > & GetCoeffsToElmt() const
Get m_coeffs to elemental value map.
int GetCoeff_Offset(int n) const
Get the start offset position for a local contiguous list of coeffs correspoinding to element n.
const std::shared_ptr< LocalRegions::ExpansionVector > GetExp() const
This function returns the vector of elements in the expansion.
int GetPhys_Offset(int n) const
Get the start offset position for a local contiguous list of quadrature points in a full array corres...
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 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...
PointsManagerT & PointsManager(void)
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
std::shared_ptr< Expansion > ExpansionSharedPtr
std::vector< ExpansionSharedPtr > ExpansionVector
@ eInterpEndPtDir0InterpDir1
std::tuple< LibUtilities::PointsKey, LibUtilities::PointsKey, LibUtilities::PointsKey, LibUtilities::PointsKey > TraceInterpPoints
Map holding points distributions required for interpolation of local traces onto global trace in two ...
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
static const NekDouble kNekZeroTol
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
@ eDir1FwdDir2_Dir2FwdDir1
The above copyright notice and this permission notice shall be included.
std::shared_ptr< DNekMat > DNekMatSharedPtr
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 Scatr(int n, const T *x, const int *y, T *z)
Scatter vector z[y[i]] = x[i].
void Gathr(int n, const T *sign, const T *x, const int *y, T *z)
Gather vector z[i] = sign[i]*x[y[i]].
void Assmb(int n, const T *x, const int *y, T *z)
Assemble z[y[i]] += x[i]; z should be zero'd first.
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 Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
scalarT< T > abs(scalarT< T > in)