Salome HOME
Copyright update 2021
[tools/medcoupling.git] / src / MEDPartitioner / MEDPARTITIONER_MEDPartitioner.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_MEDPartitioner.hxx"
21 #include "MEDPARTITIONER_MeshCollection.hxx"
22 #include "MEDPARTITIONER_Topology.hxx"
23 #include "MEDPARTITIONER_ParaDomainSelector.hxx"
24 #include "MEDPARTITIONER_ParallelTopology.hxx"
25 #include "MEDPARTITIONER_Utils.hxx"
26 #include "MEDPARTITIONER_Graph.hxx"
27 #ifdef MED_ENABLE_METIS
28 #  include "MEDPARTITIONER_MetisGraph.hxx"
29 #endif
30 #ifdef MED_ENABLE_SCOTCH
31 #  include "MEDPARTITIONER_ScotchGraph.hxx"
32 #endif
33 #ifdef MED_ENABLE_PTSCOTCH
34 #  include "MEDPARTITIONER_PTScotchGraph.hxx"
35 #endif
36 #include "MEDPARTITIONER_MeshCollectionDriver.hxx"
37
38 #include "MEDCouplingUMesh.hxx"
39 #include "MEDCouplingSkyLineArray.hxx"
40
41 #include <iostream>
42 #include <vector>
43
44 const char MEDPARTITIONER::MEDPartitioner::METIS_PART_ALG[]="Metis";
45 const char MEDPARTITIONER::MEDPartitioner::SCOTCH_PART_ALG[]="Scotch";
46 const char MEDPARTITIONER::MEDPartitioner::PTSCOTCH_PART_ALG[]="PTScotch";
47
48 MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const std::string& filename, int ndomains, const std::string& library,bool create_boundary_faces, bool create_joints, bool mesure_memory):
49   _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 )
50 {
51   MyGlobals::_World_Size = 1;
52   MyGlobals::_Rank = 0;
53   MyGlobals::_Create_Boundary_Faces = create_boundary_faces;
54   MyGlobals::_Create_Joints = create_joints;
55
56   ParaDomainSelector parallelizer(mesure_memory);
57   _input_collection=new MeshCollection(filename,parallelizer);
58   _input_collection->setParaDomainSelector( &parallelizer );
59
60   MEDPARTITIONER::ParallelTopology* aPT =
61     (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology();
62   aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() );
63   _input_collection->prepareFieldDescriptions();
64   createPartitionCollection(ndomains, library, create_boundary_faces, create_joints, mesure_memory);
65
66   parallelizer.evaluateMemory();
67 }
68
69 MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const MEDCoupling::MEDFileData* filedata, int ndomains, const std::string& library,bool create_boundary_faces, bool create_joints, bool mesure_memory):
70   _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 )
71 {
72   MyGlobals::_World_Size = 1;
73   MyGlobals::_Rank = 0;
74   MyGlobals::_Create_Boundary_Faces = create_boundary_faces;
75   MyGlobals::_Create_Joints = create_joints;
76
77   ParaDomainSelector parallelizer(mesure_memory);
78   _input_collection=new MeshCollection();
79   _input_collection->setParaDomainSelector( &parallelizer );
80   _input_collection->retrieveDriver()->readMEDFileData(filedata);
81
82   MEDPARTITIONER::ParallelTopology* aPT =
83     (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology();
84   aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() );
85   _input_collection->prepareFieldDescriptions();
86   createPartitionCollection(ndomains, library, create_boundary_faces, create_joints, mesure_memory);
87
88   parallelizer.evaluateMemory();
89 }
90
91 MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const MEDCoupling::MEDFileData* filedata, MEDPARTITIONER ::Graph* graph, bool create_boundary_faces, bool create_joints, bool mesure_memory):
92   _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 )
93 {
94   MyGlobals::_World_Size = 1;
95   MyGlobals::_Rank = 0;
96   MyGlobals::_Create_Boundary_Faces = create_boundary_faces;
97   MyGlobals::_Create_Joints = create_joints;
98
99   ParaDomainSelector parallelizer(mesure_memory);
100   _input_collection=new MeshCollection();
101   _input_collection->setParaDomainSelector( &parallelizer );
102   _input_collection->retrieveDriver()->readMEDFileData(filedata);
103
104   MEDPARTITIONER::ParallelTopology* aPT =
105     (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology();
106   aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() );
107   _input_collection->prepareFieldDescriptions();
108
109   _new_topology = new MEDPARTITIONER::ParallelTopology( graph, aPT, graph->nbDomains(), _input_collection->getMeshDimension() );
110   _output_collection=new MeshCollection(*_input_collection,_new_topology,false,false);
111   _output_collection->filterFaceOnCell();
112
113   parallelizer.evaluateMemory();
114 }
115
116 MEDPARTITIONER::MEDPartitioner::~MEDPartitioner()
117 {
118   delete _input_collection; _input_collection = 0;
119   delete _output_collection; _output_collection = 0;
120   delete _new_topology; _new_topology = 0;
121 }
122
123 void MEDPARTITIONER::MEDPartitioner::createPartitionCollection(int ndomains, const std::string& library,bool create_boundary_faces, bool create_joints, bool mesure_memory)
124 {
125   //ParallelTopology* aPT = (ParallelTopology*) _input_collection->getTopology();
126   if (library == "metis")
127     _new_topology = _input_collection->createPartition(ndomains,MEDPARTITIONER::Graph::METIS);
128   else
129     _new_topology = _input_collection->createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH);
130   _output_collection=new MeshCollection(*_input_collection,_new_topology,false,false);
131   _output_collection->filterFaceOnCell();
132 }
133
134 void MEDPARTITIONER::MEDPartitioner::write(const std::string& filename)
135 {
136   ParaDomainSelector parallelizer(false);
137   _output_collection->setParaDomainSelector( &parallelizer );
138   _output_collection->write(filename);
139   parallelizer.evaluateMemory();
140 }
141
142 MEDCoupling::MEDFileData* MEDPARTITIONER::MEDPartitioner::getMEDFileData()
143 {
144   return _output_collection->retrieveDriver()->getMEDFileData();
145 }
146
147 MEDPARTITIONER::Graph* MEDPARTITIONER::MEDPartitioner::Graph(MEDCoupling::MEDCouplingSkyLineArray* graph, Graph::splitter_type split, int* edgeweight, DataArrayIdType *vlbloctab)
148 {
149   MEDPARTITIONER::Graph* cellGraph=0;
150   // will be destroyed by XXXGraph class:
151   MEDCoupling::MCAuto<MEDCoupling::MEDCouplingSkyLineArray> arr(MEDCoupling::MEDCouplingSkyLineArray::New(graph->getIndexArray(), graph->getValuesArray()));
152   switch (split)
153     {
154     case Graph::METIS:
155       if ( !cellGraph )
156         {
157 #ifdef MED_ENABLE_METIS
158           cellGraph=new METISGraph(arr.retn(),edgeweight);
159 #endif
160         }
161       if ( !cellGraph )
162         throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : PARMETIS/METIS is not available. Check your products, please.");
163       break;
164     case Graph::SCOTCH:
165 #ifdef MED_ENABLE_SCOTCH
166       cellGraph=new SCOTCHGraph(arr.retn(),edgeweight);
167 #else
168       throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : SCOTCH is not available. Check your products, please.");
169 #endif
170       break;
171     case Graph::PTSCOTCH:
172       {
173 #ifdef MED_ENABLE_PTSCOTCH
174         cellGraph=new PTSCOTCHGraph(arr.retn(),edgeweight,vlbloctab);
175 #else
176         throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : PTSCOTCH is not available. Check your products, please.");
177 #endif
178         break;
179       }
180     default:
181       throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : Not managed split type engine !");
182     }
183   return cellGraph;
184 }
185
186 std::vector<std::string> MEDPARTITIONER::MEDPartitioner::AvailableAlgorithms()
187 {
188   std::vector<std::string> ret;
189 #ifdef MED_ENABLE_METIS
190   ret.push_back(std::string(METIS_PART_ALG));
191 #endif
192 #ifdef MED_ENABLE_SCOTCH
193   ret.push_back(std::string(SCOTCH_PART_ALG));
194 #endif
195 #ifdef MED_ENABLE_PTSCOTCH
196   ret.push_back(std::string(PTSCOTCH_PART_ALG));
197 #endif
198   return ret;
199 }
200
201 bool MEDPARTITIONER::MEDPartitioner::HasMetisAlg()
202 {
203 #ifdef MED_ENABLE_METIS
204   return true;
205 #else
206   return false;
207 #endif
208 }
209
210 bool MEDPARTITIONER::MEDPartitioner::HasScotchAlg()
211 {
212 #ifdef MED_ENABLE_SCOTCH
213   return true;
214 #else
215   return false;
216 #endif
217 }
218
219 bool MEDPARTITIONER::MEDPartitioner::HasPTScotchAlg()
220 {
221 #ifdef MED_ENABLE_PTSCOTCH
222   return true;
223 #else
224   return false;
225 #endif
226 }
227
228 std::vector<std::string> MEDPARTITIONER::MEDPartitioner::AllAlgorithms()
229 {
230   std::vector<std::string> ret;
231   ret.push_back(std::string(METIS_PART_ALG));
232   ret.push_back(std::string(SCOTCH_PART_ALG));
233   ret.push_back(std::string(PTSCOTCH_PART_ALG));
234   return ret;
235 }