Salome HOME
MEDMEM suppression
[modules/med.git] / src / MEDSPLITTER / MEDSPLITTER_METISGraph.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #ifdef MED_ENABLE_PARMETIS
21 #include <parmetis.h>
22 #endif
23 #ifdef MED_ENABLE_METIS
24 extern "C" {
25 #include <metis.h>
26 }
27 #endif
28
29 #include "MEDSPLITTER_METISGraph.hxx"
30 #include "MEDSPLITTER_ParaDomainSelector.hxx"
31
32 using namespace MEDSPLITTER;
33
34 METISGraph::METISGraph():Graph()
35 {
36 }
37
38 METISGraph::METISGraph(MEDMEM::MEDSKYLINEARRAY* graph, int* edgeweight)
39   :Graph(graph,edgeweight)
40 {
41 }
42
43 METISGraph::~METISGraph()
44 {
45 }
46
47 void METISGraph::partGraph(int                 ndomain,
48                            const string&       options_string,
49                            ParaDomainSelector* parallelizer)
50 {
51   // number of graph vertices
52   int n = m_graph->getNumberOf();
53
54   //graph
55   int * xadj=const_cast<int*>(m_graph->getIndex());
56   int * adjncy = const_cast<int*>(m_graph->getValue());
57   //constraints
58   int * vwgt=m_cellweight;
59   int * adjwgt=m_edgeweight;
60   int wgtflag=(m_edgeweight!=0)?1:0+(m_cellweight!=0)?2:0;
61
62   //base 0 or 1
63   int base=1;
64
65   //ndomain
66   int nparts = ndomain;
67
68   //options
69   int options[5]={0,0,0,0,0};
70
71   // output parameters
72   int edgecut;
73   int* partition = new int[n];
74
75   if (nparts >1)
76   {
77     if ( parallelizer )
78     {
79 #ifdef MED_ENABLE_PARMETIS
80       // distribution of vertices of the graph among the processors
81       int * vtxdist = parallelizer ? parallelizer->getNbVertOfProcs() : 0;
82       MPI_Comm comm = MPI_COMM_WORLD;
83
84       ParMETIS_PartKway( vtxdist, xadj, adjncy, vwgt, adjwgt, &wgtflag,
85                          &base, &nparts, options, &edgecut, partition, &comm );
86 #else
87       throw MED_EXCEPTION("ParMETIS is not available. Check your products, please.");
88 #endif
89     }
90     else
91     {
92 #ifdef MED_ENABLE_METIS
93       if (options_string != "k")
94         METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
95                                  &base, &nparts, options, &edgecut, partition);
96       else
97         METIS_PartGraphKway(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
98                             &base, &nparts, options, &edgecut, partition);
99 #else
100       throw MED_EXCEPTION("METIS is not available. Check your products, please.");
101 #endif
102     }
103   }
104   else
105   {
106     for (int i=0; i<n; i++)
107       partition[i]=1;
108   }
109
110   int* index=new int [n+1];
111   index[0]=1;
112   for (int i=0; i<n; i++)
113   {
114     index[i+1]=index[i]+1;
115     partition[i]--;
116   }
117
118   //creating a skylinearray with no copy of the index and partition array
119   // the fifth argument true specifies that only the pointers are passed 
120   //to the object
121   m_partition = new MEDMEM::MEDSKYLINEARRAY(n,n, index, partition, true);
122 }
123