95 : m_expType(type), m_ncoeffs(0), m_npoints(0), m_physState(false),
96 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
110ExpList::ExpList(
const ExpList &in,
const bool DeclareCoeffPhysArrays)
111 :
std::enable_shared_from_this<ExpList>(in), m_expType(in.m_expType),
113 m_comm(in.m_comm), m_session(in.m_session), m_graph(in.m_graph),
114 m_ncoeffs(in.m_ncoeffs), m_npoints(in.m_npoints), m_physState(false),
115 m_exp(in.m_exp), m_collections(in.m_collections),
116 m_collectionsDoInit(in.m_collectionsDoInit),
117 m_coeff_offset(in.m_coeff_offset), m_phys_offset(in.m_phys_offset),
118 m_blockMat(in.m_blockMat), m_WaveSpace(false),
119 m_elmtToExpId(in.m_elmtToExpId)
123 SetupCoeffPhys(DeclareCoeffPhysArrays,
false);
131ExpList::ExpList(
const ExpList &in,
const std::vector<unsigned int> &eIDs,
132 const bool DeclareCoeffPhysArrays,
133 const Collections::ImplementationType ImpType)
134 : m_expType(in.m_expType), m_comm(in.m_comm), m_session(in.m_session),
135 m_graph(in.m_graph), m_physState(false),
136 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
140 for (
int i = 0; i < eIDs.size(); ++i)
142 (*m_exp).push_back((*(in.m_exp))[eIDs[i]]);
146 SetupCoeffPhys(DeclareCoeffPhysArrays);
149 CreateCollections(ImpType);
171ExpList::ExpList(
const LibUtilities::SessionReaderSharedPtr &pSession,
172 const SpatialDomains::MeshGraphSharedPtr &graph,
173 const bool DeclareCoeffPhysArrays,
const std::string &var,
174 const Collections::ImplementationType ImpType)
175 : m_comm(pSession->GetComm()), m_session(pSession), m_graph(graph),
177 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
182 const SpatialDomains::ExpansionInfoMap &expansions =
183 graph->GetExpansionInfo(var);
186 InitialiseExpVector(expansions);
189 SetupCoeffPhys(DeclareCoeffPhysArrays);
192 CreateCollections(ImpType);
213ExpList::ExpList(
const LibUtilities::SessionReaderSharedPtr &pSession,
214 const SpatialDomains::ExpansionInfoMap &expansions,
215 const bool DeclareCoeffPhysArrays,
216 const Collections::ImplementationType ImpType)
217 : m_comm(pSession->GetComm()), m_session(pSession), m_physState(false),
218 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
223 InitialiseExpVector(expansions);
226 SetupCoeffPhys(DeclareCoeffPhysArrays);
229 CreateCollections(ImpType);
235ExpList::ExpList(SpatialDomains::PointGeom *geom)
236 : m_expType(
e0D), m_ncoeffs(1), m_npoints(1), m_physState(false),
237 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
241 LocalRegions::PointExpSharedPtr
Point =
242 MemoryManager<LocalRegions::PointExp>::AllocateSharedPtr(geom);
243 (*m_exp).push_back(Point);
272 const LibUtilities::SessionReaderSharedPtr &pSession,
273 const Array<OneD, const ExpListSharedPtr> &bndConstraint,
274 const Array<OneD, const SpatialDomains::BoundaryConditionShPtr> &bndCond,
275 const LocalRegions::ExpansionVector &locexp,
276 const SpatialDomains::MeshGraphSharedPtr &graph,
277 const LibUtilities::CommSharedPtr &comm,
const bool DeclareCoeffPhysArrays,
278 [[maybe_unused]]
const std::string variable,
279 [[maybe_unused]]
const Collections::ImplementationType ImpType)
280 : m_comm(comm), m_session(pSession), m_graph(graph), m_physState(false),
281 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
285 int i, j, id, elmtid = 0;
288 SpatialDomains::PointGeom *PointGeom;
289 SpatialDomains::Geometry1D *segGeom;
290 SpatialDomains::Geometry2D *FaceGeom;
291 SpatialDomains::QuadGeom *QuadGeom;
292 SpatialDomains::TriGeom *TriGeom;
294 LocalRegions::ExpansionSharedPtr exp;
295 LocalRegions::Expansion0DSharedPtr exp0D;
296 LocalRegions::Expansion1DSharedPtr exp1D;
297 LocalRegions::Expansion2DSharedPtr exp2D;
298 LocalRegions::Expansion3DSharedPtr exp3D;
300 map<int, vector<SpatialDomains::ExpansionInfoShPtr>> ExpOrder;
301 LibUtilities::BasisKeyVector PtBvec;
303 bool DoOptOnCollection =
304 m_session->DefinesCmdLineArgument(
"no-exp-opt") ? false :
true;
306 for (i = 0; i < bndCond.size(); ++i)
308 if (bndCond[i]->GetBoundaryConditionType() ==
309 SpatialDomains::eDirichlet)
312 for (j = 0; j < bndConstraint[i]->GetExpSize(); ++j)
314 SpatialDomains::ExpansionInfoShPtr eInfo =
315 MemoryManager<SpatialDomains::ExpansionInfo>::
317 bndConstraint[i]->GetExp(j)->GetGeom(), PtBvec);
320 std::dynamic_pointer_cast<LocalRegions::Expansion1D>(
321 bndConstraint[i]->GetExp(j))))
323 LibUtilities::BasisKey bkey =
324 exp1D->GetBasis(0)->GetBasisKey();
325 eInfo->m_basisKeyVector.push_back(bkey);
327 else if ((exp2D = std::dynamic_pointer_cast<
328 LocalRegions::Expansion2D>(
329 bndConstraint[i]->GetExp(j))))
331 LibUtilities::BasisKey bkey0 =
332 exp2D->GetBasis(0)->GetBasisKey();
333 LibUtilities::BasisKey bkey1 =
334 exp2D->GetBasis(1)->GetBasisKey();
336 eInfo->m_basisKeyVector.push_back(bkey0);
337 eInfo->m_basisKeyVector.push_back(bkey1);
344 if (DoOptOnCollection && IsNot0D)
347 for (i = 0; i < cnt; ++i)
349 if ((eInfo->m_basisKeyVector ==
350 ExpOrder[i][0]->m_basisKeyVector) &&
351 (eInfo->m_geomPtr->CalcGeomType() ==
352 ExpOrder[i][0]->m_geomPtr->CalcGeomType()))
354 ExpOrder[i].push_back(eInfo);
361 ExpOrder[cnt++].push_back(eInfo);
366 ExpOrder[0].push_back(eInfo);
373 for (
auto &ordIt : ExpOrder)
375 for (
auto &eit : ordIt.second)
379 dynamic_cast<SpatialDomains::PointGeom *
>(eit->m_geomPtr)))
383 exp = MemoryManager<LocalRegions::PointExp>::AllocateSharedPtr(
385 tracesDone.insert(PointGeom->GetGlobalID());
387 else if ((segGeom =
dynamic_cast<SpatialDomains::SegGeom *
>(
392 exp = MemoryManager<LocalRegions::SegExp>::AllocateSharedPtr(
393 eit->m_basisKeyVector[0], segGeom);
394 tracesDone.insert(segGeom->GetGlobalID());
396 else if ((TriGeom =
dynamic_cast<SpatialDomains::TriGeom *
>(
401 exp = MemoryManager<LocalRegions::TriExp>::AllocateSharedPtr(
402 eit->m_basisKeyVector[0], eit->m_basisKeyVector[1],
405 tracesDone.insert(TriGeom->GetGlobalID());
407 else if ((QuadGeom =
dynamic_cast<SpatialDomains::QuadGeom *
>(
411 exp = MemoryManager<LocalRegions::QuadExp>::AllocateSharedPtr(
412 eit->m_basisKeyVector[0], eit->m_basisKeyVector[1],
415 tracesDone.insert(QuadGeom->GetGlobalID());
419 exp->SetElmtId(elmtid++);
422 (*m_exp).push_back(exp);
426 map<int, pair<SpatialDomains::Geometry1D *, LibUtilities::BasisKey>>
429 map<int, pair<SpatialDomains::Geometry2D *,
430 pair<LibUtilities::BasisKey, LibUtilities::BasisKey>>>
433 for (i = 0; i < locexp.size(); ++i)
435 if ((exp1D = std::dynamic_pointer_cast<LocalRegions::Expansion1D>(
440 for (j = 0; j < 2; ++j)
442 PointGeom = (exp1D->GetGeom1D())->GetVertex(j);
443 id = PointGeom->GetGlobalID();
446 if (tracesDone.count(
id) != 0)
451 exp = MemoryManager<LocalRegions::PointExp>::AllocateSharedPtr(
453 tracesDone.insert(
id);
454 exp->SetElmtId(elmtid++);
455 (*m_exp).push_back(exp);
458 else if ((exp2D = std::dynamic_pointer_cast<LocalRegions::Expansion2D>(
462 for (j = 0; j < locexp[i]->GetNtraces(); ++j)
464 segGeom = exp2D->GetGeom2D()->GetEdge(j);
465 id = segGeom->GetGlobalID();
467 if (tracesDone.count(
id) != 0)
472 auto it = edgeOrders.find(
id);
474 if (it == edgeOrders.end())
476 edgeOrders.insert(std::make_pair(
477 id, std::make_pair(segGeom,
478 locexp[i]->GetTraceBasisKey(j))));
482 LibUtilities::BasisKey edge =
483 locexp[i]->GetTraceBasisKey(j);
484 LibUtilities::BasisKey existing = it->second.second;
486 int np1 = LibUtilities::PointsKey::GetDegreeOfExactness(
487 edge.GetPointsType(), edge.GetNumPoints());
488 int np2 = LibUtilities::PointsKey::GetDegreeOfExactness(
489 existing.GetPointsType(), existing.GetNumPoints());
490 int nm1 = edge.GetNumModes();
491 int nm2 = existing.GetNumModes();
499 if (np2 >= np1 && nm2 >= nm1)
503 else if (np2 <= np1 && nm2 <= nm1)
505 it->second.second = edge;
510 "inappropriate number of points/modes (max"
511 "num of points is not set with max order)");
516 else if ((exp3D = dynamic_pointer_cast<LocalRegions::Expansion3D>(
520 for (j = 0; j < exp3D->GetNtraces(); ++j)
522 FaceGeom = exp3D->GetGeom3D()->GetFace(j);
523 id = FaceGeom->GetGlobalID();
525 if (tracesDone.count(
id) != 0)
529 auto it = faceOrders.find(
id);
531 if (it == faceOrders.end())
535 LibUtilities::BasisKey face_dir0 =
536 locexp[i]->GetTraceBasisKey(j, 0);
537 LibUtilities::BasisKey face_dir1 =
538 locexp[i]->GetTraceBasisKey(j, 1);
543 if (locexp[i]->GetTraceOrient(j) >= 9)
545 std::swap(face_dir0, face_dir1);
548 faceOrders.insert(std::make_pair(
550 std::make_pair(FaceGeom,
551 std::make_pair(face_dir0, face_dir1))));
555 LibUtilities::BasisKey face0 =
556 locexp[i]->GetTraceBasisKey(j, 0);
557 LibUtilities::BasisKey face1 =
558 locexp[i]->GetTraceBasisKey(j, 1);
559 LibUtilities::BasisKey existing0 = it->second.second.first;
560 LibUtilities::BasisKey existing1 = it->second.second.second;
571 int np00 = LibUtilities::PointsKey::GetDegreeOfExactness(
572 face0.GetPointsType(), face0.GetNumPoints());
573 int np01 = LibUtilities::PointsKey::GetDegreeOfExactness(
574 face1.GetPointsType(), face1.GetNumPoints());
575 int np10 = LibUtilities::PointsKey::GetDegreeOfExactness(
576 existing0.GetPointsType(), existing0.GetNumPoints());
577 int np11 = LibUtilities::PointsKey::GetDegreeOfExactness(
578 existing1.GetPointsType(), existing1.GetNumPoints());
579 int nm00 = face0.GetNumModes();
580 int nm01 = face1.GetNumModes();
581 int nm10 = existing0.GetNumModes();
582 int nm11 = existing1.GetNumModes();
591 if (locexp[i]->GetTraceOrient(j) >= 9)
593 std::swap(np00, np01);
594 std::swap(nm00, nm01);
595 std::swap(face0, face1);
601 if (np11 >= np01 && nm11 >= nm01)
605 else if (np11 <= np01 && nm11 <= nm01)
609 LibUtilities::BasisKey newbkey(existing1.GetBasisType(),
611 face1.GetPointsKey());
612 it->second.second.second = newbkey;
617 "inappropriate number of points/modes (max"
618 "num of points is not set with max order)");
621 if (np10 >= np00 && nm10 >= nm00)
625 else if (np10 <= np00 && nm10 <= nm00)
629 LibUtilities::BasisKey newbkey(existing0.GetBasisType(),
631 face0.GetPointsKey());
632 it->second.second.first = newbkey;
637 "inappropriate number of points/modes (max"
638 "num of points is not set with max order)");
645 int nproc = m_comm->GetRowComm()->GetSize();
646 int tracepr = m_comm->GetRowComm()->GetRank();
653 for (i = 0; i < locexp.size(); ++i)
655 tCnt += locexp[i]->GetNtraces();
660 Array<OneD, int> tracesCnt(nproc, 0);
661 tracesCnt[tracepr] = tCnt;
662 m_comm->GetRowComm()->AllReduce(tracesCnt, LibUtilities::ReduceSum);
665 int totTraceCnt =
Vmath::Vsum(nproc, tracesCnt, 1);
666 Array<OneD, int> tTotOffsets(nproc, 0);
668 for (i = 1; i < nproc; ++i)
670 tTotOffsets[i] = tTotOffsets[i - 1] + tracesCnt[i - 1];
675 Array<OneD, int> TracesTotID(totTraceCnt, 0);
676 Array<OneD, int> TracesTotNm0(totTraceCnt, 0);
677 Array<OneD, int> TracesTotNm1(totTraceCnt, 0);
678 Array<OneD, int> TracesTotPnts0(totTraceCnt, 0);
679 Array<OneD, int> TracesTotPnts1(totTraceCnt, 0);
680 Array<OneD, int> TracesPointsType0(totTraceCnt, 0);
681 Array<OneD, int> TracesPointsType1(totTraceCnt, 0);
692 int cntr = tTotOffsets[tracepr];
694 for (i = 0; i < locexp.size(); ++i)
696 if ((exp2D = locexp[i]->as<LocalRegions::Expansion2D>()))
698 int nedges = locexp[i]->GetNtraces();
700 for (j = 0; j < nedges; ++j, ++cntr)
702 LibUtilities::BasisKey bkeyEdge =
703 locexp[i]->GetTraceBasisKey(j);
704 TracesTotID[cntr] = exp2D->GetGeom2D()->GetEid(j);
705 TracesTotNm0[cntr] = bkeyEdge.GetNumModes();
706 TracesTotPnts0[cntr] = bkeyEdge.GetNumPoints();
707 TracesPointsType0[cntr] =
708 static_cast<int>(bkeyEdge.GetPointsType());
713 else if ((exp3D = locexp[i]->as<LocalRegions::Expansion3D>()))
715 int nfaces = locexp[i]->GetNtraces();
717 for (j = 0; j < nfaces; ++j, ++cntr)
719 LibUtilities::BasisKey face_dir0 =
720 locexp[i]->GetTraceBasisKey(j, 0);
721 LibUtilities::BasisKey face_dir1 =
722 locexp[i]->GetTraceBasisKey(j, 1);
727 if (locexp[i]->GetTraceOrient(j) >= 9)
729 std::swap(face_dir0, face_dir1);
732 TracesTotID[cntr] = exp3D->GetGeom3D()->GetFid(j);
733 TracesTotNm0[cntr] = face_dir0.GetNumModes();
734 TracesTotNm1[cntr] = face_dir1.GetNumModes();
735 TracesTotPnts0[cntr] = face_dir0.GetNumPoints();
736 TracesTotPnts1[cntr] = face_dir1.GetNumPoints();
737 TracesPointsType0[cntr] =
738 static_cast<int>(face_dir0.GetPointsType());
739 TracesPointsType1[cntr] =
740 static_cast<int>(face_dir1.GetPointsType());
745 m_comm->GetRowComm()->AllReduce(TracesTotID, LibUtilities::ReduceSum);
746 m_comm->GetRowComm()->AllReduce(TracesTotNm0, LibUtilities::ReduceSum);
747 m_comm->GetRowComm()->AllReduce(TracesTotPnts0,
748 LibUtilities::ReduceSum);
749 m_comm->GetRowComm()->AllReduce(TracesPointsType0,
750 LibUtilities::ReduceSum);
751 if (m_expType == e2D)
753 m_comm->GetRowComm()->AllReduce(TracesTotNm1,
754 LibUtilities::ReduceSum);
755 m_comm->GetRowComm()->AllReduce(TracesTotPnts1,
756 LibUtilities::ReduceSum);
757 m_comm->GetRowComm()->AllReduce(TracesPointsType1,
758 LibUtilities::ReduceSum);
765 if (edgeOrders.size())
767 for (i = 0; i < totTraceCnt; ++i)
769 auto it = edgeOrders.find(TracesTotID[i]);
771 if (it == edgeOrders.end())
776 LibUtilities::BasisKey existing = it->second.second;
779 static_cast<LibUtilities::PointsType
>(TracesPointsType0[i]);
781 int np1 = LibUtilities::PointsKey::GetDegreeOfExactness(
782 ptype, TracesTotPnts0[i]);
783 int np2 = LibUtilities::PointsKey::GetDegreeOfExactness(
784 existing.GetPointsType(), existing.GetNumPoints());
785 int nm1 = TracesTotNm0[i];
786 int nm2 = existing.GetNumModes();
790 if (np2 >= np1 && nm2 >= nm1)
794 else if (np2 <= np1 && nm2 <= nm1)
798 LibUtilities::BasisKey newbkey(
799 existing.GetBasisType(), nm1,
800 LibUtilities::PointsKey(TracesTotPnts0[i], ptype));
801 it->second.second = newbkey;
806 "inappropriate number of points/modes (max "
807 "num of points is not set with max order)");
811 else if (faceOrders.size())
813 for (i = 0; i < totTraceCnt; ++i)
815 auto it = faceOrders.find(TracesTotID[i]);
817 if (it == faceOrders.end())
822 LibUtilities::BasisKey existing0 = it->second.second.first;
823 LibUtilities::BasisKey existing1 = it->second.second.second;
828 static_cast<LibUtilities::PointsType
>(TracesPointsType0[i]);
830 static_cast<LibUtilities::PointsType
>(TracesPointsType1[i]);
832 int np00 = LibUtilities::PointsKey::GetDegreeOfExactness(
833 ptype0, TracesTotPnts0[i]);
834 int np01 = LibUtilities::PointsKey::GetDegreeOfExactness(
835 ptype1, TracesTotPnts1[i]);
836 int np10 = LibUtilities::PointsKey::GetDegreeOfExactness(
837 existing0.GetPointsType(), existing0.GetNumPoints());
838 int np11 = LibUtilities::PointsKey::GetDegreeOfExactness(
839 existing1.GetPointsType(), existing1.GetNumPoints());
840 int nm00 = TracesTotNm0[i];
841 int nm01 = TracesTotNm1[i];
842 int nm10 = existing0.GetNumModes();
843 int nm11 = existing1.GetNumModes();
848 if (np11 >= np01 && nm11 >= nm01)
852 else if (np11 <= np01 && nm11 <= nm01)
854 LibUtilities::BasisKey newbkey(
855 existing1.GetBasisType(), nm01,
856 LibUtilities::PointsKey(TracesTotPnts1[i], ptype1));
857 it->second.second.second = newbkey;
862 "inappropriate number of points/modes (max"
863 "num of points is not set with max order)");
866 if (np10 >= np00 && nm10 >= nm00)
870 else if (np10 <= np00 && nm10 <= nm00)
872 LibUtilities::BasisKey newbkey(
873 existing0.GetBasisType(), nm00,
874 LibUtilities::PointsKey(TracesTotPnts0[i], ptype0));
875 it->second.second.first = newbkey;
880 "inappropriate number of points/modes (max"
881 "num of points is not set with max order)");
887 if (edgeOrders.size())
889 map<int, vector<int>> opt;
892 if (DoOptOnCollection)
894 for (
auto &it : edgeOrders)
897 for (i = 0; i < cnt; ++i)
899 auto it1 = edgeOrders.find(opt[i][0]);
901 if ((it.second.second == it1->second.second) &&
902 (it.second.first->CalcGeomType() ==
903 it1->second.first->CalcGeomType()))
905 opt[i].push_back(it.first);
912 opt[cnt++].push_back(it.first);
918 for (
auto &it : edgeOrders)
920 opt[0].push_back(it.first);
924 for (
int i = 0; i < opt.size(); ++i)
927 for (
int j = 0; j < opt[i].size(); ++j)
929 auto it = edgeOrders.find(opt[i][j]);
931 exp = MemoryManager<LocalRegions::SegExp>::AllocateSharedPtr(
932 it->second.second, it->second.first);
934 exp->SetElmtId(elmtid++);
935 (*m_exp).push_back(exp);
941 map<int, vector<int>> opt;
944 if (DoOptOnCollection)
946 for (
auto &it : faceOrders)
949 for (i = 0; i < cnt; ++i)
951 auto it1 = faceOrders.find(opt[i][0]);
953 if ((it.second.second.first == it1->second.second.first) &&
954 (it.second.second.second ==
955 it1->second.second.second) &&
956 (it.second.first->CalcGeomType() ==
957 it1->second.first->CalcGeomType()))
959 opt[i].push_back(it.first);
966 opt[cnt++].push_back(it.first);
972 for (
auto &it : faceOrders)
974 opt[0].push_back(it.first);
978 for (
int i = 0; i < opt.size(); ++i)
981 for (
int j = 0; j < opt[i].size(); ++j)
983 auto it = faceOrders.find(opt[i][j]);
985 FaceGeom = it->second.first;
988 dynamic_cast<SpatialDomains::QuadGeom *
>(FaceGeom)))
991 MemoryManager<LocalRegions::QuadExp>::AllocateSharedPtr(
992 it->second.second.first, it->second.second.second,
995 else if ((TriGeom =
dynamic_cast<SpatialDomains::TriGeom *
>(
999 MemoryManager<LocalRegions::TriExp>::AllocateSharedPtr(
1000 it->second.second.first, it->second.second.second,
1003 exp->SetElmtId(elmtid++);
1004 (*m_exp).push_back(exp);
1010 SetupCoeffPhys(DeclareCoeffPhysArrays);
1013 if (m_expType != e0D)
1015 CreateCollections(ImpType);
1022 for (
int i = (*m_exp).size() - 1; i >= 0; --i)
1024 m_elmtToExpId[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
1041ExpList::ExpList(
const LibUtilities::SessionReaderSharedPtr &pSession,
1042 const LocalRegions::ExpansionVector &locexp,
1043 const SpatialDomains::MeshGraphSharedPtr &graph,
1044 const bool DeclareCoeffPhysArrays,
1045 [[maybe_unused]]
const std::string variable,
1046 [[maybe_unused]]
const Collections::ImplementationType ImpType)
1047 : m_comm(pSession->GetComm()), m_session(pSession), m_graph(graph),
1049 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
1053 int i, j, elmtid = 0;
1055 SpatialDomains::PointGeom *PointGeom;
1056 SpatialDomains::Geometry1D *segGeom;
1057 SpatialDomains::Geometry2D *FaceGeom;
1058 SpatialDomains::QuadGeom *QuadGeom;
1059 SpatialDomains::TriGeom *TriGeom;
1061 LocalRegions::ExpansionSharedPtr exp;
1062 LocalRegions::Expansion0DSharedPtr exp0D;
1063 LocalRegions::Expansion1DSharedPtr exp1D;
1064 LocalRegions::Expansion2DSharedPtr exp2D;
1065 LocalRegions::Expansion3DSharedPtr exp3D;
1067 for (i = 0; i < locexp.size(); ++i)
1069 if ((exp1D = std::dynamic_pointer_cast<LocalRegions::Expansion1D>(
1074 for (j = 0; j < 2; ++j)
1076 PointGeom = (exp1D->GetGeom1D())->GetVertex(j);
1078 exp = MemoryManager<LocalRegions::PointExp>::AllocateSharedPtr(
1080 exp->SetElmtId(elmtid++);
1081 (*m_exp).push_back(exp);
1084 else if ((exp2D = std::dynamic_pointer_cast<LocalRegions::Expansion2D>(
1088 LibUtilities::BasisKey edgeKey0 =
1089 locexp[i]->GetBasis(0)->GetBasisKey();
1091 for (j = 0; j < locexp[i]->GetNtraces(); ++j)
1093 segGeom = exp2D->GetGeom2D()->GetEdge(j);
1095 int dir = exp2D->GetGeom2D()->GetDir(j);
1097 if (locexp[i]->GetNtraces() == 3)
1099 LibUtilities::BasisKey edgeKey =
1100 locexp[i]->GetBasis(dir)->GetBasisKey();
1102 LibUtilities::BasisKey nEdgeKey(edgeKey0.GetBasisType(),
1103 edgeKey.GetNumModes(),
1104 edgeKey.GetPointsKey());
1107 MemoryManager<LocalRegions::SegExp>::AllocateSharedPtr(
1113 MemoryManager<LocalRegions::SegExp>::AllocateSharedPtr(
1114 locexp[i]->GetBasis(dir)->GetBasisKey(), segGeom);
1117 exp->SetElmtId(elmtid++);
1118 (*m_exp).push_back(exp);
1121 else if ((exp3D = dynamic_pointer_cast<LocalRegions::Expansion3D>(
1126 LibUtilities::BasisKey face0_dir0 =
1127 locexp[i]->GetBasis(0)->GetBasisKey();
1128 LibUtilities::BasisKey face0_dir1 =
1129 locexp[i]->GetBasis(1)->GetBasisKey();
1131 for (j = 0; j < exp3D->GetNtraces(); ++j)
1133 FaceGeom = exp3D->GetGeom3D()->GetFace(j);
1135 int dir0 = exp3D->GetGeom3D()->GetDir(j, 0);
1136 int dir1 = exp3D->GetGeom3D()->GetDir(j, 1);
1138 LibUtilities::BasisKey face_dir0 =
1139 locexp[i]->GetBasis(dir0)->GetBasisKey();
1140 LibUtilities::BasisKey face_dir1 =
1141 locexp[i]->GetBasis(dir1)->GetBasisKey();
1144 dynamic_cast<SpatialDomains::QuadGeom *
>(FaceGeom)))
1147 MemoryManager<LocalRegions::QuadExp>::AllocateSharedPtr(
1148 face_dir0, face_dir1, QuadGeom);
1150 else if ((TriGeom =
dynamic_cast<SpatialDomains::TriGeom *
>(
1153 LibUtilities::BasisKey nface_dir0(face0_dir0.GetBasisType(),
1154 face_dir0.GetNumModes(),
1155 face_dir0.GetPointsKey());
1156 LibUtilities::BasisKey nface_dir1(face0_dir1.GetBasisType(),
1157 face_dir1.GetNumModes(),
1158 face_dir1.GetPointsKey());
1160 MemoryManager<LocalRegions::TriExp>::AllocateSharedPtr(
1161 nface_dir0, nface_dir1, TriGeom);
1163 exp->SetElmtId(elmtid++);
1164 (*m_exp).push_back(exp);
1170 SetupCoeffPhys(DeclareCoeffPhysArrays);
1173 if (m_expType != e0D)
1175 CreateCollections(ImpType);
1204ExpList::ExpList(
const LibUtilities::SessionReaderSharedPtr &pSession,
1205 const SpatialDomains::CompositeMap &domain,
1206 const SpatialDomains::MeshGraphSharedPtr &graph,
1207 const bool DeclareCoeffPhysArrays,
const std::string variable,
1208 bool SetToOneSpaceDimension,
1209 const LibUtilities::CommSharedPtr comm,
1210 const Collections::ImplementationType ImpType)
1211 : m_comm(comm), m_session(pSession), m_graph(graph), m_physState(false),
1212 m_exp(MemoryManager<LocalRegions::
ExpansionVector>::AllocateSharedPtr()),
1217 SpatialDomains::PointGeom *PtGeom;
1218 SpatialDomains::SegGeom *SegGeom;
1219 SpatialDomains::TriGeom *TriGeom;
1220 SpatialDomains::QuadGeom *QuadGeom;
1222 LocalRegions::ExpansionSharedPtr exp;
1224 LibUtilities::PointsType TriNb;
1226 int meshdim = graph->GetMeshDimension();
1229 const SpatialDomains::ExpansionInfoMap &expansions =
1230 graph->GetExpansionInfo(variable);
1231 map<int, vector<SpatialDomains::ExpansionInfoShPtr>> ExpOrder;
1232 LibUtilities::BasisKeyVector PtBvec;
1234 bool UseGLLOnTri =
false;
1236 pSession->MatchSolverInfo(
"Projection",
"Continuous", UseGLLOnTri,
false);
1238 bool DoOptOnCollection =
1239 m_session->DefinesCmdLineArgument(
"no-exp-opt") ? false :
true;
1241 for (
auto &compIt : domain)
1243 bool IsNot0D =
true;
1245 for (j = 0; j < compIt.second->m_geomVec.size(); ++j)
1247 LibUtilities::BasisKeyVector def;
1248 SpatialDomains::ExpansionInfoShPtr eInfo =
1249 MemoryManager<SpatialDomains::ExpansionInfo>::AllocateSharedPtr(
1250 compIt.second->m_geomVec[j], PtBvec);
1252 if ((SegGeom =
dynamic_cast<SpatialDomains::SegGeom *
>(
1253 compIt.second->m_geomVec[j])))
1257 auto expInfo = expansions.find(SegGeom->GetGlobalID());
1258 eInfo = expInfo->second;
1263 SpatialDomains::GeometryLinkSharedPtr elmts =
1264 graph->GetElementsFromEdge(SegGeom);
1269 SpatialDomains::Geometry *geom = elmts->at(0).first;
1270 int edge_id = elmts->at(0).second;
1271 SpatialDomains::ExpansionInfoShPtr expInfo =
1272 graph->GetExpansionInfo(geom, variable);
1273 LibUtilities::BasisKey Ba = expInfo->m_basisKeyVector[0];
1274 LibUtilities::BasisKey Bb = expInfo->m_basisKeyVector[1];
1275 StdRegions::StdExpansionSharedPtr elmtStdExp;
1277 if (geom->GetShapeType() == LibUtilities::eTriangle)
1279 elmtStdExp = MemoryManager<
1280 StdRegions::StdTriExp>::AllocateSharedPtr(Ba, Bb);
1282 else if (geom->GetShapeType() ==
1283 LibUtilities::eQuadrilateral)
1285 elmtStdExp = MemoryManager<
1286 StdRegions::StdQuadExp>::AllocateSharedPtr(Ba, Bb);
1291 "Fail to cast geom to a known 2D shape.");
1295 eInfo->m_basisKeyVector.push_back(
1296 elmtStdExp->GetTraceBasisKey(edge_id));
1299 else if ((TriGeom =
dynamic_cast<SpatialDomains::TriGeom *
>(
1300 compIt.second->m_geomVec[j])))
1303 SpatialDomains::GeometryLinkSharedPtr elmts =
1304 graph->GetElementsFromFace(TriGeom);
1308 SpatialDomains::Geometry *geom = elmts->at(0).first;
1309 int face_id = elmts->at(0).second;
1310 auto expInfo = expansions.find(geom->GetGlobalID());
1311 if (expInfo == expansions.end())
1314 "Failed to find expansion info for goemetry id: " +
1315 std::to_string(geom->GetGlobalID()));
1319 LibUtilities::BasisKey Ba =
1320 expInfo->second->m_basisKeyVector[0];
1321 LibUtilities::BasisKey Bb =
1322 expInfo->second->m_basisKeyVector[1];
1323 LibUtilities::BasisKey Bc =
1324 expInfo->second->m_basisKeyVector[2];
1325 StdRegions::StdExpansionSharedPtr elmtStdExp;
1327 if (geom->GetShapeType() == LibUtilities::ePrism)
1329 elmtStdExp = MemoryManager<
1330 StdRegions::StdPrismExp>::AllocateSharedPtr(Ba, Bb,
1333 else if (geom->GetShapeType() == LibUtilities::eTetrahedron)
1335 elmtStdExp = MemoryManager<
1336 StdRegions::StdTetExp>::AllocateSharedPtr(Ba, Bb,
1339 else if (geom->GetShapeType() == LibUtilities::ePyramid)
1341 elmtStdExp = MemoryManager<
1342 StdRegions::StdPyrExp>::AllocateSharedPtr(Ba, Bb,
1348 "Fail to cast geom to a known 3D shape.");
1352 LibUtilities::BasisKey TriBa =
1353 elmtStdExp->GetTraceBasisKey(face_id, 0, UseGLLOnTri);
1354 LibUtilities::BasisKey TriBb =
1355 elmtStdExp->GetTraceBasisKey(face_id, 1, UseGLLOnTri);
1357 if (geom->GetForient(face_id) >= 9)
1359 std::swap(TriBa, TriBb);
1362 eInfo->m_basisKeyVector.push_back(TriBa);
1363 eInfo->m_basisKeyVector.push_back(TriBb);
1366 else if ((QuadGeom =
dynamic_cast<SpatialDomains::QuadGeom *
>(
1367 compIt.second->m_geomVec[j])))
1370 SpatialDomains::GeometryLinkSharedPtr elmts =
1371 graph->GetElementsFromFace(QuadGeom);
1375 SpatialDomains::Geometry *geom = elmts->at(0).first;
1376 int face_id = elmts->at(0).second;
1377 auto expInfo = expansions.find(geom->GetGlobalID());
1378 if (expInfo == expansions.end())
1381 "Failed to find expansion info for goemetry id: " +
1382 std::to_string(geom->GetGlobalID()));
1386 LibUtilities::BasisKey Ba =
1387 expInfo->second->m_basisKeyVector[0];
1388 LibUtilities::BasisKey Bb =
1389 expInfo->second->m_basisKeyVector[1];
1390 LibUtilities::BasisKey Bc =
1391 expInfo->second->m_basisKeyVector[2];
1392 StdRegions::StdExpansionSharedPtr elmtStdExp;
1394 if (geom->GetShapeType() == LibUtilities::ePrism)
1396 elmtStdExp = MemoryManager<
1397 StdRegions::StdPrismExp>::AllocateSharedPtr(Ba, Bb,
1400 else if (geom->GetShapeType() == LibUtilities::eHexahedron)
1402 elmtStdExp = MemoryManager<
1403 StdRegions::StdHexExp>::AllocateSharedPtr(Ba, Bb,
1406 else if (geom->GetShapeType() == LibUtilities::ePyramid)
1408 elmtStdExp = MemoryManager<
1409 StdRegions::StdPyrExp>::AllocateSharedPtr(Ba, Bb,
1415 "Fail to cast geom to a known 3D shape.");
1419 LibUtilities::BasisKey QuadBa =
1420 elmtStdExp->GetTraceBasisKey(face_id, 0);
1421 LibUtilities::BasisKey QuadBb =
1422 elmtStdExp->GetTraceBasisKey(face_id, 1);
1424 if (geom->GetForient(face_id) >= 9)
1426 std::swap(QuadBa, QuadBb);
1429 eInfo->m_basisKeyVector.push_back(QuadBa);
1430 eInfo->m_basisKeyVector.push_back(QuadBb);
1438 if (DoOptOnCollection && IsNot0D)
1441 for (i = 0; i < cnt; ++i)
1443 if ((eInfo->m_basisKeyVector ==
1444 ExpOrder[i][0]->m_basisKeyVector) &&
1445 (eInfo->m_geomPtr->CalcGeomType() ==
1446 ExpOrder[i][0]->m_geomPtr->CalcGeomType()))
1448 ExpOrder[i].push_back(eInfo);
1455 ExpOrder[cnt++].push_back(eInfo);
1460 ExpOrder[0].push_back(eInfo);
1466 for (
auto &ordIt : ExpOrder)
1468 for (
auto &eit : ordIt.second)
1472 dynamic_cast<SpatialDomains::PointGeom *
>(eit->m_geomPtr)))
1476 exp = MemoryManager<LocalRegions::PointExp>::AllocateSharedPtr(
1479 else if ((SegGeom =
dynamic_cast<SpatialDomains::SegGeom *
>(
1484 if (SetToOneSpaceDimension)
1486 SpatialDomains::SegGeomUniquePtr OneDSegmentGeom =
1487 SegGeom->GenerateOneSpaceDimGeom(m_holder);
1490 MemoryManager<LocalRegions::SegExp>::AllocateSharedPtr(
1491 eit->m_basisKeyVector[0], OneDSegmentGeom.get());
1492 m_holder.m_segVec.push_back(std::move(OneDSegmentGeom));
1497 MemoryManager<LocalRegions::SegExp>::AllocateSharedPtr(
1498 eit->m_basisKeyVector[0], SegGeom);
1501 else if ((TriGeom =
dynamic_cast<SpatialDomains::TriGeom *
>(
1506 if (eit->m_basisKeyVector[0].GetBasisType() ==
1507 LibUtilities::eGLL_Lagrange)
1509 TriNb = LibUtilities::eNodalTriElec;
1511 exp = MemoryManager<LocalRegions::NodalTriExp>::
1512 AllocateSharedPtr(eit->m_basisKeyVector[0],
1513 eit->m_basisKeyVector[1], TriNb,
1519 MemoryManager<LocalRegions::TriExp>::AllocateSharedPtr(
1520 eit->m_basisKeyVector[0], eit->m_basisKeyVector[1],
1524 else if ((QuadGeom =
dynamic_cast<SpatialDomains::QuadGeom *
>(
1529 exp = MemoryManager<LocalRegions::QuadExp>::AllocateSharedPtr(
1530 eit->m_basisKeyVector[0], eit->m_basisKeyVector[1],
1536 "dynamic cast to a Geom (possibly 3D) failed");
1539 exp->SetElmtId(elmtid++);
1540 (*m_exp).push_back(exp);
1545 SetupCoeffPhys(DeclareCoeffPhysArrays);
1547 if (m_expType != e0D)
1549 CreateCollections(ImpType);
1563void ExpList::SetupCoeffPhys(
bool DeclareCoeffPhysArrays,
bool SetupOffsets)
1570 m_coeff_offset = Array<OneD, int>(m_exp->size());
1571 m_phys_offset = Array<OneD, int>(m_exp->size());
1573 m_ncoeffs = m_npoints = 0;
1575 for (i = 0; i < m_exp->size(); ++i)
1577 m_coeff_offset[i] = m_ncoeffs;
1578 m_phys_offset[i] = m_npoints;
1579 m_ncoeffs += (*m_exp)[i]->GetNcoeffs();
1580 m_npoints += (*m_exp)[i]->GetTotPoints();
1584 if (DeclareCoeffPhysArrays)
1586 m_coeffs = Array<OneD, NekDouble>(m_ncoeffs, 0.0);
1587 m_phys = Array<OneD, NekDouble>(m_npoints, 0.0);
1590 m_coeffsToElmt = Array<OneD, pair<int, int>>{size_t(m_ncoeffs)};
1592 for (
int i = 0; i < m_exp->size(); ++i)
1594 int coeffs_offset = m_coeff_offset[i];
1596 int loccoeffs = (*m_exp)[i]->GetNcoeffs();
1598 for (
int j = 0; j < loccoeffs; ++j)
1600 m_coeffsToElmt[coeffs_offset + j].first = i;
1601 m_coeffsToElmt[coeffs_offset + j].second = j;
1620void ExpList::InitialiseExpVector(
1621 const SpatialDomains::ExpansionInfoMap &expmap)
1623 SpatialDomains::SegGeom *SegmentGeom;
1624 SpatialDomains::TriGeom *TriangleGeom;
1625 SpatialDomains::QuadGeom *QuadrilateralGeom;
1626 SpatialDomains::TetGeom *TetGeom;
1627 SpatialDomains::HexGeom *HexGeom;
1628 SpatialDomains::PrismGeom *PrismGeom;
1629 SpatialDomains::PyrGeom *PyrGeom;
1632 LocalRegions::ExpansionSharedPtr exp;
1634 bool DoOptOnCollection =
1635 m_session->DefinesCmdLineArgument(
"no-exp-opt") ? false :
true;
1636 map<int, vector<int>> ExpOrder;
1637 if (DoOptOnCollection)
1639 auto expIt = expmap.begin();
1642 ExpOrder[cnt++].push_back(expIt->first);
1646 for (; expIt != expmap.end(); ++expIt)
1649 for (i = 0; i < cnt; ++i)
1651 const SpatialDomains::ExpansionInfoShPtr expInfo =
1652 expmap.find(ExpOrder[i][0])->second;
1654 if ((expIt->second->m_basisKeyVector ==
1655 expInfo->m_basisKeyVector) &&
1656 (expIt->second->m_geomPtr->CalcGeomType() ==
1657 expInfo->m_geomPtr->CalcGeomType()))
1659 ExpOrder[i].push_back(expIt->first);
1666 ExpOrder[cnt++].push_back(expIt->first);
1672 for (
auto &expIt : expmap)
1674 ExpOrder[0].push_back(expIt.first);
1681 for (
auto &it : ExpOrder)
1683 for (
int c = 0; c < it.second.size(); ++c)
1685 auto expIt = expmap.find(it.second[c]);
1687 const SpatialDomains::ExpansionInfoShPtr expInfo = expIt->second;
1689 switch (expInfo->m_basisKeyVector.size())
1693 ASSERTL1(m_expType == e1D || m_expType == eNoType,
1694 "Cannot mix expansion dimensions in one vector");
1697 if ((SegmentGeom =
dynamic_cast<SpatialDomains::SegGeom *
>(
1698 expInfo->m_geomPtr)))
1701 LibUtilities::BasisKey bkey =
1702 expInfo->m_basisKeyVector[0];
1704 exp = MemoryManager<LocalRegions::SegExp>::
1705 AllocateSharedPtr(bkey, SegmentGeom);
1710 "dynamic cast to a 1D Geom failed");
1716 ASSERTL1(m_expType == e2D || m_expType == eNoType,
1717 "Cannot mix expansion dimensions in one vector");
1720 LibUtilities::BasisKey Ba = expInfo->m_basisKeyVector[0];
1721 LibUtilities::BasisKey Bb = expInfo->m_basisKeyVector[1];
1724 dynamic_cast<SpatialDomains ::TriGeom *
>(
1725 expInfo->m_geomPtr)))
1728 if (Ba.GetBasisType() == LibUtilities::eGLL_Lagrange)
1730 LibUtilities::BasisKey newBa(LibUtilities::eOrtho_A,
1734 LibUtilities::PointsType TriNb =
1735 LibUtilities::eNodalTriElec;
1736 exp = MemoryManager<LocalRegions::NodalTriExp>::
1737 AllocateSharedPtr(newBa, Bb, TriNb,
1742 exp = MemoryManager<LocalRegions::TriExp>::
1743 AllocateSharedPtr(Ba, Bb, TriangleGeom);
1746 else if ((QuadrilateralGeom =
1747 dynamic_cast<SpatialDomains::QuadGeom *
>(
1748 expInfo->m_geomPtr)))
1750 exp = MemoryManager<LocalRegions::QuadExp>::
1751 AllocateSharedPtr(Ba, Bb, QuadrilateralGeom);
1756 "dynamic cast to a 2D Geom failed");
1762 ASSERTL1(m_expType == e3D || m_expType == eNoType,
1763 "Cannot mix expansion dimensions in one vector");
1766 LibUtilities::BasisKey Ba = expInfo->m_basisKeyVector[0];
1767 LibUtilities::BasisKey Bb = expInfo->m_basisKeyVector[1];
1768 LibUtilities::BasisKey Bc = expInfo->m_basisKeyVector[2];
1770 if ((TetGeom =
dynamic_cast<SpatialDomains::TetGeom *
>(
1771 expInfo->m_geomPtr)))
1773 if (Ba.GetBasisType() == LibUtilities::eGLL_Lagrange)
1777 if (Ba.GetBasisType() ==
1778 LibUtilities::eGLL_Lagrange)
1780 LibUtilities::BasisKey newBa(
1781 LibUtilities::eOrtho_A, Ba.GetNumModes(),
1784 LibUtilities::PointsType TetNb =
1785 LibUtilities::eNodalTetElec;
1786 exp = MemoryManager<LocalRegions::NodalTetExp>::
1787 AllocateSharedPtr(newBa, Bb, Bc, TetNb,
1791 else if (Ba.GetBasisType() ==
1792 LibUtilities::eGauss_Lagrange)
1796 "LocalRegions::NodalTetExp is not implemented "
1801 exp = MemoryManager<LocalRegions::TetExp>::
1802 AllocateSharedPtr(Ba, Bb, Bc, TetGeom);
1805 else if ((PrismGeom =
1806 dynamic_cast<SpatialDomains ::PrismGeom *
>(
1807 expInfo->m_geomPtr)))
1809 if (Ba.GetBasisType() == LibUtilities::eGLL_Lagrange)
1811 LibUtilities::BasisKey newBa(LibUtilities::eOrtho_A,
1815 LibUtilities::PointsType PrismNb =
1816 LibUtilities::eNodalPrismElec;
1818 exp = MemoryManager<LocalRegions::NodalPrismExp>::
1819 AllocateSharedPtr(newBa, Bb, Bc, PrismNb,
1824 exp = MemoryManager<LocalRegions::PrismExp>::
1825 AllocateSharedPtr(Ba, Bb, Bc, PrismGeom);
1828 else if ((PyrGeom =
dynamic_cast<SpatialDomains::PyrGeom *
>(
1829 expInfo->m_geomPtr)))
1831 exp = MemoryManager<
1832 LocalRegions::PyrExp>::AllocateSharedPtr(Ba, Bb, Bc,
1835 else if ((HexGeom =
dynamic_cast<SpatialDomains::HexGeom *
>(
1836 expInfo->m_geomPtr)))
1838 exp = MemoryManager<
1839 LocalRegions::HexExp>::AllocateSharedPtr(Ba, Bb, Bc,
1845 "dynamic cast to a Geom failed");
1851 "Dimension of basis key is greater than 3");
1855 m_elmtToExpId[exp->GetGeom()->GetGlobalID()] = id;
1856 exp->SetElmtId(
id++);
1859 (*m_exp).push_back(exp);
1884void ExpList::MultiplyByBlockMatrix(
const GlobalMatrixKey &gkey,
1885 const Array<OneD, const NekDouble> &inarray,
1886 Array<OneD, NekDouble> &outarray,
1891 int nrows = blockmat->GetRows();
1892 int ncols = blockmat->GetColumns();
1895 NekVector<NekDouble> in(ncols, inarray, eWrapper);
1896 NekVector<NekDouble> out(nrows, outarray, eWrapper);
1905 out = (*blockmat) * in;
1912void ExpList::MultiplyByQuadratureMetric(
1913 const Array<OneD, const NekDouble> &inarray,
1914 Array<OneD, NekDouble> &outarray)
1916 Array<OneD, NekDouble> e_outarray;
1918 for (
int i = 0; i < (*m_exp).size(); ++i)
1920 (*m_exp)[i]->MultiplyByQuadratureMetric(inarray + m_phys_offset[i],
1921 e_outarray = outarray +
1929void ExpList::DivideByQuadratureMetric(
1930 const Array<OneD, const NekDouble> &inarray,
1931 Array<OneD, NekDouble> &outarray)
1933 Array<OneD, NekDouble> e_outarray;
1935 for (
int i = 0; i < (*m_exp).size(); ++i)
1937 (*m_exp)[i]->DivideByQuadratureMetric(inarray + m_phys_offset[i],
1939 outarray + m_phys_offset[i]);
1956void ExpList::v_IProductWRTDerivBase(
1957 const int dir,
const Array<OneD, const NekDouble> &inarray,
1958 Array<OneD, NekDouble> &outarray)
1962 Array<OneD, NekDouble> e_outarray;
1963 for (i = 0; i < (*m_exp).size(); ++i)
1965 (*m_exp)[i]->IProductWRTDerivBase(dir, inarray + m_phys_offset[i],
1967 outarray + m_coeff_offset[i]);
1975void ExpList::IProductWRTDirectionalDerivBase(
1976 const Array<OneD, const NekDouble> &direction,
1977 const Array<OneD, const NekDouble> &inarray,
1978 Array<OneD, NekDouble> &outarray)
1981 int coordim = (*m_exp)[0]->GetGeom()->GetCoordim();
1982 int nq = direction.size() / coordim;
1984 Array<OneD, NekDouble> e_outarray;
1985 Array<OneD, NekDouble> e_MFdiv;
1987 Array<OneD, NekDouble> locdir;
1989 for (
int i = 0; i < (*m_exp).size(); ++i)
1991 npts_e = (*m_exp)[i]->GetTotPoints();
1992 locdir = Array<OneD, NekDouble>(npts_e * coordim);
1994 for (
int k = 0; k < coordim; ++k)
1996 Vmath::Vcopy(npts_e, &direction[k * nq + m_phys_offset[i]], 1,
1997 &locdir[k * npts_e], 1);
2000 (*m_exp)[i]->IProductWRTDirectionalDerivBase(
2001 locdir, inarray + m_phys_offset[i],
2002 e_outarray = outarray + m_coeff_offset[i]);
2017void ExpList::v_IProductWRTDerivBase(
2018 const Array<OneD,
const Array<OneD, NekDouble>> &inarray,
2019 Array<OneD, NekDouble> &outarray)
2021 Array<OneD, NekDouble> tmp0, tmp1, tmp2;
2023 int dim = GetCoordim(0);
2025 ASSERTL1(inarray.size() >= dim,
"inarray is not of sufficient dimension");
2028 if (m_collectionsDoInit[Collections::eIProductWRTDerivBase])
2030 for (
int i = 0; i < m_collections.size(); ++i)
2032 m_collections[i].Initialise(Collections::eIProductWRTDerivBase);
2034 m_collectionsDoInit[Collections::eIProductWRTDerivBase] =
false;
2037 LibUtilities::Timer timer;
2038 int input_offset{0};
2039 int output_offset{0};
2046 for (
int i = 0; i < m_collections.size(); ++i)
2048 m_collections[i].ApplyOperator(
2049 Collections::eIProductWRTDerivBase,
2050 inarray[0] + input_offset, tmp0 = outarray + output_offset);
2051 input_offset += m_collections[i].GetInputSize(
2052 Collections::eIProductWRTDerivBase);
2053 output_offset += m_collections[i].GetOutputSize(
2054 Collections::eIProductWRTDerivBase);
2058 for (
int i = 0; i < m_collections.size(); ++i)
2060 m_collections[i].ApplyOperator(
2061 Collections::eIProductWRTDerivBase,
2062 inarray[0] + input_offset, tmp0 = inarray[1] + input_offset,
2063 tmp1 = outarray + output_offset);
2064 input_offset += m_collections[i].GetInputSize(
2065 Collections::eIProductWRTDerivBase);
2066 output_offset += m_collections[i].GetOutputSize(
2067 Collections::eIProductWRTDerivBase);
2071 for (
int i = 0; i < m_collections.size(); ++i)
2073 m_collections[i].ApplyOperator(
2074 Collections::eIProductWRTDerivBase,
2075 inarray[0] + input_offset, tmp0 = inarray[1] + input_offset,
2076 tmp1 = inarray[2] + input_offset,
2077 tmp2 = outarray + output_offset);
2078 input_offset += m_collections[i].GetInputSize(
2079 Collections::eIProductWRTDerivBase);
2080 output_offset += m_collections[i].GetOutputSize(
2081 Collections::eIProductWRTDerivBase);
2085 NEKERROR(ErrorUtil::efatal,
"Dimension of inarray not correct");
2093 timer.AccumulateRegion(
"Collections:IProductWRTDerivBase", 10);
2129void ExpList::v_PhysDeriv(
const Array<OneD, const NekDouble> &inarray,
2130 Array<OneD, NekDouble> &out_d0,
2131 Array<OneD, NekDouble> &out_d1,
2132 Array<OneD, NekDouble> &out_d2)
2134 Array<OneD, NekDouble> e_out_d0;
2135 Array<OneD, NekDouble> e_out_d1;
2136 Array<OneD, NekDouble> e_out_d2;
2139 if (m_collectionsDoInit[Collections::ePhysDeriv])
2141 for (
int i = 0; i < m_collections.size(); ++i)
2143 m_collections[i].Initialise(Collections::ePhysDeriv);
2145 m_collectionsDoInit[Collections::ePhysDeriv] =
false;
2149 LibUtilities::Timer timer;
2151 for (
int i = 0; i < m_collections.size(); ++i)
2153 e_out_d0 = out_d0 + offset;
2154 e_out_d1 = out_d1 + offset;
2155 e_out_d2 = out_d2 + offset;
2156 m_collections[i].ApplyOperator(Collections::ePhysDeriv,
2157 inarray + offset, e_out_d0, e_out_d1,
2159 offset += m_collections[i].GetInputSize(Collections::ePhysDeriv);
2163 timer.AccumulateRegion(
"Collections:PhysDeriv", 10);
2166void ExpList::v_PhysDeriv(
const int dir,
2167 const Array<OneD, const NekDouble> &inarray,
2168 Array<OneD, NekDouble> &out_d)
2171 v_PhysDeriv(edir, inarray, out_d);
2174void ExpList::v_PhysDeriv(Direction edir,
2175 const Array<OneD, const NekDouble> &inarray,
2176 Array<OneD, NekDouble> &out_d)
2179 if (m_collectionsDoInit[Collections::ePhysDeriv])
2181 for (
int i = 0; i < m_collections.size(); ++i)
2183 m_collections[i].Initialise(Collections::ePhysDeriv);
2185 m_collectionsDoInit[Collections::ePhysDeriv] =
false;
2189 int intdir = (int)edir;
2190 Array<OneD, NekDouble> e_out_d;
2192 for (
int i = 0; i < m_collections.size(); ++i)
2194 e_out_d = out_d + offset;
2195 m_collections[i].ApplyOperator(Collections::ePhysDeriv, intdir,
2196 inarray + offset, e_out_d);
2197 offset += m_collections[i].GetInputSize(Collections::ePhysDeriv);
2205void ExpList::v_Curl(Array<OneD, Array<OneD, NekDouble>> &Vel,
2206 Array<OneD, Array<OneD, NekDouble>> &Q)
2208 int nq = GetTotPoints();
2209 Array<OneD, NekDouble> Vx(nq);
2210 Array<OneD, NekDouble> Uy(nq);
2211 Array<OneD, NekDouble> Dummy(nq);
2217 PhysDeriv(xDir, Vel[yDir], Vx);
2218 PhysDeriv(yDir, Vel[xDir], Uy);
2226 Array<OneD, NekDouble> Vz(nq);
2227 Array<OneD, NekDouble> Uz(nq);
2228 Array<OneD, NekDouble> Wx(nq);
2229 Array<OneD, NekDouble> Wy(nq);
2231 PhysDeriv(Vel[xDir], Dummy, Uy, Uz);
2232 PhysDeriv(Vel[yDir], Vx, Dummy, Vz);
2233 PhysDeriv(Vel[zDir], Wx, Wy, Dummy);
2241 ASSERTL0(0,
"Dimension not supported by ExpList::Curl");
2254void ExpList::v_CurlCurl(Array<OneD, Array<OneD, NekDouble>> &Vel,
2255 Array<OneD, Array<OneD, NekDouble>> &Q)
2257 int nq = GetTotPoints();
2258 Array<OneD, NekDouble> Vx(nq);
2259 Array<OneD, NekDouble> Uy(nq);
2260 Array<OneD, NekDouble> Dummy(nq);
2262 bool halfMode =
false;
2263 if (GetExpType() == e3DH1D)
2265 m_session->MatchSolverInfo(
"ModeType",
"HalfMode", halfMode,
false);
2272 PhysDeriv(xDir, Vel[yDir], Vx);
2273 PhysDeriv(yDir, Vel[xDir], Uy);
2277 PhysDeriv(Dummy, Q[1], Q[0]);
2287 Array<OneD, NekDouble> Vz(nq);
2288 Array<OneD, NekDouble> Uz(nq);
2289 Array<OneD, NekDouble> Wx(nq);
2290 Array<OneD, NekDouble> Wy(nq);
2292 PhysDeriv(Vel[xDir], Dummy, Uy, Uz);
2293 PhysDeriv(Vel[yDir], Vx, Dummy, Vz);
2294 PhysDeriv(Vel[zDir], Wx, Wy, Dummy);
2300 PhysDeriv(Q[0], Dummy, Uy, Uz);
2301 PhysDeriv(Q[1], Vx, Dummy, Vz);
2302 PhysDeriv(Q[2], Wx, Wy, Dummy);
2317 ASSERTL0(0,
"Dimension not supported");
2322void ExpList::v_PhysDirectionalDeriv(
2323 const Array<OneD, const NekDouble> &direction,
2324 const Array<OneD, const NekDouble> &inarray,
2325 Array<OneD, NekDouble> &outarray)
2328 int coordim = (*m_exp)[0]->GetGeom()->GetCoordim();
2329 int nq = direction.size() / coordim;
2331 Array<OneD, NekDouble> e_outarray;
2332 Array<OneD, NekDouble> e_MFdiv;
2333 Array<OneD, NekDouble> locdir;
2335 for (
int i = 0; i < (*m_exp).size(); ++i)
2337 npts_e = (*m_exp)[i]->GetTotPoints();
2338 locdir = Array<OneD, NekDouble>(npts_e * coordim);
2340 for (
int k = 0; k < coordim; ++k)
2342 Vmath::Vcopy(npts_e, &direction[k * nq + m_phys_offset[i]], 1,
2343 &locdir[k * npts_e], 1);
2346 (*m_exp)[i]->PhysDirectionalDeriv(inarray + m_phys_offset[i], locdir,
2348 outarray + m_phys_offset[i]);
2352void ExpList::ExponentialFilter(Array<OneD, NekDouble> &array,
2353 const NekDouble alpha,
const NekDouble exponent,
2354 const NekDouble cutoff)
2356 Array<OneD, NekDouble> e_array;
2358 for (
int i = 0; i < (*m_exp).size(); ++i)
2360 (*m_exp)[i]->ExponentialFilter(e_array = array + m_phys_offset[i],
2361 alpha, exponent, cutoff);
2373void ExpList::MultiplyByElmtInvMass(
const Array<OneD, const NekDouble> &inarray,
2374 Array<OneD, NekDouble> &outarray)
2376 GlobalMatrixKey mkey(StdRegions::eInvMass);
2380 NekVector<NekDouble> out(m_ncoeffs, outarray, eWrapper);
2381 if (inarray.data() == outarray.data())
2383 NekVector<NekDouble> in(m_ncoeffs, inarray);
2384 out = (*InvMass) * in;
2388 NekVector<NekDouble> in(m_ncoeffs, inarray, eWrapper);
2389 out = (*InvMass) * in;
2411void ExpList::v_FwdTransLocalElmt(
const Array<OneD, const NekDouble> &inarray,
2412 Array<OneD, NekDouble> &outarray)
2414 Array<OneD, NekDouble> f(m_ncoeffs);
2416 IProductWRTBase(inarray, f);
2417 MultiplyByElmtInvMass(f, outarray);
2420void ExpList::v_FwdTransBndConstrained(
2421 const Array<OneD, const NekDouble> &inarray,
2422 Array<OneD, NekDouble> &outarray)
2426 Array<OneD, NekDouble> e_outarray;
2428 for (i = 0; i < (*m_exp).size(); ++i)
2430 (*m_exp)[i]->FwdTransBndConstrained(inarray + m_phys_offset[i],
2432 outarray + m_coeff_offset[i]);
2443void ExpList::v_SmoothField([[maybe_unused]] Array<OneD, NekDouble> &field)
2455 ASSERTL0((*m_exp)[0]->GetBasisType(0) == LibUtilities::eGLL_Lagrange ||
2456 (*m_exp)[0]->GetBasisType(0) == LibUtilities::eGauss_Lagrange,
2457 "Smoothing is currently not allowed unless you are using "
2458 "a nodal base for efficiency reasons. The implemented "
2459 "smoothing technique requires the mass matrix inversion "
2460 "which is trivial just for GLL_LAGRANGE_SEM and "
2461 "GAUSS_LAGRANGE_SEMexpansions.");
2483 const GlobalMatrixKey &gkey)
2489 map<int, int> elmt_id;
2490 LibUtilities::ShapeType
ShapeType = gkey.GetShapeType();
2492 if (ShapeType != LibUtilities::eNoShapeType)
2494 for (i = 0; i < (*m_exp).size(); ++i)
2496 if ((*m_exp)[i]->DetShapeType() == ShapeType)
2498 elmt_id[n_exp++] = i;
2504 n_exp = (*m_exp).size();
2505 for (i = 0; i < n_exp; ++i)
2511 Array<OneD, unsigned int> nrows(n_exp);
2512 Array<OneD, unsigned int> ncols(n_exp);
2514 switch (gkey.GetMatrixType())
2516 case StdRegions::eBwdTrans:
2519 for (i = 0; i < n_exp; ++i)
2521 nrows[i] = (*m_exp)[elmt_id.find(i)->second]->GetTotPoints();
2522 ncols[i] = (*m_exp)[elmt_id.find(i)->second]->GetNcoeffs();
2526 case StdRegions::eIProductWRTBase:
2529 for (i = 0; i < n_exp; ++i)
2531 nrows[i] = (*m_exp)[elmt_id.find(i)->second]->GetNcoeffs();
2532 ncols[i] = (*m_exp)[elmt_id.find(i)->second]->GetTotPoints();
2536 case StdRegions::eMass:
2537 case StdRegions::eInvMass:
2538 case StdRegions::eHelmholtz:
2539 case StdRegions::eLaplacian:
2540 case StdRegions::eCoeffsToEquiSpaced:
2541 case StdRegions::eEquiSpacedToCoeffs:
2542 case StdRegions::eCoeffsToGLL:
2543 case StdRegions::eGLLToCoeffs:
2544 case StdRegions::eInvHybridDGHelmholtz:
2548 for (i = 0; i < n_exp; ++i)
2550 nrows[i] = (*m_exp)[elmt_id.find(i)->second]->GetNcoeffs();
2551 ncols[i] = (*m_exp)[elmt_id.find(i)->second]->GetNcoeffs();
2556 case StdRegions::eHybridDGLamToU:
2559 for (i = 0; i < n_exp; ++i)
2561 nrows[i] = (*m_exp)[elmt_id.find(i)->second]->GetNcoeffs();
2563 (*m_exp)[elmt_id.find(i)->second]->NumDGBndryCoeffs();
2567 case StdRegions::eHybridDGHelmBndLam:
2570 for (i = 0; i < n_exp; ++i)
2573 (*m_exp)[elmt_id.find(i)->second]->NumDGBndryCoeffs();
2575 (*m_exp)[elmt_id.find(i)->second]->NumDGBndryCoeffs();
2582 "Global Matrix creation not defined for this "
2588 BlkMatrix = MemoryManager<DNekScalBlkMat>::AllocateSharedPtr(nrows, ncols,
2591 int nvarcoeffs = gkey.GetNVarCoeffs();
2593 Array<OneD, NekDouble> varcoeffs_wk;
2595 for (i = cnt1 = 0; i < n_exp; ++i)
2599 StdRegions::VarCoeffMap varcoeffs;
2604 varcoeffs = StdRegions::RestrictCoeffMap(
2605 gkey.GetVarCoeffs(), m_phys_offset[i],
2606 (*m_exp)[i]->GetTotPoints());
2609 LocalRegions::MatrixKey matkey(
2610 gkey.GetMatrixType(), (*m_exp)[eid]->DetShapeType(), *(*m_exp)[eid],
2611 gkey.GetConstFactors(), varcoeffs);
2613 loc_mat = std::dynamic_pointer_cast<LocalRegions::Expansion>(
2614 (*m_exp)[elmt_id.find(i)->second])
2615 ->GetLocMatrix(matkey);
2616 BlkMatrix->SetBlock(i, i, loc_mat);
2623 const GlobalMatrixKey &gkey)
2625 auto matrixIter = m_blockMat->find(gkey);
2627 if (matrixIter == m_blockMat->end())
2629 return ((*m_blockMat)[gkey] = GenBlockMatrix(gkey));
2633 return matrixIter->second;
2666void ExpList::GeneralMatrixOp(
const GlobalMatrixKey &gkey,
2667 const Array<OneD, const NekDouble> &inarray,
2668 Array<OneD, NekDouble> &outarray)
2670 int nvarcoeffs = gkey.GetNVarCoeffs();
2672 if (gkey.GetMatrixType() == StdRegions::eHelmholtz ||
2673 gkey.GetMatrixType() == StdRegions::eLinearAdvectionDiffusionReaction)
2676 Collections::OperatorType opType =
2677 (gkey.GetMatrixType() == StdRegions::eHelmholtz)
2678 ? Collections::eHelmholtz
2682 if (m_collections.size() && m_collectionsDoInit[opType])
2684 for (
int i = 0; i < m_collections.size(); ++i)
2686 m_collections[i].Initialise(opType, gkey.GetConstFactors());
2688 m_collectionsDoInit[opType] =
false;
2693 for (
int i = 0; i < m_collections.size(); ++i)
2695 m_collections[i].UpdateFactors(opType, gkey.GetConstFactors());
2698 StdRegions::VarCoeffMap varcoeffs;
2701 varcoeffs = StdRegions::RestrictCoeffMap(
2702 gkey.GetVarCoeffs(), m_phys_offset[cnt],
2703 m_collections[i].GetPhysSize(opType));
2704 cnt += m_collections[i].GetNumElmt(opType);
2706 m_collections[i].UpdateVarcoeffs(opType, varcoeffs);
2709 Array<OneD, NekDouble> tmp;
2710 int input_offset{0};
2711 int output_offset{0};
2712 for (
int i = 0; i < m_collections.size(); ++i)
2716 m_collections[i].ApplyOperator(opType, inarray + input_offset,
2717 tmp = outarray + output_offset);
2718 input_offset += m_collections[i].GetInputSize(opType);
2719 output_offset += m_collections[i].GetOutputSize(opType);
2724 Array<OneD, NekDouble> tmp_outarray;
2725 for (
int i = 0; i < (*m_exp).size(); ++i)
2729 StdRegions::VarCoeffMap varcoeffs;
2733 varcoeffs = StdRegions::RestrictCoeffMap(
2734 gkey.GetVarCoeffs(), m_phys_offset[i],
2735 (*m_exp)[i]->GetTotPoints());
2738 StdRegions::StdMatrixKey mkey(
2739 gkey.GetMatrixType(), (*m_exp)[i]->DetShapeType(),
2740 *((*m_exp)[i]), gkey.GetConstFactors(), varcoeffs);
2742 (*m_exp)[i]->GeneralMatrixOp(
2743 inarray + m_coeff_offset[i],
2744 tmp_outarray = outarray + m_coeff_offset[i], mkey);
2749 if (GetGJPData() && GetGJPData()->IsImplicit())
2752 1.0 * gkey.GetConstFactors().find(StdRegions::eFactorGJP)->second;
2753 Array<OneD, NekDouble> inphys(GetTotPoints());
2754 BwdTrans(inarray, inphys);
2755 GetGJPData()->Apply(inphys, outarray, NullNekDouble1DArray, scale);
2767 const GlobalMatrixKey &mkey,
const AssemblyMapCGSharedPtr &locToGloMap)
2769 int i, j, n, gid1, gid2, cntdim1, cntdim2;
2773 unsigned int glob_rows = 0;
2774 unsigned int glob_cols = 0;
2775 unsigned int loc_rows = 0;
2776 unsigned int loc_cols = 0;
2778 bool assembleFirstDim =
false;
2779 bool assembleSecondDim =
false;
2781 switch (mkey.GetMatrixType())
2783 case StdRegions::eBwdTrans:
2785 glob_rows = m_npoints;
2786 glob_cols = locToGloMap->GetNumGlobalCoeffs();
2788 assembleFirstDim =
false;
2789 assembleSecondDim =
true;
2792 case StdRegions::eIProductWRTBase:
2794 glob_rows = locToGloMap->GetNumGlobalCoeffs();
2795 glob_cols = m_npoints;
2797 assembleFirstDim =
true;
2798 assembleSecondDim =
false;
2801 case StdRegions::eMass:
2802 case StdRegions::eHelmholtz:
2803 case StdRegions::eLaplacian:
2804 case StdRegions::eHybridDGHelmBndLam:
2806 glob_rows = locToGloMap->GetNumGlobalCoeffs();
2807 glob_cols = locToGloMap->GetNumGlobalCoeffs();
2809 assembleFirstDim =
true;
2810 assembleSecondDim =
true;
2816 "Global Matrix creation not defined for this "
2824 int nvarcoeffs = mkey.GetNVarCoeffs();
2828 for (n = cntdim1 = cntdim2 = 0; n < (*m_exp).size(); ++n)
2832 StdRegions::VarCoeffMap varcoeffs;
2837 varcoeffs = StdRegions::RestrictCoeffMap(
2838 mkey.GetVarCoeffs(), m_phys_offset[eid],
2839 (*m_exp)[eid]->GetTotPoints());
2842 LocalRegions::MatrixKey matkey(
2843 mkey.GetMatrixType(), (*m_exp)[eid]->DetShapeType(),
2844 *((*m_exp)[eid]), mkey.GetConstFactors(), varcoeffs);
2847 std::dynamic_pointer_cast<LocalRegions::Expansion>((*m_exp)[n])
2848 ->GetLocMatrix(matkey);
2850 loc_rows = loc_mat->GetRows();
2851 loc_cols = loc_mat->GetColumns();
2853 for (i = 0; i < loc_rows; ++i)
2855 if (assembleFirstDim)
2857 gid1 = locToGloMap->GetLocalToGlobalMap(cntdim1 + i);
2858 sign1 = locToGloMap->GetLocalToGlobalSign(cntdim1 + i);
2866 for (j = 0; j < loc_cols; ++j)
2868 if (assembleSecondDim)
2870 gid2 = locToGloMap->GetLocalToGlobalMap(cntdim2 + j);
2871 sign2 = locToGloMap->GetLocalToGlobalSign(cntdim2 + j);
2880 coord = make_pair(gid1, gid2);
2881 if (spcoomat.count(coord) == 0)
2883 spcoomat[coord] = sign1 * sign2 * (*loc_mat)(i, j);
2887 spcoomat[coord] += sign1 * sign2 * (*loc_mat)(i, j);
2891 cntdim1 += loc_rows;
2892 cntdim2 += loc_cols;
2895 return MemoryManager<GlobalMatrix>::AllocateSharedPtr(m_session, glob_rows,
2896 glob_cols, spcoomat);
2900 const GlobalLinSysKey &mkey,
const AssemblyMapCGSharedPtr &locToGloMap)
2902 int i, j, n, gid1, gid2, loc_lda, eid;
2906 int totDofs = locToGloMap->GetNumGlobalCoeffs();
2907 int NumDirBCs = locToGloMap->GetNumGlobalDirBndCoeffs();
2909 unsigned int rows = totDofs - NumDirBCs;
2910 unsigned int cols = totDofs - NumDirBCs;
2914 int bwidth = locToGloMap->GetFullSystemBandWidth();
2916 int nvarcoeffs = mkey.GetNVarCoeffs();
2919 map<int, RobinBCInfoSharedPtr> RobinBCInfo = GetRobinBCInfo();
2921 switch (mkey.GetMatrixType())
2924 case StdRegions::eHelmholtz:
2925 case StdRegions::eLaplacian:
2926 if ((2 * (bwidth + 1)) < rows)
2929 Gmat = MemoryManager<DNekMat>::AllocateSharedPtr(
2930 rows, cols, zero, matStorage, bwidth, bwidth);
2935 Gmat = MemoryManager<DNekMat>::AllocateSharedPtr(
2936 rows, cols, zero, matStorage);
2944 Gmat = MemoryManager<DNekMat>::AllocateSharedPtr(
2945 rows, cols, zero, matStorage);
2950 for (n = 0; n < (*m_exp).size(); ++n)
2954 StdRegions::VarCoeffMap varcoeffs;
2959 varcoeffs = StdRegions::RestrictCoeffMap(
2960 mkey.GetVarCoeffs(), m_phys_offset[eid],
2961 (*m_exp)[eid]->GetTotPoints());
2964 LocalRegions::MatrixKey matkey(
2965 mkey.GetMatrixType(), (*m_exp)[eid]->DetShapeType(),
2966 *((*m_exp)[eid]), mkey.GetConstFactors(), varcoeffs);
2969 std::dynamic_pointer_cast<LocalRegions::Expansion>((*m_exp)[n])
2970 ->GetLocMatrix(matkey);
2972 if (RobinBCInfo.count(n) != 0)
2977 int rows = loc_mat->GetRows();
2978 int cols = loc_mat->GetColumns();
2979 const NekDouble *dat = loc_mat->GetRawPtr();
2981 MemoryManager<DNekMat>::AllocateSharedPtr(rows, cols, dat);
2982 Blas::Dscal(rows * cols, loc_mat->Scale(), new_mat->GetRawPtr(), 1);
2985 for (rBC = RobinBCInfo.find(n)->second; rBC; rBC = rBC->next)
2987 (*m_exp)[n]->AddRobinMassMatrix(
2988 rBC->m_robinID, rBC->m_robinPrimitiveCoeffs, new_mat);
2994 MemoryManager<DNekScalMat>::AllocateSharedPtr(one, new_mat);
2997 loc_lda = loc_mat->GetColumns();
2999 for (i = 0; i < loc_lda; ++i)
3001 gid1 = locToGloMap->GetLocalToGlobalMap(m_coeff_offset[n] + i) -
3003 sign1 = locToGloMap->GetLocalToGlobalSign(m_coeff_offset[n] + i);
3006 for (j = 0; j < loc_lda; ++j)
3008 gid2 = locToGloMap->GetLocalToGlobalMap(m_coeff_offset[n] +
3011 sign2 = locToGloMap->GetLocalToGlobalSign(
3012 m_coeff_offset[n] + j);
3019 if ((matStorage == eFULL) || (gid2 >= gid1))
3021 value = Gmat->GetValue(gid1, gid2) +
3022 sign1 * sign2 * (*loc_mat)(i, j);
3023 Gmat->SetValue(gid1, gid2, value);
3052 const GlobalLinSysKey &mkey,
const AssemblyMapCGSharedPtr &locToGloMap)
3055 std::shared_ptr<ExpList> vExpList = GetSharedThisPtr();
3057 MultiRegions::GlobalSysSolnType vType = mkey.GetGlobalSysSolnType();
3059 if (vType >= eSIZE_GlobalSysSolnType)
3061 NEKERROR(ErrorUtil::efatal,
"Matrix solution type not defined");
3063 std::string vSolnType = MultiRegions::GlobalSysSolnTypeMap[vType];
3070 const GlobalLinSysKey &mkey,
const AssemblyMapSharedPtr &locToGloMap)
3072 std::shared_ptr<ExpList> vExpList = GetSharedThisPtr();
3073 const map<int, RobinBCInfoSharedPtr> vRobinBCInfo = GetRobinBCInfo();
3075 MultiRegions::GlobalSysSolnType vType = mkey.GetGlobalSysSolnType();
3077 if (vType >= eSIZE_GlobalSysSolnType)
3079 NEKERROR(ErrorUtil::efatal,
"Matrix solution type not defined");
3081 std::string vSolnType = MultiRegions::GlobalSysSolnTypeMap[vType];
3105void ExpList::v_BwdTrans(
const Array<OneD, const NekDouble> &inarray,
3106 Array<OneD, NekDouble> &outarray)
3108 LibUtilities::Timer timer;
3110 if (m_expType == e0D)
3117 if (m_collections.size() && m_collectionsDoInit[Collections::eBwdTrans])
3119 for (
int i = 0; i < m_collections.size(); ++i)
3121 m_collections[i].Initialise(Collections::eBwdTrans);
3123 m_collectionsDoInit[Collections::eBwdTrans] =
false;
3129 Array<OneD, NekDouble> tmp;
3130 int input_offset{0};
3131 int output_offset{0};
3132 for (
int i = 0; i < m_collections.size(); ++i)
3134 m_collections[i].ApplyOperator(Collections::eBwdTrans,
3135 inarray + input_offset,
3136 tmp = outarray + output_offset);
3138 m_collections[i].GetInputSize(Collections::eBwdTrans);
3140 m_collections[i].GetOutputSize(Collections::eBwdTrans);
3147 timer.AccumulateRegion(
"Collections:BwdTrans", 10);
3150LocalRegions::ExpansionSharedPtr &ExpList::GetExp(
3151 const Array<OneD, const NekDouble> &gloCoord)
3153 return GetExp(GetExpIndex(gloCoord));
3161int ExpList::GetExpIndex(
const Array<OneD, const NekDouble> &gloCoord,
3162 NekDouble tol,
bool returnNearestElmt,
int cachedId,
3163 NekDouble maxDistance)
3165 Array<OneD, NekDouble> Lcoords(gloCoord.size());
3167 return GetExpIndex(gloCoord, Lcoords, tol, returnNearestElmt, cachedId,
3171int ExpList::GetExpIndex(
const Array<OneD, const NekDouble> &gloCoords,
3172 Array<OneD, NekDouble> &locCoords, NekDouble tol,
3173 bool returnNearestElmt,
int cachedId,
3174 NekDouble maxDistance)
3176 if (GetNumElmts() == 0)
3181 if (m_elmtToExpId.size() == 0)
3186 for (
int i = (*m_exp).size() - 1; i >= 0; --i)
3188 m_elmtToExpId[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
3195 Array<OneD, NekDouble> savLocCoords(locCoords.size());
3197 if (cachedId >= 0 && cachedId < (*m_exp).size())
3200 if ((*m_exp)[cachedId]->GetGeom()->ContainsPoint(gloCoords, locCoords,
3205 else if (returnNearestElmt && (nearpt < nearpt_min))
3210 nearpt_min = nearpt;
3211 Vmath::Vcopy(locCoords.size(), locCoords, 1, savLocCoords, 1);
3215 NekDouble x = (gloCoords.size() > 0 ? gloCoords[0] : 0.0);
3216 NekDouble y = (gloCoords.size() > 1 ? gloCoords[1] : 0.0);
3217 NekDouble z = (gloCoords.size() > 2 ? gloCoords[2] : 0.0);
3218 SpatialDomains::PointGeomUniquePtr
p =
3219 ObjPoolManager<SpatialDomains::PointGeom>::AllocateUniquePtr(
3220 GetExp(0)->GetCoordim(), -1, x, y, z);
3224 std::vector<int> elmts = m_graph->GetElementsContainingPoint(
p.get());
3227 for (
int i = 0; i < elmts.size(); ++i)
3229 int id = m_elmtToExpId[elmts[i]];
3234 if ((*m_exp)[
id]->GetGeom()->ContainsPoint(gloCoords, locCoords, tol,
3239 else if (returnNearestElmt && (nearpt < nearpt_min))
3244 nearpt_min = nearpt;
3245 Vmath::Vcopy(locCoords.size(), locCoords, 1, savLocCoords, 1);
3251 if (returnNearestElmt && nearpt_min <= maxDistance)
3253 Vmath::Vcopy(locCoords.size(), savLocCoords, 1, locCoords, 1);
3254 std::string msg =
"Failed to find point within a tolerance of " +
3255 boost::lexical_cast<std::string>(tol) +
3256 ", using local point (";
3257 for (
size_t j = 0; j < locCoords.size(); ++j)
3259 msg += boost::lexical_cast<std::string>(savLocCoords[j]);
3260 if (j < locCoords.size())
3265 msg +=
") in element: " + std::to_string(min_id) +
3266 " with a distance of " + std::to_string(nearpt_min);
3280NekDouble ExpList::PhysEvaluate(
const Array<OneD, const NekDouble> &coords,
3281 const Array<OneD, const NekDouble> &phys)
3283 int dim = GetCoordim(0);
3284 ASSERTL0(dim == coords.size(),
"Invalid coordinate dimension.");
3287 Array<OneD, NekDouble> xi(dim);
3288 int elmtIdx = GetExpIndex(coords, xi);
3289 ASSERTL0(elmtIdx > 0,
"Unable to find element containing point.");
3292 Array<OneD, NekDouble> elmtPhys = phys + m_phys_offset[elmtIdx];
3295 return (*m_exp)[elmtIdx]->StdPhysEvaluate(xi, elmtPhys);
3303void ExpList::ApplyGeomInfo()
3315void ExpList::v_Reset()
3318 LibUtilities::NekManager<LocalRegions::MatrixKey,
DNekScalMat,
3319 LocalRegions::MatrixKey::opLess>::ClearManager();
3320 LibUtilities::NekManager<LocalRegions::MatrixKey,
DNekScalBlkMat,
3321 LocalRegions::MatrixKey::opLess>::ClearManager();
3324 m_blockMat->clear();
3327 for (
int i = 0; i < m_exp->size(); ++i)
3329 (*m_exp)[i]->GetGeom()->Reset(m_graph->GetCurvedEdges(),
3330 m_graph->GetCurvedFaces());
3334 for (
int i = 0; i < m_exp->size(); ++i)
3336 (*m_exp)[i]->Reset();
3339 CreateCollections(Collections::eNoImpType);
3343void ExpList::ResetMatrices()
3346 LibUtilities::NekManager<LocalRegions::MatrixKey,
DNekScalMat,
3347 LocalRegions::MatrixKey::opLess>::ClearManager();
3348 LibUtilities::NekManager<LocalRegions::MatrixKey,
DNekScalBlkMat,
3349 LocalRegions::MatrixKey::opLess>::ClearManager();
3352 m_blockMat->clear();
3360void ExpList::v_WriteTecplotHeader(std::ostream &outfile, std::string var)
3362 if (GetNumElmts() == 0)
3367 int coordim = GetExp(0)->GetCoordim();
3368 char vars[3] = {
'x',
'y',
'z'};
3370 if (m_expType == e3DH1D)
3374 else if (m_expType == e3DH2D)
3379 outfile <<
"Variables = x";
3380 for (
int i = 1; i < coordim; ++i)
3382 outfile <<
", " << vars[i];
3387 outfile <<
", " << var;
3390 outfile << std::endl << std::endl;
3398void ExpList::v_WriteTecplotZone(std::ostream &outfile,
int expansion)
3401 int coordim = GetCoordim(0);
3402 int nPoints = GetTotPoints();
3403 int nBases = (*m_exp)[0]->GetNumBases();
3406 Array<OneD, Array<OneD, NekDouble>> coords(3);
3408 if (expansion == -1)
3410 nPoints = GetTotPoints();
3412 coords[0] = Array<OneD, NekDouble>(nPoints);
3413 coords[1] = Array<OneD, NekDouble>(nPoints);
3414 coords[2] = Array<OneD, NekDouble>(nPoints);
3416 GetCoords(coords[0], coords[1], coords[2]);
3418 for (i = 0; i < m_exp->size(); ++i)
3422 for (j = 0; j < nBases; ++j)
3424 numInt *= (*m_exp)[i]->GetNumPoints(j) - 1;
3427 numBlocks += numInt;
3432 nPoints = (*m_exp)[expansion]->GetTotPoints();
3434 coords[0] = Array<OneD, NekDouble>(nPoints);
3435 coords[1] = Array<OneD, NekDouble>(nPoints);
3436 coords[2] = Array<OneD, NekDouble>(nPoints);
3438 (*m_exp)[expansion]->GetCoords(coords[0], coords[1], coords[2]);
3441 for (j = 0; j < nBases; ++j)
3443 numBlocks *= (*m_exp)[expansion]->GetNumPoints(j) - 1;
3447 if (m_expType == e3DH1D)
3451 int nPlanes = GetZIDs().size();
3452 NekDouble tmp = numBlocks * (nPlanes - 1.0) / nPlanes;
3453 numBlocks = (int)tmp;
3455 else if (m_expType == e3DH2D)
3461 outfile <<
"Zone, N=" << nPoints <<
", E=" << numBlocks <<
", F=FEBlock";
3466 outfile <<
", ET=QUADRILATERAL" << std::endl;
3469 outfile <<
", ET=BRICK" << std::endl;
3472 NEKERROR(ErrorUtil::efatal,
"Not set up for this type of output");
3477 for (j = 0; j < coordim; ++j)
3479 for (i = 0; i < nPoints; ++i)
3481 outfile << coords[j][i] <<
" ";
3482 if (i % 1000 == 0 && i)
3484 outfile << std::endl;
3487 outfile << std::endl;
3491void ExpList::v_WriteTecplotConnectivity(std::ostream &outfile,
int expansion)
3494 int nbase = (*m_exp)[0]->GetNumBases();
3497 std::shared_ptr<LocalRegions::ExpansionVector> exp = m_exp;
3499 if (expansion != -1)
3501 exp = std::shared_ptr<LocalRegions::ExpansionVector>(
3502 new LocalRegions::ExpansionVector(1));
3503 (*exp)[0] = (*m_exp)[expansion];
3508 for (i = 0; i < (*exp).size(); ++i)
3510 const int np0 = (*exp)[i]->GetNumPoints(0);
3511 const int np1 = (*exp)[i]->GetNumPoints(1);
3513 for (j = 1; j < np1; ++j)
3515 for (k = 1; k < np0; ++k)
3517 outfile << cnt + (j - 1) * np0 + k <<
" ";
3518 outfile << cnt + (j - 1) * np0 + k + 1 <<
" ";
3519 outfile << cnt + j * np0 + k + 1 <<
" ";
3520 outfile << cnt + j * np0 + k << endl;
3527 else if (nbase == 3)
3529 for (i = 0; i < (*exp).size(); ++i)
3531 const int np0 = (*exp)[i]->GetNumPoints(0);
3532 const int np1 = (*exp)[i]->GetNumPoints(1);
3533 const int np2 = (*exp)[i]->GetNumPoints(2);
3534 const int np01 = np0 * np1;
3536 for (j = 1; j < np2; ++j)
3538 for (k = 1; k < np1; ++k)
3540 for (l = 1; l < np0; ++l)
3542 outfile << cnt + (j - 1) * np01 + (k - 1) * np0 + l
3544 outfile << cnt + (j - 1) * np01 + (k - 1) * np0 + l + 1
3546 outfile << cnt + (j - 1) * np01 + k * np0 + l + 1
3548 outfile << cnt + (j - 1) * np01 + k * np0 + l <<
" ";
3549 outfile << cnt + j * np01 + (k - 1) * np0 + l <<
" ";
3550 outfile << cnt + j * np01 + (k - 1) * np0 + l + 1
3552 outfile << cnt + j * np01 + k * np0 + l + 1 <<
" ";
3553 outfile << cnt + j * np01 + k * np0 + l << endl;
3557 cnt += np0 * np1 * np2;
3562 NEKERROR(ErrorUtil::efatal,
"Not set up for this dimension");
3571void ExpList::v_WriteTecplotField(std::ostream &outfile,
int expansion)
3573 if (expansion == -1)
3575 int totpoints = GetTotPoints();
3576 if (m_physState ==
false)
3578 BwdTrans(m_coeffs, m_phys);
3581 for (
int i = 0; i < totpoints; ++i)
3583 outfile << m_phys[i] <<
" ";
3584 if (i % 1000 == 0 && i)
3586 outfile << std::endl;
3589 outfile << std::endl;
3593 int nPoints = (*m_exp)[expansion]->GetTotPoints();
3595 for (
int i = 0; i < nPoints; ++i)
3597 outfile << m_phys[i + m_phys_offset[expansion]] <<
" ";
3600 outfile << std::endl;
3604void ExpList::WriteVtkHeader(std::ostream &outfile)
3606 outfile <<
"<?xml version=\"1.0\"?>" << endl;
3607 outfile << R
"(<VTKFile type="UnstructuredGrid" version="0.1" )"
3608 << "byte_order=\"LittleEndian\">" << endl;
3609 outfile <<
" <UnstructuredGrid>" << endl;
3612void ExpList::WriteVtkFooter(std::ostream &outfile)
3614 outfile <<
" </UnstructuredGrid>" << endl;
3615 outfile <<
"</VTKFile>" << endl;
3618void ExpList::v_WriteVtkPieceHeader(std::ostream &outfile,
int expansion,
3619 [[maybe_unused]]
int istrip)
3622 int nbase = (*m_exp)[expansion]->GetNumBases();
3623 int ntot = (*m_exp)[expansion]->GetTotPoints();
3627 for (i = 0; i < nbase; ++i)
3629 nquad[i] = (*m_exp)[expansion]->GetNumPoints(i);
3630 ntotminus *= (nquad[i] - 1);
3633 Array<OneD, NekDouble> coords[3];
3634 coords[0] = Array<OneD, NekDouble>(ntot, 0.0);
3635 coords[1] = Array<OneD, NekDouble>(ntot, 0.0);
3636 coords[2] = Array<OneD, NekDouble>(ntot, 0.0);
3637 (*m_exp)[expansion]->GetCoords(coords[0], coords[1], coords[2]);
3639 outfile <<
" <Piece NumberOfPoints=\"" << ntot <<
"\" NumberOfCells=\""
3640 << ntotminus <<
"\">" << endl;
3641 outfile <<
" <Points>" << endl;
3642 outfile <<
" <DataArray type=\"Float64\" "
3643 << R
"(NumberOfComponents="3" format="ascii">)" << endl;
3645 for (i = 0; i < ntot; ++i)
3647 for (j = 0; j < 3; ++j)
3649 outfile << setprecision(8) << scientific << (float)coords[j][i]
3655 outfile <<
" </DataArray>" << endl;
3656 outfile <<
" </Points>" << endl;
3657 outfile <<
" <Cells>" << endl;
3658 outfile <<
" <DataArray type=\"Int32\" "
3659 << R
"(Name="connectivity" format="ascii">)" << endl;
3669 for (i = 0; i < nquad[0] - 1; ++i)
3671 outfile << i <<
" " << i + 1 << endl;
3679 for (i = 0; i < nquad[0] - 1; ++i)
3681 for (j = 0; j < nquad[1] - 1; ++j)
3683 outfile << j * nquad[0] + i <<
" " << j * nquad[0] + i + 1
3684 <<
" " << (j + 1) * nquad[0] + i + 1 <<
" "
3685 << (j + 1) * nquad[0] + i << endl;
3694 for (i = 0; i < nquad[0] - 1; ++i)
3696 for (j = 0; j < nquad[1] - 1; ++j)
3698 for (k = 0; k < nquad[2] - 1; ++k)
3701 << k * nquad[0] * nquad[1] + j * nquad[0] + i <<
" "
3702 << k * nquad[0] * nquad[1] + j * nquad[0] + i + 1
3704 << k * nquad[0] * nquad[1] + (j + 1) * nquad[0] +
3707 << k * nquad[0] * nquad[1] + (j + 1) * nquad[0] + i
3709 << (k + 1) * nquad[0] * nquad[1] + j * nquad[0] + i
3711 << (k + 1) * nquad[0] * nquad[1] + j * nquad[0] +
3714 << (k + 1) * nquad[0] * nquad[1] +
3715 (j + 1) * nquad[0] + i + 1
3717 << (k + 1) * nquad[0] * nquad[1] +
3718 (j + 1) * nquad[0] + i
3730 outfile <<
" </DataArray>" << endl;
3731 outfile <<
" <DataArray type=\"Int32\" "
3732 << R
"(Name="offsets" format="ascii">)" << endl;
3733 for (i = 0; i < ntotminus; ++i)
3735 outfile << i * ns + ns <<
" ";
3738 outfile <<
" </DataArray>" << endl;
3739 outfile <<
" <DataArray type=\"UInt8\" "
3740 << R
"(Name="types" format="ascii">)" << endl;
3741 for (i = 0; i < ntotminus; ++i)
3746 outfile <<
" </DataArray>" << endl;
3747 outfile <<
" </Cells>" << endl;
3748 outfile <<
" <PointData>" << endl;
3751void ExpList::WriteVtkPieceFooter(std::ostream &outfile,
3752 [[maybe_unused]]
int expansion)
3754 outfile <<
" </PointData>" << endl;
3755 outfile <<
" </Piece>" << endl;
3758void ExpList::v_WriteVtkPieceData(std::ostream &outfile,
int expansion,
3762 int nq = (*m_exp)[expansion]->GetTotPoints();
3765 outfile << R
"( <DataArray type="Float64" Name=")" << var << "\">"
3769 const Array<OneD, NekDouble> phys = m_phys + m_phys_offset[expansion];
3771 for (i = 0; i < nq; ++i)
3773 outfile << (fabs(phys[i]) < NekConstants::kNekZeroTol ? 0 : phys[i])
3777 outfile <<
" </DataArray>" << endl;
3798NekDouble ExpList::Linf(
const Array<OneD, const NekDouble> &inarray,
3799 const Array<OneD, const NekDouble> &soln)
3803 if (soln == NullNekDouble1DArray)
3809 for (
int i = 0; i < m_npoints; ++i)
3811 err =
max(err,
abs(inarray[i] - soln[i]));
3815 m_comm->GetRowComm()->AllReduce(err, LibUtilities::ReduceMax);
3836NekDouble ExpList::v_L2(
const Array<OneD, const NekDouble> &inarray,
3837 const Array<OneD, const NekDouble> &soln)
3842 if (soln == NullNekDouble1DArray)
3844 for (i = 0; i < (*m_exp).size(); ++i)
3846 errl2 = (*m_exp)[i]->L2(inarray + m_phys_offset[i]);
3847 err += errl2 * errl2;
3852 for (i = 0; i < (*m_exp).size(); ++i)
3854 errl2 = (*m_exp)[i]->L2(inarray + m_phys_offset[i],
3855 soln + m_phys_offset[i]);
3856 err += errl2 * errl2;
3860 m_comm->GetRowComm()->AllReduce(err, LibUtilities::ReduceSum);
3881NekDouble ExpList::v_Integral(
const Array<OneD, const NekDouble> &inarray)
3886 for (i = 0; i < (*m_exp).size(); ++i)
3888 sum += (*m_exp)[i]->Integral(inarray + m_phys_offset[i]);
3890 m_comm->GetRowComm()->AllReduce(sum, LibUtilities::ReduceSum);
3896 const Array<OneD, Array<OneD, NekDouble>> &inarray)
3902 for (i = 0; i < (*m_exp).size(); ++i)
3904 Array<OneD, Array<OneD, NekDouble>> tmp(inarray.size());
3905 for (j = 0; j < inarray.size(); ++j)
3907 tmp[j] = Array<OneD, NekDouble>(inarray[j] + m_phys_offset[i]);
3909 flux += (*m_exp)[i]->VectorFlux(tmp);
3915Array<OneD, const NekDouble> ExpList::v_HomogeneousEnergy(
void)
3918 "This method is not defined or valid for this class type");
3919 Array<OneD, NekDouble> NoEnergy(1, 0.0);
3923LibUtilities::TranspositionSharedPtr ExpList::v_GetTransposition(
void)
3926 "This method is not defined or valid for this class type");
3927 LibUtilities::TranspositionSharedPtr trans;
3934 "This method is not defined or valid for this class type");
3939void ExpList::v_SetHomoLen([[maybe_unused]]
const NekDouble lhom)
3942 "This method is not defined or valid for this class type");
3945Array<OneD, const unsigned int> ExpList::v_GetZIDs(
void)
3948 "This method is not defined or valid for this class type");
3949 Array<OneD, unsigned int> NoModes(1);
3953Array<OneD, const unsigned int> ExpList::v_GetYIDs(
void)
3956 "This method is not defined or valid for this class type");
3957 Array<OneD, unsigned int> NoModes(1);
3961void ExpList::v_ClearGlobalLinSysManager(
void)
3964 "ClearGlobalLinSysManager not implemented for ExpList.");
3967int ExpList::v_GetPoolCount([[maybe_unused]] std::string poolName)
3969 NEKERROR(ErrorUtil::efatal,
"GetPoolCount not implemented for ExpList.");
3973void ExpList::v_UnsetGlobalLinSys([[maybe_unused]] GlobalLinSysKey key,
3974 [[maybe_unused]]
bool clearLocalMatrices)
3977 "UnsetGlobalLinSys not implemented for ExpList.");
3980LibUtilities::NekManager<GlobalLinSysKey, GlobalLinSys> &ExpList::
3981 v_GetGlobalLinSysManager(
void)
3984 "GetGlobalLinSysManager not implemented for ExpList.");
3985 return NullGlobalLinSysManager;
3988void ExpList::ExtractCoeffsFromFile(
const std::string &fileName,
3989 LibUtilities::CommSharedPtr comm,
3990 const std::string &varName,
3991 Array<OneD, NekDouble> &coeffs)
3993 string varString = fileName.substr(0, fileName.find_last_of(
"."));
3994 int j, k, len = varString.length();
3995 varString = varString.substr(len - 1, len);
3997 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
3998 std::vector<std::vector<NekDouble>> FieldData;
4000 std::string ft = LibUtilities::FieldIO::GetFileType(fileName, comm);
4001 LibUtilities::FieldIOSharedPtr f =
4002 LibUtilities::GetFieldIOFactory().CreateInstance(
4003 ft, comm, m_session->GetSharedFilesystem());
4005 f->Import(fileName, FieldDef, FieldData);
4008 for (j = 0; j < FieldDef.size(); ++j)
4010 for (k = 0; k < FieldDef[j]->m_fields.size(); ++k)
4012 if (FieldDef[j]->m_fields[k] == varName)
4015 ExtractDataToCoeffs(FieldDef[j], FieldData[j],
4016 FieldDef[j]->m_fields[k], coeffs);
4022 ASSERTL0(found,
"Could not find variable '" + varName +
4023 "' in file boundary condition " + fileName);
4043NekDouble ExpList::H1(
const Array<OneD, const NekDouble> &inarray,
4044 const Array<OneD, const NekDouble> &soln)
4049 for (i = 0; i < (*m_exp).size(); ++i)
4051 errh1 = (*m_exp)[i]->H1(inarray + m_phys_offset[i],
4052 soln + m_phys_offset[i]);
4053 err += errh1 * errh1;
4056 m_comm->GetRowComm()->AllReduce(err, LibUtilities::ReduceSum);
4061void ExpList::GeneralGetFieldDefinitions(
4062 std::vector<LibUtilities::FieldDefinitionsSharedPtr> &fielddef,
4063 int NumHomoDir, Array<OneD, LibUtilities::BasisSharedPtr> &HomoBasis,
4064 std::vector<NekDouble> &HomoLen,
bool homoStrips,
4065 std::vector<unsigned int> &HomoSIDs, std::vector<unsigned int> &HomoZIDs,
4066 std::vector<unsigned int> &HomoYIDs)
4068 int startenum = (int)LibUtilities::eSegment;
4069 int endenum = (int)LibUtilities::eHexahedron;
4071 LibUtilities::ShapeType shape;
4073 ASSERTL1(NumHomoDir == HomoBasis.size(),
4074 "Homogeneous basis is not the same length as NumHomoDir");
4075 ASSERTL1(NumHomoDir == HomoLen.size(),
4076 "Homogeneous length vector is not the same length as NumHomDir");
4079 switch ((*m_exp)[0]->GetShapeDimension())
4082 startenum = (int)LibUtilities::eSegment;
4083 endenum = (int)LibUtilities::eSegment;
4086 startenum = (int)LibUtilities::eTriangle;
4087 endenum = (int)LibUtilities::eQuadrilateral;
4090 startenum = (int)LibUtilities::eTetrahedron;
4091 endenum = (int)LibUtilities::eHexahedron;
4095 for (s = startenum; s <= endenum; ++s)
4097 std::vector<unsigned int> elementIDs;
4098 std::vector<LibUtilities::BasisType> basis;
4099 std::vector<unsigned int> numModes;
4100 std::vector<std::string> fields;
4103 bool UniOrder =
true;
4106 shape = (LibUtilities::ShapeType)s;
4108 for (
int i = 0; i < (*m_exp).size(); ++i)
4110 if ((*m_exp)[i]->GetGeom()->GetShapeType() == shape)
4112 elementIDs.push_back((*m_exp)[i]->GetGeom()->GetGlobalID());
4115 for (
int j = 0; j < (*m_exp)[i]->GetNumBases(); ++j)
4118 (*m_exp)[i]->GetBasis(j)->GetBasisType());
4120 (*m_exp)[i]->GetBasis(j)->GetNumModes());
4124 for (n = 0; n < NumHomoDir; ++n)
4126 basis.push_back(HomoBasis[n]->GetBasisType());
4127 numModes.push_back(HomoBasis[n]->GetNumModes());
4135 (*m_exp)[i]->GetBasis(0)->GetBasisType() == basis[0],
4136 "Routine is not set up for multiple bases definitions");
4138 for (
int j = 0; j < (*m_exp)[i]->GetNumBases(); ++j)
4141 (*m_exp)[i]->GetBasis(j)->GetNumModes());
4143 (*m_exp)[i]->GetBasis(j)->GetNumModes())
4149 for (n = 0; n < NumHomoDir; ++n)
4151 numModes.push_back(HomoBasis[n]->GetNumModes());
4157 if (elementIDs.size() > 0)
4159 LibUtilities::FieldDefinitionsSharedPtr fdef =
4160 MemoryManager<LibUtilities::FieldDefinitions>::
4161 AllocateSharedPtr(shape, elementIDs, basis, UniOrder,
4162 numModes, fields, NumHomoDir, HomoLen,
4163 homoStrips, HomoSIDs, HomoZIDs, HomoYIDs);
4164 fielddef.push_back(fdef);
4172std::vector<LibUtilities::FieldDefinitionsSharedPtr> ExpList::
4173 v_GetFieldDefinitions()
4175 std::vector<LibUtilities::FieldDefinitionsSharedPtr> returnval;
4176 v_GetFieldDefinitions(returnval);
4180void ExpList::v_GetFieldDefinitions(
4181 std::vector<LibUtilities::FieldDefinitionsSharedPtr> &fielddef)
4183 GeneralGetFieldDefinitions(fielddef);
4188void ExpList::v_AppendFieldData(
4189 LibUtilities::FieldDefinitionsSharedPtr &fielddef,
4190 std::vector<NekDouble> &fielddata)
4192 v_AppendFieldData(fielddef, fielddata, m_coeffs);
4195void ExpList::v_AppendFieldData(
4196 LibUtilities::FieldDefinitionsSharedPtr &fielddef,
4197 std::vector<NekDouble> &fielddata, Array<OneD, NekDouble> &coeffs)
4204 map<int, int> ElmtID_to_ExpID;
4205 for (i = 0; i < (*m_exp).size(); ++i)
4207 ElmtID_to_ExpID[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
4210 for (i = 0; i < fielddef->m_elementIDs.size(); ++i)
4212 int eid = ElmtID_to_ExpID[fielddef->m_elementIDs[i]];
4213 int datalen = (*m_exp)[eid]->GetNcoeffs();
4214 if ((*m_exp)[eid]->IsNodalNonTensorialExp())
4217 Array<OneD, NekDouble> orthocoeffs((*m_exp)[eid]->GetNcoeffs());
4218 (*m_exp)[eid]->NodalToModal(coeffs + m_coeff_offset[eid],
4220 fielddata.insert(fielddata.end(), &orthocoeffs[0],
4221 &orthocoeffs[0] + datalen);
4225 fielddata.insert(fielddata.end(), &coeffs[m_coeff_offset[eid]],
4226 &coeffs[m_coeff_offset[eid]] + datalen);
4232void ExpList::ExtractDataToCoeffs(
4233 LibUtilities::FieldDefinitionsSharedPtr &fielddef,
4234 std::vector<NekDouble> &fielddata, std::string &field,
4235 Array<OneD, NekDouble> &coeffs, std::unordered_map<int, int> zIdToPlane)
4237 v_ExtractDataToCoeffs(fielddef, fielddata, field, coeffs, zIdToPlane);
4240void ExpList::ExtractCoeffsToCoeffs(
4241 const std::shared_ptr<ExpList> &fromExpList,
4242 const Array<OneD, const NekDouble> &fromCoeffs,
4243 Array<OneD, NekDouble> &toCoeffs)
4245 v_ExtractCoeffsToCoeffs(fromExpList, fromCoeffs, toCoeffs);
4256void ExpList::v_ExtractDataToCoeffs(
4257 LibUtilities::FieldDefinitionsSharedPtr &fielddef,
4258 std::vector<NekDouble> &fielddata, std::string &field,
4259 Array<OneD, NekDouble> &coeffs,
4260 [[maybe_unused]] std::unordered_map<int, int> zIdToPlane)
4264 int modes_offset = 0;
4265 int datalen = fielddata.size() / fielddef->m_fields.size();
4268 for (i = 0; i < fielddef->m_fields.size(); ++i)
4270 if (fielddef->m_fields[i] == field)
4277 ASSERTL0(i != fielddef->m_fields.size(),
4278 "Field (" + field +
") not found in file.");
4280 if (m_elmtToExpId.size() == 0)
4285 for (i = (*m_exp).size() - 1; i >= 0; --i)
4287 m_elmtToExpId[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
4291 for (i = 0; i < fielddef->m_elementIDs.size(); ++i)
4295 if (fielddef->m_uniOrder ==
true)
4300 datalen = LibUtilities::GetNumberOfCoefficients(
4301 fielddef->m_shapeType, fielddef->m_numModes, modes_offset);
4303 const int elmtId = fielddef->m_elementIDs[i];
4304 auto eIt = m_elmtToExpId.find(elmtId);
4306 if (eIt == m_elmtToExpId.end())
4309 modes_offset += (*m_exp)[0]->GetNumBases();
4313 expId = eIt->second;
4315 bool sameBasis =
true;
4316 for (
int j = 0; j < fielddef->m_basis.size(); ++j)
4318 if (fielddef->m_basis[j] != (*m_exp)[expId]->GetBasisType(j))
4325 if (datalen == (*m_exp)[expId]->GetNcoeffs() && sameBasis)
4328 &coeffs[m_coeff_offset[expId]], 1);
4332 (*m_exp)[expId]->ExtractDataToCoeffs(
4333 &fielddata[offset], fielddef->m_numModes, modes_offset,
4334 &coeffs[m_coeff_offset[expId]], fielddef->m_basis);
4338 modes_offset += (*m_exp)[0]->GetNumBases();
4344void ExpList::v_ExtractCoeffsToCoeffs(
4345 const std::shared_ptr<ExpList> &fromExpList,
4346 const Array<OneD, const NekDouble> &fromCoeffs,
4347 Array<OneD, NekDouble> &toCoeffs)
4352 map<int, int> GidToEid;
4354 for (i = 0; i < (*m_exp).size(); ++i)
4356 GidToEid[fromExpList->GetExp(i)->GetGeom()->GetGlobalID()] = i;
4359 for (i = 0; i < (*m_exp).size(); ++i)
4361 std::vector<unsigned int> nummodes;
4362 vector<LibUtilities::BasisType> basisTypes;
4364 int eid = GidToEid[(*m_exp)[i]->GetGeom()->GetGlobalID()];
4365 for (
int j = 0; j < fromExpList->GetExp(eid)->GetNumBases(); ++j)
4367 nummodes.push_back(fromExpList->GetExp(eid)->GetBasisNumModes(j));
4368 basisTypes.push_back(fromExpList->GetExp(eid)->GetBasisType(j));
4371 offset = fromExpList->GetCoeff_Offset(eid);
4372 (*m_exp)[i]->ExtractDataToCoeffs(&fromCoeffs[offset], nummodes, 0,
4373 &toCoeffs[m_coeff_offset[i]],
4381void ExpList::GetBwdWeight(Array<OneD, NekDouble> &weightAver,
4382 Array<OneD, NekDouble> &weightJump)
4384 size_t nTracePts = weightAver.size();
4386 for (
int i = 0; i < nTracePts; ++i)
4388 weightAver[i] = 0.5;
4389 weightJump[i] = 1.0;
4391 FillBwdWithBwdWeight(weightAver, weightJump);
4394void ExpList::v_GetMovingFrames(
const SpatialDomains::GeomMMF MMFdir,
4395 const Array<OneD, const NekDouble> &CircCentre,
4396 Array<OneD, Array<OneD, NekDouble>> &outarray)
4401 int nq = outarray[0].size() / MFdim;
4404 int coordim = (*m_exp)[0]->GetGeom()->GetCoordim();
4406 Array<OneD, Array<OneD, NekDouble>> MFloc(MFdim * coordim);
4408 for (
int i = 0; i < m_exp->size(); ++i)
4410 npts = (*m_exp)[i]->GetTotPoints();
4412 for (
int j = 0; j < MFdim * coordim; ++j)
4414 MFloc[j] = Array<OneD, NekDouble>(npts, 0.0);
4418 (*m_exp)[i]->GetGeomFactors()->GetMovingFrames(
4419 (*m_exp)[i]->GetPointsKeys(), MMFdir, CircCentre, MFloc);
4422 for (
int j = 0; j < MFdim; ++j)
4424 for (
int k = 0; k < coordim; ++k)
4427 &outarray[j][k * nq + m_phys_offset[i]], 1);
4438void ExpList::GenerateElementVector(
const int ElementID,
4439 const NekDouble scalar1,
4440 const NekDouble scalar2,
4441 Array<OneD, NekDouble> &outarray)
4446 Array<OneD, NekDouble> outarray_e;
4448 for (
int i = 0; i < (*m_exp).size(); ++i)
4450 npoints_e = (*m_exp)[i]->GetTotPoints();
4461 outarray_e = Array<OneD, NekDouble>(npoints_e, coeff);
4462 Vmath::Vcopy(npoints_e, &outarray_e[0], 1, &outarray[m_phys_offset[i]],
4467const Array<OneD, const std::shared_ptr<ExpList>> &ExpList::
4468 v_GetBndCondExpansions(
void)
4471 "This method is not defined or valid for this class type");
4472 static Array<OneD, const std::shared_ptr<ExpList>> result;
4476std::shared_ptr<ExpList> &ExpList::v_UpdateBndCondExpansion(
4477 [[maybe_unused]]
int i)
4480 "This method is not defined or valid for this class type");
4481 static std::shared_ptr<ExpList> result;
4495void ExpList::v_Upwind(
const Array<OneD,
const Array<OneD, NekDouble>> &Vec,
4496 const Array<OneD, const NekDouble> &Fwd,
4497 const Array<OneD, const NekDouble> &Bwd,
4498 Array<OneD, NekDouble> &Upwind)
4504 int i, j, k, e_npoints, offset;
4505 Array<OneD, NekDouble> normals;
4509 int coordim = GetCoordim(0);
4512 "Input vector does not have sufficient dimensions to "
4516 for (i = 0; i < m_exp->size(); ++i)
4519 e_npoints = (*m_exp)[i]->GetNumPoints(0);
4520 normals = (*m_exp)[i]->GetPhysNormals();
4523 offset = m_phys_offset[i];
4526 for (j = 0; j < e_npoints; ++j)
4530 for (k = 0; k < coordim; ++k)
4532 Vn += Vec[k][offset + j] * normals[k * e_npoints + j];
4538 Upwind[offset + j] = Fwd[offset + j];
4542 Upwind[offset + j] = Bwd[offset + j];
4550 "This method is not defined or valid for this class type");
4568void ExpList::v_Upwind(
const Array<OneD, const NekDouble> &Vn,
4569 const Array<OneD, const NekDouble> &Fwd,
4570 const Array<OneD, const NekDouble> &Bwd,
4571 Array<OneD, NekDouble> &Upwind)
4573 ASSERTL1(Vn.size() >= m_npoints,
"Vn is not of sufficient length");
4574 ASSERTL1(Fwd.size() >= m_npoints,
"Fwd is not of sufficient length");
4575 ASSERTL1(Bwd.size() >= m_npoints,
"Bwd is not of sufficient length");
4576 ASSERTL1(Upwind.size() >= m_npoints,
"Upwind is not of sufficient length");
4579 for (
int j = 0; j < m_npoints; ++j)
4593std::shared_ptr<ExpList> &ExpList::v_GetTrace()
4596 "This method is not defined or valid for this class type");
4597 static std::shared_ptr<ExpList> returnVal;
4601std::shared_ptr<AssemblyMapDG> &ExpList::v_GetTraceMap()
4604 "This method is not defined or valid for this class type");
4605 static std::shared_ptr<AssemblyMapDG> result;
4609std::shared_ptr<InterfaceMapDG> &ExpList::v_GetInterfaceMap()
4612 "This method is not defined or valid for this class type");
4613 static std::shared_ptr<InterfaceMapDG> result;
4617const Array<OneD, const int> &ExpList::v_GetTraceBndMap()
4619 return GetTraceMap()->GetBndCondIDToGlobalTraceID();
4622std::vector<bool> &ExpList::v_GetLeftAdjacentTraces()
4625 "This method is not defined or valid for this class type");
4626 static std::vector<bool> result;
4633void AlignFace(
const StdRegions::Orientation orient,
const int nquad1,
4634 const int nquad2,
const Array<OneD, const NekDouble> &in,
4635 Array<OneD, NekDouble> &out)
4638 if (orient == StdRegions::eDir1FwdDir2_Dir2FwdDir1 ||
4639 orient == StdRegions::eDir1BwdDir2_Dir2FwdDir1 ||
4640 orient == StdRegions::eDir1FwdDir2_Dir2BwdDir1 ||
4641 orient == StdRegions::eDir1BwdDir2_Dir2BwdDir1)
4643 for (
int i = 0; i < nquad2; ++i)
4645 for (
int j = 0; j < nquad1; ++j)
4647 out[i * nquad1 + j] = in[j * nquad2 + i];
4653 for (
int i = 0; i < nquad2; ++i)
4655 for (
int j = 0; j < nquad1; ++j)
4657 out[i * nquad1 + j] = in[i * nquad1 + j];
4662 if (orient == StdRegions::eDir1BwdDir1_Dir2FwdDir2 ||
4663 orient == StdRegions::eDir1BwdDir1_Dir2BwdDir2 ||
4664 orient == StdRegions::eDir1BwdDir2_Dir2FwdDir1 ||
4665 orient == StdRegions::eDir1BwdDir2_Dir2BwdDir1)
4668 for (
int i = 0; i < nquad2; ++i)
4670 for (
int j = 0; j < nquad1 / 2; ++j)
4672 swap(out[i * nquad1 + j], out[i * nquad1 + nquad1 - j - 1]);
4677 if (orient == StdRegions::eDir1FwdDir1_Dir2BwdDir2 ||
4678 orient == StdRegions::eDir1BwdDir1_Dir2BwdDir2 ||
4679 orient == StdRegions::eDir1FwdDir2_Dir2BwdDir1 ||
4680 orient == StdRegions::eDir1BwdDir2_Dir2BwdDir1)
4683 for (
int j = 0; j < nquad1; ++j)
4685 for (
int i = 0; i < nquad2 / 2; ++i)
4687 swap(out[i * nquad1 + j], out[(nquad2 - i - 1) * nquad1 + j]);
4702void ExpList::v_GetNormals(Array<OneD, Array<OneD, NekDouble>> &normals)
4704 int i, j, k, e_npoints, offset;
4705 Array<OneD, Array<OneD, NekDouble>> locnormals;
4708 int coordim = GetCoordim(0);
4710 ASSERTL1(normals.size() >= coordim,
4711 "Output vector does not have sufficient dimensions to "
4719 for (i = 0; i < m_exp->size(); ++i)
4721 LocalRegions::ExpansionSharedPtr loc_exp = (*m_exp)[i];
4723 LocalRegions::ExpansionSharedPtr loc_elmt =
4724 loc_exp->GetLeftAdjacentElementExp();
4728 locnormals = loc_elmt->GetTraceNormal(
4729 loc_exp->GetLeftAdjacentElementTrace());
4732 offset = m_phys_offset[i];
4735 for (j = 0; j < e_npoints; ++j)
4739 for (k = 0; k < coordim; ++k)
4741 normals[k][offset] = locnormals[k][0];
4750 for (i = 0; i < m_exp->size(); ++i)
4752 LocalRegions::ExpansionSharedPtr traceExp = (*m_exp)[i];
4754 int offset = m_phys_offset[i];
4757 LocalRegions::ExpansionSharedPtr exp2D =
4758 traceExp->GetLeftAdjacentElementExp();
4759 int edgeId = traceExp->GetLeftAdjacentElementTrace();
4760 LibUtilities::PointsKey edgePoints =
4761 exp2D->GetTraceBasisKey(edgeId).GetPointsKey();
4762 LibUtilities::PointsKey tracePoints =
4763 traceExp->GetBasis(0)->GetPointsKey();
4770 bool useRight =
false;
4771 if (traceExp->GetRightAdjacentElementTrace() >= 0)
4773 LocalRegions::ExpansionSharedPtr Rexp2D =
4774 traceExp->GetRightAdjacentElementExp();
4775 int RedgeId = traceExp->GetRightAdjacentElementTrace();
4776 LibUtilities::PointsKey RedgePoints =
4777 Rexp2D->GetTraceBasisKey(RedgeId).GetPointsKey();
4779 if (RedgePoints.GetNumPoints() > edgePoints.GetNumPoints())
4783 edgePoints = RedgePoints;
4788 const Array<OneD, const Array<OneD, NekDouble>> &locNormals =
4789 exp2D->GetTraceNormal(edgeId);
4794 for (
int d = 0;
d < coordim; ++
d)
4796 LibUtilities::Interp1D(edgePoints, locNormals[d].data(),
4798 normals[d].data() + offset);
4804 &normals[d][offset], 1);
4812 Array<OneD, NekDouble> tmp;
4815 for (i = 0; i < m_exp->size(); ++i)
4817 LocalRegions::ExpansionSharedPtr traceExp = (*m_exp)[i];
4819 int offset = m_phys_offset[i];
4835 LocalRegions::ExpansionSharedPtr exp3D =
4836 traceExp->GetLeftAdjacentElementExp();
4837 int faceId = traceExp->GetLeftAdjacentElementTrace();
4838 const Array<OneD, const Array<OneD, NekDouble>> &locNormals =
4839 exp3D->GetTraceNormal(faceId);
4841 StdRegions::Orientation orient = exp3D->GetTraceOrient(faceId);
4845 int fromid0, fromid1;
4847 if (orient < StdRegions::eDir1FwdDir2_Dir2FwdDir1)
4858 LibUtilities::BasisKey faceBasis0 =
4859 exp3D->GetTraceBasisKey(faceId, fromid0);
4860 LibUtilities::BasisKey faceBasis1 =
4861 exp3D->GetTraceBasisKey(faceId, fromid1);
4862 LibUtilities::BasisKey traceBasis0 =
4863 traceExp->GetBasis(0)->GetBasisKey();
4864 LibUtilities::BasisKey traceBasis1 =
4865 traceExp->GetBasis(1)->GetBasisKey();
4867 const int faceNq0 = faceBasis0.GetNumPoints();
4868 const int faceNq1 = faceBasis1.GetNumPoints();
4873 Array<OneD, int> map;
4874 exp3D->ReOrientTracePhysMap(orient, map, faceNq0, faceNq1);
4877 Array<OneD, NekDouble> traceNormals(faceNq0 * faceNq1);
4878 for (j = 0; j < coordim; ++j)
4883 LibUtilities::Interp2D(
4884 faceBasis0.GetPointsKey(), faceBasis1.GetPointsKey(),
4885 traceNormals, traceBasis0.GetPointsKey(),
4886 traceBasis1.GetPointsKey(), tmp = normals[j] + offset);
4894 "This method is not defined or valid for this class type");
4911void ExpList::GetElmtNormalLength(Array<OneD, NekDouble> &lengthsFwd,
4912 Array<OneD, NekDouble> &lengthsBwd)
4916 Array<OneD, NekDouble> locLeng;
4917 Array<OneD, Array<OneD, NekDouble>> lengintp(2);
4918 Array<OneD, Array<OneD, NekDouble>> lengAdd(2);
4919 Array<OneD, int> LRbndnumbs(2);
4920 Array<OneD, Array<OneD, NekDouble>> lengLR(2);
4921 lengLR[0] = lengthsFwd;
4922 lengLR[1] = lengthsBwd;
4923 Array<OneD, LocalRegions::ExpansionSharedPtr> LRelmts(2);
4924 LocalRegions::ExpansionSharedPtr loc_elmt;
4925 LocalRegions::ExpansionSharedPtr loc_exp;
4926 int e_npoints0 = -1;
4927 if (m_expType == e1D)
4929 for (
int i = 0; i < m_exp->size(); ++i)
4931 loc_exp = (*m_exp)[i];
4932 int offset = m_phys_offset[i];
4934 e_npoints = (*m_exp)[i]->GetNumPoints(0);
4935 if (e_npoints0 < e_npoints)
4937 for (
int nlr = 0; nlr < 2; nlr++)
4939 lengintp[nlr] = Array<OneD, NekDouble>(e_npoints, 0.0);
4941 e_npoints0 = e_npoints;
4944 LRelmts[0] = loc_exp->GetLeftAdjacentElementExp();
4945 LRelmts[1] = loc_exp->GetRightAdjacentElementExp();
4947 LRbndnumbs[0] = loc_exp->GetLeftAdjacentElementTrace();
4948 LRbndnumbs[1] = loc_exp->GetRightAdjacentElementTrace();
4949 for (
int nlr = 0; nlr < 2; ++nlr)
4952 lengAdd[nlr] = lengintp[nlr];
4953 int bndNumber = LRbndnumbs[nlr];
4954 loc_elmt = LRelmts[nlr];
4957 locLeng = loc_elmt->GetElmtBndNormDirElmtLen(bndNumber);
4959 LibUtilities::PointsKey to_key =
4960 loc_exp->GetBasis(0)->GetPointsKey();
4961 LibUtilities::PointsKey from_key =
4962 loc_elmt->GetTraceBasisKey(bndNumber).GetPointsKey();
4969 LibUtilities::Interp1D(from_key, locLeng, to_key,
4971 lengAdd[nlr] = lengintp[nlr];
4974 for (
int j = 0; j < e_npoints; ++j)
4976 lengLR[nlr][offset + j] = lengAdd[nlr][j];
4981 else if (m_expType == e2D)
4983 for (
int i = 0; i < m_exp->size(); ++i)
4985 loc_exp = (*m_exp)[i];
4986 int offset = m_phys_offset[i];
4988 LibUtilities::BasisKey traceBasis0 =
4989 loc_exp->GetBasis(0)->GetBasisKey();
4990 LibUtilities::BasisKey traceBasis1 =
4991 loc_exp->GetBasis(1)->GetBasisKey();
4992 const int TraceNq0 = traceBasis0.GetNumPoints();
4993 const int TraceNq1 = traceBasis1.GetNumPoints();
4994 e_npoints = TraceNq0 * TraceNq1;
4995 if (e_npoints0 < e_npoints)
4997 for (
int nlr = 0; nlr < 2; nlr++)
4999 lengintp[nlr] = Array<OneD, NekDouble>(e_npoints, 0.0);
5001 e_npoints0 = e_npoints;
5004 LRelmts[0] = loc_exp->GetLeftAdjacentElementExp();
5005 LRelmts[1] = loc_exp->GetRightAdjacentElementExp();
5007 LRbndnumbs[0] = loc_exp->GetLeftAdjacentElementTrace();
5008 LRbndnumbs[1] = loc_exp->GetRightAdjacentElementTrace();
5009 for (
int nlr = 0; nlr < 2; ++nlr)
5012 int bndNumber = LRbndnumbs[nlr];
5013 loc_elmt = LRelmts[nlr];
5016 locLeng = loc_elmt->GetElmtBndNormDirElmtLen(bndNumber);
5019 StdRegions::Orientation orient =
5020 loc_elmt->GetTraceOrient(bndNumber);
5022 int fromid0, fromid1;
5023 if (orient < StdRegions::eDir1FwdDir2_Dir2FwdDir1)
5034 LibUtilities::BasisKey faceBasis0 =
5035 loc_elmt->GetTraceBasisKey(bndNumber, fromid0);
5036 LibUtilities::BasisKey faceBasis1 =
5037 loc_elmt->GetTraceBasisKey(bndNumber, fromid1);
5038 const int faceNq0 = faceBasis0.GetNumPoints();
5039 const int faceNq1 = faceBasis1.GetNumPoints();
5040 Array<OneD, NekDouble> alignedLeng(faceNq0 * faceNq1);
5042 AlignFace(orient, faceNq0, faceNq1, locLeng, alignedLeng);
5043 LibUtilities::Interp2D(
5044 faceBasis0.GetPointsKey(), faceBasis1.GetPointsKey(),
5045 alignedLeng, traceBasis0.GetPointsKey(),
5046 traceBasis1.GetPointsKey(), lengintp[nlr]);
5049 for (
int j = 0; j < e_npoints; ++j)
5051 lengLR[nlr][offset + j] = lengintp[nlr][j];
5058void ExpList::v_AddTraceIntegral(
5059 [[maybe_unused]]
const Array<OneD, const NekDouble> &Fn,
5060 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5063 "This method is not defined or valid for this class type");
5066void ExpList::v_AddFwdBwdTraceIntegral(
5067 [[maybe_unused]]
const Array<OneD, const NekDouble> &Fwd,
5068 [[maybe_unused]]
const Array<OneD, const NekDouble> &Bwd,
5069 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5072 "This method is not defined or valid for this class type");
5075void ExpList::v_GetFwdBwdTracePhys([[maybe_unused]] Array<OneD, NekDouble> &Fwd,
5076 [[maybe_unused]] Array<OneD, NekDouble> &Bwd)
5079 "This method is not defined or valid for this class type");
5082void ExpList::v_GetFwdBwdTracePhys(
5083 [[maybe_unused]]
const Array<OneD, const NekDouble> &field,
5084 [[maybe_unused]] Array<OneD, NekDouble> &Fwd,
5085 [[maybe_unused]] Array<OneD, NekDouble> &Bwd, [[maybe_unused]]
bool FillBnd,
5086 [[maybe_unused]]
bool PutFwdInBwdOnBCs, [[maybe_unused]]
bool DoExchange)
5089 "This method is not defined or valid for this class type");
5092void ExpList::v_FillBwdWithBoundCond(
5093 [[maybe_unused]]
const Array<OneD, NekDouble> &Fwd,
5094 [[maybe_unused]] Array<OneD, NekDouble> &Bwd,
5095 [[maybe_unused]]
bool PutFwdInBwdOnBCs)
5098 "This method is not defined or valid for this class type");
5101void ExpList::v_AddTraceQuadPhysToField(
5102 [[maybe_unused]]
const Array<OneD, const NekDouble> &Fwd,
5103 [[maybe_unused]]
const Array<OneD, const NekDouble> &Bwd,
5104 [[maybe_unused]] Array<OneD, NekDouble> &field)
5107 "v_AddTraceQuadPhysToField is not defined for this class type");
5110void ExpList::v_AddTraceQuadPhysToOffDiag(
5111 [[maybe_unused]]
const Array<OneD, const NekDouble> &Fwd,
5112 [[maybe_unused]]
const Array<OneD, const NekDouble> &Bwd,
5113 [[maybe_unused]] Array<OneD, NekDouble> &field)
5116 "v_AddTraceQuadPhysToOffDiag is not defined for this class");
5119void ExpList::v_GetLocTraceFromTracePts(
5120 [[maybe_unused]]
const Array<OneD, const NekDouble> &Fwd,
5121 [[maybe_unused]]
const Array<OneD, const NekDouble> &Bwd,
5122 [[maybe_unused]] Array<OneD, NekDouble> &locTraceFwd,
5123 [[maybe_unused]] Array<OneD, NekDouble> &locTraceBwd)
5126 "v_GetLocTraceFromTracePts is not defined for this class");
5129const Array<OneD, const NekDouble> &ExpList::v_GetBndCondBwdWeight()
5132 "v_GetBndCondBwdWeight is not defined for this class type");
5133 static Array<OneD, NekDouble> tmp;
5137void ExpList::v_SetBndCondBwdWeight([[maybe_unused]]
const int index,
5138 [[maybe_unused]]
const NekDouble value)
5141 "v_setBndCondBwdWeight is not defined for this class type");
5144const vector<bool> &ExpList::v_GetLeftAdjacentFaces(
void)
const
5147 "This method is not defined or valid for this class type");
5148 static vector<bool> tmp;
5152void ExpList::v_ExtractTracePhys(
5153 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5156 "This method is not defined or valid for this class type");
5159void ExpList::v_ExtractTracePhys(
5160 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5161 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5162 [[maybe_unused]]
bool gridVelocity)
5165 "This method is not defined or valid for this class type");
5168void ExpList::v_MultiplyByInvMassMatrix(
5169 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5170 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5173 "This method is not defined or valid for this class type");
5176GlobalLinSysKey ExpList::v_HelmSolve(
5177 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5178 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5179 [[maybe_unused]]
const StdRegions::ConstFactorMap &factors,
5180 [[maybe_unused]]
const StdRegions::VarCoeffMap &varcoeff,
5181 [[maybe_unused]]
const StdRegions::VarFactorsMap &varfactors,
5182 [[maybe_unused]]
const Array<OneD, const NekDouble> &dirForcing,
5183 [[maybe_unused]]
const bool PhysSpaceForcing)
5185 NEKERROR(ErrorUtil::efatal,
"HelmSolve not implemented.");
5186 return NullGlobalLinSysKey;
5189GlobalLinSysKey ExpList::v_LinearAdvectionDiffusionReactionSolve(
5190 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5191 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5192 [[maybe_unused]]
const StdRegions::ConstFactorMap &factors,
5193 [[maybe_unused]]
const StdRegions::VarCoeffMap &varcoeff,
5194 [[maybe_unused]]
const StdRegions::VarFactorsMap &varfactors,
5195 [[maybe_unused]]
const Array<OneD, const NekDouble> &dirForcing,
5196 [[maybe_unused]]
const bool PhysSpaceForcing)
5199 "LinearAdvectionDiffusionReactionSolve not implemented.");
5200 return NullGlobalLinSysKey;
5203GlobalLinSysKey ExpList::v_LinearAdvectionReactionSolve(
5204 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5205 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5206 [[maybe_unused]]
const StdRegions::ConstFactorMap &factors,
5207 [[maybe_unused]]
const StdRegions::VarCoeffMap &varcoeff,
5208 [[maybe_unused]]
const StdRegions::VarFactorsMap &varfactors,
5209 [[maybe_unused]]
const Array<OneD, const NekDouble> &dirForcing,
5210 [[maybe_unused]]
const bool PhysSpaceForcing)
5213 "LinearAdvectionReactionSolve not implemented.");
5214 return NullGlobalLinSysKey;
5217void ExpList::v_HomogeneousFwdTrans(
5218 [[maybe_unused]]
const int npts,
5219 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5220 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5221 [[maybe_unused]]
bool Shuff, [[maybe_unused]]
bool UnShuff)
5224 "This method is not defined or valid for this class type");
5227void ExpList::v_HomogeneousBwdTrans(
5228 [[maybe_unused]]
const int npts,
5229 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5230 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5231 [[maybe_unused]]
bool Shuff, [[maybe_unused]]
bool UnShuff)
5234 "This method is not defined or valid for this class type");
5237void ExpList::v_DealiasedProd(
5238 [[maybe_unused]]
const int npts,
5239 [[maybe_unused]]
const Array<OneD, NekDouble> &inarray1,
5240 [[maybe_unused]]
const Array<OneD, NekDouble> &inarray2,
5241 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5244 "This method is not defined or valid for this class type");
5247void ExpList::v_DealiasedDotProd(
5248 [[maybe_unused]]
const int npts,
5249 [[maybe_unused]]
const Array<OneD, Array<OneD, NekDouble>> &inarray1,
5250 [[maybe_unused]]
const Array<OneD, Array<OneD, NekDouble>> &inarray2,
5251 [[maybe_unused]] Array<OneD, Array<OneD, NekDouble>> &outarray)
5254 "This method is not defined or valid for this class type");
5257void ExpList::v_GetBCValues(
5258 [[maybe_unused]] Array<OneD, NekDouble> &BndVals,
5259 [[maybe_unused]]
const Array<OneD, NekDouble> &TotField,
5260 [[maybe_unused]]
int BndID)
5263 "This method is not defined or valid for this class type");
5266void ExpList::v_NormVectorIProductWRTBase(
5267 [[maybe_unused]] Array<OneD, const NekDouble> &V1,
5268 [[maybe_unused]] Array<OneD, const NekDouble> &V2,
5269 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5270 [[maybe_unused]]
int BndID)
5273 "This method is not defined or valid for this class type");
5276void ExpList::v_NormVectorIProductWRTBase(
5277 Array<OneD, Array<OneD, NekDouble>> &V, Array<OneD, NekDouble> &outarray)
5279 Array<OneD, NekDouble> tmp;
5280 switch (GetCoordim(0))
5284 for (
int i = 0; i < GetExpSize(); ++i)
5286 (*m_exp)[i]->NormVectorIProductWRTBase(
5287 V[0] + GetPhys_Offset(i),
5288 tmp = outarray + GetCoeff_Offset(i));
5294 for (
int i = 0; i < GetExpSize(); ++i)
5296 (*m_exp)[i]->NormVectorIProductWRTBase(
5297 V[0] + GetPhys_Offset(i), V[1] + GetPhys_Offset(i),
5298 tmp = outarray + GetCoeff_Offset(i));
5304 for (
int i = 0; i < GetExpSize(); ++i)
5306 (*m_exp)[i]->NormVectorIProductWRTBase(
5307 V[0] + GetPhys_Offset(i), V[1] + GetPhys_Offset(i),
5308 V[2] + GetPhys_Offset(i),
5309 tmp = outarray + GetCoeff_Offset(i));
5314 NEKERROR(ErrorUtil::efatal,
"Dimension not supported");
5319void ExpList::v_ImposeDirichletConditions(
5320 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5323 "This method is not defined or valid for this class type");
5326void ExpList::v_ImposeNeumannConditions(
5327 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5330 "This method is not defined or valid for this class type");
5333void ExpList::v_ImposeRobinConditions(
5334 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5337 "This method is not defined or valid for this class type");
5342void ExpList::v_FillBndCondFromField(
5343 [[maybe_unused]]
const Array<OneD, NekDouble> coeffs)
5346 "This method is not defined or valid for this class type");
5351void ExpList::v_FillBndCondFromField(
5352 [[maybe_unused]]
const int nreg,
5353 [[maybe_unused]]
const Array<OneD, NekDouble> coeffs)
5356 "This method is not defined or valid for this class type");
5359void ExpList::v_AvgAssemble([[maybe_unused]]
bool useComm)
5361 v_AvgAssemble(m_coeffs, m_coeffs, useComm);
5364void ExpList::v_AvgAssemble(
5365 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5366 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5367 [[maybe_unused]]
bool useComm)
5370 "This method is not defined or valid for this class type");
5373void ExpList::v_LocalToGlobal([[maybe_unused]]
bool useComm)
5376 "This method is not defined or valid for this class type");
5379void ExpList::v_LocalToGlobal(
5380 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5381 [[maybe_unused]] Array<OneD, NekDouble> &outarray,
5382 [[maybe_unused]]
bool useComm)
5385 "This method is not defined or valid for this class type");
5388void ExpList::v_GlobalToLocal(
void)
5391 "This method is not defined or valid for this class type");
5394void ExpList::v_GlobalToLocal(
5395 [[maybe_unused]]
const Array<OneD, const NekDouble> &inarray,
5396 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
5399 "This method is not defined or valid for this class type");
5402void ExpList::v_FwdTrans(
const Array<OneD, const NekDouble> &inarray,
5403 Array<OneD, NekDouble> &outarray)
5405 v_FwdTransLocalElmt(inarray, outarray);
5419void ExpList::v_IProductWRTBase(
const Array<OneD, const NekDouble> &inarray,
5420 Array<OneD, NekDouble> &outarray)
5422 LibUtilities::Timer timer;
5425 if (m_collectionsDoInit[Collections::eIProductWRTBase])
5427 for (
int i = 0; i < m_collections.size(); ++i)
5429 m_collections[i].Initialise(Collections::eIProductWRTBase);
5431 m_collectionsDoInit[Collections::eIProductWRTBase] =
false;
5434 Array<OneD, NekDouble> tmp;
5435 int input_offset{0};
5436 int output_offset{0};
5437 for (
int i = 0; i < m_collections.size(); ++i)
5439 m_collections[i].ApplyOperator(Collections::eIProductWRTBase,
5440 inarray + input_offset,
5441 tmp = outarray + output_offset);
5443 m_collections[i].GetInputSize(Collections::eIProductWRTBase);
5445 m_collections[i].GetOutputSize(Collections::eIProductWRTBase);
5449 timer.AccumulateRegion(
"Collections:IProductWRTBase", 10);
5463void ExpList::v_GetCoords(Array<OneD, NekDouble> &coord_0,
5464 Array<OneD, NekDouble> &coord_1,
5465 Array<OneD, NekDouble> &coord_2)
5467 if (GetNumElmts() == 0)
5473 Array<OneD, NekDouble> e_coord_0;
5474 Array<OneD, NekDouble> e_coord_1;
5475 Array<OneD, NekDouble> e_coord_2;
5477 switch (GetExp(0)->GetCoordim())
5480 for (i = 0; i < (*m_exp).size(); ++i)
5482 e_coord_0 = coord_0 + m_phys_offset[i];
5483 (*m_exp)[i]->GetCoords(e_coord_0);
5487 ASSERTL0(coord_1.size() != 0,
"output coord_1 is not defined");
5489 for (i = 0; i < (*m_exp).size(); ++i)
5491 e_coord_0 = coord_0 + m_phys_offset[i];
5492 e_coord_1 = coord_1 + m_phys_offset[i];
5493 (*m_exp)[i]->GetCoords(e_coord_0, e_coord_1);
5497 ASSERTL0(coord_1.size() != 0,
"output coord_1 is not defined");
5498 ASSERTL0(coord_2.size() != 0,
"output coord_2 is not defined");
5500 for (i = 0; i < (*m_exp).size(); ++i)
5502 e_coord_0 = coord_0 + m_phys_offset[i];
5503 e_coord_1 = coord_1 + m_phys_offset[i];
5504 e_coord_2 = coord_2 + m_phys_offset[i];
5505 (*m_exp)[i]->GetCoords(e_coord_0, e_coord_1, e_coord_2);
5511void ExpList::v_GetCoords(
const int eid, Array<OneD, NekDouble> &xc0,
5512 Array<OneD, NekDouble> &xc1,
5513 Array<OneD, NekDouble> &xc2)
5515 (*m_exp)[eid]->GetCoords(xc0, xc1, xc2);
5523void ExpList::v_SetUpPhysNormals()
5525 for (
int i = 0; i < m_exp->size(); ++i)
5527 for (
int j = 0; j < (*m_exp)[i]->GetNtraces(); ++j)
5529 (*m_exp)[i]->ComputeTraceNormal(j);
5536void ExpList::v_GetBndElmtExpansion(
5537 [[maybe_unused]]
int i, [[maybe_unused]] std::shared_ptr<ExpList> &result,
5538 [[maybe_unused]]
const bool DeclareCoeffPhysArrays)
5541 "This method is not defined or valid for this class type");
5546void ExpList::v_ExtractElmtToBndPhys(
const int i,
5547 const Array<OneD, NekDouble> &element,
5548 Array<OneD, NekDouble> &boundary)
5551 Array<OneD, NekDouble> tmp1, tmp2;
5552 LocalRegions::ExpansionSharedPtr elmt;
5554 Array<OneD, int> ElmtID, EdgeID;
5555 GetBoundaryToElmtMap(ElmtID, EdgeID);
5559 Array<OneD, NekDouble>(GetBndCondExpansions()[i]->GetTotPoints(), 0.0);
5562 for (cnt = n = 0; n < i; ++n)
5564 cnt += GetBndCondExpansions()[n]->GetExpSize();
5569 for (n = 0; n < GetBndCondExpansions()[i]->GetExpSize(); ++n)
5571 offsetBnd = GetBndCondExpansions()[i]->GetPhys_Offset(n);
5573 elmt = GetExp(ElmtID[cnt + n]);
5574 elmt->GetTracePhysVals(
5575 EdgeID[cnt + n], GetBndCondExpansions()[i]->GetExp(n),
5576 tmp1 = element + offsetElmt, tmp2 = boundary + offsetBnd);
5578 offsetElmt += elmt->GetTotPoints();
5584void ExpList::v_ExtractPhysToBndElmt(
const int i,
5585 const Array<OneD, const NekDouble> &phys,
5586 Array<OneD, NekDouble> &bndElmt)
5590 Array<OneD, int> ElmtID, EdgeID;
5591 GetBoundaryToElmtMap(ElmtID, EdgeID);
5594 for (cnt = n = 0; n < i; ++n)
5596 cnt += GetBndCondExpansions()[n]->GetExpSize();
5601 for (n = 0; n < GetBndCondExpansions()[i]->GetExpSize(); ++n)
5603 npoints += GetExp(ElmtID[cnt + n])->GetTotPoints();
5607 bndElmt = Array<OneD, NekDouble>(npoints, 0.0);
5612 for (n = 0; n < GetBndCondExpansions()[i]->GetExpSize(); ++n)
5614 nq = GetExp(ElmtID[cnt + n])->GetTotPoints();
5615 offsetPhys = GetPhys_Offset(ElmtID[cnt + n]);
5616 Vmath::Vcopy(nq, &phys[offsetPhys], 1, &bndElmt[offsetElmt], 1);
5623void ExpList::v_ExtractPhysToBnd(
int i,
5624 const Array<OneD, const NekDouble> &phys,
5625 Array<OneD, NekDouble> &bnd)
5628 Array<OneD, NekDouble> tmp1;
5629 LocalRegions::ExpansionSharedPtr elmt;
5631 Array<OneD, int> ElmtID, EdgeID;
5632 GetBoundaryToElmtMap(ElmtID, EdgeID);
5636 Array<OneD, NekDouble>(GetBndCondExpansions()[i]->GetTotPoints(), 0.0);
5639 for (cnt = n = 0; n < i; ++n)
5641 cnt += GetBndCondExpansions()[n]->GetExpSize();
5646 for (n = 0; n < GetBndCondExpansions()[i]->GetExpSize(); ++n)
5648 offsetPhys = GetPhys_Offset(ElmtID[cnt + n]);
5649 offsetBnd = GetBndCondExpansions()[i]->GetPhys_Offset(n);
5651 elmt = GetExp(ElmtID[cnt + n]);
5652 elmt->GetTracePhysVals(EdgeID[cnt + n],
5653 GetBndCondExpansions()[i]->GetExp(n),
5654 phys + offsetPhys, tmp1 = bnd + offsetBnd);
5660void ExpList::v_GetBoundaryNormals(
int i,
5661 Array<OneD, Array<OneD, NekDouble>> &normals)
5664 int coordim = GetCoordim(0);
5665 Array<OneD, NekDouble> tmp;
5666 LocalRegions::ExpansionSharedPtr elmt;
5668 Array<OneD, int> ElmtID, EdgeID;
5669 GetBoundaryToElmtMap(ElmtID, EdgeID);
5672 normals = Array<OneD, Array<OneD, NekDouble>>(coordim);
5673 for (j = 0; j < coordim; ++j)
5675 normals[j] = Array<OneD, NekDouble>(
5676 GetBndCondExpansions()[i]->GetTotPoints(), 0.0);
5680 for (cnt = n = 0; n < i; ++n)
5682 cnt += GetBndCondExpansions()[n]->GetExpSize();
5686 for (n = 0; n < GetBndCondExpansions()[i]->GetExpSize(); ++n)
5688 offset = GetBndCondExpansions()[i]->GetPhys_Offset(n);
5690 elmt = GetExp(ElmtID[cnt + n]);
5691 const Array<OneD, const Array<OneD, NekDouble>> normalsElmt =
5692 elmt->GetTraceNormal(EdgeID[cnt + n]);
5695 for (j = 0; j < coordim; ++j)
5697 GetBndCondExpansions()[i]->GetExp(n)->PhysInterp(
5698 elmt, normalsElmt[j], tmp = normals[j] + offset);
5705void ExpList::v_GetBoundaryToElmtMap([[maybe_unused]] Array<OneD, int> &ElmtID,
5706 [[maybe_unused]] Array<OneD, int> &EdgeID)
5709 "This method is not defined or valid for this class type");
5712void ExpList::v_FillBwdWithBwdWeight(
5713 [[maybe_unused]] Array<OneD, NekDouble> &weightave,
5714 [[maybe_unused]] Array<OneD, NekDouble> &weightjmp)
5716 NEKERROR(ErrorUtil::efatal,
"v_FillBwdWithBwdWeight not defined");
5719void ExpList::v_PeriodicBwdCopy(
5720 [[maybe_unused]]
const Array<OneD, const NekDouble> &Fwd,
5721 [[maybe_unused]] Array<OneD, NekDouble> &Bwd)
5723 NEKERROR(ErrorUtil::efatal,
"v_PeriodicBwdCopy not defined");
5726void ExpList::v_PeriodicBwdRot(
5727 [[maybe_unused]] Array<OneD, Array<OneD, NekDouble>> &Bwd)
5729 NEKERROR(ErrorUtil::efatal,
"v_PeriodicBwdRot not defined");
5732void ExpList::v_PeriodicDeriveBwdRot(
5733 [[maybe_unused]] TensorOfArray3D<NekDouble> &Bwd)
5735 NEKERROR(ErrorUtil::efatal,
"v_PeriodicDeriveBwdRot not defined");
5738void ExpList::v_RotLocalBwdTrace(
5739 [[maybe_unused]] Array<OneD, Array<OneD, NekDouble>> &Bwd)
5741 NEKERROR(ErrorUtil::efatal,
"v_RotLocalBwdTrace not defined");
5744void ExpList::v_RotLocalBwdDeriveTrace(
5745 [[maybe_unused]] TensorOfArray3D<NekDouble> &Bwd)
5747 NEKERROR(ErrorUtil::efatal,
"v_RotLocalBwdDeriveTrace not defined");
5752const Array<OneD, const SpatialDomains::BoundaryConditionShPtr> &ExpList::
5753 v_GetBndConditions(
void)
5756 "This method is not defined or valid for this class type");
5757 static Array<OneD, const SpatialDomains::BoundaryConditionShPtr> result;
5763Array<OneD, SpatialDomains::BoundaryConditionShPtr> &ExpList::
5764 v_UpdateBndConditions()
5767 "This method is not defined or valid for this class type");
5768 static Array<OneD, SpatialDomains::BoundaryConditionShPtr> result;
5774void ExpList::v_EvaluateBoundaryConditions(
5775 [[maybe_unused]]
const NekDouble time,
5776 [[maybe_unused]]
const std::string varName,
5777 [[maybe_unused]]
const NekDouble x2_in,
5778 [[maybe_unused]]
const NekDouble x3_in)
5781 "This method is not defined or valid for this class type");
5784void ExpList::v_SetBCsToHomogeneous(
void)
5787 "This method is not defined or valid for this class type");
5791map<int, RobinBCInfoSharedPtr> ExpList::v_GetRobinBCInfo(
void)
5794 "This method is not defined or valid for this class type");
5795 static map<int, RobinBCInfoSharedPtr> result;
5801void ExpList::v_GetPeriodicEntities([[maybe_unused]] PeriodicMap &periodicVerts,
5802 [[maybe_unused]] PeriodicMap &periodicEdges,
5803 [[maybe_unused]] PeriodicMap &periodicFaces)
5806 "This method is not defined or valid for this class type");
5809SpatialDomains::BoundaryConditionShPtr ExpList::GetBoundaryCondition(
5810 const SpatialDomains::BoundaryConditionCollection &collection,
5811 unsigned int regionId,
const std::string &variable)
5813 auto collectionIter = collection.find(regionId);
5814 ASSERTL1(collectionIter != collection.end(),
5815 "Unable to locate collection " + std::to_string(regionId));
5817 const SpatialDomains::BoundaryConditionMapShPtr bndCondMap =
5818 (*collectionIter).second;
5819 auto conditionMapIter = bndCondMap->find(variable);
5820 ASSERTL1(conditionMapIter != bndCondMap->end(),
5821 "Unable to locate condition map.");
5823 const SpatialDomains::BoundaryConditionShPtr boundaryCondition =
5824 (*conditionMapIter).second;
5826 return boundaryCondition;
5832 "This method is not defined or valid for this class type");
5833 return NullExpListSharedPtr;
5840void ExpList::CreateCollections(Collections::ImplementationType ImpType)
5843 m_collectionsDoInit =
5844 std::vector<bool>(Collections::SIZE_OperatorType,
true);
5848 Collections::CollectionOptimisation colOpt(
5849 m_session, (*m_exp)[0]->GetShapeDimension(), ImpType);
5854 bool autotuning = colOpt.IsUsingAutotuning();
5855 if ((autotuning ==
false) && (ImpType == Collections::eNoImpType))
5859 if (m_session->GetUpdateOptFile() && m_graph)
5864 if (m_graph->GetMeshDimension() == (*m_exp)[0]->GetShapeDimension())
5870 bool verbose = (m_session->DefinesCmdLineArgument(
"verbose")) &&
5871 (m_session->GetComm()->GetRank() == 0);
5874 m_collections.clear();
5884 (colOpt.GetMaxCollectionSize() > 0 ? colOpt.GetMaxCollectionSize()
5885 : 2 * m_exp->size());
5887 vector<LocalRegions::ExpansionSharedPtr> collExp;
5888 LocalRegions::ExpansionSharedPtr exp = (*m_exp)[0];
5889 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(exp);
5892 collExp.push_back(exp);
5896 std::vector<LibUtilities::BasisKey> thisbasisKeys(
5897 3, LibUtilities::NullBasisKey);
5898 std::vector<LibUtilities::BasisKey> prevbasisKeys(
5899 3, LibUtilities::NullBasisKey);
5901 for (
int d = 0;
d < exp->GetNumBases();
d++)
5903 prevbasisKeys[
d] = exp->GetBasis(d)->GetBasisKey();
5908 exp->GetGeomFactors()->GetGtype() == SpatialDomains::eDeformed;
5911 int mincol = (*m_exp).size();
5915 for (
int i = 1; i < (*m_exp).size(); i++)
5920 for (
int d = 0;
d < exp->GetNumBases();
d++)
5922 thisbasisKeys[
d] = exp->GetBasis(d)->GetBasisKey();
5926 (exp->GetGeomFactors()->GetGtype() == SpatialDomains::eDeformed);
5930 if (thisbasisKeys != prevbasisKeys || prevDef != Deformed ||
5940 if (collExp.size() > collsize)
5943 colOpt.SetWithTimings(collExp, impTypes, verbose);
5944 collsize = collExp.size();
5947 Collections::OperatorImpMap impTypes =
5948 colOpt.GetOperatorImpMap(exp);
5950 Collections::Collection tmp(collExp, impTypes);
5951 m_collections.push_back(tmp);
5952 mincol =
min(mincol, (
int)collExp.size());
5953 maxcol =
max(maxcol, (
int)collExp.size());
5954 meancol += collExp.size();
5958 impTypes = colOpt.GetOperatorImpMap((*m_exp)[i]);
5967 collExp.push_back(exp);
5970 prevbasisKeys = thisbasisKeys;
5977 if (collExp.size() > collsize)
5979 impTypes = colOpt.SetWithTimings(collExp, impTypes, verbose);
5980 collsize = collExp.size();
5983 Collections::Collection tmp(collExp, impTypes);
5984 m_collections.push_back(tmp);
5987 mincol =
min(mincol, (
int)collExp.size());
5988 maxcol =
max(maxcol, (
int)collExp.size());
5989 meancol += collExp.size();
5990 meancol /= m_collections.size();
5991 cout <<
"Collection group: num. = " << m_collections.size()
5992 <<
"; mean len = " << meancol <<
" (min = " << mincol
5993 <<
", max = " << maxcol <<
")" << endl;
6002 if ((m_session->GetUpdateOptFile()) && (ImpType == Collections::eNoImpType))
6004 colOpt.UpdateOptFile(m_session->GetSessionName(), m_comm);
6007 m_session->SetUpdateOptFile(
false);
6011void ExpList::ClearGlobalLinSysManager(
void)
6013 v_ClearGlobalLinSysManager();
6021int ExpList::GetPoolCount(std::string poolName)
6023 return v_GetPoolCount(poolName);
6026void ExpList::UnsetGlobalLinSys(GlobalLinSysKey key,
bool clearLocalMatrices)
6028 v_UnsetGlobalLinSys(key, clearLocalMatrices);
6031LibUtilities::NekManager<GlobalLinSysKey, GlobalLinSys> &ExpList::
6032 GetGlobalLinSysManager(
void)
6034 return v_GetGlobalLinSysManager();
6037void ExpList::v_PhysInterp1DScaled([[maybe_unused]]
const NekDouble scale,
6038 const Array<OneD, NekDouble> &inarray,
6039 Array<OneD, NekDouble> &outarray)
6045 StdRegions::ConstFactorMap
factors;
6047 factors[StdRegions::eFactorConst] = scale;
6048 LibUtilities::Timer timer;
6051 if (m_collections.size() &&
6052 m_collectionsDoInit[Collections::ePhysInterp1DScaled])
6054 for (
int i = 0; i < m_collections.size(); ++i)
6056 m_collections[i].Initialise(Collections::ePhysInterp1DScaled);
6057 m_collectionsDoInit[Collections::ePhysInterp1DScaled] =
false;
6061 for (
int i = 0; i < m_collections.size(); ++i)
6064 m_collections[i].UpdateFactors(Collections::ePhysInterp1DScaled,
6070 Array<OneD, NekDouble> tmp;
6071 int input_offset{0};
6072 int output_offset{0};
6073 for (
int i = 0; i < m_collections.size(); ++i)
6075 m_collections[i].ApplyOperator(Collections::ePhysInterp1DScaled,
6076 inarray + input_offset,
6077 tmp = outarray + output_offset);
6079 m_collections[i].GetInputSize(Collections::ePhysInterp1DScaled);
6081 m_collections[i].GetOutputSize(Collections::ePhysInterp1DScaled);
6085 timer.AccumulateRegion(
"Collections:PhysInterp1DScaled", 10);
6087void ExpList::v_AddTraceIntegralToOffDiag(
6088 [[maybe_unused]]
const Array<OneD, const NekDouble> &FwdFlux,
6089 [[maybe_unused]]
const Array<OneD, const NekDouble> &BwdFlux,
6090 [[maybe_unused]] Array<OneD, NekDouble> &outarray)
6092 NEKERROR(ErrorUtil::efatal,
"AddTraceIntegralToOffDiag not defined");
6095void ExpList::GetMatIpwrtDeriveBase(
6096 const Array<OneD,
const Array<OneD, NekDouble>> &inarray,
const int nDirctn,
6097 Array<OneD, DNekMatSharedPtr> &mtxPerVar)
6099 int nTotElmt = (*m_exp).size();
6100 int nElmtPnt = (*m_exp)[0]->GetTotPoints();
6101 int nElmtCoef = (*m_exp)[0]->GetNcoeffs();
6103 Array<OneD, NekDouble> tmpCoef(nElmtCoef, 0.0);
6104 Array<OneD, NekDouble> tmpPhys(nElmtPnt, 0.0);
6106 for (
int nelmt = 0; nelmt < nTotElmt; nelmt++)
6108 nElmtCoef = (*m_exp)[nelmt]->GetNcoeffs();
6109 nElmtPnt = (*m_exp)[nelmt]->GetTotPoints();
6111 if (tmpPhys.size() != nElmtPnt || tmpCoef.size() != nElmtCoef)
6113 tmpPhys = Array<OneD, NekDouble>(nElmtPnt, 0.0);
6114 tmpCoef = Array<OneD, NekDouble>(nElmtCoef, 0.0);
6117 for (
int ncl = 0; ncl < nElmtPnt; ncl++)
6119 tmpPhys[ncl] = inarray[nelmt][ncl];
6121 (*m_exp)[nelmt]->IProductWRTDerivBase(nDirctn, tmpPhys, tmpCoef);
6123 for (
int nrw = 0; nrw < nElmtCoef; nrw++)
6125 (*mtxPerVar[nelmt])(nrw, ncl) = tmpCoef[nrw];
6133void ExpList::GetMatIpwrtDeriveBase(
const TensorOfArray3D<NekDouble> &inarray,
6134 Array<OneD, DNekMatSharedPtr> &mtxPerVar)
6136 int nTotElmt = (*m_exp).size();
6138 int nspacedim = m_graph->GetSpaceDimension();
6139 Array<OneD, Array<OneD, NekDouble>> projectedpnts(nspacedim);
6140 Array<OneD, Array<OneD, NekDouble>> tmppnts(nspacedim);
6141 Array<OneD, DNekMatSharedPtr> ArrayStdMat(nspacedim);
6142 Array<OneD, Array<OneD, NekDouble>> ArrayStdMat_data(nspacedim);
6144 Array<OneD, NekDouble> clmnArray, clmnStdMatArray;
6146 LibUtilities::ShapeType ElmtTypePrevious = LibUtilities::eNoShapeType;
6147 int nElmtPntPrevious = 0;
6148 int nElmtCoefPrevious = 0;
6150 int nElmtPnt, nElmtCoef;
6151 for (
int nelmt = 0; nelmt < nTotElmt; nelmt++)
6153 nElmtCoef = (*m_exp)[nelmt]->GetNcoeffs();
6154 nElmtPnt = (*m_exp)[nelmt]->GetTotPoints();
6155 LibUtilities::ShapeType ElmtTypeNow = (*m_exp)[nelmt]->DetShapeType();
6157 if (nElmtPntPrevious != nElmtPnt || nElmtCoefPrevious != nElmtCoef ||
6158 (ElmtTypeNow != ElmtTypePrevious))
6160 if (nElmtPntPrevious != nElmtPnt)
6162 for (
int ndir = 0; ndir < nspacedim; ndir++)
6164 projectedpnts[ndir] = Array<OneD, NekDouble>(nElmtPnt, 0.0);
6165 tmppnts[ndir] = Array<OneD, NekDouble>(nElmtPnt, 0.0);
6168 StdRegions::StdExpansionSharedPtr stdExp;
6169 stdExp = (*m_exp)[nelmt]->GetStdExp();
6170 StdRegions::StdMatrixKey matkey(StdRegions::eDerivBase0,
6171 stdExp->DetShapeType(), *stdExp);
6173 ArrayStdMat[0] = stdExp->GetStdMatrix(matkey);
6174 ArrayStdMat_data[0] = ArrayStdMat[0]->GetPtr();
6178 StdRegions::StdMatrixKey matkey(
6179 StdRegions::eDerivBase1, stdExp->DetShapeType(), *stdExp);
6181 ArrayStdMat[1] = stdExp->GetStdMatrix(matkey);
6182 ArrayStdMat_data[1] = ArrayStdMat[1]->GetPtr();
6186 StdRegions::StdMatrixKey matkey(StdRegions::eDerivBase2,
6187 stdExp->DetShapeType(),
6190 ArrayStdMat[2] = stdExp->GetStdMatrix(matkey);
6191 ArrayStdMat_data[2] = ArrayStdMat[2]->GetPtr();
6195 ElmtTypePrevious = ElmtTypeNow;
6196 nElmtPntPrevious = nElmtPnt;
6197 nElmtCoefPrevious = nElmtCoef;
6201 for (
int ndir = 0; ndir < nspacedim; ndir++)
6207 for (
int ndir = 0; ndir < nspacedim; ndir++)
6209 (*m_exp)[nelmt]->AlignVectorToCollapsedDir(
6210 ndir, inarray[ndir][nelmt], tmppnts);
6211 for (
int n = 0; n < nspacedim; n++)
6213 Vmath::Vadd(nElmtPnt, tmppnts[n], 1, projectedpnts[n], 1,
6214 projectedpnts[n], 1);
6218 for (
int ndir = 0; ndir < nspacedim; ndir++)
6221 (*m_exp)[nelmt]->MultiplyByQuadratureMetric(projectedpnts[ndir],
6222 projectedpnts[ndir]);
6223 Array<OneD, NekDouble> MatDataArray = mtxPerVar[nelmt]->GetPtr();
6225 for (
int np = 0; np < nElmtPnt; np++)
6227 NekDouble factor = projectedpnts[ndir][np];
6228 clmnArray = MatDataArray + np * nElmtCoef;
6229 clmnStdMatArray = ArrayStdMat_data[ndir] + np * nElmtCoef;
6230 Vmath::Svtvp(nElmtCoef, factor, clmnStdMatArray, 1, clmnArray,
6238void ExpList::GetDiagMatIpwrtBase(
6239 const Array<OneD,
const Array<OneD, NekDouble>> &inarray,
6240 Array<OneD, DNekMatSharedPtr> &mtxPerVar)
6242 LibUtilities::ShapeType ElmtTypePrevious = LibUtilities::eNoShapeType;
6243 int nElmtPntPrevious = 0;
6244 int nElmtCoefPrevious = 0;
6245 int nTotElmt = (*m_exp).size();
6246 int nElmtPnt = (*m_exp)[0]->GetTotPoints();
6247 int nElmtCoef = (*m_exp)[0]->GetNcoeffs();
6249 Array<OneD, NekDouble> tmpPhys;
6250 Array<OneD, NekDouble> clmnArray, clmnStdMatArray;
6251 Array<OneD, NekDouble> stdMat_data;
6253 for (
int nelmt = 0; nelmt < nTotElmt; nelmt++)
6255 nElmtCoef = (*m_exp)[nelmt]->GetNcoeffs();
6256 nElmtPnt = (*m_exp)[nelmt]->GetTotPoints();
6257 LibUtilities::ShapeType ElmtTypeNow = (*m_exp)[nelmt]->DetShapeType();
6259 if (nElmtPntPrevious != nElmtPnt || nElmtCoefPrevious != nElmtCoef ||
6260 (ElmtTypeNow != ElmtTypePrevious))
6262 StdRegions::StdExpansionSharedPtr stdExp;
6263 stdExp = (*m_exp)[nelmt]->GetStdExp();
6264 StdRegions::StdMatrixKey matkey(StdRegions::eBwdMat,
6265 stdExp->DetShapeType(), *stdExp);
6268 stdMat_data = BwdMat->GetPtr();
6270 if (nElmtPntPrevious != nElmtPnt)
6272 tmpPhys = Array<OneD, NekDouble>(nElmtPnt, 0.0);
6275 ElmtTypePrevious = ElmtTypeNow;
6276 nElmtPntPrevious = nElmtPnt;
6277 nElmtCoefPrevious = nElmtCoef;
6280 (*m_exp)[nelmt]->MultiplyByQuadratureMetric(
6284 Array<OneD, NekDouble> MatDataArray = mtxPerVar[nelmt]->GetPtr();
6286 for (
int np = 0; np < nElmtPnt; np++)
6289 clmnArray = MatDataArray + np * nElmtCoef;
6290 clmnStdMatArray = stdMat_data + np * nElmtCoef;
6291 Vmath::Smul(nElmtCoef, factor, clmnStdMatArray, 1, clmnArray, 1);
6309void ExpList::AddTraceJacToElmtJac(
6310 const Array<OneD, const DNekMatSharedPtr> &FwdMat,
6311 const Array<OneD, const DNekMatSharedPtr> &BwdMat,
6312 Array<OneD, DNekMatSharedPtr> &fieldMat)
6314 MultiRegions::ExpListSharedPtr tracelist = GetTrace();
6315 std::shared_ptr<LocalRegions::ExpansionVector> traceExp =
6316 tracelist->GetExp();
6317 int ntotTrace = (*traceExp).size();
6318 int nTracePnt, nTraceCoef;
6320 std::shared_ptr<LocalRegions::ExpansionVector> fieldExp = GetExp();
6323 const MultiRegions::LocTraceToTraceMapSharedPtr locTraceToTraceMap =
6324 GetLocTraceToTraceMap();
6325 const Array<OneD, const Array<OneD, int>> LRAdjExpid =
6326 locTraceToTraceMap->GetLeftRightAdjacentExpId();
6327 const Array<OneD, const Array<OneD, bool>> LRAdjflag =
6328 locTraceToTraceMap->GetLeftRightAdjacentExpFlag();
6330 const Array<OneD, const Array<OneD, Array<OneD, int>>> elmtLRMap =
6331 locTraceToTraceMap->GetTraceCoeffToLeftRightExpCoeffMap();
6332 const Array<OneD, const Array<OneD, Array<OneD, int>>> elmtLRSign =
6333 locTraceToTraceMap->GetTraceCoeffToLeftRightExpCoeffSign();
6335 Array<OneD, NekDouble> ElmtMat_data;
6338 int MatIndex, nPnts;
6341 int nTracePntsTtl = tracelist->GetTotPoints();
6342 int nlocTracePts = locTraceToTraceMap->GetNLocTracePts();
6343 int nlocTracePtsFwd = locTraceToTraceMap->GetNFwdLocTracePts();
6344 int nlocTracePtsBwd = nlocTracePts - nlocTracePtsFwd;
6346 Array<OneD, int> nlocTracePtsLR(2);
6347 nlocTracePtsLR[0] = nlocTracePtsFwd;
6348 nlocTracePtsLR[1] = nlocTracePtsBwd;
6350 size_t nFwdBwdNonZero = 0;
6351 Array<OneD, int> tmpIndex{2, -1};
6352 for (
int i = 0; i < 2; ++i)
6354 if (nlocTracePtsLR[i] > 0)
6356 tmpIndex[nFwdBwdNonZero] = i;
6361 Array<OneD, int> nlocTracePtsNonZeroIndex{nFwdBwdNonZero};
6362 for (
int i = 0; i < nFwdBwdNonZero; ++i)
6364 nlocTracePtsNonZeroIndex[i] = tmpIndex[i];
6367 Array<OneD, NekDouble> TraceFwdPhy(nTracePntsTtl);
6368 Array<OneD, NekDouble> TraceBwdPhy(nTracePntsTtl);
6369 Array<OneD, Array<OneD, NekDouble>> tmplocTrace(2);
6370 for (
int k = 0; k < 2; ++k)
6372 tmplocTrace[k] = NullNekDouble1DArray;
6375 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6377 size_t i = nlocTracePtsNonZeroIndex[k];
6378 tmplocTrace[i] = Array<OneD, NekDouble>(nlocTracePtsLR[i]);
6381 int nNumbElmt = fieldMat.size();
6382 Array<OneD, Array<OneD, NekDouble>> ElmtMatDataArray(nNumbElmt);
6383 Array<OneD, int> ElmtCoefArray(nNumbElmt);
6384 for (
int i = 0; i < nNumbElmt; i++)
6386 ElmtMatDataArray[i] = fieldMat[i]->GetPtr();
6387 ElmtCoefArray[i] = GetNcoeffs(i);
6390 int nTraceCoefMax = 0;
6391 int nTraceCoefMin = std::numeric_limits<int>::max();
6392 Array<OneD, int> TraceCoefArray(ntotTrace);
6393 Array<OneD, int> TracePntArray(ntotTrace);
6394 Array<OneD, int> TraceOffArray(ntotTrace);
6395 Array<OneD, Array<OneD, NekDouble>> FwdMatData(ntotTrace);
6396 Array<OneD, Array<OneD, NekDouble>> BwdMatData(ntotTrace);
6397 for (
int nt = 0; nt < ntotTrace; nt++)
6399 nTraceCoef = (*traceExp)[nt]->GetNcoeffs();
6400 nTracePnt = tracelist->GetTotPoints(nt);
6401 int noffset = tracelist->GetPhys_Offset(nt);
6402 TraceCoefArray[nt] = nTraceCoef;
6403 TracePntArray[nt] = nTracePnt;
6404 TraceOffArray[nt] = noffset;
6405 FwdMatData[nt] = FwdMat[nt]->GetPtr();
6406 BwdMatData[nt] = BwdMat[nt]->GetPtr();
6407 if (nTraceCoef > nTraceCoefMax)
6409 nTraceCoefMax = nTraceCoef;
6411 if (nTraceCoef < nTraceCoefMin)
6413 nTraceCoefMin = nTraceCoef;
6416 WARNINGL1(nTraceCoefMax == nTraceCoefMin,
6417 "nTraceCoefMax!=nTraceCoefMin: Effeciency may be low ");
6419 int traceID, nfieldPnts, ElmtId, noffset;
6420 const Array<OneD, const Array<OneD, int>> LocTracephysToTraceIDMap =
6421 locTraceToTraceMap->GetLocTracephysToTraceIDMap();
6422 const Array<OneD, const int> fieldToLocTraceMap =
6423 locTraceToTraceMap->GetLocTraceToFieldMap();
6424 Array<OneD, Array<OneD, int>> fieldToLocTraceMapLR(2);
6426 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6428 size_t i = nlocTracePtsNonZeroIndex[k];
6429 fieldToLocTraceMapLR[i] = Array<OneD, int>(nlocTracePtsLR[i]);
6430 Vmath::Vcopy(nlocTracePtsLR[i], &fieldToLocTraceMap[0] + noffset, 1,
6431 &fieldToLocTraceMapLR[i][0], 1);
6432 noffset += nlocTracePtsLR[i];
6435 Array<OneD, Array<OneD, int>> MatIndexArray(2);
6436 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6438 size_t nlr = nlocTracePtsNonZeroIndex[k];
6439 MatIndexArray[nlr] = Array<OneD, int>(nlocTracePtsLR[nlr]);
6440 for (
int nloc = 0; nloc < nlocTracePtsLR[nlr]; nloc++)
6442 traceID = LocTracephysToTraceIDMap[nlr][nloc];
6443 nTraceCoef = TraceCoefArray[traceID];
6444 ElmtId = LRAdjExpid[nlr][traceID];
6445 noffset = GetPhys_Offset(ElmtId);
6446 nElmtCoef = ElmtCoefArray[ElmtId];
6447 nfieldPnts = fieldToLocTraceMapLR[nlr][nloc];
6448 nPnts = nfieldPnts - noffset;
6450 MatIndexArray[nlr][nloc] = nPnts * nElmtCoef;
6454 for (
int nc = 0; nc < nTraceCoefMin; nc++)
6456 for (
int nt = 0; nt < ntotTrace; nt++)
6458 nTraceCoef = TraceCoefArray[nt];
6459 nTracePnt = TracePntArray[nt];
6460 noffset = TraceOffArray[nt];
6461 Vmath::Vcopy(nTracePnt, &FwdMatData[nt][nc], nTraceCoef,
6462 &TraceFwdPhy[noffset], 1);
6463 Vmath::Vcopy(nTracePnt, &BwdMatData[nt][nc], nTraceCoef,
6464 &TraceBwdPhy[noffset], 1);
6467 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6469 size_t i = nlocTracePtsNonZeroIndex[k];
6470 Vmath::Zero(nlocTracePtsLR[i], tmplocTrace[i], 1);
6473 GetLocTraceFromTracePts(TraceFwdPhy, TraceBwdPhy, tmplocTrace[0],
6476 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6478 size_t nlr = nlocTracePtsNonZeroIndex[k];
6479 for (
int nloc = 0; nloc < nlocTracePtsLR[nlr]; nloc++)
6481 traceID = LocTracephysToTraceIDMap[nlr][nloc];
6482 nTraceCoef = TraceCoefArray[traceID];
6483 ElmtId = LRAdjExpid[nlr][traceID];
6484 nrwAdjExp = elmtLRMap[nlr][traceID][nc];
6485 sign = elmtLRSign[nlr][traceID][nc];
6486 MatIndex = MatIndexArray[nlr][nloc] + nrwAdjExp;
6488 ElmtMatDataArray[ElmtId][MatIndex] -=
6489 sign * tmplocTrace[nlr][nloc];
6494 for (
int nc = nTraceCoefMin; nc < nTraceCoefMax; nc++)
6496 for (
int nt = 0; nt < ntotTrace; nt++)
6498 nTraceCoef = TraceCoefArray[nt];
6499 nTracePnt = TracePntArray[nt];
6500 noffset = TraceOffArray[nt];
6501 if (nc < nTraceCoef)
6503 Vmath::Vcopy(nTracePnt, &FwdMatData[nt][nc], nTraceCoef,
6504 &TraceFwdPhy[noffset], 1);
6505 Vmath::Vcopy(nTracePnt, &BwdMatData[nt][nc], nTraceCoef,
6506 &TraceBwdPhy[noffset], 1);
6515 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6517 size_t i = nlocTracePtsNonZeroIndex[k];
6518 Vmath::Zero(nlocTracePtsLR[i], tmplocTrace[i], 1);
6520 GetLocTraceFromTracePts(TraceFwdPhy, TraceBwdPhy, tmplocTrace[0],
6523 for (
int k = 0; k < nFwdBwdNonZero; ++k)
6525 size_t nlr = nlocTracePtsNonZeroIndex[k];
6526 for (
int nloc = 0; nloc < nlocTracePtsLR[nlr]; nloc++)
6528 traceID = LocTracephysToTraceIDMap[nlr][nloc];
6529 nTraceCoef = TraceCoefArray[traceID];
6530 if (nc < nTraceCoef)
6532 ElmtId = LRAdjExpid[nlr][traceID];
6533 nrwAdjExp = elmtLRMap[nlr][traceID][nc];
6534 sign = -elmtLRSign[nlr][traceID][nc];
6535 MatIndex = MatIndexArray[nlr][nloc] + nrwAdjExp;
6537 ElmtMatDataArray[ElmtId][MatIndex] +=
6538 sign * tmplocTrace[nlr][nloc];
6545void ExpList::AddRightIPTPhysDerivBase(
6546 const int dir,
const Array<OneD, const DNekMatSharedPtr> ElmtJacQuad,
6547 Array<OneD, DNekMatSharedPtr> ElmtJacCoef)
6550 int nelmtcoef, nelmtpnts, nelmtcoef0, nelmtpnts0;
6552 nelmtcoef = GetNcoeffs(0);
6553 nelmtpnts = GetTotPoints(0);
6555 Array<OneD, NekDouble> innarray(nelmtpnts, 0.0);
6556 Array<OneD, NekDouble> outarray(nelmtcoef, 0.0);
6558 Array<OneD, NekDouble> MatQ_data;
6559 Array<OneD, NekDouble> MatC_data;
6563 nelmtcoef0 = nelmtcoef;
6564 nelmtpnts0 = nelmtpnts;
6566 for (nelmt = 0; nelmt < (*m_exp).size(); ++nelmt)
6568 nelmtcoef = GetNcoeffs(nelmt);
6569 nelmtpnts = GetTotPoints(nelmt);
6571 tmpMatQ = ElmtJacQuad[nelmt];
6572 tmpMatC = ElmtJacCoef[nelmt];
6574 MatQ_data = tmpMatQ->GetPtr();
6575 MatC_data = tmpMatC->GetPtr();
6577 if (nelmtcoef != nelmtcoef0)
6579 outarray = Array<OneD, NekDouble>(nelmtcoef, 0.0);
6580 nelmtcoef0 = nelmtcoef;
6583 if (nelmtpnts != nelmtpnts0)
6585 innarray = Array<OneD, NekDouble>(nelmtpnts, 0.0);
6586 nelmtpnts0 = nelmtpnts;
6589 for (
int np = 0; np < nelmtcoef; np++)
6591 Vmath::Vcopy(nelmtpnts, &MatQ_data[0] + np, nelmtcoef, &innarray[0],
6593 (*m_exp)[nelmt]->DivideByQuadratureMetric(innarray, innarray);
6594 (*m_exp)[nelmt]->IProductWRTDerivBase(dir, innarray, outarray);
6596 Vmath::Vadd(nelmtcoef, &outarray[0], 1, &MatC_data[0] + np,
6597 nelmtcoef, &MatC_data[0] + np, nelmtcoef);
6602void ExpList::AddRightIPTBaseMatrix(
6603 const Array<OneD, const DNekMatSharedPtr> ElmtJacQuad,
6604 Array<OneD, DNekMatSharedPtr> ElmtJacCoef)
6607 int nelmtcoef, nelmtpnts, nelmtcoef0, nelmtpnts0;
6609 nelmtcoef = GetNcoeffs(0);
6610 nelmtpnts = GetTotPoints(0);
6612 Array<OneD, NekDouble> innarray(nelmtpnts, 0.0);
6613 Array<OneD, NekDouble> outarray(nelmtcoef, 0.0);
6615 Array<OneD, NekDouble> MatQ_data;
6616 Array<OneD, NekDouble> MatC_data;
6620 nelmtcoef0 = nelmtcoef;
6621 nelmtpnts0 = nelmtpnts;
6623 for (nelmt = 0; nelmt < (*m_exp).size(); ++nelmt)
6625 nelmtcoef = GetNcoeffs(nelmt);
6626 nelmtpnts = GetTotPoints(nelmt);
6628 tmpMatQ = ElmtJacQuad[nelmt];
6629 tmpMatC = ElmtJacCoef[nelmt];
6631 MatQ_data = tmpMatQ->GetPtr();
6632 MatC_data = tmpMatC->GetPtr();
6634 if (nelmtcoef != nelmtcoef0)
6636 outarray = Array<OneD, NekDouble>(nelmtcoef, 0.0);
6637 nelmtcoef0 = nelmtcoef;
6640 if (nelmtpnts != nelmtpnts0)
6642 innarray = Array<OneD, NekDouble>(nelmtpnts, 0.0);
6643 nelmtpnts0 = nelmtpnts;
6646 for (
int np = 0; np < nelmtcoef; np++)
6648 Vmath::Vcopy(nelmtpnts, &MatQ_data[0] + np, nelmtcoef, &innarray[0],
6650 (*m_exp)[nelmt]->DivideByQuadratureMetric(innarray, innarray);
6651 (*m_exp)[nelmt]->IProductWRTBase(innarray, outarray);
6653 Vmath::Vadd(nelmtcoef, &outarray[0], 1, &MatC_data[0] + np,
6654 nelmtcoef, &MatC_data[0] + np, nelmtcoef);
6659void ExpList::v_PhysGalerkinProjection1DScaled(
6660 const NekDouble scale,
const Array<OneD, NekDouble> &inarray,
6661 Array<OneD, NekDouble> &outarray)
6671 for (
int i = 0; i < GetExpSize(); ++i)
6674 int pt0 = (*m_exp)[i]->GetNumPoints(0);
6675 int pt1 = (*m_exp)[i]->GetNumPoints(1);
6676 int npt0 = (int)(pt0 * scale);
6677 int npt1 = (pt0 - pt1 == 1) ? (
int)(pt0 * scale - 1)
6678 : (int)(pt1 * scale);
6680 LibUtilities::PointsKey newPointsKey0(
6681 npt0, (*m_exp)[i]->GetPointsType(0));
6682 LibUtilities::PointsKey newPointsKey1(
6683 npt1, (*m_exp)[i]->GetPointsType(1));
6686 LibUtilities::PhysGalerkinProject2D(
6687 newPointsKey0, newPointsKey1, &inarray[cnt],
6688 (*m_exp)[i]->GetBasis(0)->GetPointsKey(),
6689 (*m_exp)[i]->GetBasis(1)->GetPointsKey(), &outarray[cnt1]);
6698 for (
int i = 0; i < GetExpSize(); ++i)
6701 int pt0 = (*m_exp)[i]->GetNumPoints(0);
6702 int pt1 = (*m_exp)[i]->GetNumPoints(1);
6703 int pt2 = (*m_exp)[i]->GetNumPoints(2);
6704 int npt0 = (int)(pt0 * scale);
6705 int npt1 = (pt0 - pt1 == 1) ? (
int)(pt0 * scale - 1)
6706 : (int)(pt1 * scale);
6707 int npt2 = (pt0 - pt2 == 1) ? (
int)(pt0 * scale - 1)
6708 : (int)(pt2 * scale);
6710 LibUtilities::PointsKey newPointsKey0(
6711 npt0, (*m_exp)[i]->GetPointsType(0));
6712 LibUtilities::PointsKey newPointsKey1(
6713 npt1, (*m_exp)[i]->GetPointsType(1));
6714 LibUtilities::PointsKey newPointsKey2(
6715 npt2, (*m_exp)[i]->GetPointsType(2));
6718 LibUtilities::PhysGalerkinProject3D(
6719 newPointsKey0, newPointsKey1, newPointsKey2, &inarray[cnt],
6720 (*m_exp)[i]->GetBasis(0)->GetPointsKey(),
6721 (*m_exp)[i]->GetBasis(1)->GetPointsKey(),
6722 (*m_exp)[i]->GetBasis(2)->GetPointsKey(), &outarray[cnt1]);
6724 cnt += npt0 * npt1 * npt2;
6725 cnt1 += pt0 * pt1 * pt2;
6731 NEKERROR(ErrorUtil::efatal,
"not setup for this expansion");
6739 NEKERROR(ErrorUtil::efatal,
"v_GetLocTraceToTraceMap not coded");
6740 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
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
std::shared_ptr< DNekMat > DNekMatSharedPtr
void Gathr(I n, const T *x, const I *y, T *z)
Gather vector z[i] = x[y[i]].
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 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)