Salome HOME
333bbb42d0c8676a9ed449d2f7b7b2d8c7025a8e
[tools/medcoupling.git] / src / MEDPartitioner / MEDPARTITIONER_MetisGraph.cxx
1 // Copyright (C) 2007-2020  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, or (at your option) any later version.
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 #include "MEDPARTITIONER_MetisGraph.hxx"
21 #include "MEDPARTITIONER_ParaDomainSelector.hxx"
22 #include "MEDPARTITIONER_Utils.hxx"
23
24 #include "MEDCouplingSkyLineArray.hxx"
25 #include "InterpKernelException.hxx"
26
27 #include <iostream>
28
29 extern "C"
30 {
31 #include "MEDPARTITIONER_metis.h"
32 }
33
34 using namespace MEDPARTITIONER;
35
36 METISGraph::METISGraph():Graph()
37 {
38 }
39
40 METISGraph::METISGraph(MEDCoupling::MEDCouplingSkyLineArray* graph, int* edgeweight)
41   :Graph(graph,edgeweight)
42 {
43 }
44
45 METISGraph::~METISGraph()
46 {
47 }
48
49 void METISGraph::partGraph(int ndomain,
50                            const std::string& options_string,
51                            ParaDomainSelector *parallelizer)
52 {
53   using std::vector;
54   if (MyGlobals::_Verbose>10)
55     std::cout << "proc " << MyGlobals::_Rank << " : METISGraph::partGraph" << std::endl;
56   
57   //number of graph vertices
58   int n=FromIdType<int>(_graph->getNumberOf());
59   //graph
60 #ifdef MEDCOUPLING_USE_64BIT_IDS
61   std::vector<int> indexVec( _graph->getIndex(), _graph->getIndexArray()->end() );
62   std::vector<int> valueVec( _graph->getValues(), _graph->getValuesArray()->end() );
63   int * xadj=indexVec.data();
64   int * adjncy=valueVec.data();
65 #else
66   int * xadj=const_cast<int*>(_graph->getIndex());
67   int * adjncy=const_cast<int*>(_graph->getValues());
68 #endif
69   //constraints
70   int * vwgt=_cell_weight;
71   int * adjwgt=_edge_weight;
72   int wgtflag=(_edge_weight!=0)?1:0+(_cell_weight!=0)?2:0;
73   //base 0 or 1
74   int base=0;
75   //ndomain
76   int nparts=ndomain;
77   //options
78   /*
79     (0=default_option,option,random_seed) see defs.h
80     #define PMV3_OPTION_DBGLVL 1
81     #define PMV3_OPTION_SEED 2
82     #define PMV3_OPTION_IPART 3
83     #define PMV3_OPTION_PSR 3
84     seems no changes int options[4]={1,0,33,0}; //test for a random seed of 33
85   */
86   int options[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
87 #if !defined(MED_ENABLE_METIS)
88   throw INTERP_KERNEL::Exception("METISGraph::partGraph : METIS is not available. Check your products, please.");
89 #else
90   //output parameters
91   int edgecut;
92   int* partition=new int[n];
93
94   if(nparts >1)
95     {
96       if (MyGlobals::_Verbose>10) 
97         std::cout << "METISGraph::partGraph METIS_PartGraph METIS_PartGraph(RecursiveOrKway)" << std::endl;
98       if (options_string != "k")
99         MEDPARTITIONER_METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
100                                                 &base, &nparts, options, &edgecut, partition);
101       else
102         MEDPARTITIONER_METIS_PartGraphKway(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
103                                            &base, &nparts, options, &edgecut, partition);
104     }
105   else  //force this case because METIS send all 1 in value
106     {
107       for (int i=0; i<n; i++)
108         partition[i]=0;
109     }
110   vector<mcIdType> index(n+1);
111   vector<mcIdType> value(n);
112   index[0]=0;
113   for (int i=0; i<n; i++)
114     {
115       index[i+1]=index[i]+1;
116       value[i]=ToIdType(partition[i]);
117     }
118   delete [] partition;
119
120   //creating a skylinearray with no copy of the index and partition array
121   //the fifth argument true specifies that only the pointers are passed 
122   //to the object
123   _partition = MEDCoupling::MEDCouplingSkyLineArray::New(index,value);
124 #endif
125 }
126