NeoPZ
pzmetis.cpp
Go to the documentation of this file.
1 
6 #include "pzmetis.h"
7 
8 #ifdef USING_METIS
9 #include <math.h>
10 extern "C" {
11 #include "metis.h"
12 };
13 #endif
14 
15 #include "pzlog.h"
16 
17 #ifdef LOG4CXX
18 static LoggerPtr logger(Logger::getLogger("pz.metis"));
19 #endif
20 
21 #include <iostream>
22 using namespace std;
23 
25 {
26 }
27 
28 void TPZMetis::Print(std::ostream &out,char * title) {
29  int nel = fElementGraphIndex.NElements()-1;
30  int el;
31  out << title;
32  out << "\nTPZMetis::Print fNElements = " << fNElements << " fNNodes = " << fNNodes << endl;
33  for (el=0;el<nel;el++) {
34  int firstindex = fElementGraphIndex[el];
35  int lastindex = fElementGraphIndex[el+1];
36  int index;
37  out << "Element number " << el << " : ";
38  for (index=firstindex;index<lastindex;index++) {
39  out << fElementGraph[index] << " ";
40  }
41  out << endl;
42  }
43  TPZManVector<int64_t> nodegraph(0),nodegraphindex(0);
44  ConvertGraph(fElementGraph,fElementGraphIndex,nodegraph,nodegraphindex);
45  int numelnodegraph = nodegraphindex[fNNodes];
46  if (numelnodegraph == nodegraph.NElements() ) {
47  nodegraph.Resize(numelnodegraph+1);
48  }
49  int nod;
50  for (nod = numelnodegraph; nod>0; nod--) nodegraph[nod] = nodegraph[nod-1];
51  for (el=0;el<fNNodes;el++) {
52  int firstindex = nodegraphindex[el];
53  int lastindex = nodegraphindex[el+1];
54  int index;
55  out << "Node number " << el << " : ";
56  for (index=firstindex;index<lastindex;index++) {
57  out << nodegraph[index+1] << " ";
58  }
59  out << endl;
60  }
61 }
62 
63 void TPZMetis::Print(std::ostream &out) {
64 
65  // int nel = fElementGraphIndex.NElements()-1;
66  int el;
67  out << fNNodes << std::endl;
68  /* for(el=0;el<nel;el++) {
69  int firstindex = fElementGraphIndex[el];
70  int lastindex = fElementGraphIndex[el+1];
71  int index;
72  for(index=firstindex;index<lastindex;index++) {
73  if(fElementGraph[index] == index) continue;//o atual n�o deve aparecer
74  out << (fElementGraph[index]+1) << " ";
75  }
76  out << endl;
77  } */
78  TPZManVector<int64_t> nodegraph(0),nodegraphindex(0);
79  ConvertGraph(fElementGraph,fElementGraphIndex,nodegraph,nodegraphindex);
80  int numelnodegraph = nodegraphindex[fNNodes];
81  if (numelnodegraph == nodegraph.NElements() ) {
82  nodegraph.Resize(numelnodegraph+1);
83  }
84  int nod;
85  for (nod = numelnodegraph; nod>0; nod--) nodegraph[nod] = nodegraph[nod-1];
86  for (el=0;el<fNNodes;el++) {
87  int firstindex = nodegraphindex[el];
88  int lastindex = nodegraphindex[el+1];//come�o do pr�ximo
89  int index;
90  for (index=firstindex;index<lastindex;index++) {
91  out << (nodegraph[index+1]+1) << " ";
92  }
93  out << endl;
94  }
95 }
96 
98  TPZManVector<int64_t> nodegraph(0),nodegraphindex(0);
99  ConvertGraph(fElementGraph,fElementGraphIndex,nodegraph,nodegraphindex);
100  int64_t numelnodegraph = nodegraphindex[fNNodes];
101  if (numelnodegraph == nodegraph.NElements() )
102  {
103  nodegraph.Resize(numelnodegraph+1);
104  }
105  int64_t nod;
106  for (nod = numelnodegraph; nod>0; nod--) nodegraph[nod] = nodegraph[nod-1];
107  perm.Resize(fNNodes);
108  inverseperm.Resize(fNNodes);
109  for(nod=0;nod<fNNodes;nod++)
110  {
111  perm[nod] = inverseperm[nod] = nod;
112  }
113 
114 #ifdef USING_METIS
115  TPZVec<int> nodegraphInt(0),nodegraphindexInt(0);
116  int NNodes = (int) fNNodes;
117  int64_t n, sz = nodegraph.NElements();
118  nodegraph.Resize(sz);
119  for(n=0;n<sz;n++)
120  nodegraphInt[n] = (int)nodegraph[n];
121  sz = nodegraphindex.NElements();
122  for(n=0;n<sz;n++)
123  nodegraphindexInt[n] = (int)nodegraphindex[n];
124 
125  // Using external library METIS 5
126  int numflag = 0;
127  int options = 0;
128  int nperms = perm.NElements();
129  int ninvers = inverseperm.NElements();
130  int *permint = new int[nperms];
131  int *inversepermint = new int[ninvers];
132  if(!permint || !inverseperm.size()) {
133  std::cout << "TPZMetis::Resequence memory is not enough.\n";
134  return;
135  }
136  int64_t i;
137  for(i=0L;i<nperms;i++)
138  permint[i] = (int)perm[i];
139  for(i=0L;i<nperms;i++)
140  inversepermint[i] = (int)inverseperm[i];
141 
142 // METIS_NodeND(&fNNodes,&nodegraphindex[0],&nodegraph[1],&numflag,&options,&perm[0],&inverseperm[0]);
143  METIS_NodeND(&NNodes,&nodegraphindexInt[0],&nodegraphInt[1],&numflag,&options,permint,inversepermint);
144  fNNodes = (int64_t)NNodes;
145 #endif
146 }
147 
148 void TPZMetis::Subdivide(int nParts, TPZVec < int > & Domains)
149 {
150  TPZManVector<int64_t> Adjacency,AdjacencyIndex;
151  TPZManVector<int> AdjacencyWeight;
152  ConvertToElementoToElementGraph(fElementGraph,fElementGraphIndex,Adjacency,AdjacencyWeight,AdjacencyIndex);
153 
154 #ifdef LOG4CXX
155  {
156  std::stringstream sout;
157  TPZRenumbering::Print(Adjacency,AdjacencyIndex,"Element to element graph",sout);
158  if (logger->isDebugEnabled())
159  {
160  LOGPZ_DEBUG(logger, sout.str())
161  }
162  }
163 #endif
164 
165 #ifdef USING_METIS
166  TPZManVector<int> AdjacencyInt,AdjacencyIndexInt;
167  int64_t n, nVertices = AdjacencyIndex.NElements();
168  AdjacencyIndexInt.Resize(nVertices,0);
169  for(n=0;n<nVertices;n++)
170  AdjacencyIndexInt[n] = (int)AdjacencyIndex[n];
171  int64_t nEdges = Adjacency.NElements();
172  AdjacencyInt.Resize(nEdges,0);
173  for(n=0;n<nEdges;n++)
174  AdjacencyInt[n] = (int)Adjacency[n];
175  int nvertices = (int)nVertices-1;
176 // int nedges = (int)nEdges;
177  Domains.Resize(nvertices,0);
178  // Upon successful completion, nEdgesCutted stores the edge-cut or the total communication volume of the partitioning solution.
179  int nEdgesCutted = 0;
180 
181  TPZVec<int> Options(METIS_NOPTIONS);
182  METIS_SetDefaultOptions(&Options[0]);
183 
184  int ncon = 2;
185  if(METIS_PartGraphRecursive(&nvertices, &ncon, &AdjacencyIndexInt[0], &AdjacencyInt[0], NULL, NULL, NULL, // &AdjacencyWeight[0],
186  &nParts, NULL, NULL, &Options[0], &nEdgesCutted, &Domains[0]) != METIS_OK)
187  DebugStop();
188 #else
189  DebugStop();
190 #endif
191 
192 }
193 
194 
Contains definitions to LOGPZ_DEBUG, LOGPZ_INFO, LOGPZ_WARN, LOGPZ_ERROR and LOGPZ_FATAL, and the implementation of the inline InitializePZLOG(string) function using log4cxx library or not. It must to be called out of "#ifdef LOG4CXX" scope.
void ConvertGraph(TPZVec< int64_t > &elgraph, TPZVec< int64_t > &elgraphindex, TPZManVector< int64_t > &nodegraph, TPZManVector< int64_t > &nodegraphindex)
Will convert an element graph defined by elgraph and elgraphindex into a node graph defined by nodegr...
void Print(std::ostream &out)
Prints the current object data structure.
Definition: pzmetis.cpp:63
TPZMetis()
Definition: pzmetis.cpp:24
void Subdivide(int nParts, TPZVec< int > &Domains)
Subdivides a Graph in nParts.
Definition: pzmetis.cpp:148
virtual void Resequence(TPZVec< int64_t > &perm, TPZVec< int64_t > &inverseperm)
Perform the renumbering of elements. The aim of this operation is to minimize the band of the resulti...
Definition: pzmetis.cpp:97
virtual void Resize(const int64_t newsize, const T &object)
Resizes the vector object.
Definition: pzmanvector.h:426
int64_t size() const
Returns the number of elements of the vector.
Definition: pzvec.h:196
TPZVec< int64_t > fElementGraphIndex
Indicates for each element the index of the first entry with fElementGraph for that element The size ...
virtual void Resize(const int64_t newsize, const T &object)
Resizes the vector object reallocating the necessary storage, copying the existing objects to the new...
Definition: pzvec.h:373
This abstract class which defines the behavior which derived classes need to implement for implement...
#define DebugStop()
Returns a message to user put a breakpoint in.
Definition: pzerror.h:20
#define LOGPZ_DEBUG(A, B)
Define log for debug info.
Definition: pzlog.h:87
int64_t fNElements
Number of elements in the graph.
void ConvertToElementoToElementGraph(TPZVec< int64_t > &elgraph, TPZVec< int64_t > &elgraphindex, TPZVec< int64_t > &eltotelgraph, TPZVec< int > &eltoelweight, TPZVec< int64_t > &eltoelgraphindex)
Convert a traditional elgraph to an element to element graph.
void Print(TPZVec< int64_t > &grapho, TPZVec< int64_t > &graphoindex, const char *name=0, std::ostream &out=std::cout)
Prints graph.
int64_t fNNodes
Number of nodes in the graph.
TPZVec< int64_t > fElementGraph
Node number of each element.
int64_t NElements() const
Returns the number of elements of the vector.
Definition: pzvec.h:190
Contains TPZMetis class which implements the renumbering for elements of a mesh to minimize the band...