43 #include <boost/config.hpp>
44 #include <boost/graph/adjacency_list.hpp>
45 #include <boost/graph/cuthill_mckee_ordering.hpp>
46 #include <boost/graph/properties.hpp>
47 #include <boost/graph/bandwidth.hpp>
51 namespace MultiRegions
71 const std::string variable):
74 pSession->LoadParameter(
81 const Array<OneD, const BndCond> &bndConditions,
82 const bool checkIfSystemSingular,
88 set<int> &extraDirVerts,
89 set<int> &extraDirEdges,
90 int &firstNonDirGraphVertId,
97 int meshVertId, meshEdgeId, meshFaceId;
98 int meshVertId2, meshEdgeId2;
104 PeriodicMap::const_iterator pIt;
109 for(i = 0; i < bndCondExp.num_elements(); i++)
113 for(k = 0; k < bndConditions.num_elements(); ++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))
136 vMaxVertId = bndExp->
GetGeom()->GetVid(k);
143 if(cnt == bndConditions.num_elements())
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 for (k = 0; k < bndExp->GetNedges(); k++)
160 meshEdgeId = bndExp->GetGeom()->GetEid(k);
161 if (graph[1].count(meshEdgeId) == 0)
163 graph[1][meshEdgeId] = graphVertId++;
168 meshFaceId = bndExp->GetGeom()->GetGlobalID();
169 const int bndDim = bndExp->GetNumBases();
170 if (graph[bndDim].count(meshFaceId) == 0)
172 graph[bndDim][meshFaceId] = graphVertId++;
207 int n = vComm->GetSize();
208 int p = vComm->GetRank();
213 Array<OneD, int> vertcounts (n, 0);
214 Array<OneD, int> vertoffsets(n, 0);
215 Array<OneD, int> edgecounts (n, 0);
216 Array<OneD, int> edgeoffsets(n, 0);
217 vertcounts[p] = graph[0].size();
218 edgecounts[p] = graph[1].size();
222 for (i = 1; i < n; ++i)
224 vertoffsets[i] = vertoffsets[i-1] + vertcounts[i-1];
225 edgeoffsets[i] = edgeoffsets[i-1] + edgecounts[i-1];
231 Array<OneD, int> vertlist(nTotVerts, 0);
232 Array<OneD, int> edgelist(nTotEdges, 0);
236 for (it = graph[0].begin(), i = 0;
237 it != graph[0].end();
240 vertlist[vertoffsets[p] + i] = it->first;
244 for (it = graph[1].begin(), i = 0;
245 it != graph[1].end();
248 edgelist[edgeoffsets[p] + i] = it->first;
256 map<int, int> extraDirVertIds, extraDirEdgeIds;
266 for (i = 0; i < n; ++i)
273 for(j = 0; j < locExpVector.size(); j++)
277 for(k = 0; k < exp->GetNverts(); k++)
279 meshVertId = exp->GetGeom()->GetVid(k);
280 if(graph[0].count(meshVertId) == 0)
282 for (l = 0; l < vertcounts[i]; ++l)
284 if (vertlist[vertoffsets[i]+l] == meshVertId)
286 extraDirVertIds[meshVertId] = i;
287 graph[0][meshVertId] = graphVertId++;
294 for(k = 0; k < exp->GetNedges(); k++)
296 meshEdgeId = exp->GetGeom()->GetEid(k);
297 if(graph[1].count(meshEdgeId) == 0)
299 for (l = 0; l < edgecounts[i]; ++l)
301 if (edgelist[edgeoffsets[i]+l] == meshEdgeId)
303 extraDirEdgeIds[meshEdgeId] = i;
304 graph[1][meshEdgeId] = graphVertId++;
305 nExtraDirichlet += exp->GetEdgeNcoeffs(k)-2;
315 map<int, int>::const_iterator mapConstIt;
317 for (mapConstIt = extraDirEdgeIds.begin(), i = 0;
318 mapConstIt != extraDirEdgeIds.end(); mapConstIt++)
320 meshEdgeId = mapConstIt->first;
330 for (i = 0; i < n; ++i)
338 vertcounts[p] = extraDirVertIds.size();
339 edgecounts[p] = extraDirEdgeIds.size();
345 vertoffsets[0] = edgeoffsets[0] = 0;
347 for (i = 1; i < n; ++i)
349 vertoffsets[i] = vertoffsets[i-1] + vertcounts[i-1];
350 edgeoffsets[i] = edgeoffsets[i-1] + edgecounts[i-1];
353 Array<OneD, int> vertids (nTotVerts, 0);
354 Array<OneD, int> edgeids (nTotEdges, 0);
355 Array<OneD, int> vertprocs(nTotVerts, 0);
356 Array<OneD, int> edgeprocs(nTotEdges, 0);
358 for (it = extraDirVertIds.begin(), i = 0;
359 it != extraDirVertIds.end(); ++it, ++i)
361 vertids [vertoffsets[p]+i] = it->first;
362 vertprocs[vertoffsets[p]+i] = it->second;
365 for (it = extraDirEdgeIds.begin(), i = 0;
366 it != extraDirEdgeIds.end(); ++it, ++i)
368 edgeids [edgeoffsets[p]+i] = it->first;
369 edgeprocs[edgeoffsets[p]+i] = it->second;
379 for (i = 0; i < nTotVerts; ++i)
381 if (vComm->GetRank() == vertprocs[i])
383 extraDirVerts.insert(vertids[i]);
388 for (i = 0; i < nTotEdges; ++i)
390 if (vComm->GetRank() == edgeprocs[i])
392 extraDirEdges.insert(edgeids[i]);
402 Array<OneD, int> bcminvertid(n, 0);
403 bcminvertid[p] = vMaxVertId;
418 if (
m_session->DefinesParameter(
"SingularVertex"))
420 m_session->LoadParameter(
"SingularVertex", meshVertId);
422 else if (vMaxVertId == -1)
425 meshVertId = locExpVector[0]->GetGeom()->GetVid(0);
431 meshVertId = bcminvertid[p];
434 if (graph[0].count(meshVertId) == 0)
436 graph[0][meshVertId] = graphVertId++;
452 for (i = 0; i < locExpVector.size(); ++i)
454 for (j = 0; j < locExpVector[i]->GetNverts(); ++j)
456 if (locExpVector[i]->GetGeom()->GetVid(j) !=
462 if (graph[0].count(meshVertId) == 0)
464 graph[0][meshVertId] =
480 if (graph[0].count(meshVertId) == 0)
486 gId = graph[0][meshVertId];
489 for (pIt = periodicVerts.begin();
490 pIt != periodicVerts.end(); ++pIt)
497 if (pIt->first == meshVertId)
499 graph[0][meshVertId] = gId < 0 ? graphVertId++ : gId;
501 for (i = 0; i < pIt->second.size(); ++i)
503 if (pIt->second[i].isLocal)
505 graph[0][pIt->second[i].id] = gId;
512 for (i = 0; i < pIt->second.size(); ++i)
514 if (pIt->second[i].id == meshVertId)
523 graph[0][pIt->first] = gId < 0 ? graphVertId++ : gId;
525 for (i = 0; i < pIt->second.size(); ++i)
527 if (pIt->second[i].isLocal)
529 graph[0][pIt->second[i].id] = gId;
539 firstNonDirGraphVertId = graphVertId;
541 typedef boost::adjacency_list<
542 boost::setS, boost::vecS, boost::undirectedS> BoostGraph;
543 BoostGraph boostGraphObj;
545 vector<map<int,int> > tempGraph(3);
546 map<int, int> vwgts_map;
547 Array<OneD, int> localVerts;
548 Array<OneD, int> localEdges;
549 Array<OneD, int> localFaces;
551 int tempGraphVertId = 0;
552 int localVertOffset = 0;
553 int localEdgeOffset = 0;
554 int localFaceOffset = 0;
572 map<int,int> EdgeSize;
573 map<int,int> FaceSize;
576 for(i = 0; i < locExpVector.size(); ++i)
579 nTotalVerts += exp->GetNverts();
580 nTotalEdges += exp->GetNedges();
581 nTotalFaces += exp->GetNfaces();
583 nEdges = exp->GetNedges();
584 for(j = 0; j < nEdges; ++j)
586 meshEdgeId = exp->GetGeom()->GetEid(j);
587 EdgeSize[meshEdgeId] = exp->GetEdgeNcoeffs(j) - 2;
590 nFaces = exp->GetNfaces();
592 for(j = 0; j < nFaces; ++j)
594 meshFaceId = exp->GetGeom()->GetFid(j);
595 FaceSize[meshFaceId] = exp->GetFaceIntNcoeffs(j);
600 for (pIt = periodicVerts.begin(); pIt != periodicVerts.end(); ++pIt)
602 meshVertId = pIt->first;
605 if (graph[0].count(pIt->first) != 0)
607 for (i = 0; i < pIt->second.size(); ++i)
609 meshVertId2 = pIt->second[i].id;
610 if (graph[0].count(meshVertId2) == 0 &&
611 pIt->second[i].isLocal)
613 graph[0][meshVertId2] =
614 graph[0][meshVertId];
621 bool isDirichlet =
false;
622 for (i = 0; i < pIt->second.size(); ++i)
624 if (!pIt->second[i].isLocal)
629 meshVertId2 = pIt->second[i].id;
630 if (graph[0].count(meshVertId2) > 0)
639 graph[0][meshVertId] =
640 graph[0][pIt->second[i].id];
642 for (j = 0; j < pIt->second.size(); ++j)
644 meshVertId2 = pIt->second[i].id;
645 if (j == i || !pIt->second[j].isLocal ||
646 graph[0].count(meshVertId2) > 0)
651 graph[0][meshVertId2] =
652 graph[0][pIt->second[i].id];
659 for (i = 0; i < pIt->second.size(); ++i)
661 if (!pIt->second[i].isLocal)
666 if (tempGraph[0].count(pIt->second[i].id) > 0)
672 if (i == pIt->second.size())
674 tempGraph[0][meshVertId] = tempGraphVertId++;
679 tempGraph[0][meshVertId] = tempGraph[0][pIt->second[i].id];
685 localVerts = Array<OneD, int>(nTotalVerts,-1);
686 localEdges = Array<OneD, int>(nTotalEdges,-1);
687 localFaces = Array<OneD, int>(nTotalFaces,-1);
690 for(i = 0; i < locExpVector.size(); ++i)
692 exp = locExpVector[i];
694 nVerts = exp->GetNverts();
695 for(j = 0; j < nVerts; ++j)
697 meshVertId = exp->GetGeom()->GetVid(j);
698 if(graph[0].count(meshVertId) == 0)
700 if(tempGraph[0].count(meshVertId) == 0)
702 boost::add_vertex(boostGraphObj);
703 tempGraph[0][meshVertId] = tempGraphVertId++;
706 localVerts[localVertOffset+vertCnt++] = tempGraph[0][meshVertId];
707 vwgts_map[ tempGraph[0][meshVertId] ] = 1;
711 localVertOffset+=nVerts;
715 for (pIt = periodicEdges.begin(); pIt != periodicEdges.end(); ++pIt)
717 meshEdgeId = pIt->first;
720 if (graph[1].count(pIt->first) != 0)
722 for (i = 0; i < pIt->second.size(); ++i)
724 meshEdgeId2 = pIt->second[i].id;
725 if (graph[1].count(meshEdgeId2) == 0 &&
726 pIt->second[i].isLocal)
728 graph[1][meshEdgeId2] =
729 graph[1][meshEdgeId];
736 bool isDirichlet =
false;
737 for (i = 0; i < pIt->second.size(); ++i)
739 if (!pIt->second[i].isLocal)
744 meshEdgeId2 = pIt->second[i].id;
745 if (graph[1].count(meshEdgeId2) > 0)
754 graph[1][meshEdgeId] =
755 graph[1][pIt->second[i].id];
757 for (j = 0; j < pIt->second.size(); ++j)
759 meshEdgeId2 = pIt->second[i].id;
760 if (j == i || !pIt->second[j].isLocal ||
761 graph[1].count(meshEdgeId2) > 0)
766 graph[1][meshEdgeId2] =
767 graph[1][pIt->second[i].id];
774 for (i = 0; i < pIt->second.size(); ++i)
776 if (!pIt->second[i].isLocal)
781 if (tempGraph[1].count(pIt->second[i].id) > 0)
787 if (i == pIt->second.size())
789 tempGraph[1][meshEdgeId] = tempGraphVertId++;
795 tempGraph[1][meshEdgeId] = tempGraph[1][pIt->second[i].id];
799 int nEdgeIntCoeffs, nFaceIntCoeffs;
802 for(i = 0; i < locExpVector.size(); ++i)
804 exp = locExpVector[i];
806 nEdges = exp->GetNedges();
808 for(j = 0; j < nEdges; ++j)
810 nEdgeIntCoeffs = exp->GetEdgeNcoeffs(j) - 2;
811 meshEdgeId = exp->GetGeom()->GetEid(j);
812 if(graph[1].count(meshEdgeId) == 0)
814 if(tempGraph[1].count(meshEdgeId) == 0)
816 boost::add_vertex(boostGraphObj);
817 tempGraph[1][meshEdgeId] = tempGraphVertId++;
822 localEdges[localEdgeOffset+edgeCnt++] = tempGraph[1][meshEdgeId];
823 vwgts_map[ tempGraph[1][meshEdgeId] ] = nEdgeIntCoeffs;
827 localEdgeOffset+=nEdges;
831 for (pIt = periodicFaces.begin(); pIt != periodicFaces.end(); ++pIt)
833 if (!pIt->second[0].isLocal)
836 meshFaceId = pIt->first;
837 ASSERTL0(graph[2].count(meshFaceId) == 0,
838 "This periodic boundary edge has been specified before");
839 tempGraph[2][meshFaceId] = tempGraphVertId++;
840 nFaceIntCoeffs = FaceSize[meshFaceId];
844 else if (pIt->first < pIt->second[0].id)
846 ASSERTL0(graph[2].count(pIt->first) == 0,
847 "This periodic boundary face has been specified before");
848 ASSERTL0(graph[2].count(pIt->second[0].id) == 0,
849 "This periodic boundary face has been specified before");
851 tempGraph[2][pIt->first] = tempGraphVertId;
852 tempGraph[2][pIt->second[0].id] = tempGraphVertId++;
853 nFaceIntCoeffs = FaceSize[pIt->first];
860 for(i = 0; i < locExpVector.size(); ++i)
862 exp = locExpVector[i];
863 nFaces = exp->GetNfaces();
865 for(j = 0; j < nFaces; ++j)
867 nFaceIntCoeffs = exp->GetFaceIntNcoeffs(j);
868 meshFaceId = exp->GetGeom()->GetFid(j);
869 if(graph[2].count(meshFaceId) == 0)
871 if(tempGraph[2].count(meshFaceId) == 0)
873 boost::add_vertex(boostGraphObj);
874 tempGraph[2][meshFaceId] = tempGraphVertId++;
879 localFaces[localFaceOffset+faceCnt++] = tempGraph[2][meshFaceId];
880 vwgts_map[ tempGraph[2][meshFaceId] ] = nFaceIntCoeffs;
885 localFaceOffset+=nFaces;
891 for(i = 0; i < locExpVector.size(); ++i)
893 exp = locExpVector[i];
894 nVerts = exp->GetNverts();
895 nEdges = exp->GetNedges();
896 nFaces = exp->GetNfaces();
903 for(j = 0; j < nVerts; j++)
905 if(localVerts[j+localVertOffset]==-1)
910 for(k = 0; k < nVerts; k++)
912 if(localVerts[k+localVertOffset]==-1)
918 boost::add_edge( (
size_t) localVerts[j+localVertOffset],
919 (
size_t) localVerts[k+localVertOffset],boostGraphObj);
923 for(k = 0; k < nEdges; k++)
925 if(localEdges[k+localEdgeOffset]==-1)
929 boost::add_edge( (
size_t) localVerts[j+localVertOffset],
930 (
size_t) localEdges[k+localEdgeOffset],boostGraphObj);
933 for(k = 0; k < nFaces; k++)
935 if(localFaces[k+localFaceOffset]==-1)
939 boost::add_edge( (
size_t) localVerts[j+localVertOffset],
940 (
size_t) localFaces[k+localFaceOffset],boostGraphObj);
945 for(j = 0; j < nEdges; j++)
947 if(localEdges[j+localEdgeOffset]==-1)
952 for(k = 0; k < nEdges; k++)
954 if(localEdges[k+localEdgeOffset]==-1)
960 boost::add_edge( (
size_t) localEdges[j+localEdgeOffset],
961 (
size_t) localEdges[k+localEdgeOffset],boostGraphObj);
965 for(k = 0; k < nVerts; k++)
967 if(localVerts[k+localVertOffset]==-1)
971 boost::add_edge( (
size_t) localEdges[j+localEdgeOffset],
972 (
size_t) localVerts[k+localVertOffset],boostGraphObj);
975 for(k = 0; k < nFaces; k++)
977 if(localFaces[k+localFaceOffset]==-1)
981 boost::add_edge( (
size_t) localEdges[j+localEdgeOffset],
982 (
size_t) localFaces[k+localFaceOffset],boostGraphObj);
987 for(j = 0; j < nFaces; j++)
989 if(localFaces[j+localFaceOffset]==-1)
994 for(k = 0; k < nFaces; k++)
996 if(localFaces[k+localFaceOffset]==-1)
1002 boost::add_edge( (
size_t) localFaces[j+localFaceOffset],
1003 (
size_t) localFaces[k+localFaceOffset],boostGraphObj);
1007 for(k = 0; k < nVerts; k++)
1009 if(localVerts[k+localVertOffset]==-1)
1013 boost::add_edge( (
size_t) localFaces[j+localFaceOffset],
1014 (
size_t) localVerts[k+localVertOffset],boostGraphObj);
1017 for(k = 0; k < nEdges; k++)
1019 if(localEdges[k+localEdgeOffset]==-1)
1023 boost::add_edge( (
size_t) localFaces[j+localFaceOffset],
1024 (
size_t) localEdges[k+localEdgeOffset],boostGraphObj);
1028 localVertOffset+=nVerts;
1029 localEdgeOffset+=nEdges;
1030 localFaceOffset+=nFaces;
1039 vector<long> procVerts, procEdges, procFaces;
1040 set <int> foundVerts, foundEdges, foundFaces;
1045 for(i = cnt = 0; i < locExpVector.size(); ++i)
1048 exp = locExpVector[elmtid];
1049 for (j = 0; j < exp->GetNverts(); ++j)
1051 int vid = exp->GetGeom()->GetVid(j)+1;
1052 if (foundVerts.count(vid) == 0)
1054 procVerts.push_back(vid);
1055 foundVerts.insert(vid);
1059 for (j = 0; j < exp->GetNedges(); ++j)
1061 int eid = exp->GetGeom()->GetEid(j)+1;
1063 if (foundEdges.count(eid) == 0)
1065 procEdges.push_back(eid);
1066 foundEdges.insert(eid);
1070 for (j = 0; j < exp->GetNfaces(); ++j)
1072 int fid = exp->GetGeom()->GetFid(j)+1;
1074 if (foundFaces.count(fid) == 0)
1076 procFaces.push_back(fid);
1077 foundFaces.insert(fid);
1082 int unique_verts = foundVerts.size();
1083 int unique_edges = foundEdges.size();
1084 int unique_faces = foundFaces.size();
1090 Array<OneD, long> vertArray(unique_verts, &procVerts[0]);
1092 Array<OneD, NekDouble> tmp4(unique_verts, 1.0);
1093 Array<OneD, NekDouble> tmp5(unique_edges, 1.0);
1094 Array<OneD, NekDouble> tmp6(unique_faces, 1.0);
1097 if (unique_edges > 0)
1099 Array<OneD, long> edgeArray(unique_edges, &procEdges[0]);
1104 if (unique_faces > 0)
1106 Array<OneD, long> faceArray(unique_faces, &procFaces[0]);
1113 for (i = 0; i < unique_verts; ++i)
1117 if (graph[0].count(procVerts[i]-1) == 0)
1119 partVerts.insert(tempGraph[0][procVerts[i]-1]);
1124 for (i = 0; i < unique_edges; ++i)
1128 if (graph[1].count(procEdges[i]-1) == 0)
1130 partVerts.insert(tempGraph[1][procEdges[i]-1]);
1135 for (i = 0; i < unique_faces; ++i)
1139 if (graph[2].count(procFaces[i]-1) == 0)
1141 partVerts.insert(tempGraph[2][procFaces[i]-1]);
1147 int nGraphVerts = tempGraphVertId;
1148 Array<OneD, int> perm(nGraphVerts);
1149 Array<OneD, int> iperm(nGraphVerts);
1150 Array<OneD, int> vwgts(nGraphVerts);
1151 ASSERTL1(vwgts_map.size()==nGraphVerts,
"Non matching dimensions");
1152 for(i = 0; i < nGraphVerts; ++i)
1154 vwgts[i] = vwgts_map[i];
1185 boostGraphObj, perm, iperm, bottomUpGraph,
1186 partVerts, mdswitch);
1192 "Unrecognised solution type: " + std::string(
1216 for(mapIt = tempGraph[0].begin(); mapIt != tempGraph[0].end(); mapIt++)
1218 graph[0][mapIt->first] = iperm[mapIt->second] + graphVertId;
1220 for(mapIt = tempGraph[1].begin(); mapIt != tempGraph[1].end(); mapIt++)
1222 graph[1][mapIt->first] = iperm[mapIt->second] + graphVertId;
1224 for(mapIt = tempGraph[2].begin(); mapIt != tempGraph[2].end(); mapIt++)
1226 graph[2][mapIt->first] = iperm[mapIt->second] + graphVertId;
1237 const int numLocalCoeffs,
1241 const bool checkIfSystemSingular,
1242 const std::string variable,
1251 int meshVertId, meshEdgeId, meshFaceId;
1253 int nEdgeInteriorCoeffs;
1254 int nFaceInteriorCoeffs;
1255 int firstNonDirGraphVertId;
1261 Array<OneD, unsigned int> edgeInteriorMap;
1262 Array<OneD, int> edgeInteriorSign;
1263 Array<OneD, unsigned int> faceInteriorMap;
1264 Array<OneD, int> faceInteriorSign;
1265 PeriodicMap::const_iterator pIt;
1275 set<int> extraDirVerts, extraDirEdges;
1280 for (i = 0; i < locExpVector.size(); ++i)
1282 exp = locExpVector[i];
1284 for(j = 0; j < locExpVector[i]->GetNverts(); ++j)
1286 dofs[0][exp->GetGeom()->GetVid(j)] = 1;
1289 for(j = 0; j < locExpVector[i]->GetNedges(); ++j)
1291 dofs[1][exp->GetGeom()->GetEid(j)] =
1292 exp->GetEdgeNcoeffs(j) - 2;
1295 for(j = 0; j < locExpVector[i]->GetNfaces(); ++j)
1297 dofs[2][exp->GetGeom()->GetFid(j)] =
1298 exp->GetFaceIntNcoeffs(j);
1302 Array<OneD, const BndCond> bndCondVec(1, bndConditions);
1307 int nExtraDirichlet;
1310 checkIfSystemSingular, periodicVerts, periodicEdges,
1311 periodicFaces, graph, bottomUpGraph, extraDirVerts,
1312 extraDirEdges, firstNonDirGraphVertId,
1326 Array<OneD, int> graphVertOffset(
1327 graph[0].size() + graph[1].size() + graph[2].size() + 1);
1329 graphVertOffset[0] = 0;
1331 for(i = 0; i < locExpVector.size(); ++i)
1335 for(j = 0; j < exp->GetNverts(); ++j)
1337 meshVertId = exp->GetGeom()->GetVid(j);
1338 graphVertOffset[graph[0][meshVertId]+1] = 1;
1341 for(j = 0; j < exp->GetNedges(); ++j)
1343 nEdgeInteriorCoeffs = exp->GetEdgeNcoeffs(j) - 2;
1344 meshEdgeId = exp->GetGeom()->GetEid(j);
1345 graphVertOffset[graph[1][meshEdgeId]+1]
1346 = nEdgeInteriorCoeffs;
1348 bType = exp->GetEdgeBasisType(j);
1352 if(nEdgeInteriorCoeffs >= 2 &&
1360 for(j = 0; j < exp->GetNfaces(); ++j)
1362 nFaceInteriorCoeffs = exp->GetFaceIntNcoeffs(j);
1363 meshFaceId = exp->GetGeom()->GetFid(j);
1364 graphVertOffset[graph[2][meshFaceId]+1] = nFaceInteriorCoeffs;
1368 for(i = 1; i < graphVertOffset.num_elements(); i++)
1370 graphVertOffset[i] += graphVertOffset[i-1];
1395 m_numLocalIntCoeffsPerPatch[i] = (
unsigned int)
1412 for(i = 0; i < locExpVector.size(); ++i)
1414 exp = locExpVector[i];
1416 for(j = 0; j < exp->GetNverts(); ++j)
1418 meshVertId = exp->GetGeom()->GetVid(j);
1422 graphVertOffset[graph[0][meshVertId]];
1425 for(j = 0; j < exp->GetNedges(); ++j)
1427 nEdgeInteriorCoeffs = exp->GetEdgeNcoeffs(j)-2;
1428 edgeOrient = exp->GetGeom()->GetEorient(j);
1429 meshEdgeId = exp->GetGeom()->GetEid(j);
1431 pIt = periodicEdges.find(meshEdgeId);
1436 if (pIt != periodicEdges.end())
1438 int minId = pIt->second[0].id;
1440 for (k = 1; k < pIt->second.size(); ++k)
1442 if (pIt->second[k].id < minId)
1444 minId = min(minId, pIt->second[k].id);
1449 if( meshEdgeId != min(minId, meshEdgeId))
1461 exp->GetEdgeInteriorMap(j,edgeOrient,edgeInteriorMap,edgeInteriorSign);
1464 for(k = 0; k < nEdgeInteriorCoeffs; ++k)
1467 graphVertOffset[graph[1][meshEdgeId]]+k;
1473 for(k = 0; k < nEdgeInteriorCoeffs; ++k)
1480 for(j = 0; j < exp->GetNfaces(); ++j)
1482 nFaceInteriorCoeffs = exp->GetFaceIntNcoeffs(j);
1483 faceOrient = exp->GetGeom()->GetForient(j);
1484 meshFaceId = exp->GetGeom()->GetFid(j);
1486 pIt = periodicFaces.find(meshFaceId);
1488 if (pIt != periodicFaces.end() &&
1489 meshFaceId == min(meshFaceId, pIt->second[0].id))
1494 exp->GetFaceInteriorMap(j,faceOrient,faceInteriorMap,faceInteriorSign);
1497 for(k = 0; k < nFaceInteriorCoeffs; ++k)
1500 graphVertOffset[graph[2][meshFaceId]]+k;
1505 for(k = 0; k < nFaceInteriorCoeffs; ++k)
1516 for(i = 0; i < bndCondExp.num_elements(); i++)
1518 set<int> foundExtraVerts, foundExtraEdges;
1519 for(j = 0; j < bndCondExp[i]->GetNumElmts(); j++)
1521 bndExp = bndCondExp[i]->GetExp(j);
1522 cnt = offset + bndCondExp[i]->GetCoeff_Offset(j);
1523 for(k = 0; k < bndExp->GetNverts(); k++)
1525 meshVertId = bndExp->GetGeom()->GetVid(k);
1526 m_bndCondCoeffsToGlobalCoeffsMap[cnt+bndExp->GetVertexMap(k)] = graphVertOffset[graph[0][meshVertId]];
1528 if (bndConditions[i]->GetBoundaryConditionType() !=
1535 if (iter != extraDirVerts.end() &&
1536 foundExtraVerts.count(meshVertId) == 0)
1538 int loc = bndCondExp[i]->GetCoeff_Offset(j) +
1539 bndExp->GetVertexMap(k);
1540 int gid = graphVertOffset[
1541 graph[0][meshVertId]];
1544 foundExtraVerts.insert(meshVertId);
1548 for(k = 0; k < bndExp->GetNedges(); k++)
1550 nEdgeInteriorCoeffs = bndExp->GetEdgeNcoeffs(k)-2;
1551 edgeOrient = bndExp->GetGeom()->GetEorient(k);
1552 meshEdgeId = bndExp->GetGeom()->GetEid(k);
1554 pIt = periodicEdges.find(meshEdgeId);
1559 if (pIt != periodicEdges.end())
1561 int minId = pIt->second[0].id;
1563 for (l = 1; l < pIt->second.size(); ++l)
1565 if (pIt->second[l].id < minId)
1567 minId = min(minId, pIt->second[l].id);
1573 meshEdgeId != min(minId, meshEdgeId))
1579 bndExp->GetEdgeInteriorMap(
1580 k,edgeOrient,edgeInteriorMap,edgeInteriorSign);
1582 for(l = 0; l < nEdgeInteriorCoeffs; ++l)
1584 m_bndCondCoeffsToGlobalCoeffsMap[cnt+edgeInteriorMap[l]] =
1585 graphVertOffset[graph[1][meshEdgeId]]+l;
1591 for(l = 0; l < nEdgeInteriorCoeffs; ++l)
1597 if (bndConditions[i]->GetBoundaryConditionType() !=
1604 if (iter != extraDirEdges.end() &&
1605 foundExtraEdges.count(meshEdgeId) == 0 &&
1606 nEdgeInteriorCoeffs > 0)
1608 for(l = 0; l < nEdgeInteriorCoeffs; ++l)
1610 int loc = bndCondExp[i]->GetCoeff_Offset(j) +
1612 int gid = graphVertOffset[
1613 graph[1][meshEdgeId]]+l;
1617 foundExtraEdges.insert(meshEdgeId);
1621 meshFaceId = bndExp->GetGeom()->GetGlobalID();
1623 for(k = 0; k < bndExp->GetNcoeffs(); k++)
1625 if(m_bndCondCoeffsToGlobalCoeffsMap[cnt+k] == -1)
1627 m_bndCondCoeffsToGlobalCoeffsMap[cnt+k] =
1628 graphVertOffset[graph[bndExp->GetNumBases()][meshFaceId]]+intDofCnt;
1633 offset += bndCondExp[i]->GetNcoeffs();
1673 map<int, vector<ExtraDirDof> >
::iterator Tit;
1678 for (i = 0; i < Tit->second.size(); ++i)
1680 valence[Tit->second[i].get<1>()] = 1.0;
1689 for (i = 0; i < Tit->second.size(); ++i)
1691 boost::get<2>(Tit->second.at(i)) /= valence[Tit->second.at(i).get<1>()];
1704 Array<OneD, int> vwgts_perm(
1705 dofs[0].size() + dofs[1].size() + dofs[2].size()
1706 - firstNonDirGraphVertId);
1708 for (i = 0; i < locExpVector.size(); ++i)
1712 for (j = 0; j < exp->GetNverts(); ++j)
1714 meshVertId = exp->GetGeom()->GetVid(j);
1716 if (graph[0][meshVertId] >= firstNonDirGraphVertId)
1718 vwgts_perm[graph[0][meshVertId] -
1719 firstNonDirGraphVertId] =
1720 dofs[0][meshVertId];
1724 for (j = 0; j < exp->GetNedges(); ++j)
1726 meshEdgeId = exp->GetGeom()->GetEid(j);
1728 if (graph[1][meshEdgeId] >= firstNonDirGraphVertId)
1730 vwgts_perm[graph[1][meshEdgeId] -
1731 firstNonDirGraphVertId] =
1732 dofs[1][meshEdgeId];
1736 for (j = 0; j < exp->GetNfaces(); ++j)
1738 meshFaceId = exp->GetGeom()->GetFid(j);
1740 if (graph[2][meshFaceId] >= firstNonDirGraphVertId)
1742 vwgts_perm[graph[2][meshFaceId] -
1743 firstNonDirGraphVertId] =
1744 dofs[2][meshFaceId];
1749 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
1790 int tmp1 = (int)faceOrient - 5;
1791 int tmp2 = (int)perFaceOrient - 5;
1793 int flipDir1Map [8] = {2,3,0,1,6,7,4,5};
1794 int flipDir2Map [8] = {1,0,3,2,5,4,7,6};
1795 int transposeMap[8] = {4,5,6,7,0,2,1,3};
1800 tmp1 = transposeMap[tmp1];
1804 if (tmp2 == 2 || tmp2 == 3 || tmp2 == 6 || tmp2 == 7)
1806 tmp1 = flipDir1Map[tmp1];
1812 tmp1 = flipDir2Map[tmp1];
1846 int maxBndGlobalId = 0;
1849 Array<OneD, unsigned int> edgeInteriorMap;
1850 Array<OneD, int> edgeInteriorSign;
1851 Array<OneD, unsigned int> faceInteriorMap;
1852 Array<OneD, int> faceInteriorSign;
1853 Array<OneD, unsigned int> interiorMap;
1854 PeriodicMap::const_iterator pIt;
1865 for(i = 0; i < locExpVector.size(); ++i)
1867 exp = locExpVector[i];
1868 nVert += exp->GetNverts();
1869 nEdge += exp->GetNedges();
1870 nFace += exp->GetNfaces();
1872 for(j = 0; j < exp->GetNedges(); ++j)
1874 dof = exp->GetEdgeNcoeffs(j)-2;
1875 maxEdgeDof = (dof > maxEdgeDof ? dof : maxEdgeDof);
1877 for(j = 0; j < exp->GetNfaces(); ++j)
1879 dof = exp->GetFaceIntNcoeffs(j);
1880 maxFaceDof = (dof > maxFaceDof ? dof : maxFaceDof);
1882 exp->GetInteriorMap(interiorMap);
1883 dof = interiorMap.num_elements();
1884 maxIntDof = (dof > maxIntDof ? dof : maxIntDof);
1896 for(i = 0; i < locExpVector.size(); ++i)
1898 exp = locExpVector[i];
1902 for(j = 0; j < exp->GetNverts(); ++j)
1904 meshVertId = exp->GetGeom()->GetVid(j);
1907 pIt = perVerts.find(meshVertId);
1908 if (pIt != perVerts.end())
1910 for (k = 0; k < pIt->second.size(); ++k)
1912 meshVertId = min(meshVertId, pIt->second[k].id);
1918 maxBndGlobalId = (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
1922 for(j = 0; j < exp->GetNedges(); ++j)
1924 meshEdgeId = exp->GetGeom()->GetEid(j);
1925 pIt = perEdges.find(meshEdgeId);
1926 if (pIt != perEdges.end())
1928 for (k = 0; k < pIt->second.size(); ++k)
1930 meshEdgeId = min(meshEdgeId, pIt->second[k].id);
1934 edgeOrient = exp->GetGeom()->GetEorient(j);
1935 exp->GetEdgeInteriorMap(j,edgeOrient,edgeInteriorMap,edgeInteriorSign);
1936 dof = exp->GetEdgeNcoeffs(j)-2;
1939 for(k = 0; k < dof; ++k)
1943 = nVert + meshEdgeId * maxEdgeDof + k + 1;
1945 maxBndGlobalId = (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
1950 for(j = 0; j < exp->GetNfaces(); ++j)
1952 faceOrient = exp->GetGeom()->GetForient(j);
1954 meshFaceId = exp->GetGeom()->GetFid(j);
1956 pIt = perFaces.find(meshFaceId);
1957 if (pIt != perFaces.end())
1959 if(meshFaceId == min(meshFaceId, pIt->second[0].id))
1963 meshFaceId = min(meshFaceId, pIt->second[0].id);
1967 exp->GetFaceInteriorMap(j,faceOrient,faceInteriorMap,faceInteriorSign);
1968 dof = exp->GetFaceIntNcoeffs(j);
1971 for(k = 0; k < dof; ++k)
1975 = nVert + nEdge*maxEdgeDof + meshFaceId * maxFaceDof
1979 maxBndGlobalId = (vGlobalId > maxBndGlobalId ? vGlobalId : maxBndGlobalId);
1984 exp->GetInteriorMap(interiorMap);
1985 dof = interiorMap.num_elements();
1986 elementId = (exp->GetGeom())->GetGlobalID();
1987 for (k = 0; k < dof; ++k)
1991 = nVert + nEdge*maxEdgeDof + nFace*maxFaceDof + elementId*maxIntDof + k + 1;
1999 Nektar::Array<OneD, long> tmp(m_numGlobalCoeffs);
2001 Nektar::Array<OneD, long> tmp2(m_numGlobalBndCoeffs, tmp);
2012 m_globalToUniversalMapUnique[i] = (tmp[i] >= 0 ? 1 : 0);
2016 m_globalToUniversalBndMapUnique[i] = (tmp2[i] >= 0 ? 1 : 0);
2035 const boost::shared_ptr<LocalRegions::ExpansionVector> exp
2037 int nelmts = exp->size();
2042 returnval->m_solnType = solnType;
2043 returnval->m_preconType =
eNull;
2044 returnval->m_maxStaticCondLevel = 0;
2045 returnval->m_signChange =
false;
2046 returnval->m_comm =
m_comm;
2049 for (i = 0; i < nelmts; ++i)
2051 nverts += (*exp)[i]->GetNverts();
2054 returnval->m_numLocalCoeffs = nverts;
2055 returnval->m_localToGlobalMap = Array<OneD, int>(nverts, -1);
2058 returnval->m_localToGlobalBndMap = Array<OneD, int>(nverts, -1);
2065 for (i = 0; i < nelmts; ++i)
2067 for (j = 0; j < (*exp)[i]->GetNverts(); ++j)
2069 returnval->m_localToGlobalMap[cnt] =
2070 returnval->m_localToGlobalBndMap[cnt] =
2072 GlobCoeffs[returnval->m_localToGlobalMap[cnt]] = 1;
2075 if ((returnval->m_localToGlobalMap[cnt]) <
2078 returnval->m_numLocalDirBndCoeffs++;
2082 cnt1 += (*exp)[i]->GetNcoeffs();
2089 if (GlobCoeffs[i] != -1)
2091 GlobCoeffs[i] = cnt++;
2096 returnval->m_numGlobalCoeffs = cnt;
2101 if (GlobCoeffs[i] != -1)
2103 returnval->m_numGlobalDirBndCoeffs++;
2112 int nglocoeffs = returnval->m_numGlobalCoeffs;
2113 returnval->m_globalToUniversalMap
2114 = Array<OneD, int> (nglocoeffs);
2115 returnval->m_globalToUniversalMapUnique
2116 = Array<OneD, int> (nglocoeffs);
2119 for (i = 0; i < nverts; ++i)
2121 cnt = returnval->m_localToGlobalMap[i];
2122 returnval->m_localToGlobalMap[i] = GlobCoeffs[cnt];
2124 returnval->m_globalToUniversalMap[GlobCoeffs[cnt]] =
2128 Nektar::Array<OneD, long> tmp(nglocoeffs);
2130 for (
unsigned int i = 0; i < nglocoeffs; ++i)
2132 tmp[i] = returnval->m_globalToUniversalMap[i];
2134 returnval->m_gsh =
Gs::Init(tmp, vCommRow);
2136 for (
unsigned int i = 0; i < nglocoeffs; ++i)
2138 returnval->m_globalToUniversalMapUnique[i]
2139 = (tmp[i] >= 0 ? 1 : 0);
2144 for (i = 0; i < nverts; ++i)
2146 cnt = returnval->m_localToGlobalMap[i];
2147 returnval->m_localToGlobalMap[i] = GlobCoeffs[cnt];
2180 for(j = 0; j < locSize; j++)
2195 bwidth = (bwidth>(maxId-minId))?bwidth:(maxId-minId);
2219 const Array<OneD,const int>&
2225 const Array<OneD,const int>&
2231 const Array<OneD,const int>&
2256 const Array<OneD, const NekDouble>& loc,
2257 Array<OneD, NekDouble>& global)
const
2259 Array<OneD, const NekDouble> local;
2260 if(global.data() == loc.data())
2262 local = Array<OneD, NekDouble>(loc.num_elements(),loc.data());
2291 const Array<OneD, const NekDouble>& global,
2292 Array<OneD, NekDouble>& loc)
const
2294 Array<OneD, const NekDouble> glo;
2295 if(global.data() == loc.data())
2297 glo = Array<OneD, NekDouble>(global.num_elements(),global.data());
2323 const Array<OneD, const NekDouble> &loc,
2324 Array<OneD, NekDouble> &global)
const
2326 Array<OneD, const NekDouble> local;
2327 if(global.data() == loc.data())
2329 local = Array<OneD, NekDouble>(local.num_elements(),local.data());
2358 Array<OneD, NekDouble>& pGlobal)
const
2370 Array<OneD, NekDouble>& pGlobal,
2373 Array<OneD, NekDouble> tmp(offset);