Salome HOME
6ea40a0e6a931d31e57ba4008dbe8fae12c3b138
[tools/medcoupling.git] / src / MEDPartitioner / MEDPARTITIONER_MEDPartitioner.cxx
1 // Copyright (C) 2007-2016  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 #include "MEDPARTITIONER_MeshCollectionDriver.hxx"
34
35 #include "MEDCouplingUMesh.hxx"
36 #include "MEDCouplingSkyLineArray.hxx"
37
38 #include <iostream>
39 #include <vector>
40
41 MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const std::string& filename, int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory):
42   _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 )
43 {
44   MyGlobals::_World_Size = 1;
45   MyGlobals::_Rank = 0;
46   MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces;
47   MyGlobals::_Create_Joints = create_joints;
48
49   ParaDomainSelector parallelizer(mesure_memory);
50   _input_collection=new MeshCollection(filename,parallelizer);
51   _input_collection->setParaDomainSelector( &parallelizer );
52
53   MEDPARTITIONER::ParallelTopology* aPT =
54     (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology();
55   aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() );
56   _input_collection->prepareFieldDescriptions();
57   createPartitionCollection(ndomains, library, creates_boundary_faces, create_joints, mesure_memory);
58
59   parallelizer.evaluateMemory();
60 }
61
62 MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const MEDCoupling::MEDFileData* filedata, int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory):
63   _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 )
64 {
65   MyGlobals::_World_Size = 1;
66   MyGlobals::_Rank = 0;
67   MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces;
68   MyGlobals::_Create_Joints = create_joints;
69
70   ParaDomainSelector parallelizer(mesure_memory);
71   _input_collection=new MeshCollection();
72   _input_collection->setParaDomainSelector( &parallelizer );
73   _input_collection->retrieveDriver()->readMEDFileData(filedata);
74
75   MEDPARTITIONER::ParallelTopology* aPT =
76     (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology();
77   aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() );
78   _input_collection->prepareFieldDescriptions();
79   createPartitionCollection(ndomains, library, creates_boundary_faces, create_joints, mesure_memory);
80
81   parallelizer.evaluateMemory();
82 }
83
84 MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const MEDCoupling::MEDFileData* filedata, MEDPARTITIONER ::Graph* graph, bool creates_boundary_faces, bool create_joints, bool mesure_memory):
85   _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 )
86 {
87   MyGlobals::_World_Size = 1;
88   MyGlobals::_Rank = 0;
89   MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces;
90   MyGlobals::_Create_Joints = create_joints;
91
92   ParaDomainSelector parallelizer(mesure_memory);
93   _input_collection=new MeshCollection();
94   _input_collection->setParaDomainSelector( &parallelizer );
95   _input_collection->retrieveDriver()->readMEDFileData(filedata);
96
97   MEDPARTITIONER::ParallelTopology* aPT =
98     (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology();
99   aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() );
100   _input_collection->prepareFieldDescriptions();
101
102   _new_topology = new MEDPARTITIONER::ParallelTopology( graph, aPT, graph->nbDomains(), _input_collection->getMeshDimension() );
103   _output_collection=new MeshCollection(*_input_collection,_new_topology,false,false);
104   _output_collection->filterFaceOnCell();
105
106   parallelizer.evaluateMemory();
107 }
108
109 MEDPARTITIONER::MEDPartitioner::~MEDPartitioner()
110 {
111   delete _input_collection; _input_collection = 0;
112   delete _output_collection; _output_collection = 0;
113   delete _new_topology; _new_topology = 0;
114 }
115
116 void MEDPARTITIONER::MEDPartitioner::createPartitionCollection(int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory)
117 {
118   //ParallelTopology* aPT = (ParallelTopology*) _input_collection->getTopology();
119   if (library == "metis")
120     _new_topology = _input_collection->createPartition(ndomains,MEDPARTITIONER::Graph::METIS);
121   else
122     _new_topology = _input_collection->createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH);
123   _output_collection=new MeshCollection(*_input_collection,_new_topology,false,false);
124   _output_collection->filterFaceOnCell();
125 }
126
127 void MEDPARTITIONER::MEDPartitioner::write(const std::string& filename)
128 {
129   ParaDomainSelector parallelizer(false);
130   _output_collection->setParaDomainSelector( &parallelizer );
131   _output_collection->write(filename);
132   parallelizer.evaluateMemory();
133 }
134
135 MEDCoupling::MEDFileData* MEDPARTITIONER::MEDPartitioner::getMEDFileData()
136 {
137   return _output_collection->retrieveDriver()->getMEDFileData();
138 }
139
140 MEDPARTITIONER::Graph* MEDPARTITIONER::MEDPartitioner::Graph(MEDCoupling::MEDCouplingSkyLineArray* graph, Graph::splitter_type split, int* edgeweight)
141 {
142   MEDPARTITIONER::Graph* cellGraph=0;
143   // will be destroyed by XXXGraph class:
144   MEDCoupling::MEDCouplingSkyLineArray* arr = MEDCoupling::MEDCouplingSkyLineArray::New(graph->getIndexArray(), graph->getValuesArray());
145   switch (split)
146     {
147     case Graph::METIS:
148       if ( !cellGraph )
149         {
150 #ifdef MED_ENABLE_METIS
151           cellGraph=new METISGraph(arr,edgeweight);
152 #endif
153         }
154       if ( !cellGraph )
155         throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : PARMETIS/METIS is not available. Check your products, please.");
156       break;
157     case Graph::SCOTCH:
158 #ifdef MED_ENABLE_SCOTCH
159       cellGraph=new SCOTCHGraph(arr,edgeweight);
160 #else
161       throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : SCOTCH is not available. Check your products, please.");
162 #endif
163       break;
164     }
165   return cellGraph;
166 }