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>
80 const bool checkIfSystemSingular,
const PeriodicMap &periodicVerts,
83 set<int> &extraDirVerts, set<int> &extraDirEdges,
84 int &firstNonDirGraphVertId,
int &nExtraDirichlet,
int mdswitch)
89 int meshVertId, meshEdgeId, meshFaceId;
90 int meshVertId2, meshEdgeId2;
99 for (i = 0; i < bndCondExp.size(); i++)
104 if (bndConditions[0][i]->GetBoundaryConditionType() ==
114 for (k = 0; k < bndConditions.size(); ++k)
116 if (bndConditions[k][i]->GetBoundaryConditionType() ==
121 if (bndConditions[k][i]->GetBoundaryConditionType() !=
130 for (j = 0; j < bndCondExp[i]->GetNumElmts(); ++j)
133 for (k = 0; k < bndExp->GetNverts(); ++k)
135 if (vMaxVertId < bndExp->GetGeom()->GetVid(k))
137 vMaxVertId = bndExp->
GetGeom()->GetVid(k);
143 if (cnt == bndConditions.size())
145 for (j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
147 bndExp = bndCondExp[i]->GetExp(j);
149 for (k = 0; k < bndExp->GetNverts(); k++)
151 meshVertId = bndExp->GetGeom()->GetVid(k);
152 if (graph[0].count(meshVertId) == 0)
154 graph[0][meshVertId] = graphVertId++;
158 const int bndDim = bndExp->GetNumBases();
161 for (k = 0; k < bndExp->GetNtraces(); k++)
163 meshEdgeId = bndExp->GetGeom()->GetEid(k);
164 if (graph[1].count(meshEdgeId) == 0)
166 graph[1][meshEdgeId] = graphVertId++;
172 meshFaceId = bndExp->GetGeom()->GetGlobalID();
173 if (graph[bndDim].count(meshFaceId) == 0)
175 graph[bndDim][meshFaceId] = graphVertId++;
208 int n = vComm->GetSize();
209 int p = vComm->GetRank();
211 if (vComm->IsSerial())
225 vertcounts[
p] = graph[0].size();
226 edgecounts[
p] = graph[1].size();
230 for (i = 1; i < n; ++i)
232 vertoffsets[i] = vertoffsets[i - 1] + vertcounts[i - 1];
233 edgeoffsets[i] = edgeoffsets[i - 1] + edgecounts[i - 1];
244 for (
auto &it : graph[0])
246 vertlist[vertoffsets[
p] + i++] = it.first;
251 for (
auto &it : graph[1])
253 edgelist[edgeoffsets[
p] + i++] = it.first;
261 map<int, int> extraDirVertIds, extraDirEdgeIds;
271 for (i = 0; i < n; ++i)
278 for (j = 0; j < locExpVector.size(); j++)
280 exp = locExpVector[j];
282 for (k = 0; k < exp->GetNverts(); k++)
284 meshVertId = exp->GetGeom()->GetVid(k);
285 if (graph[0].count(meshVertId) == 0)
287 for (l = 0; l < vertcounts[i]; ++l)
289 if (vertlist[vertoffsets[i] + l] == meshVertId)
291 extraDirVertIds[meshVertId] = i;
292 graph[0][meshVertId] = graphVertId++;
299 for (k = 0; k < exp->GetGeom()->GetNumEdges(); k++)
301 meshEdgeId = exp->GetGeom()->GetEid(k);
302 if (graph[1].count(meshEdgeId) == 0)
304 for (l = 0; l < edgecounts[i]; ++l)
306 if (edgelist[edgeoffsets[i] + l] == meshEdgeId)
308 extraDirEdgeIds[meshEdgeId] = i;
309 graph[1][meshEdgeId] = graphVertId++;
310 if (exp->GetGeom()->GetNumFaces())
314 ->GetEdgeNcoeffs(k) -
332 for (
auto &it : extraDirEdgeIds)
334 meshEdgeId = it.first;
344 for (i = 0; i < n; ++i)
352 vertcounts[
p] = extraDirVertIds.size();
353 edgecounts[
p] = extraDirEdgeIds.size();
359 vertoffsets[0] = edgeoffsets[0] = 0;
361 for (i = 1; i < n; ++i)
363 vertoffsets[i] = vertoffsets[i - 1] + vertcounts[i - 1];
364 edgeoffsets[i] = edgeoffsets[i - 1] + edgecounts[i - 1];
373 for (
auto &it : extraDirVertIds)
375 vertids[vertoffsets[
p] + i] = it.first;
376 vertprocs[vertoffsets[
p] + i] = it.second;
381 for (
auto &it : extraDirEdgeIds)
383 edgeids[edgeoffsets[
p] + i] = it.first;
384 edgeprocs[edgeoffsets[
p] + i] = it.second;
395 for (i = 0; i < nTotVerts; ++i)
397 if (
p == vertprocs[i])
399 extraDirVerts.insert(vertids[i]);
404 for (i = 0; i < nTotEdges; ++i)
406 if (
p == edgeprocs[i])
408 extraDirEdges.insert(edgeids[i]);
419 bcminvertid[
p] = vMaxVertId;
435 if (
m_session->DefinesParameter(
"SingularVertex"))
437 m_session->LoadParameter(
"SingularVertex", meshVertId);
439 else if (vMaxVertId == -1)
442 meshVertId = locExpVector[0]->GetGeom()->GetVid(0);
448 meshVertId = bcminvertid[
p];
451 if (graph[0].count(meshVertId) == 0)
453 graph[0][meshVertId] = graphVertId++;
469 for (i = 0; i < locExpVector.size(); ++i)
471 for (j = 0; j < locExpVector[i]->GetNverts(); ++j)
473 if (locExpVector[i]->GetGeom()->GetVid(j) != meshVertId)
478 if (graph[0].count(meshVertId) == 0)
480 graph[0][meshVertId] = graphVertId++;
495 if (graph[0].count(meshVertId) == 0)
501 gId = graph[0][meshVertId];
504 for (
auto &pIt : periodicVerts)
511 if (pIt.first == meshVertId)
513 gId = gId < 0 ? graphVertId++ : gId;
514 graph[0][meshVertId] = gId;
516 for (i = 0; i < pIt.second.size(); ++i)
518 if (pIt.second[i].isLocal)
520 graph[0][pIt.second[i].id] = graph[0][meshVertId];
527 for (i = 0; i < pIt.second.size(); ++i)
529 if (pIt.second[i].id == meshVertId)
538 gId = gId < 0 ? graphVertId++ : gId;
539 graph[0][pIt.first] = gId;
541 for (i = 0; i < pIt.second.size(); ++i)
543 if (pIt.second[i].isLocal)
545 graph[0][pIt.second[i].id] = graph[0][pIt.first];
555 firstNonDirGraphVertId = graphVertId;
557 typedef boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS>
559 BoostGraph boostGraphObj;
561 vector<map<int, int>> tempGraph(3);
562 map<int, int> vwgts_map;
567 int tempGraphVertId = 0;
568 int localVertOffset = 0;
569 int localEdgeOffset = 0;
570 int localFaceOffset = 0;
588 map<int, int> EdgeSize;
589 map<int, int> FaceSize;
592 for (i = 0; i < locExpVector.size(); ++i)
594 exp = locExpVector[i];
595 nEdges = exp->GetGeom()->GetNumEdges();
596 nFaces = exp->GetGeom()->GetNumFaces();
598 nTotalVerts += exp->GetNverts();
599 nTotalEdges += nEdges;
600 nTotalFaces += nFaces;
602 for (j = 0; j < nEdges; ++j)
604 meshEdgeId = exp->GetGeom()->GetEid(j);
617 if (EdgeSize.count(meshEdgeId) > 0)
619 EdgeSize[meshEdgeId] = min(EdgeSize[meshEdgeId], nEdgeInt);
623 EdgeSize[meshEdgeId] = nEdgeInt;
628 for (j = 0; j < nFaces; ++j)
630 meshFaceId = exp->GetGeom()->GetFid(j);
631 if (FaceSize.count(meshFaceId) > 0)
633 FaceSize[meshFaceId] =
634 min(FaceSize[meshFaceId], exp->GetTraceIntNcoeffs(j));
638 FaceSize[meshFaceId] = exp->GetTraceIntNcoeffs(j);
640 FaceSize[meshFaceId] = exp->GetTraceIntNcoeffs(j);
645 for (
auto &pIt : periodicVerts)
647 meshVertId = pIt.first;
650 if (graph[0].count(pIt.first) != 0)
652 for (i = 0; i < pIt.second.size(); ++i)
654 meshVertId2 = pIt.second[i].id;
655 if (graph[0].count(meshVertId2) == 0 && pIt.second[i].isLocal)
657 graph[0][meshVertId2] = graph[0][meshVertId];
664 bool isDirichlet =
false;
665 for (i = 0; i < pIt.second.size(); ++i)
667 if (!pIt.second[i].isLocal)
672 meshVertId2 = pIt.second[i].id;
673 if (graph[0].count(meshVertId2) > 0)
682 graph[0][meshVertId] = graph[0][pIt.second[i].id];
684 for (j = 0; j < pIt.second.size(); ++j)
686 meshVertId2 = pIt.second[i].id;
687 if (j == i || !pIt.second[j].isLocal ||
688 graph[0].count(meshVertId2) > 0)
693 graph[0][meshVertId2] = graph[0][pIt.second[i].id];
700 for (i = 0; i < pIt.second.size(); ++i)
702 if (!pIt.second[i].isLocal)
707 if (tempGraph[0].count(pIt.second[i].id) > 0)
713 if (i == pIt.second.size())
715 boost::add_vertex(boostGraphObj);
716 tempGraph[0][meshVertId] = tempGraphVertId++;
721 tempGraph[0][meshVertId] = tempGraph[0][pIt.second[i].id];
732 for (i = 0; i < locExpVector.size(); ++i)
734 exp = locExpVector[i];
736 nVerts = exp->GetNverts();
737 for (j = 0; j < nVerts; ++j)
739 meshVertId = exp->GetGeom()->GetVid(j);
740 if (graph[0].count(meshVertId) == 0)
742 if (tempGraph[0].count(meshVertId) == 0)
744 boost::add_vertex(boostGraphObj);
745 tempGraph[0][meshVertId] = tempGraphVertId++;
748 localVerts[localVertOffset + vertCnt++] =
749 tempGraph[0][meshVertId];
750 vwgts_map[tempGraph[0][meshVertId]] = 1;
754 localVertOffset += nVerts;
758 for (
auto &pIt : periodicEdges)
760 meshEdgeId = pIt.first;
763 if (graph[1].count(pIt.first) != 0)
765 for (i = 0; i < pIt.second.size(); ++i)
767 meshEdgeId2 = pIt.second[i].id;
768 if (graph[1].count(meshEdgeId2) == 0 && pIt.second[i].isLocal)
770 graph[1][meshEdgeId2] = graph[1][meshEdgeId];
777 bool isDirichlet =
false;
778 for (i = 0; i < pIt.second.size(); ++i)
780 if (!pIt.second[i].isLocal)
785 meshEdgeId2 = pIt.second[i].id;
786 if (graph[1].count(meshEdgeId2) > 0)
795 graph[1][meshEdgeId] = graph[1][pIt.second[i].id];
797 for (j = 0; j < pIt.second.size(); ++j)
799 meshEdgeId2 = pIt.second[i].id;
800 if (j == i || !pIt.second[j].isLocal ||
801 graph[1].count(meshEdgeId2) > 0)
806 graph[1][meshEdgeId2] = graph[1][pIt.second[i].id];
813 for (i = 0; i < pIt.second.size(); ++i)
815 if (!pIt.second[i].isLocal)
820 if (tempGraph[1].count(pIt.second[i].id) > 0)
826 if (i == pIt.second.size())
828 boost::add_vertex(boostGraphObj);
829 tempGraph[1][meshEdgeId] = tempGraphVertId++;
835 tempGraph[1][meshEdgeId] = tempGraph[1][pIt.second[i].id];
839 int nEdgeIntCoeffs, nFaceIntCoeffs;
842 for (i = 0; i < locExpVector.size(); ++i)
844 exp = locExpVector[i];
846 nEdges = exp->GetGeom()->GetNumEdges();
848 for (j = 0; j < nEdges; ++j)
850 meshEdgeId = exp->GetGeom()->GetEid(j);
851 nEdgeIntCoeffs = EdgeSize[meshEdgeId];
852 if (graph[1].count(meshEdgeId) == 0)
854 if (tempGraph[1].count(meshEdgeId) == 0)
856 boost::add_vertex(boostGraphObj);
857 tempGraph[1][meshEdgeId] = tempGraphVertId++;
862 localEdges[localEdgeOffset + edgeCnt++] =
863 tempGraph[1][meshEdgeId];
864 vwgts_map[tempGraph[1][meshEdgeId]] = nEdgeIntCoeffs;
868 localEdgeOffset += nEdges;
872 for (
auto &pIt : periodicFaces)
874 if (!pIt.second[0].isLocal)
877 meshFaceId = pIt.first;
878 ASSERTL0(graph[2].count(meshFaceId) == 0,
879 "This periodic boundary edge has been specified before");
880 boost::add_vertex(boostGraphObj);
881 tempGraph[2][meshFaceId] = tempGraphVertId++;
882 nFaceIntCoeffs = FaceSize[meshFaceId];
886 else if (pIt.first < pIt.second[0].id)
888 ASSERTL0(graph[2].count(pIt.first) == 0,
889 "This periodic boundary face has been specified before");
890 ASSERTL0(graph[2].count(pIt.second[0].id) == 0,
891 "This periodic boundary face has been specified before");
893 boost::add_vertex(boostGraphObj);
894 tempGraph[2][pIt.first] = tempGraphVertId;
895 tempGraph[2][pIt.second[0].id] = tempGraphVertId++;
896 nFaceIntCoeffs = FaceSize[pIt.first];
903 for (i = 0; i < locExpVector.size(); ++i)
905 exp = locExpVector[i];
906 nFaces = exp->GetGeom()->GetNumFaces();
908 for (j = 0; j < nFaces; ++j)
910 nFaceIntCoeffs = exp->GetTraceIntNcoeffs(j);
911 meshFaceId = exp->GetGeom()->GetFid(j);
912 if (graph[2].count(meshFaceId) == 0)
914 if (tempGraph[2].count(meshFaceId) == 0)
916 boost::add_vertex(boostGraphObj);
917 tempGraph[2][meshFaceId] = tempGraphVertId++;
922 localFaces[localFaceOffset + faceCnt++] =
923 tempGraph[2][meshFaceId];
924 vwgts_map[tempGraph[2][meshFaceId]] = nFaceIntCoeffs;
929 localFaceOffset += nFaces;
935 for (i = 0; i < locExpVector.size(); ++i)
937 exp = locExpVector[i];
938 nVerts = exp->GetNverts();
939 nEdges = exp->GetGeom()->GetNumEdges();
940 nFaces = exp->GetGeom()->GetNumFaces();
947 for (j = 0; j < nVerts; j++)
949 if (localVerts[j + localVertOffset] == -1)
954 for (k = 0; k < nVerts; k++)
956 if (localVerts[k + localVertOffset] == -1)
962 boost::add_edge((
size_t)localVerts[j + localVertOffset],
963 (
size_t)localVerts[k + localVertOffset],
968 for (k = 0; k < nEdges; k++)
970 if (localEdges[k + localEdgeOffset] == -1)
974 boost::add_edge((
size_t)localVerts[j + localVertOffset],
975 (
size_t)localEdges[k + localEdgeOffset],
979 for (k = 0; k < nFaces; k++)
981 if (localFaces[k + localFaceOffset] == -1)
985 boost::add_edge((
size_t)localVerts[j + localVertOffset],
986 (
size_t)localFaces[k + localFaceOffset],
992 for (j = 0; j < nEdges; j++)
994 if (localEdges[j + localEdgeOffset] == -1)
999 for (k = 0; k < nEdges; k++)
1001 if (localEdges[k + localEdgeOffset] == -1)
1007 boost::add_edge((
size_t)localEdges[j + localEdgeOffset],
1008 (
size_t)localEdges[k + localEdgeOffset],
1013 for (k = 0; k < nVerts; k++)
1015 if (localVerts[k + localVertOffset] == -1)
1019 boost::add_edge((
size_t)localEdges[j + localEdgeOffset],
1020 (
size_t)localVerts[k + localVertOffset],
1024 for (k = 0; k < nFaces; k++)
1026 if (localFaces[k + localFaceOffset] == -1)
1030 boost::add_edge((
size_t)localEdges[j + localEdgeOffset],
1031 (
size_t)localFaces[k + localFaceOffset],
1037 for (j = 0; j < nFaces; j++)
1039 if (localFaces[j + localFaceOffset] == -1)
1044 for (k = 0; k < nFaces; k++)
1046 if (localFaces[k + localFaceOffset] == -1)
1052 boost::add_edge((
size_t)localFaces[j + localFaceOffset],
1053 (
size_t)localFaces[k + localFaceOffset],
1058 for (k = 0; k < nVerts; k++)
1060 if (localVerts[k + localVertOffset] == -1)
1064 boost::add_edge((
size_t)localFaces[j + localFaceOffset],
1065 (
size_t)localVerts[k + localVertOffset],
1069 for (k = 0; k < nEdges; k++)
1071 if (localEdges[k + localEdgeOffset] == -1)
1075 boost::add_edge((
size_t)localFaces[j + localFaceOffset],
1076 (
size_t)localEdges[k + localEdgeOffset],
1081 localVertOffset += nVerts;
1082 localEdgeOffset += nEdges;
1083 localFaceOffset += nFaces;
1093 vector<long> procVerts, procEdges, procFaces;
1094 set<int> foundVerts, foundEdges, foundFaces;
1099 for (i = cnt = 0; i < locExpVector.size(); ++i)
1102 exp = locExpVector[elmtid];
1103 for (j = 0; j < exp->GetNverts(); ++j)
1105 int vid = exp->GetGeom()->GetVid(j) + 1;
1106 if (foundVerts.count(vid) == 0)
1108 procVerts.push_back(vid);
1109 foundVerts.insert(vid);
1113 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1115 int eid = exp->GetGeom()->GetEid(j) + 1;
1117 if (foundEdges.count(eid) == 0)
1119 procEdges.push_back(eid);
1120 foundEdges.insert(eid);
1124 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1126 int fid = exp->GetGeom()->GetFid(j) + 1;
1128 if (foundFaces.count(fid) == 0)
1130 procFaces.push_back(fid);
1131 foundFaces.insert(fid);
1136 int unique_verts = foundVerts.size();
1137 int unique_edges = foundEdges.size();
1138 int unique_faces = foundFaces.size();
1140 bool verbose =
m_session->DefinesCmdLineArgument(
"verbose");
1154 if (unique_edges > 0)
1162 if (unique_faces > 0)
1172 for (i = 0; i < unique_verts; ++i)
1176 if (graph[0].count(procVerts[i] - 1) == 0)
1178 partVerts.insert(tempGraph[0][procVerts[i] - 1]);
1183 for (i = 0; i < unique_edges; ++i)
1187 if (graph[1].count(procEdges[i] - 1) == 0)
1189 partVerts.insert(tempGraph[1][procEdges[i] - 1]);
1194 for (i = 0; i < unique_faces; ++i)
1198 if (graph[2].count(procFaces[i] - 1) == 0)
1200 partVerts.insert(tempGraph[2][procFaces[i] - 1]);
1206 for (
auto &pIt : periodicVerts)
1208 if (graph[0].count(pIt.first) == 0)
1210 partVerts.insert(tempGraph[0][pIt.first]);
1213 for (
auto &pIt : periodicEdges)
1215 if (graph[1].count(pIt.first) == 0)
1217 partVerts.insert(tempGraph[1][pIt.first]);
1220 for (
auto &pIt : periodicFaces)
1222 if (graph[2].count(pIt.first) == 0)
1224 partVerts.insert(tempGraph[2][pIt.first]);
1229 int nGraphVerts = tempGraphVertId;
1233 ASSERTL1(vwgts_map.size() == nGraphVerts,
"Non matching dimensions");
1234 for (i = 0; i < nGraphVerts; ++i)
1236 vwgts[i] = vwgts_map[i];
1267 bottomUpGraph, partVerts,
1274 "Unrecognised solution type: " +
1300 for (
auto &mapIt : tempGraph[0])
1302 graph[0][mapIt.first] = iperm[mapIt.second] + graphVertId;
1304 for (
auto &mapIt : tempGraph[1])
1306 graph[1][mapIt.first] = iperm[mapIt.second] + graphVertId;
1308 for (
auto &mapIt : tempGraph[2])
1310 graph[2][mapIt.first] = iperm[mapIt.second] + graphVertId;
1321 const int numLocalCoeffs,
const ExpList &locExp,
1323 const bool checkIfSystemSingular,
const std::string variable,
1326 :
AssemblyMap(pSession, locExp.GetComm(), variable)
1329 int p,
q, numModes0, numModes1;
1331 int meshVertId, meshEdgeId, meshEdgeId2, meshFaceId, meshFaceId2;
1333 int nEdgeInteriorCoeffs;
1334 int firstNonDirGraphVertId;
1346 bool verbose =
m_session->DefinesCmdLineArgument(
"verbose");
1353 vector<map<int, int>> faceModes(2);
1354 map<int, LibUtilities::ShapeType> faceType;
1356 set<int> extraDirVerts, extraDirEdges;
1361 for (i = 0; i < locExpVector.size(); ++i)
1363 exp = locExpVector[i];
1365 for (j = 0; j < exp->GetNverts(); ++j)
1367 dofs[0][exp->GetGeom()->GetVid(j)] = 1;
1370 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1373 if (exp->GetGeom()->GetNumFaces())
1383 if (dofs[1].count(exp->GetGeom()->GetEid(j)) > 0)
1385 if (dofs[1][exp->GetGeom()->GetEid(j)] != nEdgeInt)
1389 (exp->GetBasisType(1) ==
1391 (exp->GetBasisType(2) ==
1393 (exp->GetBasisType(2) ==
1395 "CG with variable order only available with "
1398 dofs[1][exp->GetGeom()->GetEid(j)] =
1399 min(dofs[1][exp->GetGeom()->GetEid(j)], nEdgeInt);
1403 dofs[1][exp->GetGeom()->GetEid(j)] = nEdgeInt;
1407 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1409 faceOrient = exp->GetGeom()->GetForient(j);
1410 meshFaceId = exp->GetGeom()->GetFid(j);
1411 exp->GetTraceNumModes(j, numModes0, numModes1, faceOrient);
1413 if (faceModes[0].count(meshFaceId) > 0)
1415 faceModes[0][meshFaceId] =
1416 min(faceModes[0][meshFaceId], numModes0);
1418 faceModes[1][meshFaceId] =
1419 min(faceModes[1][meshFaceId], numModes1);
1423 faceModes[0][meshFaceId] = numModes0;
1424 faceModes[1][meshFaceId] = numModes1;
1428 geom = std::dynamic_pointer_cast<SpatialDomains::Geometry3D>(
1430 faceType[meshFaceId] = geom->GetFace(j)->GetShapeType();
1436 for (
auto &pIt : periodicEdges)
1438 for (i = 0; i < pIt.second.size(); ++i)
1440 meshEdgeId2 = pIt.second[i].id;
1441 if (dofs[1].count(meshEdgeId2) == 0)
1443 dofs[1][meshEdgeId2] = 1e6;
1447 for (
auto &pIt : periodicFaces)
1449 for (i = 0; i < pIt.second.size(); ++i)
1451 meshFaceId2 = pIt.second[i].id;
1452 if (faceModes[0].count(meshFaceId2) == 0)
1454 faceModes[0][meshFaceId2] = 1e6;
1455 faceModes[1][meshFaceId2] = 1e6;
1467 for (
auto &dofIt : dofs[1])
1469 edgeId[i] = dofIt.first + 1;
1475 for (i = 0; i < dofs[1].size(); i++)
1477 dofs[1][edgeId[i] - 1] = (int)(edgeDof[i] + 0.5);
1480 for (
auto &pIt : periodicEdges)
1482 meshEdgeId = pIt.first;
1483 for (i = 0; i < pIt.second.size(); ++i)
1485 meshEdgeId2 = pIt.second[i].id;
1486 if (dofs[1][meshEdgeId2] < dofs[1][meshEdgeId])
1488 dofs[1][meshEdgeId] = dofs[1][meshEdgeId2];
1498 for (
auto dofIt = faceModes[0].begin(), dofIt2 = faceModes[1].begin();
1499 dofIt != faceModes[0].end(); dofIt++, dofIt2++, i++)
1501 faceId[i] = dofIt->first + 1;
1509 for (i = 0; i < faceModes[0].size(); i++)
1511 faceModes[0][faceId[i] - 1] = (int)(faceP[i] + 0.5);
1512 faceModes[1][faceId[i] - 1] = (int)(faceQ[i] + 0.5);
1515 for (
auto &pIt : periodicFaces)
1517 meshFaceId = pIt.first;
1518 for (i = 0; i < pIt.second.size(); ++i)
1520 meshFaceId2 = pIt.second[i].id;
1521 if (faceModes[0][meshFaceId2] < faceModes[0][meshFaceId])
1523 faceModes[0][meshFaceId] = faceModes[0][meshFaceId2];
1525 if (faceModes[1][meshFaceId2] < faceModes[1][meshFaceId])
1527 faceModes[1][meshFaceId] = faceModes[1][meshFaceId2];
1533 for (i = 0; i < faceModes[0].size(); i++)
1535 P = faceModes[0][faceId[i] - 1];
1536 Q = faceModes[1][faceId[i] - 1];
1540 dofs[2][faceId[i] - 1] =
1547 dofs[2][faceId[i] - 1] =
1558 int nExtraDirichlet;
1560 m_session->LoadParameter(
"MDSwitch", mdswitch, 10);
1563 locExp, bndCondExp, bndCondVec, checkIfSystemSingular, periodicVerts,
1564 periodicEdges, periodicFaces, graph, bottomUpGraph, extraDirVerts,
1565 extraDirEdges, firstNonDirGraphVertId, nExtraDirichlet, mdswitch);
1579 graph[0].size() + graph[1].size() + graph[2].size() + 1, 0);
1581 graphVertOffset[0] = 0;
1583 for (i = 0; i < locExpVector.size(); ++i)
1585 exp = locExpVector[i];
1587 for (j = 0; j < exp->GetNverts(); ++j)
1589 meshVertId = exp->GetGeom()->GetVid(j);
1590 graphVertOffset[graph[0][meshVertId] + 1] = 1;
1593 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1595 if (exp->GetGeom()->GetNumFaces())
1597 nEdgeInteriorCoeffs =
1604 meshEdgeId = exp->GetGeom()->GetEid(j);
1605 graphVertOffset[graph[1][meshEdgeId] + 1] = dofs[1][meshEdgeId];
1609 if (nEdgeInteriorCoeffs &&
1616 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1618 meshFaceId = exp->GetGeom()->GetFid(j);
1619 graphVertOffset[graph[2][meshFaceId] + 1] = dofs[2][meshFaceId];
1623 for (i = 1; i < graphVertOffset.size(); i++)
1625 graphVertOffset[i] += graphVertOffset[i - 1];
1656 (
unsigned int)locExpVector[i]->NumBndryCoeffs();
1658 (
unsigned int)locExpVector[i]->GetNcoeffs() -
1659 locExpVector[i]->NumBndryCoeffs();
1676 for (i = 0; i < locExpVector.size(); ++i)
1678 exp = locExpVector[i];
1681 int nbdry = exp->NumBndryCoeffs();
1682 int nint = exp->GetNcoeffs() - nbdry;
1687 exp->GetBoundaryMap(bmap);
1688 exp->GetInteriorMap(imap);
1690 for (j = 0; j < nbdry; ++j)
1695 for (j = 0; j < nint; ++j)
1700 for (j = 0; j < exp->GetNverts(); ++j)
1702 meshVertId = exp->GetGeom()->GetVid(j);
1706 graphVertOffset[graph[0][meshVertId]];
1709 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1711 if (exp->GetGeom()->GetNumFaces())
1713 nEdgeInteriorCoeffs =
1720 edgeOrient = exp->GetGeom()->GetEorient(j);
1721 meshEdgeId = exp->GetGeom()->GetEid(j);
1723 auto pIt = periodicEdges.find(meshEdgeId);
1728 if (pIt != periodicEdges.end())
1730 pair<int, StdRegions::Orientation> idOrient =
1733 edgeOrient = idOrient.second;
1736 if (exp->GetGeom()->GetNumFaces())
1739 ->GetEdgeInteriorToElementMap(j, edgeInteriorMap,
1740 edgeInteriorSign, edgeOrient);
1744 exp->GetTraceInteriorToElementMap(j, edgeInteriorMap,
1745 edgeInteriorSign, edgeOrient);
1749 for (k = 0; k < dofs[1][meshEdgeId]; ++k)
1752 graphVertOffset[graph[1][meshEdgeId]] + k;
1754 for (k = dofs[1][meshEdgeId]; k < nEdgeInteriorCoeffs; ++k)
1762 for (k = 0; k < dofs[1][meshEdgeId]; ++k)
1767 for (k = dofs[1][meshEdgeId]; k < nEdgeInteriorCoeffs; ++k)
1774 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1776 faceOrient = exp->GetGeom()->GetForient(j);
1777 meshFaceId = exp->GetGeom()->GetFid(j);
1779 auto pIt = periodicFaces.find(meshFaceId);
1781 if (pIt != periodicFaces.end() &&
1782 meshFaceId == min(meshFaceId, pIt->second[0].id))
1785 pIt->second[0].orient);
1788 exp->GetTraceInteriorToElementMap(j, faceInteriorMap,
1789 faceInteriorSign, faceOrient);
1792 exp->GetTraceNumModes(j, numModes0, numModes1, faceOrient);
1793 switch (faceType[meshFaceId])
1799 for (
q = 2;
q < numModes1;
q++)
1801 for (
p = 2;
p < numModes0;
p++)
1803 if ((
p < faceModes[0][meshFaceId]) &&
1804 (
q < faceModes[1][meshFaceId]))
1807 faceInteriorMap[kLoc]] =
1808 graphVertOffset[graph[2][meshFaceId]] + k;
1812 faceInteriorMap[kLoc]] =
1820 faceInteriorMap[kLoc]] = 0;
1824 faceInteriorMap[kLoc]] =
1837 for (
p = 2;
p < numModes0;
p++)
1839 for (
q = 1;
q < numModes1 -
p;
q++)
1841 if ((
p < faceModes[0][meshFaceId]) &&
1842 (
p +
q < faceModes[1][meshFaceId]))
1845 faceInteriorMap[kLoc]] =
1846 graphVertOffset[graph[2][meshFaceId]] + k;
1850 faceInteriorMap[kLoc]] =
1858 faceInteriorMap[kLoc]] = 0;
1862 faceInteriorMap[kLoc]] =
1872 ASSERTL0(
false,
"Shape not recognised");
1880 map<int, pair<int, int>> traceToElmtTraceMap;
1883 for (cnt = i = 0; i < locExpVector.size(); ++i)
1885 exp = locExpVector[i];
1887 for (j = 0; j < exp->GetNtraces(); ++j)
1889 id = exp->GetGeom()->GetTid(j);
1891 traceToElmtTraceMap[id] = pair<int, int>(i, j);
1897 map<int, pair<int, NekDouble>> GloDirBndCoeffToLocalCoeff;
1898 set<int> CoeffOnDirTrace;
1902 for (i = 0; i < bndCondExp.size(); i++)
1904 set<int> foundExtraVerts, foundExtraEdges;
1905 for (j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
1907 bndExp = bndCondExp[i]->GetExp(j);
1908 cnt = offset + bndCondExp[i]->GetCoeff_Offset(j);
1910 int id = bndExp->GetGeom()->GetGlobalID();
1912 ASSERTL1(traceToElmtTraceMap.count(
id) > 0,
1913 "Failed to find trace id");
1915 int eid = traceToElmtTraceMap[id].first;
1916 int tid = traceToElmtTraceMap[id].second;
1918 exp = locExpVector[eid];
1919 int dim = exp->GetShapeDimension();
1930 exp->GetTraceToElementMap(tid, maparray, signarray,
1931 exp->GetGeom()->GetEorient(tid),
1932 bndExp->GetBasisNumModes(0));
1936 exp->GetTraceToElementMap(tid, maparray, signarray,
1937 exp->GetGeom()->GetForient(tid),
1938 bndExp->GetBasisNumModes(0),
1939 bndExp->GetBasisNumModes(1));
1942 for (k = 0; k < bndExp->GetNcoeffs(); k++)
1959 for (k = 0; k < bndExp->GetNcoeffs(); k++)
1970 if (bndConditions[i]->GetBoundaryConditionType() ==
1973 CoeffOnDirTrace.insert(locid);
1977 GloDirBndCoeffToLocalCoeff[gloid] =
1978 pair<int, NekDouble>(locid,
sign);
1982 offset += bndCondExp[i]->GetNcoeffs();
1998 for (i = 0; i < locExpVector.size(); ++i)
2002 exp = locExpVector[i];
2004 exp->GetBoundaryMap(bndmap);
2006 for (j = 0; j < bndmap.size(); ++j)
2008 k = cnt + bndmap[j];
2010 if (CoeffOnDirTrace.count(k) == 0)
2016 if (GloDirBndCoeffToLocalCoeff.count(gloid))
2018 int locid = GloDirBndCoeffToLocalCoeff[gloid].first;
2033 gloParaDirBnd[gloid] = gloid;
2039 cnt += exp->GetNcoeffs();
2073 int gloid = gloParaDirBnd[i];
2076 gloParaDirBnd[i] = 0.0;
2092 for (i = 0; i < numLocalCoeffs; ++i)
2094 paraDirBnd[i] = 0.0;
2103 paraDirBnd[i] = gloParaDirBnd[id];
2105 if (gloParaDirBnd[
id] > 0.0)
2132 firstNonDirGraphVertId);
2134 for (i = 0; i < locExpVector.size(); ++i)
2136 exp = locExpVector[i];
2138 for (j = 0; j < exp->GetNverts(); ++j)
2140 meshVertId = exp->GetGeom()->GetVid(j);
2142 if (graph[0][meshVertId] >= firstNonDirGraphVertId)
2144 vwgts_perm[graph[0][meshVertId] -
2145 firstNonDirGraphVertId] =
2146 dofs[0][meshVertId];
2150 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
2152 meshEdgeId = exp->GetGeom()->GetEid(j);
2154 if (graph[1][meshEdgeId] >= firstNonDirGraphVertId)
2156 vwgts_perm[graph[1][meshEdgeId] -
2157 firstNonDirGraphVertId] =
2158 dofs[1][meshEdgeId];
2162 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
2164 meshFaceId = exp->GetGeom()->GetFid(j);
2166 if (graph[2][meshFaceId] >= firstNonDirGraphVertId)
2168 vwgts_perm[graph[2][meshFaceId] -
2169 firstNonDirGraphVertId] =
2170 dofs[2][meshFaceId];
2175 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
2223 const vector<PeriodicEntity> &periodicEdges)
2225 int minId = periodicEdges[0].id;
2229 for (k = 1; k < periodicEdges.size(); ++k)
2231 if (periodicEdges[k].
id < minId)
2233 minId = min(minId, periodicEdges[k].
id);
2238 minId = min(minId, meshEdgeId);
2240 if (meshEdgeId != minId)
2251 return make_pair(minId, edgeOrient);
2276 int tmp1 = (int)faceOrient - 5;
2277 int tmp2 = (int)perFaceOrient - 5;
2279 int flipDir1Map[8] = {2, 3, 0, 1, 6, 7, 4, 5};
2280 int flipDir2Map[8] = {1, 0, 3, 2, 5, 4, 7, 6};
2281 int transposeMap[8] = {4, 5, 6, 7, 0, 2, 1, 3};
2286 tmp1 = transposeMap[tmp1];
2290 if (tmp2 == 2 || tmp2 == 3 || tmp2 == 6 || tmp2 == 7)
2292 tmp1 = flipDir1Map[tmp1];
2298 tmp1 = flipDir2Map[tmp1];
2330 int maxBndGlobalId = 0;
2341 const bool verbose = locExp.
GetSession()->DefinesCmdLineArgument(
"verbose");
2352 for (i = 0; i < locExpVector.size(); ++i)
2354 exp = locExpVector[i];
2356 int nv = exp->GetNverts();
2357 int ne = exp->GetGeom()->GetNumEdges();
2358 int nf = exp->GetGeom()->GetNumFaces();
2365 for (j = 0; j < ne; ++j)
2377 maxEdgeDof = (dof > maxEdgeDof ? dof : maxEdgeDof);
2379 for (j = 0; j < nf; ++j)
2381 dof = exp->GetTraceIntNcoeffs(j);
2382 maxFaceDof = (dof > maxFaceDof ? dof : maxFaceDof);
2384 exp->GetInteriorMap(interiorMap);
2385 dof = interiorMap.size();
2386 maxIntDof = (dof > maxIntDof ? dof : maxIntDof);
2398 for (i = 0; i < locExpVector.size(); ++i)
2400 exp = locExpVector[i];
2403 int nf = exp->GetGeom()->GetNumFaces();
2406 for (j = 0; j < exp->GetNverts(); ++j)
2408 meshVertId = exp->GetGeom()->GetVid(j);
2411 auto pIt = perVerts.find(meshVertId);
2412 if (pIt != perVerts.end())
2414 for (k = 0; k < pIt->second.size(); ++k)
2416 meshVertId = min(meshVertId, pIt->second[k].id);
2424 (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
2428 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
2430 meshEdgeId = exp->GetGeom()->GetEid(j);
2431 auto pIt = perEdges.find(meshEdgeId);
2432 edgeOrient = exp->GetGeom()->GetEorient(j);
2434 if (pIt != perEdges.end())
2436 pair<int, StdRegions::Orientation> idOrient =
2439 meshEdgeId = idOrient.first;
2440 edgeOrient = idOrient.second;
2446 ->GetEdgeInteriorToElementMap(j, edgeInteriorMap,
2447 edgeInteriorSign, edgeOrient);
2454 edgeInteriorSign, edgeOrient);
2455 dof = exp->GetTraceNcoeffs(j) - 2;
2460 for (k = 0, l = 0; k < dof; ++k)
2471 nVert + meshEdgeId * maxEdgeDof + l + 1;
2475 (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
2481 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
2483 faceOrient = exp->GetGeom()->GetForient(j);
2485 meshFaceId = exp->GetGeom()->GetFid(j);
2487 auto pIt = perFaces.find(meshFaceId);
2488 if (pIt != perFaces.end())
2490 if (meshFaceId == min(meshFaceId, pIt->second[0].id))
2493 faceOrient, pIt->second[0].orient);
2495 meshFaceId = min(meshFaceId, pIt->second[0].id);
2498 exp->GetTraceInteriorToElementMap(j, faceInteriorMap,
2499 faceInteriorSign, faceOrient);
2500 dof = exp->GetTraceIntNcoeffs(j);
2502 for (k = 0, l = 0; k < dof; ++k)
2513 meshFaceId * maxFaceDof +
2519 (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
2525 exp->GetInteriorMap(interiorMap);
2526 dof = interiorMap.size();
2527 elementId = (exp->GetGeom())->GetGlobalID();
2528 for (k = 0; k < dof; ++k)
2532 nFace * maxFaceDof +
2533 elementId * maxIntDof + k + 1;
2577 const std::shared_ptr<LocalRegions::ExpansionVector> exp = locexp.
GetExp();
2578 int nelmts = exp->size();
2579 const bool verbose = locexp.
GetSession()->DefinesCmdLineArgument(
"verbose");
2584 returnval->m_solnType = solnType;
2585 returnval->m_preconType =
"Null";
2586 returnval->m_maxStaticCondLevel = 0;
2587 returnval->m_signChange =
false;
2588 returnval->m_comm =
m_comm;
2591 for (i = 0; i < nelmts; ++i)
2593 nverts += (*exp)[i]->GetNverts();
2596 returnval->m_numLocalCoeffs = nverts;
2607 for (i = 0; i < nelmts; ++i)
2609 for (j = 0; j < (*exp)[i]->GetNverts(); ++j)
2611 returnval->m_localToGlobalMap[cnt] =
2612 returnval->m_localToGlobalBndMap[cnt] =
2614 GlobCoeffs[returnval->m_localToGlobalMap[cnt]] = 1;
2619 returnval->m_numLocalDirBndCoeffs++;
2623 cnt1 += (*exp)[i]->GetNcoeffs();
2630 if (GlobCoeffs[i] != -1)
2632 GlobCoeffs[i] = cnt++;
2637 returnval->m_numGlobalCoeffs = cnt;
2642 if (GlobCoeffs[i] != -1)
2644 returnval->m_numGlobalDirBndCoeffs++;
2653 int nglocoeffs = returnval->m_numGlobalCoeffs;
2658 for (i = 0; i < nverts; ++i)
2660 cnt = returnval->m_localToGlobalMap[i];
2661 returnval->m_localToGlobalMap[i] = GlobCoeffs[cnt];
2663 returnval->m_globalToUniversalMap[GlobCoeffs[cnt]] =
2669 for (
unsigned int i = 0; i < nglocoeffs; ++i)
2671 tmp[i] = returnval->m_globalToUniversalMap[i];
2673 returnval->m_gsh =
Gs::Init(tmp, vCommRow, verbose);
2675 for (
unsigned int i = 0; i < nglocoeffs; ++i)
2677 returnval->m_globalToUniversalMapUnique[i] = (tmp[i] >= 0 ? 1 : 0);
2682 for (i = 0; i < nverts; ++i)
2684 cnt = returnval->m_localToGlobalMap[i];
2685 returnval->m_localToGlobalMap[i] = GlobCoeffs[cnt];
2719 for (j = 0; j < locSize; j++)
2734 bwidth = (bwidth > (maxId - minId)) ? bwidth : (maxId - minId);
2795 if (global.data() ==
loc.data())
2833 if (global.data() ==
loc.data())
2864 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 v_GetFullSystemBandWidth() const override
int m_maxStaticCondLevel
Maximum static condensation level.
int m_numNonDirVertexModes
Number of non Dirichlet vertex modes.
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)
const Array< OneD, const int > & v_GetGlobalToUniversalMap() override
void v_GlobalToLocal(const Array< OneD, const NekDouble > &global, Array< OneD, NekDouble > &loc) const override
const Array< OneD, const int > & v_GetExtraDirEdges() override
const Array< OneD, const int > & v_GetGlobalToUniversalMapUnique() override
int m_numNonDirEdges
Number of Dirichlet edges.
int v_GetNumDirFaces() const override
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.
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.
int v_GetNumNonDirVertexModes() const override
int m_numNonDirFaceModes
Number of non Dirichlet face modes.
void v_UniversalAssemble(Array< OneD, NekDouble > &pGlobal) const override
int m_numNonDirEdgeModes
Number of non Dirichlet edge modes.
int v_GetNumNonDirFaces() const override
int m_numDirEdges
Number of Dirichlet edges.
AssemblyMapSharedPtr v_LinearSpaceMap(const ExpList &locexp, GlobalSysSolnType solnType) override
Construct an AssemblyMapCG object which corresponds to the linear space of the current object.
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.
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.
int v_GetNumNonDirFaceModes() const override
int v_GetNumNonDirEdges() const override
const Array< OneD, NekDouble > & v_GetLocalToGlobalSign() const override
~AssemblyMapCG() override
Destructor.
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)
std::size_t hash_range(Iter first, Iter last)
void Gathr(I n, const T *x, const I *y, T *z)
Gather vector z[i] = x[y[i]].
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 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)