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>
55 namespace MultiRegions
65 m_dofId = Array<OneD, int> (nvals);
67 m_sign = Array<OneD, NekDouble> (nvals);
79 const unsigned int bndPatch,
89 const Array<OneD, const int> sepTree) :
91 m_leftDaughterGraph (),
92 m_rightDaughterGraph()
94 static int offset = -5;
97 int recurLevel = sepTree[offset+0];
98 int nLeftIntDofs = sepTree[offset+2];
99 int nRightIntDofs = sepTree[offset+3];
100 int nBndDofs = sepTree[offset+4];
102 bool daughtersConstructed[2] = {
false,
false};
104 if ((offset + 5) < sepTree.num_elements())
106 while (sepTree[offset+5] > recurLevel)
108 switch (sepTree[offset+6])
115 daughtersConstructed[0] =
true;
123 daughtersConstructed[1] =
true;
131 if ((offset + 5) >= sepTree.num_elements())
140 if (!daughtersConstructed[0] && nLeftIntDofs)
146 if (!daughtersConstructed[1] && nRightIntDofs)
160 const int nPartition)
168 m_leftDaughterGraph(),
169 m_rightDaughterGraph()
179 static int nBndDofs = 0;
180 static int level = 0;
195 returnval = nBndDofs;
208 static int level = 0;
209 static int offset = 0;
233 static int level = 0;
235 cout <<
"LEVEL " << level <<
" " <<
m_BndDofs->GetNverts() << endl;
250 std::vector<SubGraphSharedPtr>& leaves)
const
269 leaves.push_back(leave);
293 static int level = 0;
294 static int nLeaves = 0;
347 static int level = 0;
348 static int nLeaves = 0;
398 const int nVerts) : m_IntBlocks(), m_daughterGraph()
405 for (
int i = 0 ; i < nVerts; i++)
413 const Array<OneD, const int> septree,
414 const int nPartition) :
432 topDownGraph->SetGlobalNumberingOffset();
434 topDownGraph->CutEmptyLeaves();
443 int ncuts = topDownGraph->CutLeaves();
459 graph->CutEmptyLeaves();
461 ncuts = graph->CutLeaves();
476 static int nIntDofs = 0;
477 static int level = 0;
492 returnval = nIntDofs;
505 static int level = 0;
508 cout <<
"LEVEL " << level << endl;
509 cout <<
"interior blocks" << endl;
528 Array<OneD, int> &perm,
529 Array<OneD, int> &iperm)
const
537 Array<OneD, int> iperm1(nDofs);
544 for (
int i=0; i < nDofs; i++)
546 iperm[i] = iperm1[iperm[i]];
552 Array<OneD, int>& iperm)
const
554 static int offset = 0;
555 static int level = 0;
567 for(
int j = 0; j <
m_IntBlocks[i]->GetNverts(); j++)
569 iperm[GlobIdOffset+j] = offset;
582 const Array<OneD, const int>& wgts)
584 static int offset = 0;
585 static int level = 0;
595 int OrigGlobIdOffset =
m_IntBlocks[i]->GetIdOffset();
600 for(
int j = 0; j <
m_IntBlocks[i]->GetNverts(); j++)
602 newNverts += wgts[OrigGlobIdOffset+j];
603 offset += wgts[OrigGlobIdOffset+j];
631 const int leveltomask,
632 Array<OneD, NekDouble> &maskarray)
const
634 static int level = 0;
637 if(level < leveltomask)
641 else if(level == leveltomask)
649 for(
int j = 0; j < nVerts; j++)
651 maskarray[GlobIdOffset+j] = (
NekDouble) i;
658 "If statement should not arrive here");
665 const int whichlevel)
const
668 static int level = 0;
671 if(level < whichlevel)
676 else if(level == whichlevel)
683 "If statement should not arrive here");
692 const int whichlevel,
693 Array<OneD, unsigned int> &outarray)
const
695 static int level = 0;
698 if(level < whichlevel)
702 else if(level == whichlevel)
705 "Array dimension not sufficient");
709 outarray[i] = (
unsigned int)
m_IntBlocks[i]->GetNverts();
715 "If statement should not arrive here");
722 const int whichlevel,
const int patch)
const
725 static int level = 0;
728 if(level < whichlevel)
732 else if(level == whichlevel)
739 "If statement should not arrive here");
750 std::vector<SubGraphSharedPtr> returnval;
751 static int level = 0;
754 if(level < whichlevel)
758 else if(level == whichlevel)
765 "If statement should not arrive here");
773 const int whichlevel)
const
776 static int level = 0;
779 if(level < whichlevel)
783 else if(level == whichlevel)
791 "If statement should not arrive here");
802 static int level = 0;
809 returnval = max(returnval,level);
819 return g->GetNverts() == 0;
829 typedef boost::adjacency_list<
830 boost::setS, boost::vecS, boost::undirectedS> BoostGraph;
831 typedef boost::graph_traits<BoostGraph>::vertex_descriptor
833 typedef boost::graph_traits<BoostGraph>::vertex_iterator
835 typedef boost::graph_traits<BoostGraph>::adjacency_iterator
836 BoostAdjacencyIterator;
840 Array<OneD, int>& perm,
841 Array<OneD, int>& iperm)
843 int nGraphVerts = boost::num_vertices(graph);
845 ASSERTL1(perm. num_elements() >= nGraphVerts &&
846 iperm.num_elements() >= nGraphVerts,
847 "Non-matching dimensions");
851 std::vector<BoostVertex> reorderedVerts(nGraphVerts);
852 boost::cuthill_mckee_ordering(graph, reorderedVerts.rbegin());
855 for(
int i = 0; i < nGraphVerts; i++)
857 perm[i] = reorderedVerts[i];
858 iperm[ reorderedVerts[i] ] = i;
863 const BoostGraph &graph,
864 Array<OneD, int> &perm,
865 Array<OneD, int> &iperm,
867 std::set<int> partVerts,
870 int nGraphVerts = boost::num_vertices(graph);
871 int nGraphEdges = boost::num_edges (graph);
873 ASSERTL1(perm. num_elements() >= nGraphVerts &&
874 iperm.num_elements() >= nGraphVerts,
875 "Non-matching dimensions");
912 int nPartition = partVerts.size();
913 int nNonPartition = nGraphVerts - partVerts.size();
914 BoostVertexIterator vertit, vertit_end;
915 BoostAdjacencyIterator adjvertit, adjvertit_end;
916 Array<OneD, int> xadj(nNonPartition+1,0);
917 Array<OneD, int> adjncy(2*nGraphEdges);
918 Array<OneD, int> initial_perm(nGraphVerts);
919 Array<OneD, int> iinitial_perm(nGraphVerts);
920 Array<OneD, int> perm_tmp (nNonPartition);
921 Array<OneD, int> iperm_tmp(nNonPartition);
927 for (i = cnt = 0; i < nGraphVerts; ++i)
929 if (partVerts.count(i) == 0)
931 initial_perm [i] = cnt;
932 iinitial_perm[cnt++] = i;
936 for (i = 0; i < nGraphVerts; ++i)
938 if (partVerts.count(i) > 0)
940 initial_perm [i] = cnt;
941 iinitial_perm[cnt++] = i;
946 boost::property_map<BoostGraph, boost::vertex_index_t>::type
947 index =
get(boost::vertex_index, graph);
949 for (boost::tie(vertit, vertit_end) = boost::vertices(graph);
950 vertit != vertit_end; ++vertit)
952 if (partVerts.count(index[*vertit]) > 0)
957 for (boost::tie(adjvertit, adjvertit_end) =
958 boost::adjacent_vertices(*vertit,graph);
959 adjvertit != adjvertit_end;
962 if (partVerts.count(index[*adjvertit]) > 0)
966 adjncy[acnt++] = initial_perm[*adjvertit];
975 int sizeSeparatorTree = nGraphVerts*10;
976 Array<OneD,int> septreeTmp(sizeSeparatorTree,-1);
995 nNonPartition,xadj,adjncy,perm_tmp,iperm_tmp,
996 septreeTmp, mdswitch);
1001 "Error in calling metis (the size of the separator"
1002 " tree might not be sufficient)");
1006 for (i = 0; i < nGraphVerts; ++i)
1008 if (partVerts.count(i) == 0)
1010 iperm[i] = iperm_tmp[initial_perm[i]];
1015 for (i = nNonPartition, it = partVerts.begin();
1016 it != partVerts.end(); ++it, ++i)
1022 for (i = 0; i < nGraphVerts; ++i)
1025 "Perm error " + boost::lexical_cast<std::string>(i));
1029 int trueSizeSepTree = 0;
1030 for (i = 0; septreeTmp[i] != -1; i++)
1034 Array<OneD,int> septree(trueSizeSepTree);
1058 substructgraph->UpdateBottomUpReordering(perm,iperm);
1064 for(
int i = 0; i < nGraphVerts; i++)
1075 Array<OneD, int>& perm,
1076 Array<OneD, int>& iperm)
1078 int nGraphVerts = boost::num_vertices(graph);
1080 ASSERTL1(perm. num_elements() >= nGraphVerts &&
1081 iperm.num_elements() >= nGraphVerts,
1082 "Non-matching dimensions");
1084 for (
int i = 0; i < nGraphVerts; i++)