Salome HOME
Merge from BR_V5_DEV 16Feb09
[modules/med.git] / src / MEDSPLITTER / Test / MEDSPLITTERTest_ParallelTopology.cxx
1 //  Copyright (C) 2007-2008  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.
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 #include "MEDSPLITTERTest.hxx"
20 #include <cppunit/TestAssert.h>
21
22 #include "MEDMEM_ConnectZone.hxx" 
23 #include "MEDMEM_DriversDef.hxx"
24 #include "MEDMEM_Mesh.hxx"
25 #include "MEDMEM_Meshing.hxx"
26 #include "MEDMEM_GaussLocalization.hxx"
27 #include "MEDMEM_Field.hxx"
28 #include "MEDMEM_CellModel.hxx"
29 #include "MEDMEM_Group.hxx"
30
31 #include "MEDSPLITTER_Graph.hxx"
32 #include "MEDSPLITTER_Topology.hxx"
33 #include "MEDSPLITTER_ParallelTopology.hxx"
34 #include "MEDSPLITTER_SequentialTopology.hxx"
35 #include "MEDSPLITTER_MESHCollection.hxx"
36 #include "MEDSPLITTER_MESHCollectionDriver.hxx"
37
38 #ifdef ENABLE_METIS
39 #include "MEDSPLITTER_METISGraph.hxx"
40 #endif
41 //#include "MEDSPLITTER_SCOTCHGraph.hxx"
42
43 #include "MEDMEM_Exception.hxx"
44
45 #include <string>
46
47 // use this define to enable lines, execution of which leads to Segmentation Fault
48 //#define ENABLE_FAULTS
49
50 // use this define to enable CPPUNIT asserts and fails, showing bugs
51 #define ENABLE_FORCED_FAILURES
52
53
54 using namespace std;
55 using namespace MEDSPLITTER;
56 using namespace MEDMEM;
57  
58 /*
59  * Check methods defined in ParallelTopology.hxx
60  * 
61  ParallelTopology();
62  ParallelTopology(vector<MEDMEM::MESH*>, vector<MEDMEM::CONNECTZONE*>,vector<int*>&, vector<int*>&, vector<int*>&);
63  (+) ParallelTopology(boost::shared_ptr<Graph> graph, int nbdomain, int mesh_dimension);
64  ~ParallelTopology();
65  (+) void convertGlobalNodeList(const int*, int,int*,int*);
66  (+) void convertGlobalNodeList(const int*, int,int*,int);
67  (+) void convertGlobalNodeListWithTwins(const int* face_list, int nbnode, int*& local, int*& ip, int*& full_array, int& size);
68  (+) void convertGlobalCellList(const int*, int , int*, int *);
69  void convertGlobalFaceList(const int*, int , int*, int *);    
70  void convertGlobalFaceList(const int*, int , int*, int);  
71  void convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array,int& size);
72  void createNodeMapping(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
73  std::map<MED_EN::medGeometryElement,int>& present_type_numbers,
74  int idomain);
75  void createFaceMapping(const MESHCollection &);
76  void createFaceMapping2ndversion(const MESHCollection &);
77  void convertToLocal(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
78  std::map<MED_EN::medGeometryElement,int>& present_type_numbers,
79  int idomain,
80  MED_EN::medEntityMesh entity);
81  void computeNodeNodeCorrespondencies(int nbdomain,vector<MEDMEM::MEDSKYLINEARRAY*>& ) const;
82  void computeCellCellCorrespondencies(int nbdomain,vector<MEDMEM::MEDSKYLINEARRAY*>&, const Graph* ) const;
83  inline  int convertNodeToGlobal(int ip,int icell) const
84  inline  int convertFaceToGlobal(int ip,int icell) const
85  inline  int convertCellToGlobal(int ip,int icell) const
86  inline  void convertNodeToGlobal(int ip, const int* local, int n, int* global)const
87  (+)inline  void convertCellToGlobal(int ip, const int* local, int n, int* global)const
88  inline  void convertFaceToGlobal(int ip, const int* local, int n, int* global)const
89  (+) inline  int nbDomain() const
90  int nbCells() const
91  (+) inline  int nbCells( int idomain) const
92  (+) inline  int getNodeNumber(int idomain) const
93  inline  int getNodeNumber() const
94  inline  void getNodeList(int idomain, int* list) const
95  (+) inline  int getCellNumber(int idomain) const
96  inline  int getCellDomainNumber(int global) const
97  inline  void getCellList(int idomain, int* list) const
98  inline int getFaceNumber(int idomain) const
99  inline  int getFaceNumber() const
100  inline  void getFaceList(int idomain, int* list) const
101  boost::shared_ptr<Graph> getGraph() const
102 */
103  
104 void MEDSPLITTERTest::testParallelTopology_graph_constructor()
105 {
106 #ifndef ENABLE_METIS
107   CPPUNIT_FAIL("METIS is not available. Please, check your compilation.");
108 #else
109   string data_dir                   = getenv("MED_ROOT_DIR");
110   string tmp_dir                    = getenv("TMP");
111   if (tmp_dir == "")
112     tmp_dir = "/tmp";
113   string filename_rd                = data_dir + "/share/salome/resources/med/carre_en_quad4_import22.med";  
114   string filename_para_wr            = tmp_dir + "/myWrField_seq_pointe22_";
115   string filename_para_med0           = tmp_dir + "/myWrField_seq_pointe22_1.med";
116   string filename_para_med1           = tmp_dir + "/myWrField_seq_pointe22_2.med";
117   
118   string meshname="carre_en_quad4";
119   MESHCollection collection(filename_rd,meshname);
120   
121   MEDMEM::MEDSKYLINEARRAY* array=0;
122   int* edgeweights=0;
123     
124   collection.buildCellGraph(array,edgeweights);
125     
126   boost::shared_ptr<Graph> cell_graph=boost::shared_ptr<Graph>(new METISGraph(array,edgeweights));
127          
128   cell_graph->partGraph(2,"");
129   
130   //cell_graph is a shared pointer 
131   Topology* topology = new ParallelTopology (cell_graph, 2, collection.getMeshDimension());
132   
133   
134         /*
135          * test_SPLITTER_square
136          * 
137          * computes a partitioning for the following geometry
138          * 
139          * 
140          * 
141          * 7------------8------------9
142          * |            |            |
143          * |            |            |
144          * |     3      |     4      |
145          * |            |            |
146          * |            |            |
147          * 4------------5------------6
148          * |            |            |
149          * |            |            |
150          * |     1      |     2      |
151          * |            |            |
152          * |            |            |
153          * 1------------2------------3 
154          *
155          * Result of the 2 domain split :
156          *  
157          * 5------------6 5------------6
158          * |            | |            |
159          * |            | |            |
160          * |     2      | |     2      |
161          * |            | |            |
162          * |            | |            |
163          * 1------------2 1------------2
164          * |            | |            |
165          * |            | |            |
166          * |     1      | |     1      |
167          * |            | |            |
168          * |            | |            |
169          * 4------------3 4------------3 
170          */
171  
172   int iglobal[3]={1,2,3};
173   int* iloc=new int[3];
174   int* iproc=new int[3];
175   int iloc_answer[3]={1,1,2};
176   int iproc_answer[3]={0,1,0};
177   topology->convertGlobalCellList(iglobal,3,iloc,iproc);
178   for(int i=0; i<3; i++)
179                 { 
180                         CPPUNIT_ASSERT_EQUAL(iloc_answer[i], iloc[i]);
181                         CPPUNIT_ASSERT_EQUAL(iproc_answer[i],iproc[i]);
182                 }
183   int* global_2 = new int[3];
184   topology->convertCellToGlobal(0,iloc,3,global_2);
185   int global_answer[3]={1,1,3};
186   for (int i=0; i<3; i++)
187                 {
188                         CPPUNIT_ASSERT_EQUAL(global_answer[i],global_2[i]);
189                 }
190   
191   CPPUNIT_ASSERT_EQUAL(topology->getCellNumber(0),2);  
192   CPPUNIT_ASSERT_EQUAL(topology->getCellNumber(1),2);
193   
194     
195   CPPUNIT_ASSERT_EQUAL(topology->nbCells(0),2);
196   CPPUNIT_ASSERT_EQUAL(topology->nbCells(1),2);
197   
198   CPPUNIT_ASSERT_EQUAL(topology->nbDomain(),2);
199   //node and face lists have not yet been computed
200   CPPUNIT_ASSERT_THROW(topology->convertGlobalNodeList(iglobal,3,iloc,iproc),MEDEXCEPTION);
201   CPPUNIT_ASSERT_THROW(topology->convertGlobalFaceList(iglobal,3,iloc,iproc),MEDEXCEPTION);
202   
203   MESHCollection new_collection(collection, topology);
204   
205   CPPUNIT_ASSERT_EQUAL(topology->getNodeNumber(0),6);  
206   CPPUNIT_ASSERT_EQUAL(topology->getNodeNumber(1),6);
207   
208   topology->convertGlobalNodeList(iglobal,3,iloc,iproc);
209    
210   int iloc_node_answer[3]={4,3,3};
211   int iproc_node_answer[3]={0,0,1};
212   for(int i=0; i<3; i++)
213                 { 
214                         CPPUNIT_ASSERT_EQUAL(iloc_node_answer[i], iloc[i]);
215                         CPPUNIT_ASSERT_EQUAL(iproc_node_answer[i],iproc[i]);
216                 }
217   int* local_nodes;
218   int* ip_nodes;
219   int* full_array;
220   int size;
221   topology->convertGlobalNodeListWithTwins(iglobal, 3, local_nodes, ip_nodes, full_array, size);
222   CPPUNIT_ASSERT_EQUAL(size,4);
223   int iloc_node_wt_answer[4]={4,3,4,3};
224   int iproc_node_wt_answer[4]={0,0,1,1};
225   for(int i=0; i<4; i++)
226                 { 
227                         CPPUNIT_ASSERT_EQUAL(iloc_node_wt_answer[i], local_nodes[i]);
228                         CPPUNIT_ASSERT_EQUAL(iproc_node_wt_answer[i],ip_nodes[i]);
229                 }
230   delete topology;
231   delete[] iloc;
232   delete[]iproc;
233   delete[] global_2;
234   delete[] local_nodes;
235   delete[] ip_nodes;
236   delete[] full_array;
237 #endif // ENABLE_METIS
238 }