92 : m_expType(type), m_ncoeffs(0), m_npoints(0), m_physState(false),
93 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
107ExpList::ExpList(
const ExpList &in,
const bool DeclareCoeffPhysArrays)
108 :
std::enable_shared_from_this<ExpList>(in), m_expType(in.m_expType),
110 m_comm(in.m_comm), m_session(in.m_session), m_graph(in.m_graph),
111 m_ncoeffs(in.m_ncoeffs), m_npoints(in.m_npoints), m_physState(false),
112 m_exp(in.m_exp), m_collections(in.m_collections),
113 m_collectionsDoInit(in.m_collectionsDoInit),
114 m_coeff_offset(in.m_coeff_offset), m_phys_offset(in.m_phys_offset),
115 m_blockMat(in.m_blockMat), m_WaveSpace(false),
116 m_elmtToExpId(in.m_elmtToExpId)
120 SetupCoeffPhys(DeclareCoeffPhysArrays,
false);
128ExpList::ExpList(
const ExpList &in,
const std::vector<unsigned int> &eIDs,
129 const bool DeclareCoeffPhysArrays,
130 const Collections::ImplementationType ImpType)
131 : m_expType(in.m_expType), m_comm(in.m_comm), m_session(in.m_session),
132 m_graph(in.m_graph), m_physState(false),
133 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
137 for (
int i = 0; i < eIDs.size(); ++i)
139 (*m_exp).push_back((*(in.m_exp))[eIDs[i]]);
143 SetupCoeffPhys(DeclareCoeffPhysArrays);
146 CreateCollections(ImpType);
168ExpList::ExpList(
const LibUtilities::SessionReaderSharedPtr &pSession,
169 const SpatialDomains::MeshGraphSharedPtr &graph,
170 const bool DeclareCoeffPhysArrays,
const std::string &var,
171 const Collections::ImplementationType ImpType)
172 : m_comm(pSession->GetComm()), m_session(pSession), m_graph(graph),
174 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
179 const SpatialDomains::ExpansionInfoMap &expansions =
180 graph->GetExpansionInfo(var);
183 InitialiseExpVector(expansions);
186 SetupCoeffPhys(DeclareCoeffPhysArrays);
189 CreateCollections(ImpType);
210ExpList::ExpList(
const LibUtilities::SessionReaderSharedPtr &pSession,
211 const SpatialDomains::ExpansionInfoMap &expansions,
212 const bool DeclareCoeffPhysArrays,
213 const Collections::ImplementationType ImpType)
214 : m_comm(pSession->GetComm()), m_session(pSession), m_physState(false),
215 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
220 InitialiseExpVector(expansions);
223 SetupCoeffPhys(DeclareCoeffPhysArrays);
226 CreateCollections(ImpType);
232ExpList::ExpList(SpatialDomains::PointGeom *geom)
233 : m_expType(
e0D), m_ncoeffs(1), m_npoints(1), m_physState(false),
234 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
238 LocalRegions::PointExpSharedPtr
Point =
239 MemoryManager<LocalRegions::PointExp>::AllocateSharedPtr(geom);
240 (*m_exp).push_back(Point);
269 const LibUtilities::SessionReaderSharedPtr &pSession,
270 const Array<OneD, const ExpListSharedPtr> &bndConstraint,
271 const Array<OneD, const SpatialDomains::BoundaryConditionShPtr> &bndCond,
272 const LocalRegions::ExpansionVector &locexp,
273 const SpatialDomains::MeshGraphSharedPtr &graph,
274 const LibUtilities::CommSharedPtr &comm,
const bool DeclareCoeffPhysArrays,
275 [[maybe_unused]]
const std::string variable,
276 [[maybe_unused]]
const Collections::ImplementationType ImpType)
277 : m_comm(comm), m_session(pSession), m_graph(graph), m_physState(false),
278 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
282 int i, j, id, elmtid = 0;
285 SpatialDomains::PointGeom *PointGeom;
286 SpatialDomains::Geometry1D *segGeom;
287 SpatialDomains::Geometry2D *FaceGeom;
288 SpatialDomains::QuadGeom *QuadGeom;
289 SpatialDomains::TriGeom *TriGeom;
291 LocalRegions::ExpansionSharedPtr exp;
292 LocalRegions::Expansion0DSharedPtr exp0D;
293 LocalRegions::Expansion1DSharedPtr exp1D;
294 LocalRegions::Expansion2DSharedPtr exp2D;
295 LocalRegions::Expansion3DSharedPtr exp3D;
297 map<int, vector<SpatialDomains::ExpansionInfoShPtr>> ExpOrder;
298 LibUtilities::BasisKeyVector PtBvec;
300 bool DoOptOnCollection =
301 m_session->DefinesCmdLineArgument(
"no-exp-opt") ? false :
true;
303 for (i = 0; i < bndCond.size(); ++i)
305 if (bndCond[i]->GetBoundaryConditionType() ==
306 SpatialDomains::eDirichlet)
309 for (j = 0; j < bndConstraint[i]->GetExpSize(); ++j)
311 SpatialDomains::ExpansionInfoShPtr eInfo =
312 MemoryManager<SpatialDomains::ExpansionInfo>::
314 bndConstraint[i]->GetExp(j)->GetGeom(), PtBvec);
317 std::dynamic_pointer_cast<LocalRegions::Expansion1D>(
318 bndConstraint[i]->GetExp(j))))
320 LibUtilities::BasisKey bkey =
321 exp1D->GetBasis(0)->GetBasisKey();
322 eInfo->m_basisKeyVector.push_back(bkey);
324 else if ((exp2D = std::dynamic_pointer_cast<
325 LocalRegions::Expansion2D>(
326 bndConstraint[i]->GetExp(j))))
328 LibUtilities::BasisKey bkey0 =
329 exp2D->GetBasis(0)->GetBasisKey();
330 LibUtilities::BasisKey bkey1 =
331 exp2D->GetBasis(1)->GetBasisKey();
333 eInfo->m_basisKeyVector.push_back(bkey0);
334 eInfo->m_basisKeyVector.push_back(bkey1);
341 if (DoOptOnCollection && IsNot0D)
344 for (i = 0; i < cnt; ++i)
346 if ((eInfo->m_basisKeyVector ==
347 ExpOrder[i][0]->m_basisKeyVector) &&
348 (eInfo->m_geomPtr->GetGeomFactors()->GetGtype() ==
350 ->m_geomPtr->GetGeomFactors()
353 ExpOrder[i].push_back(eInfo);
360 ExpOrder[cnt++].push_back(eInfo);
365 ExpOrder[0].push_back(eInfo);
372 for (
auto &ordIt : ExpOrder)
374 for (
auto &eit : ordIt.second)
378 dynamic_cast<SpatialDomains::PointGeom *
>(eit->m_geomPtr)))
382 exp = MemoryManager<LocalRegions::PointExp>::AllocateSharedPtr(
384 tracesDone.insert(PointGeom->GetGlobalID());
386 else if ((segGeom =
dynamic_cast<SpatialDomains::SegGeom *
>(
391 exp = MemoryManager<LocalRegions::SegExp>::AllocateSharedPtr(
392 eit->m_basisKeyVector[0], segGeom);
393 tracesDone.insert(segGeom->GetGlobalID());
395 else if ((TriGeom =
dynamic_cast<SpatialDomains::TriGeom *
>(
400 exp = MemoryManager<LocalRegions::TriExp>::AllocateSharedPtr(
401 eit->m_basisKeyVector[0], eit->m_basisKeyVector[1],
404 tracesDone.insert(TriGeom->GetGlobalID());
406 else if ((QuadGeom =
dynamic_cast<SpatialDomains::QuadGeom *
>(
410 exp = MemoryManager<LocalRegions::QuadExp>::AllocateSharedPtr(
411 eit->m_basisKeyVector[0], eit->m_basisKeyVector[1],
414 tracesDone.insert(QuadGeom->GetGlobalID());
418 exp->SetElmtId(elmtid++);
421 (*m_exp).push_back(exp);
425 map<int, pair<SpatialDomains::Geometry1D *, LibUtilities::BasisKey>>
428 map<int, pair<SpatialDomains::Geometry2D *,
429 pair<LibUtilities::BasisKey, LibUtilities::BasisKey>>>
432 for (i = 0; i < locexp.size(); ++i)
434 if ((exp1D = std::dynamic_pointer_cast<LocalRegions::Expansion1D>(
439 for (j = 0; j < 2; ++j)
441 PointGeom = (exp1D->GetGeom1D())->GetVertex(j);
442 id = PointGeom->GetGlobalID();
445 if (tracesDone.count(
id) != 0)
450 exp = MemoryManager<LocalRegions::PointExp>::AllocateSharedPtr(
452 tracesDone.insert(
id);
453 exp->SetElmtId(elmtid++);
454 (*m_exp).push_back(exp);
457 else if ((exp2D = std::dynamic_pointer_cast<LocalRegions::Expansion2D>(
461 for (j = 0; j < locexp[i]->GetNtraces(); ++j)
463 segGeom = exp2D->GetGeom2D()->GetEdge(j);
464 id = segGeom->GetGlobalID();
466 if (tracesDone.count(
id) != 0)
471 auto it = edgeOrders.find(
id);
473 if (it == edgeOrders.end())
475 edgeOrders.insert(std::make_pair(
476 id, std::make_pair(segGeom,
477 locexp[i]->GetTraceBasisKey(j))));
481 LibUtilities::BasisKey edge =
482 locexp[i]->GetTraceBasisKey(j);
483 LibUtilities::BasisKey existing = it->second.second;
485 int np1 = LibUtilities::GetDegreeOfExactness(
486 edge.GetPointsType(), edge.GetNumPoints());
487 int np2 = LibUtilities::GetDegreeOfExactness(
488 existing.GetPointsType(), existing.GetNumPoints());
489 int nm1 = edge.GetNumModes();
490 int nm2 = existing.GetNumModes();
498 if (np2 >= np1 && nm2 >= nm1)
502 else if (np2 <= np1 && nm2 <= nm1)
504 it->second.second = edge;
509 "inappropriate number of points/modes (max"
510 "num of points is not set with max order)");
515 else if ((exp3D = dynamic_pointer_cast<LocalRegions::Expansion3D>(
519 for (j = 0; j < exp3D->GetNtraces(); ++j)
521 FaceGeom = exp3D->GetGeom3D()->GetFace(j);
522 id = FaceGeom->GetGlobalID();
524 if (tracesDone.count(
id) != 0)
528 auto it = faceOrders.find(
id);
530 if (it == faceOrders.end())
534 LibUtilities::BasisKey face_dir0 =
535 locexp[i]->GetTraceBasisKey(j, 0);
536 LibUtilities::BasisKey face_dir1 =
537 locexp[i]->GetTraceBasisKey(j, 1);
542 if (locexp[i]->GetTraceOrient(j) >= 9)
544 std::swap(face_dir0, face_dir1);
547 faceOrders.insert(std::make_pair(
549 std::make_pair(FaceGeom,
550 std::make_pair(face_dir0, face_dir1))));
554 LibUtilities::BasisKey face0 =
555 locexp[i]->GetTraceBasisKey(j, 0);
556 LibUtilities::BasisKey face1 =
557 locexp[i]->GetTraceBasisKey(j, 1);
558 LibUtilities::BasisKey existing0 = it->second.second.first;
559 LibUtilities::BasisKey existing1 = it->second.second.second;
570 int np00 = LibUtilities::GetDegreeOfExactness(
571 face0.GetPointsType(), face0.GetNumPoints());
572 int np01 = LibUtilities::GetDegreeOfExactness(
573 face1.GetPointsType(), face1.GetNumPoints());
574 int np10 = LibUtilities::GetDegreeOfExactness(
575 existing0.GetPointsType(), existing0.GetNumPoints());
576 int np11 = LibUtilities::GetDegreeOfExactness(
577 existing1.GetPointsType(), existing1.GetNumPoints());
578 int nm00 = face0.GetNumModes();
579 int nm01 = face1.GetNumModes();
580 int nm10 = existing0.GetNumModes();
581 int nm11 = existing1.GetNumModes();
590 if (locexp[i]->GetTraceOrient(j) >= 9)
592 std::swap(np00, np01);
593 std::swap(nm00, nm01);
594 std::swap(face0, face1);
600 if (np11 >= np01 && nm11 >= nm01)
604 else if (np11 <= np01 && nm11 <= nm01)
608 LibUtilities::BasisKey newbkey(existing1.GetBasisType(),
610 face1.GetPointsKey());
611 it->second.second.second = newbkey;
616 "inappropriate number of points/modes (max"
617 "num of points is not set with max order)");
620 if (np10 >= np00 && nm10 >= nm00)
624 else if (np10 <= np00 && nm10 <= nm00)
628 LibUtilities::BasisKey newbkey(existing0.GetBasisType(),
630 face0.GetPointsKey());
631 it->second.second.first = newbkey;
636 "inappropriate number of points/modes (max"
637 "num of points is not set with max order)");
644 int nproc = m_comm->GetRowComm()->GetSize();
645 int tracepr = m_comm->GetRowComm()->GetRank();
652 for (i = 0; i < locexp.size(); ++i)
654 tCnt += locexp[i]->GetNtraces();
659 Array<OneD, int> tracesCnt(nproc, 0);
660 tracesCnt[tracepr] = tCnt;
661 m_comm->GetRowComm()->AllReduce(tracesCnt, LibUtilities::ReduceSum);
664 int totTraceCnt =
Vmath::Vsum(nproc, tracesCnt, 1);
665 Array<OneD, int> tTotOffsets(nproc, 0);
667 for (i = 1; i < nproc; ++i)
669 tTotOffsets[i] = tTotOffsets[i - 1] + tracesCnt[i - 1];
674 Array<OneD, int> TracesTotID(totTraceCnt, 0);
675 Array<OneD, int> TracesTotNm0(totTraceCnt, 0);
676 Array<OneD, int> TracesTotNm1(totTraceCnt, 0);
677 Array<OneD, int> TracesTotPnts0(totTraceCnt, 0);
678 Array<OneD, int> TracesTotPnts1(totTraceCnt, 0);
679 Array<OneD, int> TracesPointsType0(totTraceCnt, 0);
680 Array<OneD, int> TracesPointsType1(totTraceCnt, 0);
691 int cntr = tTotOffsets[tracepr];
693 for (i = 0; i < locexp.size(); ++i)
695 if ((exp2D = locexp[i]->as<LocalRegions::Expansion2D>()))
697 int nedges = locexp[i]->GetNtraces();
699 for (j = 0; j < nedges; ++j, ++cntr)
701 LibUtilities::BasisKey bkeyEdge =
702 locexp[i]->GetTraceBasisKey(j);
703 TracesTotID[cntr] = exp2D->GetGeom2D()->GetEid(j);
704 TracesTotNm0[cntr] = bkeyEdge.GetNumModes();
705 TracesTotPnts0[cntr] = bkeyEdge.GetNumPoints();
706 TracesPointsType0[cntr] =
707 static_cast<int>(bkeyEdge.GetPointsType());
712 else if ((exp3D = locexp[i]->as<LocalRegions::Expansion3D>()))
714 int nfaces = locexp[i]->GetNtraces();
716 for (j = 0; j < nfaces; ++j, ++cntr)
718 LibUtilities::BasisKey face_dir0 =
719 locexp[i]->GetTraceBasisKey(j, 0);
720 LibUtilities::BasisKey face_dir1 =
721 locexp[i]->GetTraceBasisKey(j, 1);
726 if (locexp[i]->GetTraceOrient(j) >= 9)
728 std::swap(face_dir0, face_dir1);
731 TracesTotID[cntr] = exp3D->GetGeom3D()->GetFid(j);
732 TracesTotNm0[cntr] = face_dir0.GetNumModes();
733 TracesTotNm1[cntr] = face_dir1.GetNumModes();
734 TracesTotPnts0[cntr] = face_dir0.GetNumPoints();
735 TracesTotPnts1[cntr] = face_dir1.GetNumPoints();
736 TracesPointsType0[cntr] =
737 static_cast<int>(face_dir0.GetPointsType());
738 TracesPointsType1[cntr] =
739 static_cast<int>(face_dir1.GetPointsType());
744 m_comm->GetRowComm()->AllReduce(TracesTotID, LibUtilities::ReduceSum);
745 m_comm->GetRowComm()->AllReduce(TracesTotNm0, LibUtilities::ReduceSum);
746 m_comm->GetRowComm()->AllReduce(TracesTotPnts0,
747 LibUtilities::ReduceSum);
748 m_comm->GetRowComm()->AllReduce(TracesPointsType0,
749 LibUtilities::ReduceSum);
750 if (m_expType == e2D)
752 m_comm->GetRowComm()->AllReduce(TracesTotNm1,
753 LibUtilities::ReduceSum);
754 m_comm->GetRowComm()->AllReduce(TracesTotPnts1,
755 LibUtilities::ReduceSum);
756 m_comm->GetRowComm()->AllReduce(TracesPointsType1,
757 LibUtilities::ReduceSum);
764 if (edgeOrders.size())
766 for (i = 0; i < totTraceCnt; ++i)
768 auto it = edgeOrders.find(TracesTotID[i]);
770 if (it == edgeOrders.end())
775 LibUtilities::BasisKey existing = it->second.second;
778 static_cast<LibUtilities::PointsType
>(TracesPointsType0[i]);
780 int np1 = LibUtilities::GetDegreeOfExactness(ptype,
782 int np2 = LibUtilities::GetDegreeOfExactness(
783 existing.GetPointsType(), existing.GetNumPoints());
784 int nm1 = TracesTotNm0[i];
785 int nm2 = existing.GetNumModes();
789 if (np2 >= np1 && nm2 >= nm1)
793 else if (np2 <= np1 && nm2 <= nm1)
797 LibUtilities::BasisKey newbkey(
798 existing.GetBasisType(), nm1,
799 LibUtilities::PointsKey(TracesTotPnts0[i], ptype));
800 it->second.second = newbkey;
805 "inappropriate number of points/modes (max "
806 "num of points is not set with max order)");
810 else if (faceOrders.size())
812 for (i = 0; i < totTraceCnt; ++i)
814 auto it = faceOrders.find(TracesTotID[i]);
816 if (it == faceOrders.end())
821 LibUtilities::BasisKey existing0 = it->second.second.first;
822 LibUtilities::BasisKey existing1 = it->second.second.second;
827 static_cast<LibUtilities::PointsType
>(TracesPointsType0[i]);
829 static_cast<LibUtilities::PointsType
>(TracesPointsType1[i]);
831 int np00 = LibUtilities::GetDegreeOfExactness(
832 ptype0, TracesTotPnts0[i]);
833 int np01 = LibUtilities::GetDegreeOfExactness(
834 ptype1, TracesTotPnts1[i]);
835 int np10 = LibUtilities::GetDegreeOfExactness(
836 existing0.GetPointsType(), existing0.GetNumPoints());
837 int np11 = LibUtilities::GetDegreeOfExactness(
838 existing1.GetPointsType(), existing1.GetNumPoints());
839 int nm00 = TracesTotNm0[i];
840 int nm01 = TracesTotNm1[i];
841 int nm10 = existing0.GetNumModes();
842 int nm11 = existing1.GetNumModes();
847 if (np11 >= np01 && nm11 >= nm01)
851 else if (np11 <= np01 && nm11 <= nm01)
853 LibUtilities::BasisKey newbkey(
854 existing1.GetBasisType(), nm01,
855 LibUtilities::PointsKey(TracesTotPnts1[i], ptype1));
856 it->second.second.second = newbkey;
861 "inappropriate number of points/modes (max"
862 "num of points is not set with max order)");
865 if (np10 >= np00 && nm10 >= nm00)
869 else if (np10 <= np00 && nm10 <= nm00)
871 LibUtilities::BasisKey newbkey(
872 existing0.GetBasisType(), nm00,
873 LibUtilities::PointsKey(TracesTotPnts0[i], ptype0));
874 it->second.second.first = newbkey;
879 "inappropriate number of points/modes (max"
880 "num of points is not set with max order)");
886 if (edgeOrders.size())
888 map<int, vector<int>> opt;
891 if (DoOptOnCollection)
893 for (
auto &it : edgeOrders)
896 for (i = 0; i < cnt; ++i)
898 auto it1 = edgeOrders.find(opt[i][0]);
900 if ((it.second.second == it1->second.second) &&
901 (it.second.first->GetGeomFactors()->GetGtype() ==
902 it1->second.first->GetGeomFactors()->GetGtype()))
904 opt[i].push_back(it.first);
911 opt[cnt++].push_back(it.first);
917 for (
auto &it : edgeOrders)
919 opt[0].push_back(it.first);
923 for (
int i = 0; i < opt.size(); ++i)
926 for (
int j = 0; j < opt[i].size(); ++j)
928 auto it = edgeOrders.find(opt[i][j]);
930 exp = MemoryManager<LocalRegions::SegExp>::AllocateSharedPtr(
931 it->second.second, it->second.first);
933 exp->SetElmtId(elmtid++);
934 (*m_exp).push_back(exp);
940 map<int, vector<int>> opt;
943 if (DoOptOnCollection)
945 for (
auto &it : faceOrders)
948 for (i = 0; i < cnt; ++i)
950 auto it1 = faceOrders.find(opt[i][0]);
952 if ((it.second.second.first == it1->second.second.first) &&
953 (it.second.second.second ==
954 it1->second.second.second) &&
955 (it.second.first->GetGeomFactors()->GetGtype() ==
956 it1->second.first->GetGeomFactors()->GetGtype()))
958 opt[i].push_back(it.first);
965 opt[cnt++].push_back(it.first);
971 for (
auto &it : faceOrders)
973 opt[0].push_back(it.first);
977 for (
int i = 0; i < opt.size(); ++i)
980 for (
int j = 0; j < opt[i].size(); ++j)
982 auto it = faceOrders.find(opt[i][j]);
984 FaceGeom = it->second.first;
987 dynamic_cast<SpatialDomains::QuadGeom *
>(FaceGeom)))
990 MemoryManager<LocalRegions::QuadExp>::AllocateSharedPtr(
991 it->second.second.first, it->second.second.second,
994 else if ((TriGeom =
dynamic_cast<SpatialDomains::TriGeom *
>(
998 MemoryManager<LocalRegions::TriExp>::AllocateSharedPtr(
999 it->second.second.first, it->second.second.second,
1002 exp->SetElmtId(elmtid++);
1003 (*m_exp).push_back(exp);
1009 SetupCoeffPhys(DeclareCoeffPhysArrays);
1012 if (m_expType != e0D)
1014 CreateCollections(ImpType);
1021 for (
int i = (*m_exp).size() - 1; i >= 0; --i)
1023 m_elmtToExpId[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
1040ExpList::ExpList(
const LibUtilities::SessionReaderSharedPtr &pSession,
1041 const LocalRegions::ExpansionVector &locexp,
1042 const SpatialDomains::MeshGraphSharedPtr &graph,
1043 const bool DeclareCoeffPhysArrays,
1044 [[maybe_unused]]
const std::string variable,
1045 [[maybe_unused]]
const Collections::ImplementationType ImpType)
1046 : m_comm(pSession->GetComm()), m_session(pSession), m_graph(graph),
1048 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
1052 int i, j, elmtid = 0;
1054 SpatialDomains::PointGeom *PointGeom;
1055 SpatialDomains::Geometry1D *segGeom;
1056 SpatialDomains::Geometry2D *FaceGeom;
1057 SpatialDomains::QuadGeom *QuadGeom;
1058 SpatialDomains::TriGeom *TriGeom;
1060 LocalRegions::ExpansionSharedPtr exp;
1061 LocalRegions::Expansion0DSharedPtr exp0D;
1062 LocalRegions::Expansion1DSharedPtr exp1D;
1063 LocalRegions::Expansion2DSharedPtr exp2D;
1064 LocalRegions::Expansion3DSharedPtr exp3D;
1066 for (i = 0; i < locexp.size(); ++i)
1068 if ((exp1D = std::dynamic_pointer_cast<LocalRegions::Expansion1D>(
1073 for (j = 0; j < 2; ++j)
1075 PointGeom = (exp1D->GetGeom1D())->GetVertex(j);
1077 exp = MemoryManager<LocalRegions::PointExp>::AllocateSharedPtr(
1079 exp->SetElmtId(elmtid++);
1080 (*m_exp).push_back(exp);
1083 else if ((exp2D = std::dynamic_pointer_cast<LocalRegions::Expansion2D>(
1087 LibUtilities::BasisKey edgeKey0 =
1088 locexp[i]->GetBasis(0)->GetBasisKey();
1090 for (j = 0; j < locexp[i]->GetNtraces(); ++j)
1092 segGeom = exp2D->GetGeom2D()->GetEdge(j);
1094 int dir = exp2D->GetGeom2D()->GetDir(j);
1096 if (locexp[i]->GetNtraces() == 3)
1098 LibUtilities::BasisKey edgeKey =
1099 locexp[i]->GetBasis(dir)->GetBasisKey();
1101 LibUtilities::BasisKey nEdgeKey(edgeKey0.GetBasisType(),
1102 edgeKey.GetNumModes(),
1103 edgeKey.GetPointsKey());
1106 MemoryManager<LocalRegions::SegExp>::AllocateSharedPtr(
1112 MemoryManager<LocalRegions::SegExp>::AllocateSharedPtr(
1113 locexp[i]->GetBasis(dir)->GetBasisKey(), segGeom);
1116 exp->SetElmtId(elmtid++);
1117 (*m_exp).push_back(exp);
1120 else if ((exp3D = dynamic_pointer_cast<LocalRegions::Expansion3D>(
1125 LibUtilities::BasisKey face0_dir0 =
1126 locexp[i]->GetBasis(0)->GetBasisKey();
1127 LibUtilities::BasisKey face0_dir1 =
1128 locexp[i]->GetBasis(1)->GetBasisKey();
1130 for (j = 0; j < exp3D->GetNtraces(); ++j)
1132 FaceGeom = exp3D->GetGeom3D()->GetFace(j);
1134 int dir0 = exp3D->GetGeom3D()->GetDir(j, 0);
1135 int dir1 = exp3D->GetGeom3D()->GetDir(j, 1);
1137 LibUtilities::BasisKey face_dir0 =
1138 locexp[i]->GetBasis(dir0)->GetBasisKey();
1139 LibUtilities::BasisKey face_dir1 =
1140 locexp[i]->GetBasis(dir1)->GetBasisKey();
1143 dynamic_cast<SpatialDomains::QuadGeom *
>(FaceGeom)))
1146 MemoryManager<LocalRegions::QuadExp>::AllocateSharedPtr(
1147 face_dir0, face_dir1, QuadGeom);
1149 else if ((TriGeom =
dynamic_cast<SpatialDomains::TriGeom *
>(
1152 LibUtilities::BasisKey nface_dir0(face0_dir0.GetBasisType(),
1153 face_dir0.GetNumModes(),
1154 face_dir0.GetPointsKey());
1155 LibUtilities::BasisKey nface_dir1(face0_dir1.GetBasisType(),
1156 face_dir1.GetNumModes(),
1157 face_dir1.GetPointsKey());
1159 MemoryManager<LocalRegions::TriExp>::AllocateSharedPtr(
1160 nface_dir0, nface_dir1, TriGeom);
1162 exp->SetElmtId(elmtid++);
1163 (*m_exp).push_back(exp);
1169 SetupCoeffPhys(DeclareCoeffPhysArrays);
1172 if (m_expType != e0D)
1174 CreateCollections(ImpType);
1203ExpList::ExpList(
const LibUtilities::SessionReaderSharedPtr &pSession,
1204 const SpatialDomains::CompositeMap &domain,
1205 const SpatialDomains::MeshGraphSharedPtr &graph,
1206 const bool DeclareCoeffPhysArrays,
const std::string variable,
1207 bool SetToOneSpaceDimension,
1208 const LibUtilities::CommSharedPtr comm,
1209 const Collections::ImplementationType ImpType)
1210 : m_comm(comm), m_session(pSession), m_graph(graph), m_physState(false),
1211 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
1216 SpatialDomains::PointGeom *PtGeom;
1217 SpatialDomains::SegGeom *SegGeom;
1218 SpatialDomains::TriGeom *TriGeom;
1219 SpatialDomains::QuadGeom *QuadGeom;
1221 LocalRegions::ExpansionSharedPtr exp;
1223 LibUtilities::PointsType TriNb;
1225 int meshdim = graph->GetMeshDimension();
1228 const SpatialDomains::ExpansionInfoMap &expansions =
1229 graph->GetExpansionInfo(variable);
1230 map<int, vector<SpatialDomains::ExpansionInfoShPtr>> ExpOrder;
1231 LibUtilities::BasisKeyVector PtBvec;
1233 bool UseGLLOnTri =
false;
1235 pSession->MatchSolverInfo(
"Projection",
"Continuous", UseGLLOnTri,
false);
1237 bool DoOptOnCollection =
1238 m_session->DefinesCmdLineArgument(
"no-exp-opt") ? false :
true;
1240 for (
auto &compIt : domain)
1242 bool IsNot0D =
true;
1244 for (j = 0; j < compIt.second->m_geomVec.size(); ++j)
1246 LibUtilities::BasisKeyVector def;
1247 SpatialDomains::ExpansionInfoShPtr eInfo =
1248 MemoryManager<SpatialDomains::ExpansionInfo>::AllocateSharedPtr(
1249 compIt.second->m_geomVec[j], PtBvec);
1251 if ((SegGeom =
dynamic_cast<SpatialDomains::SegGeom *
>(
1252 compIt.second->m_geomVec[j])))
1256 auto expInfo = expansions.find(SegGeom->GetGlobalID());
1257 eInfo = expInfo->second;
1262 SpatialDomains::GeometryLinkSharedPtr elmts =
1263 graph->GetElementsFromEdge(SegGeom);
1268 SpatialDomains::Geometry *geom = elmts->at(0).first;
1269 int edge_id = elmts->at(0).second;
1270 SpatialDomains::ExpansionInfoShPtr expInfo =
1271 graph->GetExpansionInfo(geom, variable);
1272 LibUtilities::BasisKey Ba = expInfo->m_basisKeyVector[0];
1273 LibUtilities::BasisKey Bb = expInfo->m_basisKeyVector[1];
1274 StdRegions::StdExpansionSharedPtr elmtStdExp;
1276 if (geom->GetShapeType() == LibUtilities::eTriangle)
1278 elmtStdExp = MemoryManager<
1279 StdRegions::StdTriExp>::AllocateSharedPtr(Ba, Bb);
1281 else if (geom->GetShapeType() ==
1282 LibUtilities::eQuadrilateral)
1284 elmtStdExp = MemoryManager<
1285 StdRegions::StdQuadExp>::AllocateSharedPtr(Ba, Bb);
1290 "Fail to cast geom to a known 2D shape.");
1294 eInfo->m_basisKeyVector.push_back(
1295 elmtStdExp->GetTraceBasisKey(edge_id));
1298 else if ((TriGeom =
dynamic_cast<SpatialDomains::TriGeom *
>(
1299 compIt.second->m_geomVec[j])))
1302 SpatialDomains::GeometryLinkSharedPtr elmts =
1303 graph->GetElementsFromFace(TriGeom);
1307 SpatialDomains::Geometry *geom = elmts->at(0).first;
1308 int face_id = elmts->at(0).second;
1309 auto expInfo = expansions.find(geom->GetGlobalID());
1310 if (expInfo == expansions.end())
1313 "Failed to find expansion info for goemetry id: " +
1314 std::to_string(geom->GetGlobalID()));
1318 LibUtilities::BasisKey Ba =
1319 expInfo->second->m_basisKeyVector[0];
1320 LibUtilities::BasisKey Bb =
1321 expInfo->second->m_basisKeyVector[1];
1322 LibUtilities::BasisKey Bc =
1323 expInfo->second->m_basisKeyVector[2];
1324 StdRegions::StdExpansionSharedPtr elmtStdExp;
1326 if (geom->GetShapeType() == LibUtilities::ePrism)
1328 elmtStdExp = MemoryManager<
1329 StdRegions::StdPrismExp>::AllocateSharedPtr(Ba, Bb,
1332 else if (geom->GetShapeType() == LibUtilities::eTetrahedron)
1334 elmtStdExp = MemoryManager<
1335 StdRegions::StdTetExp>::AllocateSharedPtr(Ba, Bb,
1338 else if (geom->GetShapeType() == LibUtilities::ePyramid)
1340 elmtStdExp = MemoryManager<
1341 StdRegions::StdPyrExp>::AllocateSharedPtr(Ba, Bb,
1347 "Fail to cast geom to a known 3D shape.");
1351 LibUtilities::BasisKey TriBa =
1352 elmtStdExp->GetTraceBasisKey(face_id, 0, UseGLLOnTri);
1353 LibUtilities::BasisKey TriBb =
1354 elmtStdExp->GetTraceBasisKey(face_id, 1, UseGLLOnTri);
1356 if (geom->GetForient(face_id) >= 9)
1358 std::swap(TriBa, TriBb);
1361 eInfo->m_basisKeyVector.push_back(TriBa);
1362 eInfo->m_basisKeyVector.push_back(TriBb);
1365 else if ((QuadGeom =
dynamic_cast<SpatialDomains::QuadGeom *
>(
1366 compIt.second->m_geomVec[j])))
1369 SpatialDomains::GeometryLinkSharedPtr elmts =
1370 graph->GetElementsFromFace(QuadGeom);
1374 SpatialDomains::Geometry *geom = elmts->at(0).first;
1375 int face_id = elmts->at(0).second;
1376 auto expInfo = expansions.find(geom->GetGlobalID());
1377 if (expInfo == expansions.end())
1380 "Failed to find expansion info for goemetry id: " +
1381 std::to_string(geom->GetGlobalID()));
1385 LibUtilities::BasisKey Ba =
1386 expInfo->second->m_basisKeyVector[0];
1387 LibUtilities::BasisKey Bb =
1388 expInfo->second->m_basisKeyVector[1];
1389 LibUtilities::BasisKey Bc =
1390 expInfo->second->m_basisKeyVector[2];
1391 StdRegions::StdExpansionSharedPtr elmtStdExp;
1393 if (geom->GetShapeType() == LibUtilities::ePrism)
1395 elmtStdExp = MemoryManager<
1396 StdRegions::StdPrismExp>::AllocateSharedPtr(Ba, Bb,
1399 else if (geom->GetShapeType() == LibUtilities::eHexahedron)
1401 elmtStdExp = MemoryManager<
1402 StdRegions::StdHexExp>::AllocateSharedPtr(Ba, Bb,
1405 else if (geom->GetShapeType() == LibUtilities::ePyramid)
1407 elmtStdExp = MemoryManager<
1408 StdRegions::StdPyrExp>::AllocateSharedPtr(Ba, Bb,
1414 "Fail to cast geom to a known 3D shape.");
1418 LibUtilities::BasisKey QuadBa =
1419 elmtStdExp->GetTraceBasisKey(face_id, 0);
1420 LibUtilities::BasisKey QuadBb =
1421 elmtStdExp->GetTraceBasisKey(face_id, 1);
1423 if (geom->GetForient(face_id) >= 9)
1425 std::swap(QuadBa, QuadBb);
1428 eInfo->m_basisKeyVector.push_back(QuadBa);
1429 eInfo->m_basisKeyVector.push_back(QuadBb);
1437 if (DoOptOnCollection && IsNot0D)
1440 for (i = 0; i < cnt; ++i)
1442 if ((eInfo->m_basisKeyVector ==
1443 ExpOrder[i][0]->m_basisKeyVector) &&
1444 (eInfo->m_geomPtr->GetGeomFactors()->GetGtype() ==
1446 ->m_geomPtr->GetGeomFactors()
1449 ExpOrder[i].push_back(eInfo);
1456 ExpOrder[cnt++].push_back(eInfo);
1461 ExpOrder[0].push_back(eInfo);
1467 for (
auto &ordIt : ExpOrder)
1469 for (
auto &eit : ordIt.second)
1473 dynamic_cast<SpatialDomains::PointGeom *
>(eit->m_geomPtr)))
1477 exp = MemoryManager<LocalRegions::PointExp>::AllocateSharedPtr(
1480 else if ((SegGeom =
dynamic_cast<SpatialDomains::SegGeom *
>(
1485 if (SetToOneSpaceDimension)
1487 SpatialDomains::SegGeomUniquePtr OneDSegmentGeom =
1488 SegGeom->GenerateOneSpaceDimGeom(m_holder);
1491 MemoryManager<LocalRegions::SegExp>::AllocateSharedPtr(
1492 eit->m_basisKeyVector[0], OneDSegmentGeom.get());
1493 m_holder.m_segVec.push_back(std::move(OneDSegmentGeom));
1498 MemoryManager<LocalRegions::SegExp>::AllocateSharedPtr(
1499 eit->m_basisKeyVector[0], SegGeom);
1502 else if ((TriGeom =
dynamic_cast<SpatialDomains::TriGeom *
>(
1507 if (eit->m_basisKeyVector[0].GetBasisType() ==
1508 LibUtilities::eGLL_Lagrange)
1510 TriNb = LibUtilities::eNodalTriElec;
1512 exp = MemoryManager<LocalRegions::NodalTriExp>::
1513 AllocateSharedPtr(eit->m_basisKeyVector[0],
1514 eit->m_basisKeyVector[1], TriNb,
1520 MemoryManager<LocalRegions::TriExp>::AllocateSharedPtr(
1521 eit->m_basisKeyVector[0], eit->m_basisKeyVector[1],
1525 else if ((QuadGeom =
dynamic_cast<SpatialDomains::QuadGeom *
>(
1530 exp = MemoryManager<LocalRegions::QuadExp>::AllocateSharedPtr(
1531 eit->m_basisKeyVector[0], eit->m_basisKeyVector[1],
1537 "dynamic cast to a Geom (possibly 3D) failed");
1540 exp->SetElmtId(elmtid++);
1541 (*m_exp).push_back(exp);
1546 SetupCoeffPhys(DeclareCoeffPhysArrays);
1548 if (m_expType != e0D)
1550 CreateCollections(ImpType);
1564void ExpList::SetupCoeffPhys(
bool DeclareCoeffPhysArrays,
bool SetupOffsets)
1571 m_coeff_offset = Array<OneD, int>(m_exp->size());
1572 m_phys_offset = Array<OneD, int>(m_exp->size());
1574 m_ncoeffs = m_npoints = 0;
1576 for (i = 0; i < m_exp->size(); ++i)
1578 m_coeff_offset[i] = m_ncoeffs;
1579 m_phys_offset[i] = m_npoints;
1580 m_ncoeffs += (*m_exp)[i]->GetNcoeffs();
1581 m_npoints += (*m_exp)[i]->GetTotPoints();
1585 if (DeclareCoeffPhysArrays)
1587 m_coeffs = Array<OneD, NekDouble>(m_ncoeffs, 0.0);
1588 m_phys = Array<OneD, NekDouble>(m_npoints, 0.0);
1591 m_coeffsToElmt = Array<OneD, pair<int, int>>{size_t(m_ncoeffs)};
1593 for (
int i = 0; i < m_exp->size(); ++i)
1595 int coeffs_offset = m_coeff_offset[i];
1597 int loccoeffs = (*m_exp)[i]->GetNcoeffs();
1599 for (
int j = 0; j < loccoeffs; ++j)
1601 m_coeffsToElmt[coeffs_offset + j].first = i;
1602 m_coeffsToElmt[coeffs_offset + j].second = j;
1621void ExpList::InitialiseExpVector(
1622 const SpatialDomains::ExpansionInfoMap &expmap)
1624 SpatialDomains::SegGeom *SegmentGeom;
1625 SpatialDomains::TriGeom *TriangleGeom;
1626 SpatialDomains::QuadGeom *QuadrilateralGeom;
1627 SpatialDomains::TetGeom *TetGeom;
1628 SpatialDomains::HexGeom *HexGeom;
1629 SpatialDomains::PrismGeom *PrismGeom;
1630 SpatialDomains::PyrGeom *PyrGeom;
1633 LocalRegions::ExpansionSharedPtr exp;
1635 bool DoOptOnCollection =
1636 m_session->DefinesCmdLineArgument(
"no-exp-opt") ? false :
true;
1637 map<int, vector<int>> ExpOrder;
1638 if (DoOptOnCollection)
1640 auto expIt = expmap.begin();
1643 ExpOrder[cnt++].push_back(expIt->first);
1647 for (; expIt != expmap.end(); ++expIt)
1650 for (i = 0; i < cnt; ++i)
1652 const SpatialDomains::ExpansionInfoShPtr expInfo =
1653 expmap.find(ExpOrder[i][0])->second;
1655 if ((expIt->second->m_basisKeyVector ==
1656 expInfo->m_basisKeyVector) &&
1657 (expIt->second->m_geomPtr->GetGeomFactors()->GetGtype() ==
1658 expInfo->m_geomPtr->GetGeomFactors()->GetGtype()))
1660 ExpOrder[i].push_back(expIt->first);
1667 ExpOrder[cnt++].push_back(expIt->first);
1673 for (
auto &expIt : expmap)
1675 ExpOrder[0].push_back(expIt.first);
1682 for (
auto &it : ExpOrder)
1684 for (
int c = 0; c < it.second.size(); ++c)
1686 auto expIt = expmap.find(it.second[c]);
1688 const SpatialDomains::ExpansionInfoShPtr expInfo = expIt->second;
1690 switch (expInfo->m_basisKeyVector.size())
1694 ASSERTL1(m_expType == e1D || m_expType == eNoType,
1695 "Cannot mix expansion dimensions in one vector");
1698 if ((SegmentGeom =
dynamic_cast<SpatialDomains::SegGeom *
>(
1699 expInfo->m_geomPtr)))
1702 LibUtilities::BasisKey bkey =
1703 expInfo->m_basisKeyVector[0];
1705 exp = MemoryManager<LocalRegions::SegExp>::
1706 AllocateSharedPtr(bkey, SegmentGeom);
1711 "dynamic cast to a 1D Geom failed");
1717 ASSERTL1(m_expType == e2D || m_expType == eNoType,
1718 "Cannot mix expansion dimensions in one vector");
1721 LibUtilities::BasisKey Ba = expInfo->m_basisKeyVector[0];
1722 LibUtilities::BasisKey Bb = expInfo->m_basisKeyVector[1];
1725 dynamic_cast<SpatialDomains ::TriGeom *
>(
1726 expInfo->m_geomPtr)))
1729 if (Ba.GetBasisType() == LibUtilities::eGLL_Lagrange)
1731 LibUtilities::BasisKey newBa(LibUtilities::eOrtho_A,
1735 LibUtilities::PointsType TriNb =
1736 LibUtilities::eNodalTriElec;
1737 exp = MemoryManager<LocalRegions::NodalTriExp>::
1738 AllocateSharedPtr(newBa, Bb, TriNb,
1743 exp = MemoryManager<LocalRegions::TriExp>::
1744 AllocateSharedPtr(Ba, Bb, TriangleGeom);
1747 else if ((QuadrilateralGeom =
1748 dynamic_cast<SpatialDomains::QuadGeom *
>(
1749 expInfo->m_geomPtr)))
1751 exp = MemoryManager<LocalRegions::QuadExp>::
1752 AllocateSharedPtr(Ba, Bb, QuadrilateralGeom);
1757 "dynamic cast to a 2D Geom failed");
1763 ASSERTL1(m_expType == e3D || m_expType == eNoType,
1764 "Cannot mix expansion dimensions in one vector");
1767 LibUtilities::BasisKey Ba = expInfo->m_basisKeyVector[0];
1768 LibUtilities::BasisKey Bb = expInfo->m_basisKeyVector[1];
1769 LibUtilities::BasisKey Bc = expInfo->m_basisKeyVector[2];
1771 if ((TetGeom =
dynamic_cast<SpatialDomains::TetGeom *
>(
1772 expInfo->m_geomPtr)))
1774 if (Ba.GetBasisType() == LibUtilities::eGLL_Lagrange ||
1775 Ba.GetBasisType() == LibUtilities::eGauss_Lagrange)
1779 "LocalRegions::NodalTetExp is not implemented "
1784 exp = MemoryManager<LocalRegions::TetExp>::
1785 AllocateSharedPtr(Ba, Bb, Bc, TetGeom);
1788 else if ((PrismGeom =
1789 dynamic_cast<SpatialDomains ::PrismGeom *
>(
1790 expInfo->m_geomPtr)))
1792 exp = MemoryManager<LocalRegions::PrismExp>::
1793 AllocateSharedPtr(Ba, Bb, Bc, PrismGeom);
1795 else if ((PyrGeom =
dynamic_cast<SpatialDomains::PyrGeom *
>(
1796 expInfo->m_geomPtr)))
1798 exp = MemoryManager<
1799 LocalRegions::PyrExp>::AllocateSharedPtr(Ba, Bb, Bc,
1802 else if ((HexGeom =
dynamic_cast<SpatialDomains::HexGeom *
>(
1803 expInfo->m_geomPtr)))
1805 exp = MemoryManager<
1806 LocalRegions::HexExp>::AllocateSharedPtr(Ba, Bb, Bc,
1812 "dynamic cast to a Geom failed");
1818 "Dimension of basis key is greater than 3");
1822 m_elmtToExpId[exp->GetGeom()->GetGlobalID()] = id;
1823 exp->SetElmtId(
id++);
1826 (*m_exp).push_back(exp);
1851void ExpList::MultiplyByBlockMatrix(
const GlobalMatrixKey &gkey,
1852 const Array<OneD, const NekDouble> &inarray,
1853 Array<OneD, NekDouble> &outarray)
1857 int nrows = blockmat->GetRows();
1858 int ncols = blockmat->GetColumns();
1861 NekVector<NekDouble> in(ncols, inarray, eWrapper);
1862 NekVector<NekDouble> out(nrows, outarray, eWrapper);
1865 out = (*blockmat) * in;
1871void ExpList::MultiplyByQuadratureMetric(
1872 const Array<OneD, const NekDouble> &inarray,
1873 Array<OneD, NekDouble> &outarray)
1875 Array<OneD, NekDouble> e_outarray;
1877 for (
int i = 0; i < (*m_exp).size(); ++i)
1879 (*m_exp)[i]->MultiplyByQuadratureMetric(inarray + m_phys_offset[i],
1880 e_outarray = outarray +
1888void ExpList::DivideByQuadratureMetric(
1889 const Array<OneD, const NekDouble> &inarray,
1890 Array<OneD, NekDouble> &outarray)
1892 Array<OneD, NekDouble> e_outarray;
1894 for (
int i = 0; i < (*m_exp).size(); ++i)
1896 (*m_exp)[i]->DivideByQuadratureMetric(inarray + m_phys_offset[i],
1898 outarray + m_phys_offset[i]);
1915void ExpList::v_IProductWRTDerivBase(
1916 const int dir,
const Array<OneD, const NekDouble> &inarray,
1917 Array<OneD, NekDouble> &outarray)
1921 Array<OneD, NekDouble> e_outarray;
1922 for (i = 0; i < (*m_exp).size(); ++i)
1924 (*m_exp)[i]->IProductWRTDerivBase(dir, inarray + m_phys_offset[i],
1926 outarray + m_coeff_offset[i]);
1934void ExpList::IProductWRTDirectionalDerivBase(
1935 const Array<OneD, const NekDouble> &direction,
1936 const Array<OneD, const NekDouble> &inarray,
1937 Array<OneD, NekDouble> &outarray)
1940 int coordim = (*m_exp)[0]->GetGeom()->GetCoordim();
1941 int nq = direction.size() / coordim;
1943 Array<OneD, NekDouble> e_outarray;
1944 Array<OneD, NekDouble> e_MFdiv;
1946 Array<OneD, NekDouble> locdir;
1948 for (
int i = 0; i < (*m_exp).size(); ++i)
1950 npts_e = (*m_exp)[i]->GetTotPoints();
1951 locdir = Array<OneD, NekDouble>(npts_e * coordim);
1953 for (
int k = 0; k < coordim; ++k)
1955 Vmath::Vcopy(npts_e, &direction[k * nq + m_phys_offset[i]], 1,
1956 &locdir[k * npts_e], 1);
1959 (*m_exp)[i]->IProductWRTDirectionalDerivBase(
1960 locdir, inarray + m_phys_offset[i],
1961 e_outarray = outarray + m_coeff_offset[i]);
1976void ExpList::v_IProductWRTDerivBase(
1977 const Array<OneD,
const Array<OneD, NekDouble>> &inarray,
1978 Array<OneD, NekDouble> &outarray)
1980 Array<OneD, NekDouble> tmp0, tmp1, tmp2;
1982 int dim = GetCoordim(0);
1984 ASSERTL1(inarray.size() >= dim,
"inarray is not of sufficient dimension");
1987 if (m_collectionsDoInit[Collections::eIProductWRTDerivBase])
1989 for (
int i = 0; i < m_collections.size(); ++i)
1991 m_collections[i].Initialise(Collections::eIProductWRTDerivBase);
1993 m_collectionsDoInit[Collections::eIProductWRTDerivBase] =
false;
1996 LibUtilities::Timer timer;
1997 int input_offset{0};
1998 int output_offset{0};
2005 for (
int i = 0; i < m_collections.size(); ++i)
2007 m_collections[i].ApplyOperator(
2008 Collections::eIProductWRTDerivBase,
2009 inarray[0] + input_offset, tmp0 = outarray + output_offset);
2010 input_offset += m_collections[i].GetInputSize(
2011 Collections::eIProductWRTDerivBase);
2012 output_offset += m_collections[i].GetOutputSize(
2013 Collections::eIProductWRTDerivBase);
2017 for (
int i = 0; i < m_collections.size(); ++i)
2019 m_collections[i].ApplyOperator(
2020 Collections::eIProductWRTDerivBase,
2021 inarray[0] + input_offset, tmp0 = inarray[1] + input_offset,
2022 tmp1 = outarray + output_offset);
2023 input_offset += m_collections[i].GetInputSize(
2024 Collections::eIProductWRTDerivBase);
2025 output_offset += m_collections[i].GetOutputSize(
2026 Collections::eIProductWRTDerivBase);
2030 for (
int i = 0; i < m_collections.size(); ++i)
2032 m_collections[i].ApplyOperator(
2033 Collections::eIProductWRTDerivBase,
2034 inarray[0] + input_offset, tmp0 = inarray[1] + input_offset,
2035 tmp1 = inarray[2] + input_offset,
2036 tmp2 = outarray + output_offset);
2037 input_offset += m_collections[i].GetInputSize(
2038 Collections::eIProductWRTDerivBase);
2039 output_offset += m_collections[i].GetOutputSize(
2040 Collections::eIProductWRTDerivBase);
2044 NEKERROR(ErrorUtil::efatal,
"Dimension of inarray not correct");
2052 timer.AccumulateRegion(
"Collections:IProductWRTDerivBase", 10);
2088void ExpList::v_PhysDeriv(
const Array<OneD, const NekDouble> &inarray,
2089 Array<OneD, NekDouble> &out_d0,
2090 Array<OneD, NekDouble> &out_d1,
2091 Array<OneD, NekDouble> &out_d2)
2093 Array<OneD, NekDouble> e_out_d0;
2094 Array<OneD, NekDouble> e_out_d1;
2095 Array<OneD, NekDouble> e_out_d2;
2098 if (m_collectionsDoInit[Collections::ePhysDeriv])
2100 for (
int i = 0; i < m_collections.size(); ++i)
2102 m_collections[i].Initialise(Collections::ePhysDeriv);
2104 m_collectionsDoInit[Collections::ePhysDeriv] =
false;
2108 LibUtilities::Timer timer;
2110 for (
int i = 0; i < m_collections.size(); ++i)
2112 e_out_d0 = out_d0 + offset;
2113 e_out_d1 = out_d1 + offset;
2114 e_out_d2 = out_d2 + offset;
2115 m_collections[i].ApplyOperator(Collections::ePhysDeriv,
2116 inarray + offset, e_out_d0, e_out_d1,
2118 offset += m_collections[i].GetInputSize(Collections::ePhysDeriv);
2122 timer.AccumulateRegion(
"Collections:PhysDeriv", 10);
2125void ExpList::v_PhysDeriv(
const int dir,
2126 const Array<OneD, const NekDouble> &inarray,
2127 Array<OneD, NekDouble> &out_d)
2130 v_PhysDeriv(edir, inarray, out_d);
2133void ExpList::v_PhysDeriv(Direction edir,
2134 const Array<OneD, const NekDouble> &inarray,
2135 Array<OneD, NekDouble> &out_d)
2138 if (edir == MultiRegions::eS)
2140 Array<OneD, NekDouble> e_out_ds;
2141 for (i = 0; i < (*m_exp).size(); ++i)
2143 e_out_ds = out_d + m_phys_offset[i];
2144 (*m_exp)[i]->PhysDeriv_s(inarray + m_phys_offset[i], e_out_ds);
2147 else if (edir == MultiRegions::eN)
2149 Array<OneD, NekDouble> e_out_dn;
2150 for (i = 0; i < (*m_exp).size(); i++)
2152 e_out_dn = out_d + m_phys_offset[i];
2153 (*m_exp)[i]->PhysDeriv_n(inarray + m_phys_offset[i], e_out_dn);
2159 if (m_collectionsDoInit[Collections::ePhysDeriv])
2161 for (
int i = 0; i < m_collections.size(); ++i)
2163 m_collections[i].Initialise(Collections::ePhysDeriv);
2165 m_collectionsDoInit[Collections::ePhysDeriv] =
false;
2169 int intdir = (int)edir;
2170 Array<OneD, NekDouble> e_out_d;
2172 for (
int i = 0; i < m_collections.size(); ++i)
2174 e_out_d = out_d + offset;
2175 m_collections[i].ApplyOperator(Collections::ePhysDeriv, intdir,
2176 inarray + offset, e_out_d);
2177 offset += m_collections[i].GetInputSize(Collections::ePhysDeriv);
2186void ExpList::v_Curl(Array<OneD, Array<OneD, NekDouble>> &Vel,
2187 Array<OneD, Array<OneD, NekDouble>> &Q)
2189 int nq = GetTotPoints();
2190 Array<OneD, NekDouble> Vx(nq);
2191 Array<OneD, NekDouble> Uy(nq);
2192 Array<OneD, NekDouble> Dummy(nq);
2198 PhysDeriv(xDir, Vel[yDir], Vx);
2199 PhysDeriv(yDir, Vel[xDir], Uy);
2207 Array<OneD, NekDouble> Vz(nq);
2208 Array<OneD, NekDouble> Uz(nq);
2209 Array<OneD, NekDouble> Wx(nq);
2210 Array<OneD, NekDouble> Wy(nq);
2212 PhysDeriv(Vel[xDir], Dummy, Uy, Uz);
2213 PhysDeriv(Vel[yDir], Vx, Dummy, Vz);
2214 PhysDeriv(Vel[zDir], Wx, Wy, Dummy);
2222 ASSERTL0(0,
"Dimension not supported by ExpList::Curl");
2235void ExpList::v_CurlCurl(Array<OneD, Array<OneD, NekDouble>> &Vel,
2236 Array<OneD, Array<OneD, NekDouble>> &Q)
2238 int nq = GetTotPoints();
2239 Array<OneD, NekDouble> Vx(nq);
2240 Array<OneD, NekDouble> Uy(nq);
2241 Array<OneD, NekDouble> Dummy(nq);
2243 bool halfMode =
false;
2244 if (GetExpType() == e3DH1D)
2246 m_session->MatchSolverInfo(
"ModeType",
"HalfMode", halfMode,
false);
2253 PhysDeriv(xDir, Vel[yDir], Vx);
2254 PhysDeriv(yDir, Vel[xDir], Uy);
2258 PhysDeriv(Dummy, Q[1], Q[0]);
2268 Array<OneD, NekDouble> Vz(nq);
2269 Array<OneD, NekDouble> Uz(nq);
2270 Array<OneD, NekDouble> Wx(nq);
2271 Array<OneD, NekDouble> Wy(nq);
2273 PhysDeriv(Vel[xDir], Dummy, Uy, Uz);
2274 PhysDeriv(Vel[yDir], Vx, Dummy, Vz);
2275 PhysDeriv(Vel[zDir], Wx, Wy, Dummy);
2281 PhysDeriv(Q[0], Dummy, Uy, Uz);
2282 PhysDeriv(Q[1], Vx, Dummy, Vz);
2283 PhysDeriv(Q[2], Wx, Wy, Dummy);
2298 ASSERTL0(0,
"Dimension not supported");
2303void ExpList::v_PhysDirectionalDeriv(
2304 const Array<OneD, const NekDouble> &direction,
2305 const Array<OneD, const NekDouble> &inarray,
2306 Array<OneD, NekDouble> &outarray)
2309 int coordim = (*m_exp)[0]->GetGeom()->GetCoordim();
2310 int nq = direction.size() / coordim;
2312 Array<OneD, NekDouble> e_outarray;
2313 Array<OneD, NekDouble> e_MFdiv;
2314 Array<OneD, NekDouble> locdir;
2316 for (
int i = 0; i < (*m_exp).size(); ++i)
2318 npts_e = (*m_exp)[i]->GetTotPoints();
2319 locdir = Array<OneD, NekDouble>(npts_e * coordim);
2321 for (
int k = 0; k < coordim; ++k)
2323 Vmath::Vcopy(npts_e, &direction[k * nq + m_phys_offset[i]], 1,
2324 &locdir[k * npts_e], 1);
2327 (*m_exp)[i]->PhysDirectionalDeriv(inarray + m_phys_offset[i], locdir,
2329 outarray + m_phys_offset[i]);
2333void ExpList::ExponentialFilter(Array<OneD, NekDouble> &array,
2334 const NekDouble alpha,
const NekDouble exponent,
2335 const NekDouble cutoff)
2337 Array<OneD, NekDouble> e_array;
2339 for (
int i = 0; i < (*m_exp).size(); ++i)
2341 (*m_exp)[i]->ExponentialFilter(e_array = array + m_phys_offset[i],
2342 alpha, exponent, cutoff);
2354void ExpList::MultiplyByElmtInvMass(
const Array<OneD, const NekDouble> &inarray,
2355 Array<OneD, NekDouble> &outarray)
2357 GlobalMatrixKey mkey(StdRegions::eInvMass);
2361 NekVector<NekDouble> out(m_ncoeffs, outarray, eWrapper);
2362 if (inarray.data() == outarray.data())
2364 NekVector<NekDouble> in(m_ncoeffs, inarray);
2365 out = (*InvMass) * in;
2369 NekVector<NekDouble> in(m_ncoeffs, inarray, eWrapper);
2370 out = (*InvMass) * in;
2392void ExpList::v_FwdTransLocalElmt(
const Array<OneD, const NekDouble> &inarray,
2393 Array<OneD, NekDouble> &outarray)
2395 Array<OneD, NekDouble> f(m_ncoeffs);
2397 IProductWRTBase(inarray, f);
2398 MultiplyByElmtInvMass(f, outarray);
2401void ExpList::v_FwdTransBndConstrained(
2402 const Array<OneD, const NekDouble> &inarray,
2403 Array<OneD, NekDouble> &outarray)
2407 Array<OneD, NekDouble> e_outarray;
2409 for (i = 0; i < (*m_exp).size(); ++i)
2411 (*m_exp)[i]->FwdTransBndConstrained(inarray + m_phys_offset[i],
2413 outarray + m_coeff_offset[i]);
2424void ExpList::v_SmoothField([[maybe_unused]] Array<OneD, NekDouble> &field)
2436 ASSERTL0((*m_exp)[0]->GetBasisType(0) == LibUtilities::eGLL_Lagrange ||
2437 (*m_exp)[0]->GetBasisType(0) == LibUtilities::eGauss_Lagrange,
2438 "Smoothing is currently not allowed unless you are using "
2439 "a nodal base for efficiency reasons. The implemented "
2440 "smoothing technique requires the mass matrix inversion "
2441 "which is trivial just for GLL_LAGRANGE_SEM and "
2442 "GAUSS_LAGRANGE_SEMexpansions.");
2464 const GlobalMatrixKey &gkey)
2470 map<int, int> elmt_id;
2471 LibUtilities::ShapeType
ShapeType = gkey.GetShapeType();
2473 if (ShapeType != LibUtilities::eNoShapeType)
2475 for (i = 0; i < (*m_exp).size(); ++i)
2477 if ((*m_exp)[i]->DetShapeType() == ShapeType)
2479 elmt_id[n_exp++] = i;
2485 n_exp = (*m_exp).size();
2486 for (i = 0; i < n_exp; ++i)
2492 Array<OneD, unsigned int> nrows(n_exp);
2493 Array<OneD, unsigned int> ncols(n_exp);
2495 switch (gkey.GetMatrixType())
2497 case StdRegions::eBwdTrans:
2500 for (i = 0; i < n_exp; ++i)
2502 nrows[i] = (*m_exp)[elmt_id.find(i)->second]->GetTotPoints();
2503 ncols[i] = (*m_exp)[elmt_id.find(i)->second]->GetNcoeffs();
2507 case StdRegions::eIProductWRTBase:
2510 for (i = 0; i < n_exp; ++i)
2512 nrows[i] = (*m_exp)[elmt_id.find(i)->second]->GetNcoeffs();
2513 ncols[i] = (*m_exp)[elmt_id.find(i)->second]->GetTotPoints();
2517 case StdRegions::eMass:
2518 case StdRegions::eInvMass:
2519 case StdRegions::eHelmholtz:
2520 case StdRegions::eLaplacian:
2521 case StdRegions::eInvHybridDGHelmholtz:
2524 for (i = 0; i < n_exp; ++i)
2526 nrows[i] = (*m_exp)[elmt_id.find(i)->second]->GetNcoeffs();
2527 ncols[i] = (*m_exp)[elmt_id.find(i)->second]->GetNcoeffs();
2532 case StdRegions::eHybridDGLamToU:
2535 for (i = 0; i < n_exp; ++i)
2537 nrows[i] = (*m_exp)[elmt_id.find(i)->second]->GetNcoeffs();
2539 (*m_exp)[elmt_id.find(i)->second]->NumDGBndryCoeffs();
2543 case StdRegions::eHybridDGHelmBndLam:
2546 for (i = 0; i < n_exp; ++i)
2549 (*m_exp)[elmt_id.find(i)->second]->NumDGBndryCoeffs();
2551 (*m_exp)[elmt_id.find(i)->second]->NumDGBndryCoeffs();
2558 "Global Matrix creation not defined for this "
2564 BlkMatrix = MemoryManager<DNekScalBlkMat>::AllocateSharedPtr(nrows, ncols,
2567 int nvarcoeffs = gkey.GetNVarCoeffs();
2569 Array<OneD, NekDouble> varcoeffs_wk;
2571 for (i = cnt1 = 0; i < n_exp; ++i)
2575 StdRegions::VarCoeffMap varcoeffs;
2580 varcoeffs = StdRegions::RestrictCoeffMap(
2581 gkey.GetVarCoeffs(), m_phys_offset[i],
2582 (*m_exp)[i]->GetTotPoints());
2585 LocalRegions::MatrixKey matkey(
2586 gkey.GetMatrixType(), (*m_exp)[eid]->DetShapeType(), *(*m_exp)[eid],
2587 gkey.GetConstFactors(), varcoeffs);
2589 loc_mat = std::dynamic_pointer_cast<LocalRegions::Expansion>(
2590 (*m_exp)[elmt_id.find(i)->second])
2591 ->GetLocMatrix(matkey);
2592 BlkMatrix->SetBlock(i, i, loc_mat);
2599 const GlobalMatrixKey &gkey)
2601 auto matrixIter = m_blockMat->find(gkey);
2603 if (matrixIter == m_blockMat->end())
2605 return ((*m_blockMat)[gkey] = GenBlockMatrix(gkey));
2609 return matrixIter->second;
2642void ExpList::GeneralMatrixOp(
const GlobalMatrixKey &gkey,
2643 const Array<OneD, const NekDouble> &inarray,
2644 Array<OneD, NekDouble> &outarray)
2646 int nvarcoeffs = gkey.GetNVarCoeffs();
2648 if (gkey.GetMatrixType() == StdRegions::eHelmholtz ||
2649 gkey.GetMatrixType() == StdRegions::eLinearAdvectionDiffusionReaction)
2652 Collections::OperatorType opType =
2653 (gkey.GetMatrixType() == StdRegions::eHelmholtz)
2654 ? Collections::eHelmholtz
2658 if (m_collections.size() && m_collectionsDoInit[opType])
2660 for (
int i = 0; i < m_collections.size(); ++i)
2662 m_collections[i].Initialise(opType, gkey.GetConstFactors());
2664 m_collectionsDoInit[opType] =
false;
2669 for (
int i = 0; i < m_collections.size(); ++i)
2671 m_collections[i].UpdateFactors(opType, gkey.GetConstFactors());
2674 StdRegions::VarCoeffMap varcoeffs;
2677 varcoeffs = StdRegions::RestrictCoeffMap(
2678 gkey.GetVarCoeffs(), m_phys_offset[cnt],
2679 m_collections[i].GetInputSize(opType,
false));
2680 cnt += m_collections[i].GetNumElmt(opType);
2682 m_collections[i].UpdateVarcoeffs(opType, varcoeffs);
2685 Array<OneD, NekDouble> tmp;
2686 int input_offset{0};
2687 int output_offset{0};
2688 for (
int i = 0; i < m_collections.size(); ++i)
2692 m_collections[i].ApplyOperator(opType, inarray + input_offset,
2693 tmp = outarray + output_offset);
2694 input_offset += m_collections[i].GetInputSize(opType);
2695 output_offset += m_collections[i].GetOutputSize(opType);
2700 Array<OneD, NekDouble> tmp_outarray;
2701 for (
int i = 0; i < (*m_exp).size(); ++i)
2705 StdRegions::VarCoeffMap varcoeffs;
2709 varcoeffs = StdRegions::RestrictCoeffMap(
2710 gkey.GetVarCoeffs(), m_phys_offset[i],
2711 (*m_exp)[i]->GetTotPoints());
2714 StdRegions::StdMatrixKey mkey(
2715 gkey.GetMatrixType(), (*m_exp)[i]->DetShapeType(),
2716 *((*m_exp)[i]), gkey.GetConstFactors(), varcoeffs);
2718 (*m_exp)[i]->GeneralMatrixOp(
2719 inarray + m_coeff_offset[i],
2720 tmp_outarray = outarray + m_coeff_offset[i], mkey);
2733 const GlobalMatrixKey &mkey,
const AssemblyMapCGSharedPtr &locToGloMap)
2735 int i, j, n, gid1, gid2, cntdim1, cntdim2;
2739 unsigned int glob_rows = 0;
2740 unsigned int glob_cols = 0;
2741 unsigned int loc_rows = 0;
2742 unsigned int loc_cols = 0;
2744 bool assembleFirstDim =
false;
2745 bool assembleSecondDim =
false;
2747 switch (mkey.GetMatrixType())
2749 case StdRegions::eBwdTrans:
2751 glob_rows = m_npoints;
2752 glob_cols = locToGloMap->GetNumGlobalCoeffs();
2754 assembleFirstDim =
false;
2755 assembleSecondDim =
true;
2758 case StdRegions::eIProductWRTBase:
2760 glob_rows = locToGloMap->GetNumGlobalCoeffs();
2761 glob_cols = m_npoints;
2763 assembleFirstDim =
true;
2764 assembleSecondDim =
false;
2767 case StdRegions::eMass:
2768 case StdRegions::eHelmholtz:
2769 case StdRegions::eLaplacian:
2770 case StdRegions::eHybridDGHelmBndLam:
2772 glob_rows = locToGloMap->GetNumGlobalCoeffs();
2773 glob_cols = locToGloMap->GetNumGlobalCoeffs();
2775 assembleFirstDim =
true;
2776 assembleSecondDim =
true;
2782 "Global Matrix creation not defined for this "
2790 int nvarcoeffs = mkey.GetNVarCoeffs();
2794 for (n = cntdim1 = cntdim2 = 0; n < (*m_exp).size(); ++n)
2798 StdRegions::VarCoeffMap varcoeffs;
2803 varcoeffs = StdRegions::RestrictCoeffMap(
2804 mkey.GetVarCoeffs(), m_phys_offset[eid],
2805 (*m_exp)[eid]->GetTotPoints());
2808 LocalRegions::MatrixKey matkey(
2809 mkey.GetMatrixType(), (*m_exp)[eid]->DetShapeType(),
2810 *((*m_exp)[eid]), mkey.GetConstFactors(), varcoeffs);
2813 std::dynamic_pointer_cast<LocalRegions::Expansion>((*m_exp)[n])
2814 ->GetLocMatrix(matkey);
2816 loc_rows = loc_mat->GetRows();
2817 loc_cols = loc_mat->GetColumns();
2819 for (i = 0; i < loc_rows; ++i)
2821 if (assembleFirstDim)
2823 gid1 = locToGloMap->GetLocalToGlobalMap(cntdim1 + i);
2824 sign1 = locToGloMap->GetLocalToGlobalSign(cntdim1 + i);
2832 for (j = 0; j < loc_cols; ++j)
2834 if (assembleSecondDim)
2836 gid2 = locToGloMap->GetLocalToGlobalMap(cntdim2 + j);
2837 sign2 = locToGloMap->GetLocalToGlobalSign(cntdim2 + j);
2846 coord = make_pair(gid1, gid2);
2847 if (spcoomat.count(coord) == 0)
2849 spcoomat[coord] = sign1 * sign2 * (*loc_mat)(i, j);
2853 spcoomat[coord] += sign1 * sign2 * (*loc_mat)(i, j);
2857 cntdim1 += loc_rows;
2858 cntdim2 += loc_cols;
2861 return MemoryManager<GlobalMatrix>::AllocateSharedPtr(m_session, glob_rows,
2862 glob_cols, spcoomat);
2866 const GlobalLinSysKey &mkey,
const AssemblyMapCGSharedPtr &locToGloMap)
2868 int i, j, n, gid1, gid2, loc_lda, eid;
2872 int totDofs = locToGloMap->GetNumGlobalCoeffs();
2873 int NumDirBCs = locToGloMap->GetNumGlobalDirBndCoeffs();
2875 unsigned int rows = totDofs - NumDirBCs;
2876 unsigned int cols = totDofs - NumDirBCs;
2880 int bwidth = locToGloMap->GetFullSystemBandWidth();
2882 int nvarcoeffs = mkey.GetNVarCoeffs();
2885 map<int, RobinBCInfoSharedPtr> RobinBCInfo = GetRobinBCInfo();
2887 switch (mkey.GetMatrixType())
2890 case StdRegions::eHelmholtz:
2891 case StdRegions::eLaplacian:
2892 if ((2 * (bwidth + 1)) < rows)
2895 Gmat = MemoryManager<DNekMat>::AllocateSharedPtr(
2896 rows, cols, zero, matStorage, bwidth, bwidth);
2901 Gmat = MemoryManager<DNekMat>::AllocateSharedPtr(
2902 rows, cols, zero, matStorage);
2910 Gmat = MemoryManager<DNekMat>::AllocateSharedPtr(
2911 rows, cols, zero, matStorage);
2916 for (n = 0; n < (*m_exp).size(); ++n)
2920 StdRegions::VarCoeffMap varcoeffs;
2925 varcoeffs = StdRegions::RestrictCoeffMap(
2926 mkey.GetVarCoeffs(), m_phys_offset[eid],
2927 (*m_exp)[eid]->GetTotPoints());
2930 LocalRegions::MatrixKey matkey(
2931 mkey.GetMatrixType(), (*m_exp)[eid]->DetShapeType(),
2932 *((*m_exp)[eid]), mkey.GetConstFactors(), varcoeffs);
2935 std::dynamic_pointer_cast<LocalRegions::Expansion>((*m_exp)[n])
2936 ->GetLocMatrix(matkey);
2938 if (RobinBCInfo.count(n) != 0)
2943 int rows = loc_mat->GetRows();
2944 int cols = loc_mat->GetColumns();
2945 const NekDouble *dat = loc_mat->GetRawPtr();
2947 MemoryManager<DNekMat>::AllocateSharedPtr(rows, cols, dat);
2948 Blas::Dscal(rows * cols, loc_mat->Scale(), new_mat->GetRawPtr(), 1);
2951 for (rBC = RobinBCInfo.find(n)->second; rBC; rBC = rBC->next)
2953 (*m_exp)[n]->AddRobinMassMatrix(
2954 rBC->m_robinID, rBC->m_robinPrimitiveCoeffs, new_mat);
2960 MemoryManager<DNekScalMat>::AllocateSharedPtr(one, new_mat);
2963 loc_lda = loc_mat->GetColumns();
2965 for (i = 0; i < loc_lda; ++i)
2967 gid1 = locToGloMap->GetLocalToGlobalMap(m_coeff_offset[n] + i) -
2969 sign1 = locToGloMap->GetLocalToGlobalSign(m_coeff_offset[n] + i);
2972 for (j = 0; j < loc_lda; ++j)
2974 gid2 = locToGloMap->GetLocalToGlobalMap(m_coeff_offset[n] +
2977 sign2 = locToGloMap->GetLocalToGlobalSign(
2978 m_coeff_offset[n] + j);
2985 if ((matStorage == eFULL) || (gid2 >= gid1))
2987 value = Gmat->GetValue(gid1, gid2) +
2988 sign1 * sign2 * (*loc_mat)(i, j);
2989 Gmat->SetValue(gid1, gid2, value);
3018 const GlobalLinSysKey &mkey,
const AssemblyMapCGSharedPtr &locToGloMap)
3021 std::shared_ptr<ExpList> vExpList = GetSharedThisPtr();
3023 MultiRegions::GlobalSysSolnType vType = mkey.GetGlobalSysSolnType();
3025 if (vType >= eSIZE_GlobalSysSolnType)
3027 NEKERROR(ErrorUtil::efatal,
"Matrix solution type not defined");
3029 std::string vSolnType = MultiRegions::GlobalSysSolnTypeMap[vType];
3036 const GlobalLinSysKey &mkey,
const AssemblyMapSharedPtr &locToGloMap)
3038 std::shared_ptr<ExpList> vExpList = GetSharedThisPtr();
3039 const map<int, RobinBCInfoSharedPtr> vRobinBCInfo = GetRobinBCInfo();
3041 MultiRegions::GlobalSysSolnType vType = mkey.GetGlobalSysSolnType();
3043 if (vType >= eSIZE_GlobalSysSolnType)
3045 NEKERROR(ErrorUtil::efatal,
"Matrix solution type not defined");
3047 std::string vSolnType = MultiRegions::GlobalSysSolnTypeMap[vType];
3071void ExpList::v_BwdTrans(
const Array<OneD, const NekDouble> &inarray,
3072 Array<OneD, NekDouble> &outarray)
3074 LibUtilities::Timer timer;
3076 if (m_expType == e0D)
3083 if (m_collections.size() && m_collectionsDoInit[Collections::eBwdTrans])
3085 for (
int i = 0; i < m_collections.size(); ++i)
3087 m_collections[i].Initialise(Collections::eBwdTrans);
3089 m_collectionsDoInit[Collections::eBwdTrans] =
false;
3095 Array<OneD, NekDouble> tmp;
3096 int input_offset{0};
3097 int output_offset{0};
3098 for (
int i = 0; i < m_collections.size(); ++i)
3100 m_collections[i].ApplyOperator(Collections::eBwdTrans,
3101 inarray + input_offset,
3102 tmp = outarray + output_offset);
3104 m_collections[i].GetInputSize(Collections::eBwdTrans);
3106 m_collections[i].GetOutputSize(Collections::eBwdTrans);
3113 timer.AccumulateRegion(
"Collections:BwdTrans", 10);
3116LocalRegions::ExpansionSharedPtr &ExpList::GetExp(
3117 const Array<OneD, const NekDouble> &gloCoord)
3119 return GetExp(GetExpIndex(gloCoord));
3127int ExpList::GetExpIndex(
const Array<OneD, const NekDouble> &gloCoord,
3128 NekDouble tol,
bool returnNearestElmt,
int cachedId,
3129 NekDouble maxDistance)
3131 Array<OneD, NekDouble> Lcoords(gloCoord.size());
3133 return GetExpIndex(gloCoord, Lcoords, tol, returnNearestElmt, cachedId,
3137int ExpList::GetExpIndex(
const Array<OneD, const NekDouble> &gloCoords,
3138 Array<OneD, NekDouble> &locCoords, NekDouble tol,
3139 bool returnNearestElmt,
int cachedId,
3140 NekDouble maxDistance)
3142 if (GetNumElmts() == 0)
3147 if (m_elmtToExpId.size() == 0)
3152 for (
int i = (*m_exp).size() - 1; i >= 0; --i)
3154 m_elmtToExpId[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
3161 Array<OneD, NekDouble> savLocCoords(locCoords.size());
3163 if (cachedId >= 0 && cachedId < (*m_exp).size())
3166 if ((*m_exp)[cachedId]->GetGeom()->ContainsPoint(gloCoords, locCoords,
3171 else if (returnNearestElmt && (nearpt < nearpt_min))
3176 nearpt_min = nearpt;
3177 Vmath::Vcopy(locCoords.size(), locCoords, 1, savLocCoords, 1);
3181 NekDouble x = (gloCoords.size() > 0 ? gloCoords[0] : 0.0);
3182 NekDouble y = (gloCoords.size() > 1 ? gloCoords[1] : 0.0);
3183 NekDouble z = (gloCoords.size() > 2 ? gloCoords[2] : 0.0);
3184 SpatialDomains::PointGeomUniquePtr
p =
3185 ObjPoolManager<SpatialDomains::PointGeom>::AllocateUniquePtr(
3186 GetExp(0)->GetCoordim(), -1, x, y, z);
3190 std::vector<int> elmts = m_graph->GetElementsContainingPoint(
p.get());
3193 for (
int i = 0; i < elmts.size(); ++i)
3195 int id = m_elmtToExpId[elmts[i]];
3200 if ((*m_exp)[
id]->GetGeom()->ContainsPoint(gloCoords, locCoords, tol,
3205 else if (returnNearestElmt && (nearpt < nearpt_min))
3210 nearpt_min = nearpt;
3211 Vmath::Vcopy(locCoords.size(), locCoords, 1, savLocCoords, 1);
3217 if (returnNearestElmt && nearpt_min <= maxDistance)
3219 Vmath::Vcopy(locCoords.size(), savLocCoords, 1, locCoords, 1);
3220 std::string msg =
"Failed to find point within a tolerance of " +
3221 boost::lexical_cast<std::string>(tol) +
3222 ", using local point (";
3223 for (
size_t j = 0; j < locCoords.size(); ++j)
3225 msg += boost::lexical_cast<std::string>(savLocCoords[j]);
3226 if (j < locCoords.size())
3231 msg +=
") in element: " + std::to_string(min_id) +
3232 " with a distance of " + std::to_string(nearpt_min);
3246NekDouble ExpList::PhysEvaluate(
const Array<OneD, const NekDouble> &coords,
3247 const Array<OneD, const NekDouble> &phys)
3249 int dim = GetCoordim(0);
3250 ASSERTL0(dim == coords.size(),
"Invalid coordinate dimension.");
3253 Array<OneD, NekDouble> xi(dim);
3254 int elmtIdx = GetExpIndex(coords, xi);
3255 ASSERTL0(elmtIdx > 0,
"Unable to find element containing point.");
3258 Array<OneD, NekDouble> elmtPhys = phys + m_phys_offset[elmtIdx];
3261 return (*m_exp)[elmtIdx]->StdPhysEvaluate(xi, elmtPhys);
3269void ExpList::ApplyGeomInfo()
3281void ExpList::v_Reset()
3284 LibUtilities::NekManager<LocalRegions::MatrixKey,
DNekScalMat,
3285 LocalRegions::MatrixKey::opLess>::ClearManager();
3286 LibUtilities::NekManager<LocalRegions::MatrixKey,
DNekScalBlkMat,
3287 LocalRegions::MatrixKey::opLess>::ClearManager();
3290 m_blockMat->clear();
3293 for (
int i = 0; i < m_exp->size(); ++i)
3295 (*m_exp)[i]->GetGeom()->Reset(m_graph->GetCurvedEdges(),
3296 m_graph->GetCurvedFaces());
3300 for (
int i = 0; i < m_exp->size(); ++i)
3302 (*m_exp)[i]->Reset();
3305 CreateCollections(Collections::eNoImpType);
3309void ExpList::ResetMatrices()
3312 LibUtilities::NekManager<LocalRegions::MatrixKey,
DNekScalMat,
3313 LocalRegions::MatrixKey::opLess>::ClearManager();
3314 LibUtilities::NekManager<LocalRegions::MatrixKey,
DNekScalBlkMat,
3315 LocalRegions::MatrixKey::opLess>::ClearManager();
3318 m_blockMat->clear();
3326void ExpList::v_WriteTecplotHeader(std::ostream &outfile, std::string var)
3328 if (GetNumElmts() == 0)
3333 int coordim = GetExp(0)->GetCoordim();
3334 char vars[3] = {
'x',
'y',
'z'};
3336 if (m_expType == e3DH1D)
3340 else if (m_expType == e3DH2D)
3345 outfile <<
"Variables = x";
3346 for (
int i = 1; i < coordim; ++i)
3348 outfile <<
", " << vars[i];
3353 outfile <<
", " << var;
3356 outfile << std::endl << std::endl;
3364void ExpList::v_WriteTecplotZone(std::ostream &outfile,
int expansion)
3367 int coordim = GetCoordim(0);
3368 int nPoints = GetTotPoints();
3369 int nBases = (*m_exp)[0]->GetNumBases();
3372 Array<OneD, Array<OneD, NekDouble>> coords(3);
3374 if (expansion == -1)
3376 nPoints = GetTotPoints();
3378 coords[0] = Array<OneD, NekDouble>(nPoints);
3379 coords[1] = Array<OneD, NekDouble>(nPoints);
3380 coords[2] = Array<OneD, NekDouble>(nPoints);
3382 GetCoords(coords[0], coords[1], coords[2]);
3384 for (i = 0; i < m_exp->size(); ++i)
3388 for (j = 0; j < nBases; ++j)
3390 numInt *= (*m_exp)[i]->GetNumPoints(j) - 1;
3393 numBlocks += numInt;
3398 nPoints = (*m_exp)[expansion]->GetTotPoints();
3400 coords[0] = Array<OneD, NekDouble>(nPoints);
3401 coords[1] = Array<OneD, NekDouble>(nPoints);
3402 coords[2] = Array<OneD, NekDouble>(nPoints);
3404 (*m_exp)[expansion]->GetCoords(coords[0], coords[1], coords[2]);
3407 for (j = 0; j < nBases; ++j)
3409 numBlocks *= (*m_exp)[expansion]->GetNumPoints(j) - 1;
3413 if (m_expType == e3DH1D)
3417 int nPlanes = GetZIDs().size();
3418 NekDouble tmp = numBlocks * (nPlanes - 1.0) / nPlanes;
3419 numBlocks = (int)tmp;
3421 else if (m_expType == e3DH2D)
3427 outfile <<
"Zone, N=" << nPoints <<
", E=" << numBlocks <<
", F=FEBlock";
3432 outfile <<
", ET=QUADRILATERAL" << std::endl;
3435 outfile <<
", ET=BRICK" << std::endl;
3438 NEKERROR(ErrorUtil::efatal,
"Not set up for this type of output");
3443 for (j = 0; j < coordim; ++j)
3445 for (i = 0; i < nPoints; ++i)
3447 outfile << coords[j][i] <<
" ";
3448 if (i % 1000 == 0 && i)
3450 outfile << std::endl;
3453 outfile << std::endl;
3457void ExpList::v_WriteTecplotConnectivity(std::ostream &outfile,
int expansion)
3460 int nbase = (*m_exp)[0]->GetNumBases();
3463 std::shared_ptr<LocalRegions::ExpansionVector> exp = m_exp;
3465 if (expansion != -1)
3467 exp = std::shared_ptr<LocalRegions::ExpansionVector>(
3468 new LocalRegions::ExpansionVector(1));
3469 (*exp)[0] = (*m_exp)[expansion];
3474 for (i = 0; i < (*exp).size(); ++i)
3476 const int np0 = (*exp)[i]->GetNumPoints(0);
3477 const int np1 = (*exp)[i]->GetNumPoints(1);
3479 for (j = 1; j < np1; ++j)
3481 for (k = 1; k < np0; ++k)
3483 outfile << cnt + (j - 1) * np0 + k <<
" ";
3484 outfile << cnt + (j - 1) * np0 + k + 1 <<
" ";
3485 outfile << cnt + j * np0 + k + 1 <<
" ";
3486 outfile << cnt + j * np0 + k << endl;
3493 else if (nbase == 3)
3495 for (i = 0; i < (*exp).size(); ++i)
3497 const int np0 = (*exp)[i]->GetNumPoints(0);
3498 const int np1 = (*exp)[i]->GetNumPoints(1);
3499 const int np2 = (*exp)[i]->GetNumPoints(2);
3500 const int np01 = np0 * np1;
3502 for (j = 1; j < np2; ++j)
3504 for (k = 1; k < np1; ++k)
3506 for (l = 1; l < np0; ++l)
3508 outfile << cnt + (j - 1) * np01 + (k - 1) * np0 + l
3510 outfile << cnt + (j - 1) * np01 + (k - 1) * np0 + l + 1
3512 outfile << cnt + (j - 1) * np01 + k * np0 + l + 1
3514 outfile << cnt + (j - 1) * np01 + k * np0 + l <<
" ";
3515 outfile << cnt + j * np01 + (k - 1) * np0 + l <<
" ";
3516 outfile << cnt + j * np01 + (k - 1) * np0 + l + 1
3518 outfile << cnt + j * np01 + k * np0 + l + 1 <<
" ";
3519 outfile << cnt + j * np01 + k * np0 + l << endl;
3523 cnt += np0 * np1 * np2;
3528 NEKERROR(ErrorUtil::efatal,
"Not set up for this dimension");
3537void ExpList::v_WriteTecplotField(std::ostream &outfile,
int expansion)
3539 if (expansion == -1)
3541 int totpoints = GetTotPoints();
3542 if (m_physState ==
false)
3544 BwdTrans(m_coeffs, m_phys);
3547 for (
int i = 0; i < totpoints; ++i)
3549 outfile << m_phys[i] <<
" ";
3550 if (i % 1000 == 0 && i)
3552 outfile << std::endl;
3555 outfile << std::endl;
3559 int nPoints = (*m_exp)[expansion]->GetTotPoints();
3561 for (
int i = 0; i < nPoints; ++i)
3563 outfile << m_phys[i + m_phys_offset[expansion]] <<
" ";
3566 outfile << std::endl;
3570void ExpList::WriteVtkHeader(std::ostream &outfile)
3572 outfile <<
"<?xml version=\"1.0\"?>" << endl;
3573 outfile << R
"(<VTKFile type="UnstructuredGrid" version="0.1" )"
3574 << "byte_order=\"LittleEndian\">" << endl;
3575 outfile <<
" <UnstructuredGrid>" << endl;
3578void ExpList::WriteVtkFooter(std::ostream &outfile)
3580 outfile <<
" </UnstructuredGrid>" << endl;
3581 outfile <<
"</VTKFile>" << endl;
3584void ExpList::v_WriteVtkPieceHeader(std::ostream &outfile,
int expansion,
3585 [[maybe_unused]]
int istrip)
3588 int nbase = (*m_exp)[expansion]->GetNumBases();
3589 int ntot = (*m_exp)[expansion]->GetTotPoints();
3593 for (i = 0; i < nbase; ++i)
3595 nquad[i] = (*m_exp)[expansion]->GetNumPoints(i);
3596 ntotminus *= (nquad[i] - 1);
3599 Array<OneD, NekDouble> coords[3];
3600 coords[0] = Array<OneD, NekDouble>(ntot, 0.0);
3601 coords[1] = Array<OneD, NekDouble>(ntot, 0.0);
3602 coords[2] = Array<OneD, NekDouble>(ntot, 0.0);
3603 (*m_exp)[expansion]->GetCoords(coords[0], coords[1], coords[2]);
3605 outfile <<
" <Piece NumberOfPoints=\"" << ntot <<
"\" NumberOfCells=\""
3606 << ntotminus <<
"\">" << endl;
3607 outfile <<
" <Points>" << endl;
3608 outfile <<
" <DataArray type=\"Float64\" "
3609 << R
"(NumberOfComponents="3" format="ascii">)" << endl;
3611 for (i = 0; i < ntot; ++i)
3613 for (j = 0; j < 3; ++j)
3615 outfile << setprecision(8) << scientific << (float)coords[j][i]
3621 outfile <<
" </DataArray>" << endl;
3622 outfile <<
" </Points>" << endl;
3623 outfile <<
" <Cells>" << endl;
3624 outfile <<
" <DataArray type=\"Int32\" "
3625 << R
"(Name="connectivity" format="ascii">)" << endl;
3635 for (i = 0; i < nquad[0] - 1; ++i)
3637 outfile << i <<
" " << i + 1 << endl;
3645 for (i = 0; i < nquad[0] - 1; ++i)
3647 for (j = 0; j < nquad[1] - 1; ++j)
3649 outfile << j * nquad[0] + i <<
" " << j * nquad[0] + i + 1
3650 <<
" " << (j + 1) * nquad[0] + i + 1 <<
" "
3651 << (j + 1) * nquad[0] + i << endl;
3660 for (i = 0; i < nquad[0] - 1; ++i)
3662 for (j = 0; j < nquad[1] - 1; ++j)
3664 for (k = 0; k < nquad[2] - 1; ++k)
3667 << k * nquad[0] * nquad[1] + j * nquad[0] + i <<
" "
3668 << k * nquad[0] * nquad[1] + j * nquad[0] + i + 1
3670 << k * nquad[0] * nquad[1] + (j + 1) * nquad[0] +
3673 << k * nquad[0] * nquad[1] + (j + 1) * nquad[0] + i
3675 << (k + 1) * nquad[0] * nquad[1] + j * nquad[0] + i
3677 << (k + 1) * nquad[0] * nquad[1] + j * nquad[0] +
3680 << (k + 1) * nquad[0] * nquad[1] +
3681 (j + 1) * nquad[0] + i + 1
3683 << (k + 1) * nquad[0] * nquad[1] +
3684 (j + 1) * nquad[0] + i
3696 outfile <<
" </DataArray>" << endl;
3697 outfile <<
" <DataArray type=\"Int32\" "
3698 << R
"(Name="offsets" format="ascii">)" << endl;
3699 for (i = 0; i < ntotminus; ++i)
3701 outfile << i * ns + ns <<
" ";
3704 outfile <<
" </DataArray>" << endl;
3705 outfile <<
" <DataArray type=\"UInt8\" "
3706 << R
"(Name="types" format="ascii">)" << endl;
3707 for (i = 0; i < ntotminus; ++i)
3712 outfile <<
" </DataArray>" << endl;
3713 outfile <<
" </Cells>" << endl;
3714 outfile <<
" <PointData>" << endl;
3717void ExpList::WriteVtkPieceFooter(std::ostream &outfile,
3718 [[maybe_unused]]
int expansion)
3720 outfile <<
" </PointData>" << endl;
3721 outfile <<
" </Piece>" << endl;
3724void ExpList::v_WriteVtkPieceData(std::ostream &outfile,
int expansion,
3728 int nq = (*m_exp)[expansion]->GetTotPoints();
3731 outfile << R
"( <DataArray type="Float64" Name=")" << var << "\">"
3735 const Array<OneD, NekDouble> phys = m_phys + m_phys_offset[expansion];
3737 for (i = 0; i < nq; ++i)
3739 outfile << (fabs(phys[i]) < NekConstants::kNekZeroTol ? 0 : phys[i])
3743 outfile <<
" </DataArray>" << endl;
3764NekDouble ExpList::Linf(
const Array<OneD, const NekDouble> &inarray,
3765 const Array<OneD, const NekDouble> &soln)
3769 if (soln == NullNekDouble1DArray)
3775 for (
int i = 0; i < m_npoints; ++i)
3777 err =
max(err,
abs(inarray[i] - soln[i]));
3781 m_comm->GetRowComm()->AllReduce(err, LibUtilities::ReduceMax);
3802NekDouble ExpList::v_L2(
const Array<OneD, const NekDouble> &inarray,
3803 const Array<OneD, const NekDouble> &soln)
3808 if (soln == NullNekDouble1DArray)
3810 for (i = 0; i < (*m_exp).size(); ++i)
3812 errl2 = (*m_exp)[i]->L2(inarray + m_phys_offset[i]);
3813 err += errl2 * errl2;
3818 for (i = 0; i < (*m_exp).size(); ++i)
3820 errl2 = (*m_exp)[i]->L2(inarray + m_phys_offset[i],
3821 soln + m_phys_offset[i]);
3822 err += errl2 * errl2;
3826 m_comm->GetRowComm()->AllReduce(err, LibUtilities::ReduceSum);
3847NekDouble ExpList::v_Integral(
const Array<OneD, const NekDouble> &inarray)
3852 for (i = 0; i < (*m_exp).size(); ++i)
3854 sum += (*m_exp)[i]->Integral(inarray + m_phys_offset[i]);
3856 m_comm->GetRowComm()->AllReduce(sum, LibUtilities::ReduceSum);
3862 const Array<OneD, Array<OneD, NekDouble>> &inarray)
3868 for (i = 0; i < (*m_exp).size(); ++i)
3870 Array<OneD, Array<OneD, NekDouble>> tmp(inarray.size());
3871 for (j = 0; j < inarray.size(); ++j)
3873 tmp[j] = Array<OneD, NekDouble>(inarray[j] + m_phys_offset[i]);
3875 flux += (*m_exp)[i]->VectorFlux(tmp);
3881Array<OneD, const NekDouble> ExpList::v_HomogeneousEnergy(
void)
3884 "This method is not defined or valid for this class type");
3885 Array<OneD, NekDouble> NoEnergy(1, 0.0);
3889LibUtilities::TranspositionSharedPtr ExpList::v_GetTransposition(
void)
3892 "This method is not defined or valid for this class type");
3893 LibUtilities::TranspositionSharedPtr trans;
3900 "This method is not defined or valid for this class type");
3905void ExpList::v_SetHomoLen([[maybe_unused]]
const NekDouble lhom)
3908 "This method is not defined or valid for this class type");
3911Array<OneD, const unsigned int> ExpList::v_GetZIDs(
void)
3914 "This method is not defined or valid for this class type");
3915 Array<OneD, unsigned int> NoModes(1);
3919Array<OneD, const unsigned int> ExpList::v_GetYIDs(
void)
3922 "This method is not defined or valid for this class type");
3923 Array<OneD, unsigned int> NoModes(1);
3927void ExpList::v_ClearGlobalLinSysManager(
void)
3930 "ClearGlobalLinSysManager not implemented for ExpList.");
3933int ExpList::v_GetPoolCount([[maybe_unused]] std::string poolName)
3935 NEKERROR(ErrorUtil::efatal,
"GetPoolCount not implemented for ExpList.");
3939void ExpList::v_UnsetGlobalLinSys([[maybe_unused]] GlobalLinSysKey key,
3940 [[maybe_unused]]
bool clearLocalMatrices)
3943 "UnsetGlobalLinSys not implemented for ExpList.");
3946LibUtilities::NekManager<GlobalLinSysKey, GlobalLinSys> &ExpList::
3947 v_GetGlobalLinSysManager(
void)
3950 "GetGlobalLinSysManager not implemented for ExpList.");
3951 return NullGlobalLinSysManager;
3954void ExpList::ExtractCoeffsFromFile(
const std::string &fileName,
3955 LibUtilities::CommSharedPtr comm,
3956 const std::string &varName,
3957 Array<OneD, NekDouble> &coeffs)
3959 string varString = fileName.substr(0, fileName.find_last_of(
"."));
3960 int j, k, len = varString.length();
3961 varString = varString.substr(len - 1, len);
3963 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
3964 std::vector<std::vector<NekDouble>> FieldData;
3966 std::string ft = LibUtilities::FieldIO::GetFileType(fileName, comm);
3967 LibUtilities::FieldIOSharedPtr f =
3968 LibUtilities::GetFieldIOFactory().CreateInstance(
3969 ft, comm, m_session->GetSharedFilesystem());
3971 f->Import(fileName, FieldDef, FieldData);
3974 for (j = 0; j < FieldDef.size(); ++j)
3976 for (k = 0; k < FieldDef[j]->m_fields.size(); ++k)
3978 if (FieldDef[j]->m_fields[k] == varName)
3981 ExtractDataToCoeffs(FieldDef[j], FieldData[j],
3982 FieldDef[j]->m_fields[k], coeffs);
3988 ASSERTL0(found,
"Could not find variable '" + varName +
3989 "' in file boundary condition " + fileName);
4009NekDouble ExpList::H1(
const Array<OneD, const NekDouble> &inarray,
4010 const Array<OneD, const NekDouble> &soln)
4015 for (i = 0; i < (*m_exp).size(); ++i)
4017 errh1 = (*m_exp)[i]->H1(inarray + m_phys_offset[i],
4018 soln + m_phys_offset[i]);
4019 err += errh1 * errh1;
4022 m_comm->GetRowComm()->AllReduce(err, LibUtilities::ReduceSum);
4027void ExpList::GeneralGetFieldDefinitions(
4028 std::vector<LibUtilities::FieldDefinitionsSharedPtr> &fielddef,
4029 int NumHomoDir, Array<OneD, LibUtilities::BasisSharedPtr> &HomoBasis,
4030 std::vector<NekDouble> &HomoLen,
bool homoStrips,
4031 std::vector<unsigned int> &HomoSIDs, std::vector<unsigned int> &HomoZIDs,
4032 std::vector<unsigned int> &HomoYIDs)
4034 int startenum = (int)LibUtilities::eSegment;
4035 int endenum = (int)LibUtilities::eHexahedron;
4037 LibUtilities::ShapeType shape;
4039 ASSERTL1(NumHomoDir == HomoBasis.size(),
4040 "Homogeneous basis is not the same length as NumHomoDir");
4041 ASSERTL1(NumHomoDir == HomoLen.size(),
4042 "Homogeneous length vector is not the same length as NumHomDir");
4045 switch ((*m_exp)[0]->GetShapeDimension())
4048 startenum = (int)LibUtilities::eSegment;
4049 endenum = (int)LibUtilities::eSegment;
4052 startenum = (int)LibUtilities::eTriangle;
4053 endenum = (int)LibUtilities::eQuadrilateral;
4056 startenum = (int)LibUtilities::eTetrahedron;
4057 endenum = (int)LibUtilities::eHexahedron;
4061 for (s = startenum; s <= endenum; ++s)
4063 std::vector<unsigned int> elementIDs;
4064 std::vector<LibUtilities::BasisType> basis;
4065 std::vector<unsigned int> numModes;
4066 std::vector<std::string> fields;
4069 bool UniOrder =
true;
4072 shape = (LibUtilities::ShapeType)s;
4074 for (
int i = 0; i < (*m_exp).size(); ++i)
4076 if ((*m_exp)[i]->GetGeom()->GetShapeType() == shape)
4078 elementIDs.push_back((*m_exp)[i]->GetGeom()->GetGlobalID());
4081 for (
int j = 0; j < (*m_exp)[i]->GetNumBases(); ++j)
4084 (*m_exp)[i]->GetBasis(j)->GetBasisType());
4086 (*m_exp)[i]->GetBasis(j)->GetNumModes());
4090 for (n = 0; n < NumHomoDir; ++n)
4092 basis.push_back(HomoBasis[n]->GetBasisType());
4093 numModes.push_back(HomoBasis[n]->GetNumModes());
4101 (*m_exp)[i]->GetBasis(0)->GetBasisType() == basis[0],
4102 "Routine is not set up for multiple bases definitions");
4104 for (
int j = 0; j < (*m_exp)[i]->GetNumBases(); ++j)
4107 (*m_exp)[i]->GetBasis(j)->GetNumModes());
4109 (*m_exp)[i]->GetBasis(j)->GetNumModes())
4115 for (n = 0; n < NumHomoDir; ++n)
4117 numModes.push_back(HomoBasis[n]->GetNumModes());
4123 if (elementIDs.size() > 0)
4125 LibUtilities::FieldDefinitionsSharedPtr fdef =
4126 MemoryManager<LibUtilities::FieldDefinitions>::
4127 AllocateSharedPtr(shape, elementIDs, basis, UniOrder,
4128 numModes, fields, NumHomoDir, HomoLen,
4129 homoStrips, HomoSIDs, HomoZIDs, HomoYIDs);
4130 fielddef.push_back(fdef);
4138std::vector<LibUtilities::FieldDefinitionsSharedPtr> ExpList::
4139 v_GetFieldDefinitions()
4141 std::vector<LibUtilities::FieldDefinitionsSharedPtr> returnval;
4142 v_GetFieldDefinitions(returnval);
4146void ExpList::v_GetFieldDefinitions(
4147 std::vector<LibUtilities::FieldDefinitionsSharedPtr> &fielddef)
4149 GeneralGetFieldDefinitions(fielddef);
4154void ExpList::v_AppendFieldData(
4155 LibUtilities::FieldDefinitionsSharedPtr &fielddef,
4156 std::vector<NekDouble> &fielddata)
4158 v_AppendFieldData(fielddef, fielddata, m_coeffs);
4161void ExpList::v_AppendFieldData(
4162 LibUtilities::FieldDefinitionsSharedPtr &fielddef,
4163 std::vector<NekDouble> &fielddata, Array<OneD, NekDouble> &coeffs)
4170 map<int, int> ElmtID_to_ExpID;
4171 for (i = 0; i < (*m_exp).size(); ++i)
4173 ElmtID_to_ExpID[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
4176 for (i = 0; i < fielddef->m_elementIDs.size(); ++i)
4178 int eid = ElmtID_to_ExpID[fielddef->m_elementIDs[i]];
4179 int datalen = (*m_exp)[eid]->GetNcoeffs();
4180 if ((*m_exp)[eid]->IsNodalNonTensorialExp())
4183 Array<OneD, NekDouble> orthocoeffs((*m_exp)[eid]->GetNcoeffs());
4184 (*m_exp)[eid]->NodalToModal(coeffs + m_coeff_offset[eid],
4186 fielddata.insert(fielddata.end(), &orthocoeffs[0],
4187 &orthocoeffs[0] + datalen);
4191 fielddata.insert(fielddata.end(), &coeffs[m_coeff_offset[eid]],
4192 &coeffs[m_coeff_offset[eid]] + datalen);
4198void ExpList::ExtractDataToCoeffs(
4199 LibUtilities::FieldDefinitionsSharedPtr &fielddef,
4200 std::vector<NekDouble> &fielddata, std::string &field,
4201 Array<OneD, NekDouble> &coeffs, std::unordered_map<int, int> zIdToPlane)
4203 v_ExtractDataToCoeffs(fielddef, fielddata, field, coeffs, zIdToPlane);
4206void ExpList::ExtractCoeffsToCoeffs(
4207 const std::shared_ptr<ExpList> &fromExpList,
4208 const Array<OneD, const NekDouble> &fromCoeffs,
4209 Array<OneD, NekDouble> &toCoeffs)
4211 v_ExtractCoeffsToCoeffs(fromExpList, fromCoeffs, toCoeffs);
4222void ExpList::v_ExtractDataToCoeffs(
4223 LibUtilities::FieldDefinitionsSharedPtr &fielddef,
4224 std::vector<NekDouble> &fielddata, std::string &field,
4225 Array<OneD, NekDouble> &coeffs,
4226 [[maybe_unused]] std::unordered_map<int, int> zIdToPlane)
4230 int modes_offset = 0;
4231 int datalen = fielddata.size() / fielddef->m_fields.size();
4234 for (i = 0; i < fielddef->m_fields.size(); ++i)
4236 if (fielddef->m_fields[i] == field)
4243 ASSERTL0(i != fielddef->m_fields.size(),
4244 "Field (" + field +
") not found in file.");
4246 if (m_elmtToExpId.size() == 0)
4251 for (i = (*m_exp).size() - 1; i >= 0; --i)
4253 m_elmtToExpId[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
4257 for (i = 0; i < fielddef->m_elementIDs.size(); ++i)
4261 if (fielddef->m_uniOrder ==
true)
4266 datalen = LibUtilities::GetNumberOfCoefficients(
4267 fielddef->m_shapeType, fielddef->m_numModes, modes_offset);
4269 const int elmtId = fielddef->m_elementIDs[i];
4270 auto eIt = m_elmtToExpId.find(elmtId);
4272 if (eIt == m_elmtToExpId.end())
4275 modes_offset += (*m_exp)[0]->GetNumBases();
4279 expId = eIt->second;
4281 bool sameBasis =
true;
4282 for (
int j = 0; j < fielddef->m_basis.size(); ++j)
4284 if (fielddef->m_basis[j] != (*m_exp)[expId]->GetBasisType(j))
4291 if (datalen == (*m_exp)[expId]->GetNcoeffs() && sameBasis)
4294 &coeffs[m_coeff_offset[expId]], 1);
4298 (*m_exp)[expId]->ExtractDataToCoeffs(
4299 &fielddata[offset], fielddef->m_numModes, modes_offset,
4300 &coeffs[m_coeff_offset[expId]], fielddef->m_basis);
4304 modes_offset += (*m_exp)[0]->GetNumBases();
4310void ExpList::v_ExtractCoeffsToCoeffs(
4311 const std::shared_ptr<ExpList> &fromExpList,
4312 const Array<OneD, const NekDouble> &fromCoeffs,
4313 Array<OneD, NekDouble> &toCoeffs)
4318 map<int, int> GidToEid;
4320 for (i = 0; i < (*m_exp).size(); ++i)
4322 GidToEid[fromExpList->GetExp(i)->GetGeom()->GetGlobalID()] = i;
4325 for (i = 0; i < (*m_exp).size(); ++i)
4327 std::vector<unsigned int> nummodes;
4328 vector<LibUtilities::BasisType> basisTypes;
4330 int eid = GidToEid[(*m_exp)[i]->GetGeom()->GetGlobalID()];
4331 for (
int j = 0; j < fromExpList->GetExp(eid)->GetNumBases(); ++j)
4333 nummodes.push_back(fromExpList->GetExp(eid)->GetBasisNumModes(j));
4334 basisTypes.push_back(fromExpList->GetExp(eid)->GetBasisType(j));
4337 offset = fromExpList->GetCoeff_Offset(eid);
4338 (*m_exp)[i]->ExtractDataToCoeffs(&fromCoeffs[offset], nummodes, 0,
4339 &toCoeffs[m_coeff_offset[i]],
4347void ExpList::GetBwdWeight(Array<OneD, NekDouble> &weightAver,
4348 Array<OneD, NekDouble> &weightJump)
4350 size_t nTracePts = weightAver.size();
4352 for (
int i = 0; i < nTracePts; ++i)
4354 weightAver[i] = 0.5;
4355 weightJump[i] = 1.0;
4357 FillBwdWithBwdWeight(weightAver, weightJump);
4360void ExpList::v_GetMovingFrames(
const SpatialDomains::GeomMMF MMFdir,
4361 const Array<OneD, const NekDouble> &CircCentre,
4362 Array<OneD, Array<OneD, NekDouble>> &outarray)
4367 int nq = outarray[0].size() / MFdim;
4370 int coordim = (*m_exp)[0]->GetGeom()->GetCoordim();
4372 Array<OneD, Array<OneD, NekDouble>> MFloc(MFdim * coordim);
4374 for (
int i = 0; i < m_exp->size(); ++i)
4376 npts = (*m_exp)[i]->GetTotPoints();
4378 for (
int j = 0; j < MFdim * coordim; ++j)
4380 MFloc[j] = Array<OneD, NekDouble>(npts, 0.0);
4384 (*m_exp)[i]->GetMetricInfo()->GetMovingFrames(
4385 (*m_exp)[i]->GetPointsKeys(), MMFdir, CircCentre, MFloc);
4388 for (
int j = 0; j < MFdim; ++j)
4390 for (
int k = 0; k < coordim; ++k)
4393 &outarray[j][k * nq + m_phys_offset[i]], 1);
4404void ExpList::GenerateElementVector(
const int ElementID,
4405 const NekDouble scalar1,
4406 const NekDouble scalar2,
4407 Array<OneD, NekDouble> &outarray)
4412 Array<OneD, NekDouble> outarray_e;
4414 for (
int i = 0; i < (*m_exp).size(); ++i)
4416 npoints_e = (*m_exp)[i]->GetTotPoints();
4427 outarray_e = Array<OneD, NekDouble>(npoints_e, coeff);
4428 Vmath::Vcopy(npoints_e, &outarray_e[0], 1, &outarray[m_phys_offset[i]],
4433const Array<OneD, const std::shared_ptr<ExpList>> &ExpList::
4434 v_GetBndCondExpansions(
void)
4437 "This method is not defined or valid for this class type");
4438 static Array<OneD, const std::shared_ptr<ExpList>> result;
4442std::shared_ptr<ExpList> &ExpList::v_UpdateBndCondExpansion(
4443 [[maybe_unused]]
int i)
4446 "This method is not defined or valid for this class type");
4447 static std::shared_ptr<ExpList> result;
4461void ExpList::v_Upwind(
const Array<OneD,
const Array<OneD, NekDouble>> &Vec,
4462 const Array<OneD, const NekDouble> &Fwd,
4463 const Array<OneD, const NekDouble> &Bwd,
4464 Array<OneD, NekDouble> &Upwind)
4470 int i, j, k, e_npoints, offset;
4471 Array<OneD, NekDouble> normals;
4475 int coordim = GetCoordim(0);
4478 "Input vector does not have sufficient dimensions to "
4482 for (i = 0; i < m_exp->size(); ++i)
4485 e_npoints = (*m_exp)[i]->GetNumPoints(0);
4486 normals = (*m_exp)[i]->GetPhysNormals();
4489 offset = m_phys_offset[i];
4492 for (j = 0; j < e_npoints; ++j)
4496 for (k = 0; k < coordim; ++k)
4498 Vn += Vec[k][offset + j] * normals[k * e_npoints + j];
4504 Upwind[offset + j] = Fwd[offset + j];
4508 Upwind[offset + j] = Bwd[offset + j];
4516 "This method is not defined or valid for this class type");
4534void ExpList::v_Upwind(
const Array<OneD, const NekDouble> &Vn,
4535 const Array<OneD, const NekDouble> &Fwd,
4536 const Array<OneD, const NekDouble> &Bwd,
4537 Array<OneD, NekDouble> &Upwind)
4539 ASSERTL1(Vn.size() >= m_npoints,
"Vn is not of sufficient length");
4540 ASSERTL1(Fwd.size() >= m_npoints,
"Fwd is not of sufficient length");
4541 ASSERTL1(Bwd.size() >= m_npoints,
"Bwd is not of sufficient length");
4542 ASSERTL1(Upwind.size() >= m_npoints,
"Upwind is not of sufficient length");
4545 for (
int j = 0; j < m_npoints; ++j)
4559std::shared_ptr<ExpList> &ExpList::v_GetTrace()
4562 "This method is not defined or valid for this class type");
4563 static std::shared_ptr<ExpList> returnVal;
4567std::shared_ptr<AssemblyMapDG> &ExpList::v_GetTraceMap()
4570 "This method is not defined or valid for this class type");
4571 static std::shared_ptr<AssemblyMapDG> result;
4575std::shared_ptr<InterfaceMapDG> &ExpList::v_GetInterfaceMap()
4578 "This method is not defined or valid for this class type");
4579 static std::shared_ptr<InterfaceMapDG> result;
4583const Array<OneD, const int> &ExpList::v_GetTraceBndMap()
4585 return GetTraceMap()->GetBndCondIDToGlobalTraceID();
4588std::vector<bool> &ExpList::v_GetLeftAdjacentTraces()
4591 "This method is not defined or valid for this class type");
4592 static std::vector<bool> result;
4599void AlignFace(
const StdRegions::Orientation orient,
const int nquad1,
4600 const int nquad2,
const Array<OneD, const NekDouble> &in,
4601 Array<OneD, NekDouble> &out)
4604 if (orient == StdRegions::eDir1FwdDir2_Dir2FwdDir1 ||
4605 orient == StdRegions::eDir1BwdDir2_Dir2FwdDir1 ||
4606 orient == StdRegions::eDir1FwdDir2_Dir2BwdDir1 ||
4607 orient == StdRegions::eDir1BwdDir2_Dir2BwdDir1)
4609 for (
int i = 0; i < nquad2; ++i)
4611 for (
int j = 0; j < nquad1; ++j)
4613 out[i * nquad1 + j] = in[j * nquad2 + i];
4619 for (
int i = 0; i < nquad2; ++i)
4621 for (
int j = 0; j < nquad1; ++j)
4623 out[i * nquad1 + j] = in[i * nquad1 + j];
4628 if (orient == StdRegions::eDir1BwdDir1_Dir2FwdDir2 ||
4629 orient == StdRegions::eDir1BwdDir1_Dir2BwdDir2 ||
4630 orient == StdRegions::eDir1BwdDir2_Dir2FwdDir1 ||
4631 orient == StdRegions::eDir1BwdDir2_Dir2BwdDir1)
4634 for (
int i = 0; i < nquad2; ++i)
4636 for (
int j = 0; j < nquad1 / 2; ++j)
4638 swap(out[i * nquad1 + j], out[i * nquad1 + nquad1 - j - 1]);
4643 if (orient == StdRegions::eDir1FwdDir1_Dir2BwdDir2 ||
4644 orient == StdRegions::eDir1BwdDir1_Dir2BwdDir2 ||
4645 orient == StdRegions::eDir1FwdDir2_Dir2BwdDir1 ||
4646 orient == StdRegions::eDir1BwdDir2_Dir2BwdDir1)
4649 for (
int j = 0; j < nquad1; ++j)
4651 for (
int i = 0; i < nquad2 / 2; ++i)
4653 swap(out[i * nquad1 + j], out[(nquad2 - i - 1) * nquad1 + j]);
4668void ExpList::v_GetNormals(Array<OneD, Array<OneD, NekDouble>> &normals)
4670 int i, j, k, e_npoints, offset;
4671 Array<OneD, Array<OneD, NekDouble>> locnormals;
4674 int coordim = GetCoordim(0);
4676 ASSERTL1(normals.size() >= coordim,
4677 "Output vector does not have sufficient dimensions to "
4685 for (i = 0; i < m_exp->size(); ++i)
4687 LocalRegions::ExpansionSharedPtr loc_exp = (*m_exp)[i];
4689 LocalRegions::ExpansionSharedPtr loc_elmt =
4690 loc_exp->GetLeftAdjacentElementExp();
4694 locnormals = loc_elmt->GetTraceNormal(
4695 loc_exp->GetLeftAdjacentElementTrace());
4698 offset = m_phys_offset[i];
4701 for (j = 0; j < e_npoints; ++j)
4705 for (k = 0; k < coordim; ++k)
4707 normals[k][offset] = locnormals[k][0];
4716 for (i = 0; i < m_exp->size(); ++i)
4718 LocalRegions::ExpansionSharedPtr traceExp = (*m_exp)[i];
4720 int offset = m_phys_offset[i];
4723 LocalRegions::ExpansionSharedPtr exp2D =
4724 traceExp->GetLeftAdjacentElementExp();
4725 int edgeId = traceExp->GetLeftAdjacentElementTrace();
4726 LibUtilities::PointsKey edgePoints =
4727 exp2D->GetTraceBasisKey(edgeId).GetPointsKey();
4728 LibUtilities::PointsKey tracePoints =
4729 traceExp->GetBasis(0)->GetPointsKey();
4736 bool useRight =
false;
4737 if (traceExp->GetRightAdjacentElementTrace() >= 0)
4739 LocalRegions::ExpansionSharedPtr Rexp2D =
4740 traceExp->GetRightAdjacentElementExp();
4741 int RedgeId = traceExp->GetRightAdjacentElementTrace();
4742 LibUtilities::PointsKey RedgePoints =
4743 Rexp2D->GetTraceBasisKey(RedgeId).GetPointsKey();
4745 if (RedgePoints.GetNumPoints() > edgePoints.GetNumPoints())
4749 edgePoints = RedgePoints;
4754 const Array<OneD, const Array<OneD, NekDouble>> &locNormals =
4755 exp2D->GetTraceNormal(edgeId);
4760 for (
int d = 0;
d < coordim; ++
d)
4762 LibUtilities::Interp1D(edgePoints, locNormals[d].data(),
4764 normals[d].data() + offset);
4770 &normals[d][offset], 1);
4778 Array<OneD, NekDouble> tmp;
4781 for (i = 0; i < m_exp->size(); ++i)
4783 LocalRegions::ExpansionSharedPtr traceExp = (*m_exp)[i];
4785 int offset = m_phys_offset[i];
4801 LocalRegions::ExpansionSharedPtr exp3D =
4802 traceExp->GetLeftAdjacentElementExp();
4803 int faceId = traceExp->GetLeftAdjacentElementTrace();
4804 const Array<OneD, const Array<OneD, NekDouble>> &locNormals =
4805 exp3D->GetTraceNormal(faceId);
4807 StdRegions::Orientation orient = exp3D->GetTraceOrient(faceId);
4811 int fromid0, fromid1;
4813 if (orient < StdRegions::eDir1FwdDir2_Dir2FwdDir1)
4824 LibUtilities::BasisKey faceBasis0 =
4825 exp3D->GetTraceBasisKey(faceId, fromid0);
4826 LibUtilities::BasisKey faceBasis1 =
4827 exp3D->GetTraceBasisKey(faceId, fromid1);
4828 LibUtilities::BasisKey traceBasis0 =
4829 traceExp->GetBasis(0)->GetBasisKey();
4830 LibUtilities::BasisKey traceBasis1 =
4831 traceExp->GetBasis(1)->GetBasisKey();
4833 const int faceNq0 = faceBasis0.GetNumPoints();
4834 const int faceNq1 = faceBasis1.GetNumPoints();
4839 Array<OneD, int> map;
4840 exp3D->ReOrientTracePhysMap(orient, map, faceNq0, faceNq1);
4843 Array<OneD, NekDouble> traceNormals(faceNq0 * faceNq1);
4844 for (j = 0; j < coordim; ++j)
4849 LibUtilities::Interp2D(
4850 faceBasis0.GetPointsKey(), faceBasis1.GetPointsKey(),
4851 traceNormals, traceBasis0.GetPointsKey(),
4852 traceBasis1.GetPointsKey(), tmp = normals[j] + offset);
4860 "This method is not defined or valid for this class type");
4877void ExpList::GetElmtNormalLength(Array<OneD, NekDouble> &lengthsFwd,
4878 Array<OneD, NekDouble> &lengthsBwd)
4882 Array<OneD, NekDouble> locLeng;
4883 Array<OneD, Array<OneD, NekDouble>> lengintp(2);
4884 Array<OneD, Array<OneD, NekDouble>> lengAdd(2);
4885 Array<OneD, int> LRbndnumbs(2);
4886 Array<OneD, Array<OneD, NekDouble>> lengLR(2);
4887 lengLR[0] = lengthsFwd;
4888 lengLR[1] = lengthsBwd;
4889 Array<OneD, LocalRegions::ExpansionSharedPtr> LRelmts(2);
4890 LocalRegions::ExpansionSharedPtr loc_elmt;
4891 LocalRegions::ExpansionSharedPtr loc_exp;
4892 int e_npoints0 = -1;
4893 if (m_expType == e1D)
4895 for (
int i = 0; i < m_exp->size(); ++i)
4897 loc_exp = (*m_exp)[i];
4898 int offset = m_phys_offset[i];
4900 e_npoints = (*m_exp)[i]->GetNumPoints(0);
4901 if (e_npoints0 < e_npoints)
4903 for (
int nlr = 0; nlr < 2; nlr++)
4905 lengintp[nlr] = Array<OneD, NekDouble>(e_npoints, 0.0);
4907 e_npoints0 = e_npoints;
4910 LRelmts[0] = loc_exp->GetLeftAdjacentElementExp();
4911 LRelmts[1] = loc_exp->GetRightAdjacentElementExp();
4913 LRbndnumbs[0] = loc_exp->GetLeftAdjacentElementTrace();
4914 LRbndnumbs[1] = loc_exp->GetRightAdjacentElementTrace();
4915 for (
int nlr = 0; nlr < 2; ++nlr)
4918 lengAdd[nlr] = lengintp[nlr];
4919 int bndNumber = LRbndnumbs[nlr];
4920 loc_elmt = LRelmts[nlr];
4923 locLeng = loc_elmt->GetElmtBndNormDirElmtLen(bndNumber);
4925 LibUtilities::PointsKey to_key =
4926 loc_exp->GetBasis(0)->GetPointsKey();
4927 LibUtilities::PointsKey from_key =
4928 loc_elmt->GetTraceBasisKey(bndNumber).GetPointsKey();
4935 LibUtilities::Interp1D(from_key, locLeng, to_key,
4937 lengAdd[nlr] = lengintp[nlr];
4940 for (
int j = 0; j < e_npoints; ++j)
4942 lengLR[nlr][offset + j] = lengAdd[nlr][j];
4947 else if (m_expType == e2D)
4949 for (
int i = 0; i < m_exp->size(); ++i)
4951 loc_exp = (*m_exp)[i];
4952 int offset = m_phys_offset[i];
4954 LibUtilities::BasisKey traceBasis0 =
4955 loc_exp->GetBasis(0)->GetBasisKey();
4956 LibUtilities::BasisKey traceBasis1 =
4957 loc_exp->GetBasis(1)->GetBasisKey();
4958 const int TraceNq0 = traceBasis0.GetNumPoints();
4959 const int TraceNq1 = traceBasis1.GetNumPoints();
4960 e_npoints = TraceNq0 * TraceNq1;
4961 if (e_npoints0 < e_npoints)
4963 for (
int nlr = 0; nlr < 2; nlr++)
4965 lengintp[nlr] = Array<OneD, NekDouble>(e_npoints, 0.0);
4967 e_npoints0 = e_npoints;
4970 LRelmts[0] = loc_exp->GetLeftAdjacentElementExp();
4971 LRelmts[1] = loc_exp->GetRightAdjacentElementExp();
4973 LRbndnumbs[0] = loc_exp->GetLeftAdjacentElementTrace();
4974 LRbndnumbs[1] = loc_exp->GetRightAdjacentElementTrace();
4975 for (
int nlr = 0; nlr < 2; ++nlr)
4978 int bndNumber = LRbndnumbs[nlr];
4979 loc_elmt = LRelmts[nlr];
4982 locLeng = loc_elmt->GetElmtBndNormDirElmtLen(bndNumber);
4985 StdRegions::Orientation orient =
4986 loc_elmt->GetTraceOrient(bndNumber);
4988 int fromid0, fromid1;
4989 if (orient < StdRegions::eDir1FwdDir2_Dir2FwdDir1)
5000 LibUtilities::BasisKey faceBasis0 =
5001 loc_elmt->GetTraceBasisKey(bndNumber, fromid0);
5002 LibUtilities::BasisKey faceBasis1 =
5003 loc_elmt->GetTraceBasisKey(bndNumber, fromid1);
5004 const int faceNq0 = faceBasis0.GetNumPoints();
5005 const int faceNq1 = faceBasis1.GetNumPoints();
5006 Array<OneD, NekDouble> alignedLeng(faceNq0 * faceNq1);
5008 AlignFace(orient, faceNq0, faceNq1, locLeng, alignedLeng);
5009 LibUtilities::Interp2D(
5010 faceBasis0.GetPointsKey(), faceBasis1.GetPointsKey(),
5011 alignedLeng, traceBasis0.GetPointsKey(),
5012 traceBasis1.GetPointsKey(), lengintp[nlr]);
5015 for (
int j = 0; j < e_npoints; ++j)
5017 lengLR[nlr][offset + j] = lengintp[nlr][j];
5024void ExpList::v_AddTraceIntegral(
5025 [[maybe_unused]]
const Array<OneD, const NekDouble> &Fn,
5026 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5029 "This method is not defined or valid for this class type");
5032void ExpList::v_AddFwdBwdTraceIntegral(
5033 [[maybe_unused]]
const Array<OneD, const NekDouble> &Fwd,
5034 [[maybe_unused]]
const Array<OneD, const NekDouble> &Bwd,
5035 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5038 "This method is not defined or valid for this class type");
5041void ExpList::v_GetFwdBwdTracePhys([[maybe_unused]] Array<OneD, NekDouble> &Fwd,
5042 [[maybe_unused]] Array<OneD, NekDouble> &Bwd)
5045 "This method is not defined or valid for this class type");
5048void ExpList::v_GetFwdBwdTracePhys(
5049 [[maybe_unused]]
const Array<OneD, const NekDouble> &field,
5050 [[maybe_unused]] Array<OneD, NekDouble> &Fwd,
5051 [[maybe_unused]] Array<OneD, NekDouble> &Bwd, [[maybe_unused]]
bool FillBnd,
5052 [[maybe_unused]]
bool PutFwdInBwdOnBCs, [[maybe_unused]]
bool DoExchange)
5055 "This method is not defined or valid for this class type");
5058void ExpList::v_FillBwdWithBoundCond(
5059 [[maybe_unused]]
const Array<OneD, NekDouble> &Fwd,
5060 [[maybe_unused]] Array<OneD, NekDouble> &Bwd,
5061 [[maybe_unused]]
bool PutFwdInBwdOnBCs)
5064 "This method is not defined or valid for this class type");
5067void ExpList::v_AddTraceQuadPhysToField(
5068 [[maybe_unused]]
const Array<OneD, const NekDouble> &Fwd,
5069 [[maybe_unused]]
const Array<OneD, const NekDouble> &Bwd,
5070 [[maybe_unused]] Array<OneD, NekDouble> &field)
5073 "v_AddTraceQuadPhysToField is not defined for this class type");
5076void ExpList::v_AddTraceQuadPhysToOffDiag(
5077 [[maybe_unused]]
const Array<OneD, const NekDouble> &Fwd,
5078 [[maybe_unused]]
const Array<OneD, const NekDouble> &Bwd,
5079 [[maybe_unused]] Array<OneD, NekDouble> &field)
5082 "v_AddTraceQuadPhysToOffDiag is not defined for this class");
5085void ExpList::v_GetLocTraceFromTracePts(
5086 [[maybe_unused]]
const Array<OneD, const NekDouble> &Fwd,
5087 [[maybe_unused]]
const Array<OneD, const NekDouble> &Bwd,
5088 [[maybe_unused]] Array<OneD, NekDouble> &locTraceFwd,
5089 [[maybe_unused]] Array<OneD, NekDouble> &locTraceBwd)
5092 "v_GetLocTraceFromTracePts is not defined for this class");
5095const Array<OneD, const NekDouble> &ExpList::v_GetBndCondBwdWeight()
5098 "v_GetBndCondBwdWeight is not defined for this class type");
5099 static Array<OneD, NekDouble> tmp;
5103void ExpList::v_SetBndCondBwdWeight([[maybe_unused]]
const int index,
5104 [[maybe_unused]]
const NekDouble value)
5107 "v_setBndCondBwdWeight is not defined for this class type");
5110const vector<bool> &ExpList::v_GetLeftAdjacentFaces(
void)
const
5113 "This method is not defined or valid for this class type");
5114 static vector<bool> tmp;
5118void ExpList::v_ExtractTracePhys(
5119 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5122 "This method is not defined or valid for this class type");
5125void ExpList::v_ExtractTracePhys(
5126 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5127 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5128 [[maybe_unused]]
bool gridVelocity)
5131 "This method is not defined or valid for this class type");
5134void ExpList::v_MultiplyByInvMassMatrix(
5135 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5136 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5139 "This method is not defined or valid for this class type");
5142GlobalLinSysKey ExpList::v_HelmSolve(
5143 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5144 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5145 [[maybe_unused]]
const StdRegions::ConstFactorMap &factors,
5146 [[maybe_unused]]
const StdRegions::VarCoeffMap &varcoeff,
5147 [[maybe_unused]]
const MultiRegions::VarFactorsMap &varfactors,
5148 [[maybe_unused]]
const Array<OneD, const NekDouble> &dirForcing,
5149 [[maybe_unused]]
const bool PhysSpaceForcing)
5151 NEKERROR(ErrorUtil::efatal,
"HelmSolve not implemented.");
5152 return NullGlobalLinSysKey;
5155GlobalLinSysKey ExpList::v_LinearAdvectionDiffusionReactionSolve(
5156 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5157 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5158 [[maybe_unused]]
const StdRegions::ConstFactorMap &factors,
5159 [[maybe_unused]]
const StdRegions::VarCoeffMap &varcoeff,
5160 [[maybe_unused]]
const MultiRegions::VarFactorsMap &varfactors,
5161 [[maybe_unused]]
const Array<OneD, const NekDouble> &dirForcing,
5162 [[maybe_unused]]
const bool PhysSpaceForcing)
5165 "LinearAdvectionDiffusionReactionSolve not implemented.");
5166 return NullGlobalLinSysKey;
5169GlobalLinSysKey ExpList::v_LinearAdvectionReactionSolve(
5170 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5171 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5172 [[maybe_unused]]
const StdRegions::ConstFactorMap &factors,
5173 [[maybe_unused]]
const StdRegions::VarCoeffMap &varcoeff,
5174 [[maybe_unused]]
const MultiRegions::VarFactorsMap &varfactors,
5175 [[maybe_unused]]
const Array<OneD, const NekDouble> &dirForcing,
5176 [[maybe_unused]]
const bool PhysSpaceForcing)
5179 "LinearAdvectionReactionSolve not implemented.");
5180 return NullGlobalLinSysKey;
5183void ExpList::v_HomogeneousFwdTrans(
5184 [[maybe_unused]]
const int npts,
5185 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5186 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5187 [[maybe_unused]]
bool Shuff, [[maybe_unused]]
bool UnShuff)
5190 "This method is not defined or valid for this class type");
5193void ExpList::v_HomogeneousBwdTrans(
5194 [[maybe_unused]]
const int npts,
5195 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5196 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5197 [[maybe_unused]]
bool Shuff, [[maybe_unused]]
bool UnShuff)
5200 "This method is not defined or valid for this class type");
5203void ExpList::v_DealiasedProd(
5204 [[maybe_unused]]
const int npts,
5205 [[maybe_unused]]
const Array<OneD, NekDouble> &inarray1,
5206 [[maybe_unused]]
const Array<OneD, NekDouble> &inarray2,
5207 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5210 "This method is not defined or valid for this class type");
5213void ExpList::v_DealiasedDotProd(
5214 [[maybe_unused]]
const int npts,
5215 [[maybe_unused]]
const Array<OneD, Array<OneD, NekDouble>> &inarray1,
5216 [[maybe_unused]]
const Array<OneD, Array<OneD, NekDouble>> &inarray2,
5217 [[maybe_unused]] Array<OneD, Array<OneD, NekDouble>> &outarray)
5220 "This method is not defined or valid for this class type");
5223void ExpList::v_GetBCValues(
5224 [[maybe_unused]] Array<OneD, NekDouble> &BndVals,
5225 [[maybe_unused]]
const Array<OneD, NekDouble> &TotField,
5226 [[maybe_unused]]
int BndID)
5229 "This method is not defined or valid for this class type");
5232void ExpList::v_NormVectorIProductWRTBase(
5233 [[maybe_unused]] Array<OneD, const NekDouble> &V1,
5234 [[maybe_unused]] Array<OneD, const NekDouble> &V2,
5235 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5236 [[maybe_unused]]
int BndID)
5239 "This method is not defined or valid for this class type");
5242void ExpList::v_NormVectorIProductWRTBase(
5243 Array<OneD, Array<OneD, NekDouble>> &V, Array<OneD, NekDouble> &outarray)
5245 Array<OneD, NekDouble> tmp;
5246 switch (GetCoordim(0))
5250 for (
int i = 0; i < GetExpSize(); ++i)
5252 (*m_exp)[i]->NormVectorIProductWRTBase(
5253 V[0] + GetPhys_Offset(i),
5254 tmp = outarray + GetCoeff_Offset(i));
5260 for (
int i = 0; i < GetExpSize(); ++i)
5262 (*m_exp)[i]->NormVectorIProductWRTBase(
5263 V[0] + GetPhys_Offset(i), V[1] + GetPhys_Offset(i),
5264 tmp = outarray + GetCoeff_Offset(i));
5270 for (
int i = 0; i < GetExpSize(); ++i)
5272 (*m_exp)[i]->NormVectorIProductWRTBase(
5273 V[0] + GetPhys_Offset(i), V[1] + GetPhys_Offset(i),
5274 V[2] + GetPhys_Offset(i),
5275 tmp = outarray + GetCoeff_Offset(i));
5280 NEKERROR(ErrorUtil::efatal,
"Dimension not supported");
5285void ExpList::v_ImposeDirichletConditions(
5286 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5289 "This method is not defined or valid for this class type");
5292void ExpList::v_ImposeNeumannConditions(
5293 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5296 "This method is not defined or valid for this class type");
5299void ExpList::v_ImposeRobinConditions(
5300 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5303 "This method is not defined or valid for this class type");
5308void ExpList::v_FillBndCondFromField(
5309 [[maybe_unused]]
const Array<OneD, NekDouble> coeffs)
5312 "This method is not defined or valid for this class type");
5317void ExpList::v_FillBndCondFromField(
5318 [[maybe_unused]]
const int nreg,
5319 [[maybe_unused]]
const Array<OneD, NekDouble> coeffs)
5322 "This method is not defined or valid for this class type");
5325void ExpList::v_LocalToGlobal([[maybe_unused]]
bool useComm)
5328 "This method is not defined or valid for this class type");
5331void ExpList::v_LocalToGlobal(
5332 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5333 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5334 [[maybe_unused]]
bool useComm)
5337 "This method is not defined or valid for this class type");
5340void ExpList::v_GlobalToLocal(
void)
5343 "This method is not defined or valid for this class type");
5346void ExpList::v_GlobalToLocal(
5347 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5348 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5351 "This method is not defined or valid for this class type");
5354void ExpList::v_FwdTrans(
const Array<OneD, const NekDouble> &inarray,
5355 Array<OneD, NekDouble> &outarray)
5357 v_FwdTransLocalElmt(inarray, outarray);
5371void ExpList::v_IProductWRTBase(
const Array<OneD, const NekDouble> &inarray,
5372 Array<OneD, NekDouble> &outarray)
5374 LibUtilities::Timer timer;
5377 if (m_collectionsDoInit[Collections::eIProductWRTBase])
5379 for (
int i = 0; i < m_collections.size(); ++i)
5381 m_collections[i].Initialise(Collections::eIProductWRTBase);
5383 m_collectionsDoInit[Collections::eIProductWRTBase] =
false;
5386 Array<OneD, NekDouble> tmp;
5387 int input_offset{0};
5388 int output_offset{0};
5389 for (
int i = 0; i < m_collections.size(); ++i)
5391 m_collections[i].ApplyOperator(Collections::eIProductWRTBase,
5392 inarray + input_offset,
5393 tmp = outarray + output_offset);
5395 m_collections[i].GetInputSize(Collections::eIProductWRTBase);
5397 m_collections[i].GetOutputSize(Collections::eIProductWRTBase);
5401 timer.AccumulateRegion(
"Collections:IProductWRTBase", 10);
5415void ExpList::v_GetCoords(Array<OneD, NekDouble> &coord_0,
5416 Array<OneD, NekDouble> &coord_1,
5417 Array<OneD, NekDouble> &coord_2)
5419 if (GetNumElmts() == 0)
5425 Array<OneD, NekDouble> e_coord_0;
5426 Array<OneD, NekDouble> e_coord_1;
5427 Array<OneD, NekDouble> e_coord_2;
5429 switch (GetExp(0)->GetCoordim())
5432 for (i = 0; i < (*m_exp).size(); ++i)
5434 e_coord_0 = coord_0 + m_phys_offset[i];
5435 (*m_exp)[i]->GetCoords(e_coord_0);
5439 ASSERTL0(coord_1.size() != 0,
"output coord_1 is not defined");
5441 for (i = 0; i < (*m_exp).size(); ++i)
5443 e_coord_0 = coord_0 + m_phys_offset[i];
5444 e_coord_1 = coord_1 + m_phys_offset[i];
5445 (*m_exp)[i]->GetCoords(e_coord_0, e_coord_1);
5449 ASSERTL0(coord_1.size() != 0,
"output coord_1 is not defined");
5450 ASSERTL0(coord_2.size() != 0,
"output coord_2 is not defined");
5452 for (i = 0; i < (*m_exp).size(); ++i)
5454 e_coord_0 = coord_0 + m_phys_offset[i];
5455 e_coord_1 = coord_1 + m_phys_offset[i];
5456 e_coord_2 = coord_2 + m_phys_offset[i];
5457 (*m_exp)[i]->GetCoords(e_coord_0, e_coord_1, e_coord_2);
5463void ExpList::v_GetCoords(
const int eid, Array<OneD, NekDouble> &xc0,
5464 Array<OneD, NekDouble> &xc1,
5465 Array<OneD, NekDouble> &xc2)
5467 (*m_exp)[eid]->GetCoords(xc0, xc1, xc2);
5475void ExpList::v_SetUpPhysNormals()
5477 for (
int i = 0; i < m_exp->size(); ++i)
5479 for (
int j = 0; j < (*m_exp)[i]->GetNtraces(); ++j)
5481 (*m_exp)[i]->ComputeTraceNormal(j);
5488void ExpList::v_GetBndElmtExpansion(
5489 [[maybe_unused]]
int i, [[maybe_unused]] std::shared_ptr<ExpList> &result,
5490 [[maybe_unused]]
const bool DeclareCoeffPhysArrays)
5493 "This method is not defined or valid for this class type");
5498void ExpList::v_ExtractElmtToBndPhys(
const int i,
5499 const Array<OneD, NekDouble> &element,
5500 Array<OneD, NekDouble> &boundary)
5503 Array<OneD, NekDouble> tmp1, tmp2;
5504 LocalRegions::ExpansionSharedPtr elmt;
5506 Array<OneD, int> ElmtID, EdgeID;
5507 GetBoundaryToElmtMap(ElmtID, EdgeID);
5511 Array<OneD, NekDouble>(GetBndCondExpansions()[i]->GetTotPoints(), 0.0);
5514 for (cnt = n = 0; n < i; ++n)
5516 cnt += GetBndCondExpansions()[n]->GetExpSize();
5521 for (n = 0; n < GetBndCondExpansions()[i]->GetExpSize(); ++n)
5523 offsetBnd = GetBndCondExpansions()[i]->GetPhys_Offset(n);
5525 elmt = GetExp(ElmtID[cnt + n]);
5526 elmt->GetTracePhysVals(
5527 EdgeID[cnt + n], GetBndCondExpansions()[i]->GetExp(n),
5528 tmp1 = element + offsetElmt, tmp2 = boundary + offsetBnd);
5530 offsetElmt += elmt->GetTotPoints();
5536void ExpList::v_ExtractPhysToBndElmt(
const int i,
5537 const Array<OneD, const NekDouble> &phys,
5538 Array<OneD, NekDouble> &bndElmt)
5542 Array<OneD, int> ElmtID, EdgeID;
5543 GetBoundaryToElmtMap(ElmtID, EdgeID);
5546 for (cnt = n = 0; n < i; ++n)
5548 cnt += GetBndCondExpansions()[n]->GetExpSize();
5553 for (n = 0; n < GetBndCondExpansions()[i]->GetExpSize(); ++n)
5555 npoints += GetExp(ElmtID[cnt + n])->GetTotPoints();
5559 bndElmt = Array<OneD, NekDouble>(npoints, 0.0);
5564 for (n = 0; n < GetBndCondExpansions()[i]->GetExpSize(); ++n)
5566 nq = GetExp(ElmtID[cnt + n])->GetTotPoints();
5567 offsetPhys = GetPhys_Offset(ElmtID[cnt + n]);
5568 Vmath::Vcopy(nq, &phys[offsetPhys], 1, &bndElmt[offsetElmt], 1);
5575void ExpList::v_ExtractPhysToBnd(
int i,
5576 const Array<OneD, const NekDouble> &phys,
5577 Array<OneD, NekDouble> &bnd)
5580 Array<OneD, NekDouble> tmp1;
5581 LocalRegions::ExpansionSharedPtr elmt;
5583 Array<OneD, int> ElmtID, EdgeID;
5584 GetBoundaryToElmtMap(ElmtID, EdgeID);
5588 Array<OneD, NekDouble>(GetBndCondExpansions()[i]->GetTotPoints(), 0.0);
5591 for (cnt = n = 0; n < i; ++n)
5593 cnt += GetBndCondExpansions()[n]->GetExpSize();
5598 for (n = 0; n < GetBndCondExpansions()[i]->GetExpSize(); ++n)
5600 offsetPhys = GetPhys_Offset(ElmtID[cnt + n]);
5601 offsetBnd = GetBndCondExpansions()[i]->GetPhys_Offset(n);
5603 elmt = GetExp(ElmtID[cnt + n]);
5604 elmt->GetTracePhysVals(EdgeID[cnt + n],
5605 GetBndCondExpansions()[i]->GetExp(n),
5606 phys + offsetPhys, tmp1 = bnd + offsetBnd);
5612void ExpList::v_GetBoundaryNormals(
int i,
5613 Array<OneD, Array<OneD, NekDouble>> &normals)
5616 int coordim = GetCoordim(0);
5617 Array<OneD, NekDouble> tmp;
5618 LocalRegions::ExpansionSharedPtr elmt;
5620 Array<OneD, int> ElmtID, EdgeID;
5621 GetBoundaryToElmtMap(ElmtID, EdgeID);
5624 normals = Array<OneD, Array<OneD, NekDouble>>(coordim);
5625 for (j = 0; j < coordim; ++j)
5627 normals[j] = Array<OneD, NekDouble>(
5628 GetBndCondExpansions()[i]->GetTotPoints(), 0.0);
5632 for (cnt = n = 0; n < i; ++n)
5634 cnt += GetBndCondExpansions()[n]->GetExpSize();
5638 for (n = 0; n < GetBndCondExpansions()[i]->GetExpSize(); ++n)
5640 offset = GetBndCondExpansions()[i]->GetPhys_Offset(n);
5642 elmt = GetExp(ElmtID[cnt + n]);
5643 const Array<OneD, const Array<OneD, NekDouble>> normalsElmt =
5644 elmt->GetTraceNormal(EdgeID[cnt + n]);
5647 for (j = 0; j < coordim; ++j)
5649 GetBndCondExpansions()[i]->GetExp(n)->PhysInterp(
5650 elmt, normalsElmt[j], tmp = normals[j] + offset);
5657void ExpList::v_GetBoundaryToElmtMap([[maybe_unused]] Array<OneD, int> &ElmtID,
5658 [[maybe_unused]] Array<OneD, int> &EdgeID)
5661 "This method is not defined or valid for this class type");
5664void ExpList::v_FillBwdWithBwdWeight(
5665 [[maybe_unused]] Array<OneD, NekDouble> &weightave,
5666 [[maybe_unused]] Array<OneD, NekDouble> &weightjmp)
5668 NEKERROR(ErrorUtil::efatal,
"v_FillBwdWithBwdWeight not defined");
5671void ExpList::v_PeriodicBwdCopy(
5672 [[maybe_unused]]
const Array<OneD, const NekDouble> &Fwd,
5673 [[maybe_unused]] Array<OneD, NekDouble> &Bwd)
5675 NEKERROR(ErrorUtil::efatal,
"v_PeriodicBwdCopy not defined");
5678void ExpList::v_PeriodicBwdRot(
5679 [[maybe_unused]] Array<OneD, Array<OneD, NekDouble>> &Bwd)
5681 NEKERROR(ErrorUtil::efatal,
"v_PeriodicBwdRot not defined");
5684void ExpList::v_PeriodicDeriveBwdRot(
5685 [[maybe_unused]] TensorOfArray3D<NekDouble> &Bwd)
5687 NEKERROR(ErrorUtil::efatal,
"v_PeriodicDeriveBwdRot not defined");
5690void ExpList::v_RotLocalBwdTrace(
5691 [[maybe_unused]] Array<OneD, Array<OneD, NekDouble>> &Bwd)
5693 NEKERROR(ErrorUtil::efatal,
"v_RotLocalBwdTrace not defined");
5696void ExpList::v_RotLocalBwdDeriveTrace(
5697 [[maybe_unused]] TensorOfArray3D<NekDouble> &Bwd)
5699 NEKERROR(ErrorUtil::efatal,
"v_RotLocalBwdDeriveTrace not defined");
5704const Array<OneD, const SpatialDomains::BoundaryConditionShPtr> &ExpList::
5705 v_GetBndConditions(
void)
5708 "This method is not defined or valid for this class type");
5709 static Array<OneD, const SpatialDomains::BoundaryConditionShPtr> result;
5715Array<OneD, SpatialDomains::BoundaryConditionShPtr> &ExpList::
5716 v_UpdateBndConditions()
5719 "This method is not defined or valid for this class type");
5720 static Array<OneD, SpatialDomains::BoundaryConditionShPtr> result;
5726void ExpList::v_EvaluateBoundaryConditions(
5727 [[maybe_unused]]
const NekDouble time,
5728 [[maybe_unused]]
const std::string varName,
5729 [[maybe_unused]]
const NekDouble x2_in,
5730 [[maybe_unused]]
const NekDouble x3_in)
5733 "This method is not defined or valid for this class type");
5738map<int, RobinBCInfoSharedPtr> ExpList::v_GetRobinBCInfo(
void)
5741 "This method is not defined or valid for this class type");
5742 static map<int, RobinBCInfoSharedPtr> result;
5748void ExpList::v_GetPeriodicEntities([[maybe_unused]] PeriodicMap &periodicVerts,
5749 [[maybe_unused]] PeriodicMap &periodicEdges,
5750 [[maybe_unused]] PeriodicMap &periodicFaces)
5753 "This method is not defined or valid for this class type");
5756SpatialDomains::BoundaryConditionShPtr ExpList::GetBoundaryCondition(
5757 const SpatialDomains::BoundaryConditionCollection &collection,
5758 unsigned int regionId,
const std::string &variable)
5760 auto collectionIter = collection.find(regionId);
5761 ASSERTL1(collectionIter != collection.end(),
5762 "Unable to locate collection " + std::to_string(regionId));
5764 const SpatialDomains::BoundaryConditionMapShPtr bndCondMap =
5765 (*collectionIter).second;
5766 auto conditionMapIter = bndCondMap->find(variable);
5767 ASSERTL1(conditionMapIter != bndCondMap->end(),
5768 "Unable to locate condition map.");
5770 const SpatialDomains::BoundaryConditionShPtr boundaryCondition =
5771 (*conditionMapIter).second;
5773 return boundaryCondition;
5779 "This method is not defined or valid for this class type");
5780 return NullExpListSharedPtr;
5787void ExpList::CreateCollections(Collections::ImplementationType ImpType)
5790 m_collectionsDoInit =
5791 std::vector<bool>(Collections::SIZE_OperatorType,
true);
5795 Collections::CollectionOptimisation colOpt(
5796 m_session, (*m_exp)[0]->GetShapeDimension(), ImpType);
5801 bool autotuning = colOpt.IsUsingAutotuning();
5802 if ((autotuning ==
false) && (ImpType == Collections::eNoImpType))
5806 if (m_session->GetUpdateOptFile() && m_graph)
5811 if (m_graph->GetMeshDimension() == (*m_exp)[0]->GetShapeDimension())
5817 bool verbose = (m_session->DefinesCmdLineArgument(
"verbose")) &&
5818 (m_session->GetComm()->GetRank() == 0);
5821 m_collections.clear();
5831 (colOpt.GetMaxCollectionSize() > 0 ? colOpt.GetMaxCollectionSize()
5832 : 2 * m_exp->size());
5834 vector<StdRegions::StdExpansionSharedPtr> collExp;
5835 LocalRegions::ExpansionSharedPtr exp = (*m_exp)[0];
5836 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(exp);
5839 collExp.push_back(exp);
5843 std::vector<LibUtilities::BasisKey> thisbasisKeys(
5844 3, LibUtilities::NullBasisKey);
5845 std::vector<LibUtilities::BasisKey> prevbasisKeys(
5846 3, LibUtilities::NullBasisKey);
5848 for (
int d = 0;
d < exp->GetNumBases();
d++)
5850 prevbasisKeys[
d] = exp->GetBasis(d)->GetBasisKey();
5855 exp->GetMetricInfo()->GetGtype() == SpatialDomains::eDeformed;
5858 int mincol = (*m_exp).size();
5862 for (
int i = 1; i < (*m_exp).size(); i++)
5867 for (
int d = 0;
d < exp->GetNumBases();
d++)
5869 thisbasisKeys[
d] = exp->GetBasis(d)->GetBasisKey();
5873 (exp->GetMetricInfo()->GetGtype() == SpatialDomains::eDeformed);
5877 if (thisbasisKeys != prevbasisKeys || prevDef != Deformed ||
5887 if (collExp.size() > collsize)
5890 colOpt.SetWithTimings(collExp, impTypes, verbose);
5891 collsize = collExp.size();
5894 Collections::OperatorImpMap impTypes =
5895 colOpt.GetOperatorImpMap(exp);
5897 Collections::Collection tmp(collExp, impTypes);
5898 m_collections.push_back(tmp);
5899 mincol =
min(mincol, (
int)collExp.size());
5900 maxcol =
max(maxcol, (
int)collExp.size());
5901 meancol += collExp.size();
5905 impTypes = colOpt.GetOperatorImpMap((*m_exp)[i]);
5914 collExp.push_back(exp);
5917 prevbasisKeys = thisbasisKeys;
5924 if (collExp.size() > collsize)
5926 impTypes = colOpt.SetWithTimings(collExp, impTypes, verbose);
5927 collsize = collExp.size();
5930 Collections::Collection tmp(collExp, impTypes);
5931 m_collections.push_back(tmp);
5934 mincol =
min(mincol, (
int)collExp.size());
5935 maxcol =
max(maxcol, (
int)collExp.size());
5936 meancol += collExp.size();
5937 meancol /= m_collections.size();
5938 cout <<
"Collection group: num. = " << m_collections.size()
5939 <<
"; mean len = " << meancol <<
" (min = " << mincol
5940 <<
", max = " << maxcol <<
")" << endl;
5949 if ((m_session->GetUpdateOptFile()) && (ImpType == Collections::eNoImpType))
5951 colOpt.UpdateOptFile(m_session->GetSessionName(), m_comm);
5954 m_session->SetUpdateOptFile(
false);
5958void ExpList::ClearGlobalLinSysManager(
void)
5960 v_ClearGlobalLinSysManager();
5968int ExpList::GetPoolCount(std::string poolName)
5970 return v_GetPoolCount(poolName);
5973void ExpList::UnsetGlobalLinSys(GlobalLinSysKey key,
bool clearLocalMatrices)
5975 v_UnsetGlobalLinSys(key, clearLocalMatrices);
5978LibUtilities::NekManager<GlobalLinSysKey, GlobalLinSys> &ExpList::
5979 GetGlobalLinSysManager(
void)
5981 return v_GetGlobalLinSysManager();
5984void ExpList::v_PhysInterp1DScaled([[maybe_unused]]
const NekDouble scale,
5985 const Array<OneD, NekDouble> &inarray,
5986 Array<OneD, NekDouble> &outarray)
5992 StdRegions::ConstFactorMap
factors;
5994 factors[StdRegions::eFactorConst] = scale;
5995 LibUtilities::Timer timer;
5998 if (m_collections.size() &&
5999 m_collectionsDoInit[Collections::ePhysInterp1DScaled])
6001 for (
int i = 0; i < m_collections.size(); ++i)
6003 m_collections[i].Initialise(Collections::ePhysInterp1DScaled);
6004 m_collectionsDoInit[Collections::ePhysInterp1DScaled] =
false;
6008 for (
int i = 0; i < m_collections.size(); ++i)
6011 m_collections[i].UpdateFactors(Collections::ePhysInterp1DScaled,
6017 Array<OneD, NekDouble> tmp;
6018 int input_offset{0};
6019 int output_offset{0};
6020 for (
int i = 0; i < m_collections.size(); ++i)
6022 m_collections[i].ApplyOperator(Collections::ePhysInterp1DScaled,
6023 inarray + input_offset,
6024 tmp = outarray + output_offset);
6026 m_collections[i].GetInputSize(Collections::ePhysInterp1DScaled);
6028 m_collections[i].GetOutputSize(Collections::ePhysInterp1DScaled);
6032 timer.AccumulateRegion(
"Collections:PhysInterp1DScaled", 10);
6034void ExpList::v_AddTraceIntegralToOffDiag(
6035 [[maybe_unused]]
const Array<OneD, const NekDouble> &FwdFlux,
6036 [[maybe_unused]]
const Array<OneD, const NekDouble> &BwdFlux,
6037 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
6039 NEKERROR(ErrorUtil::efatal,
"AddTraceIntegralToOffDiag not defined");
6042void ExpList::GetMatIpwrtDeriveBase(
6043 const Array<OneD,
const Array<OneD, NekDouble>> &inarray,
const int nDirctn,
6044 Array<OneD, DNekMatSharedPtr> &mtxPerVar)
6046 int nTotElmt = (*m_exp).size();
6047 int nElmtPnt = (*m_exp)[0]->GetTotPoints();
6048 int nElmtCoef = (*m_exp)[0]->GetNcoeffs();
6050 Array<OneD, NekDouble> tmpCoef(nElmtCoef, 0.0);
6051 Array<OneD, NekDouble> tmpPhys(nElmtPnt, 0.0);
6053 for (
int nelmt = 0; nelmt < nTotElmt; nelmt++)
6055 nElmtCoef = (*m_exp)[nelmt]->GetNcoeffs();
6056 nElmtPnt = (*m_exp)[nelmt]->GetTotPoints();
6058 if (tmpPhys.size() != nElmtPnt || tmpCoef.size() != nElmtCoef)
6060 tmpPhys = Array<OneD, NekDouble>(nElmtPnt, 0.0);
6061 tmpCoef = Array<OneD, NekDouble>(nElmtCoef, 0.0);
6064 for (
int ncl = 0; ncl < nElmtPnt; ncl++)
6066 tmpPhys[ncl] = inarray[nelmt][ncl];
6068 (*m_exp)[nelmt]->IProductWRTDerivBase(nDirctn, tmpPhys, tmpCoef);
6070 for (
int nrw = 0; nrw < nElmtCoef; nrw++)
6072 (*mtxPerVar[nelmt])(nrw, ncl) = tmpCoef[nrw];
6080void ExpList::GetMatIpwrtDeriveBase(
const TensorOfArray3D<NekDouble> &inarray,
6081 Array<OneD, DNekMatSharedPtr> &mtxPerVar)
6083 int nTotElmt = (*m_exp).size();
6085 int nspacedim = m_graph->GetSpaceDimension();
6086 Array<OneD, Array<OneD, NekDouble>> projectedpnts(nspacedim);
6087 Array<OneD, Array<OneD, NekDouble>> tmppnts(nspacedim);
6088 Array<OneD, DNekMatSharedPtr> ArrayStdMat(nspacedim);
6089 Array<OneD, Array<OneD, NekDouble>> ArrayStdMat_data(nspacedim);
6091 Array<OneD, NekDouble> clmnArray, clmnStdMatArray;
6093 LibUtilities::ShapeType ElmtTypePrevious = LibUtilities::eNoShapeType;
6094 int nElmtPntPrevious = 0;
6095 int nElmtCoefPrevious = 0;
6097 int nElmtPnt, nElmtCoef;
6098 for (
int nelmt = 0; nelmt < nTotElmt; nelmt++)
6100 nElmtCoef = (*m_exp)[nelmt]->GetNcoeffs();
6101 nElmtPnt = (*m_exp)[nelmt]->GetTotPoints();
6102 LibUtilities::ShapeType ElmtTypeNow = (*m_exp)[nelmt]->DetShapeType();
6104 if (nElmtPntPrevious != nElmtPnt || nElmtCoefPrevious != nElmtCoef ||
6105 (ElmtTypeNow != ElmtTypePrevious))
6107 if (nElmtPntPrevious != nElmtPnt)
6109 for (
int ndir = 0; ndir < nspacedim; ndir++)
6111 projectedpnts[ndir] = Array<OneD, NekDouble>(nElmtPnt, 0.0);
6112 tmppnts[ndir] = Array<OneD, NekDouble>(nElmtPnt, 0.0);
6115 StdRegions::StdExpansionSharedPtr stdExp;
6116 stdExp = (*m_exp)[nelmt]->GetStdExp();
6117 StdRegions::StdMatrixKey matkey(StdRegions::eDerivBase0,
6118 stdExp->DetShapeType(), *stdExp);
6120 ArrayStdMat[0] = stdExp->GetStdMatrix(matkey);
6121 ArrayStdMat_data[0] = ArrayStdMat[0]->GetPtr();
6125 StdRegions::StdMatrixKey matkey(
6126 StdRegions::eDerivBase1, stdExp->DetShapeType(), *stdExp);
6128 ArrayStdMat[1] = stdExp->GetStdMatrix(matkey);
6129 ArrayStdMat_data[1] = ArrayStdMat[1]->GetPtr();
6133 StdRegions::StdMatrixKey matkey(StdRegions::eDerivBase2,
6134 stdExp->DetShapeType(),
6137 ArrayStdMat[2] = stdExp->GetStdMatrix(matkey);
6138 ArrayStdMat_data[2] = ArrayStdMat[2]->GetPtr();
6142 ElmtTypePrevious = ElmtTypeNow;
6143 nElmtPntPrevious = nElmtPnt;
6144 nElmtCoefPrevious = nElmtCoef;
6148 for (
int ndir = 0; ndir < nspacedim; ndir++)
6154 for (
int ndir = 0; ndir < nspacedim; ndir++)
6156 (*m_exp)[nelmt]->AlignVectorToCollapsedDir(
6157 ndir, inarray[ndir][nelmt], tmppnts);
6158 for (
int n = 0; n < nspacedim; n++)
6160 Vmath::Vadd(nElmtPnt, tmppnts[n], 1, projectedpnts[n], 1,
6161 projectedpnts[n], 1);
6165 for (
int ndir = 0; ndir < nspacedim; ndir++)
6168 (*m_exp)[nelmt]->MultiplyByQuadratureMetric(projectedpnts[ndir],
6169 projectedpnts[ndir]);
6170 Array<OneD, NekDouble> MatDataArray = mtxPerVar[nelmt]->GetPtr();
6172 for (
int np = 0; np < nElmtPnt; np++)
6174 NekDouble factor = projectedpnts[ndir][np];
6175 clmnArray = MatDataArray + np * nElmtCoef;
6176 clmnStdMatArray = ArrayStdMat_data[ndir] + np * nElmtCoef;
6177 Vmath::Svtvp(nElmtCoef, factor, clmnStdMatArray, 1, clmnArray,
6185void ExpList::GetDiagMatIpwrtBase(
6186 const Array<OneD,
const Array<OneD, NekDouble>> &inarray,
6187 Array<OneD, DNekMatSharedPtr> &mtxPerVar)
6189 LibUtilities::ShapeType ElmtTypePrevious = LibUtilities::eNoShapeType;
6190 int nElmtPntPrevious = 0;
6191 int nElmtCoefPrevious = 0;
6192 int nTotElmt = (*m_exp).size();
6193 int nElmtPnt = (*m_exp)[0]->GetTotPoints();
6194 int nElmtCoef = (*m_exp)[0]->GetNcoeffs();
6196 Array<OneD, NekDouble> tmpPhys;
6197 Array<OneD, NekDouble> clmnArray, clmnStdMatArray;
6198 Array<OneD, NekDouble> stdMat_data;
6200 for (
int nelmt = 0; nelmt < nTotElmt; nelmt++)
6202 nElmtCoef = (*m_exp)[nelmt]->GetNcoeffs();
6203 nElmtPnt = (*m_exp)[nelmt]->GetTotPoints();
6204 LibUtilities::ShapeType ElmtTypeNow = (*m_exp)[nelmt]->DetShapeType();
6206 if (nElmtPntPrevious != nElmtPnt || nElmtCoefPrevious != nElmtCoef ||
6207 (ElmtTypeNow != ElmtTypePrevious))
6209 StdRegions::StdExpansionSharedPtr stdExp;
6210 stdExp = (*m_exp)[nelmt]->GetStdExp();
6211 StdRegions::StdMatrixKey matkey(StdRegions::eBwdMat,
6212 stdExp->DetShapeType(), *stdExp);
6215 stdMat_data = BwdMat->GetPtr();
6217 if (nElmtPntPrevious != nElmtPnt)
6219 tmpPhys = Array<OneD, NekDouble>(nElmtPnt, 0.0);
6222 ElmtTypePrevious = ElmtTypeNow;
6223 nElmtPntPrevious = nElmtPnt;
6224 nElmtCoefPrevious = nElmtCoef;
6227 (*m_exp)[nelmt]->MultiplyByQuadratureMetric(
6231 Array<OneD, NekDouble> MatDataArray = mtxPerVar[nelmt]->GetPtr();
6233 for (
int np = 0; np < nElmtPnt; np++)
6236 clmnArray = MatDataArray + np * nElmtCoef;
6237 clmnStdMatArray = stdMat_data + np * nElmtCoef;
6238 Vmath::Smul(nElmtCoef, factor, clmnStdMatArray, 1, clmnArray, 1);
6256void ExpList::AddTraceJacToElmtJac(
6257 const Array<OneD, const DNekMatSharedPtr> &FwdMat,
6258 const Array<OneD, const DNekMatSharedPtr> &BwdMat,
6259 Array<OneD, DNekMatSharedPtr> &fieldMat)
6261 MultiRegions::ExpListSharedPtr tracelist = GetTrace();
6262 std::shared_ptr<LocalRegions::ExpansionVector> traceExp =
6263 tracelist->GetExp();
6264 int ntotTrace = (*traceExp).size();
6265 int nTracePnt, nTraceCoef;
6267 std::shared_ptr<LocalRegions::ExpansionVector> fieldExp = GetExp();
6270 const MultiRegions::LocTraceToTraceMapSharedPtr locTraceToTraceMap =
6271 GetLocTraceToTraceMap();
6272 const Array<OneD, const Array<OneD, int>> LRAdjExpid =
6273 locTraceToTraceMap->GetLeftRightAdjacentExpId();
6274 const Array<OneD, const Array<OneD, bool>> LRAdjflag =
6275 locTraceToTraceMap->GetLeftRightAdjacentExpFlag();
6277 const Array<OneD, const Array<OneD, Array<OneD, int>>> elmtLRMap =
6278 locTraceToTraceMap->GetTraceCoeffToLeftRightExpCoeffMap();
6279 const Array<OneD, const Array<OneD, Array<OneD, int>>> elmtLRSign =
6280 locTraceToTraceMap->GetTraceCoeffToLeftRightExpCoeffSign();
6282 Array<OneD, NekDouble> ElmtMat_data;
6285 int MatIndex, nPnts;
6288 int nTracePntsTtl = tracelist->GetTotPoints();
6289 int nlocTracePts = locTraceToTraceMap->GetNLocTracePts();
6290 int nlocTracePtsFwd = locTraceToTraceMap->GetNFwdLocTracePts();
6291 int nlocTracePtsBwd = nlocTracePts - nlocTracePtsFwd;
6293 Array<OneD, int> nlocTracePtsLR(2);
6294 nlocTracePtsLR[0] = nlocTracePtsFwd;
6295 nlocTracePtsLR[1] = nlocTracePtsBwd;
6297 size_t nFwdBwdNonZero = 0;
6298 Array<OneD, int> tmpIndex{2, -1};
6299 for (
int i = 0; i < 2; ++i)
6301 if (nlocTracePtsLR[i] > 0)
6303 tmpIndex[nFwdBwdNonZero] = i;
6308 Array<OneD, int> nlocTracePtsNonZeroIndex{nFwdBwdNonZero};
6309 for (
int i = 0; i < nFwdBwdNonZero; ++i)
6311 nlocTracePtsNonZeroIndex[i] = tmpIndex[i];
6314 Array<OneD, NekDouble> TraceFwdPhy(nTracePntsTtl);
6315 Array<OneD, NekDouble> TraceBwdPhy(nTracePntsTtl);
6316 Array<OneD, Array<OneD, NekDouble>> tmplocTrace(2);
6317 for (
int k = 0; k < 2; ++k)
6319 tmplocTrace[k] = NullNekDouble1DArray;
6322 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6324 size_t i = nlocTracePtsNonZeroIndex[k];
6325 tmplocTrace[i] = Array<OneD, NekDouble>(nlocTracePtsLR[i]);
6328 int nNumbElmt = fieldMat.size();
6329 Array<OneD, Array<OneD, NekDouble>> ElmtMatDataArray(nNumbElmt);
6330 Array<OneD, int> ElmtCoefArray(nNumbElmt);
6331 for (
int i = 0; i < nNumbElmt; i++)
6333 ElmtMatDataArray[i] = fieldMat[i]->GetPtr();
6334 ElmtCoefArray[i] = GetNcoeffs(i);
6337 int nTraceCoefMax = 0;
6338 int nTraceCoefMin = std::numeric_limits<int>::max();
6339 Array<OneD, int> TraceCoefArray(ntotTrace);
6340 Array<OneD, int> TracePntArray(ntotTrace);
6341 Array<OneD, int> TraceOffArray(ntotTrace);
6342 Array<OneD, Array<OneD, NekDouble>> FwdMatData(ntotTrace);
6343 Array<OneD, Array<OneD, NekDouble>> BwdMatData(ntotTrace);
6344 for (
int nt = 0; nt < ntotTrace; nt++)
6346 nTraceCoef = (*traceExp)[nt]->GetNcoeffs();
6347 nTracePnt = tracelist->GetTotPoints(nt);
6348 int noffset = tracelist->GetPhys_Offset(nt);
6349 TraceCoefArray[nt] = nTraceCoef;
6350 TracePntArray[nt] = nTracePnt;
6351 TraceOffArray[nt] = noffset;
6352 FwdMatData[nt] = FwdMat[nt]->GetPtr();
6353 BwdMatData[nt] = BwdMat[nt]->GetPtr();
6354 if (nTraceCoef > nTraceCoefMax)
6356 nTraceCoefMax = nTraceCoef;
6358 if (nTraceCoef < nTraceCoefMin)
6360 nTraceCoefMin = nTraceCoef;
6363 WARNINGL1(nTraceCoefMax == nTraceCoefMin,
6364 "nTraceCoefMax!=nTraceCoefMin: Effeciency may be low ");
6366 int traceID, nfieldPnts, ElmtId, noffset;
6367 const Array<OneD, const Array<OneD, int>> LocTracephysToTraceIDMap =
6368 locTraceToTraceMap->GetLocTracephysToTraceIDMap();
6369 const Array<OneD, const int> fieldToLocTraceMap =
6370 locTraceToTraceMap->GetLocTraceToFieldMap();
6371 Array<OneD, Array<OneD, int>> fieldToLocTraceMapLR(2);
6373 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6375 size_t i = nlocTracePtsNonZeroIndex[k];
6376 fieldToLocTraceMapLR[i] = Array<OneD, int>(nlocTracePtsLR[i]);
6377 Vmath::Vcopy(nlocTracePtsLR[i], &fieldToLocTraceMap[0] + noffset, 1,
6378 &fieldToLocTraceMapLR[i][0], 1);
6379 noffset += nlocTracePtsLR[i];
6382 Array<OneD, Array<OneD, int>> MatIndexArray(2);
6383 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6385 size_t nlr = nlocTracePtsNonZeroIndex[k];
6386 MatIndexArray[nlr] = Array<OneD, int>(nlocTracePtsLR[nlr]);
6387 for (
int nloc = 0; nloc < nlocTracePtsLR[nlr]; nloc++)
6389 traceID = LocTracephysToTraceIDMap[nlr][nloc];
6390 nTraceCoef = TraceCoefArray[traceID];
6391 ElmtId = LRAdjExpid[nlr][traceID];
6392 noffset = GetPhys_Offset(ElmtId);
6393 nElmtCoef = ElmtCoefArray[ElmtId];
6394 nfieldPnts = fieldToLocTraceMapLR[nlr][nloc];
6395 nPnts = nfieldPnts - noffset;
6397 MatIndexArray[nlr][nloc] = nPnts * nElmtCoef;
6401 for (
int nc = 0; nc < nTraceCoefMin; nc++)
6403 for (
int nt = 0; nt < ntotTrace; nt++)
6405 nTraceCoef = TraceCoefArray[nt];
6406 nTracePnt = TracePntArray[nt];
6407 noffset = TraceOffArray[nt];
6408 Vmath::Vcopy(nTracePnt, &FwdMatData[nt][nc], nTraceCoef,
6409 &TraceFwdPhy[noffset], 1);
6410 Vmath::Vcopy(nTracePnt, &BwdMatData[nt][nc], nTraceCoef,
6411 &TraceBwdPhy[noffset], 1);
6414 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6416 size_t i = nlocTracePtsNonZeroIndex[k];
6417 Vmath::Zero(nlocTracePtsLR[i], tmplocTrace[i], 1);
6420 GetLocTraceFromTracePts(TraceFwdPhy, TraceBwdPhy, tmplocTrace[0],
6423 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6425 size_t nlr = nlocTracePtsNonZeroIndex[k];
6426 for (
int nloc = 0; nloc < nlocTracePtsLR[nlr]; nloc++)
6428 traceID = LocTracephysToTraceIDMap[nlr][nloc];
6429 nTraceCoef = TraceCoefArray[traceID];
6430 ElmtId = LRAdjExpid[nlr][traceID];
6431 nrwAdjExp = elmtLRMap[nlr][traceID][nc];
6432 sign = elmtLRSign[nlr][traceID][nc];
6433 MatIndex = MatIndexArray[nlr][nloc] + nrwAdjExp;
6435 ElmtMatDataArray[ElmtId][MatIndex] -=
6436 sign * tmplocTrace[nlr][nloc];
6441 for (
int nc = nTraceCoefMin; nc < nTraceCoefMax; nc++)
6443 for (
int nt = 0; nt < ntotTrace; nt++)
6445 nTraceCoef = TraceCoefArray[nt];
6446 nTracePnt = TracePntArray[nt];
6447 noffset = TraceOffArray[nt];
6448 if (nc < nTraceCoef)
6450 Vmath::Vcopy(nTracePnt, &FwdMatData[nt][nc], nTraceCoef,
6451 &TraceFwdPhy[noffset], 1);
6452 Vmath::Vcopy(nTracePnt, &BwdMatData[nt][nc], nTraceCoef,
6453 &TraceBwdPhy[noffset], 1);
6462 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6464 size_t i = nlocTracePtsNonZeroIndex[k];
6465 Vmath::Zero(nlocTracePtsLR[i], tmplocTrace[i], 1);
6467 GetLocTraceFromTracePts(TraceFwdPhy, TraceBwdPhy, tmplocTrace[0],
6470 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6472 size_t nlr = nlocTracePtsNonZeroIndex[k];
6473 for (
int nloc = 0; nloc < nlocTracePtsLR[nlr]; nloc++)
6475 traceID = LocTracephysToTraceIDMap[nlr][nloc];
6476 nTraceCoef = TraceCoefArray[traceID];
6477 if (nc < nTraceCoef)
6479 ElmtId = LRAdjExpid[nlr][traceID];
6480 nrwAdjExp = elmtLRMap[nlr][traceID][nc];
6481 sign = -elmtLRSign[nlr][traceID][nc];
6482 MatIndex = MatIndexArray[nlr][nloc] + nrwAdjExp;
6484 ElmtMatDataArray[ElmtId][MatIndex] +=
6485 sign * tmplocTrace[nlr][nloc];
6492void ExpList::AddRightIPTPhysDerivBase(
6493 const int dir,
const Array<OneD, const DNekMatSharedPtr> ElmtJacQuad,
6494 Array<OneD, DNekMatSharedPtr> ElmtJacCoef)
6497 int nelmtcoef, nelmtpnts, nelmtcoef0, nelmtpnts0;
6499 nelmtcoef = GetNcoeffs(0);
6500 nelmtpnts = GetTotPoints(0);
6502 Array<OneD, NekDouble> innarray(nelmtpnts, 0.0);
6503 Array<OneD, NekDouble> outarray(nelmtcoef, 0.0);
6505 Array<OneD, NekDouble> MatQ_data;
6506 Array<OneD, NekDouble> MatC_data;
6510 nelmtcoef0 = nelmtcoef;
6511 nelmtpnts0 = nelmtpnts;
6513 for (nelmt = 0; nelmt < (*m_exp).size(); ++nelmt)
6515 nelmtcoef = GetNcoeffs(nelmt);
6516 nelmtpnts = GetTotPoints(nelmt);
6518 tmpMatQ = ElmtJacQuad[nelmt];
6519 tmpMatC = ElmtJacCoef[nelmt];
6521 MatQ_data = tmpMatQ->GetPtr();
6522 MatC_data = tmpMatC->GetPtr();
6524 if (nelmtcoef != nelmtcoef0)
6526 outarray = Array<OneD, NekDouble>(nelmtcoef, 0.0);
6527 nelmtcoef0 = nelmtcoef;
6530 if (nelmtpnts != nelmtpnts0)
6532 innarray = Array<OneD, NekDouble>(nelmtpnts, 0.0);
6533 nelmtpnts0 = nelmtpnts;
6536 for (
int np = 0; np < nelmtcoef; np++)
6538 Vmath::Vcopy(nelmtpnts, &MatQ_data[0] + np, nelmtcoef, &innarray[0],
6540 (*m_exp)[nelmt]->DivideByQuadratureMetric(innarray, innarray);
6541 (*m_exp)[nelmt]->IProductWRTDerivBase(dir, innarray, outarray);
6543 Vmath::Vadd(nelmtcoef, &outarray[0], 1, &MatC_data[0] + np,
6544 nelmtcoef, &MatC_data[0] + np, nelmtcoef);
6549void ExpList::AddRightIPTBaseMatrix(
6550 const Array<OneD, const DNekMatSharedPtr> ElmtJacQuad,
6551 Array<OneD, DNekMatSharedPtr> ElmtJacCoef)
6554 int nelmtcoef, nelmtpnts, nelmtcoef0, nelmtpnts0;
6556 nelmtcoef = GetNcoeffs(0);
6557 nelmtpnts = GetTotPoints(0);
6559 Array<OneD, NekDouble> innarray(nelmtpnts, 0.0);
6560 Array<OneD, NekDouble> outarray(nelmtcoef, 0.0);
6562 Array<OneD, NekDouble> MatQ_data;
6563 Array<OneD, NekDouble> MatC_data;
6567 nelmtcoef0 = nelmtcoef;
6568 nelmtpnts0 = nelmtpnts;
6570 for (nelmt = 0; nelmt < (*m_exp).size(); ++nelmt)
6572 nelmtcoef = GetNcoeffs(nelmt);
6573 nelmtpnts = GetTotPoints(nelmt);
6575 tmpMatQ = ElmtJacQuad[nelmt];
6576 tmpMatC = ElmtJacCoef[nelmt];
6578 MatQ_data = tmpMatQ->GetPtr();
6579 MatC_data = tmpMatC->GetPtr();
6581 if (nelmtcoef != nelmtcoef0)
6583 outarray = Array<OneD, NekDouble>(nelmtcoef, 0.0);
6584 nelmtcoef0 = nelmtcoef;
6587 if (nelmtpnts != nelmtpnts0)
6589 innarray = Array<OneD, NekDouble>(nelmtpnts, 0.0);
6590 nelmtpnts0 = nelmtpnts;
6593 for (
int np = 0; np < nelmtcoef; np++)
6595 Vmath::Vcopy(nelmtpnts, &MatQ_data[0] + np, nelmtcoef, &innarray[0],
6597 (*m_exp)[nelmt]->DivideByQuadratureMetric(innarray, innarray);
6598 (*m_exp)[nelmt]->IProductWRTBase(innarray, outarray);
6600 Vmath::Vadd(nelmtcoef, &outarray[0], 1, &MatC_data[0] + np,
6601 nelmtcoef, &MatC_data[0] + np, nelmtcoef);
6606void ExpList::v_PhysGalerkinProjection1DScaled(
6607 const NekDouble scale,
const Array<OneD, NekDouble> &inarray,
6608 Array<OneD, NekDouble> &outarray)
6618 for (
int i = 0; i < GetExpSize(); ++i)
6621 int pt0 = (*m_exp)[i]->GetNumPoints(0);
6622 int pt1 = (*m_exp)[i]->GetNumPoints(1);
6623 int npt0 = (int)(pt0 * scale);
6624 int npt1 = (pt0 - pt1 == 1) ? (
int)(pt0 * scale - 1)
6625 : (int)(pt1 * scale);
6627 LibUtilities::PointsKey newPointsKey0(
6628 npt0, (*m_exp)[i]->GetPointsType(0));
6629 LibUtilities::PointsKey newPointsKey1(
6630 npt1, (*m_exp)[i]->GetPointsType(1));
6633 LibUtilities::PhysGalerkinProject2D(
6634 newPointsKey0, newPointsKey1, &inarray[cnt],
6635 (*m_exp)[i]->GetBasis(0)->GetPointsKey(),
6636 (*m_exp)[i]->GetBasis(1)->GetPointsKey(), &outarray[cnt1]);
6645 for (
int i = 0; i < GetExpSize(); ++i)
6648 int pt0 = (*m_exp)[i]->GetNumPoints(0);
6649 int pt1 = (*m_exp)[i]->GetNumPoints(1);
6650 int pt2 = (*m_exp)[i]->GetNumPoints(2);
6651 int npt0 = (int)(pt0 * scale);
6652 int npt1 = (pt0 - pt1 == 1) ? (
int)(pt0 * scale - 1)
6653 : (int)(pt1 * scale);
6654 int npt2 = (pt0 - pt2 == 1) ? (
int)(pt0 * scale - 1)
6655 : (int)(pt2 * scale);
6657 LibUtilities::PointsKey newPointsKey0(
6658 npt0, (*m_exp)[i]->GetPointsType(0));
6659 LibUtilities::PointsKey newPointsKey1(
6660 npt1, (*m_exp)[i]->GetPointsType(1));
6661 LibUtilities::PointsKey newPointsKey2(
6662 npt2, (*m_exp)[i]->GetPointsType(2));
6665 LibUtilities::PhysGalerkinProject3D(
6666 newPointsKey0, newPointsKey1, newPointsKey2, &inarray[cnt],
6667 (*m_exp)[i]->GetBasis(0)->GetPointsKey(),
6668 (*m_exp)[i]->GetBasis(1)->GetPointsKey(),
6669 (*m_exp)[i]->GetBasis(2)->GetPointsKey(), &outarray[cnt1]);
6671 cnt += npt0 * npt1 * npt2;
6672 cnt1 += pt0 * pt1 * pt2;
6678 NEKERROR(ErrorUtil::efatal,
"not setup for this expansion");
6686 NEKERROR(ErrorUtil::efatal,
"v_GetLocTraceToTraceMap not coded");
6687 return NullLocTraceToTraceMapSharedPtr;
#define WARNINGL1(condition, msg)
#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 LIKWID_MARKER_START(regionTag)
#define LIKWID_MARKER_STOP(regionTag)
#define sign(a, b)
return the sign(b)*a
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
ExpList(const ExpansionType Type=eNoType)
The default constructor using a type.
static void Dscal(const int &n, const double &alpha, double *x, const int &incx)
BLAS level 1: x = alpha x.
std::vector< ExpansionSharedPtr > ExpansionVector
MultiRegions::Direction const DirCartesianMap[]
std::shared_ptr< RobinBCInfo > RobinBCInfoSharedPtr
std::shared_ptr< GlobalLinSys > GlobalLinSysSharedPtr
Pointer to a GlobalLinSys object.
std::shared_ptr< GlobalMatrix > GlobalMatrixSharedPtr
Shared pointer to a GlobalMatrix object.
GlobalLinSysFactory & GetGlobalLinSysFactory()
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::shared_ptr< LocTraceToTraceMap > LocTraceToTraceMapSharedPtr
std::map< GlobalMatrixKey, DNekScalBlkMatSharedPtr > BlockMatrixMap
A map between global matrix keys and their associated block matrices.
@ eLinearAdvectionDiffusionReaction
std::vector< double > p(NPUPPER)
std::vector< double > z(NPUPPER)
std::vector< double > d(NPUPPER *NPUPPER)
StdRegions::ConstFactorMap factors
NekMatrix< NekMatrix< NekMatrix< NekDouble, StandardMatrixTag >, ScaledMatrixTag >, BlockMatrixTag > DNekScalBlkMat
NekMatrix< NekMatrix< NekDouble, StandardMatrixTag >, ScaledMatrixTag > DNekScalMat
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
std::pair< IndexType, IndexType > CoordType
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
@ ePOSITIVE_DEFINITE_SYMMETRIC_BANDED
@ ePOSITIVE_DEFINITE_SYMMETRIC
std::map< CoordType, NekDouble > COOMatType
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 Neg(int n, T *x, const int incx)
Negate x = -x.
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
void Scatr(int n, const T *x, const int *y, T *z)
Scatter vector z[y[i]] = x[i].
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 Zero(int n, T *x, const int incx)
Zero vector.
T Vmax(int n, const T *x, const int incx)
Return the maximum element in x – called vmax to avoid conflict with max.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
scalarT< T > abs(scalarT< T > in)
scalarT< T > max(scalarT< T > lhs, scalarT< T > rhs)
scalarT< T > min(scalarT< T > lhs, scalarT< T > rhs)
scalarT< T > sqrt(scalarT< T > in)