1 // Copyright (C) 2007-2016 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 "MEDCouplingMappedExtrudedMesh.hxx"
33 #include "MEDCouplingFieldDouble.hxx"
34 #include "MEDCouplingMemArray.hxx"
35 #include "MEDCouplingMultiFields.hxx"
37 #include <cppunit/TestAssert.h>
46 #include <unistd.h> // get_current_dir_name()
51 using namespace MEDCoupling;
52 using namespace MEDPARTITIONER;
55 std::string MEDPARTITIONERTest::getPartitionerParaExe() const
58 if ( getenv("MEDCOUPLING_ROOT_DIR") )
60 execName=getenv("MEDCOUPLING_ROOT_DIR");
61 execName+="/bin/medpartitioner_para";
62 std::ifstream my_file(execName.c_str());
66 execName = get_current_dir_name();
67 execName += "/../../MEDPartitioner/medpartitioner_para";
68 if (! std::ifstream(execName.c_str()))
69 CPPUNIT_FAIL("Can't find medpartitioner_para, please set MEDCOUPLING_ROOT_DIR");
73 void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForMesh()
76 string fileName,cmd,execName,sourceName,targetName,input;
77 execName=getPartitionerParaExe();
78 fileName=_file_name_with_faces;
80 MEDCoupling::MEDFileUMesh* initialMesh=MEDCoupling::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
81 MEDCoupling::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
82 MEDCoupling::MEDCouplingUMesh* faceMesh=initialMesh->getLevelM1Mesh(false);
84 cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc
87 targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
88 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
89 if (_verbose) cout<<endl<<cmd<<endl;
90 res=system(cmd.c_str());
91 CPPUNIT_ASSERT_EQUAL(0, res);
92 input=targetName+".xml";
94 MEDPARTITIONER::ParaDomainSelector parallelizer(false);
95 MEDPARTITIONER::MeshCollection collection(input,parallelizer);
96 CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension());
97 std::vector<MEDCoupling::MEDCouplingUMesh*>cellMeshes=collection.getMesh();
98 CPPUNIT_ASSERT_EQUAL(5, (int) cellMeshes.size());
100 for (std::size_t i = 0; i < cellMeshes.size(); i++)
101 nbcells+=cellMeshes[i]->getNumberOfCells();
102 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
104 std::vector<MEDCoupling::MEDCouplingUMesh*>faceMeshes=collection.getFaceMesh();
105 CPPUNIT_ASSERT_EQUAL(5, (int) faceMeshes.size());
107 for (std::size_t i=0; i < faceMeshes.size(); i++)
108 nbfaces+=faceMeshes[i]->getNumberOfCells();
109 CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), nbfaces);
111 //merge split meshes and test equality
112 cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc
113 sourceName=targetName+".xml";
115 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
116 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
117 if (_verbose) cout<<endl<<cmd<<endl;
118 res=system(cmd.c_str());
119 CPPUNIT_ASSERT_EQUAL(0, res);
121 string refusedName=targetName+"1.med";
122 MEDCoupling::MEDFileUMesh* refusedMesh=MEDCoupling::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
123 MEDCoupling::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
124 MEDCoupling::MEDCouplingUMesh* refusedFaceMesh=refusedMesh->getLevelM1Mesh(false);
126 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
127 CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), refusedFaceMesh->getNumberOfCells());
130 MEDCoupling::MEDCouplingMesh* mergeCell=cellMesh->mergeMyselfWith(refusedCellMesh);
131 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), mergeCell->getNumberOfCells());
133 MEDCoupling::MEDCouplingMesh* mergeFace=faceMesh->mergeMyselfWith(refusedFaceMesh);
134 CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), mergeFace->getNumberOfCells());
136 CPPUNIT_ASSERT(faceMesh->isEqual(refusedFaceMesh,1e-12));
139 std::vector<const MEDCouplingUMesh *> meshes;
140 std::vector<DataArrayInt *> corr;
141 meshes.push_back(cellMesh);
142 refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9);
143 meshes.push_back(refusedCellMesh);
144 MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
145 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
148 for (std::size_t i = 0; i < corr.size(); i++)
151 meshes.push_back(faceMesh);
152 refusedFaceMesh->tryToShareSameCoordsPermute(*faceMesh, 1e-9);
153 meshes.push_back(refusedFaceMesh);
154 MEDCouplingUMesh* fusedFace=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
155 CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), fusedFace->getNumberOfCells());
157 for (std::size_t i = 0; i < corr.size(); i++)
159 fusedFace->decrRef();
160 refusedFaceMesh->decrRef();
162 fusedCell->decrRef();
163 refusedCellMesh->decrRef();
165 //done in ~collection
166 //for (int i = 0; i < faceMeshes.size(); i++) faceMeshes[i]->decrRef();
167 //for (int i = 0; i < cellMeshes.size(); i++) cellMeshes[i]->decrRef();
170 void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForFieldOnCells()
173 string fileName,cmd,execName,sourceName,targetName,input;
174 execName=getPartitionerParaExe();
176 fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnCells.med");
178 MEDCoupling::MEDFileUMesh* initialMesh=MEDCoupling::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
179 MEDCoupling::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
181 cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc
184 targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
185 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
186 if (_verbose) cout<<endl<<cmd<<endl;
187 res=system(cmd.c_str());
188 CPPUNIT_ASSERT_EQUAL(0, res);
189 input=targetName+".xml";
191 //merge split meshes and test equality
192 cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc
193 sourceName=targetName+".xml";
195 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
196 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
197 if (_verbose) cout<<endl<<cmd<<endl;
198 res=system(cmd.c_str());
199 CPPUNIT_ASSERT_EQUAL(0, res);
201 string refusedName=targetName+"1.med";
202 MEDCoupling::MEDFileUMesh* refusedMesh=MEDCoupling::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
203 MEDCoupling::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
205 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
207 std::vector<const MEDCouplingUMesh *> meshes;
208 std::vector<DataArrayInt *> corr;
209 meshes.push_back(cellMesh);
210 refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9);
211 meshes.push_back(refusedCellMesh);
212 MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
213 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
215 MEDCouplingFieldDouble* field1=ReadFieldCell(fileName.c_str(),initialMesh->getName().c_str(),0,"VectorFieldOnCells",0,1);
216 MEDCouplingFieldDouble* field2=ReadFieldCell(refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"VectorFieldOnCells",0,1);
218 int nbcells=corr[1]->getNumberOfTuples();
219 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
220 //use corr to test equality of field
221 DataArrayDouble* f1=field1->getArray();
222 DataArrayDouble* f2=field2->getArray();
225 cout<<"\nf1 : "<<f1->reprZip();
226 cout<<"\nf2 : "<<f2->reprZip(); //field2->advancedRepradvancedRepr();
227 for (std::size_t i = 0; i < corr.size(); i++)
228 cout << "\ncorr " << i << " : " << corr[i]->reprZip();
232 int nbcomp=field1->getNumberOfComponents();
233 double* p1=f1->getPointer();
234 double* p2=f2->getPointer();
235 int* pc=corr[1]->getPointer();
236 for (int i = 0; i < nbcells; i++)
240 for (int j = 0; j < nbcomp; j++)
242 if (p1[i1+j]==p2[i2+j]) nbequal++;
243 //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j];
246 CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp, nbequal);
248 for (std::size_t i = 0; i < corr.size(); i++)
252 fusedCell->decrRef();
253 refusedCellMesh->decrRef();
257 void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForFieldOnGaussNe()
260 string fileName,cmd,execName,sourceName,targetName,input;
261 execName=getPartitionerParaExe();
263 fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnGaussNe.med");
265 MEDCoupling::MEDFileUMesh* initialMesh=MEDCoupling::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
266 MEDCoupling::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
268 cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc
271 targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
272 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
273 if (_verbose) cout<<endl<<cmd<<endl;
274 res=system(cmd.c_str());
275 CPPUNIT_ASSERT_EQUAL(0, res);
276 input=targetName+".xml";
278 //merge split meshes and test equality
279 cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc
280 sourceName=targetName+".xml";
282 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
283 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
284 if (_verbose) cout<<endl<<cmd<<endl;
285 res=system(cmd.c_str());
286 CPPUNIT_ASSERT_EQUAL(0, res);
288 string refusedName=targetName+"1.med";
289 MEDCoupling::MEDFileUMesh* refusedMesh=MEDCoupling::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
290 MEDCoupling::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
292 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
294 std::vector<const MEDCouplingUMesh *> meshes;
295 std::vector<DataArrayInt *> corr;
296 meshes.push_back(cellMesh);
297 refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9);
298 meshes.push_back(refusedCellMesh);
299 MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
300 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
302 MEDCouplingFieldDouble* field1=ReadField(ON_GAUSS_NE,fileName.c_str(),initialMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6);
303 MEDCouplingFieldDouble* field2=ReadField(ON_GAUSS_NE,refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6);
305 int nbcells=corr[1]->getNumberOfTuples();
306 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
307 //use corr to test equality of field
308 DataArrayDouble* f1=field1->getArray();
309 DataArrayDouble* f2=field2->getArray();
312 cout << "\nf1 : " << f1->reprZip(); //123.4 for 12th cell,3rd component, 4th gausspoint
313 cout << "\nf2 : " << f2->reprZip(); //field2->advancedRepradvancedRepr();
314 for (std::size_t i = 0; i < corr.size(); i++)
315 cout << "\ncorr " << i << " : " << corr[i]->reprZip();
320 int nbcomp=field1->getNumberOfComponents();
321 double* p1=f1->getPointer();
322 double* p2=f2->getPointer();
323 int* pc=corr[1]->getPointer();
324 for (int i = 0; i < nbcells; i++)
326 int i1=pc[i]*nbcomp*nbptgauss;
327 int i2=i*nbcomp*nbptgauss;
328 for (int j = 0; j < nbcomp*nbptgauss; j++)
330 if (p1[i1+j]==p2[i2+j]) nbequal++;
331 //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j];
334 CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp*nbptgauss, nbequal);
336 for (std::size_t i = 0; i < corr.size(); i++)
340 fusedCell->decrRef();
341 refusedCellMesh->decrRef();
345 void MEDPARTITIONERTest::launchMedpartitionerOnTestMeshes()
349 export INFI=/home/vb144235/resources/blade.med
350 //no need export MESH=Fuse_1
351 export INFI=tmp_testMeshxxx.med
352 //no need export MESH=testMesh
353 mpirun -np 2 medpartitioner_para --input-file=$INFI --output-file=ttmp1_ --ndomains=4
354 mpirun -np 5 medpartitioner_para --input-file=ttmp1_.xml --output-file=ttmp2_ --ndomains=5
355 mpirun -np 2 valgrind medpartitioner_para --input-file=tmp_testMesh_20x30x50.med --output-file=ttmp1petit_ --ndomains=4 --dump-cpu-memory --verbose=111
358 string cmd,execName,sourceName,targetName;
360 res=system("which mpirun 2>/dev/null 1>/dev/null"); //no trace
361 CPPUNIT_ASSERT_EQUAL(0, res);
363 execName=getPartitionerParaExe();
365 cmd="which "+execName+" 2>/dev/null 1>/dev/null"; //no trace
366 res=system(cmd.c_str());
367 CPPUNIT_ASSERT_EQUAL(0, res);
369 cmd="mpirun -np 2 "+execName+" --ndomains=2 --split-method=metis"; //on same proc
370 sourceName=_file_name;
371 targetName=_file_name;
372 targetName.replace(targetName.find(".med"),4,"_partitionedTo2_");
373 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
374 if (_verbose) cout<<endl<<cmd<<endl;
375 res=system(cmd.c_str());
376 CPPUNIT_ASSERT_EQUAL(0, res);
378 cmd="mpirun -np 3 "+execName+" --ndomains=5 --split-method=metis"; //on less proc
379 sourceName=_file_name;
380 targetName=_file_name;
381 targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
382 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
383 if (_verbose) cout<<endl<<cmd<<endl;
384 res=system(cmd.c_str());
385 CPPUNIT_ASSERT_EQUAL(0, res);
387 cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on 1 proc
388 sourceName=targetName+".xml";
389 targetName=_file_name;
390 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
391 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
392 if (_verbose) cout<<endl<<cmd<<endl;
393 res=system(cmd.c_str());
394 CPPUNIT_ASSERT_EQUAL(0, res);
396 cmd="mpirun -np 8 "+execName+" --ndomains=1 --split-method=metis"; //on more proc
397 //sourceName=targetName+".xml";
398 targetName=_file_name;
399 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
400 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
401 if (_verbose) cout<<endl<<cmd<<endl;
402 res=system(cmd.c_str());
403 CPPUNIT_ASSERT_EQUAL(0, res);
406 void MEDPARTITIONERTest::launchMedpartitionerOnHugeTestMeshes()
409 string cmd,execName,sourceName,targetName;
410 execName=getPartitionerParaExe();
412 string snbTarget=IntToStr(_nb_target_huge);
413 cmd="mpirun -np "+snbTarget+" "+execName+" --ndomains="+snbTarget+" --split-method=metis"; //on same proc
414 sourceName=_file_name_huge_xml;
415 targetName=_file_name_huge_xml;
416 string tmp="_partitionedTo"+snbTarget+"_";
417 targetName.replace(targetName.find(".xml"),4,tmp);
418 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
419 if (_verbose) cout<<endl<<cmd<<endl;
420 res=system(cmd.c_str());
421 CPPUNIT_ASSERT_EQUAL(0, res);
424 void MEDPARTITIONERTest::testMpirunSmallSize()
428 launchMedpartitionerOnTestMeshes();
429 verifyMedpartitionerOnSmallSizeForMesh();
430 verifyMedpartitionerOnSmallSizeForFieldOnCells();
431 verifyMedpartitionerOnSmallSizeForFieldOnGaussNe();
434 void MEDPARTITIONERTest::testMpirunMedianSize()
438 launchMedpartitionerOnTestMeshes();
441 void MEDPARTITIONERTest::testMpirunHugeSize()
443 //setBigSize(); //may be a lot for now
445 //create a set of nbx*nby*nbz files mesh of ni*ny*nz cells
447 createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //it is now to know how far we are going to test
448 launchMedpartitionerOnHugeTestMeshes();