1 // Copyright (C) 2017-2023 CEA, EDF
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "MEDPARTITIONER_PTScotchGraph.hxx"
21 #include "MEDPARTITIONER_Utils.hxx"
23 #include "MEDCouplingSkyLineArray.hxx"
24 #include "MEDCouplingMemArray.hxx"
31 #ifdef MED_ENABLE_PTSCOTCH
39 using namespace MEDPARTITIONER;
42 PTSCOTCHGraph::PTSCOTCHGraph(MEDCoupling::MEDCouplingSkyLineArray *graph, int *edgeweight, DataArrayIdType *vlbloctab):Graph(graph,edgeweight),_vlbloctab(vlbloctab)
46 PTSCOTCHGraph::~PTSCOTCHGraph()
50 void PTSCOTCHGraph::partGraph(int ndomain, const std::string& options_string, ParaDomainSelector* sel)
52 if (MyGlobals::_Verbose>10)
53 std::cout << "proc " << MyGlobals::_Rank << " : PTSCOTCHGraph::partGraph" << std::endl;
55 //number of graph vertices
56 int n = FromIdType<int>(_graph->getNumberOf());
58 mcIdType * xadj=const_cast<mcIdType*>(_graph->getIndex());
59 mcIdType * adjncy=const_cast<mcIdType*>(_graph->getValues());
63 #if !defined(MED_ENABLE_PTSCOTCH)
64 throw INTERP_KERNEL::Exception("PTSCOTCHGraph::partGraph : PTSCOTCH is not available. Check your products, please.");
67 std::unique_ptr<mcIdType[]> partition(new mcIdType[n+1]);
68 #ifdef MEDCOUPLING_USE_64BIT_IDS
69 mcIdType *cellWeightPtr(nullptr);
70 std::vector<mcIdType> cellWeightVec;
73 cellWeightVec.insert(cellWeightVec.end(),_cell_weight,_cell_weight+_graph->getLength());
74 cellWeightPtr = cellWeightVec.data();
76 mcIdType *edgeWeightPtr(nullptr);
77 std::vector<mcIdType> edgeWeightVec;
80 edgeWeightVec.insert(edgeWeightVec.end(),_edge_weight,_edge_weight+_graph->getLength());
81 edgeWeightPtr = edgeWeightVec.data();
84 mcIdType *cellWeightPtr(_cell_weight);
85 mcIdType *edgeWeightPtr(_edge_weight);
88 mcIdType *vlbloctab = _vlbloctab?const_cast<mcIdType*>(_vlbloctab->begin()):nullptr;
91 SCOTCH_Dgraph scotch_graph;
92 SCOTCH_dgraphInit(&scotch_graph, MPI_COMM_WORLD);
93 SCOTCH_dgraphBuild(&scotch_graph,
94 0, // baseval , base first indice 0
95 n, // vertlocnbr , nb of local graph nodes
96 n, // vertlocmax , should be set to vertlocnbr for graphs without holes
97 xadj, // vertloctab[vertnbr+1] , index vertex table
98 0, // vendloctab , index end vertex table if disjoint, set to zero
99 cellWeightPtr, // veloloctab , graph vertices loads, set to zero
100 vlbloctab, // vlblocltab , vertex label array : global vertex index
101 xadj[n], // edgelocnbr , number of edges
102 xadj[n], // edgelocsiz , same as edgelocnbr if edgeloctab is compact
103 adjncy, // edgeloctab[edgelocnbr], global indexes of edges
104 0, // edgegsttab , optional, should be computed internally, set to zero
105 edgeWeightPtr); // edloloctab , graph edges loads, set to zero
107 SCOTCH_Strat scotch_strategy;
108 SCOTCH_stratInit(&scotch_strategy);
110 //!user-defined options for the strategy
111 if (options_string!="")
112 SCOTCH_stratGraphMap(&scotch_strategy,options_string.c_str());
116 if (MyGlobals::_Verbose>10) std::cout << "SCOTCHGraph::graphPart SCOTCH_graphPart" << std::endl;
117 SCOTCH_dgraphPart(&scotch_graph,nparts,&scotch_strategy,partition.get());
119 else //partition for 1 subdomain
121 for (int i=0; i<n+1; i++)
125 SCOTCH_stratExit(&scotch_strategy);
126 SCOTCH_dgraphExit(&scotch_graph);
128 std::vector<mcIdType> index(n+1);
129 std::vector<mcIdType> value(n);
131 for (int i=0; i<n; i++)
133 index[i+1]=index[i]+1;
134 value[i]=ToIdType(partition[i]);
137 //creating a skylinearray with no copy of the index and partition array
138 //the fifth argument true specifies that only the pointers are passed
140 _partition = MEDCoupling::MEDCouplingSkyLineArray::New(index,value);