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)
74 const Array<OneD, const MultiRegions::ExpListSharedPtr> &bndCondExp,
75 const Array<OneD, const SpatialDomains::BoundaryConditionShPtr> &bndCond,
77 const std::string variable):
80 int i, j, k, cnt, eid, id, id1, gid;
82 int nTraceExp = trace->GetExpSize();
83 int nbnd = bndCondExp.num_elements();
90 int nel = expList.size();
92 map<int, int> meshTraceId;
97 for(i = 0; i < nTraceExp; ++i)
99 meshTraceId[trace->GetExp(i)->GetGeom()->GetGlobalID()] = i;
104 for(i = 0; i < nel; ++i)
106 cnt += expList[i]->GetNtrace();
109 Array<OneD, LocalRegions::ExpansionSharedPtr> tracemap(cnt);
111 OneD, Array<OneD, LocalRegions::ExpansionSharedPtr> >(nel);
114 for(cnt = i = 0; i < nel; ++i)
118 for(j = 0; j < expList[i]->GetNtrace(); ++j)
120 id = expList[i]->GetGeom()->GetTid(j);
122 if(meshTraceId.count(
id) > 0)
125 trace->GetExp(meshTraceId.find(
id)->second);
129 ASSERTL0(
false,
"Failed to find trace map");
133 cnt += expList[i]->GetNtrace();
138 for(i = 0; i < nbnd; ++i)
140 cnt += bndCondExp[i]->GetExpSize();
149 for(i = 0; i < bndCondExp.num_elements(); ++i)
151 for(j = 0; j < bndCondExp[i]->GetExpSize(); ++j)
153 bndExp = bndCondExp[i]->GetExp(j);
154 traceGeom = bndExp->GetGeom();
155 id = traceGeom->GetGlobalID();
157 if(bndCond[i]->GetBoundaryConditionType() ==
178 for(i = 0; i < nel; ++i)
181 nbndry += expList[eid]->NumDGBndryCoeffs();
182 m_numLocalIntCoeffsPerPatch[i] = 0;
184 (
unsigned int) expList[eid]->NumDGBndryCoeffs();
194 Array<OneD,int> traceElmtGid(nTraceExp, -1);
200 typedef boost::adjacency_list<
201 boost::setS, boost::vecS, boost::undirectedS> BoostGraph;
203 BoostGraph boostGraphObj;
204 int trace_id, trace_id1;
209 for(i = 0; i < nTraceExp; ++i)
211 id = trace->GetExp(i)->GetGeom()->GetGlobalID();
213 if (dirTrace.count(
id) == 0)
217 boost::add_vertex(boostGraphObj);
218 traceElmtGid[i] = cnt++;
223 traceElmtGid[i] = dirOffset;
224 dirOffset += trace->GetExp(i)->GetNcoeffs();
230 for(i = 0; i < nel; ++i)
234 for(j = 0; j < expList[eid]->GetNtrace(); ++j)
238 id = traceGeom->GetGlobalID();
239 trace_id = meshTraceId.find(
id)->second;
241 if(dirTrace.count(
id) == 0)
243 for(k = j+1; k < expList[eid]->GetNtrace(); ++k)
246 id1 = traceGeom->GetGlobalID();
247 trace_id1 = meshTraceId.find(id1)->second;
249 if(dirTrace.count(id1) == 0)
251 boost::add_edge((
size_t)traceElmtGid[trace_id],
252 (
size_t)traceElmtGid[trace_id1],
260 int nGraphVerts = nTraceExp - nDir;
261 Array<OneD, int> perm (nGraphVerts);
262 Array<OneD, int> iperm(nGraphVerts);
263 Array<OneD, int> vwgts(nGraphVerts);
266 for(i = 0; i < nGraphVerts; ++i)
268 vwgts[i] = trace->GetExp(i+nDir)->GetNcoeffs();
302 ASSERTL0(
false,
"Unrecognised solution type");
310 for(i = 0; i < nTraceExp - nDir; ++i)
312 traceElmtGid[perm[i]+nDir] = cnt;
313 cnt += trace->GetExp(perm[i]+nDir)->GetNcoeffs();
319 for(i = 0; i < nel; ++i)
325 for(j = 0; j < exp->GetNtrace(); ++j)
328 id = traceGeom->GetGlobalID();
329 gid = traceElmtGid[meshTraceId.find(
id)->second];
331 const int nDim = expList[eid]->GetNumBases();
340 order_e = expList[eid]->GetEdgeNcoeffs(j);
344 for(k = 0; k < order_e; ++k)
358 for (k = 2; k < order_e; ++k)
364 for(k = 3; k < order_e; k+=2)
366 m_localToGlobalBndSign[cnt+k] = -1.0;
373 for(k = 0; k < order_e; ++k)
382 for(k = 0; k < order_e; ++k)
390 ASSERTL0(
false,
"Boundary type not permitted");
397 order_e = expList[eid]->GetFaceNcoeffs(j);
399 std::map<int, int> orientMap;
401 Array<OneD, unsigned int> elmMap1 (order_e);
402 Array<OneD, int> elmSign1(order_e);
403 Array<OneD, unsigned int> elmMap2 (order_e);
404 Array<OneD, int> elmSign2(order_e);
410 expList[eid]->GetFaceToElementMap(j,fo,elmMap1,elmSign1);
411 expList[eid]->GetFaceToElementMap(
414 for (k = 0; k < elmMap1.num_elements(); ++k)
419 for (
int l = 0; l < elmMap2.num_elements(); ++l)
421 if (elmMap1[k] == elmMap2[l])
428 ASSERTL2(idx != -1,
"Problem with face to element map!");
432 for(k = 0; k < order_e; ++k)
435 m_localToGlobalBndSign[k+cnt] = elmSign2[orientMap[k]];
445 for(i = 0; i < nbnd; ++i)
447 cnt += bndCondExp[i]->GetNcoeffs();
453 int nbndexp = 0, bndOffset, bndTotal = 0;
454 for(cnt = i = 0; i < nbnd; ++i)
456 for(j = 0; j < bndCondExp[i]->GetExpSize(); ++j)
458 bndExp = bndCondExp[i]->GetExp(j);
459 id = bndExp->GetGeom()->GetGlobalID();
460 gid = traceElmtGid[meshTraceId.find(
id)->second];
461 bndOffset = bndCondExp[i]->GetCoeff_Offset(j) + bndTotal;
466 for(k = 0; k < bndExp->GetNcoeffs(); ++k)
472 nbndexp += bndCondExp[i]->GetExpSize();
473 bndTotal += bndCondExp[i]->GetNcoeffs();
489 Array<OneD, int> vwgts_perm(nGraphVerts);
491 for(
int i = 0; i < nGraphVerts; i++)
493 vwgts_perm[i] = vwgts[perm[i]];
496 bottomUpGraph->ExpandGraphWithVertexWeights(vwgts_perm);
504 for(i = 0; i < bndCondExp.num_elements(); ++i)
506 for(j = 0; j < bndCondExp[i]->GetExpSize(); ++j)
508 bndExp = bndCondExp[i]->GetExp(j);
509 traceGeom = bndExp->GetGeom();
510 id = traceGeom->GetGlobalID();
512 meshTraceId.find(
id)->second;
554 for(i = 0; i < locExpVector.size(); ++i)
556 locExpansion = locExpVector[i];
557 nDim = locExpansion->GetShapeDimension();
562 maxDof = (1 > maxDof ? 1 : maxDof);
566 for (j = 0; j < locExpansion->GetNedges(); ++j)
568 dof = locExpansion->GetEdgeNcoeffs(j);
569 maxDof = (dof > maxDof ? dof : maxDof);
574 for (j = 0; j < locExpansion->GetNfaces(); ++j)
576 dof = locExpansion->GetFaceNcoeffs(j);
577 maxDof = (dof > maxDof ? dof : maxDof);
585 for(i = 0; i < locExpVector.size(); ++i)
587 locExpansion = locExpVector[i];
588 nDim = locExpansion->GetShapeDimension();
597 int nverts = locExpansion->GetNverts();
598 for(j = 0; j < nverts; ++j)
602 id = locPointExp->
GetGeom()->GetGlobalID();
605 =
id * maxDof + j + 1;
611 for(j = 0; j < locExpansion->GetNedges(); ++j)
617 order_e = locExpVector[eid]->GetEdgeNcoeffs(j);
619 map<int,int> orientMap;
620 Array<OneD, unsigned int> map1(order_e), map2(order_e);
621 Array<OneD, int> sign1(order_e), sign2(order_e);
624 locExpVector[eid]->GetEdgeToElementMap(j, locExpVector[eid]->GetEorient(j), map2, sign2);
626 for (k = 0; k < map1.num_elements(); ++k)
631 for (
int l = 0; l < map2.num_elements(); ++l)
633 if (map1[k] == map2[l])
640 ASSERTL2(idx != -1,
"Problem with face to element map!");
644 for(k = 0; k < order_e; ++k)
648 =
id * maxDof + orientMap[k] + 1;
655 for(j = 0; j < locExpansion->GetNfaces(); ++j)
662 order_e = locExpVector[eid]->GetFaceNcoeffs(j);
664 map<int,int> orientMap;
665 Array<OneD, unsigned int> map1(order_e), map2(order_e);
666 Array<OneD, int> sign1(order_e), sign2(order_e);
669 locExpVector[eid]->GetFaceToElementMap(j, locExpVector[eid]->GetForient(j), map2, sign2);
671 for (k = 0; k < map1.num_elements(); ++k)
676 for (
int l = 0; l < map2.num_elements(); ++l)
678 if (map1[k] == map2[l])
685 ASSERTL2(idx != -1,
"Problem with face to element map!");
689 for(k = 0; k < order_e; ++k)
693 =
id * maxDof + orientMap[k] + 1;
710 m_globalToUniversalBndMapUnique[i] = (tmp[i] >= 0 ? 1 : 0);
719 Array<OneD, int> tmp;
722 int maxQuad = 0, quad = 0, nDim = 0, eid = 0, offset = 0;
726 int nTracePhys = trace->GetTotPoints();
730 Nektar::Array<OneD, int>(nTracePhys, -1);
732 Nektar::Array<OneD, int>(nTracePhys, -1);
736 nDim = locExpVector[0]->GetShapeDimension();
740 maxQuad = (1 > maxQuad ? 1 : maxQuad);
744 for (i = 0; i < trace->GetExpSize(); ++i)
746 quad = trace->GetExp(i)->GetTotPoints();
757 for (
int i = 0; i < trace->GetExpSize(); ++i)
759 eid = trace->GetExp(i)->GetGeom()->GetGlobalID();
760 offset = trace->GetPhys_Offset(i);
764 PeriodicMap::const_iterator it = perMap.find(eid);
765 if (perMap.count(eid) > 0)
770 eid = min(eid, ent.
id);
779 for (
int i = 0; i < trace->GetExpSize(); ++i)
781 eid = trace->GetExp(i)->GetGeom()->GetGlobalID();
782 offset = trace->GetPhys_Offset(i);
783 quad = trace->GetExp(i)->GetTotPoints();
789 PeriodicMap::const_iterator it = perMap.find(eid);
790 bool realign =
false;
791 if (perMap.count(eid) > 0)
796 realign = eid == min(eid, ent.
id);
797 eid = min(eid, ent.
id);
801 for (
int j = 0; j < quad; ++j)
812 it->second[0].orient, quad);
818 it->second[0].orient,
819 trace->GetExp(i)->GetNumPoints(0),
820 trace->GetExp(i)->GetNumPoints(1));
826 Array<OneD, long> tmp2(nTracePhys);
827 for (
int i = 0; i < nTracePhys; ++i)
833 for (
int i = 0; i < nTracePhys; ++i)
835 m_traceToUniversalMapUnique[i] = tmp2[i];
840 Array<OneD, int> &toAlign,
847 ASSERTL1(nquad2 == 0,
"nquad2 != 0 for reorienation");
848 for (
int i = 0; i < nquad1/2; ++i)
850 swap(toAlign[i], toAlign[nquad1-1-i]);
855 ASSERTL1(nquad2 != 0,
"nquad2 == 0 for reorienation");
857 Array<OneD, int> tmp(nquad1*nquad2);
865 for (
int i = 0; i < nquad2; ++i)
867 for (
int j = 0; j < nquad1; ++j)
869 tmp[i*nquad1 + j] = toAlign[j*nquad2 + i];
875 for (
int i = 0; i < nquad2; ++i)
877 for (
int j = 0; j < nquad1; ++j)
879 tmp[i*nquad1 + j] = toAlign[i*nquad1 + j];
890 for (
int i = 0; i < nquad2; ++i)
892 for (
int j = 0; j < nquad1/2; ++j)
894 swap(tmp[i*nquad1 + j],
895 tmp[i*nquad1 + nquad1-j-1]);
906 for (
int j = 0; j < nquad1; ++j)
908 for (
int i = 0; i < nquad2/2; ++i)
910 swap(tmp[i*nquad1 + j],
911 tmp[(nquad2-i-1)*nquad1 + j]);
920 Array<OneD, NekDouble> &pGlobal)
const
962 const Array<OneD, const NekDouble>& loc,
963 Array<OneD, NekDouble>& global)
const
976 const Array<OneD, const NekDouble>& global,
977 Array<OneD, NekDouble>& loc)
const
990 const Array<OneD, const NekDouble> &loc,
991 Array<OneD, NekDouble> &global)
const
1004 Array<OneD, NekDouble>& pGlobal)
const
1035 Array<OneD, LocalRegions::ExpansionSharedPtr>&
1039 "i is out of range");
1043 Array<OneD, Array< OneD, LocalRegions::ExpansionSharedPtr> >&