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 = 0; k < nVerts; k++)
955 if (localVerts[k + localVertOffset] == -1)
961 boost::add_edge((
size_t)localVerts[j + localVertOffset],
962 (
size_t)localVerts[k + localVertOffset],
967 for (k = 0; k < nEdges; k++)
969 if (localEdges[k + localEdgeOffset] == -1)
973 boost::add_edge((
size_t)localVerts[j + localVertOffset],
974 (
size_t)localEdges[k + localEdgeOffset],
978 for (k = 0; k < nFaces; k++)
980 if (localFaces[k + localFaceOffset] == -1)
984 boost::add_edge((
size_t)localVerts[j + localVertOffset],
985 (
size_t)localFaces[k + localFaceOffset],
991 for (j = 0; j < nEdges; j++)
993 if (localEdges[j + localEdgeOffset] == -1)
998 for (k = 0; k < nEdges; k++)
1000 if (localEdges[k + localEdgeOffset] == -1)
1006 boost::add_edge((
size_t)localEdges[j + localEdgeOffset],
1007 (
size_t)localEdges[k + localEdgeOffset],
1012 for (k = 0; k < nVerts; k++)
1014 if (localVerts[k + localVertOffset] == -1)
1018 boost::add_edge((
size_t)localEdges[j + localEdgeOffset],
1019 (
size_t)localVerts[k + localVertOffset],
1023 for (k = 0; k < nFaces; k++)
1025 if (localFaces[k + localFaceOffset] == -1)
1029 boost::add_edge((
size_t)localEdges[j + localEdgeOffset],
1030 (
size_t)localFaces[k + localFaceOffset],
1036 for (j = 0; j < nFaces; j++)
1038 if (localFaces[j + localFaceOffset] == -1)
1043 for (k = 0; k < nFaces; k++)
1045 if (localFaces[k + localFaceOffset] == -1)
1051 boost::add_edge((
size_t)localFaces[j + localFaceOffset],
1052 (
size_t)localFaces[k + localFaceOffset],
1057 for (k = 0; k < nVerts; k++)
1059 if (localVerts[k + localVertOffset] == -1)
1063 boost::add_edge((
size_t)localFaces[j + localFaceOffset],
1064 (
size_t)localVerts[k + localVertOffset],
1068 for (k = 0; k < nEdges; k++)
1070 if (localEdges[k + localEdgeOffset] == -1)
1074 boost::add_edge((
size_t)localFaces[j + localFaceOffset],
1075 (
size_t)localEdges[k + localEdgeOffset],
1080 localVertOffset += nVerts;
1081 localEdgeOffset += nEdges;
1082 localFaceOffset += nFaces;
1092 vector<long> procVerts, procEdges, procFaces;
1093 set<int> foundVerts, foundEdges, foundFaces;
1098 for (i = cnt = 0; i < locExpVector.size(); ++i)
1101 exp = locExpVector[elmtid];
1102 for (j = 0; j < exp->GetNverts(); ++j)
1104 int vid = exp->GetGeom()->GetVid(j) + 1;
1105 if (foundVerts.count(vid) == 0)
1107 procVerts.push_back(vid);
1108 foundVerts.insert(vid);
1112 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1114 int eid = exp->GetGeom()->GetEid(j) + 1;
1116 if (foundEdges.count(eid) == 0)
1118 procEdges.push_back(eid);
1119 foundEdges.insert(eid);
1123 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1125 int fid = exp->GetGeom()->GetFid(j) + 1;
1127 if (foundFaces.count(fid) == 0)
1129 procFaces.push_back(fid);
1130 foundFaces.insert(fid);
1135 int unique_verts = foundVerts.size();
1136 int unique_edges = foundEdges.size();
1137 int unique_faces = foundFaces.size();
1139 bool verbose =
m_session->DefinesCmdLineArgument(
"verbose");
1153 if (unique_edges > 0)
1161 if (unique_faces > 0)
1171 for (i = 0; i < unique_verts; ++i)
1175 if (graph[0].count(procVerts[i] - 1) == 0)
1177 partVerts.insert(tempGraph[0][procVerts[i] - 1]);
1182 for (i = 0; i < unique_edges; ++i)
1186 if (graph[1].count(procEdges[i] - 1) == 0)
1188 partVerts.insert(tempGraph[1][procEdges[i] - 1]);
1193 for (i = 0; i < unique_faces; ++i)
1197 if (graph[2].count(procFaces[i] - 1) == 0)
1199 partVerts.insert(tempGraph[2][procFaces[i] - 1]);
1205 for (
auto &pIt : periodicVerts)
1207 if (graph[0].count(pIt.first) == 0)
1209 partVerts.insert(tempGraph[0][pIt.first]);
1212 for (
auto &pIt : periodicEdges)
1214 if (graph[1].count(pIt.first) == 0)
1216 partVerts.insert(tempGraph[1][pIt.first]);
1219 for (
auto &pIt : periodicFaces)
1221 if (graph[2].count(pIt.first) == 0)
1223 partVerts.insert(tempGraph[2][pIt.first]);
1228 int nGraphVerts = tempGraphVertId;
1260 bottomUpGraph, partVerts,
1267 "Unrecognised solution type: " +
1293 for (
auto &mapIt : tempGraph[0])
1295 graph[0][mapIt.first] = iperm[mapIt.second] + graphVertId;
1297 for (
auto &mapIt : tempGraph[1])
1299 graph[1][mapIt.first] = iperm[mapIt.second] + graphVertId;
1301 for (
auto &mapIt : tempGraph[2])
1303 graph[2][mapIt.first] = iperm[mapIt.second] + graphVertId;
1314 const int numLocalCoeffs,
const ExpList &locExp,
1316 const bool checkIfSystemSingular,
const std::string variable,
1319 :
AssemblyMap(pSession, locExp.GetComm(), variable)
1322 int p, q, numModes0, numModes1;
1324 int meshVertId, meshEdgeId, meshEdgeId2, meshFaceId, meshFaceId2;
1326 int nEdgeInteriorCoeffs;
1327 int firstNonDirGraphVertId;
1339 bool verbose =
m_session->DefinesCmdLineArgument(
"verbose");
1346 vector<map<int, int>> faceModes(2);
1347 map<int, LibUtilities::ShapeType> faceType;
1349 set<int> extraDirVerts, extraDirEdges;
1354 for (i = 0; i < locExpVector.size(); ++i)
1356 exp = locExpVector[i];
1358 for (j = 0; j < exp->GetNverts(); ++j)
1360 dofs[0][exp->GetGeom()->GetVid(j)] = 1;
1363 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1366 if (exp->GetGeom()->GetNumFaces())
1376 if (dofs[1].count(exp->GetGeom()->GetEid(j)) > 0)
1378 if (dofs[1][exp->GetGeom()->GetEid(j)] != nEdgeInt)
1382 (exp->GetBasisType(1) ==
1384 (exp->GetBasisType(2) ==
1386 (exp->GetBasisType(2) ==
1388 "CG with variable order only available with "
1391 dofs[1][exp->GetGeom()->GetEid(j)] =
1392 min(dofs[1][exp->GetGeom()->GetEid(j)], nEdgeInt);
1396 dofs[1][exp->GetGeom()->GetEid(j)] = nEdgeInt;
1400 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1402 faceOrient = exp->GetGeom()->GetForient(j);
1403 meshFaceId = exp->GetGeom()->GetFid(j);
1404 exp->GetTraceNumModes(j, numModes0, numModes1, faceOrient);
1406 if (faceModes[0].count(meshFaceId) > 0)
1408 faceModes[0][meshFaceId] =
1409 min(faceModes[0][meshFaceId], numModes0);
1411 faceModes[1][meshFaceId] =
1412 min(faceModes[1][meshFaceId], numModes1);
1416 faceModes[0][meshFaceId] = numModes0;
1417 faceModes[1][meshFaceId] = numModes1;
1420 faceType[meshFaceId] =
1421 exp->GetGeom()->GetFace(j)->GetShapeType();
1427 for (
auto &pIt : periodicEdges)
1429 for (i = 0; i < pIt.second.size(); ++i)
1431 meshEdgeId2 = pIt.second[i].id;
1432 if (dofs[1].count(meshEdgeId2) == 0)
1434 dofs[1][meshEdgeId2] = 1e6;
1438 for (
auto &pIt : periodicFaces)
1440 for (i = 0; i < pIt.second.size(); ++i)
1442 meshFaceId2 = pIt.second[i].id;
1443 if (faceModes[0].count(meshFaceId2) == 0)
1445 faceModes[0][meshFaceId2] = 1e6;
1446 faceModes[1][meshFaceId2] = 1e6;
1458 for (
auto &dofIt : dofs[1])
1460 edgeId[i] = dofIt.first + 1;
1466 for (i = 0; i < dofs[1].size(); i++)
1468 dofs[1][edgeId[i] - 1] = (int)(edgeDof[i] + 0.5);
1471 for (
auto &pIt : periodicEdges)
1473 meshEdgeId = pIt.first;
1474 for (i = 0; i < pIt.second.size(); ++i)
1476 meshEdgeId2 = pIt.second[i].id;
1477 if (dofs[1][meshEdgeId2] < dofs[1][meshEdgeId])
1479 dofs[1][meshEdgeId] = dofs[1][meshEdgeId2];
1489 for (
auto dofIt = faceModes[0].begin(), dofIt2 = faceModes[1].begin();
1490 dofIt != faceModes[0].end(); dofIt++, dofIt2++, i++)
1492 faceId[i] = dofIt->first + 1;
1500 for (i = 0; i < faceModes[0].size(); i++)
1502 faceModes[0][faceId[i] - 1] = (int)(faceP[i] + 0.5);
1503 faceModes[1][faceId[i] - 1] = (int)(faceQ[i] + 0.5);
1506 for (
auto &pIt : periodicFaces)
1508 meshFaceId = pIt.first;
1509 for (i = 0; i < pIt.second.size(); ++i)
1511 meshFaceId2 = pIt.second[i].id;
1512 if (faceModes[0][meshFaceId2] < faceModes[0][meshFaceId])
1514 faceModes[0][meshFaceId] = faceModes[0][meshFaceId2];
1516 if (faceModes[1][meshFaceId2] < faceModes[1][meshFaceId])
1518 faceModes[1][meshFaceId] = faceModes[1][meshFaceId2];
1524 for (i = 0; i < faceModes[0].size(); i++)
1526 P = faceModes[0][faceId[i] - 1];
1527 Q = faceModes[1][faceId[i] - 1];
1531 dofs[2][faceId[i] - 1] =
1538 dofs[2][faceId[i] - 1] =
1549 int nExtraDirichlet;
1551 m_session->LoadParameter(
"MDSwitch", mdswitch, 10);
1554 locExp, bndCondExp, bndCondVec, checkIfSystemSingular, periodicVerts,
1555 periodicEdges, periodicFaces, graph, bottomUpGraph, extraDirVerts,
1556 extraDirEdges, firstNonDirGraphVertId, nExtraDirichlet, mdswitch);
1570 graph[0].size() + graph[1].size() + graph[2].size() + 1, 0);
1572 graphVertOffset[0] = 0;
1574 for (i = 0; i < locExpVector.size(); ++i)
1576 exp = locExpVector[i];
1578 for (j = 0; j < exp->GetNverts(); ++j)
1580 meshVertId = exp->GetGeom()->GetVid(j);
1581 graphVertOffset[graph[0][meshVertId] + 1] = 1;
1584 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1586 if (exp->GetGeom()->GetNumFaces())
1588 nEdgeInteriorCoeffs =
1595 meshEdgeId = exp->GetGeom()->GetEid(j);
1596 graphVertOffset[graph[1][meshEdgeId] + 1] = dofs[1][meshEdgeId];
1600 if (nEdgeInteriorCoeffs &&
1607 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1609 meshFaceId = exp->GetGeom()->GetFid(j);
1610 graphVertOffset[graph[2][meshFaceId] + 1] = dofs[2][meshFaceId];
1614 for (i = 1; i < graphVertOffset.size(); i++)
1616 graphVertOffset[i] += graphVertOffset[i - 1];
1647 (
unsigned int)locExpVector[i]->NumBndryCoeffs();
1649 (
unsigned int)locExpVector[i]->GetNcoeffs() -
1650 locExpVector[i]->NumBndryCoeffs();
1667 for (i = 0; i < locExpVector.size(); ++i)
1669 exp = locExpVector[i];
1672 int nbdry = exp->NumBndryCoeffs();
1673 int nint = exp->GetNcoeffs() - nbdry;
1678 exp->GetBoundaryMap(bmap);
1679 exp->GetInteriorMap(imap);
1681 for (j = 0; j < nbdry; ++j)
1686 for (j = 0; j < nint; ++j)
1691 for (j = 0; j < exp->GetNverts(); ++j)
1693 meshVertId = exp->GetGeom()->GetVid(j);
1697 graphVertOffset[graph[0][meshVertId]];
1700 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
1702 if (exp->GetGeom()->GetNumFaces())
1704 nEdgeInteriorCoeffs =
1711 edgeOrient = exp->GetGeom()->GetEorient(j);
1712 meshEdgeId = exp->GetGeom()->GetEid(j);
1714 auto pIt = periodicEdges.find(meshEdgeId);
1719 if (pIt != periodicEdges.end())
1721 pair<int, StdRegions::Orientation> idOrient =
1724 edgeOrient = idOrient.second;
1727 if (exp->GetGeom()->GetNumFaces())
1730 ->GetEdgeInteriorToElementMap(j, edgeInteriorMap,
1731 edgeInteriorSign, edgeOrient);
1735 exp->GetTraceInteriorToElementMap(j, edgeInteriorMap,
1736 edgeInteriorSign, edgeOrient);
1740 for (k = 0; k < dofs[1][meshEdgeId]; ++k)
1743 graphVertOffset[graph[1][meshEdgeId]] + k;
1745 for (k = dofs[1][meshEdgeId]; k < nEdgeInteriorCoeffs; ++k)
1753 for (k = 0; k < dofs[1][meshEdgeId]; ++k)
1758 for (k = dofs[1][meshEdgeId]; k < nEdgeInteriorCoeffs; ++k)
1765 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
1767 faceOrient = exp->GetGeom()->GetForient(j);
1768 meshFaceId = exp->GetGeom()->GetFid(j);
1770 auto pIt = periodicFaces.find(meshFaceId);
1772 if (pIt != periodicFaces.end() &&
1773 meshFaceId ==
min(meshFaceId, pIt->second[0].id))
1776 pIt->second[0].orient);
1779 exp->GetTraceInteriorToElementMap(j, faceInteriorMap,
1780 faceInteriorSign, faceOrient);
1783 exp->GetTraceNumModes(j, numModes0, numModes1, faceOrient);
1784 switch (faceType[meshFaceId])
1790 for (q = 2; q < numModes1; q++)
1792 for (p = 2; p < numModes0; p++)
1794 if ((p < faceModes[0][meshFaceId]) &&
1795 (q < faceModes[1][meshFaceId]))
1798 faceInteriorMap[kLoc]] =
1799 graphVertOffset[graph[2][meshFaceId]] + k;
1803 faceInteriorMap[kLoc]] =
1811 faceInteriorMap[kLoc]] = 0;
1815 faceInteriorMap[kLoc]] =
1828 for (p = 2; p < numModes0; p++)
1830 for (q = 1; q < numModes1 - p; q++)
1832 if ((p < faceModes[0][meshFaceId]) &&
1833 (p + q < faceModes[1][meshFaceId]))
1836 faceInteriorMap[kLoc]] =
1837 graphVertOffset[graph[2][meshFaceId]] + k;
1841 faceInteriorMap[kLoc]] =
1849 faceInteriorMap[kLoc]] = 0;
1853 faceInteriorMap[kLoc]] =
1863 ASSERTL0(
false,
"Shape not recognised");
1871 map<int, pair<int, int>> traceToElmtTraceMap;
1874 for (cnt = i = 0; i < locExpVector.size(); ++i)
1876 exp = locExpVector[i];
1878 for (j = 0; j < exp->GetNtraces(); ++j)
1880 id = exp->GetGeom()->GetTid(j);
1882 traceToElmtTraceMap[id] = pair<int, int>(i, j);
1888 map<int, pair<int, NekDouble>> GloDirBndCoeffToLocalCoeff;
1889 set<int> CoeffOnDirTrace;
1893 for (i = 0; i < bndCondExp.size(); i++)
1895 set<int> foundExtraVerts, foundExtraEdges;
1896 for (j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
1898 bndExp = bndCondExp[i]->GetExp(j);
1899 cnt = offset + bndCondExp[i]->GetCoeff_Offset(j);
1901 int id = bndExp->GetGeom()->GetGlobalID();
1903 ASSERTL1(traceToElmtTraceMap.count(
id) > 0,
1904 "Failed to find trace id");
1906 int eid = traceToElmtTraceMap[id].first;
1907 int tid = traceToElmtTraceMap[id].second;
1909 exp = locExpVector[eid];
1910 int dim = exp->GetShapeDimension();
1921 exp->GetTraceToElementMap(tid, maparray, signarray,
1922 exp->GetGeom()->GetEorient(tid),
1923 bndExp->GetBasisNumModes(0));
1927 exp->GetTraceToElementMap(tid, maparray, signarray,
1928 exp->GetGeom()->GetForient(tid),
1929 bndExp->GetBasisNumModes(0),
1930 bndExp->GetBasisNumModes(1));
1933 for (k = 0; k < bndExp->GetNcoeffs(); k++)
1950 for (k = 0; k < bndExp->GetNcoeffs(); k++)
1961 if (bndConditions[i]->GetBoundaryConditionType() ==
1974 CoeffOnDirTrace.insert(locid);
1978 GloDirBndCoeffToLocalCoeff[gloid] =
1979 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];
2013 if (CoeffOnDirTrace.count(k) == 0)
2019 if (GloDirBndCoeffToLocalCoeff.count(gloid))
2021 int locid = GloDirBndCoeffToLocalCoeff[gloid].first;
2036 gloParaDirBnd[gloid] = gloid;
2042 cnt += exp->GetNcoeffs();
2076 int gloid = gloParaDirBnd[i];
2079 gloParaDirBnd[i] = 0.0;
2095 for (i = 0; i < numLocalCoeffs; ++i)
2097 paraDirBnd[i] = 0.0;
2106 paraDirBnd[i] = gloParaDirBnd[id];
2108 if (gloParaDirBnd[
id] > 0.0)
2135 firstNonDirGraphVertId);
2137 for (i = 0; i < locExpVector.size(); ++i)
2139 exp = locExpVector[i];
2141 for (j = 0; j < exp->GetNverts(); ++j)
2143 meshVertId = exp->GetGeom()->GetVid(j);
2145 if (graph[0][meshVertId] >= firstNonDirGraphVertId)
2147 vwgts_perm[graph[0][meshVertId] -
2148 firstNonDirGraphVertId] =
2149 dofs[0][meshVertId];
2153 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
2155 meshEdgeId = exp->GetGeom()->GetEid(j);
2157 if (graph[1][meshEdgeId] >= firstNonDirGraphVertId)
2159 vwgts_perm[graph[1][meshEdgeId] -
2160 firstNonDirGraphVertId] =
2161 dofs[1][meshEdgeId];
2165 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
2167 meshFaceId = exp->GetGeom()->GetFid(j);
2169 if (graph[2][meshFaceId] >= firstNonDirGraphVertId)
2171 vwgts_perm[graph[2][meshFaceId] -
2172 firstNonDirGraphVertId] =
2173 dofs[2][meshFaceId];
2178 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
2333 int maxBndGlobalId = 0;
2344 const bool verbose = locExp.
GetSession()->DefinesCmdLineArgument(
"verbose");
2355 for (i = 0; i < locExpVector.size(); ++i)
2357 exp = locExpVector[i];
2359 int nv = exp->GetNverts();
2360 int ne = exp->GetGeom()->GetNumEdges();
2361 int nf = exp->GetGeom()->GetNumFaces();
2368 for (j = 0; j < ne; ++j)
2380 maxEdgeDof = (dof > maxEdgeDof ? dof : maxEdgeDof);
2382 for (j = 0; j < nf; ++j)
2384 dof = exp->GetTraceIntNcoeffs(j);
2385 maxFaceDof = (dof > maxFaceDof ? dof : maxFaceDof);
2387 exp->GetInteriorMap(interiorMap);
2388 dof = interiorMap.size();
2389 maxIntDof = (dof > maxIntDof ? dof : maxIntDof);
2401 for (i = 0; i < locExpVector.size(); ++i)
2403 exp = locExpVector[i];
2406 int nf = exp->GetGeom()->GetNumFaces();
2409 for (j = 0; j < exp->GetNverts(); ++j)
2411 meshVertId = exp->GetGeom()->GetVid(j);
2414 auto pIt = perVerts.find(meshVertId);
2415 if (pIt != perVerts.end())
2417 for (k = 0; k < pIt->second.size(); ++k)
2419 meshVertId =
min(meshVertId, pIt->second[k].id);
2427 (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
2431 for (j = 0; j < exp->GetGeom()->GetNumEdges(); ++j)
2433 meshEdgeId = exp->GetGeom()->GetEid(j);
2434 auto pIt = perEdges.find(meshEdgeId);
2435 edgeOrient = exp->GetGeom()->GetEorient(j);
2437 if (pIt != perEdges.end())
2439 pair<int, StdRegions::Orientation> idOrient =
2442 meshEdgeId = idOrient.first;
2443 edgeOrient = idOrient.second;
2449 ->GetEdgeInteriorToElementMap(j, edgeInteriorMap,
2450 edgeInteriorSign, edgeOrient);
2457 edgeInteriorSign, edgeOrient);
2458 dof = exp->GetTraceNcoeffs(j) - 2;
2463 for (k = 0, l = 0; k < dof; ++k)
2474 nVert + meshEdgeId * maxEdgeDof + l + 1;
2478 (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
2484 for (j = 0; j < exp->GetGeom()->GetNumFaces(); ++j)
2486 faceOrient = exp->GetGeom()->GetForient(j);
2488 meshFaceId = exp->GetGeom()->GetFid(j);
2490 auto pIt = perFaces.find(meshFaceId);
2491 if (pIt != perFaces.end())
2493 if (meshFaceId ==
min(meshFaceId, pIt->second[0].id))
2496 faceOrient, pIt->second[0].orient);
2498 meshFaceId =
min(meshFaceId, pIt->second[0].id);
2501 exp->GetTraceInteriorToElementMap(j, faceInteriorMap,
2502 faceInteriorSign, faceOrient);
2503 dof = exp->GetTraceIntNcoeffs(j);
2505 for (k = 0, l = 0; k < dof; ++k)
2516 meshFaceId * maxFaceDof +
2522 (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
2528 exp->GetInteriorMap(interiorMap);
2529 dof = interiorMap.size();
2530 elementId = (exp->GetGeom())->GetGlobalID();
2531 for (k = 0; k < dof; ++k)
2535 nFace * maxFaceDof +
2536 elementId * maxIntDof + k + 1;