1 // Copyright (C) 2007-2015 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 std::string MEDPARTITIONERTest::getPartitionerParaExe() const
56 if ( getenv("MEDCOUPLING_ROOT_DIR") )
58 execName=getenv("MEDCOUPLING_ROOT_DIR"); //.../INSTALL/MED
59 execName+="/bin/medpartitioner_para";
63 execName = get_current_dir_name();
64 execName += "/../../MEDPartitioner/medpartitioner_para";
65 if (! std::ifstream(execName.c_str()))
66 CPPUNIT_FAIL("Can't find medpartitioner_para, please set MEDCOUPLING_ROOT_DIR");
71 void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForMesh()
74 string fileName,cmd,execName,sourceName,targetName,input;
75 execName=getPartitionerParaExe();
76 fileName=_file_name_with_faces;
78 ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
79 ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
80 ParaMEDMEM::MEDCouplingUMesh* faceMesh=initialMesh->getLevelM1Mesh(false);
82 cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc
85 targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
86 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
87 if (_verbose) cout<<endl<<cmd<<endl;
88 res=system(cmd.c_str());
89 CPPUNIT_ASSERT_EQUAL(0, res);
90 input=targetName+".xml";
92 MEDPARTITIONER::ParaDomainSelector parallelizer(false);
93 MEDPARTITIONER::MeshCollection collection(input,parallelizer);
94 CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension());
95 std::vector<ParaMEDMEM::MEDCouplingUMesh*>cellMeshes=collection.getMesh();
96 CPPUNIT_ASSERT_EQUAL(5, (int) cellMeshes.size());
98 for (std::size_t i = 0; i < cellMeshes.size(); i++)
99 nbcells+=cellMeshes[i]->getNumberOfCells();
100 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
102 std::vector<ParaMEDMEM::MEDCouplingUMesh*>faceMeshes=collection.getFaceMesh();
103 CPPUNIT_ASSERT_EQUAL(5, (int) faceMeshes.size());
105 for (std::size_t i=0; i < faceMeshes.size(); i++)
106 nbfaces+=faceMeshes[i]->getNumberOfCells();
107 CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), nbfaces);
109 //merge split meshes and test equality
110 cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc
111 sourceName=targetName+".xml";
113 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
114 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
115 if (_verbose) cout<<endl<<cmd<<endl;
116 res=system(cmd.c_str());
117 CPPUNIT_ASSERT_EQUAL(0, res);
119 string refusedName=targetName+"1.med";
120 ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
121 ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
122 ParaMEDMEM::MEDCouplingUMesh* refusedFaceMesh=refusedMesh->getLevelM1Mesh(false);
124 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
125 CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), refusedFaceMesh->getNumberOfCells());
128 ParaMEDMEM::MEDCouplingMesh* mergeCell=cellMesh->mergeMyselfWith(refusedCellMesh);
129 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), mergeCell->getNumberOfCells());
131 ParaMEDMEM::MEDCouplingMesh* mergeFace=faceMesh->mergeMyselfWith(refusedFaceMesh);
132 CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), mergeFace->getNumberOfCells());
134 CPPUNIT_ASSERT(faceMesh->isEqual(refusedFaceMesh,1e-12));
137 std::vector<const MEDCouplingUMesh *> meshes;
138 std::vector<DataArrayInt *> corr;
139 meshes.push_back(cellMesh);
140 refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9);
141 meshes.push_back(refusedCellMesh);
142 MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
143 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
146 for (std::size_t i = 0; i < corr.size(); i++)
149 meshes.push_back(faceMesh);
150 refusedFaceMesh->tryToShareSameCoordsPermute(*faceMesh, 1e-9);
151 meshes.push_back(refusedFaceMesh);
152 MEDCouplingUMesh* fusedFace=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
153 CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), fusedFace->getNumberOfCells());
155 for (std::size_t i = 0; i < corr.size(); i++)
157 fusedFace->decrRef();
158 refusedFaceMesh->decrRef();
160 fusedCell->decrRef();
161 refusedCellMesh->decrRef();
163 //done in ~collection
164 //for (int i = 0; i < faceMeshes.size(); i++) faceMeshes[i]->decrRef();
165 //for (int i = 0; i < cellMeshes.size(); i++) cellMeshes[i]->decrRef();
168 void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForFieldOnCells()
171 string fileName,cmd,execName,sourceName,targetName,input;
172 execName=getPartitionerParaExe();
174 fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnCells.med");
176 ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
177 ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
179 cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc
182 targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
183 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
184 if (_verbose) cout<<endl<<cmd<<endl;
185 res=system(cmd.c_str());
186 CPPUNIT_ASSERT_EQUAL(0, res);
187 input=targetName+".xml";
189 //merge split meshes and test equality
190 cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc
191 sourceName=targetName+".xml";
193 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
194 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
195 if (_verbose) cout<<endl<<cmd<<endl;
196 res=system(cmd.c_str());
197 CPPUNIT_ASSERT_EQUAL(0, res);
199 string refusedName=targetName+"1.med";
200 ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
201 ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
203 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
205 std::vector<const MEDCouplingUMesh *> meshes;
206 std::vector<DataArrayInt *> corr;
207 meshes.push_back(cellMesh);
208 refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9);
209 meshes.push_back(refusedCellMesh);
210 MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
211 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
213 MEDCouplingFieldDouble* field1=MEDLoader::ReadFieldCell(fileName.c_str(),initialMesh->getName().c_str(),0,"VectorFieldOnCells",0,1);
214 MEDCouplingFieldDouble* field2=MEDLoader::ReadFieldCell(refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"VectorFieldOnCells",0,1);
216 int nbcells=corr[1]->getNumberOfTuples();
217 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
218 //use corr to test equality of field
219 DataArrayDouble* f1=field1->getArray();
220 DataArrayDouble* f2=field2->getArray();
223 cout<<"\nf1 : "<<f1->reprZip();
224 cout<<"\nf2 : "<<f2->reprZip(); //field2->advancedRepradvancedRepr();
225 for (std::size_t i = 0; i < corr.size(); i++)
226 cout << "\ncorr " << i << " : " << corr[i]->reprZip();
230 int nbcomp=field1->getNumberOfComponents();
231 double* p1=f1->getPointer();
232 double* p2=f2->getPointer();
233 int* pc=corr[1]->getPointer();
234 for (int i = 0; i < nbcells; i++)
238 for (int j = 0; j < nbcomp; j++)
240 if (p1[i1+j]==p2[i2+j]) nbequal++;
241 //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j];
244 CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp, nbequal);
246 for (std::size_t i = 0; i < corr.size(); i++)
250 fusedCell->decrRef();
251 refusedCellMesh->decrRef();
255 void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForFieldOnGaussNe()
258 string fileName,cmd,execName,sourceName,targetName,input;
259 execName=getPartitionerParaExe();
261 fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnGaussNe.med");
263 ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
264 ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
266 cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc
269 targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
270 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
271 if (_verbose) cout<<endl<<cmd<<endl;
272 res=system(cmd.c_str());
273 CPPUNIT_ASSERT_EQUAL(0, res);
274 input=targetName+".xml";
276 //merge split meshes and test equality
277 cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc
278 sourceName=targetName+".xml";
280 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
281 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
282 if (_verbose) cout<<endl<<cmd<<endl;
283 res=system(cmd.c_str());
284 CPPUNIT_ASSERT_EQUAL(0, res);
286 string refusedName=targetName+"1.med";
287 ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
288 ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
290 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
292 std::vector<const MEDCouplingUMesh *> meshes;
293 std::vector<DataArrayInt *> corr;
294 meshes.push_back(cellMesh);
295 refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9);
296 meshes.push_back(refusedCellMesh);
297 MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
298 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
300 MEDCouplingFieldDouble* field1=MEDLoader::ReadField(ON_GAUSS_NE,fileName.c_str(),initialMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6);
301 MEDCouplingFieldDouble* field2=MEDLoader::ReadField(ON_GAUSS_NE,refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6);
303 int nbcells=corr[1]->getNumberOfTuples();
304 CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
305 //use corr to test equality of field
306 DataArrayDouble* f1=field1->getArray();
307 DataArrayDouble* f2=field2->getArray();
310 cout << "\nf1 : " << f1->reprZip(); //123.4 for 12th cell,3rd component, 4th gausspoint
311 cout << "\nf2 : " << f2->reprZip(); //field2->advancedRepradvancedRepr();
312 for (std::size_t i = 0; i < corr.size(); i++)
313 cout << "\ncorr " << i << " : " << corr[i]->reprZip();
318 int nbcomp=field1->getNumberOfComponents();
319 double* p1=f1->getPointer();
320 double* p2=f2->getPointer();
321 int* pc=corr[1]->getPointer();
322 for (int i = 0; i < nbcells; i++)
324 int i1=pc[i]*nbcomp*nbptgauss;
325 int i2=i*nbcomp*nbptgauss;
326 for (int j = 0; j < nbcomp*nbptgauss; j++)
328 if (p1[i1+j]==p2[i2+j]) nbequal++;
329 //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j];
332 CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp*nbptgauss, nbequal);
334 for (std::size_t i = 0; i < corr.size(); i++)
338 fusedCell->decrRef();
339 refusedCellMesh->decrRef();
343 void MEDPARTITIONERTest::launchMedpartitionerOnTestMeshes()
347 export INFI=/home/vb144235/resources/blade.med
348 //no need export MESH=Fuse_1
349 export INFI=tmp_testMeshxxx.med
350 //no need export MESH=testMesh
351 mpirun -np 2 medpartitioner_para --input-file=$INFI --output-file=ttmp1_ --ndomains=4
352 mpirun -np 5 medpartitioner_para --input-file=ttmp1_.xml --output-file=ttmp2_ --ndomains=5
353 mpirun -np 2 valgrind medpartitioner_para --input-file=tmp_testMesh_20x30x50.med --output-file=ttmp1petit_ --ndomains=4 --dump-cpu-memory --verbose=111
356 string cmd,execName,sourceName,targetName;
358 res=system("which mpirun 2>/dev/null 1>/dev/null"); //no trace
359 CPPUNIT_ASSERT_EQUAL(0, res);
361 execName=getPartitionerParaExe();
363 cmd="which "+execName+" 2>/dev/null 1>/dev/null"; //no trace
364 res=system(cmd.c_str());
365 CPPUNIT_ASSERT_EQUAL(0, res);
367 cmd="mpirun -np 2 "+execName+" --ndomains=2 --split-method=metis"; //on same proc
368 sourceName=_file_name;
369 targetName=_file_name;
370 targetName.replace(targetName.find(".med"),4,"_partitionedTo2_");
371 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
372 if (_verbose) cout<<endl<<cmd<<endl;
373 res=system(cmd.c_str());
374 CPPUNIT_ASSERT_EQUAL(0, res);
376 cmd="mpirun -np 3 "+execName+" --ndomains=5 --split-method=metis"; //on less proc
377 sourceName=_file_name;
378 targetName=_file_name;
379 targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
380 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
381 if (_verbose) cout<<endl<<cmd<<endl;
382 res=system(cmd.c_str());
383 CPPUNIT_ASSERT_EQUAL(0, res);
385 cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on 1 proc
386 sourceName=targetName+".xml";
387 targetName=_file_name;
388 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
389 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
390 if (_verbose) cout<<endl<<cmd<<endl;
391 res=system(cmd.c_str());
392 CPPUNIT_ASSERT_EQUAL(0, res);
394 cmd="mpirun -np 8 "+execName+" --ndomains=1 --split-method=metis"; //on more proc
395 //sourceName=targetName+".xml";
396 targetName=_file_name;
397 targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
398 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
399 if (_verbose) cout<<endl<<cmd<<endl;
400 res=system(cmd.c_str());
401 CPPUNIT_ASSERT_EQUAL(0, res);
404 void MEDPARTITIONERTest::launchMedpartitionerOnHugeTestMeshes()
407 string cmd,execName,sourceName,targetName;
408 execName=getPartitionerParaExe();
410 string snbTarget=IntToStr(_nb_target_huge);
411 cmd="mpirun -np "+snbTarget+" "+execName+" --ndomains="+snbTarget+" --split-method=metis"; //on same proc
412 sourceName=_file_name_huge_xml;
413 targetName=_file_name_huge_xml;
414 string tmp="_partitionedTo"+snbTarget+"_";
415 targetName.replace(targetName.find(".xml"),4,tmp);
416 cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
417 if (_verbose) cout<<endl<<cmd<<endl;
418 res=system(cmd.c_str());
419 CPPUNIT_ASSERT_EQUAL(0, res);
422 void MEDPARTITIONERTest::testMpirunSmallSize()
426 launchMedpartitionerOnTestMeshes();
427 verifyMedpartitionerOnSmallSizeForMesh();
428 verifyMedpartitionerOnSmallSizeForFieldOnCells();
429 verifyMedpartitionerOnSmallSizeForFieldOnGaussNe();
432 void MEDPARTITIONERTest::testMpirunMedianSize()
436 launchMedpartitionerOnTestMeshes();
439 void MEDPARTITIONERTest::testMpirunHugeSize()
441 //setBigSize(); //may be a lot for now
443 //create a set of nbx*nby*nbz files mesh of ni*ny*nz cells
445 createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //it is now to know how far we are going to test
446 launchMedpartitionerOnHugeTestMeshes();