Salome HOME
Copyright update 2021
[tools/medcoupling.git] / src / MEDPartitioner / MEDPARTITIONER_ScotchGraph.cxx
1 // Copyright (C) 2007-2021  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_Graph.hxx"
21 #include "MEDPARTITIONER_ScotchGraph.hxx"
22 #include "MEDPARTITIONER_Utils.hxx"
23
24 #include "MEDCouplingSkyLineArray.hxx"
25
26 #include <cstdio>
27
28 #ifdef MED_ENABLE_SCOTCH
29 extern "C"
30 {
31 #define restrict
32 #include "scotch.h"
33 }
34 #endif
35
36 using namespace MEDPARTITIONER;
37   
38 SCOTCHGraph::SCOTCHGraph():Graph()
39 {
40 }
41
42 SCOTCHGraph::SCOTCHGraph(MEDCoupling::MEDCouplingSkyLineArray* graph, int* edgeweight):Graph(graph,edgeweight)
43 {
44 }
45
46 SCOTCHGraph::~SCOTCHGraph()
47 {
48 }
49
50 void SCOTCHGraph::partGraph(int ndomain, const std::string& options_string, ParaDomainSelector* sel)
51 {
52   if (MyGlobals::_Verbose>10)
53     std::cout << "proc " << MyGlobals::_Rank << " : SCOTCHGraph::partGraph" << std::endl;
54   
55   //number of graph vertices
56   int n = FromIdType<int>(_graph->getNumberOf());
57   //graph
58 #ifdef MEDCOUPLING_USE_64BIT_IDS
59   std::vector<int> indexVec( _graph->getIndex(), _graph->getIndexArray()->end() );
60   std::vector<int> valueVec( _graph->getValues(), _graph->getValuesArray()->end() );
61   int * xadj=indexVec.data();
62   int * adjncy=valueVec.data();
63 #else
64   int * xadj=const_cast<int*>(_graph->getIndex());
65   int * adjncy=const_cast<int*>(_graph->getValues());
66 #endif
67   //ndomain
68   int nparts=ndomain;
69
70 #if !defined(MED_ENABLE_SCOTCH)
71   throw INTERP_KERNEL::Exception("SCOTCHGraph::partGraph : SCOTCH is not available. Check your products, please.");
72 #else
73   //output parameters
74   int* partition = new int[n+1];
75   
76   SCOTCH_Graph scotch_graph;
77   SCOTCH_graphInit(&scotch_graph);
78   SCOTCH_graphBuild(&scotch_graph,
79                     0, //base first indice 0
80                     n, //nb of graph nodes
81                     xadj,
82                     0,
83                     _cell_weight, //graph vertices loads
84                     0,
85                     xadj[n], //number of edges
86                     adjncy,
87                     _edge_weight);
88   SCOTCH_Strat scotch_strategy;
89   SCOTCH_stratInit(&scotch_strategy);
90   
91   //!user-defined options for the strategy
92   if (options_string!="")
93     SCOTCH_stratGraphMap(&scotch_strategy,options_string.c_str());
94
95   if (nparts>1)
96     {
97       if (MyGlobals::_Verbose>10) std::cout << "SCOTCHGraph::graphPart SCOTCH_graphPart" << std::endl;
98       SCOTCH_graphPart(&scotch_graph,nparts,&scotch_strategy,partition);
99     }
100   else  //partition for 1 subdomain
101     {
102     for (int i=0; i<n+1; i++)
103       partition[i]=0;
104     }
105   
106   SCOTCH_stratExit(&scotch_strategy);
107   SCOTCH_graphExit(&scotch_graph);
108
109   std::vector<mcIdType> index(n+1);
110   std::vector<mcIdType> value(n);
111   index[0]=0;
112   for (int i=0; i<n; i++)
113     {
114       index[i+1]=index[i]+1;
115       value[i]=ToIdType(partition[i]);
116     }
117   delete [] partition;
118   
119   //creating a skylinearray with no copy of the index and partition array
120   //the fifth argument true specifies that only the pointers are passed 
121   //to the object
122   _partition = MEDCoupling::MEDCouplingSkyLineArray::New(index,value);
123 #endif
124 }