49 #include <boost/config.hpp>
50 #include <boost/graph/adjacency_list.hpp>
51 #include <boost/graph/cuthill_mckee_ordering.hpp>
52 #include <boost/graph/properties.hpp>
53 #include <boost/graph/bandwidth.hpp>
58 namespace MultiRegions
61 m_numDirichletBndPhys(0)
78 const Array<OneD, const MultiRegions::ExpListSharedPtr> &bndCondExp,
79 const Array<OneD, const SpatialDomains::BoundaryConditionShPtr> &bndCond,
81 const std::string variable)
86 int ntrace_exp = trace->GetExpSize();
87 int nbnd = bndCondExp.num_elements();
89 int nel = locExp.
GetExp()->size();
90 map<int, int> MeshVertId;
93 for(i = 0; i < ntrace_exp; ++i)
95 int id = trace->GetExp(i)->GetGeom()->GetVid(0);
100 Array<OneD, StdRegions::StdExpansionSharedPtr> vertmap(2*nel);
101 m_elmtToTrace = Array<OneD, Array<OneD,StdRegions::StdExpansionSharedPtr> >(nel);
105 for(i = 0; i < nel; ++i)
109 for(j = 0; j < locExp.
GetExp(i)->GetNverts(); ++j)
111 int id = ((locExp.
GetExp(i)->GetGeom())->GetVertex(j))->GetVid();
113 if(MeshVertId.count(
id) > 0)
115 m_elmtToTrace[i][j] = (*trace).GetExp(MeshVertId.find(
id)->second)->as<LocalRegions::PointExp>();
120 ASSERTL0(
false,
"Failed to find edge map");
127 Array<OneD,unsigned int> vmap;
130 const boost::shared_ptr<LocalRegions::ExpansionVector> exp1D = locExp.
GetExp();
146 m_numLocalIntCoeffsPerPatch[i] = (
unsigned int) 0;
149 map<int, int> MeshVertToLocalVert;
153 for(i = 0; i < nbnd; i++)
158 vid = bndCondExp[i]->GetExp(0)->GetGeom()->GetVertex(0)->GetVid();
160 MeshVertToLocalVert[vid] = gid++;
166 for(i = 0; i < exp1D->size(); ++i)
168 if((locSegExp = (*exp1D)[i]->as<LocalRegions::SegExp>()))
170 locSegExp->GetBoundaryMap(vmap);
172 for(j = 0; j < locSegExp->GetNverts(); ++j)
174 vid = (locSegExp->GetGeom1D())->GetVid(j);
176 if(MeshVertToLocalVert.count(vid) == 0)
178 MeshVertToLocalVert[vid] = gid++;
182 MeshVertToLocalVert.find(vid)->second;
184 cnt += locSegExp->NumBndryCoeffs();
188 ASSERTL0(
false,
"dynamic cast to a segment expansion failed");
198 for(i = 0; i < nbnd; ++i)
200 vid = bndCondExp[i]->GetExp(0)->GetGeom()->GetVertex(0)->GetVid();
215 for(i = 0; i < bndCondExp.num_elements(); ++i)
217 int id = bndCondExp[i]->GetExp(0)->GetGeom()->GetVid(0);
219 MeshVertId.find(
id)->second;
223 #if 1 // Routines need debugging -> Currently causing crash when turned on
242 const Array<OneD, MultiRegions::ExpListSharedPtr> &bndCondExp,
243 const Array<OneD, SpatialDomains::BoundaryConditionShPtr> &bndCond,
245 const std::string variable) :
249 int i,j,k,cnt,eid, id, id1, order_e,gid;
250 int ntrace_exp = trace->GetExpSize();
251 int nbnd = bndCondExp.num_elements();
257 const boost::shared_ptr<LocalRegions::ExpansionVector> exp2D = locExp.
GetExp();
258 int nel = exp2D->size();
260 map<int, int> MeshEdgeId;
265 for(i = 0; i < ntrace_exp; ++i)
269 id = (locSegExp->GetGeom1D())->GetEid();
274 ASSERTL0(
false,
"Dynamics cast to segment expansion failed");
280 for(i = 0; i < nel; ++i)
282 cnt += (*exp2D)[i]->GetNedges();
285 Array<OneD, StdRegions::StdExpansionSharedPtr> edgemap(cnt);
286 m_elmtToTrace = Array<OneD, Array<OneD,StdRegions::StdExpansionSharedPtr> >(nel);
290 for(i = 0; i < nel; ++i)
294 if((locQuadExp = (*exp2D)[i]->as<LocalRegions::QuadExp>()))
296 for(j = 0; j < locQuadExp->GetNedges(); ++j)
298 SegGeom = (locQuadExp->GetGeom2D())->
GetEdge(j);
300 id = SegGeom->GetEid();
302 if(MeshEdgeId.count(
id) > 0)
310 ASSERTL0(
false,
"Failed to find edge map");
314 else if((locTriExp = (*exp2D)[i]->as<LocalRegions::TriExp>()))
316 for(j = 0; j < locTriExp->GetNedges(); ++j)
318 SegGeom = (locTriExp->GetGeom2D())->
GetEdge(j);
320 id = SegGeom->GetEid();
322 if(MeshEdgeId.count(
id) > 0)
330 ASSERTL0(
false,
"Failed to find edge map");
337 ASSERTL0(
false,
"dynamic cast to a local 2D expansion failed");
339 cnt += (*exp2D)[i]->GetNedges();
344 for(i = 0; i < nbnd; ++i)
346 cnt += bndCondExp[i]->GetExpSize();
353 for(i = 0; i < bndCondExp.num_elements(); ++i)
355 for(j = 0; j < bndCondExp[i]->GetExpSize(); ++j)
357 if((locSegExp = bndCondExp[i]->GetExp(j)
358 ->as<LocalRegions::SegExp>()))
360 SegGeom = locSegExp->GetGeom1D();
361 id = SegGeom->GetEid();
365 ASSERTL0(
false,
"dynamic cast to a local Segment expansion failed");
386 for(i = 0; i < nel; ++i)
389 nbndry += (*exp2D)[eid]->NumDGBndryCoeffs();
391 m_numLocalIntCoeffsPerPatch[i] = (
unsigned int) 0;
402 Array<OneD,int> TraceElmtGid(ntrace_exp,-1);
409 typedef boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS> BoostGraph;
411 BoostGraph boostGraphObj;
412 int trace_id,trace_id1;
416 for(i = 0; i < ntrace_exp; ++i)
422 boost::add_vertex(boostGraphObj);
423 TraceElmtGid[i] = cnt++;
428 TraceElmtGid[i] = trace->GetCoeff_Offset(i);
434 for(i = 0; i < nel; ++i)
437 nbndry += (*exp2D)[eid]->NumDGBndryCoeffs();
439 for(j = 0; j < (*exp2D)[eid]->GetNedges(); ++j)
445 id = SegGeom->GetEid();
446 trace_id = MeshEdgeId.find(
id)->second;
449 for(k = j+1; k < (*exp2D)[eid]->GetNedges(); ++k)
454 id1 = SegGeom->GetEid();
455 trace_id1 = MeshEdgeId.find(id1)->second;
456 if(trace->GetCoeff_Offset(trace_id1)
459 boost::add_edge( (
size_t) TraceElmtGid[trace_id], (
size_t) TraceElmtGid[trace_id1], boostGraphObj);
467 int nGraphVerts = ntrace_exp-nDir;
468 Array<OneD, int> perm(nGraphVerts);
469 Array<OneD, int> iperm(nGraphVerts);
471 Array<OneD, int> vwgts(nGraphVerts);
472 for(i = 0; i < nGraphVerts; ++i)
474 vwgts[i] = trace->GetExp(i+nDir)->GetNcoeffs();
503 ASSERTL0(
false,
"Unrecognised solution type");
512 for(i = 0; i < ntrace_exp-nDir; ++i)
514 TraceElmtGid[perm[i]+nDir]=cnt;
515 cnt += trace->GetExp(perm[i]+nDir)->GetNcoeffs();
520 for(i = 0; i < nel; ++i)
526 nbndry += (*exp2D)[eid]->NumDGBndryCoeffs();
528 for(j = 0; j < (*exp2D)[eid]->GetNedges(); ++j)
533 id = SegGeom->GetEid();
534 gid = TraceElmtGid[MeshEdgeId.find(
id)->second];
541 for(k = 0; k < order_e; ++k)
548 switch(locSegExp->GetBasisType(0))
555 for (k = 2; k < order_e; ++k)
561 for(k = 3; k < order_e; k+=2)
563 m_localToGlobalBndSign[cnt+k] = -1.0;
570 for(k = 0; k < order_e; ++k)
579 for(k = 0; k < order_e; ++k)
587 ASSERTL0(
false,
"Boundary type not permitted");
598 for(i = 0; i < nbnd; ++i)
600 cnt += bndCondExp[i]->GetNcoeffs();
607 for(cnt = i = 0; i < nbnd; ++i)
609 for(j = 0; j < bndCondExp[i]->GetExpSize(); ++j)
611 if((locSegExp = bndCondExp[i]->GetExp(j)
612 ->as<LocalRegions::SegExp>()))
615 SegGeom = locSegExp->GetGeom1D();
616 id = SegGeom->GetEid();
617 gid = TraceElmtGid[MeshEdgeId.find(
id)->second];
619 order_e = locSegExp->GetNcoeffs();
624 for(k = 0; k < order_e; ++k)
642 Array<OneD, int> vwgts_perm(nGraphVerts);
644 for(
int i = 0; i < nGraphVerts; i++)
646 vwgts_perm[i] = vwgts[perm[i]];
649 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
658 for(i = 0; i < bndCondExp.num_elements(); ++i)
660 for(j = 0; j < bndCondExp[i]->GetExpSize(); ++j)
662 if((locSegExp = bndCondExp[i]->GetExp(j)
663 ->as<LocalRegions::SegExp>()))
665 SegGeom = locSegExp->GetGeom1D();
666 id = SegGeom->GetEid();
690 const Array<OneD, MultiRegions::ExpListSharedPtr> &bndCondExp,
691 const Array<OneD, SpatialDomains::BoundaryConditionShPtr> &bndCond,
693 const std::string variable):
696 int i,j,k,cnt,eid, id, id1, order_e,gid;
697 int ntrace_exp = trace->GetExpSize();
698 int nbnd = bndCondExp.num_elements();
708 const boost::shared_ptr<LocalRegions::ExpansionVector> exp3D =
710 int nel = exp3D->size();
712 map<int, int> MeshFaceId;
717 for(i = 0; i < ntrace_exp; ++i)
720 ->GetGeom2D()->GetFid();
726 for(i = 0; i < nel; ++i)
728 cnt += (*exp3D)[i]->GetNfaces();
731 Array<OneD, StdRegions::StdExpansionSharedPtr> facemap(cnt);
733 Array<OneD, StdRegions::StdExpansionSharedPtr> >(nel);
737 for(i = 0; i < nel; ++i)
741 for(j = 0; j < (*exp3D)[i]->GetNfaces(); ++j)
744 ->GetGeom3D()->GetFid(j);
746 if(MeshFaceId.count(
id) > 0)
749 trace->GetExp(MeshFaceId.find(
id)->second);
753 ASSERTL0(
false,
"Failed to find face map");
757 cnt += (*exp3D)[i]->GetNfaces();
762 for(i = 0; i < nbnd; ++i)
764 cnt += bndCondExp[i]->GetExpSize();
773 for(i = 0; i < bndCondExp.num_elements(); ++i)
775 for(j = 0; j < bndCondExp[i]->GetExpSize(); ++j)
777 locBndExp = bndCondExp[i]->GetExp(j);
780 id = FaceGeom->GetFid();
782 if(bndCond[i]->GetBoundaryConditionType() ==
803 for(i = 0; i < nel; ++i)
806 nbndry += (*exp3D)[eid]->NumDGBndryCoeffs();
808 m_numLocalIntCoeffsPerPatch[i] = (
unsigned int) 0;
818 Array<OneD,int> FaceElmtGid(ntrace_exp,-1);
825 typedef boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS> BoostGraph;
827 BoostGraph boostGraphObj;
828 int face_id, face_id1;
833 for(i = 0; i < ntrace_exp; ++i)
836 ->GetGeom2D()->GetFid();
838 if (dirFaces.count(
id) == 0)
842 boost::add_vertex(boostGraphObj);
843 FaceElmtGid[i] = cnt++;
848 FaceElmtGid[i] = dirOffset;
849 dirOffset += trace->GetExp(i)->GetNcoeffs();
855 for(i = 0; i < nel; ++i)
859 for(j = 0; j < (*exp3D)[eid]->GetNfaces(); ++j)
864 id = FaceGeom->GetFid();
865 face_id = MeshFaceId.find(
id)->second;
867 if(dirFaces.count(
id) == 0)
869 for(k = j+1; k < (*exp3D)[eid]->GetNfaces(); ++k)
873 id1 = FaceGeom->GetFid();
874 face_id1 = MeshFaceId.find(id1)->second;
876 if(dirFaces.count(id1) == 0)
878 boost::add_edge((
size_t) FaceElmtGid[face_id],
879 (
size_t) FaceElmtGid[face_id1],
887 int nGraphVerts = ntrace_exp - nDir;
888 Array<OneD, int> perm (nGraphVerts);
889 Array<OneD, int> iperm(nGraphVerts);
890 Array<OneD, int> vwgts(nGraphVerts);
893 for(i = 0; i < nGraphVerts; ++i)
895 vwgts[i] = trace->GetExp(i+nDir)->GetNcoeffs();
925 ASSERTL0(
false,
"Unrecognised solution type");
933 for(i = 0; i < ntrace_exp - nDir; ++i)
935 FaceElmtGid[perm[i]+nDir] = cnt;
936 cnt += trace->GetExp(perm[i]+nDir)->GetNcoeffs();
941 for(i = 0; i < nel; ++i)
946 for(j = 0; j < (*exp3D)[eid]->GetNfaces(); ++j)
950 id = FaceGeom->GetFid();
951 gid = FaceElmtGid[MeshFaceId.find(
id)->second];
952 order_e = (*exp3D)[eid]->GetFaceNcoeffs(j);
954 std::map<int,int> orientMap;
956 Array<OneD, unsigned int> elmMap1 (order_e);
957 Array<OneD, int> elmSign1(order_e);
958 Array<OneD, unsigned int> elmMap2 (order_e);
959 Array<OneD, int> elmSign2(order_e);
965 (*exp3D)[eid]->GetFaceToElementMap(j,fo,elmMap1,elmSign1);
966 (*exp3D)[eid]->GetFaceToElementMap(
969 for (k = 0; k < elmMap1.num_elements(); ++k)
974 for (
int l = 0; l < elmMap2.num_elements(); ++l)
976 if (elmMap1[k] == elmMap2[l])
983 ASSERTL2(idx != -1,
"Problem with face to element map!");
987 for(k = 0; k < order_e; ++k)
990 m_localToGlobalBndSign[k+cnt] = elmSign2[orientMap[k]];
999 for(i = 0; i < nbnd; ++i)
1001 cnt += bndCondExp[i]->GetNcoeffs();
1007 int nbndexp = 0, bndOffset, bndTotal = 0;
1008 for(cnt = i = 0; i < nbnd; ++i)
1010 for(j = 0; j < bndCondExp[i]->GetExpSize(); ++j)
1012 locBndExp = bndCondExp[i]->GetExp(j);
1014 ->GetGeom2D()->GetFid();
1015 gid = FaceElmtGid[MeshFaceId.find(
id)->second];
1016 bndOffset = bndCondExp[i]->GetCoeff_Offset(j) + bndTotal;
1021 for(k = 0; k < locBndExp->GetNcoeffs(); ++k)
1027 nbndexp += bndCondExp[i]->GetExpSize();
1028 bndTotal += bndCondExp[i]->GetNcoeffs();
1040 Array<OneD, int> vwgts_perm(nGraphVerts);
1042 for(
int i = 0; i < nGraphVerts; i++)
1044 vwgts_perm[i] = vwgts[perm[i]];
1047 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
1056 for(i = 0; i < bndCondExp.num_elements(); ++i)
1058 for(j = 0; j < bndCondExp[i]->GetExpSize(); ++j)
1060 locBndExp = bndCondExp[i]->GetExp(j);
1063 id = FaceGeom->GetFid();
1065 MeshFaceId.find(
id)->second;
1107 for(i = 0; i < locExpVector.size(); ++i)
1109 locExpansion = boost::dynamic_pointer_cast<
1116 maxDof = (1 > maxDof ? 1 : maxDof);
1120 for (j = 0; j < locExpansion->GetNedges(); ++j)
1122 dof = locExpansion->GetEdgeNcoeffs(j);
1123 maxDof = (dof > maxDof ? dof : maxDof);
1128 for (j = 0; j < locExpansion->GetNfaces(); ++j)
1130 dof = locExpansion->GetFaceNcoeffs(j);
1131 maxDof = (dof > maxDof ? dof : maxDof);
1139 for(i = 0; i < locExpVector.size(); ++i)
1141 locExpansion = boost::dynamic_pointer_cast<
1152 int nverts = locExpansion->GetNverts();
1153 for(j = 0; j < nverts; ++j)
1157 id = locPointExp->
GetGeom()->GetGlobalID();
1160 =
id * maxDof + j + 1;
1166 for(j = 0; j < locExpansion->GetNedges(); ++j)
1172 order_e = locExpVector[eid]->GetEdgeNcoeffs(j);
1174 map<int,int> orientMap;
1175 Array<OneD, unsigned int> map1(order_e), map2(order_e);
1176 Array<OneD, int> sign1(order_e), sign2(order_e);
1179 locExpVector[eid]->GetEdgeToElementMap(j, locExpVector[eid]->GetEorient(j), map2, sign2);
1181 for (k = 0; k < map1.num_elements(); ++k)
1186 for (
int l = 0; l < map2.num_elements(); ++l)
1188 if (map1[k] == map2[l])
1195 ASSERTL2(idx != -1,
"Problem with face to element map!");
1199 for(k = 0; k < order_e; ++k)
1203 =
id * maxDof + orientMap[k] + 1;
1210 for(j = 0; j < locExpansion->GetNfaces(); ++j)
1217 order_e = locExpVector[eid]->GetFaceNcoeffs(j);
1219 map<int,int> orientMap;
1220 Array<OneD, unsigned int> map1(order_e), map2(order_e);
1221 Array<OneD, int> sign1(order_e), sign2(order_e);
1224 locExpVector[eid]->GetFaceToElementMap(j, locExpVector[eid]->GetFaceOrient(j), map2, sign2);
1226 for (k = 0; k < map1.num_elements(); ++k)
1231 for (
int l = 0; l < map2.num_elements(); ++l)
1233 if (map1[k] == map2[l])
1240 ASSERTL2(idx != -1,
"Problem with face to element map!");
1244 for(k = 0; k < order_e; ++k)
1248 =
id * maxDof + orientMap[k] + 1;
1265 m_globalToUniversalBndMapUnique[i] = (tmp[i] >= 0 ? 1 : 0);
1274 Array<OneD, int> tmp;
1277 int maxQuad = 0, quad = 0, nDim = 0, eid = 0, offset = 0;
1281 int nTracePhys = trace->GetTotPoints();
1285 Nektar::Array<OneD, int>(nTracePhys, -1);
1287 Nektar::Array<OneD, int>(nTracePhys, -1);
1291 nDim = locExpVector[0]->GetShapeDimension();
1295 maxQuad = (1 > maxQuad ? 1 : maxQuad);
1299 for (i = 0; i < trace->GetExpSize(); ++i)
1301 quad = trace->GetExp(i)->GetTotPoints();
1312 for (
int i = 0; i < trace->GetExpSize(); ++i)
1314 eid = trace->GetExp(i)->GetGeom()->GetGlobalID();
1315 offset = trace->GetPhys_Offset(i);
1320 PeriodicMap::const_iterator it = perMap.find(eid);
1321 if (perMap.count(eid) > 0)
1326 eid = min(eid, ent.
id);
1336 for (
int i = 0; i < trace->GetExpSize(); ++i)
1338 eid = trace->GetExp(i)->GetGeom()->GetGlobalID();
1339 offset = trace->GetPhys_Offset(i);
1340 quad = trace->GetExp(i)->GetTotPoints();
1346 PeriodicMap::const_iterator it = perMap.find(eid);
1347 bool realign =
false;
1348 if (perMap.count(eid) > 0)
1353 realign = eid == min(eid, ent.
id);
1354 eid = min(eid, ent.
id);
1358 for (
int j = 0; j < quad; ++j)
1369 it->second[0].orient, quad);
1375 it->second[0].orient,
1376 trace->GetExp(i)->GetNumPoints(0),
1377 trace->GetExp(i)->GetNumPoints(1));
1383 Array<OneD, long> tmp2(nTracePhys);
1384 for (
int i = 0; i < nTracePhys; ++i)
1390 for (
int i = 0; i < nTracePhys; ++i)
1392 m_traceToUniversalMapUnique[i] = tmp2[i];
1397 Array<OneD, int> &toAlign,
1404 ASSERTL1(nquad2 == 0,
"nquad2 != 0 for reorienation");
1405 for (
int i = 0; i < nquad1/2; ++i)
1407 swap(toAlign[i], toAlign[nquad1-1-i]);
1412 ASSERTL1(nquad2 != 0,
"nquad2 == 0 for reorienation");
1414 Array<OneD, int> tmp(nquad1*nquad2);
1422 for (
int i = 0; i < nquad2; ++i)
1424 for (
int j = 0; j < nquad1; ++j)
1426 tmp[i*nquad1 + j] = toAlign[j*nquad2 + i];
1432 for (
int i = 0; i < nquad2; ++i)
1434 for (
int j = 0; j < nquad1; ++j)
1436 tmp[i*nquad1 + j] = toAlign[i*nquad1 + j];
1447 for (
int i = 0; i < nquad2; ++i)
1449 for (
int j = 0; j < nquad1/2; ++j)
1451 swap(tmp[i*nquad1 + j],
1452 tmp[i*nquad1 + nquad1-j-1]);
1463 for (
int j = 0; j < nquad1; ++j)
1465 for (
int i = 0; i < nquad2/2; ++i)
1467 swap(tmp[i*nquad1 + j],
1468 tmp[(nquad2-i-1)*nquad1 + j]);
1477 Array<OneD, NekDouble> &pGlobal)
const
1519 const Array<OneD, const NekDouble>& loc,
1520 Array<OneD, NekDouble>& global)
const
1533 const Array<OneD, const NekDouble>& global,
1534 Array<OneD, NekDouble>& loc)
const
1547 const Array<OneD, const NekDouble> &loc,
1548 Array<OneD, NekDouble> &global)
const
1561 Array<OneD, NekDouble>& pGlobal)
const
1592 Array<OneD, StdRegions::StdExpansionSharedPtr>&
1596 "i is out of range");
1600 Array<OneD, Array< OneD, StdRegions::StdExpansionSharedPtr> >&