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