Salome HOME
Merge from V6_main 01/04/2013
[modules/med.git] / src / MEDSPLITTER / Test / ParaMEDSPLITTERTest_medsplitter_para.cxx
1 // Copyright (C) 2007-2013  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 // File      : ParaMEDSPLITTERTest_medsplitter_para.cxx
20 // Created   : Fri Jul 31 12:35:44 2009
21 // Author    : Edward AGAPOV (eap)
22 //
23
24 #include "ParaMEDSPLITTERTest.hxx"
25 #include "MEDSPLITTERTest_Utils.hxx"
26
27 #include "MEDSPLITTER_ParaDomainSelector.hxx"
28 #include "MEDSPLITTER_MESHCollection.hxx"
29 #include "MEDSPLITTER_ParaDomainSelector.hxx"
30 #include "MEDSPLITTER_Topology.hxx"
31 //#include "MEDSPLITTER_API.hxx"
32
33 #include <MEDMEM_Mesh.hxx>
34 #include <MEDMEM_PointerOf.hxx>
35
36 using namespace std;
37 using namespace MEDSPLITTER;
38 using namespace MED_EN;
39
40 //================================================================================
41 /*!
42  * \brief call test_medsplitter_para with 2 files: blade.med et pointe.med
43  */
44 //================================================================================
45
46 void ParaMEDSPLITTERTest::functional_validation()
47 {
48   //test_medsplitter_para( "/dn25/salome/eap/salome/misc/tmp/meshing_REsplit1.med", "meshing_1");
49   test_medsplitter_para( MEDSPLITTERTest_Utils::getResourceFile("TimeStamps.med"), "dom");
50   test_medsplitter_para( MEDSPLITTERTest_Utils::getResourceFile("square1.med"), "Mesh_2");
51   test_medsplitter_para( MEDSPLITTERTest_Utils::getResourceFile("pointe.med"), "maa1");
52 }
53
54 //================================================================================
55 /*!
56  * \brief La validation consistera à prendre un maillage, à le découper en deux,
57  * à passer de deux à trois sous-domaines, puis à revenir vers un sous-domaine.
58  */
59 //================================================================================
60
61 void ParaMEDSPLITTERTest::test_medsplitter_para( const string& med_file, const string& meshname )
62 {
63   ParaDomainSelector dom_sel;
64
65   string tmp_dir = MEDSPLITTERTest_Utils::getTmpDirectory();
66   // if splitter is running on different hosts, assure tmp_dir to be accessible from all procs
67   bool diff_hosts = dom_sel.isOnDifferentHosts();
68   if ( diff_hosts )
69     if ( getenv("HOME"))
70       tmp_dir = getenv("HOME");
71
72   string file_2 = tmp_dir + "/test_medsplitter_para_2" ;
73   string file_3 = tmp_dir + "/test_medsplitter_para_3" ;
74   string file_1 = tmp_dir + "/test_medsplitter_para_1" ;
75   string file_3c= tmp_dir + "/test_medsplitter_para_3c" ;
76   MEDMEM::STRING rm_cmd("rm "); rm_cmd << tmp_dir << "/test_medsplitter_para_*";
77
78   MPI_Barrier( MPI_COMM_WORLD ); // avoid removing files being read
79
80   // remove all old (master and med) files
81   if ( dom_sel.rank() == 0 )
82     system( rm_cmd );
83
84   // découper en deux
85   if ( dom_sel.rank() == 0 )
86   {
87     MESHCollection collection_1(med_file,meshname);
88     auto_ptr<Topology> new_topo_2( collection_1.createPartition( 2, Graph::SCOTCH ));
89
90     MESHCollection collection_2w( collection_1, new_topo_2.get());
91     collection_2w.setDriverType(MEDSPLITTER::MedAscii);
92     collection_2w.write( file_2 );
93   }
94   MPI_Barrier( MPI_COMM_WORLD ); // wait for master file_2
95
96   // passer de deux à trois sous-domaines
97   MESHCollection collection_2r(file_2,dom_sel);
98   auto_ptr<Topology> new_topo_3( collection_2r.createPartition( 3, Graph::METIS ));
99
100   MESHCollection collection_3w( collection_2r, new_topo_3.get());
101   collection_3w.setDriverType(MEDSPLITTER::MedAscii);
102   collection_3w.write( file_3 );
103
104   // check global face numbers of collection_3w
105   {
106     int total_nb_faces = 0;
107     for ( int idomain=0; idomain < collection_3w.getMesh().size(); ++idomain )
108       total_nb_faces += collection_3w.getMesh()[idomain]->getNumberOfElements(collection_3w.getSubEntity(), MED_ALL_ELEMENTS );
109
110     for ( int idomain=0; idomain < collection_3w.getMesh().size(); ++idomain )
111     {
112       int nb_dom_faces = new_topo_3->getFaceNumber(idomain);
113       MEDMEM::PointerOf<int> glob_ids( nb_dom_faces );
114       new_topo_3->getFaceList(idomain, glob_ids);
115       for ( int i = 0; i < nb_dom_faces; ++i )
116         if ( glob_ids[i] < 1 || glob_ids[i] > total_nb_faces )
117           CPPUNIT_FAIL(MEDMEM::STRING("Invalid global face id: ")<< glob_ids[i]);
118     }
119   }
120   
121   MPI_Barrier( MPI_COMM_WORLD ); // wait for master file_3
122
123   // revenir vers un sous-domaine
124   MESHCollection collection_3r(file_3,dom_sel);
125   auto_ptr<Topology> new_topo_1( collection_3r.createPartition( 1, Graph::METIS ));
126
127   MESHCollection collection_1w( collection_3r, new_topo_1.get());
128   collection_1w.setDriverType(MEDSPLITTER::MedAscii);
129   collection_1w.write( file_1 );
130
131   // compare initial and final mesh
132
133   if ( dom_sel.getProccessorID(0) == dom_sel.rank() )
134   {
135     MEDMEM::MESH init_mesh( MEDMEM::MED_DRIVER, med_file, meshname);
136     MEDMEM::MESH& res_mesh = * collection_1w.getMesh()[0];
137
138     // nb nodes
139     int i_nb_nodes = init_mesh.getNumberOfNodes();
140     int r_nb_nodes = res_mesh.getNumberOfNodes();
141     CPPUNIT_ASSERT_EQUAL( i_nb_nodes, r_nb_nodes );
142
143     // coord
144     string i_coo_sys = init_mesh.getCoordinatesSystem();
145     string r_coo_sys = res_mesh.getCoordinatesSystem();
146     CPPUNIT_ASSERT_EQUAL( i_coo_sys, r_coo_sys );
147
148     // types and nb elements
149     int i_nb_types = init_mesh.getNumberOfTypes(MED_CELL);
150     int r_nb_types = res_mesh.getNumberOfTypes(MED_CELL);
151     CPPUNIT_ASSERT_EQUAL( i_nb_types, r_nb_types );
152     {
153       const medGeometryElement* i_types = init_mesh.getTypes(MED_CELL);
154       const medGeometryElement* r_types = res_mesh.getTypes(MED_CELL);
155       for ( int i=0; i<i_nb_types; ++i )
156         CPPUNIT_ASSERT_EQUAL( i_types[i], r_types[i] );
157       const int * i_nbs = init_mesh.getGlobalNumberingIndex( MED_CELL );
158       const int * r_nbs = res_mesh.getGlobalNumberingIndex( MED_CELL );
159       for ( int i=0; i<i_nb_types; ++i )
160         CPPUNIT_ASSERT_EQUAL( i_nbs[i], r_nbs[i] );
161     }
162     i_nb_types = init_mesh.getNumberOfTypes(MED_FACE);
163     r_nb_types = res_mesh.getNumberOfTypes(MED_FACE);
164     CPPUNIT_ASSERT_EQUAL( i_nb_types, r_nb_types );
165     if ( i_nb_types )
166     {
167       const medGeometryElement* i_types = init_mesh.getTypes(MED_FACE);
168       const medGeometryElement* r_types = res_mesh.getTypes(MED_FACE);
169       for ( int i=0; i<i_nb_types; ++i )
170         CPPUNIT_ASSERT_EQUAL( i_types[i], r_types[i] );
171       const int * i_nbs = init_mesh.getGlobalNumberingIndex( MED_FACE );
172       const int * r_nbs = res_mesh.getGlobalNumberingIndex( MED_FACE );
173       for ( int i=0; i<i_nb_types; ++i )
174         CPPUNIT_ASSERT_EQUAL( i_nbs[i], r_nbs[i] );
175     }
176     i_nb_types = init_mesh.getNumberOfTypes(MED_EDGE);
177     r_nb_types = res_mesh.getNumberOfTypes(MED_EDGE);
178     CPPUNIT_ASSERT_EQUAL( i_nb_types, r_nb_types );
179     if ( i_nb_types )
180     {
181       const medGeometryElement* i_types = init_mesh.getTypes(MED_EDGE);
182       const medGeometryElement* r_types = res_mesh.getTypes(MED_EDGE);
183       for ( int i=0; i<i_nb_types; ++i )
184         CPPUNIT_ASSERT_EQUAL( i_types[i], r_types[i] );
185       const int * i_nbs = init_mesh.getGlobalNumberingIndex( MED_EDGE );
186       const int * r_nbs = res_mesh.getGlobalNumberingIndex( MED_EDGE );
187       for ( int i=0; i<i_nb_types; ++i )
188         CPPUNIT_ASSERT_EQUAL( i_nbs[i], r_nbs[i] );
189     }
190   }
191
192   // Check C API and create_boundary_faces
193 //   medsplitter_para( file_2.c_str(),
194 //                     file_3c.c_str(), 
195 //                     /*nprocs                =*/ 3,
196 //                     /*method                =*/ 0,
197 //                     /*create_boundary_faces =*/ true,
198 //                     /*family_splitting      =*/ false);
199
200 //   CPPUNIT_ASSERT( access(file_3c.data(), F_OK) == 0);
201
202   MPI_Barrier( MPI_COMM_WORLD ); // avoid removing files being read
203
204   // remove all (master and med) files
205   if ( dom_sel.rank() == 0 )
206     system( rm_cmd );
207 }