Salome HOME
9a23993945d4d800f9d35507933aad1651801ed3
[tools/medcoupling.git] / src / MEDPartitioner / MEDPARTITIONER_PTScotchGraph.cxx
1 // Copyright (C) 2017-2019  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_PTScotchGraph.hxx"
21 #include "MEDPARTITIONER_Utils.hxx"
22
23 #include "MEDCouplingSkyLineArray.hxx"
24 #include "MEDCouplingMemArray.hxx"
25 #include "MCType.hxx"
26
27 #include <cstdio>
28 #include <mpi.h>
29
30 #ifdef MED_ENABLE_PTSCOTCH
31 extern "C"
32 {
33 #define restrict
34 #include "ptscotch.h"
35 }
36 #endif
37
38 using namespace MEDPARTITIONER;
39
40
41 PTSCOTCHGraph::PTSCOTCHGraph(MEDCoupling::MEDCouplingSkyLineArray *graph, int *edgeweight, DataArrayInt *vlbloctab):Graph(graph,edgeweight),_vlbloctab(vlbloctab)
42 {
43 }
44
45 PTSCOTCHGraph::~PTSCOTCHGraph()
46 {
47 }
48
49 void PTSCOTCHGraph::partGraph(int ndomain, const std::string& options_string, ParaDomainSelector* sel)
50 {
51   if (MyGlobals::_Verbose>10)
52     std::cout << "proc " << MyGlobals::_Rank << " : PTSCOTCHGraph::partGraph" << std::endl;
53   
54   //number of graph vertices
55   int n = _graph->getNumberOf();
56   //graph
57   int * xadj=const_cast<int*>(_graph->getIndex());
58   int * adjncy=const_cast<int*>(_graph->getValues());
59   //ndomain
60   int nparts=ndomain;
61
62 #if !defined(MED_ENABLE_PTSCOTCH)
63   throw INTERP_KERNEL::Exception("PTSCOTCHGraph::partGraph : PTSCOTCH is not available. Check your products, please.");
64 #else
65   //output parameters
66   int* partition = new int[n+1];
67   
68   int* vlbloctab = _vlbloctab?const_cast<int*>(_vlbloctab->begin()):0;
69   
70   SCOTCH_Dgraph scotch_graph;
71   SCOTCH_dgraphInit(&scotch_graph, MPI_COMM_WORLD);
72   SCOTCH_dgraphBuild(&scotch_graph,
73                      0,             // baseval               , base first indice 0
74                      n,             // vertlocnbr            , nb of local graph nodes
75                      n,             // vertlocmax            , should be set to vertlocnbr for graphs without holes
76                      xadj,          // vertloctab[vertnbr+1] , index vertex table
77                      0,             // vendloctab            , index end vertex table if disjoint, set to zero
78                      _cell_weight,  // veloloctab            , graph vertices loads, set to zero
79                      vlbloctab,     // vlblocltab            , vertex label array : global vertex index
80                      xadj[n],       // edgelocnbr            , number of edges
81                      xadj[n],       // edgelocsiz            , same as edgelocnbr if edgeloctab is compact
82                      adjncy,        // edgeloctab[edgelocnbr], global indexes of edges
83                      0,             // edgegsttab            , optional, should be computed internally, set to zero
84                      _edge_weight); // edloloctab            , graph edges loads, set to zero
85   
86   SCOTCH_Strat scotch_strategy;
87   SCOTCH_stratInit(&scotch_strategy);
88   
89   //!user-defined options for the strategy
90   if (options_string!="")
91     SCOTCH_stratGraphMap(&scotch_strategy,options_string.c_str());
92
93   if (nparts>1)
94     {
95       if (MyGlobals::_Verbose>10) std::cout << "SCOTCHGraph::graphPart SCOTCH_graphPart" << std::endl;
96       SCOTCH_dgraphPart(&scotch_graph,nparts,&scotch_strategy,partition);
97     }
98   else  //partition for 1 subdomain
99     {
100     for (int i=0; i<n+1; i++)
101       partition[i]=0;
102     }
103   
104   SCOTCH_stratExit(&scotch_strategy);
105   SCOTCH_dgraphExit(&scotch_graph);
106
107   std::vector<int> index(n+1);
108   std::vector<int> value(n);
109   index[0]=0;
110   for (int i=0; i<n; i++)
111     {
112       index[i+1]=index[i]+1;
113       value[i]=partition[i];
114     }
115   delete [] partition;
116   
117   //creating a skylinearray with no copy of the index and partition array
118   //the fifth argument true specifies that only the pointers are passed 
119   //to the object
120   _partition = MEDCoupling::MEDCouplingSkyLineArray::New(index,value);
121 #endif
122 }
123