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++)
103 if (bndConditions[0][i]->GetBoundaryConditionType() ==
113 for (k = 0; k < bndConditions.size(); ++k)
115 if (bndConditions[k][i]->GetBoundaryConditionType() ==
120 if (bndConditions[k][i]->GetBoundaryConditionType() !=
129 for (j = 0; j < bndCondExp[i]->GetNumElmts(); ++j)
132 for (k = 0; k < bndExp->GetNverts(); ++k)
134 if (vMaxVertId < bndExp->GetGeom()->GetVid(k))
142 if (cnt == bndConditions.size())
144 for (j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
146 bndExp = bndCondExp[i]->GetExp(j);
148 for (k = 0; k < bndExp->GetNverts(); k++)
150 meshVertId = bndExp->GetGeom()->GetVid(k);
151 if (graph[0].count(meshVertId) == 0)
153 graph[0][meshVertId] = graphVertId++;
157 const int bndDim = bndExp->GetNumBases();
160 for (k = 0; k < bndExp->GetNtraces(); k++)
162 meshEdgeId = bndExp->GetGeom()->GetEid(k);
163 if (graph[1].count(meshEdgeId) == 0)
165 graph[1][meshEdgeId] = graphVertId++;
171 meshFaceId = bndExp->GetGeom()->GetGlobalID();
172 if (graph[bndDim].count(meshFaceId) == 0)
174 graph[bndDim][meshFaceId] = graphVertId++;
207 int n = vRowComm->GetSize();
208 int p = vRowComm->GetRank();
210 if (vRowComm->IsSerial())
224 vertcounts[p] = graph[0].size();
225 edgecounts[p] = graph[1].size();
229 for (i = 1; i < n; ++i)
231 vertoffsets[i] = vertoffsets[i - 1] + vertcounts[i - 1];
232 edgeoffsets[i] = edgeoffsets[i - 1] + edgecounts[i - 1];
243 for (
auto &it : graph[0])
245 vertlist[vertoffsets[p] + i++] = it.first;
250 for (
auto &it : graph[1])
252 edgelist[edgeoffsets[p] + i++] = it.first;
260 map<int, int> extraDirVertIds, extraDirEdgeIds;
270 for (i = 0; i < n; ++i)
277 for (j = 0; j < locExpVector.size(); j++)
279 exp = locExpVector[j];
281 for (k = 0; k < exp->GetNverts(); k++)
283 meshVertId = exp->GetGeom()->GetVid(k);
284 if (graph[0].count(meshVertId) == 0)
286 for (l = 0; l < vertcounts[i]; ++l)
288 if (vertlist[vertoffsets[i] + l] == meshVertId)
290 extraDirVertIds[meshVertId] = i;
291 graph[0][meshVertId] = graphVertId++;
298 for (k = 0; k < exp->GetGeom()->GetNumEdges(); k++)
300 meshEdgeId = exp->GetGeom()->GetEid(k);
301 if (graph[1].count(meshEdgeId) == 0)
303 for (l = 0; l < edgecounts[i]; ++l)
305 if (edgelist[edgeoffsets[i] + l] == meshEdgeId)
307 extraDirEdgeIds[meshEdgeId] = i;
308 graph[1][meshEdgeId] = graphVertId++;
309 if (exp->GetGeom()->GetNumFaces())
313 ->GetEdgeNcoeffs(k) -
331 for (
auto &it : extraDirEdgeIds)
333 meshEdgeId = it.first;
343 for (i = 0; i < n; ++i)
351 vertcounts[p] = extraDirVertIds.size();
352 edgecounts[p] = extraDirEdgeIds.size();
358 vertoffsets[0] = edgeoffsets[0] = 0;
360 for (i = 1; i < n; ++i)
362 vertoffsets[i] = vertoffsets[i - 1] + vertcounts[i - 1];
363 edgeoffsets[i] = edgeoffsets[i - 1] + edgecounts[i - 1];
372 for (
auto &it : extraDirVertIds)
374 vertids[vertoffsets[p] + i] = it.first;
375 vertprocs[vertoffsets[p] + i] = it.second;
380 for (
auto &it : extraDirEdgeIds)
382 edgeids[edgeoffsets[p] + i] = it.first;
383 edgeprocs[edgeoffsets[p] + i] = it.second;
394 for (i = 0; i < nTotVerts; ++i)
396 if (p == vertprocs[i])
398 extraDirVerts.insert(vertids[i]);
403 for (i = 0; i < nTotEdges; ++i)
405 if (p == edgeprocs[i])
407 extraDirEdges.insert(edgeids[i]);
418 bcminvertid[p] = vMaxVertId;
434 if (
m_session->DefinesParameter(
"SingularVertex"))
436 m_session->LoadParameter(
"SingularVertex", meshVertId);
438 else if (vMaxVertId == -1)
441 meshVertId = locExpVector[0]->GetGeom()->GetVid(0);
447 meshVertId = bcminvertid[p];
450 if (graph[0].count(meshVertId) == 0)
452 graph[0][meshVertId] = graphVertId++;
468 for (i = 0; i < locExpVector.size(); ++i)
470 for (j = 0; j < locExpVector[i]->GetNverts(); ++j)
472 if (locExpVector[i]->GetGeom()->GetVid(j) != meshVertId)
477 if (graph[0].count(meshVertId) == 0)
479 graph[0][meshVertId] = graphVertId++;
494 if (graph[0].count(meshVertId) == 0)
500 gId = graph[0][meshVertId];
503 for (
auto &pIt : periodicVerts)
510 if (pIt.first == meshVertId)
512 gId = gId < 0 ? graphVertId++ : gId;
513 graph[0][meshVertId] = gId;
515 for (i = 0; i < pIt.second.size(); ++i)
517 if (pIt.second[i].isLocal)
519 graph[0][pIt.second[i].id] = graph[0][meshVertId];
526 for (i = 0; i < pIt.second.size(); ++i)
528 if (pIt.second[i].id == meshVertId)
537 gId = gId < 0 ? graphVertId++ : gId;
538 graph[0][pIt.first] = gId;
540 for (i = 0; i < pIt.second.size(); ++i)
542 if (pIt.second[i].isLocal)
544 graph[0][pIt.second[i].id] = graph[0][pIt.first];
554 firstNonDirGraphVertId = graphVertId;
556 typedef boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS>
558 BoostGraph boostGraphObj;
560 vector<map<int, int>> tempGraph(3);
561 map<int, int> vwgts_map;
566 int tempGraphVertId = 0;
567 int localVertOffset = 0;
568 int localEdgeOffset = 0;
569 int localFaceOffset = 0;
587 map<int, int> EdgeSize;
588 map<int, int> FaceSize;
591 for (i = 0; i < locExpVector.size(); ++i)
593 exp = locExpVector[i];
594 nEdges = exp->GetGeom()->GetNumEdges();
595 nFaces = exp->GetGeom()->GetNumFaces();
597 nTotalVerts += exp->GetNverts();
598 nTotalEdges += nEdges;
599 nTotalFaces += nFaces;
601 for (j = 0; j < nEdges; ++j)
603 meshEdgeId = exp->GetGeom()->GetEid(j);
616 if (EdgeSize.count(meshEdgeId) > 0)
618 EdgeSize[meshEdgeId] =
min(EdgeSize[meshEdgeId], nEdgeInt);
622 EdgeSize[meshEdgeId] = nEdgeInt;
627 for (j = 0; j < nFaces; ++j)
629 meshFaceId = exp->GetGeom()->GetFid(j);
630 if (FaceSize.count(meshFaceId) > 0)
632 FaceSize[meshFaceId] =
633 min(FaceSize[meshFaceId], exp->GetTraceIntNcoeffs(j));
637 FaceSize[meshFaceId] = exp->GetTraceIntNcoeffs(j);
639 FaceSize[meshFaceId] = exp->GetTraceIntNcoeffs(j);
644 for (
auto &pIt : periodicVerts)
646 meshVertId = pIt.first;
649 if (graph[0].count(pIt.first) != 0)
651 for (i = 0; i < pIt.second.size(); ++i)
653 meshVertId2 = pIt.second[i].id;
654 if (graph[0].count(meshVertId2) == 0 && pIt.second[i].isLocal)
656 graph[0][meshVertId2] = graph[0][meshVertId];
663 bool isDirichlet =
false;
664 for (i = 0; i < pIt.second.size(); ++i)
666 if (!pIt.second[i].isLocal)
671 meshVertId2 = pIt.second[i].id;
672 if (graph[0].count(meshVertId2) > 0)
681 graph[0][meshVertId] = graph[0][pIt.second[i].id];
683 for (j = 0; j < pIt.second.size(); ++j)
685 meshVertId2 = pIt.second[i].id;
686 if (j == i || !pIt.second[j].isLocal ||
687 graph[0].count(meshVertId2) > 0)
692 graph[0][meshVertId2] = graph[0][pIt.second[i].id];
699 for (i = 0; i < pIt.second.size(); ++i)
701 if (!pIt.second[i].isLocal)
706 if (tempGraph[0].count(pIt.second[i].id) > 0)
712 if (i == pIt.second.size())
714 boost::add_vertex(boostGraphObj);
715 tempGraph[0][meshVertId] = tempGraphVertId++;
720 tempGraph[0][meshVertId] = tempGraph[0][pIt.second[i].id];
731 for (i = 0; i < locExpVector.size(); ++i)
733 exp = locExpVector[i];
735 nVerts = exp->GetNverts();
736 for (j = 0; j < nVerts; ++j)
738 meshVertId = exp->GetGeom()->GetVid(j);
739 if (graph[0].count(meshVertId) == 0)
741 if (tempGraph[0].count(meshVertId) == 0)
743 boost::add_vertex(boostGraphObj);
744 tempGraph[0][meshVertId] = tempGraphVertId++;
747 localVerts[localVertOffset + vertCnt++] =
748 tempGraph[0][meshVertId];
749 vwgts_map[tempGraph[0][meshVertId]] = 1;
753 localVertOffset += nVerts;
757 for (
auto &pIt : periodicEdges)
759 meshEdgeId = pIt.first;
762 if (graph[1].count(pIt.first) != 0)
764 for (i = 0; i < pIt.second.size(); ++i)
766 meshEdgeId2 = pIt.second[i].id;
767 if (graph[1].count(meshEdgeId2) == 0 && pIt.second[i].isLocal)
769 graph[1][meshEdgeId2] = graph[1][meshEdgeId];
776 bool isDirichlet =
false;
777 for (i = 0; i < pIt.second.size(); ++i)
779 if (!pIt.second[i].isLocal)
784 meshEdgeId2 = pIt.second[i].id;
785 if (graph[1].count(meshEdgeId2) > 0)
794 graph[1][meshEdgeId] = graph[1][pIt.second[i].id];
796 for (j = 0; j < pIt.second.size(); ++j)
798 meshEdgeId2 = pIt.second[i].id;
799 if (j == i || !pIt.second[j].isLocal ||
800 graph[1].count(meshEdgeId2) > 0)
805 graph[1][meshEdgeId2] = graph[1][pIt.second[i].id];
812 for (i = 0; i < pIt.second.size(); ++i)
814 if (!pIt.second[i].isLocal)
819 if (tempGraph[1].count(pIt.second[i].id) > 0)
825 if (i == pIt.second.size())
827 boost::add_vertex(boostGraphObj);
828 tempGraph[1][meshEdgeId] = tempGraphVertId++;
834 tempGraph[1][meshEdgeId] = tempGraph[1][pIt.second[i].id];
838 int nEdgeIntCoeffs, nFaceIntCoeffs;
841 for (i = 0; i < locExpVector.size(); ++i)
843 exp = locExpVector[i];
845 nEdges = exp->GetGeom()->GetNumEdges();
847 for (j = 0; j < nEdges; ++j)
849 meshEdgeId = exp->GetGeom()->GetEid(j);
850 nEdgeIntCoeffs = EdgeSize[meshEdgeId];
851 if (graph[1].count(meshEdgeId) == 0)
853 if (tempGraph[1].count(meshEdgeId) == 0)
855 boost::add_vertex(boostGraphObj);
856 tempGraph[1][meshEdgeId] = tempGraphVertId++;
861 localEdges[localEdgeOffset + edgeCnt++] =
862 tempGraph[1][meshEdgeId];
863 vwgts_map[tempGraph[1][meshEdgeId]] = nEdgeIntCoeffs;
867 localEdgeOffset += nEdges;
871 for (
auto &pIt : periodicFaces)
873 if (!pIt.second[0].isLocal)
876 meshFaceId = pIt.first;
877 ASSERTL0(graph[2].count(meshFaceId) == 0,
878 "This periodic boundary edge has been specified before");
879 boost::add_vertex(boostGraphObj);
880 tempGraph[2][meshFaceId] = tempGraphVertId++;
881 nFaceIntCoeffs = FaceSize[meshFaceId];
885 else if (pIt.first < pIt.second[0].id)
887 ASSERTL0(graph[2].count(pIt.first) == 0,
888 "This periodic boundary face has been specified before");
889 ASSERTL0(graph[2].count(pIt.second[0].id) == 0,
890 "This periodic boundary face has been specified before");
892 boost::add_vertex(boostGraphObj);
893 tempGraph[2][pIt.first] = tempGraphVertId;
894 tempGraph[2][pIt.second[0].id] = tempGraphVertId++;
895 nFaceIntCoeffs = FaceSize[pIt.first];
902 for (i = 0; i < locExpVector.size(); ++i)
904 exp = locExpVector[i];
905 nFaces = exp->GetGeom()->GetNumFaces();
907 for (j = 0; j < nFaces; ++j)
909 nFaceIntCoeffs = exp->GetTraceIntNcoeffs(j);
910 meshFaceId = exp->GetGeom()->GetFid(j);
911 if (graph[2].count(meshFaceId) == 0)
913 if (tempGraph[2].count(meshFaceId) == 0)
915 boost::add_vertex(boostGraphObj);
916 tempGraph[2][meshFaceId] = tempGraphVertId++;
921 localFaces[localFaceOffset + faceCnt++] =
922 tempGraph[2][meshFaceId];
923 vwgts_map[tempGraph[2][meshFaceId]] = nFaceIntCoeffs;
928 localFaceOffset += nFaces;
934 for (i = 0; i < locExpVector.size(); ++i)
936 exp = locExpVector[i];
937 nVerts = exp->GetNverts();
938 nEdges = exp->GetGeom()->GetNumEdges();
939 nFaces = exp->GetGeom()->GetNumFaces();
946 for (j = 0; j < nVerts; j++)
948 if (localVerts[j + localVertOffset] == -1)
953 for (k = j + 1; k < nVerts; k++)
955 if (localVerts[k + localVertOffset] == -1)
960 boost::add_edge((
size_t)localVerts[j + localVertOffset],
961 (
size_t)localVerts[k + localVertOffset],
965 for (k = 0; k < nEdges; k++)
967 if (localEdges[k + localEdgeOffset] == -1)
971 boost::add_edge((
size_t)localVerts[j + localVertOffset],
972 (
size_t)localEdges[k + localEdgeOffset],
976 for (k = 0; k < nFaces; k++)
978 if (localFaces[k + localFaceOffset] == -1)
982 boost::add_edge((
size_t)localVerts[j + localVertOffset],
983 (
size_t)localFaces[k + localFaceOffset],
989 for (j = 0; j < nEdges; j++)
991 if (localEdges[j + localEdgeOffset] == -1)
996 for (k = j + 1; k < nEdges; k++)
998 if (localEdges[k + localEdgeOffset] == -1)
1002 boost::add_edge((
size_t)localEdges[j + localEdgeOffset],
1003 (
size_t)localEdges[k + localEdgeOffset],
1007 for (k = 0; k < nFaces; k++)
1009 if (localFaces[k + localFaceOffset] == -1)
1013 boost::add_edge((
size_t)localEdges[j + localEdgeOffset],
1014 (
size_t)localFaces[k + localFaceOffset],
1020 for (j = 0; j < nFaces; j++)
1022 if (localFaces[j + localFaceOffset] == -1)
1027 for (k = j + 1; k < nFaces; k++)
1029 if (localFaces[k + localFaceOffset] == -1)
1033 boost::add_edge((
size_t)localFaces[j + localFaceOffset],
1034 (
size_t)localFaces[k + localFaceOffset],
1039 localVertOffset += nVerts;
1040 localEdgeOffset += nEdges;
1041 localFaceOffset += nFaces;
1051 vector<long> procVerts, procEdges, procFaces;
1052 set<int> foundVerts, foundEdges, foundFaces;
1057 for (i = cnt = 0; i < locExpVector.size(); ++i)
1060 exp = locExpVector[elmtid];
1061 for (j = 0; j < exp->GetNverts(); ++j)
1063 int vid = exp->GetGeom()->GetVid(j) + 1;
1064 if (foundVerts.count(vid) == 0)
1066 procVerts.push_back(vid);
1067 foundVerts.insert(vid);
1071 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1073 int eid = exp->GetGeom()->GetEid(j) + 1;
1075 if (foundEdges.count(eid) == 0)
1077 procEdges.push_back(eid);
1078 foundEdges.insert(eid);
1082 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1084 int fid = exp->GetGeom()->GetFid(j) + 1;
1086 if (foundFaces.count(fid) == 0)
1088 procFaces.push_back(fid);
1089 foundFaces.insert(fid);
1094 int unique_verts = foundVerts.size();
1095 int unique_edges = foundEdges.size();
1096 int unique_faces = foundFaces.size();
1098 bool verbose =
m_session->DefinesCmdLineArgument(
"verbose");
1112 if (unique_edges > 0)
1120 if (unique_faces > 0)
1130 for (i = 0; i < unique_verts; ++i)
1134 if (graph[0].count(procVerts[i] - 1) == 0)
1136 partVerts.insert(tempGraph[0][procVerts[i] - 1]);
1141 for (i = 0; i < unique_edges; ++i)
1145 if (graph[1].count(procEdges[i] - 1) == 0)
1147 partVerts.insert(tempGraph[1][procEdges[i] - 1]);
1152 for (i = 0; i < unique_faces; ++i)
1156 if (graph[2].count(procFaces[i] - 1) == 0)
1158 partVerts.insert(tempGraph[2][procFaces[i] - 1]);
1164 for (
auto &pIt : periodicVerts)
1166 if (graph[0].count(pIt.first) == 0)
1168 partVerts.insert(tempGraph[0][pIt.first]);
1171 for (
auto &pIt : periodicEdges)
1173 if (graph[1].count(pIt.first) == 0)
1175 partVerts.insert(tempGraph[1][pIt.first]);
1178 for (
auto &pIt : periodicFaces)
1180 if (graph[2].count(pIt.first) == 0)
1182 partVerts.insert(tempGraph[2][pIt.first]);
1187 int nGraphVerts = tempGraphVertId;
1219 bottomUpGraph, partVerts,
1226 "Unrecognised solution type: " +
1252 for (
auto &mapIt : tempGraph[0])
1254 graph[0][mapIt.first] = iperm[mapIt.second] + graphVertId;
1256 for (
auto &mapIt : tempGraph[1])
1258 graph[1][mapIt.first] = iperm[mapIt.second] + graphVertId;
1260 for (
auto &mapIt : tempGraph[2])
1262 graph[2][mapIt.first] = iperm[mapIt.second] + graphVertId;
1273 const int numLocalCoeffs,
const ExpList &locExp,
1275 const bool checkIfSystemSingular,
const std::string variable,
1278 :
AssemblyMap(pSession, locExp.GetComm(), variable)
1281 int p, q, numModes0, numModes1;
1283 int meshVertId, meshEdgeId, meshEdgeId2, meshFaceId, meshFaceId2;
1285 int nEdgeInteriorCoeffs;
1286 int firstNonDirGraphVertId;
1298 bool verbose =
m_session->DefinesCmdLineArgument(
"verbose");
1305 vector<map<int, int>> faceModes(2);
1306 map<int, LibUtilities::ShapeType> faceType;
1308 set<int> extraDirVerts, extraDirEdges;
1313 for (i = 0; i < locExpVector.size(); ++i)
1315 exp = locExpVector[i];
1317 for (j = 0; j < exp->GetNverts(); ++j)
1319 dofs[0][exp->GetGeom()->GetVid(j)] = 1;
1322 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1325 if (exp->GetGeom()->GetNumFaces())
1335 if (dofs[1].count(exp->GetGeom()->GetEid(j)) > 0)
1337 if (dofs[1][exp->GetGeom()->GetEid(j)] != nEdgeInt)
1341 (exp->GetBasisType(1) ==
1343 (exp->GetBasisType(2) ==
1345 (exp->GetBasisType(2) ==
1347 "CG with variable order only available with "
1350 dofs[1][exp->GetGeom()->GetEid(j)] =
1351 min(dofs[1][exp->GetGeom()->GetEid(j)], nEdgeInt);
1355 dofs[1][exp->GetGeom()->GetEid(j)] = nEdgeInt;
1359 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1361 faceOrient = exp->GetGeom()->GetForient(j);
1362 meshFaceId = exp->GetGeom()->GetFid(j);
1363 exp->GetTraceNumModes(j, numModes0, numModes1, faceOrient);
1365 if (faceModes[0].count(meshFaceId) > 0)
1367 faceModes[0][meshFaceId] =
1368 min(faceModes[0][meshFaceId], numModes0);
1370 faceModes[1][meshFaceId] =
1371 min(faceModes[1][meshFaceId], numModes1);
1375 faceModes[0][meshFaceId] = numModes0;
1376 faceModes[1][meshFaceId] = numModes1;
1379 faceType[meshFaceId] =
1380 exp->GetGeom()->GetFace(j)->GetShapeType();
1386 for (
auto &pIt : periodicEdges)
1388 for (i = 0; i < pIt.second.size(); ++i)
1390 meshEdgeId2 = pIt.second[i].id;
1391 if (dofs[1].count(meshEdgeId2) == 0)
1393 dofs[1][meshEdgeId2] = 1e6;
1397 for (
auto &pIt : periodicFaces)
1399 for (i = 0; i < pIt.second.size(); ++i)
1401 meshFaceId2 = pIt.second[i].id;
1402 if (faceModes[0].count(meshFaceId2) == 0)
1404 faceModes[0][meshFaceId2] = 1e6;
1405 faceModes[1][meshFaceId2] = 1e6;
1417 for (
auto &dofIt : dofs[1])
1419 edgeId[i] = dofIt.first + 1;
1425 for (i = 0; i < dofs[1].size(); i++)
1427 dofs[1][edgeId[i] - 1] = (int)(edgeDof[i] + 0.5);
1430 for (
auto &pIt : periodicEdges)
1432 meshEdgeId = pIt.first;
1433 for (i = 0; i < pIt.second.size(); ++i)
1435 meshEdgeId2 = pIt.second[i].id;
1436 if (dofs[1][meshEdgeId2] < dofs[1][meshEdgeId])
1438 dofs[1][meshEdgeId] = dofs[1][meshEdgeId2];
1448 for (
auto dofIt = faceModes[0].begin(), dofIt2 = faceModes[1].begin();
1449 dofIt != faceModes[0].end(); dofIt++, dofIt2++, i++)
1451 faceId[i] = dofIt->first + 1;
1459 for (i = 0; i < faceModes[0].size(); i++)
1461 faceModes[0][faceId[i] - 1] = (int)(faceP[i] + 0.5);
1462 faceModes[1][faceId[i] - 1] = (int)(faceQ[i] + 0.5);
1465 for (
auto &pIt : periodicFaces)
1467 meshFaceId = pIt.first;
1468 for (i = 0; i < pIt.second.size(); ++i)
1470 meshFaceId2 = pIt.second[i].id;
1471 if (faceModes[0][meshFaceId2] < faceModes[0][meshFaceId])
1473 faceModes[0][meshFaceId] = faceModes[0][meshFaceId2];
1475 if (faceModes[1][meshFaceId2] < faceModes[1][meshFaceId])
1477 faceModes[1][meshFaceId] = faceModes[1][meshFaceId2];
1483 for (i = 0; i < faceModes[0].size(); i++)
1485 P = faceModes[0][faceId[i] - 1];
1486 Q = faceModes[1][faceId[i] - 1];
1490 dofs[2][faceId[i] - 1] =
1497 dofs[2][faceId[i] - 1] =
1508 int nExtraDirichlet;
1510 m_session->LoadParameter(
"MDSwitch", mdswitch, 10);
1513 locExp, bndCondExp, bndCondVec, checkIfSystemSingular, periodicVerts,
1514 periodicEdges, periodicFaces, graph, bottomUpGraph, extraDirVerts,
1515 extraDirEdges, firstNonDirGraphVertId, nExtraDirichlet, mdswitch);
1529 graph[0].size() + graph[1].size() + graph[2].size() + 1, 0);
1531 graphVertOffset[0] = 0;
1533 for (i = 0; i < locExpVector.size(); ++i)
1535 exp = locExpVector[i];
1537 for (j = 0; j < exp->GetNverts(); ++j)
1539 meshVertId = exp->GetGeom()->GetVid(j);
1540 graphVertOffset[graph[0][meshVertId] + 1] = 1;
1543 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1545 if (exp->GetGeom()->GetNumFaces())
1547 nEdgeInteriorCoeffs =
1554 meshEdgeId = exp->GetGeom()->GetEid(j);
1555 graphVertOffset[graph[1][meshEdgeId] + 1] = dofs[1][meshEdgeId];
1559 if (nEdgeInteriorCoeffs &&
1566 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1568 meshFaceId = exp->GetGeom()->GetFid(j);
1569 graphVertOffset[graph[2][meshFaceId] + 1] = dofs[2][meshFaceId];
1573 for (i = 1; i < graphVertOffset.size(); i++)
1575 graphVertOffset[i] += graphVertOffset[i - 1];
1606 (
unsigned int)locExpVector[i]->NumBndryCoeffs();
1608 (
unsigned int)locExpVector[i]->GetNcoeffs() -
1609 locExpVector[i]->NumBndryCoeffs();
1626 for (i = 0; i < locExpVector.size(); ++i)
1628 exp = locExpVector[i];
1631 int nbdry = exp->NumBndryCoeffs();
1632 int nint = exp->GetNcoeffs() - nbdry;
1637 exp->GetBoundaryMap(bmap);
1638 exp->GetInteriorMap(imap);
1640 for (j = 0; j < nbdry; ++j)
1645 for (j = 0; j < nint; ++j)
1650 for (j = 0; j < exp->GetNverts(); ++j)
1652 meshVertId = exp->GetGeom()->GetVid(j);
1656 graphVertOffset[graph[0][meshVertId]];
1659 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1661 if (exp->GetGeom()->GetNumFaces())
1663 nEdgeInteriorCoeffs =
1670 edgeOrient = exp->GetGeom()->GetEorient(j);
1671 meshEdgeId = exp->GetGeom()->GetEid(j);
1675 auto meshEdgeVertId = exp->GetGeom()->GetEdge(j)->GetVid(0);
1677 auto pIt = periodicEdges.find(meshEdgeId);
1682 if (pIt != periodicEdges.end())
1684 pair<int, StdRegions::Orientation> idOrient =
1687 edgeOrient = idOrient.second;
1690 if (exp->GetGeom()->GetNumFaces())
1693 ->GetEdgeInteriorToElementMap(j, edgeInteriorMap,
1694 edgeInteriorSign, edgeOrient);
1698 exp->GetTraceInteriorToElementMap(j, edgeInteriorMap,
1699 edgeInteriorSign, edgeOrient);
1703 for (k = 0; k < dofs[1][meshEdgeId]; ++k)
1706 graphVertOffset[graph[1][meshEdgeId]] + k;
1708 for (k = dofs[1][meshEdgeId]; k < nEdgeInteriorCoeffs; ++k)
1713 graphVertOffset[graph[0][meshEdgeVertId]];
1719 for (k = 0; k < dofs[1][meshEdgeId]; ++k)
1724 for (k = dofs[1][meshEdgeId]; k < nEdgeInteriorCoeffs; ++k)
1731 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1733 faceOrient = exp->GetGeom()->GetForient(j);
1734 meshFaceId = exp->GetGeom()->GetFid(j);
1738 auto meshFaceVertId = exp->GetGeom()->GetFace(j)->GetVid(0);
1740 auto pIt = periodicFaces.find(meshFaceId);
1742 if (pIt != periodicFaces.end() &&
1743 meshFaceId ==
min(meshFaceId, pIt->second[0].id))
1746 pIt->second[0].orient);
1749 exp->GetTraceInteriorToElementMap(j, faceInteriorMap,
1750 faceInteriorSign, faceOrient);
1753 exp->GetTraceNumModes(j, numModes0, numModes1, faceOrient);
1754 switch (faceType[meshFaceId])
1760 for (q = 2; q < numModes1; q++)
1762 for (p = 2; p < numModes0; p++)
1764 if ((p < faceModes[0][meshFaceId]) &&
1765 (q < faceModes[1][meshFaceId]))
1768 faceInteriorMap[kLoc]] =
1769 graphVertOffset[graph[2][meshFaceId]] + k;
1773 faceInteriorMap[kLoc]] =
1783 faceInteriorMap[kLoc]] =
1784 graphVertOffset[graph[0][meshFaceVertId]];
1789 faceInteriorMap[kLoc]] =
1802 for (p = 2; p < numModes0; p++)
1804 for (q = 1; q < numModes1 - p; q++)
1806 if ((p < faceModes[0][meshFaceId]) &&
1807 (p + q < faceModes[1][meshFaceId]))
1810 faceInteriorMap[kLoc]] =
1811 graphVertOffset[graph[2][meshFaceId]] + k;
1815 faceInteriorMap[kLoc]] =
1825 faceInteriorMap[kLoc]] =
1826 graphVertOffset[graph[0][meshFaceVertId]];
1830 faceInteriorMap[kLoc]] =
1840 ASSERTL0(
false,
"Shape not recognised");
1848 map<int, pair<int, int>> traceToElmtTraceMap;
1851 for (cnt = i = 0; i < locExpVector.size(); ++i)
1853 exp = locExpVector[i];
1855 for (j = 0; j < exp->GetNtraces(); ++j)
1857 id = exp->GetGeom()->GetTid(j);
1859 traceToElmtTraceMap[id] = pair<int, int>(i, j);
1865 map<int, pair<int, NekDouble>> GloDirBndCoeffToLocalCoeff;
1866 set<int> CoeffOnDirTrace;
1870 for (i = 0; i < bndCondExp.size(); i++)
1872 set<int> foundExtraVerts, foundExtraEdges;
1873 for (j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
1875 bndExp = bndCondExp[i]->GetExp(j);
1876 cnt = offset + bndCondExp[i]->GetCoeff_Offset(j);
1878 int id = bndExp->GetGeom()->GetGlobalID();
1880 ASSERTL1(traceToElmtTraceMap.count(
id) > 0,
1881 "Failed to find trace id");
1883 int eid = traceToElmtTraceMap[id].first;
1884 int tid = traceToElmtTraceMap[id].second;
1886 exp = locExpVector[eid];
1887 int dim = exp->GetShapeDimension();
1898 exp->GetTraceToElementMap(tid, maparray, signarray,
1899 exp->GetGeom()->GetEorient(tid),
1900 bndExp->GetBasisNumModes(0));
1904 exp->GetTraceToElementMap(tid, maparray, signarray,
1905 exp->GetGeom()->GetForient(tid),
1906 bndExp->GetBasisNumModes(0),
1907 bndExp->GetBasisNumModes(1));
1910 for (k = 0; k < bndExp->GetNcoeffs(); k++)
1927 for (k = 0; k < bndExp->GetNcoeffs(); k++)
1938 if (bndConditions[i]->GetBoundaryConditionType() ==
1951 CoeffOnDirTrace.insert(locid);
1955 GloDirBndCoeffToLocalCoeff[gloid] =
1956 pair<int, NekDouble>(locid,
sign);
1961 offset += bndCondExp[i]->GetNcoeffs();
1977 for (i = 0; i < locExpVector.size(); ++i)
1981 exp = locExpVector[i];
1983 exp->GetBoundaryMap(bndmap);
1985 for (j = 0; j < bndmap.size(); ++j)
1987 k = cnt + bndmap[j];
1990 if (CoeffOnDirTrace.count(k) == 0)
1996 if (GloDirBndCoeffToLocalCoeff.count(gloid))
1998 int locid = GloDirBndCoeffToLocalCoeff[gloid].first;
2013 gloParaDirBnd[gloid] = gloid;
2019 cnt += exp->GetNcoeffs();
2053 int gloid = gloParaDirBnd[i];
2056 gloParaDirBnd[i] = 0.0;
2072 for (i = 0; i < numLocalCoeffs; ++i)
2074 paraDirBnd[i] = 0.0;
2083 paraDirBnd[i] = gloParaDirBnd[id];
2085 if (gloParaDirBnd[
id] > 0.0)
2112 firstNonDirGraphVertId);
2114 for (i = 0; i < locExpVector.size(); ++i)
2116 exp = locExpVector[i];
2118 for (j = 0; j < exp->GetNverts(); ++j)
2120 meshVertId = exp->GetGeom()->GetVid(j);
2122 if (graph[0][meshVertId] >= firstNonDirGraphVertId)
2124 vwgts_perm[graph[0][meshVertId] -
2125 firstNonDirGraphVertId] =
2126 dofs[0][meshVertId];
2130 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
2132 meshEdgeId = exp->GetGeom()->GetEid(j);
2134 if (graph[1][meshEdgeId] >= firstNonDirGraphVertId)
2136 vwgts_perm[graph[1][meshEdgeId] -
2137 firstNonDirGraphVertId] =
2138 dofs[1][meshEdgeId];
2142 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
2144 meshFaceId = exp->GetGeom()->GetFid(j);
2146 if (graph[2][meshFaceId] >= firstNonDirGraphVertId)
2148 vwgts_perm[graph[2][meshFaceId] -
2149 firstNonDirGraphVertId] =
2150 dofs[2][meshFaceId];
2155 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
2312 int maxBndGlobalId = 0;
2323 const bool verbose = locExp.
GetSession()->DefinesCmdLineArgument(
"verbose");
2334 for (i = 0; i < locExpVector.size(); ++i)
2336 exp = locExpVector[i];
2338 int nv = exp->GetNverts();
2339 int ne = exp->GetGeom()->GetNumEdges();
2340 int nf = exp->GetGeom()->GetNumFaces();
2347 for (j = 0; j < ne; ++j)
2359 maxEdgeDof = (dof > maxEdgeDof ? dof : maxEdgeDof);
2361 for (j = 0; j < nf; ++j)
2363 dof = exp->GetTraceIntNcoeffs(j);
2364 maxFaceDof = (dof > maxFaceDof ? dof : maxFaceDof);
2366 exp->GetInteriorMap(interiorMap);
2367 dof = interiorMap.size();
2368 maxIntDof = (dof > maxIntDof ? dof : maxIntDof);
2380 for (i = 0; i < locExpVector.size(); ++i)
2382 exp = locExpVector[i];
2385 int nf = exp->GetGeom()->GetNumFaces();
2388 for (j = 0; j < exp->GetNverts(); ++j)
2390 meshVertId = exp->GetGeom()->GetVid(j);
2393 auto pIt = perVerts.find(meshVertId);
2394 if (pIt != perVerts.end())
2396 for (k = 0; k < pIt->second.size(); ++k)
2398 meshVertId =
min(meshVertId, pIt->second[k].id);
2406 (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
2410 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
2412 meshEdgeId = exp->GetGeom()->GetEid(j);
2413 auto pIt = perEdges.find(meshEdgeId);
2414 edgeOrient = exp->GetGeom()->GetEorient(j);
2416 if (pIt != perEdges.end())
2418 pair<int, StdRegions::Orientation> idOrient =
2421 meshEdgeId = idOrient.first;
2422 edgeOrient = idOrient.second;
2428 ->GetEdgeInteriorToElementMap(j, edgeInteriorMap,
2429 edgeInteriorSign, edgeOrient);
2436 edgeInteriorSign, edgeOrient);
2437 dof = exp->GetTraceNcoeffs(j) - 2;
2442 for (k = 0, l = 0; k < dof; ++k)
2453 nVert + meshEdgeId * maxEdgeDof + l + 1;
2457 (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
2463 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
2465 faceOrient = exp->GetGeom()->GetForient(j);
2467 meshFaceId = exp->GetGeom()->GetFid(j);
2469 auto pIt = perFaces.find(meshFaceId);
2470 if (pIt != perFaces.end())
2472 if (meshFaceId ==
min(meshFaceId, pIt->second[0].id))
2475 faceOrient, pIt->second[0].orient);
2477 meshFaceId =
min(meshFaceId, pIt->second[0].id);
2480 exp->GetTraceInteriorToElementMap(j, faceInteriorMap,
2481 faceInteriorSign, faceOrient);
2482 dof = exp->GetTraceIntNcoeffs(j);
2484 for (k = 0, l = 0; k < dof; ++k)
2495 meshFaceId * maxFaceDof +
2501 (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
2507 exp->GetInteriorMap(interiorMap);
2508 dof = interiorMap.size();
2509 elementId = (exp->GetGeom())->GetGlobalID();
2510 for (k = 0; k < dof; ++k)
2514 nFace * maxFaceDof +
2515 elementId * maxIntDof + k + 1;