43 #include <boost/config.hpp>
44 #include <boost/graph/adjacency_list.hpp>
45 #include <boost/graph/cuthill_mckee_ordering.hpp>
46 #include <boost/graph/properties.hpp>
47 #include <boost/graph/bandwidth.hpp>
53 namespace MultiRegions
71 AssemblyMapCG::AssemblyMapCG(
73 const std::string variable):
76 pSession->LoadParameter(
84 const bool checkIfSystemSingular,
90 set<int> &extraDirVerts,
91 set<int> &extraDirEdges,
92 int &firstNonDirGraphVertId,
99 int meshVertId, meshEdgeId, meshFaceId;
100 int meshVertId2, meshEdgeId2;
110 for(i = 0; i < bndCondExp.size(); i++)
115 if (bndConditions[0][i]->GetBoundaryConditionType() ==
125 for(k = 0; k < bndConditions.size(); ++k)
127 if (bndConditions[k][i]->GetBoundaryConditionType() ==
132 if (bndConditions[k][i]->GetBoundaryConditionType() !=
141 for (j = 0; j < bndCondExp[i]->GetNumElmts(); ++j)
144 for (k = 0; k < bndExp->GetNverts(); ++k)
146 if (vMaxVertId < bndExp->GetGeom()->GetVid(k))
148 vMaxVertId = bndExp->
GetGeom()->GetVid(k);
154 if(cnt == bndConditions.size())
156 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
158 bndExp = bndCondExp[i]->GetExp(j);
160 for (k = 0; k < bndExp->GetNverts(); k++)
162 meshVertId = bndExp->GetGeom()->GetVid(k);
163 if (graph[0].count(meshVertId) == 0)
165 graph[0][meshVertId] = graphVertId++;
169 const int bndDim = bndExp->GetNumBases();
172 for (k = 0; k < bndExp->GetNtraces(); k++)
174 meshEdgeId = bndExp->GetGeom()->GetEid(k);
175 if (graph[1].count(meshEdgeId) == 0)
177 graph[1][meshEdgeId] = graphVertId++;
183 meshFaceId = bndExp->GetGeom()->GetGlobalID();
184 if (graph[bndDim].count(meshFaceId) == 0)
186 graph[bndDim][meshFaceId] = graphVertId++;
219 int n = vComm->GetSize();
220 int p = vComm->GetRank();
222 if(vComm->IsSerial())
236 vertcounts[
p] = graph[0].size();
237 edgecounts[
p] = graph[1].size();
241 for (i = 1; i < n; ++i)
243 vertoffsets[i] = vertoffsets[i-1] + vertcounts[i-1];
244 edgeoffsets[i] = edgeoffsets[i-1] + edgecounts[i-1];
255 for (
auto &it : graph[0])
257 vertlist[vertoffsets[
p] + i++] = it.first;
262 for (
auto &it : graph[1])
264 edgelist[edgeoffsets[
p] + i++] = it.first;
272 map<int, int> extraDirVertIds, extraDirEdgeIds;
282 for (i = 0; i < n; ++i)
289 for(j = 0; j < locExpVector.size(); j++)
291 exp = locExpVector[j];
293 for(k = 0; k < exp->GetNverts(); k++)
295 meshVertId = exp->GetGeom()->GetVid(k);
296 if(graph[0].count(meshVertId) == 0)
298 for (l = 0; l < vertcounts[i]; ++l)
300 if (vertlist[vertoffsets[i]+l] == meshVertId)
302 extraDirVertIds[meshVertId] = i;
303 graph[0][meshVertId] = graphVertId++;
310 for(k = 0; k < exp->GetGeom()->GetNumEdges(); k++)
312 meshEdgeId = exp->GetGeom()->GetEid(k);
313 if(graph[1].count(meshEdgeId) == 0)
315 for (l = 0; l < edgecounts[i]; ++l)
317 if (edgelist[edgeoffsets[i]+l] == meshEdgeId)
319 extraDirEdgeIds[meshEdgeId] = i;
320 graph[1][meshEdgeId] = graphVertId++;
321 if(exp->GetGeom()->GetNumFaces())
325 ->GetEdgeNcoeffs(k)-2;
343 for (
auto &it : extraDirEdgeIds)
345 meshEdgeId = it.first;
355 for (i = 0; i < n; ++i)
363 vertcounts[
p] = extraDirVertIds.size();
364 edgecounts[
p] = extraDirEdgeIds.size();
370 vertoffsets[0] = edgeoffsets[0] = 0;
372 for (i = 1; i < n; ++i)
374 vertoffsets[i] = vertoffsets[i-1] + vertcounts[i-1];
375 edgeoffsets[i] = edgeoffsets[i-1] + edgecounts[i-1];
384 for (
auto &it : extraDirVertIds)
386 vertids [vertoffsets[
p]+i] = it.first;
387 vertprocs[vertoffsets[
p]+i] = it.second;
392 for (
auto &it : extraDirEdgeIds)
394 edgeids [edgeoffsets[
p]+i] = it.first;
395 edgeprocs[edgeoffsets[
p]+i] = it.second;
406 for (i = 0; i < nTotVerts; ++i)
408 if (
p == vertprocs[i])
410 extraDirVerts.insert(vertids[i]);
415 for (i = 0; i < nTotEdges; ++i)
417 if (
p == edgeprocs[i])
419 extraDirEdges.insert(edgeids[i]);
430 bcminvertid[
p] = vMaxVertId;
446 if (
m_session->DefinesParameter(
"SingularVertex"))
448 m_session->LoadParameter(
"SingularVertex", meshVertId);
450 else if (vMaxVertId == -1)
453 meshVertId = locExpVector[0]->GetGeom()->GetVid(0);
459 meshVertId = bcminvertid[
p];
462 if (graph[0].count(meshVertId) == 0)
464 graph[0][meshVertId] = graphVertId++;
480 for (i = 0; i < locExpVector.size(); ++i)
482 for (j = 0; j < locExpVector[i]->GetNverts(); ++j)
484 if (locExpVector[i]->GetGeom()->GetVid(j) !=
490 if (graph[0].count(meshVertId) == 0)
492 graph[0][meshVertId] =
508 if (graph[0].count(meshVertId) == 0)
514 gId = graph[0][meshVertId];
517 for (
auto &pIt : periodicVerts)
524 if (pIt.first == meshVertId)
526 gId = gId < 0 ? graphVertId++ : gId;
527 graph[0][meshVertId] = gId;
529 for (i = 0; i < pIt.second.size(); ++i)
531 if (pIt.second[i].isLocal)
533 graph[0][pIt.second[i].id] = graph[0][meshVertId];
540 for (i = 0; i < pIt.second.size(); ++i)
542 if (pIt.second[i].id == meshVertId)
551 gId = gId < 0 ? graphVertId++ : gId;
552 graph[0][pIt.first] = gId;
554 for (i = 0; i < pIt.second.size(); ++i)
556 if (pIt.second[i].isLocal)
558 graph[0][pIt.second[i].id] = graph[0][pIt.first];
568 firstNonDirGraphVertId = graphVertId;
570 typedef boost::adjacency_list<
571 boost::setS, boost::vecS, boost::undirectedS> BoostGraph;
572 BoostGraph boostGraphObj;
574 vector<map<int,int> > tempGraph(3);
575 map<int, int> vwgts_map;
580 int tempGraphVertId = 0;
581 int localVertOffset = 0;
582 int localEdgeOffset = 0;
583 int localFaceOffset = 0;
601 map<int,int> EdgeSize;
602 map<int,int> FaceSize;
605 for(i = 0; i < locExpVector.size(); ++i)
607 exp = locExpVector[i];
608 nEdges = exp->GetGeom()->GetNumEdges();
609 nFaces = exp->GetGeom()->GetNumFaces();
611 nTotalVerts += exp->GetNverts();
612 nTotalEdges += nEdges;
613 nTotalFaces += nFaces;
615 for(j = 0; j < nEdges; ++j)
617 meshEdgeId = exp->GetGeom()->GetEid(j);
623 ->GetEdgeNcoeffs(j)-2;
630 if (EdgeSize.count(meshEdgeId) > 0)
632 EdgeSize[meshEdgeId] =
633 min(EdgeSize[meshEdgeId], nEdgeInt);
637 EdgeSize[meshEdgeId] = nEdgeInt;
642 for(j = 0; j < nFaces; ++j)
644 meshFaceId = exp->GetGeom()->GetFid(j);
645 if (FaceSize.count(meshFaceId) > 0)
647 FaceSize[meshFaceId] =
648 min(FaceSize[meshFaceId],
649 exp->GetTraceIntNcoeffs(j));
653 FaceSize[meshFaceId] = exp->GetTraceIntNcoeffs(j);
655 FaceSize[meshFaceId] = exp->GetTraceIntNcoeffs(j);
660 for (
auto &pIt : periodicVerts)
662 meshVertId = pIt.first;
665 if (graph[0].count(pIt.first) != 0)
667 for (i = 0; i < pIt.second.size(); ++i)
669 meshVertId2 = pIt.second[i].id;
670 if (graph[0].count(meshVertId2) == 0 &&
671 pIt.second[i].isLocal)
673 graph[0][meshVertId2] =
674 graph[0][meshVertId];
681 bool isDirichlet =
false;
682 for (i = 0; i < pIt.second.size(); ++i)
684 if (!pIt.second[i].isLocal)
689 meshVertId2 = pIt.second[i].id;
690 if (graph[0].count(meshVertId2) > 0)
699 graph[0][meshVertId] =
700 graph[0][pIt.second[i].id];
702 for (j = 0; j < pIt.second.size(); ++j)
704 meshVertId2 = pIt.second[i].id;
705 if (j == i || !pIt.second[j].isLocal ||
706 graph[0].count(meshVertId2) > 0)
711 graph[0][meshVertId2] =
712 graph[0][pIt.second[i].id];
719 for (i = 0; i < pIt.second.size(); ++i)
721 if (!pIt.second[i].isLocal)
726 if (tempGraph[0].count(pIt.second[i].id) > 0)
732 if (i == pIt.second.size())
734 boost::add_vertex(boostGraphObj);
735 tempGraph[0][meshVertId] = tempGraphVertId++;
740 tempGraph[0][meshVertId] = tempGraph[0][pIt.second[i].id];
751 for(i = 0; i < locExpVector.size(); ++i)
753 exp = locExpVector[i];
755 nVerts = exp->GetNverts();
756 for(j = 0; j < nVerts; ++j)
758 meshVertId = exp->GetGeom()->GetVid(j);
759 if(graph[0].count(meshVertId) == 0)
761 if(tempGraph[0].count(meshVertId) == 0)
763 boost::add_vertex(boostGraphObj);
764 tempGraph[0][meshVertId] = tempGraphVertId++;
767 localVerts[localVertOffset+vertCnt++] = tempGraph[0][meshVertId];
768 vwgts_map[ tempGraph[0][meshVertId] ] = 1;
772 localVertOffset+=nVerts;
776 for (
auto &pIt : periodicEdges)
778 meshEdgeId = pIt.first;
781 if (graph[1].count(pIt.first) != 0)
783 for (i = 0; i < pIt.second.size(); ++i)
785 meshEdgeId2 = pIt.second[i].id;
786 if (graph[1].count(meshEdgeId2) == 0 &&
787 pIt.second[i].isLocal)
789 graph[1][meshEdgeId2] =
790 graph[1][meshEdgeId];
797 bool isDirichlet =
false;
798 for (i = 0; i < pIt.second.size(); ++i)
800 if (!pIt.second[i].isLocal)
805 meshEdgeId2 = pIt.second[i].id;
806 if (graph[1].count(meshEdgeId2) > 0)
815 graph[1][meshEdgeId] =
816 graph[1][pIt.second[i].id];
818 for (j = 0; j < pIt.second.size(); ++j)
820 meshEdgeId2 = pIt.second[i].id;
821 if (j == i || !pIt.second[j].isLocal ||
822 graph[1].count(meshEdgeId2) > 0)
827 graph[1][meshEdgeId2] =
828 graph[1][pIt.second[i].id];
835 for (i = 0; i < pIt.second.size(); ++i)
837 if (!pIt.second[i].isLocal)
842 if (tempGraph[1].count(pIt.second[i].id) > 0)
848 if (i == pIt.second.size())
850 boost::add_vertex(boostGraphObj);
851 tempGraph[1][meshEdgeId] = tempGraphVertId++;
857 tempGraph[1][meshEdgeId] = tempGraph[1][pIt.second[i].id];
861 int nEdgeIntCoeffs, nFaceIntCoeffs;
864 for(i = 0; i < locExpVector.size(); ++i)
866 exp = locExpVector[i];
868 nEdges = exp->GetGeom()->GetNumEdges();
870 for(j = 0; j < nEdges; ++j)
872 meshEdgeId = exp->GetGeom()->GetEid(j);
873 nEdgeIntCoeffs = EdgeSize[meshEdgeId];
874 if(graph[1].count(meshEdgeId) == 0)
876 if(tempGraph[1].count(meshEdgeId) == 0)
878 boost::add_vertex(boostGraphObj);
879 tempGraph[1][meshEdgeId] = tempGraphVertId++;
884 localEdges[localEdgeOffset+edgeCnt++] = tempGraph[1][meshEdgeId];
885 vwgts_map[ tempGraph[1][meshEdgeId] ] = nEdgeIntCoeffs;
889 localEdgeOffset+=nEdges;
893 for (
auto &pIt : periodicFaces)
895 if (!pIt.second[0].isLocal)
898 meshFaceId = pIt.first;
899 ASSERTL0(graph[2].count(meshFaceId) == 0,
900 "This periodic boundary edge has been specified before");
901 boost::add_vertex(boostGraphObj);
902 tempGraph[2][meshFaceId] = tempGraphVertId++;
903 nFaceIntCoeffs = FaceSize[meshFaceId];
907 else if (pIt.first < pIt.second[0].id)
909 ASSERTL0(graph[2].count(pIt.first) == 0,
910 "This periodic boundary face has been specified before");
911 ASSERTL0(graph[2].count(pIt.second[0].id) == 0,
912 "This periodic boundary face has been specified before");
914 boost::add_vertex(boostGraphObj);
915 tempGraph[2][pIt.first] = tempGraphVertId;
916 tempGraph[2][pIt.second[0].id] = tempGraphVertId++;
917 nFaceIntCoeffs = FaceSize[pIt.first];
924 for(i = 0; i < locExpVector.size(); ++i)
926 exp = locExpVector[i];
927 nFaces = exp->GetGeom()->GetNumFaces();
929 for(j = 0; j < nFaces; ++j)
931 nFaceIntCoeffs = exp->GetTraceIntNcoeffs(j);
932 meshFaceId = exp->GetGeom()->GetFid(j);
933 if(graph[2].count(meshFaceId) == 0)
935 if(tempGraph[2].count(meshFaceId) == 0)
937 boost::add_vertex(boostGraphObj);
938 tempGraph[2][meshFaceId] = tempGraphVertId++;
943 localFaces[localFaceOffset+faceCnt++] =
944 tempGraph[2][meshFaceId];
945 vwgts_map[ tempGraph[2][meshFaceId] ] =
951 localFaceOffset+=nFaces;
957 for(i = 0; i < locExpVector.size(); ++i)
959 exp = locExpVector[i];
960 nVerts = exp->GetNverts();
961 nEdges = exp->GetGeom()->GetNumEdges();
962 nFaces = exp->GetGeom()->GetNumFaces();
969 for(j = 0; j < nVerts; j++)
971 if(localVerts[j+localVertOffset]==-1)
976 for(k = 0; k < nVerts; k++)
978 if(localVerts[k+localVertOffset]==-1)
984 boost::add_edge( (
size_t) localVerts[j+localVertOffset],
985 (
size_t) localVerts[k+localVertOffset],boostGraphObj);
989 for(k = 0; k < nEdges; k++)
991 if(localEdges[k+localEdgeOffset]==-1)
995 boost::add_edge( (
size_t) localVerts[j+localVertOffset],
996 (
size_t) localEdges[k+localEdgeOffset],boostGraphObj);
999 for(k = 0; k < nFaces; k++)
1001 if(localFaces[k+localFaceOffset]==-1)
1005 boost::add_edge( (
size_t) localVerts[j+localVertOffset],
1006 (
size_t) localFaces[k+localFaceOffset],boostGraphObj);
1011 for(j = 0; j < nEdges; j++)
1013 if(localEdges[j+localEdgeOffset]==-1)
1018 for(k = 0; k < nEdges; k++)
1020 if(localEdges[k+localEdgeOffset]==-1)
1026 boost::add_edge( (
size_t) localEdges[j+localEdgeOffset],
1027 (
size_t) localEdges[k+localEdgeOffset],boostGraphObj);
1031 for(k = 0; k < nVerts; k++)
1033 if(localVerts[k+localVertOffset]==-1)
1037 boost::add_edge( (
size_t) localEdges[j+localEdgeOffset],
1038 (
size_t) localVerts[k+localVertOffset],boostGraphObj);
1041 for(k = 0; k < nFaces; k++)
1043 if(localFaces[k+localFaceOffset]==-1)
1047 boost::add_edge( (
size_t) localEdges[j+localEdgeOffset],
1048 (
size_t) localFaces[k+localFaceOffset],boostGraphObj);
1053 for(j = 0; j < nFaces; j++)
1055 if(localFaces[j+localFaceOffset]==-1)
1060 for(k = 0; k < nFaces; k++)
1062 if(localFaces[k+localFaceOffset]==-1)
1068 boost::add_edge( (
size_t) localFaces[j+localFaceOffset],
1069 (
size_t) localFaces[k+localFaceOffset],boostGraphObj);
1073 for(k = 0; k < nVerts; k++)
1075 if(localVerts[k+localVertOffset]==-1)
1079 boost::add_edge( (
size_t) localFaces[j+localFaceOffset],
1080 (
size_t) localVerts[k+localVertOffset],boostGraphObj);
1083 for(k = 0; k < nEdges; k++)
1085 if(localEdges[k+localEdgeOffset]==-1)
1089 boost::add_edge( (
size_t) localFaces[j+localFaceOffset],
1090 (
size_t) localEdges[k+localEdgeOffset],boostGraphObj);
1094 localVertOffset+=nVerts;
1095 localEdgeOffset+=nEdges;
1096 localFaceOffset+=nFaces;
1106 vector<long> procVerts, procEdges, procFaces;
1107 set <int> foundVerts, foundEdges, foundFaces;
1112 for(i = cnt = 0; i < locExpVector.size(); ++i)
1115 exp = locExpVector[elmtid];
1116 for (j = 0; j < exp->GetNverts(); ++j)
1118 int vid = exp->GetGeom()->GetVid(j)+1;
1119 if (foundVerts.count(vid) == 0)
1121 procVerts.push_back(vid);
1122 foundVerts.insert(vid);
1126 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1128 int eid = exp->GetGeom()->GetEid(j)+1;
1130 if (foundEdges.count(eid) == 0)
1132 procEdges.push_back(eid);
1133 foundEdges.insert(eid);
1137 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1139 int fid = exp->GetGeom()->GetFid(j)+1;
1141 if (foundFaces.count(fid) == 0)
1143 procFaces.push_back(fid);
1144 foundFaces.insert(fid);
1149 int unique_verts = foundVerts.size();
1150 int unique_edges = foundEdges.size();
1151 int unique_faces = foundFaces.size();
1153 bool verbose =
m_session->DefinesCmdLineArgument(
"verbose");
1167 if (unique_edges > 0)
1175 if (unique_faces > 0)
1185 for (i = 0; i < unique_verts; ++i)
1189 if (graph[0].count(procVerts[i]-1) == 0)
1191 partVerts.insert(tempGraph[0][procVerts[i]-1]);
1196 for (i = 0; i < unique_edges; ++i)
1200 if (graph[1].count(procEdges[i]-1) == 0)
1202 partVerts.insert(tempGraph[1][procEdges[i]-1]);
1207 for (i = 0; i < unique_faces; ++i)
1211 if (graph[2].count(procFaces[i]-1) == 0)
1213 partVerts.insert(tempGraph[2][procFaces[i]-1]);
1219 for (
auto &pIt : periodicVerts)
1221 if (graph[0].count(pIt.first) == 0)
1223 partVerts.insert(tempGraph[0][pIt.first]);
1226 for (
auto &pIt : periodicEdges)
1228 if (graph[1].count(pIt.first) == 0)
1230 partVerts.insert(tempGraph[1][pIt.first]);
1233 for (
auto &pIt : periodicFaces)
1235 if (graph[2].count(pIt.first) == 0)
1237 partVerts.insert(tempGraph[2][pIt.first]);
1242 int nGraphVerts = tempGraphVertId;
1246 ASSERTL1(vwgts_map.size()==nGraphVerts,
"Non matching dimensions");
1247 for(i = 0; i < nGraphVerts; ++i)
1249 vwgts[i] = vwgts_map[i];
1280 boostGraphObj, perm, iperm, bottomUpGraph,
1281 partVerts, mdswitch);
1287 "Unrecognised solution type: " + std::string(
1313 for(
auto &mapIt : tempGraph[0])
1315 graph[0][mapIt.first] = iperm[mapIt.second] + graphVertId;
1317 for(
auto &mapIt : tempGraph[1])
1319 graph[1][mapIt.first] = iperm[mapIt.second] + graphVertId;
1321 for(
auto &mapIt : tempGraph[2])
1323 graph[2][mapIt.first] = iperm[mapIt.second] + graphVertId;
1334 const int numLocalCoeffs,
1338 const bool checkIfSystemSingular,
1339 const std::string variable,
1346 int p, q, numModes0, numModes1;
1348 int meshVertId, meshEdgeId, meshEdgeId2, meshFaceId, meshFaceId2;
1350 int nEdgeInteriorCoeffs;
1351 int firstNonDirGraphVertId;
1363 bool verbose =
m_session->DefinesCmdLineArgument(
"verbose");
1370 vector<map<int, int> > faceModes(2);
1371 map<int, LibUtilities::ShapeType> faceType;
1373 set<int> extraDirVerts, extraDirEdges;
1378 for (i = 0; i < locExpVector.size(); ++i)
1380 exp = locExpVector[i];
1382 for(j = 0; j < exp->GetNverts(); ++j)
1384 dofs[0][exp->GetGeom()->GetVid(j)] = 1;
1387 for(j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1390 if(exp->GetGeom()->GetNumFaces())
1393 GetEdgeNcoeffs(j)-2;
1400 if (dofs[1].count(exp->GetGeom()->GetEid(j)) > 0)
1402 if (dofs[1][exp->GetGeom()->GetEid(j)] != nEdgeInt)
1408 "CG with variable order only available with modal expansion");
1410 dofs[1][exp->GetGeom()->GetEid(j)] =
1411 min(dofs[1][exp->GetGeom()->GetEid(j)],
1416 dofs[1][exp->GetGeom()->GetEid(j)] = nEdgeInt;
1420 for(j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1422 faceOrient = exp->GetGeom()->GetForient(j);
1423 meshFaceId = exp->GetGeom()->GetFid(j);
1424 exp->GetTraceNumModes(j, numModes0, numModes1, faceOrient);
1426 if (faceModes[0].count(meshFaceId) > 0)
1428 faceModes[0][meshFaceId] =
1429 min(faceModes[0][meshFaceId], numModes0);
1431 faceModes[1][meshFaceId] =
1432 min(faceModes[1][meshFaceId], numModes1);
1436 faceModes[0][meshFaceId] = numModes0;
1437 faceModes[1][meshFaceId] = numModes1;
1441 geom = std::dynamic_pointer_cast<SpatialDomains::
1442 Geometry3D> (exp->GetGeom());
1443 faceType[meshFaceId] =
1444 geom->GetFace(j)->GetShapeType();
1450 for (
auto &pIt : periodicEdges)
1452 for (i = 0; i < pIt.second.size(); ++i)
1454 meshEdgeId2 = pIt.second[i].id;
1455 if (dofs[1].count(meshEdgeId2) == 0)
1457 dofs[1][meshEdgeId2] = 1e6;
1461 for (
auto &pIt : periodicFaces)
1463 for (i = 0; i < pIt.second.size(); ++i)
1465 meshFaceId2 = pIt.second[i].id;
1466 if (faceModes[0].count(meshFaceId2) == 0)
1468 faceModes[0][meshFaceId2] = 1e6;
1469 faceModes[1][meshFaceId2] = 1e6;
1481 for(
auto &dofIt : dofs[1])
1483 edgeId [i ] = dofIt.first + 1;
1484 edgeDof[i++] = (
NekDouble) dofIt.second;
1489 for (i = 0; i < dofs[1].size(); i++)
1491 dofs[1][edgeId[i]-1] = (int) (edgeDof[i]+0.5);
1494 for (
auto &pIt : periodicEdges)
1496 meshEdgeId = pIt.first;
1497 for (i = 0; i < pIt.second.size(); ++i)
1499 meshEdgeId2 = pIt.second[i].id;
1500 if (dofs[1][meshEdgeId2] < dofs[1][meshEdgeId])
1502 dofs[1][meshEdgeId] = dofs[1][meshEdgeId2];
1512 for(
auto dofIt = faceModes[0].begin(), dofIt2 = faceModes[1].begin();
1513 dofIt != faceModes[0].end(); dofIt++, dofIt2++, i++)
1515 faceId[i] = dofIt->first+1;
1523 for (i=0; i < faceModes[0].size(); i++)
1525 faceModes[0][faceId[i]-1] = (int) (faceP[i]+0.5);
1526 faceModes[1][faceId[i]-1] = (int) (faceQ[i]+0.5);
1529 for (
auto &pIt : periodicFaces)
1531 meshFaceId = pIt.first;
1532 for (i = 0; i < pIt.second.size(); ++i)
1534 meshFaceId2 = pIt.second[i].id;
1535 if (faceModes[0][meshFaceId2] < faceModes[0][meshFaceId])
1537 faceModes[0][meshFaceId] = faceModes[0][meshFaceId2];
1539 if (faceModes[1][meshFaceId2] < faceModes[1][meshFaceId])
1541 faceModes[1][meshFaceId] = faceModes[1][meshFaceId2];
1547 for (i=0; i < faceModes[0].size(); i++)
1549 P = faceModes[0][faceId[i]-1];
1550 Q = faceModes[1][faceId[i]-1];
1554 dofs[2][faceId[i]-1] =
1561 dofs[2][faceId[i]-1] =
1572 int nExtraDirichlet;
1575 "MDSwitch", mdswitch, 10);
1579 checkIfSystemSingular, periodicVerts, periodicEdges,
1580 periodicFaces, graph, bottomUpGraph, extraDirVerts,
1581 extraDirEdges, firstNonDirGraphVertId,
1582 nExtraDirichlet, mdswitch);
1596 graph[0].size() + graph[1].size() + graph[2].size() + 1,0);
1598 graphVertOffset[0] = 0;
1600 for(i = 0; i < locExpVector.size(); ++i)
1602 exp = locExpVector[i];
1604 for(j = 0; j < exp->GetNverts(); ++j)
1606 meshVertId = exp->GetGeom()->GetVid(j);
1607 graphVertOffset[graph[0][meshVertId]+1] = 1;
1610 for(j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1612 if(exp->GetGeom()->GetNumFaces())
1614 nEdgeInteriorCoeffs =
1616 GetEdgeNcoeffs(j) - 2;
1622 meshEdgeId = exp->GetGeom()->GetEid(j);
1623 graphVertOffset[graph[1][meshEdgeId]+1]
1624 = dofs[1][meshEdgeId];
1628 if(nEdgeInteriorCoeffs &&
1635 for(j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1637 meshFaceId = exp->GetGeom()->GetFid(j);
1638 graphVertOffset[graph[2][meshFaceId]+1] =
1639 dofs[2][meshFaceId];
1643 for(i = 1; i < graphVertOffset.size(); i++)
1645 graphVertOffset[i] += graphVertOffset[i-1];
1677 locExpVector[i]->NumBndryCoeffs();
1679 locExpVector[i]->GetNcoeffs() -
1680 locExpVector[i]->NumBndryCoeffs();
1697 for(i = 0; i < locExpVector.size(); ++i)
1699 exp = locExpVector[i];
1702 int nbdry = exp->NumBndryCoeffs();
1703 int nint = exp->GetNcoeffs() - nbdry;
1708 exp->GetBoundaryMap(bmap);
1709 exp->GetInteriorMap(imap);
1711 for(j = 0; j < nbdry; ++j)
1716 for(j = 0; j < nint; ++j)
1721 for(j = 0; j < exp->GetNverts(); ++j)
1723 meshVertId = exp->GetGeom()->GetVid(j);
1727 graphVertOffset[graph[0][meshVertId]];
1730 for(j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1732 if(exp->GetGeom()->GetNumFaces())
1734 nEdgeInteriorCoeffs = exp->
1735 as<LocalRegions::Expansion3D>()->
1736 GetEdgeNcoeffs(j)-2;
1740 nEdgeInteriorCoeffs = exp->GetTraceNcoeffs(j)-2;
1742 edgeOrient = exp->GetGeom()->GetEorient(j);
1743 meshEdgeId = exp->GetGeom()->GetEid(j);
1745 auto pIt = periodicEdges.find(meshEdgeId);
1750 if (pIt != periodicEdges.end())
1752 pair<int, StdRegions::Orientation> idOrient =
1754 meshEdgeId, edgeOrient, pIt->second);
1755 edgeOrient = idOrient.second;
1758 if(exp->GetGeom()->GetNumFaces())
1761 GetEdgeInteriorToElementMap(j,edgeInteriorMap,
1762 edgeInteriorSign,edgeOrient);
1766 exp->GetTraceInteriorToElementMap(j,edgeInteriorMap,
1767 edgeInteriorSign,edgeOrient);
1771 for(k = 0; k < dofs[1][meshEdgeId]; ++k)
1774 graphVertOffset[graph[1][meshEdgeId]]+k;
1776 for(k = dofs[1][meshEdgeId]; k < nEdgeInteriorCoeffs; ++k)
1784 for(k = 0; k < dofs[1][meshEdgeId]; ++k)
1789 for(k = dofs[1][meshEdgeId]; k < nEdgeInteriorCoeffs; ++k)
1796 for(j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1798 faceOrient = exp->GetGeom()->GetForient(j);
1799 meshFaceId = exp->GetGeom()->GetFid(j);
1801 auto pIt = periodicFaces.find(meshFaceId);
1803 if (pIt != periodicFaces.end() &&
1804 meshFaceId == min(meshFaceId, pIt->second[0].id))
1809 exp->GetTraceInteriorToElementMap(j,faceInteriorMap,
1814 exp->GetTraceNumModes(j, numModes0, numModes1, faceOrient);
1815 switch(faceType[meshFaceId])
1821 for( q = 2; q < numModes1; q++)
1823 for(
p = 2;
p < numModes0;
p++)
1825 if( (
p < faceModes[0][meshFaceId]) &&
1826 (q < faceModes[1][meshFaceId]))
1829 graphVertOffset[graph[2][meshFaceId]]+k;
1854 for(
p = 2;
p < numModes0;
p++)
1856 for( q = 1; q < numModes1-
p; q++)
1858 if( (
p < faceModes[0][meshFaceId]) &&
1859 (
p+q < faceModes[1][meshFaceId]))
1862 graphVertOffset[graph[2][meshFaceId]]+k;
1884 ASSERTL0(
false,
"Shape not recognised");
1892 map<int, pair<int,int> > traceToElmtTraceMap;
1895 for(cnt = i = 0; i < locExpVector.size(); ++i)
1897 exp = locExpVector[i];
1899 for(j = 0; j < exp->GetNtraces(); ++j)
1901 id = exp->GetGeom()->GetTid(j);
1903 traceToElmtTraceMap[id] = pair<int,int>(i,j);
1909 map<int,pair<int,NekDouble>> GloDirBndCoeffToLocalCoeff;
1910 set<int> CoeffOnDirTrace;
1914 for(i = 0; i < bndCondExp.size(); i++)
1916 set<int> foundExtraVerts, foundExtraEdges;
1917 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
1919 bndExp = bndCondExp[i]->GetExp(j);
1920 cnt = offset + bndCondExp[i]->GetCoeff_Offset(j);
1922 int id = bndExp->GetGeom()->GetGlobalID();
1924 ASSERTL1(traceToElmtTraceMap.count(
id) > 0,
1925 "Failed to find trace id");
1927 int eid = traceToElmtTraceMap[id].first;
1928 int tid = traceToElmtTraceMap[id].second;
1930 exp = locExpVector[eid];
1931 int dim = exp->GetShapeDimension();
1942 exp->GetTraceToElementMap(tid,
1946 bndExp->GetBasisNumModes(0));
1950 exp->GetTraceToElementMap(tid, maparray,signarray,
1953 bndExp->GetBasisNumModes(0),
1954 bndExp->GetBasisNumModes(1));
1957 for(k = 0; k < bndExp->GetNcoeffs(); k++)
1974 for(k = 0; k < bndExp->GetNcoeffs(); k++)
1985 if (bndConditions[i]->GetBoundaryConditionType() ==
1988 CoeffOnDirTrace.insert(locid);
1992 GloDirBndCoeffToLocalCoeff[gloid] =
1993 pair<int,NekDouble> (locid,
sign);
1997 offset += bndCondExp[i]->GetNcoeffs();
2013 for(i = 0; i < locExpVector.size(); ++i)
2017 exp = locExpVector[i];
2019 exp->GetBoundaryMap(bndmap);
2021 for(j = 0; j < bndmap.size(); ++j)
2023 k = cnt + bndmap[j];
2025 if(CoeffOnDirTrace.count(k) == 0)
2031 if(GloDirBndCoeffToLocalCoeff.count(gloid))
2033 int locid = GloDirBndCoeffToLocalCoeff[gloid].
2049 gloParaDirBnd[gloid] = gloid;
2055 cnt += exp->GetNcoeffs();
2089 int gloid = gloParaDirBnd[i];
2092 gloParaDirBnd[i] = 0.0;
2107 for(i = 0; i < numLocalCoeffs; ++i)
2109 paraDirBnd[i] = 0.0;
2118 paraDirBnd[i] = gloParaDirBnd[id];
2120 if(gloParaDirBnd[
id] > 0.0)
2145 graph[0].size() + graph[1].size() + graph[2].size()
2146 - firstNonDirGraphVertId);
2148 for (i = 0; i < locExpVector.size(); ++i)
2150 exp = locExpVector[i];
2152 for (j = 0; j < exp->GetNverts(); ++j)
2154 meshVertId = exp->GetGeom()->GetVid(j);
2156 if (graph[0][meshVertId] >= firstNonDirGraphVertId)
2158 vwgts_perm[graph[0][meshVertId] -
2159 firstNonDirGraphVertId] =
2160 dofs[0][meshVertId];
2164 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
2166 meshEdgeId = exp->GetGeom()->GetEid(j);
2168 if (graph[1][meshEdgeId] >= firstNonDirGraphVertId)
2170 vwgts_perm[graph[1][meshEdgeId] -
2171 firstNonDirGraphVertId] =
2172 dofs[1][meshEdgeId];
2176 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
2178 meshFaceId = exp->GetGeom()->GetFid(j);
2180 if (graph[2][meshFaceId] >= firstNonDirGraphVertId)
2182 vwgts_perm[graph[2][meshFaceId] -
2183 firstNonDirGraphVertId] =
2184 dofs[2][meshFaceId];
2189 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
2238 const vector<PeriodicEntity> &periodicEdges)
2240 int minId = periodicEdges[0].id;
2244 for (k = 1; k < periodicEdges.size(); ++k)
2246 if (periodicEdges[k].
id < minId)
2248 minId = min(minId, periodicEdges[k].
id);
2253 minId = min(minId, meshEdgeId);
2255 if (meshEdgeId != minId)
2265 return make_pair(minId, edgeOrient);
2291 int tmp1 = (int)faceOrient - 5;
2292 int tmp2 = (int)perFaceOrient - 5;
2294 int flipDir1Map [8] = {2,3,0,1,6,7,4,5};
2295 int flipDir2Map [8] = {1,0,3,2,5,4,7,6};
2296 int transposeMap[8] = {4,5,6,7,0,2,1,3};
2301 tmp1 = transposeMap[tmp1];
2305 if (tmp2 == 2 || tmp2 == 3 || tmp2 == 6 || tmp2 == 7)
2307 tmp1 = flipDir1Map[tmp1];
2313 tmp1 = flipDir2Map[tmp1];
2347 int maxBndGlobalId = 0;
2358 const bool verbose = locExp.
GetSession()->DefinesCmdLineArgument(
"verbose");
2366 for(i = 0; i < locExpVector.size(); ++i)
2368 exp = locExpVector[i];
2370 int nv = exp->GetNverts();
2371 int ne = exp->GetGeom()->GetNumEdges();
2372 int nf = exp->GetGeom()->GetNumFaces();
2379 for(j = 0; j < ne; ++j)
2384 GetEdgeNcoeffs(j)-2;
2391 maxEdgeDof = (dof > maxEdgeDof ? dof : maxEdgeDof);
2393 for(j = 0; j < nf; ++j)
2395 dof = exp->GetTraceIntNcoeffs(j);
2396 maxFaceDof = (dof > maxFaceDof ? dof : maxFaceDof);
2398 exp->GetInteriorMap(interiorMap);
2399 dof = interiorMap.size();
2400 maxIntDof = (dof > maxIntDof ? dof : maxIntDof);
2412 for(i = 0; i < locExpVector.size(); ++i)
2414 exp = locExpVector[i];
2417 int nf = exp->GetGeom()->GetNumFaces();
2420 for(j = 0; j < exp->GetNverts(); ++j)
2422 meshVertId = exp->GetGeom()->GetVid(j);
2425 auto pIt = perVerts.find(meshVertId);
2426 if (pIt != perVerts.end())
2428 for (k = 0; k < pIt->second.size(); ++k)
2430 meshVertId = min(meshVertId, pIt->second[k].id);
2437 maxBndGlobalId = (vGlobalId > maxBndGlobalId ?
2438 vGlobalId : maxBndGlobalId);
2442 for(j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
2444 meshEdgeId = exp->GetGeom()->GetEid(j);
2445 auto pIt = perEdges.find(meshEdgeId);
2446 edgeOrient = exp->GetGeom()->GetEorient(j);
2448 if (pIt != perEdges.end())
2450 pair<int, StdRegions::Orientation> idOrient =
2452 meshEdgeId, edgeOrient, pIt->second);
2453 meshEdgeId = idOrient.first;
2454 edgeOrient = idOrient.second;
2460 GetEdgeInteriorToElementMap(j,edgeInteriorMap,
2461 edgeInteriorSign,edgeOrient);
2463 GetEdgeNcoeffs(j)-2;
2468 edgeInteriorSign,edgeOrient);
2469 dof = exp->GetTraceNcoeffs(j)-2;
2474 for(k = 0, l = 0; k < dof; ++k)
2485 = nVert + meshEdgeId * maxEdgeDof + l + 1;
2488 maxBndGlobalId = (vGlobalId > maxBndGlobalId ?
2489 vGlobalId : maxBndGlobalId);
2495 for(j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
2497 faceOrient = exp->GetGeom()->GetForient(j);
2499 meshFaceId = exp->GetGeom()->GetFid(j);
2501 auto pIt = perFaces.find(meshFaceId);
2502 if (pIt != perFaces.end())
2504 if(meshFaceId == min(meshFaceId, pIt->second[0].id))
2507 (faceOrient,pIt->second[0].orient);
2509 meshFaceId = min(meshFaceId, pIt->second[0].id);
2513 exp->GetTraceInteriorToElementMap(j,faceInteriorMap,
2514 faceInteriorSign,faceOrient);
2515 dof = exp->GetTraceIntNcoeffs(j);
2517 for(k = 0, l = 0; k < dof; ++k)
2528 = nVert + nEdge*maxEdgeDof + meshFaceId * maxFaceDof
2533 maxBndGlobalId = (vGlobalId > maxBndGlobalId ?
2534 vGlobalId : maxBndGlobalId);
2540 exp->GetInteriorMap(interiorMap);
2541 dof = interiorMap.size();
2542 elementId = (exp->GetGeom())->GetGlobalID();
2543 for (k = 0; k < dof; ++k)
2547 = nVert + nEdge*maxEdgeDof + nFace*maxFaceDof + elementId*maxIntDof + k + 1;
2591 const std::shared_ptr<LocalRegions::ExpansionVector> exp
2593 int nelmts = exp->size();
2594 const bool verbose = locexp.
GetSession()->DefinesCmdLineArgument(
"verbose");
2599 returnval->m_solnType = solnType;
2600 returnval->m_preconType =
eNull;
2601 returnval->m_maxStaticCondLevel = 0;
2602 returnval->m_signChange =
false;
2603 returnval->m_comm =
m_comm;
2606 for (i = 0; i < nelmts; ++i)
2608 nverts += (*exp)[i]->GetNverts();
2611 returnval->m_numLocalCoeffs = nverts;
2622 for (i = 0; i < nelmts; ++i)
2624 for (j = 0; j < (*exp)[i]->GetNverts(); ++j)
2626 returnval->m_localToGlobalMap[cnt] =
2627 returnval->m_localToGlobalBndMap[cnt] =
2629 GlobCoeffs[returnval->m_localToGlobalMap[cnt]] = 1;
2632 if ((returnval->m_localToGlobalMap[cnt]) <
2635 returnval->m_numLocalDirBndCoeffs++;
2639 cnt1 += (*exp)[i]->GetNcoeffs();
2646 if (GlobCoeffs[i] != -1)
2648 GlobCoeffs[i] = cnt++;
2653 returnval->m_numGlobalCoeffs = cnt;
2658 if (GlobCoeffs[i] != -1)
2660 returnval->m_numGlobalDirBndCoeffs++;
2669 int nglocoeffs = returnval->m_numGlobalCoeffs;
2670 returnval->m_globalToUniversalMap
2672 returnval->m_globalToUniversalMapUnique
2676 for (i = 0; i < nverts; ++i)
2678 cnt = returnval->m_localToGlobalMap[i];
2679 returnval->m_localToGlobalMap[i] = GlobCoeffs[cnt];
2681 returnval->m_globalToUniversalMap[GlobCoeffs[cnt]] =
2687 for (
unsigned int i = 0; i < nglocoeffs; ++i)
2689 tmp[i] = returnval->m_globalToUniversalMap[i];
2691 returnval->m_gsh =
Gs::Init(tmp, vCommRow, verbose);
2693 for (
unsigned int i = 0; i < nglocoeffs; ++i)
2695 returnval->m_globalToUniversalMapUnique[i]
2696 = (tmp[i] >= 0 ? 1 : 0);
2701 for (i = 0; i < nverts; ++i)
2703 cnt = returnval->m_localToGlobalMap[i];
2704 returnval->m_localToGlobalMap[i] = GlobCoeffs[cnt];
2737 for(j = 0; j < locSize; j++)
2752 bwidth = (bwidth>(maxId-minId))?bwidth:(maxId-minId);
2818 if(global.data() ==
loc.data())
2858 if(global.data() ==
loc.data())
2890 if(global.data() ==
loc.data())
#define ASSERTL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define sign(a, b)
return the sign(b)*a
SpatialDomains::GeometrySharedPtr GetGeom() const
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
int m_maxStaticCondLevel
Maximum static condensation level.
int m_numNonDirVertexModes
Number of non Dirichlet vertex modes.
virtual const Array< OneD, const int > & v_GetGlobalToUniversalMap()
virtual int v_GetFullSystemBandWidth() const
Array< OneD, int > m_globalToUniversalMapUnique
Integer map of unique process coeffs to universal space (signed)
int CreateGraph(const ExpList &locExp, const BndCondExp &bndCondExp, const Array< OneD, const BndCond > &bndConditions, const bool checkIfSystemSingular, const PeriodicMap &periodicVerts, const PeriodicMap &periodicEdges, const PeriodicMap &periodicFaces, DofGraph &graph, BottomUpSubStructuredGraphSharedPtr &bottomUpGraph, std::set< int > &extraDirVerts, std::set< int > &extraDirEdges, int &firstNonDirGraphVertId, int &nExtraDirichlet, int mdswitch=1)
virtual int v_GetNumDirEdges() const
virtual int v_GetNumDirFaces() const
virtual int v_GetNumNonDirFaceModes() const
virtual const Array< OneD, const int > & v_GetLocalToGlobalMap()
virtual int v_GetNumNonDirEdgeModes() const
int m_numNonDirEdges
Number of Dirichlet edges.
std::set< int > m_parallelDirBndSign
Set indicating the local coeffs just touching parallel dirichlet boundary that have a sign change.
Array< OneD, int > m_globalToUniversalMap
Integer map of process coeffs to universal space.
virtual const Array< OneD, const int > & v_GetGlobalToUniversalMapUnique()
virtual int v_GetNumNonDirFaces() const
Array< OneD, NekDouble > m_localToGlobalSign
Integer sign of local coeffs to global space.
virtual void v_LocalToGlobal(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global, bool useComm) const
virtual int v_GetNumNonDirVertexModes() const
Array< OneD, int > m_extraDirEdges
Extra dirichlet edges in parallel.
virtual void v_Assemble(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global) const
int m_numNonDirFaceModes
Number of non Dirichlet face modes.
int m_numNonDirEdgeModes
Number of non Dirichlet edge modes.
virtual void v_UniversalAssemble(Array< OneD, NekDouble > &pGlobal) const
int m_numDirEdges
Number of Dirichlet edges.
virtual const Array< OneD, NekDouble > & v_GetLocalToGlobalSign() const
AssemblyMapCG(const LibUtilities::SessionReaderSharedPtr &pSession, const std::string variable="DefaultVar")
Default constructor.
virtual const Array< OneD, const int > & v_GetExtraDirEdges()
int m_fullSystemBandWidth
Bandwith of the full matrix system (no static condensation).
int m_numDirFaces
Number of Dirichlet faces.
virtual int v_GetNumNonDirEdges() const
void SetUpUniversalC0ContMap(const ExpList &locExp, const PeriodicMap &perVerts=NullPeriodicMap, const PeriodicMap &perEdges=NullPeriodicMap, const PeriodicMap &perFaces=NullPeriodicMap)
virtual void v_GlobalToLocal(const Array< OneD, const NekDouble > &global, Array< OneD, NekDouble > &loc) const
void CalculateFullSystemBandWidth()
Calculate the bandwith of the full matrix system.
std::set< ExtraDirDof > m_copyLocalDirDofs
Set indicating degrees of freedom which are Dirichlet but whose value is stored on another processor.
int m_numNonDirFaces
Number of Dirichlet faces.
Array< OneD, int > m_localToGlobalMap
Integer map of local coeffs to global space.
virtual ~AssemblyMapCG()
Destructor.
virtual AssemblyMapSharedPtr v_LinearSpaceMap(const ExpList &locexp, GlobalSysSolnType solnType)
Construct an AssemblyMapCG object which corresponds to the linear space of the current object.
int m_numLocalBndCondCoeffs
Number of local boundary condition coefficients.
Base class for constructing local to global mapping of degrees of freedom.
int m_lowestStaticCondLevel
Lowest static condensation level.
GlobalSysSolnType m_solnType
The solution type of the global system.
int m_numLocalCoeffs
Total number of local coefficients.
Array< OneD, int > m_globalToUniversalBndMap
Integer map of process coeffs to universal space.
bool m_signChange
Flag indicating if modes require sign reversal.
void Assemble(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global) const
Array< OneD, int > m_bndCondCoeffsToLocalCoeffsMap
Integer map of bnd cond coeffs to local coefficients.
int m_numGlobalCoeffs
Total number of global coefficients.
Array< OneD, int > m_localToGlobalBndMap
Integer map of local coeffs to global Boundary Dofs.
void CalculateBndSystemBandWidth()
Calculates the bandwidth of the boundary system.
void LocalToGlobal(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global, bool useComm=true) const
Array< OneD, unsigned int > m_numLocalBndCoeffsPerPatch
The number of bnd dofs per patch.
LibUtilities::SessionReaderSharedPtr m_session
Session object.
int m_numLocalBndCoeffs
Number of local boundary coefficients.
AssemblyMapSharedPtr m_nextLevelLocalToGlobalMap
Map from the patches of the previous level to the patches of the current level.
int m_staticCondLevel
The level of recursion in the case of multi-level static condensation.
Array< OneD, NekDouble > m_localToGlobalBndSign
Integer sign of local boundary coeffs to global space.
Array< OneD, int > m_localToLocalIntMap
Integer map of local boundary coeffs to local interior system numbering.
void GlobalToLocal(const Array< OneD, const NekDouble > &global, Array< OneD, NekDouble > &loc) const
int m_numLocalDirBndCoeffs
Number of Local Dirichlet Boundary Coefficients.
int m_numGlobalDirBndCoeffs
Number of Global Dirichlet Boundary Coefficients.
Array< OneD, unsigned int > m_numLocalIntCoeffsPerPatch
The number of int dofs per patch.
bool m_systemSingular
Flag indicating if the system is singular or not.
Gs::gs_data * m_dirBndGsh
gs gather communication to impose Dirhichlet BCs.
size_t m_hash
Hash for map.
Array< OneD, NekDouble > m_bndCondCoeffsToLocalCoeffsSign
Integer map of sign of bnd cond coeffs to local coefficients.
LibUtilities::CommSharedPtr m_comm
Communicator.
Array< OneD, int > m_localToLocalBndMap
Integer map of local boundary coeffs to local boundary system numbering.
Array< OneD, int > m_globalToUniversalBndMapUnique
Integer map of unique process coeffs to universal space (signed)
void UniversalAssemble(Array< OneD, NekDouble > &pGlobal) const
int m_numPatches
The number of patches (~elements) in the current level.
int m_numGlobalBndCoeffs
Total number of global boundary coefficients.
Base class for all multi-elemental spectral/hp expansions.
int GetCoeff_Offset(int n) const
Get the start offset position for a global list of m_coeffs correspoinding to element n.
const std::shared_ptr< LocalRegions::ExpansionVector > GetExp() const
This function returns the vector of elements in the expansion.
std::shared_ptr< LibUtilities::SessionReader > GetSession() const
Returns the session object.
Array< OneD, DataType > & GetPtr()
void GetTraceInteriorToElementMap(const int tid, Array< OneD, unsigned int > &maparray, Array< OneD, int > &signarray, const Orientation traceOrient=eForwards)
int GetTraceNcoeffs(const int i) const
This function returns the number of expansion coefficients belonging to the i-th trace.
static void Gather(Nektar::Array< OneD, NekDouble > pU, gs_op pOp, gs_data *pGsh, Nektar::Array< OneD, NekDouble > pBuffer=NullNekDouble1DArray)
Performs a gather-scatter operation of the provided values.
static void Finalise(gs_data *pGsh)
Deallocates the GSLib mapping data.
static gs_data * Init(const Nektar::Array< OneD, long > pId, const LibUtilities::CommSharedPtr &pComm, bool verbose=true)
Initialise Gather-Scatter map.
static void Unique(const Nektar::Array< OneD, long > pId, const LibUtilities::CommSharedPtr &pComm)
Updates pId to negate all-but-one references to each universal ID.
int getNumberOfCoefficients(int Na, int Nb)
int getNumberOfBndCoefficients(int Na, int Nb)
int getNumberOfCoefficients(int Na, int Nb)
int getNumberOfBndCoefficients(int Na, int Nb)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
@ eModified_B
Principle Modified Functions .
@ eModified_C
Principle Modified Functions .
@ eModifiedPyr_C
Principle Modified Functions .
@ eModified_A
Principle Modified Functions .
std::shared_ptr< Expansion > ExpansionSharedPtr
std::vector< ExpansionSharedPtr > ExpansionVector
void NoReordering(const BoostGraph &graph, Array< OneD, int > &perm, Array< OneD, int > &iperm)
@ eIterativeMultiLevelStaticCond
@ eDirectMultiLevelStaticCond
@ eXxtMultiLevelStaticCond
@ ePETScMultiLevelStaticCond
void CuthillMckeeReordering(const BoostGraph &graph, Array< OneD, int > &perm, Array< OneD, int > &iperm)
void MultiLevelBisectionReordering(const BoostGraph &graph, Array< OneD, int > &perm, Array< OneD, int > &iperm, BottomUpSubStructuredGraphSharedPtr &substructgraph, std::set< int > partVerts, int mdswitch)
std::shared_ptr< BottomUpSubStructuredGraph > BottomUpSubStructuredGraphSharedPtr
std::shared_ptr< AssemblyMapCG > AssemblyMapCGSharedPtr
const char *const GlobalSysSolnTypeMap[]
std::tuple< int, int, NekDouble > ExtraDirDof
std::vector< std::map< int, int > > DofGraph
pair< int, StdRegions::Orientation > DeterminePeriodicEdgeOrientId(int meshEdgeId, StdRegions::Orientation edgeOrient, const vector< PeriodicEntity > &periodicEdges)
Determine orientation of an edge to its periodic equivalents, as well as the ID of the representative...
std::shared_ptr< AssemblyMap > AssemblyMapSharedPtr
std::map< int, std::vector< PeriodicEntity > > PeriodicMap
StdRegions::Orientation DeterminePeriodicFaceOrient(StdRegions::Orientation faceOrient, StdRegions::Orientation perFaceOrient)
Determine relative orientation between two faces.
@ eNull
No Solution type specified.
std::shared_ptr< Geometry3D > Geometry3DSharedPtr
@ eDir1FwdDir1_Dir2FwdDir2
The above copyright notice and this permission notice shall be included.
std::size_t hash_range(Iter first, Iter last)
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
void Scatr(int n, const T *x, const int *y, T *z)
Scatter vector z[y[i]] = x[i].
void Gathr(int n, const T *sign, const T *x, const int *y, T *z)
Gather vector z[i] = sign[i]*x[y[i]].
void Assmb(int n, const T *x, const int *y, T *z)
Assemble z[y[i]] += x[i]; z should be zero'd first.
int Imax(int n, const T *x, const int incx)
Return the index of the maximum element in 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)