1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "MEDPARTITIONERTest.hxx"
22 #include "MEDPARTITIONER_MeshCollection.hxx"
23 #include "MEDPARTITIONER_ParallelTopology.hxx"
24 #include "MEDPARTITIONER_ParaDomainSelector.hxx"
25 #include "MEDPARTITIONER_Utils.hxx"
27 #include "CellModel.hxx"
28 #include "MEDFileMesh.hxx"
29 #include "MEDLoader.hxx"
30 #include "MEDLoaderBase.hxx"
31 #include "MEDCouplingUMesh.hxx"
32 #include "MEDCouplingExtrudedMesh.hxx"
33 #include "MEDCouplingFieldDouble.hxx"
34 #include "MEDCouplingMemArray.hxx"
35 #include "MEDCouplingMultiFields.hxx"
37 #include <cppunit/TestAssert.h>
49 using namespace ParaMEDMEM;
50 using namespace MEDPARTITIONER;
53 void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForMesh()
56 string fileName,cmd,execName,sourceName,targetName,input;
57 execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED
58 execName+="/bin/salome/medpartitioner_para";
59 fileName=_file_name_with_faces;
61 ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
62 ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
63 ParaMEDMEM::MEDCouplingUMesh* faceMesh=initialMesh->getLevelM1Mesh(false);
65 cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc
68 targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
69 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
70 if (_verbose) cout<<endl<<cmd<<endl;
71 res=system(cmd.c_str());
72 CPPUNIT_ASSERT_EQUAL(0, res);
73 input=targetName+".xml";
75 MEDPARTITIONER::ParaDomainSelector parallelizer(false);
76 MEDPARTITIONER::MeshCollection collection(input,parallelizer);
77 CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension());
78 std::vector<ParaMEDMEM::MEDCouplingUMesh*>cellMeshes=collection.getMesh();
79 CPPUNIT_ASSERT_EQUAL(5, (int) cellMeshes.size());
81 for (std::size_t i = 0; i < cellMeshes.size(); i++)
82 nbcells+=cellMeshes[i]->getNumberOfCells();
83 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
85 std::vector<ParaMEDMEM::MEDCouplingUMesh*>faceMeshes=collection.getFaceMesh();
86 CPPUNIT_ASSERT_EQUAL(5, (int) faceMeshes.size());
88 for (std::size_t i=0; i < faceMeshes.size(); i++)
89 nbfaces+=faceMeshes[i]->getNumberOfCells();
90 CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), nbfaces);
92 //merge split meshes and test equality
93 cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc
94 sourceName=targetName+".xml";
96 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
97 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
98 if (_verbose) cout<<endl<<cmd<<endl;
99 res=system(cmd.c_str());
100 CPPUNIT_ASSERT_EQUAL(0, res);
102 string refusedName=targetName+"1.med";
103 ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
104 ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
105 ParaMEDMEM::MEDCouplingUMesh* refusedFaceMesh=refusedMesh->getLevelM1Mesh(false);
107 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
108 CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), refusedFaceMesh->getNumberOfCells());
111 ParaMEDMEM::MEDCouplingMesh* mergeCell=cellMesh->mergeMyselfWith(refusedCellMesh);
112 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), mergeCell->getNumberOfCells());
114 ParaMEDMEM::MEDCouplingMesh* mergeFace=faceMesh->mergeMyselfWith(refusedFaceMesh);
115 CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), mergeFace->getNumberOfCells());
117 CPPUNIT_ASSERT(faceMesh->isEqual(refusedFaceMesh,1e-12));
120 std::vector<const MEDCouplingUMesh *> meshes;
121 std::vector<DataArrayInt *> corr;
122 meshes.push_back(cellMesh);
123 refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9);
124 meshes.push_back(refusedCellMesh);
125 MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
126 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
129 for (std::size_t i = 0; i < corr.size(); i++)
132 meshes.push_back(faceMesh);
133 refusedFaceMesh->tryToShareSameCoordsPermute(*faceMesh, 1e-9);
134 meshes.push_back(refusedFaceMesh);
135 MEDCouplingUMesh* fusedFace=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
136 CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), fusedFace->getNumberOfCells());
138 for (std::size_t i = 0; i < corr.size(); i++)
140 fusedFace->decrRef();
141 refusedFaceMesh->decrRef();
143 fusedCell->decrRef();
144 refusedCellMesh->decrRef();
146 //done in ~collection
147 //for (int i = 0; i < faceMeshes.size(); i++) faceMeshes[i]->decrRef();
148 //for (int i = 0; i < cellMeshes.size(); i++) cellMeshes[i]->decrRef();
151 void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForFieldOnCells()
154 string fileName,cmd,execName,sourceName,targetName,input;
155 execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED
156 execName+="/bin/salome/medpartitioner_para";
158 fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnCells.med");
160 ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
161 ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
163 cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc
166 targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
167 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
168 if (_verbose) cout<<endl<<cmd<<endl;
169 res=system(cmd.c_str());
170 CPPUNIT_ASSERT_EQUAL(0, res);
171 input=targetName+".xml";
173 //merge split meshes and test equality
174 cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc
175 sourceName=targetName+".xml";
177 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
178 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
179 if (_verbose) cout<<endl<<cmd<<endl;
180 res=system(cmd.c_str());
181 CPPUNIT_ASSERT_EQUAL(0, res);
183 string refusedName=targetName+"1.med";
184 ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
185 ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
187 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
189 std::vector<const MEDCouplingUMesh *> meshes;
190 std::vector<DataArrayInt *> corr;
191 meshes.push_back(cellMesh);
192 refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9);
193 meshes.push_back(refusedCellMesh);
194 MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
195 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
197 MEDCouplingFieldDouble* field1=MEDLoader::ReadFieldCell(fileName.c_str(),initialMesh->getName().c_str(),0,"VectorFieldOnCells",0,1);
198 MEDCouplingFieldDouble* field2=MEDLoader::ReadFieldCell(refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"VectorFieldOnCells",0,1);
200 int nbcells=corr[1]->getNumberOfTuples();
201 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
202 //use corr to test equality of field
203 DataArrayDouble* f1=field1->getArray();
204 DataArrayDouble* f2=field2->getArray();
207 cout<<"\nf1 : "<<f1->reprZip();
208 cout<<"\nf2 : "<<f2->reprZip(); //field2->advancedRepradvancedRepr();
209 for (std::size_t i = 0; i < corr.size(); i++)
210 cout << "\ncorr " << i << " : " << corr[i]->reprZip();
214 int nbcomp=field1->getNumberOfComponents();
215 double* p1=f1->getPointer();
216 double* p2=f2->getPointer();
217 int* pc=corr[1]->getPointer();
218 for (int i = 0; i < nbcells; i++)
222 for (int j = 0; j < nbcomp; j++)
224 if (p1[i1+j]==p2[i2+j]) nbequal++;
225 //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j];
228 CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp, nbequal);
230 for (std::size_t i = 0; i < corr.size(); i++)
234 fusedCell->decrRef();
235 refusedCellMesh->decrRef();
239 void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForFieldOnGaussNe()
242 string fileName,cmd,execName,sourceName,targetName,input;
243 execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED
244 execName+="/bin/salome/medpartitioner_para";
246 fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnGaussNe.med");
248 ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
249 ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
251 cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc
254 targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
255 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
256 if (_verbose) cout<<endl<<cmd<<endl;
257 res=system(cmd.c_str());
258 CPPUNIT_ASSERT_EQUAL(0, res);
259 input=targetName+".xml";
261 //merge split meshes and test equality
262 cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc
263 sourceName=targetName+".xml";
265 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
266 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
267 if (_verbose) cout<<endl<<cmd<<endl;
268 res=system(cmd.c_str());
269 CPPUNIT_ASSERT_EQUAL(0, res);
271 string refusedName=targetName+"1.med";
272 ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
273 ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
275 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
277 std::vector<const MEDCouplingUMesh *> meshes;
278 std::vector<DataArrayInt *> corr;
279 meshes.push_back(cellMesh);
280 refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9);
281 meshes.push_back(refusedCellMesh);
282 MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
283 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
285 MEDCouplingFieldDouble* field1=MEDLoader::ReadField(ON_GAUSS_NE,fileName.c_str(),initialMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6);
286 MEDCouplingFieldDouble* field2=MEDLoader::ReadField(ON_GAUSS_NE,refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6);
288 int nbcells=corr[1]->getNumberOfTuples();
289 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
290 //use corr to test equality of field
291 DataArrayDouble* f1=field1->getArray();
292 DataArrayDouble* f2=field2->getArray();
295 cout << "\nf1 : " << f1->reprZip(); //123.4 for 12th cell,3rd component, 4th gausspoint
296 cout << "\nf2 : " << f2->reprZip(); //field2->advancedRepradvancedRepr();
297 for (std::size_t i = 0; i < corr.size(); i++)
298 cout << "\ncorr " << i << " : " << corr[i]->reprZip();
303 int nbcomp=field1->getNumberOfComponents();
304 double* p1=f1->getPointer();
305 double* p2=f2->getPointer();
306 int* pc=corr[1]->getPointer();
307 for (int i = 0; i < nbcells; i++)
309 int i1=pc[i]*nbcomp*nbptgauss;
310 int i2=i*nbcomp*nbptgauss;
311 for (int j = 0; j < nbcomp*nbptgauss; j++)
313 if (p1[i1+j]==p2[i2+j]) nbequal++;
314 //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j];
317 CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp*nbptgauss, nbequal);
319 for (std::size_t i = 0; i < corr.size(); i++)
323 fusedCell->decrRef();
324 refusedCellMesh->decrRef();
328 void MEDPARTITIONERTest::launchMedpartitionerOnTestMeshes()
332 export INFI=/home/vb144235/resources/blade.med
333 //no need export MESH=Fuse_1
334 export INFI=tmp_testMeshxxx.med
335 //no need export MESH=testMesh
336 mpirun -np 2 medpartitioner_para --input-file=$INFI --output-file=ttmp1_ --ndomains=4
337 mpirun -np 5 medpartitioner_para --input-file=ttmp1_.xml --output-file=ttmp2_ --ndomains=5
338 mpirun -np 2 valgrind medpartitioner_para --input-file=tmp_testMesh_20x30x50.med --output-file=ttmp1petit_ --ndomains=4 --dump-cpu-memory --verbose=111
341 string cmd,execName,sourceName,targetName;
343 res=system("which mpirun 2>/dev/null 1>/dev/null"); //no trace
344 CPPUNIT_ASSERT_EQUAL(0, res);
346 execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED
347 execName+="/bin/salome/medpartitioner_para";
349 cmd="which "+execName+" 2>/dev/null 1>/dev/null"; //no trace
350 res=system(cmd.c_str());
351 CPPUNIT_ASSERT_EQUAL(0, res);
353 cmd="mpirun -np 2 "+execName+" --ndomains=2 --split-method=metis"; //on same proc
354 sourceName=_file_name;
355 targetName=_file_name;
356 targetName.replace(targetName.find(".med"),4,"_partitionedTo2_");
357 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
358 if (_verbose) cout<<endl<<cmd<<endl;
359 res=system(cmd.c_str());
360 CPPUNIT_ASSERT_EQUAL(0, res);
362 cmd="mpirun -np 3 "+execName+" --ndomains=5 --split-method=metis"; //on less proc
363 sourceName=_file_name;
364 targetName=_file_name;
365 targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
366 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
367 if (_verbose) cout<<endl<<cmd<<endl;
368 res=system(cmd.c_str());
369 CPPUNIT_ASSERT_EQUAL(0, res);
371 cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on 1 proc
372 sourceName=targetName+".xml";
373 targetName=_file_name;
374 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
375 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
376 if (_verbose) cout<<endl<<cmd<<endl;
377 res=system(cmd.c_str());
378 CPPUNIT_ASSERT_EQUAL(0, res);
380 cmd="mpirun -np 8 "+execName+" --ndomains=1 --split-method=metis"; //on more proc
381 //sourceName=targetName+".xml";
382 targetName=_file_name;
383 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
384 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
385 if (_verbose) cout<<endl<<cmd<<endl;
386 res=system(cmd.c_str());
387 CPPUNIT_ASSERT_EQUAL(0, res);
390 void MEDPARTITIONERTest::launchMedpartitionerOnHugeTestMeshes()
393 string cmd,execName,sourceName,targetName;
394 execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED
395 execName+="/bin/salome/medpartitioner_para";
397 string snbTarget=IntToStr(_nb_target_huge);
398 cmd="mpirun -np "+snbTarget+" "+execName+" --ndomains="+snbTarget+" --split-method=metis"; //on same proc
399 sourceName=_file_name_huge_xml;
400 targetName=_file_name_huge_xml;
401 string tmp="_partitionedTo"+snbTarget+"_";
402 targetName.replace(targetName.find(".xml"),4,tmp);
403 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
404 if (_verbose) cout<<endl<<cmd<<endl;
405 res=system(cmd.c_str());
406 CPPUNIT_ASSERT_EQUAL(0, res);
409 void MEDPARTITIONERTest::testMpirunSmallSize()
413 launchMedpartitionerOnTestMeshes();
414 verifyMedpartitionerOnSmallSizeForMesh();
415 verifyMedpartitionerOnSmallSizeForFieldOnCells();
416 verifyMedpartitionerOnSmallSizeForFieldOnGaussNe();
419 void MEDPARTITIONERTest::testMpirunMedianSize()
423 launchMedpartitionerOnTestMeshes();
426 void MEDPARTITIONERTest::testMpirunHugeSize()
428 //setBigSize(); //may be a lot for now
430 //create a set of nbx*nby*nbz files mesh of ni*ny*nz cells
432 createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //it is now to know how far we are going to test
433 launchMedpartitionerOnHugeTestMeshes();