43#include <boost/config.hpp>
44#include <boost/graph/adjacency_list.hpp>
45#include <boost/graph/bandwidth.hpp>
46#include <boost/graph/cuthill_mckee_ordering.hpp>
47#include <boost/graph/properties.hpp>
82 const bool checkIfSystemSingular,
const PeriodicMap &periodicVerts,
85 set<int> &extraDirVerts, set<int> &extraDirEdges,
86 int &firstNonDirGraphVertId,
int &nExtraDirichlet,
int mdswitch)
91 int meshVertId, meshEdgeId, meshFaceId;
92 int meshVertId2, meshEdgeId2;
101 for (i = 0; i < bndCondExp.size(); i++)
106 if (bndConditions[0][i]->GetBoundaryConditionType() ==
116 for (k = 0; k < bndConditions.size(); ++k)
118 if (bndConditions[k][i]->GetBoundaryConditionType() ==
123 if (bndConditions[k][i]->GetBoundaryConditionType() !=
132 for (j = 0; j < bndCondExp[i]->GetNumElmts(); ++j)
135 for (k = 0; k < bndExp->GetNverts(); ++k)
137 if (vMaxVertId < bndExp->GetGeom()->GetVid(k))
139 vMaxVertId = bndExp->
GetGeom()->GetVid(k);
145 if (cnt == bndConditions.size())
147 for (j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
149 bndExp = bndCondExp[i]->GetExp(j);
151 for (k = 0; k < bndExp->GetNverts(); k++)
153 meshVertId = bndExp->GetGeom()->GetVid(k);
154 if (graph[0].count(meshVertId) == 0)
156 graph[0][meshVertId] = graphVertId++;
160 const int bndDim = bndExp->GetNumBases();
163 for (k = 0; k < bndExp->GetNtraces(); k++)
165 meshEdgeId = bndExp->GetGeom()->GetEid(k);
166 if (graph[1].count(meshEdgeId) == 0)
168 graph[1][meshEdgeId] = graphVertId++;
174 meshFaceId = bndExp->GetGeom()->GetGlobalID();
175 if (graph[bndDim].count(meshFaceId) == 0)
177 graph[bndDim][meshFaceId] = graphVertId++;
210 int n = vComm->GetSize();
211 int p = vComm->GetRank();
213 if (vComm->IsSerial())
227 vertcounts[
p] = graph[0].size();
228 edgecounts[
p] = graph[1].size();
232 for (i = 1; i < n; ++i)
234 vertoffsets[i] = vertoffsets[i - 1] + vertcounts[i - 1];
235 edgeoffsets[i] = edgeoffsets[i - 1] + edgecounts[i - 1];
246 for (
auto &it : graph[0])
248 vertlist[vertoffsets[
p] + i++] = it.first;
253 for (
auto &it : graph[1])
255 edgelist[edgeoffsets[
p] + i++] = it.first;
263 map<int, int> extraDirVertIds, extraDirEdgeIds;
273 for (i = 0; i < n; ++i)
280 for (j = 0; j < locExpVector.size(); j++)
282 exp = locExpVector[j];
284 for (k = 0; k < exp->GetNverts(); k++)
286 meshVertId = exp->GetGeom()->GetVid(k);
287 if (graph[0].count(meshVertId) == 0)
289 for (l = 0; l < vertcounts[i]; ++l)
291 if (vertlist[vertoffsets[i] + l] == meshVertId)
293 extraDirVertIds[meshVertId] = i;
294 graph[0][meshVertId] = graphVertId++;
301 for (k = 0; k < exp->GetGeom()->GetNumEdges(); k++)
303 meshEdgeId = exp->GetGeom()->GetEid(k);
304 if (graph[1].count(meshEdgeId) == 0)
306 for (l = 0; l < edgecounts[i]; ++l)
308 if (edgelist[edgeoffsets[i] + l] == meshEdgeId)
310 extraDirEdgeIds[meshEdgeId] = i;
311 graph[1][meshEdgeId] = graphVertId++;
312 if (exp->GetGeom()->GetNumFaces())
316 ->GetEdgeNcoeffs(k) -
334 for (
auto &it : extraDirEdgeIds)
336 meshEdgeId = it.first;
346 for (i = 0; i < n; ++i)
354 vertcounts[
p] = extraDirVertIds.size();
355 edgecounts[
p] = extraDirEdgeIds.size();
361 vertoffsets[0] = edgeoffsets[0] = 0;
363 for (i = 1; i < n; ++i)
365 vertoffsets[i] = vertoffsets[i - 1] + vertcounts[i - 1];
366 edgeoffsets[i] = edgeoffsets[i - 1] + edgecounts[i - 1];
375 for (
auto &it : extraDirVertIds)
377 vertids[vertoffsets[
p] + i] = it.first;
378 vertprocs[vertoffsets[
p] + i] = it.second;
383 for (
auto &it : extraDirEdgeIds)
385 edgeids[edgeoffsets[
p] + i] = it.first;
386 edgeprocs[edgeoffsets[
p] + i] = it.second;
397 for (i = 0; i < nTotVerts; ++i)
399 if (
p == vertprocs[i])
401 extraDirVerts.insert(vertids[i]);
406 for (i = 0; i < nTotEdges; ++i)
408 if (
p == edgeprocs[i])
410 extraDirEdges.insert(edgeids[i]);
421 bcminvertid[
p] = vMaxVertId;
437 if (
m_session->DefinesParameter(
"SingularVertex"))
439 m_session->LoadParameter(
"SingularVertex", meshVertId);
441 else if (vMaxVertId == -1)
444 meshVertId = locExpVector[0]->GetGeom()->GetVid(0);
450 meshVertId = bcminvertid[
p];
453 if (graph[0].count(meshVertId) == 0)
455 graph[0][meshVertId] = graphVertId++;
471 for (i = 0; i < locExpVector.size(); ++i)
473 for (j = 0; j < locExpVector[i]->GetNverts(); ++j)
475 if (locExpVector[i]->GetGeom()->GetVid(j) != meshVertId)
480 if (graph[0].count(meshVertId) == 0)
482 graph[0][meshVertId] = graphVertId++;
497 if (graph[0].count(meshVertId) == 0)
503 gId = graph[0][meshVertId];
506 for (
auto &pIt : periodicVerts)
513 if (pIt.first == meshVertId)
515 gId = gId < 0 ? graphVertId++ : gId;
516 graph[0][meshVertId] = gId;
518 for (i = 0; i < pIt.second.size(); ++i)
520 if (pIt.second[i].isLocal)
522 graph[0][pIt.second[i].id] = graph[0][meshVertId];
529 for (i = 0; i < pIt.second.size(); ++i)
531 if (pIt.second[i].id == meshVertId)
540 gId = gId < 0 ? graphVertId++ : gId;
541 graph[0][pIt.first] = gId;
543 for (i = 0; i < pIt.second.size(); ++i)
545 if (pIt.second[i].isLocal)
547 graph[0][pIt.second[i].id] = graph[0][pIt.first];
557 firstNonDirGraphVertId = graphVertId;
559 typedef boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS>
561 BoostGraph boostGraphObj;
563 vector<map<int, int>> tempGraph(3);
564 map<int, int> vwgts_map;
569 int tempGraphVertId = 0;
570 int localVertOffset = 0;
571 int localEdgeOffset = 0;
572 int localFaceOffset = 0;
590 map<int, int> EdgeSize;
591 map<int, int> FaceSize;
594 for (i = 0; i < locExpVector.size(); ++i)
596 exp = locExpVector[i];
597 nEdges = exp->GetGeom()->GetNumEdges();
598 nFaces = exp->GetGeom()->GetNumFaces();
600 nTotalVerts += exp->GetNverts();
601 nTotalEdges += nEdges;
602 nTotalFaces += nFaces;
604 for (j = 0; j < nEdges; ++j)
606 meshEdgeId = exp->GetGeom()->GetEid(j);
619 if (EdgeSize.count(meshEdgeId) > 0)
621 EdgeSize[meshEdgeId] = min(EdgeSize[meshEdgeId], nEdgeInt);
625 EdgeSize[meshEdgeId] = nEdgeInt;
630 for (j = 0; j < nFaces; ++j)
632 meshFaceId = exp->GetGeom()->GetFid(j);
633 if (FaceSize.count(meshFaceId) > 0)
635 FaceSize[meshFaceId] =
636 min(FaceSize[meshFaceId], exp->GetTraceIntNcoeffs(j));
640 FaceSize[meshFaceId] = exp->GetTraceIntNcoeffs(j);
642 FaceSize[meshFaceId] = exp->GetTraceIntNcoeffs(j);
647 for (
auto &pIt : periodicVerts)
649 meshVertId = pIt.first;
652 if (graph[0].count(pIt.first) != 0)
654 for (i = 0; i < pIt.second.size(); ++i)
656 meshVertId2 = pIt.second[i].id;
657 if (graph[0].count(meshVertId2) == 0 && pIt.second[i].isLocal)
659 graph[0][meshVertId2] = graph[0][meshVertId];
666 bool isDirichlet =
false;
667 for (i = 0; i < pIt.second.size(); ++i)
669 if (!pIt.second[i].isLocal)
674 meshVertId2 = pIt.second[i].id;
675 if (graph[0].count(meshVertId2) > 0)
684 graph[0][meshVertId] = graph[0][pIt.second[i].id];
686 for (j = 0; j < pIt.second.size(); ++j)
688 meshVertId2 = pIt.second[i].id;
689 if (j == i || !pIt.second[j].isLocal ||
690 graph[0].count(meshVertId2) > 0)
695 graph[0][meshVertId2] = graph[0][pIt.second[i].id];
702 for (i = 0; i < pIt.second.size(); ++i)
704 if (!pIt.second[i].isLocal)
709 if (tempGraph[0].count(pIt.second[i].id) > 0)
715 if (i == pIt.second.size())
717 boost::add_vertex(boostGraphObj);
718 tempGraph[0][meshVertId] = tempGraphVertId++;
723 tempGraph[0][meshVertId] = tempGraph[0][pIt.second[i].id];
734 for (i = 0; i < locExpVector.size(); ++i)
736 exp = locExpVector[i];
738 nVerts = exp->GetNverts();
739 for (j = 0; j < nVerts; ++j)
741 meshVertId = exp->GetGeom()->GetVid(j);
742 if (graph[0].count(meshVertId) == 0)
744 if (tempGraph[0].count(meshVertId) == 0)
746 boost::add_vertex(boostGraphObj);
747 tempGraph[0][meshVertId] = tempGraphVertId++;
750 localVerts[localVertOffset + vertCnt++] =
751 tempGraph[0][meshVertId];
752 vwgts_map[tempGraph[0][meshVertId]] = 1;
756 localVertOffset += nVerts;
760 for (
auto &pIt : periodicEdges)
762 meshEdgeId = pIt.first;
765 if (graph[1].count(pIt.first) != 0)
767 for (i = 0; i < pIt.second.size(); ++i)
769 meshEdgeId2 = pIt.second[i].id;
770 if (graph[1].count(meshEdgeId2) == 0 && pIt.second[i].isLocal)
772 graph[1][meshEdgeId2] = graph[1][meshEdgeId];
779 bool isDirichlet =
false;
780 for (i = 0; i < pIt.second.size(); ++i)
782 if (!pIt.second[i].isLocal)
787 meshEdgeId2 = pIt.second[i].id;
788 if (graph[1].count(meshEdgeId2) > 0)
797 graph[1][meshEdgeId] = graph[1][pIt.second[i].id];
799 for (j = 0; j < pIt.second.size(); ++j)
801 meshEdgeId2 = pIt.second[i].id;
802 if (j == i || !pIt.second[j].isLocal ||
803 graph[1].count(meshEdgeId2) > 0)
808 graph[1][meshEdgeId2] = graph[1][pIt.second[i].id];
815 for (i = 0; i < pIt.second.size(); ++i)
817 if (!pIt.second[i].isLocal)
822 if (tempGraph[1].count(pIt.second[i].id) > 0)
828 if (i == pIt.second.size())
830 boost::add_vertex(boostGraphObj);
831 tempGraph[1][meshEdgeId] = tempGraphVertId++;
837 tempGraph[1][meshEdgeId] = tempGraph[1][pIt.second[i].id];
841 int nEdgeIntCoeffs, nFaceIntCoeffs;
844 for (i = 0; i < locExpVector.size(); ++i)
846 exp = locExpVector[i];
848 nEdges = exp->GetGeom()->GetNumEdges();
850 for (j = 0; j < nEdges; ++j)
852 meshEdgeId = exp->GetGeom()->GetEid(j);
853 nEdgeIntCoeffs = EdgeSize[meshEdgeId];
854 if (graph[1].count(meshEdgeId) == 0)
856 if (tempGraph[1].count(meshEdgeId) == 0)
858 boost::add_vertex(boostGraphObj);
859 tempGraph[1][meshEdgeId] = tempGraphVertId++;
864 localEdges[localEdgeOffset + edgeCnt++] =
865 tempGraph[1][meshEdgeId];
866 vwgts_map[tempGraph[1][meshEdgeId]] = nEdgeIntCoeffs;
870 localEdgeOffset += nEdges;
874 for (
auto &pIt : periodicFaces)
876 if (!pIt.second[0].isLocal)
879 meshFaceId = pIt.first;
880 ASSERTL0(graph[2].count(meshFaceId) == 0,
881 "This periodic boundary edge has been specified before");
882 boost::add_vertex(boostGraphObj);
883 tempGraph[2][meshFaceId] = tempGraphVertId++;
884 nFaceIntCoeffs = FaceSize[meshFaceId];
888 else if (pIt.first < pIt.second[0].id)
890 ASSERTL0(graph[2].count(pIt.first) == 0,
891 "This periodic boundary face has been specified before");
892 ASSERTL0(graph[2].count(pIt.second[0].id) == 0,
893 "This periodic boundary face has been specified before");
895 boost::add_vertex(boostGraphObj);
896 tempGraph[2][pIt.first] = tempGraphVertId;
897 tempGraph[2][pIt.second[0].id] = tempGraphVertId++;
898 nFaceIntCoeffs = FaceSize[pIt.first];
905 for (i = 0; i < locExpVector.size(); ++i)
907 exp = locExpVector[i];
908 nFaces = exp->GetGeom()->GetNumFaces();
910 for (j = 0; j < nFaces; ++j)
912 nFaceIntCoeffs = exp->GetTraceIntNcoeffs(j);
913 meshFaceId = exp->GetGeom()->GetFid(j);
914 if (graph[2].count(meshFaceId) == 0)
916 if (tempGraph[2].count(meshFaceId) == 0)
918 boost::add_vertex(boostGraphObj);
919 tempGraph[2][meshFaceId] = tempGraphVertId++;
924 localFaces[localFaceOffset + faceCnt++] =
925 tempGraph[2][meshFaceId];
926 vwgts_map[tempGraph[2][meshFaceId]] = nFaceIntCoeffs;
931 localFaceOffset += nFaces;
937 for (i = 0; i < locExpVector.size(); ++i)
939 exp = locExpVector[i];
940 nVerts = exp->GetNverts();
941 nEdges = exp->GetGeom()->GetNumEdges();
942 nFaces = exp->GetGeom()->GetNumFaces();
949 for (j = 0; j < nVerts; j++)
951 if (localVerts[j + localVertOffset] == -1)
956 for (k = 0; k < nVerts; k++)
958 if (localVerts[k + localVertOffset] == -1)
964 boost::add_edge((
size_t)localVerts[j + localVertOffset],
965 (
size_t)localVerts[k + localVertOffset],
970 for (k = 0; k < nEdges; k++)
972 if (localEdges[k + localEdgeOffset] == -1)
976 boost::add_edge((
size_t)localVerts[j + localVertOffset],
977 (
size_t)localEdges[k + localEdgeOffset],
981 for (k = 0; k < nFaces; k++)
983 if (localFaces[k + localFaceOffset] == -1)
987 boost::add_edge((
size_t)localVerts[j + localVertOffset],
988 (
size_t)localFaces[k + localFaceOffset],
994 for (j = 0; j < nEdges; j++)
996 if (localEdges[j + localEdgeOffset] == -1)
1001 for (k = 0; k < nEdges; k++)
1003 if (localEdges[k + localEdgeOffset] == -1)
1009 boost::add_edge((
size_t)localEdges[j + localEdgeOffset],
1010 (
size_t)localEdges[k + localEdgeOffset],
1015 for (k = 0; k < nVerts; k++)
1017 if (localVerts[k + localVertOffset] == -1)
1021 boost::add_edge((
size_t)localEdges[j + localEdgeOffset],
1022 (
size_t)localVerts[k + localVertOffset],
1026 for (k = 0; k < nFaces; k++)
1028 if (localFaces[k + localFaceOffset] == -1)
1032 boost::add_edge((
size_t)localEdges[j + localEdgeOffset],
1033 (
size_t)localFaces[k + localFaceOffset],
1039 for (j = 0; j < nFaces; j++)
1041 if (localFaces[j + localFaceOffset] == -1)
1046 for (k = 0; k < nFaces; k++)
1048 if (localFaces[k + localFaceOffset] == -1)
1054 boost::add_edge((
size_t)localFaces[j + localFaceOffset],
1055 (
size_t)localFaces[k + localFaceOffset],
1060 for (k = 0; k < nVerts; k++)
1062 if (localVerts[k + localVertOffset] == -1)
1066 boost::add_edge((
size_t)localFaces[j + localFaceOffset],
1067 (
size_t)localVerts[k + localVertOffset],
1071 for (k = 0; k < nEdges; k++)
1073 if (localEdges[k + localEdgeOffset] == -1)
1077 boost::add_edge((
size_t)localFaces[j + localFaceOffset],
1078 (
size_t)localEdges[k + localEdgeOffset],
1083 localVertOffset += nVerts;
1084 localEdgeOffset += nEdges;
1085 localFaceOffset += nFaces;
1095 vector<long> procVerts, procEdges, procFaces;
1096 set<int> foundVerts, foundEdges, foundFaces;
1101 for (i = cnt = 0; i < locExpVector.size(); ++i)
1104 exp = locExpVector[elmtid];
1105 for (j = 0; j < exp->GetNverts(); ++j)
1107 int vid = exp->GetGeom()->GetVid(j) + 1;
1108 if (foundVerts.count(vid) == 0)
1110 procVerts.push_back(vid);
1111 foundVerts.insert(vid);
1115 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1117 int eid = exp->GetGeom()->GetEid(j) + 1;
1119 if (foundEdges.count(eid) == 0)
1121 procEdges.push_back(eid);
1122 foundEdges.insert(eid);
1126 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1128 int fid = exp->GetGeom()->GetFid(j) + 1;
1130 if (foundFaces.count(fid) == 0)
1132 procFaces.push_back(fid);
1133 foundFaces.insert(fid);
1138 int unique_verts = foundVerts.size();
1139 int unique_edges = foundEdges.size();
1140 int unique_faces = foundFaces.size();
1142 bool verbose =
m_session->DefinesCmdLineArgument(
"verbose");
1156 if (unique_edges > 0)
1164 if (unique_faces > 0)
1174 for (i = 0; i < unique_verts; ++i)
1178 if (graph[0].count(procVerts[i] - 1) == 0)
1180 partVerts.insert(tempGraph[0][procVerts[i] - 1]);
1185 for (i = 0; i < unique_edges; ++i)
1189 if (graph[1].count(procEdges[i] - 1) == 0)
1191 partVerts.insert(tempGraph[1][procEdges[i] - 1]);
1196 for (i = 0; i < unique_faces; ++i)
1200 if (graph[2].count(procFaces[i] - 1) == 0)
1202 partVerts.insert(tempGraph[2][procFaces[i] - 1]);
1208 for (
auto &pIt : periodicVerts)
1210 if (graph[0].count(pIt.first) == 0)
1212 partVerts.insert(tempGraph[0][pIt.first]);
1215 for (
auto &pIt : periodicEdges)
1217 if (graph[1].count(pIt.first) == 0)
1219 partVerts.insert(tempGraph[1][pIt.first]);
1222 for (
auto &pIt : periodicFaces)
1224 if (graph[2].count(pIt.first) == 0)
1226 partVerts.insert(tempGraph[2][pIt.first]);
1231 int nGraphVerts = tempGraphVertId;
1235 ASSERTL1(vwgts_map.size() == nGraphVerts,
"Non matching dimensions");
1236 for (i = 0; i < nGraphVerts; ++i)
1238 vwgts[i] = vwgts_map[i];
1269 bottomUpGraph, partVerts,
1276 "Unrecognised solution type: " +
1302 for (
auto &mapIt : tempGraph[0])
1304 graph[0][mapIt.first] = iperm[mapIt.second] + graphVertId;
1306 for (
auto &mapIt : tempGraph[1])
1308 graph[1][mapIt.first] = iperm[mapIt.second] + graphVertId;
1310 for (
auto &mapIt : tempGraph[2])
1312 graph[2][mapIt.first] = iperm[mapIt.second] + graphVertId;
1323 const int numLocalCoeffs,
const ExpList &locExp,
1325 const bool checkIfSystemSingular,
const std::string variable,
1328 :
AssemblyMap(pSession, locExp.GetComm(), variable)
1331 int p,
q, numModes0, numModes1;
1333 int meshVertId, meshEdgeId, meshEdgeId2, meshFaceId, meshFaceId2;
1335 int nEdgeInteriorCoeffs;
1336 int firstNonDirGraphVertId;
1348 bool verbose =
m_session->DefinesCmdLineArgument(
"verbose");
1355 vector<map<int, int>> faceModes(2);
1356 map<int, LibUtilities::ShapeType> faceType;
1358 set<int> extraDirVerts, extraDirEdges;
1363 for (i = 0; i < locExpVector.size(); ++i)
1365 exp = locExpVector[i];
1367 for (j = 0; j < exp->GetNverts(); ++j)
1369 dofs[0][exp->GetGeom()->GetVid(j)] = 1;
1372 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1375 if (exp->GetGeom()->GetNumFaces())
1385 if (dofs[1].count(exp->GetGeom()->GetEid(j)) > 0)
1387 if (dofs[1][exp->GetGeom()->GetEid(j)] != nEdgeInt)
1391 (exp->GetBasisType(1) ==
1393 (exp->GetBasisType(2) ==
1395 (exp->GetBasisType(2) ==
1397 "CG with variable order only available with "
1400 dofs[1][exp->GetGeom()->GetEid(j)] =
1401 min(dofs[1][exp->GetGeom()->GetEid(j)], nEdgeInt);
1405 dofs[1][exp->GetGeom()->GetEid(j)] = nEdgeInt;
1409 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1411 faceOrient = exp->GetGeom()->GetForient(j);
1412 meshFaceId = exp->GetGeom()->GetFid(j);
1413 exp->GetTraceNumModes(j, numModes0, numModes1, faceOrient);
1415 if (faceModes[0].count(meshFaceId) > 0)
1417 faceModes[0][meshFaceId] =
1418 min(faceModes[0][meshFaceId], numModes0);
1420 faceModes[1][meshFaceId] =
1421 min(faceModes[1][meshFaceId], numModes1);
1425 faceModes[0][meshFaceId] = numModes0;
1426 faceModes[1][meshFaceId] = numModes1;
1430 geom = std::dynamic_pointer_cast<SpatialDomains::Geometry3D>(
1432 faceType[meshFaceId] = geom->GetFace(j)->GetShapeType();
1438 for (
auto &pIt : periodicEdges)
1440 for (i = 0; i < pIt.second.size(); ++i)
1442 meshEdgeId2 = pIt.second[i].id;
1443 if (dofs[1].count(meshEdgeId2) == 0)
1445 dofs[1][meshEdgeId2] = 1e6;
1449 for (
auto &pIt : periodicFaces)
1451 for (i = 0; i < pIt.second.size(); ++i)
1453 meshFaceId2 = pIt.second[i].id;
1454 if (faceModes[0].count(meshFaceId2) == 0)
1456 faceModes[0][meshFaceId2] = 1e6;
1457 faceModes[1][meshFaceId2] = 1e6;
1469 for (
auto &dofIt : dofs[1])
1471 edgeId[i] = dofIt.first + 1;
1477 for (i = 0; i < dofs[1].size(); i++)
1479 dofs[1][edgeId[i] - 1] = (int)(edgeDof[i] + 0.5);
1482 for (
auto &pIt : periodicEdges)
1484 meshEdgeId = pIt.first;
1485 for (i = 0; i < pIt.second.size(); ++i)
1487 meshEdgeId2 = pIt.second[i].id;
1488 if (dofs[1][meshEdgeId2] < dofs[1][meshEdgeId])
1490 dofs[1][meshEdgeId] = dofs[1][meshEdgeId2];
1500 for (
auto dofIt = faceModes[0].begin(), dofIt2 = faceModes[1].begin();
1501 dofIt != faceModes[0].end(); dofIt++, dofIt2++, i++)
1503 faceId[i] = dofIt->first + 1;
1511 for (i = 0; i < faceModes[0].size(); i++)
1513 faceModes[0][faceId[i] - 1] = (int)(faceP[i] + 0.5);
1514 faceModes[1][faceId[i] - 1] = (int)(faceQ[i] + 0.5);
1517 for (
auto &pIt : periodicFaces)
1519 meshFaceId = pIt.first;
1520 for (i = 0; i < pIt.second.size(); ++i)
1522 meshFaceId2 = pIt.second[i].id;
1523 if (faceModes[0][meshFaceId2] < faceModes[0][meshFaceId])
1525 faceModes[0][meshFaceId] = faceModes[0][meshFaceId2];
1527 if (faceModes[1][meshFaceId2] < faceModes[1][meshFaceId])
1529 faceModes[1][meshFaceId] = faceModes[1][meshFaceId2];
1535 for (i = 0; i < faceModes[0].size(); i++)
1537 P = faceModes[0][faceId[i] - 1];
1538 Q = faceModes[1][faceId[i] - 1];
1542 dofs[2][faceId[i] - 1] =
1549 dofs[2][faceId[i] - 1] =
1560 int nExtraDirichlet;
1562 m_session->LoadParameter(
"MDSwitch", mdswitch, 10);
1565 locExp, bndCondExp, bndCondVec, checkIfSystemSingular, periodicVerts,
1566 periodicEdges, periodicFaces, graph, bottomUpGraph, extraDirVerts,
1567 extraDirEdges, firstNonDirGraphVertId, nExtraDirichlet, mdswitch);
1581 graph[0].size() + graph[1].size() + graph[2].size() + 1, 0);
1583 graphVertOffset[0] = 0;
1585 for (i = 0; i < locExpVector.size(); ++i)
1587 exp = locExpVector[i];
1589 for (j = 0; j < exp->GetNverts(); ++j)
1591 meshVertId = exp->GetGeom()->GetVid(j);
1592 graphVertOffset[graph[0][meshVertId] + 1] = 1;
1595 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1597 if (exp->GetGeom()->GetNumFaces())
1599 nEdgeInteriorCoeffs =
1606 meshEdgeId = exp->GetGeom()->GetEid(j);
1607 graphVertOffset[graph[1][meshEdgeId] + 1] = dofs[1][meshEdgeId];
1611 if (nEdgeInteriorCoeffs &&
1618 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1620 meshFaceId = exp->GetGeom()->GetFid(j);
1621 graphVertOffset[graph[2][meshFaceId] + 1] = dofs[2][meshFaceId];
1625 for (i = 1; i < graphVertOffset.size(); i++)
1627 graphVertOffset[i] += graphVertOffset[i - 1];
1658 (
unsigned int)locExpVector[i]->NumBndryCoeffs();
1660 (
unsigned int)locExpVector[i]->GetNcoeffs() -
1661 locExpVector[i]->NumBndryCoeffs();
1678 for (i = 0; i < locExpVector.size(); ++i)
1680 exp = locExpVector[i];
1683 int nbdry = exp->NumBndryCoeffs();
1684 int nint = exp->GetNcoeffs() - nbdry;
1689 exp->GetBoundaryMap(bmap);
1690 exp->GetInteriorMap(imap);
1692 for (j = 0; j < nbdry; ++j)
1697 for (j = 0; j < nint; ++j)
1702 for (j = 0; j < exp->GetNverts(); ++j)
1704 meshVertId = exp->GetGeom()->GetVid(j);
1708 graphVertOffset[graph[0][meshVertId]];
1711 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1713 if (exp->GetGeom()->GetNumFaces())
1715 nEdgeInteriorCoeffs =
1722 edgeOrient = exp->GetGeom()->GetEorient(j);
1723 meshEdgeId = exp->GetGeom()->GetEid(j);
1725 auto pIt = periodicEdges.find(meshEdgeId);
1730 if (pIt != periodicEdges.end())
1732 pair<int, StdRegions::Orientation> idOrient =
1735 edgeOrient = idOrient.second;
1738 if (exp->GetGeom()->GetNumFaces())
1741 ->GetEdgeInteriorToElementMap(j, edgeInteriorMap,
1742 edgeInteriorSign, edgeOrient);
1746 exp->GetTraceInteriorToElementMap(j, edgeInteriorMap,
1747 edgeInteriorSign, edgeOrient);
1751 for (k = 0; k < dofs[1][meshEdgeId]; ++k)
1754 graphVertOffset[graph[1][meshEdgeId]] + k;
1756 for (k = dofs[1][meshEdgeId]; k < nEdgeInteriorCoeffs; ++k)
1764 for (k = 0; k < dofs[1][meshEdgeId]; ++k)
1769 for (k = dofs[1][meshEdgeId]; k < nEdgeInteriorCoeffs; ++k)
1776 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1778 faceOrient = exp->GetGeom()->GetForient(j);
1779 meshFaceId = exp->GetGeom()->GetFid(j);
1781 auto pIt = periodicFaces.find(meshFaceId);
1783 if (pIt != periodicFaces.end() &&
1784 meshFaceId == min(meshFaceId, pIt->second[0].id))
1787 pIt->second[0].orient);
1790 exp->GetTraceInteriorToElementMap(j, faceInteriorMap,
1791 faceInteriorSign, faceOrient);
1794 exp->GetTraceNumModes(j, numModes0, numModes1, faceOrient);
1795 switch (faceType[meshFaceId])
1801 for (
q = 2;
q < numModes1;
q++)
1803 for (
p = 2;
p < numModes0;
p++)
1805 if ((
p < faceModes[0][meshFaceId]) &&
1806 (
q < faceModes[1][meshFaceId]))
1809 faceInteriorMap[kLoc]] =
1810 graphVertOffset[graph[2][meshFaceId]] + k;
1814 faceInteriorMap[kLoc]] =
1822 faceInteriorMap[kLoc]] = 0;
1826 faceInteriorMap[kLoc]] =
1839 for (
p = 2;
p < numModes0;
p++)
1841 for (
q = 1;
q < numModes1 -
p;
q++)
1843 if ((
p < faceModes[0][meshFaceId]) &&
1844 (
p +
q < faceModes[1][meshFaceId]))
1847 faceInteriorMap[kLoc]] =
1848 graphVertOffset[graph[2][meshFaceId]] + k;
1852 faceInteriorMap[kLoc]] =
1860 faceInteriorMap[kLoc]] = 0;
1864 faceInteriorMap[kLoc]] =
1874 ASSERTL0(
false,
"Shape not recognised");
1882 map<int, pair<int, int>> traceToElmtTraceMap;
1885 for (cnt = i = 0; i < locExpVector.size(); ++i)
1887 exp = locExpVector[i];
1889 for (j = 0; j < exp->GetNtraces(); ++j)
1891 id = exp->GetGeom()->GetTid(j);
1893 traceToElmtTraceMap[id] = pair<int, int>(i, j);
1899 map<int, pair<int, NekDouble>> GloDirBndCoeffToLocalCoeff;
1900 set<int> CoeffOnDirTrace;
1904 for (i = 0; i < bndCondExp.size(); i++)
1906 set<int> foundExtraVerts, foundExtraEdges;
1907 for (j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
1909 bndExp = bndCondExp[i]->GetExp(j);
1910 cnt = offset + bndCondExp[i]->GetCoeff_Offset(j);
1912 int id = bndExp->GetGeom()->GetGlobalID();
1914 ASSERTL1(traceToElmtTraceMap.count(
id) > 0,
1915 "Failed to find trace id");
1917 int eid = traceToElmtTraceMap[id].first;
1918 int tid = traceToElmtTraceMap[id].second;
1920 exp = locExpVector[eid];
1921 int dim = exp->GetShapeDimension();
1932 exp->GetTraceToElementMap(tid, maparray, signarray,
1933 exp->GetGeom()->GetEorient(tid),
1934 bndExp->GetBasisNumModes(0));
1938 exp->GetTraceToElementMap(tid, maparray, signarray,
1939 exp->GetGeom()->GetForient(tid),
1940 bndExp->GetBasisNumModes(0),
1941 bndExp->GetBasisNumModes(1));
1944 for (k = 0; k < bndExp->GetNcoeffs(); k++)
1961 for (k = 0; k < bndExp->GetNcoeffs(); k++)
1972 if (bndConditions[i]->GetBoundaryConditionType() ==
1975 CoeffOnDirTrace.insert(locid);
1979 GloDirBndCoeffToLocalCoeff[gloid] =
1980 pair<int, NekDouble>(locid,
sign);
1984 offset += bndCondExp[i]->GetNcoeffs();
2000 for (i = 0; i < locExpVector.size(); ++i)
2004 exp = locExpVector[i];
2006 exp->GetBoundaryMap(bndmap);
2008 for (j = 0; j < bndmap.size(); ++j)
2010 k = cnt + bndmap[j];
2012 if (CoeffOnDirTrace.count(k) == 0)
2018 if (GloDirBndCoeffToLocalCoeff.count(gloid))
2020 int locid = GloDirBndCoeffToLocalCoeff[gloid].first;
2035 gloParaDirBnd[gloid] = gloid;
2041 cnt += exp->GetNcoeffs();
2075 int gloid = gloParaDirBnd[i];
2078 gloParaDirBnd[i] = 0.0;
2094 for (i = 0; i < numLocalCoeffs; ++i)
2096 paraDirBnd[i] = 0.0;
2105 paraDirBnd[i] = gloParaDirBnd[id];
2107 if (gloParaDirBnd[
id] > 0.0)
2134 firstNonDirGraphVertId);
2136 for (i = 0; i < locExpVector.size(); ++i)
2138 exp = locExpVector[i];
2140 for (j = 0; j < exp->GetNverts(); ++j)
2142 meshVertId = exp->GetGeom()->GetVid(j);
2144 if (graph[0][meshVertId] >= firstNonDirGraphVertId)
2146 vwgts_perm[graph[0][meshVertId] -
2147 firstNonDirGraphVertId] =
2148 dofs[0][meshVertId];
2152 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
2154 meshEdgeId = exp->GetGeom()->GetEid(j);
2156 if (graph[1][meshEdgeId] >= firstNonDirGraphVertId)
2158 vwgts_perm[graph[1][meshEdgeId] -
2159 firstNonDirGraphVertId] =
2160 dofs[1][meshEdgeId];
2164 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
2166 meshFaceId = exp->GetGeom()->GetFid(j);
2168 if (graph[2][meshFaceId] >= firstNonDirGraphVertId)
2170 vwgts_perm[graph[2][meshFaceId] -
2171 firstNonDirGraphVertId] =
2172 dofs[2][meshFaceId];
2177 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
2225 const vector<PeriodicEntity> &periodicEdges)
2227 int minId = periodicEdges[0].id;
2231 for (k = 1; k < periodicEdges.size(); ++k)
2233 if (periodicEdges[k].
id < minId)
2235 minId = min(minId, periodicEdges[k].
id);
2240 minId = min(minId, meshEdgeId);
2242 if (meshEdgeId != minId)
2253 return make_pair(minId, edgeOrient);
2278 int tmp1 = (int)faceOrient - 5;
2279 int tmp2 = (int)perFaceOrient - 5;
2281 int flipDir1Map[8] = {2, 3, 0, 1, 6, 7, 4, 5};
2282 int flipDir2Map[8] = {1, 0, 3, 2, 5, 4, 7, 6};
2283 int transposeMap[8] = {4, 5, 6, 7, 0, 2, 1, 3};
2288 tmp1 = transposeMap[tmp1];
2292 if (tmp2 == 2 || tmp2 == 3 || tmp2 == 6 || tmp2 == 7)
2294 tmp1 = flipDir1Map[tmp1];
2300 tmp1 = flipDir2Map[tmp1];
2332 int maxBndGlobalId = 0;
2343 const bool verbose = locExp.
GetSession()->DefinesCmdLineArgument(
"verbose");
2354 for (i = 0; i < locExpVector.size(); ++i)
2356 exp = locExpVector[i];
2358 int nv = exp->GetNverts();
2359 int ne = exp->GetGeom()->GetNumEdges();
2360 int nf = exp->GetGeom()->GetNumFaces();
2367 for (j = 0; j < ne; ++j)
2379 maxEdgeDof = (dof > maxEdgeDof ? dof : maxEdgeDof);
2381 for (j = 0; j < nf; ++j)
2383 dof = exp->GetTraceIntNcoeffs(j);
2384 maxFaceDof = (dof > maxFaceDof ? dof : maxFaceDof);
2386 exp->GetInteriorMap(interiorMap);
2387 dof = interiorMap.size();
2388 maxIntDof = (dof > maxIntDof ? dof : maxIntDof);
2400 for (i = 0; i < locExpVector.size(); ++i)
2402 exp = locExpVector[i];
2405 int nf = exp->GetGeom()->GetNumFaces();
2408 for (j = 0; j < exp->GetNverts(); ++j)
2410 meshVertId = exp->GetGeom()->GetVid(j);
2413 auto pIt = perVerts.find(meshVertId);
2414 if (pIt != perVerts.end())
2416 for (k = 0; k < pIt->second.size(); ++k)
2418 meshVertId = min(meshVertId, pIt->second[k].id);
2426 (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
2430 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
2432 meshEdgeId = exp->GetGeom()->GetEid(j);
2433 auto pIt = perEdges.find(meshEdgeId);
2434 edgeOrient = exp->GetGeom()->GetEorient(j);
2436 if (pIt != perEdges.end())
2438 pair<int, StdRegions::Orientation> idOrient =
2441 meshEdgeId = idOrient.first;
2442 edgeOrient = idOrient.second;
2448 ->GetEdgeInteriorToElementMap(j, edgeInteriorMap,
2449 edgeInteriorSign, edgeOrient);
2456 edgeInteriorSign, edgeOrient);
2457 dof = exp->GetTraceNcoeffs(j) - 2;
2462 for (k = 0, l = 0; k < dof; ++k)
2473 nVert + meshEdgeId * maxEdgeDof + l + 1;
2477 (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
2483 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
2485 faceOrient = exp->GetGeom()->GetForient(j);
2487 meshFaceId = exp->GetGeom()->GetFid(j);
2489 auto pIt = perFaces.find(meshFaceId);
2490 if (pIt != perFaces.end())
2492 if (meshFaceId == min(meshFaceId, pIt->second[0].id))
2495 faceOrient, pIt->second[0].orient);
2497 meshFaceId = min(meshFaceId, pIt->second[0].id);
2500 exp->GetTraceInteriorToElementMap(j, faceInteriorMap,
2501 faceInteriorSign, faceOrient);
2502 dof = exp->GetTraceIntNcoeffs(j);
2504 for (k = 0, l = 0; k < dof; ++k)
2515 meshFaceId * maxFaceDof +
2521 (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
2527 exp->GetInteriorMap(interiorMap);
2528 dof = interiorMap.size();
2529 elementId = (exp->GetGeom())->GetGlobalID();
2530 for (k = 0; k < dof; ++k)
2534 nFace * maxFaceDof +
2535 elementId * maxIntDof + k + 1;
2579 const std::shared_ptr<LocalRegions::ExpansionVector> exp = locexp.
GetExp();
2580 int nelmts = exp->size();
2581 const bool verbose = locexp.
GetSession()->DefinesCmdLineArgument(
"verbose");
2586 returnval->m_solnType = solnType;
2587 returnval->m_preconType =
"Null";
2588 returnval->m_maxStaticCondLevel = 0;
2589 returnval->m_signChange =
false;
2590 returnval->m_comm =
m_comm;
2593 for (i = 0; i < nelmts; ++i)
2595 nverts += (*exp)[i]->GetNverts();
2598 returnval->m_numLocalCoeffs = nverts;
2609 for (i = 0; i < nelmts; ++i)
2611 for (j = 0; j < (*exp)[i]->GetNverts(); ++j)
2613 returnval->m_localToGlobalMap[cnt] =
2614 returnval->m_localToGlobalBndMap[cnt] =
2616 GlobCoeffs[returnval->m_localToGlobalMap[cnt]] = 1;
2621 returnval->m_numLocalDirBndCoeffs++;
2625 cnt1 += (*exp)[i]->GetNcoeffs();
2632 if (GlobCoeffs[i] != -1)
2634 GlobCoeffs[i] = cnt++;
2639 returnval->m_numGlobalCoeffs = cnt;
2644 if (GlobCoeffs[i] != -1)
2646 returnval->m_numGlobalDirBndCoeffs++;
2655 int nglocoeffs = returnval->m_numGlobalCoeffs;
2660 for (i = 0; i < nverts; ++i)
2662 cnt = returnval->m_localToGlobalMap[i];
2663 returnval->m_localToGlobalMap[i] = GlobCoeffs[cnt];
2665 returnval->m_globalToUniversalMap[GlobCoeffs[cnt]] =
2671 for (
unsigned int i = 0; i < nglocoeffs; ++i)
2673 tmp[i] = returnval->m_globalToUniversalMap[i];
2675 returnval->m_gsh =
Gs::Init(tmp, vCommRow, verbose);
2677 for (
unsigned int i = 0; i < nglocoeffs; ++i)
2679 returnval->m_globalToUniversalMapUnique[i] = (tmp[i] >= 0 ? 1 : 0);
2684 for (i = 0; i < nverts; ++i)
2686 cnt = returnval->m_localToGlobalMap[i];
2687 returnval->m_localToGlobalMap[i] = GlobCoeffs[cnt];
2721 for (j = 0; j < locSize; j++)
2736 bwidth = (bwidth > (maxId - minId)) ? bwidth : (maxId - minId);
2797 if (global.data() ==
loc.data())
2835 if (global.data() ==
loc.data())
2866 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.
virtual int v_GetFullSystemBandWidth() const override
int m_maxStaticCondLevel
Maximum static condensation level.
int m_numNonDirVertexModes
Number of non Dirichlet vertex modes.
virtual const Array< OneD, const int > & v_GetLocalToGlobalMap() override
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 const Array< OneD, const int > & v_GetGlobalToUniversalMap() override
virtual void v_GlobalToLocal(const Array< OneD, const NekDouble > &global, Array< OneD, NekDouble > &loc) const override
virtual const Array< OneD, const int > & v_GetExtraDirEdges() override
virtual const Array< OneD, const int > & v_GetGlobalToUniversalMapUnique() override
int m_numNonDirEdges
Number of Dirichlet edges.
virtual int v_GetNumDirFaces() const override
virtual void v_Assemble(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global) const override
std::set< int > m_parallelDirBndSign
Set indicating the local coeffs just touching parallel dirichlet boundary that have a sign change.
virtual int v_GetNumDirEdges() const override
Array< OneD, int > m_globalToUniversalMapUnique
Integer map of unique process coeffs to universal space (signed)
Array< OneD, int > m_extraDirEdges
Extra dirichlet edges in parallel.
virtual int v_GetNumNonDirVertexModes() const override
int m_numNonDirFaceModes
Number of non Dirichlet face modes.
virtual void v_UniversalAssemble(Array< OneD, NekDouble > &pGlobal) const override
int m_numNonDirEdgeModes
Number of non Dirichlet edge modes.
virtual int v_GetNumNonDirFaces() const override
int m_numDirEdges
Number of Dirichlet edges.
virtual AssemblyMapSharedPtr v_LinearSpaceMap(const ExpList &locexp, GlobalSysSolnType solnType) override
Construct an AssemblyMapCG object which corresponds to the linear space of the current object.
virtual int v_GetNumNonDirEdgeModes() const override
int m_fullSystemBandWidth
Bandwith of the full matrix system (no static condensation).
Array< OneD, int > m_localToGlobalMap
Integer map of local coeffs to global space.
AssemblyMapCG(const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &comm, const std::string variable="DefaultVar")
Default constructor.
int m_numDirFaces
Number of Dirichlet faces.
virtual void v_LocalToGlobal(const Array< OneD, const NekDouble > &loc, Array< OneD, NekDouble > &global, bool useComm) const override
void SetUpUniversalC0ContMap(const ExpList &locExp, const PeriodicMap &perVerts=NullPeriodicMap, const PeriodicMap &perEdges=NullPeriodicMap, const PeriodicMap &perFaces=NullPeriodicMap)
Array< OneD, NekDouble > m_localToGlobalSign
Integer sign of local coeffs to global space.
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_globalToUniversalMap
Integer map of process coeffs to universal space.
virtual int v_GetNumNonDirFaceModes() const override
virtual ~AssemblyMapCG()
Destructor.
virtual int v_GetNumNonDirEdges() const override
virtual const Array< OneD, NekDouble > & v_GetLocalToGlobalSign() const override
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_bndCondCoeffsToLocalCoeffsMap
Integer map of bnd cond coeffs to local coefficients.
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_localToLocalIntMap
Integer map of local boundary coeffs to local interior system numbering.
int m_numGlobalCoeffs
Total number of global coefficients.
Array< OneD, int > m_globalToUniversalBndMap
Integer map of process coeffs to universal space.
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, NekDouble > m_localToGlobalBndSign
Integer sign of local boundary coeffs to global space.
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.
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.
Array< OneD, int > m_localToGlobalBndMap
Integer map of local coeffs to global Boundary Dofs.
Gs::gs_data * m_dirBndGsh
gs gather communication to impose Dirhichlet BCs.
size_t m_hash
Hash for map.
Array< OneD, int > m_globalToUniversalBndMapUnique
Integer map of unique process coeffs to universal space (signed)
LibUtilities::CommSharedPtr m_comm
Communicator.
Array< OneD, int > m_localToLocalBndMap
Integer map of local boundary coeffs to local boundary system numbering.
Array< OneD, NekDouble > m_bndCondCoeffsToLocalCoeffsSign
Integer map of sign of bnd cond coeffs to local coefficients.
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 local contiguous list of coeffs correspoinding to element n.
std::shared_ptr< LibUtilities::SessionReader > GetSession() const
Returns the session object.
const std::shared_ptr< LocalRegions::ExpansionVector > GetExp() const
This function returns the vector of elements in the expansion.
std::shared_ptr< LibUtilities::Comm > GetComm() const
Returns the comm 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 gs_data * Init(const Nektar::Array< OneD, long > pId, const LibUtilities::CommSharedPtr &pComm, bool verbose=true)
Initialise Gather-Scatter map.
static void Finalise(gs_data *pGsh)
Deallocates the GSLib mapping data.
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 .
@ P
Monomial polynomials .
@ 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.
std::shared_ptr< Geometry3D > Geometry3DSharedPtr
@ eDir1FwdDir1_Dir2FwdDir2
std::vector< double > q(NPUPPER *NPUPPER)
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)