Salome HOME
1a377236333fa069aaaafc4779fb85d3bc5f99e8
[tools/medcoupling.git] / src / MEDPartitioner / Test / MEDPARTITIONERTest.cxx
1 // Copyright (C) 2007-2012  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
20 #include "MEDPARTITIONERTest.hxx"
21
22 #include "MEDPARTITIONER_MeshCollection.hxx"
23 #include "MEDPARTITIONER_ParallelTopology.hxx"
24 #include "MEDPARTITIONER_ParaDomainSelector.hxx"
25 #include "MEDPARTITIONER_Utils.hxx"
26
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"
36
37 #include <cppunit/TestAssert.h>
38
39 #include <sstream>
40 #include <cmath>
41 #include <list>
42 #include <stdexcept>
43 #include <cstdlib>
44 #include <vector>
45
46 #ifdef HAVE_MPI2
47 #include <mpi.h>
48 #endif
49
50 using namespace std;
51 using namespace ParaMEDMEM;
52 using namespace MEDPARTITIONER;
53
54 void MEDPARTITIONERTest::setSize(int ni, int nj, int nk)
55 {
56   this->_ni=ni;  //nb of hexa9
57   this->_nj=nj;
58   this->_nk=nk;
59   this->_ntot=_ni*_nj*_nk;
60   string ijk=IntToStr(ni)+"x"+IntToStr(nj)+"x"+IntToStr(nk);
61   this->_file_name="tmp_testMesh_"+ijk+".med";
62   this->_file_name_with_faces="tmp_testMeshWithFaces_"+ijk+".med";
63   string ij=IntToStr(ni)+"x"+IntToStr(nj);
64   this->_file_name2="tmp_testMesh_"+ij+".med";
65   this->_mesh_name="testMesh";
66 }
67
68 void MEDPARTITIONERTest::setSmallSize()
69 {
70   setSize(2,3,5); //nb of hexa9
71 }
72
73 void MEDPARTITIONERTest::setMedianSize()
74 {
75   setSize(20,30,50); //nb of hexa9
76 }
77
78 void MEDPARTITIONERTest::setbigSize()
79 {
80   setSize(200,300,500); //nb of hexa9
81 }
82
83 std::string MEDPARTITIONERTest::getPartitionerExe() const
84 {
85   std::string execName;
86   if ( getenv("top_builddir")) // make distcheck
87     {
88       execName = getenv("top_builddir");
89       execName += "/src/MEDPartitioner/medpartitioner";
90     }
91   else if ( getenv("MED_ROOT_DIR") )
92     {
93       execName=getenv("MED_ROOT_DIR");  //.../INSTALL/MED
94       execName+="/bin/salome/medpartitioner";
95     }
96   else
97     {
98       CPPUNIT_FAIL("Can't find medpartitioner, neither MED_ROOT_DIR nor top_builddir is set");
99     }
100   return execName;
101 }
102
103 // ============================================================================
104 /*!
105  *  Set up the environment called at every CPPUNIT_TEST ()
106  */
107 // ============================================================================
108 void MEDPARTITIONERTest::setUp()
109 {
110   this->_verbose=0;
111 #if defined(HAVE_MPI2)
112   if (MyGlobals::_Rank==-1)  //do once only
113     {
114       MPI_Init(0,0);
115       MPI_Comm_size(MPI_COMM_WORLD, &MyGlobals::_World_Size);
116       MPI_Comm_rank(MPI_COMM_WORLD, &MyGlobals::_Rank);
117     }
118 #else
119   //sequential : no MPI
120   MyGlobals::_World_Size=1;
121   MyGlobals::_Rank=0;
122 #endif
123
124   if (_verbose>10)
125     {
126 #if defined(HAVE_MPI2)
127       cout<<"\ndefined(HAVE_MPI2)"<<endl;
128 #else
129       cout<<"\nNOT defined(HAVE_MPI2)"<<endl;
130 #endif
131 #if defined(MED_ENABLE_PARMETIS)
132       cout<<"defined(MED_ENABLE_PARMETIS)"<<endl;
133 #else
134       cout<<"NOT defined(MED_ENABLE_PARMETIS)"<<endl;
135 #endif
136 #if defined(MED_ENABLE_METIS)
137       cout<<"defined(MED_ENABLE_METIS)"<<endl;
138 #else
139       cout<<"NOT defined(MED_ENABLE_METIS)"<<endl;
140 #endif
141 #if defined(MED_ENABLE_SCOTCH)
142       cout<<"defined(MED_ENABLE_SCOTCH)"<<endl;
143 #else
144       cout<<"NOT defined(MED_ENABLE_SCOTCH)"<<endl;
145 #endif
146     }
147 }
148
149 // ============================================================================
150 /*!
151  *  - delete
152  */
153 // ============================================================================
154 void MEDPARTITIONERTest::tearDown()
155 {
156 }
157
158 ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildCUBE3DMesh()
159 //only hexa8
160 {
161   vector<int> conn;
162   vector<double> coor;
163   for (int k=0; k<=_nk; k++)
164     for (int j=0; j<=_nj; j++)
165       for (int i=0; i<=_ni; i++)
166         {
167           coor.push_back(i+.1);
168           coor.push_back(j+.2);
169           coor.push_back(k+.3);
170         }
171   int ii;
172   for (int k=0; k<_nk; k++)
173     for (int j=0; j<_nj; j++)
174       for (int i=0; i<_ni; i++)
175         {
176           ii=i + j*(_ni+1) + k*(_ni+1)*(_nj+1);
177           conn.push_back(ii);
178           conn.push_back(ii+1);
179           ii=ii + _ni + 2 ;
180           conn.push_back(ii);
181           conn.push_back(ii-1);
182     
183           ii=i + j*(_ni+1) + (k+1)*(_ni+1)*(_nj+1);
184           conn.push_back(ii);
185           conn.push_back(ii+1);
186           ii=ii + _ni + 2 ;
187           conn.push_back(ii);
188           conn.push_back(ii-1);
189         }
190
191   /*
192   if (_verbose)  //only for debug
193     {
194       cout<< "\nnb coor " << (_ni+1)*(_nj+1)*(_nk+1)*3 << " " << coor.size() << endl;
195       for (int i=0; i<(int)coor.size(); i++)
196         cout << coor[i] << " ";
197       cout << endl;
198       cout << "\nnb conn " << (_ni)*(_nj)*(_nk)*8 << " " << conn.size() << endl;
199       for (int i=0; i<(int)conn.size(); i=i+8)
200         { 
201           for (int j=0; j<8; j++)
202             cout << conn[i+j] << " ";
203           cout << endl;
204         }
205       cout << endl;
206     }
207   */
208   
209   MEDCouplingUMesh *mesh=MEDCouplingUMesh::New();
210   mesh->setMeshDimension(3);
211   int nbc=conn.size()/8; //nb of cells
212   int nbv=coor.size()/3; //nb of vertices
213   mesh->allocateCells(nbc);
214   for(int i=0; i<nbc; i++)
215     {
216       int onehexa[8];
217       std::copy(conn.begin()+i*8,conn.begin()+(i+1)*8,onehexa);
218       if (false) //(_verbose)
219         {
220           for (int j=0; j<8; j++) cout<<onehexa[j]<<" ";
221           cout<<endl;
222         }
223       mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,onehexa);
224     }
225   mesh->finishInsertingCells();
226   DataArrayDouble *myCoords=DataArrayDouble::New();
227   myCoords->alloc(nbv,3);
228   std::copy(coor.begin(),coor.end(),myCoords->getPointer());
229   mesh->setCoords(myCoords);
230   mesh->setName(_mesh_name.c_str());
231   myCoords->decrRef();
232   mesh->checkCoherency();
233   return mesh;
234 }
235
236 ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildCARRE3DMesh()
237 //only quad4 in oblique (k=j)
238 {
239   vector<int> conn;
240   vector<double> coor;
241   for (int j=0; j<=_nj; j++)
242     for (int i=0; i<=_ni; i++)
243       {
244         int k=j;
245         coor.push_back(i+.1);
246         coor.push_back(j+.2);
247         coor.push_back(k+.3);
248       }
249   int ii;
250   int k=0;
251   for (int j=0; j<_nj; j++)
252     for (int i=0; i<_ni; i++)
253       {
254         ii=i + j*(_ni+1) + k*(_ni+1)*(_nj+1);
255         conn.push_back(ii);
256         conn.push_back(ii+1);
257         ii=ii + _ni + 2 ;
258         conn.push_back(ii);
259         conn.push_back(ii-1);
260       }
261
262   if (false) //(_verbose)
263     {
264       cout<<"\nnb coor "<<(_ni+1)*(_nj+1)*3<<" "<<coor.size()<<endl;
265       for (int i=0; i<(int)coor.size(); i++)
266         cout << coor[i] << " ";
267       cout<<endl;
268       cout<<"\nnb conn "<<(_ni)*(_nj)*4<<" "<<conn.size()<<endl;
269       for (int i=0; i<(int)conn.size(); i=i+4)
270         { 
271           for (int j=0; j<4; j++) cout<<conn[i+j]<<" ";
272           cout<<endl;
273         }
274       cout<<endl;
275     }
276   
277   MEDCouplingUMesh *mesh=MEDCouplingUMesh::New();
278   mesh->setMeshDimension(2);
279   int nbc=conn.size()/4; //nb of cells
280   int nbv=coor.size()/3; //nb of vertices
281   mesh->allocateCells(nbc);
282   for(int i=0; i<nbc; i++)
283     {
284       int onequa[4];
285       std::copy(conn.begin()+i*4,conn.begin()+(i+1)*4,onequa);
286       if (false) //(_verbose)
287         {
288           for (int j=0; j<4; j++) cout<<onequa[j]<<" ";
289           cout<<endl;
290         }
291       mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,onequa);
292     }
293   mesh->finishInsertingCells();
294   DataArrayDouble *myCoords=DataArrayDouble::New();
295   myCoords->alloc(nbv,3);
296   std::copy(coor.begin(),coor.end(),myCoords->getPointer());
297   mesh->setCoords(myCoords);
298   mesh->setName(_mesh_name.c_str());
299   myCoords->decrRef();
300   mesh->checkCoherency();
301   return mesh;
302 }
303
304 ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildFACE3DMesh()
305 //only quad4 on a global face of the CUBE3D (k=0)
306 {
307   vector<int> conn;
308   vector<double> coor;
309   for (int j=0; j<=_nj; j++)
310     for (int i=0; i<=_ni; i++)
311       {
312         int k=0;
313         coor.push_back(i+.1);
314         coor.push_back(j+.2);
315         coor.push_back(k+.3);
316       }
317   int ii;
318   int k=0;
319   for (int j=0; j<_nj; j++)
320     for (int i=0; i<_ni; i++)
321       {
322         ii=i + j*(_ni+1) + k*(_ni+1)*(_nj+1);
323         conn.push_back(ii);
324         conn.push_back(ii+1);
325         ii=ii + _ni + 2 ;
326         conn.push_back(ii);
327         conn.push_back(ii-1);
328       }
329
330   if (false) //(_verbose)
331     {
332       cout<<"\nnb coor "<<(_ni+1)*(_nj+1)*3<<" "<<coor.size()<<endl;
333       for (int i=0; i<(int)coor.size(); i++)
334         cout << coor[i] << " ";
335       cout<<endl;
336       cout<<"\nnb conn "<<(_ni)*(_nj)*4<<" "<<conn.size()<<endl;
337       for (int i=0; i<(int)conn.size(); i=i+4)
338         { 
339           for (int j=0; j<4; j++)
340             cout << conn[i+j] << " ";
341           cout << endl;
342         }
343       cout << endl;
344     }
345   
346   MEDCouplingUMesh *mesh=MEDCouplingUMesh::New();
347   mesh->setMeshDimension(2);
348   int nbc=conn.size()/4; //nb of cells
349   int nbv=coor.size()/3; //nb of vertices
350   mesh->allocateCells(nbc);
351   for(int i=0; i<nbc; i++)
352     {
353       int onequa[4];
354       std::copy(conn.begin()+i*4,conn.begin()+(i+1)*4,onequa);
355       if (false) //(_verbose)
356         {
357           for (int j=0; j<4; j++) cout<<onequa[j]<<" ";
358           cout<<endl;
359         }
360       mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,onequa);
361     }
362   mesh->finishInsertingCells();
363   DataArrayDouble *myCoords=DataArrayDouble::New();
364   myCoords->alloc(nbv,3);
365   std::copy(coor.begin(),coor.end(),myCoords->getPointer());
366   mesh->setCoords(myCoords);
367   mesh->setName(_mesh_name.c_str());
368   myCoords->decrRef();
369   mesh->checkCoherency();
370   return mesh;
371 }
372
373 MEDCouplingFieldDouble * MEDPARTITIONERTest::buildVecFieldOnCells(string myfileName)
374 {
375   //int ni=2,nj=3,nk=5; //nb of hexa9
376   vector<double> field;
377   for (int k=0; k<_nk; k++)
378     for (int j=0; j<_nj; j++)
379       for (int i=0; i<_ni; i++)
380         {
381           field.push_back(i+.1);
382           field.push_back(j+.2);
383           field.push_back(k+.3);
384         }
385
386   MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(myfileName.c_str(),_mesh_name.c_str(),0);
387   int nbOfCells=mesh->getNumberOfCells();
388   MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
389   f1->setName("VectorFieldOnCells");
390   f1->setDescription("DescriptionOfFieldOnCells"); //not saved in file?
391   f1->setMesh(mesh);
392   DataArrayDouble *myField=DataArrayDouble::New();
393   myField->alloc(nbOfCells,3);
394   std::copy(field.begin(),field.end(),myField->getPointer());
395   f1->setArray(myField);
396   myField->setInfoOnComponent(0,"vx");
397   myField->setInfoOnComponent(1,"vy");
398   myField->setInfoOnComponent(2,"vz");
399   myField->decrRef();
400   f1->setTime(2.,0,1);
401   f1->checkCoherency();
402   mesh->decrRef();
403   return f1;
404 }
405
406 MEDCouplingFieldDouble * MEDPARTITIONERTest::buildVecFieldOnNodes()
407 {
408   //int ni=2,nj=3,nk=5; //nb of hexa9
409   vector<double> field;
410   for (int k=0; k<=_nk; k++)
411     for (int j=0; j<=_nj; j++)
412       for (int i=0; i<=_ni; i++)
413         {
414           field.push_back(i+.1);
415           field.push_back(j+.2);
416           field.push_back(k+.3);
417         }
418   
419   MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(_file_name.c_str(),_mesh_name.c_str(),0);
420   int nbOfNodes=mesh->getNumberOfNodes();
421   MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME);
422   f1->setName("VectorFieldOnNodes");
423   f1->setDescription("DescriptionOfFieldOnNodes"); //not saved in file?
424   f1->setMesh(mesh);
425   DataArrayDouble *myField=DataArrayDouble::New();
426   myField->alloc(nbOfNodes,3);
427   std::copy(field.begin(),field.end(),myField->getPointer());
428   f1->setArray(myField);
429   myField->setInfoOnComponent(0,"vx");
430   myField->setInfoOnComponent(1,"vy");
431   myField->setInfoOnComponent(2,"vz");
432   myField->decrRef();
433   f1->setTime(2.,0,1);
434   f1->checkCoherency();
435   mesh->decrRef();
436   return f1;
437 }
438
439
440 void MEDPARTITIONERTest::createTestMeshWithoutField()
441 {
442   {
443     MEDCouplingUMesh * mesh = buildCUBE3DMesh();
444     MEDLoader::WriteUMesh(_file_name.c_str(),mesh,true);
445     if (_verbose) cout<<endl<<_file_name<<" created"<<endl;
446     if (_ntot<1000000) //too long
447       {
448         MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name.c_str(),mesh->getName(),0);
449         if (_verbose) cout<<_file_name<<" reread"<<endl;
450         CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12));
451         mesh_rw->decrRef();
452       }
453     mesh->decrRef();
454   }
455   
456   {
457     vector<const ParaMEDMEM::MEDCouplingUMesh*> meshes;
458     MEDCouplingUMesh * mesh1 = buildCUBE3DMesh();
459     MEDCouplingUMesh * mesh2 = buildFACE3DMesh();
460     mesh1->setName("testMesh");
461     mesh2->setName("theFaces");
462     mesh2->tryToShareSameCoordsPermute(*mesh1, 1e-9);
463     mesh2->checkCoherency();
464     mesh1->checkCoherency();
465     meshes.push_back(mesh1);
466     meshes.push_back(mesh2);
467     MEDLoader::WriteUMeshes(_file_name_with_faces.c_str(), meshes, true);
468   
469     ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(_file_name_with_faces.c_str(), mesh1->getName());
470     DataArrayInt* FacesFam=DataArrayInt::New();
471     FacesFam->alloc(mfm->getSizeAtLevel(-1),1);
472     FacesFam->fillWithValue(-1);
473     DataArrayInt* CellsFam=DataArrayInt::New();
474     CellsFam->alloc(mfm->getSizeAtLevel(0),1);
475     CellsFam->fillWithValue(1);
476     mfm->setFamilyFieldArr(-1,FacesFam);
477     mfm->setFamilyFieldArr(0,CellsFam);
478     map<string,int> theFamilies;
479     theFamilies["FAMILLE_ZERO"]=0;
480     theFamilies["FamilyFaces"]=-1;
481     theFamilies["FamilyCells"]=1;
482     map<string, vector<string> > theGroups;
483     theGroups["GroupFaces"].push_back("FamilyFaces");
484     theGroups["GroupCells"].push_back("FamilyCells");
485     mfm->setFamilyInfo(theFamilies);
486     mfm->setGroupInfo(theGroups);
487     mfm->write(_file_name_with_faces.c_str(),0);
488     FacesFam->decrRef();
489     CellsFam->decrRef();
490   
491     /*ce truc marche pas!
492       ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(_file_name_with_faces.c_str(), mesh1->getName());
493       vector<const ParaMEDMEM::MEDCouplingUMesh*> ms;
494       ms.push_back(mesh2);
495       mfm->setGroupsFromScratch(-1, ms);
496       mfm->write(_file_name_with_faces.c_str(),0);
497     */
498   
499     if (_verbose) cout<<endl<<_file_name_with_faces<<" created"<<endl;
500     if (_ntot<1000000) //too long
501       {
502         MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name_with_faces.c_str(),mesh1->getName(),0);
503         if (_verbose) cout<<_file_name_with_faces<<" reread"<<endl;
504         CPPUNIT_ASSERT(mesh1->isEqual(mesh_rw,1e-12));
505         mesh_rw->decrRef();
506       }
507     mesh1->decrRef();
508     mesh2->decrRef();
509   }
510    
511   {
512     MEDCouplingUMesh * mesh = buildCARRE3DMesh();
513     MEDLoader::WriteUMesh(_file_name2.c_str(),mesh,true);
514     if (_verbose) cout<<endl<<_file_name2<<" created"<<endl;
515     MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name2.c_str(),mesh->getName(),0);
516     if (_verbose) cout<<_file_name2<<" reread"<<endl;
517     CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12));
518     mesh_rw->decrRef();
519     mesh->decrRef();
520   }
521 }
522
523 /*
524 create a set of nbx*nby*nbz files mesh of ni*ny*nz cells
525 */
526 void MEDPARTITIONERTest::createHugeTestMesh(int ni, int nj, int nk, int nbx, int nby, int nbz, int nbTarget)
527 {
528   setSize(ni,nj,nk);
529   _nb_target_huge=nbTarget;
530   MEDCouplingUMesh * mesh = buildCUBE3DMesh();
531   //int nbx=1, nby=1, nbz=2;
532   std::vector< double > cooDep,cooFin;
533   mesh->getCoordinatesOfNode(0, cooDep);
534   mesh->getCoordinatesOfNode(mesh->getNumberOfNodes()-1, cooFin);
535   //cout<<endl<<cooDep[0]<<" "<<cooDep[1]<<" "<<cooDep[2]<<endl;
536   //cout<<cooFin[0]<<" "<<cooFin[1]<<" "<<cooFin[2]<<endl;
537
538   string tagXml="\
539 <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n \
540 <root>\n \
541   <version maj=\"2\" min=\"3\" ver=\"1\"/>\n \
542   <description what=\"\" when=\"YYMMDDHHmm\"/>\n \
543   <content>\n \
544     <mesh name=\"testMesh\"/>\n \
545   </content>\n \
546   <splitting>\n \
547     <subdomain number=\"$subdomainNumber\"/>\n \
548     <global_numbering present=\"no\"/>\n \
549   </splitting>\n \
550   <files>\n$tagSubfile \
551   </files>\n \
552   <mapping>\n$tagMesh \
553   </mapping>\n \
554 </root>\n";
555   
556   string tagSubfiles, tagSubfile="\
557     <subfile id=\"$xyz\">\n \
558       <name>$fileName</name>\n \
559       <machine>localhost</machine>\n \
560     </subfile>\n";
561   string tagMeshes, tagMesh="\
562     <mesh name=\"testMesh\">\n \
563       <chunk subdomain=\"$xyz\">\n \
564         <name>testMesh</name>\n \
565       </chunk>\n \
566     </mesh>\n";
567   
568   int xyz=1;
569   string sxyz;
570   DataArrayDouble* coordsInit=mesh->getCoords()->deepCpy();
571   double* ptrInit=coordsInit->getPointer();
572   double deltax=cooFin[0]-cooDep[0];
573   double deltay=cooFin[1]-cooDep[1];
574   double deltaz=cooFin[2]-cooDep[2];
575   
576   double dz=0.;
577   for (int z=0; z<nbz; z++)
578     {
579       double dy=0.;
580       for (int y=0; y<nby; y++)
581         {
582           double dx=0.;
583           for (int x=0; x<nbx; x++)
584             {
585               string fileName;
586               sxyz=IntToStr(xyz);
587               fileName="tmp_testMeshHuge_"+IntToStr(_ni)+"x"+IntToStr(_nj)+"x"+IntToStr(_nk)+"_"+sxyz+".med";
588         
589               DataArrayDouble* coords=mesh->getCoords();
590               //int nbOfComp=coords->getNumberOfComponents();  //be 3D
591               int nbOfTuple=coords->getNumberOfTuples();
592               double* ptr=coords->getPointer();
593               double* ptrini=ptrInit;
594               for (int i=0; i<nbOfTuple; i++)
595                 {
596                   *ptr=(*ptrini)+dx; ptr++; ptrini++; //be 3D
597                   *ptr=(*ptrini)+dy; ptr++; ptrini++;
598                   *ptr=(*ptrini)+dz; ptr++; ptrini++;
599                 }
600
601               MEDLoader::WriteUMesh(fileName.c_str(),mesh,true);
602         
603               tagSubfiles+=tagSubfile;
604               tagSubfiles.replace(tagSubfiles.find("$xyz"),4,sxyz);
605               tagSubfiles.replace(tagSubfiles.find("$fileName"),9,fileName);
606         
607               tagMeshes+=tagMesh;
608               tagMeshes.replace(tagMeshes.find("$xyz"),4,sxyz);
609               xyz++;
610               dx+=deltax;
611             }
612           dy+=deltay;
613         }
614       dz+=deltaz;
615     }
616   coordsInit->decrRef();
617   
618   tagXml.replace(tagXml.find("$subdomainNumber"),16,sxyz);
619   tagXml.replace(tagXml.find("$tagSubfile"),11,tagSubfiles);
620   tagXml.replace(tagXml.find("$tagMesh"),8,tagMeshes);
621
622   string nameFileXml;
623   _file_name_huge_xml="tmp_testMeshHuge_"+IntToStr(_ni)+"x"+IntToStr(_nj)+"x"+IntToStr(_nk)+"_"+sxyz+".xml";
624   std::ofstream f(_file_name_huge_xml.c_str());
625   f<<tagXml;
626   f.close();
627   //cout<<"\n"<<tagXml<<endl;
628   if (_verbose) 
629     cout<<endl<<nameFileXml<<" created"<<endl;
630 }
631
632 void MEDPARTITIONERTest::createTestMeshWithVecFieldOnCells()
633 {
634   {
635     string name=_file_name;
636     MEDCouplingFieldDouble *f1=buildVecFieldOnCells(name);
637     name.replace(name.find(".med"),4,"_WithVecFieldOnCells.med");
638     MEDLoader::WriteField(name.c_str(),f1,true);
639     f1->setTime(3.,1,1);  //time,it,order
640     f1->applyFunc("x/2.");
641     MEDLoader::WriteField(name.c_str(),f1,false);
642     if (_verbose) cout<<endl<<name<<" created"<<endl;
643     if (_ntot<1000000) //too long
644       {
645         MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name.c_str(),f1->getMesh()->getName(),0,f1->getName(),0,1);
646         //DataArrayDouble *res=f2->getArray();
647         if (_verbose) cout<<name<<" reread"<<endl;
648         //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
649         f2->decrRef();
650       }
651     f1->decrRef();
652   }
653   {
654     string name=_file_name;
655     MEDCouplingFieldDouble *f1=buildVecFieldOnCells(name);
656     name.replace(name.find(".med"),4,"_WithVecFieldOnGaussNe.med");
657     MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::New(ON_GAUSS_NE,ONE_TIME);
658     f3->setMesh(f1->getMesh());
659     //cout<<"\nNumberOfMeshPlacesExpected "<<f3->getNumberOfMeshPlacesExpected()<<" "
660     //                                     /*<<getNumberOfTuples(f1->getMesh())<<" "*/
661     //                                     <<f3->getMesh()->getNumberOfNodes()<<" "
662     //                                     <<f3->getMesh()->getNumberOfCells()<<endl;
663     f3->setName("MyFieldOnGaussNE");
664     f3->setDescription("MyDescriptionNE");
665     DataArrayDouble *array=DataArrayDouble::New();
666     //int nb=f1->getMesh()->getNumberOfNodes();
667   
668     /*8 pt de gauss by cell
669       int nb=f3->getMesh()->getNumberOfCells()*8;
670       array->alloc(nb,2);
671       double *ptr=array->getPointer();
672       for (int i=0; i<nb*2; i=i+2) {ptr[i]=(double)(i/8) ; ptr[i]=2.*(double)(i/8);}
673     */
674   
675     //more nbptgauss=8 by default needs set MEDCouplingFieldDiscretizationPerCell
676     //theory: (may be) http://www.code-aster.org/V2/doc/v9/fr/man_r/r3/r3.06.03.pdf
677     int nbptgauss=8; //nb pt de gauss by cell 
678     int nbcell=f3->getMesh()->getNumberOfCells();
679     int nb=nbcell*nbptgauss;
680     int nbcomp=2;
681     array->alloc(nb,nbcomp);
682     double *ptr=array->getPointer();
683     int ii=0;
684     for (int i=0; i<nbcell; i++)
685       for (int j=0; j<nbptgauss; j++)
686         for (int k=0; k<nbcomp; k++)
687           {
688             //123.4 for 12th cell,3rd component, 4th gausspoint
689             ptr[ii]=(double)((i+1)*10+(k+1))+((double)(j+1))/10.;
690             ii++;
691           }
692     array->setInfoOnComponent(0,"vGx");
693     array->setInfoOnComponent(1,"vGy");
694     f3->setTime(4.,5,6);
695     f3->setArray(array);
696     array->decrRef();
697     MEDLoader::WriteField(name.c_str(),f3,true);
698     if (_verbose) cout<<endl<<name<<" created"<<endl;
699     f3->checkCoherency();
700     f1->decrRef();
701     if (_ntot<1000000) //too long
702       {
703         MEDCouplingFieldDouble* f4=MEDLoader::ReadField(ON_GAUSS_NE,
704                                                         name.c_str(), f3->getMesh()->getName(), 0, "MyFieldOnGaussNE", 5, 6);
705         if (_verbose) cout<<"MyFieldOnGaussNE reread"<<endl;
706         f4->decrRef();
707       }
708     f3->decrRef();
709   }
710   {
711     string name=_file_name_with_faces;
712     MEDCouplingFieldDouble *f1=buildVecFieldOnCells(name);
713     name.replace(name.find(".med"),4,"_WithVecFieldOnCells.med");
714     MEDLoader::WriteField(name.c_str(),f1,true);
715     if (_verbose) cout<<endl<<name<<" created"<<endl;
716     if (_ntot<1000000) //too long
717       {
718         MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name.c_str(),f1->getMesh()->getName(),0,f1->getName(),0,1);
719         if (_verbose) cout<<name<<" reread"<<endl;
720         //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); assertion failed!!
721         f2->decrRef();
722       }
723     f1->decrRef();
724   }
725 }
726
727 void MEDPARTITIONERTest::createTestMeshWithVecFieldOnNodes()
728 {
729   MEDCouplingFieldDouble *f1=buildVecFieldOnNodes();
730   string name=_file_name;
731   name.replace(name.find(".med"),4,"_WithVecFieldOnNodes.med");
732   MEDLoader::WriteField(name.c_str(),f1,true);
733   if (_verbose) cout<<endl<<name<<" created"<<endl;
734   if (_ntot<1000000) //too long
735     {
736       MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldNode(name.c_str(),f1->getMesh()->getName(),0,f1->getName(),0,1);
737       if (_verbose) cout<<name<<" reread"<<endl;
738       //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); assertion failed!!
739       f2->decrRef();
740     }
741   f1->decrRef();
742 }
743
744 void MEDPARTITIONERTest::verifyTestMeshWithVecFieldOnNodes()
745 {
746   string name=_file_name;
747   name.replace(name.find(".med"),4,"_WithVecFieldOnNodes.med");
748   MEDCouplingUMesh * m=MEDLoader::ReadUMeshFromFile(name.c_str(),_mesh_name.c_str(),0);
749   const std::set<INTERP_KERNEL::NormalizedCellType>& types=m->getAllTypes();
750   if (_verbose)
751     {
752       cout<<"\n types in "<<name<<" : ";
753       //for (std::set<INTERP_KERNEL::NormalizedCellType>::iterator t=types.begin(); t!=types.end(); ++t) cout<<" "<<*t;
754       for (std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator t=types.begin(); t!=types.end(); ++t) 
755         {
756           //INTERP_KERNEL::CellModel essai=INTERP_KERNEL::CellModel::GetCellModel(*t);
757           cout<<" "<<(INTERP_KERNEL::CellModel::GetCellModel(*t)).getRepr();
758         }
759       cout<<endl;
760     }
761   m->decrRef();
762   
763   MEDFileUMesh * mf = MEDFileUMesh::New(_file_name.c_str(),_mesh_name.c_str(),-1,-1);
764   vector<int> lev;
765   lev=mf->getNonEmptyLevels();
766   if (_verbose)
767     {
768       cout<<" levels in "<<name<<" : ";
769       for (vector<int>::iterator l=lev.begin(); l!=lev.end(); ++l) cout<<" "<<*l;
770       cout<<endl;
771     }
772   mf->decrRef();
773 }
774
775 void MEDPARTITIONERTest::createTestMeshes()
776 {
777   createTestMeshWithoutField();
778   createTestMeshWithVecFieldOnCells();
779   createTestMeshWithVecFieldOnNodes();
780 }
781
782 void MEDPARTITIONERTest::deleteTestMeshes()
783 {
784   string cmd="rm *tmp_testMesh*";
785   if (_verbose) cout<<endl<<cmd<<endl;
786   system(cmd.c_str());  //may be not if debug
787 }
788
789 void MEDPARTITIONERTest::testMeshCollectionSingle()
790 {
791   setSmallSize();
792   createTestMeshes();
793   MyGlobals::_World_Size=1;
794   MyGlobals::_Rank=0;
795   string fileName=_file_name_with_faces;
796   MEDPARTITIONER::ParaDomainSelector parallelizer(false);
797   MEDPARTITIONER::MeshCollection collection(fileName,parallelizer);
798   CPPUNIT_ASSERT(collection.isParallelMode());
799   CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension());
800   CPPUNIT_ASSERT(collection.getName()=="testMesh");
801   CPPUNIT_ASSERT_EQUAL(1,collection.getNbOfLocalMeshes());
802   CPPUNIT_ASSERT_EQUAL(1,collection.getNbOfGlobalMeshes());
803   CPPUNIT_ASSERT_EQUAL(_ni*_nj*_nk,collection.getNbOfLocalCells());
804   CPPUNIT_ASSERT_EQUAL(_ni*_nj,collection.getNbOfLocalFaces());
805 }
806
807 void MEDPARTITIONERTest::testMeshCollectionXml()
808 {
809   setSmallSize();
810   createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //xml but not so huge
811   string fileName=_file_name_huge_xml;
812   MEDPARTITIONER::ParaDomainSelector parallelizer(false);
813   MEDPARTITIONER::MeshCollection collection(fileName,parallelizer);
814   CPPUNIT_ASSERT(collection.isParallelMode());
815   CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension());
816   CPPUNIT_ASSERT(collection.getName()=="testMesh");
817   CPPUNIT_ASSERT_EQUAL(8,collection.getNbOfLocalMeshes());
818   CPPUNIT_ASSERT_EQUAL(8,collection.getNbOfGlobalMeshes());
819   CPPUNIT_ASSERT_EQUAL(_ni*_nj*_nk*8,collection.getNbOfLocalCells());
820   CPPUNIT_ASSERT_EQUAL(0,collection.getNbOfLocalFaces());
821 }
822
823
824 //#################for metis
825
826
827
828 #if defined(MED_ENABLE_METIS)
829 void MEDPARTITIONERTest::testMeshCollectionSinglePartitionMetis()
830 {
831   setSmallSize();
832   createTestMeshes();
833   //MyGlobals::_Verbose=500;
834   string fileName=_file_name_with_faces;
835   int ndomains=2;
836   bool split_family=false;
837   bool empty_groups=false;
838   MEDPARTITIONER::ParaDomainSelector parallelizer(false);
839   MEDPARTITIONER::MeshCollection collection(fileName,parallelizer);
840   
841   MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology();
842   aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector());
843   //Creating the graph and partitioning it
844   auto_ptr< MEDPARTITIONER::Topology > new_topo;
845   new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS) );
846   //Creating a new mesh collection from the partitioning
847   MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups);
848   
849   //example to create files
850   //MyGlobals::_General_Informations.clear();
851   //MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=Merge"));
852   //if (MyGlobals::_Verbose>100) cout << "generalInformations : \n"<<ReprVectorOfString(MyGlobals::_General_Informations);
853   //new_collection.write("ttmp")
854   
855   CPPUNIT_ASSERT(new_collection.isParallelMode());
856   CPPUNIT_ASSERT_EQUAL(3, new_collection.getMeshDimension());
857   CPPUNIT_ASSERT(new_collection.getName()==collection.getName());
858   CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes());
859   CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes());
860   CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells());
861   CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces());
862 }
863
864 void MEDPARTITIONERTest::testMeshCollectionComplexPartitionMetis()
865 {
866   setSmallSize();
867   createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //xml on 2*2*2 meshes but not so huge
868   string fileName=_file_name_huge_xml;
869   bool split_family=false;
870   bool empty_groups=false;
871   MEDPARTITIONER::ParaDomainSelector parallelizer(false);
872   MEDPARTITIONER::MeshCollection collection(fileName,parallelizer);
873   
874   MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology();
875   aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector());
876   
877   for (int ndomains=2 ; ndomains<=16 ; ndomains++)
878     {
879       //Creating the graph and partitioning it
880       auto_ptr< MEDPARTITIONER::Topology > new_topo;
881       new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS) );
882       //Creating a new mesh collection from the partitioning
883       MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups);
884       
885       CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes());
886       CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes());
887       CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells());
888       CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces());
889     }
890 }
891
892 void MEDPARTITIONERTest::testMetisSmallSize()
893 {
894 #if !defined(HAVE_MPI2)
895   setSmallSize();
896   createTestMeshes();
897   std::string MetisOrScotch("metis");
898   launchMetisOrScotchMedpartitionerOnTestMeshes(MetisOrScotch);
899   verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch);
900   verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch);
901   verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch);
902 #endif
903 }
904 #endif
905
906
907 //#################for scotch
908
909
910 #if defined(MED_ENABLE_SCOTCH)
911 void MEDPARTITIONERTest::testMeshCollectionSinglePartitionScotch()
912 {
913   setSmallSize();
914   createTestMeshes();
915   //MyGlobals::_Verbose=500;
916   string fileName=_file_name_with_faces;
917   int ndomains=2;
918   bool split_family=false;
919   bool empty_groups=false;
920   MEDPARTITIONER::ParaDomainSelector parallelizer(false);
921   MEDPARTITIONER::MeshCollection collection(fileName,parallelizer);
922   
923   MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology();
924   aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector());
925   //Creating the graph and partitioning it
926   auto_ptr< MEDPARTITIONER::Topology > new_topo;
927   new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH) );
928   //Creating a new mesh collection from the partitioning
929   MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups);
930   
931   //example to create files
932   //MyGlobals::_General_Informations.clear();
933   //MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=Merge"));
934   //if (MyGlobals::_Verbose>100) cout << "generalInformations : \n"<<ReprVectorOfString(MyGlobals::_General_Informations);
935   //new_collection.write("ttmp")
936   
937   CPPUNIT_ASSERT(new_collection.isParallelMode());
938   CPPUNIT_ASSERT_EQUAL(3, new_collection.getMeshDimension());
939   CPPUNIT_ASSERT(new_collection.getName()==collection.getName());
940   CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes());
941   CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes());
942   CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells());
943   CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces());
944 }
945
946 void MEDPARTITIONERTest::testMeshCollectionComplexPartitionScotch()
947 {
948   setSmallSize();
949   createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //xml on 2*2*2 meshes but not so huge
950   string fileName=_file_name_huge_xml;
951   bool split_family=false;
952   bool empty_groups=false;
953   MEDPARTITIONER::ParaDomainSelector parallelizer(false);
954   MEDPARTITIONER::MeshCollection collection(fileName,parallelizer);
955   
956   MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology();
957   aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector());
958   
959   for (int ndomains=2 ; ndomains<=16 ; ndomains++)
960     {
961       //Creating the graph and partitioning it
962       auto_ptr< MEDPARTITIONER::Topology > new_topo;
963       new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH) );
964       //Creating a new mesh collection from the partitioning
965       MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups);
966       
967       CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes());
968       CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes());
969       CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells());
970       CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces());
971     }
972 }
973
974 void MEDPARTITIONERTest::testScotchSmallSize()
975 {
976 #if !defined(HAVE_MPI2)
977   setSmallSize();
978   createTestMeshes();
979   std::string MetisOrScotch("scotch");
980   launchMetisOrScotchMedpartitionerOnTestMeshes(MetisOrScotch);
981   verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch);
982   verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch);
983   verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch);
984 #endif
985 }
986 #endif
987
988 void MEDPARTITIONERTest::launchMetisOrScotchMedpartitionerOnTestMeshes(std::string MetisOrScotch)
989 {
990   int res;
991   string cmd,execName,sourceName,targetName;
992   
993   execName=getPartitionerExe();
994   
995   cmd="which "+execName+" 2>/dev/null 1>/dev/null";  //no trace
996   res=system(cmd.c_str());
997   CPPUNIT_ASSERT_EQUAL_MESSAGE(execName + " - INVALID PATH TO medpartitioner", 0, res);
998   
999   cmd=execName+" --ndomains=2 --split-method="+MetisOrScotch;  //on same proc
1000   sourceName=_file_name;
1001   targetName=_file_name;
1002   targetName.replace(targetName.find(".med"),4,"_partitionedTo2_");
1003   cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
1004   if (_verbose) cout<<endl<<cmd<<endl;
1005   res=system(cmd.c_str());
1006   CPPUNIT_ASSERT_EQUAL(0, res);
1007   
1008   cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on less proc
1009   sourceName=_file_name;
1010   targetName=_file_name;
1011   targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
1012   cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
1013   if (_verbose) cout<<endl<<cmd<<endl;
1014   res=system(cmd.c_str());
1015   CPPUNIT_ASSERT_EQUAL(0, res);
1016   
1017   cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch;  //on 1 proc
1018   sourceName=targetName+".xml";
1019   targetName=_file_name;
1020   targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
1021   cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
1022   if (_verbose) cout<<endl<<cmd<<endl;
1023   res=system(cmd.c_str());
1024   CPPUNIT_ASSERT_EQUAL(0, res);
1025
1026   cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch;  //on more proc
1027   //sourceName=targetName+".xml";
1028   targetName=_file_name;
1029   targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
1030   cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
1031   if (_verbose) cout<<endl<<cmd<<endl;
1032   res=system(cmd.c_str());
1033   CPPUNIT_ASSERT_EQUAL(0, res);
1034 }  
1035
1036 void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std::string MetisOrScotch)
1037 {
1038   int res;
1039   string fileName,cmd,execName,sourceName,targetName,input;
1040   execName=getPartitionerExe();
1041   fileName=_file_name_with_faces;
1042   
1043   ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
1044   ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
1045   ParaMEDMEM::MEDCouplingUMesh* faceMesh=initialMesh->getLevelM1Mesh(false);
1046   
1047   cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch;  //on same proc
1048   sourceName=fileName;
1049   targetName=fileName;
1050   targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
1051   cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
1052   if (_verbose) cout<<endl<<cmd<<endl;
1053   res=system(cmd.c_str());
1054   CPPUNIT_ASSERT_EQUAL(0, res);
1055   input=targetName+".xml";
1056   
1057   MEDPARTITIONER::ParaDomainSelector parallelizer(false);
1058   MEDPARTITIONER::MeshCollection collection(input,parallelizer);
1059   CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension());
1060   std::vector<ParaMEDMEM::MEDCouplingUMesh*>cellMeshes=collection.getMesh();
1061   CPPUNIT_ASSERT_EQUAL(5, (int) cellMeshes.size());
1062   int nbcells=0;
1063   for (std::size_t i = 0; i < cellMeshes.size(); i++)
1064     nbcells+=cellMeshes[i]->getNumberOfCells();
1065   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
1066   
1067   std::vector<ParaMEDMEM::MEDCouplingUMesh*>faceMeshes=collection.getFaceMesh();
1068   CPPUNIT_ASSERT_EQUAL(5, (int) faceMeshes.size());
1069   int nbfaces=0;
1070   for (std::size_t i=0; i < faceMeshes.size(); i++)
1071     nbfaces+=faceMeshes[i]->getNumberOfCells();
1072   CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), nbfaces);
1073   
1074   //merge split meshes and test equality
1075   cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch;  //on same proc
1076   sourceName=targetName+".xml";
1077   targetName=fileName;
1078   targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
1079   cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
1080   if (_verbose) cout<<endl<<cmd<<endl;
1081   res=system(cmd.c_str());
1082   CPPUNIT_ASSERT_EQUAL(0, res);
1083   
1084   string refusedName=targetName+"1.med";
1085   ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
1086   ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
1087   ParaMEDMEM::MEDCouplingUMesh* refusedFaceMesh=refusedMesh->getLevelM1Mesh(false);
1088   
1089   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
1090   CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), refusedFaceMesh->getNumberOfCells());
1091   
1092   /*not the good job
1093     ParaMEDMEM::MEDCouplingMesh* mergeCell=cellMesh->mergeMyselfWith(refusedCellMesh);
1094     CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), mergeCell->getNumberOfCells());
1095   
1096     ParaMEDMEM::MEDCouplingMesh* mergeFace=faceMesh->mergeMyselfWith(refusedFaceMesh);
1097     CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), mergeFace->getNumberOfCells());
1098   
1099     CPPUNIT_ASSERT(faceMesh->isEqual(refusedFaceMesh,1e-12));
1100   */
1101   
1102   std::vector<const MEDCouplingUMesh *> meshes;
1103   std::vector<DataArrayInt *> corr;
1104   meshes.push_back(cellMesh);
1105   refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9);
1106   meshes.push_back(refusedCellMesh);
1107   MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
1108   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
1109   
1110   meshes.resize(0);
1111   for (std::size_t i = 0; i < corr.size(); i++)
1112     corr[i]->decrRef();
1113   corr.resize(0);
1114   meshes.push_back(faceMesh);
1115   refusedFaceMesh->tryToShareSameCoordsPermute(*faceMesh, 1e-9);
1116   meshes.push_back(refusedFaceMesh);
1117   MEDCouplingUMesh* fusedFace=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
1118   CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), fusedFace->getNumberOfCells());
1119   
1120   for (std::size_t i = 0; i < corr.size(); i++)
1121     corr[i]->decrRef();
1122   fusedFace->decrRef();
1123   refusedFaceMesh->decrRef();
1124   faceMesh->decrRef();
1125   fusedCell->decrRef();
1126   refusedCellMesh->decrRef();
1127   cellMesh->decrRef();
1128   //done in ~collection
1129   //for (int i = 0; i < faceMeshes.size(); i++) faceMeshes[i]->decrRef();
1130   //for (int i = 0; i < cellMeshes.size(); i++) cellMeshes[i]->decrRef();
1131 }
1132
1133 void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(std::string MetisOrScotch)
1134 {
1135   int res;
1136   string fileName,cmd,execName,sourceName,targetName,input;
1137   execName=getPartitionerExe();
1138   fileName=_file_name;
1139   fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnCells.med");
1140   
1141   ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
1142   ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
1143   
1144   cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch;  //on same proc
1145   sourceName=fileName;
1146   targetName=fileName;
1147   targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
1148   cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
1149   if (_verbose) cout<<endl<<cmd<<endl;
1150   res=system(cmd.c_str());
1151   CPPUNIT_ASSERT_EQUAL(0, res);
1152   input=targetName+".xml";
1153   
1154   //merge split meshes and test equality
1155   cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch;  //on same proc
1156   sourceName=targetName+".xml";
1157   targetName=fileName;
1158   targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
1159   cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
1160   if (_verbose) cout<<endl<<cmd<<endl;
1161   res=system(cmd.c_str());
1162   CPPUNIT_ASSERT_EQUAL(0, res);
1163   
1164   string refusedName=targetName+"1.med";
1165   ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
1166   ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
1167   
1168   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
1169   
1170   std::vector<const MEDCouplingUMesh *> meshes;
1171   std::vector<DataArrayInt *> corr;
1172   meshes.push_back(cellMesh);
1173   refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9);
1174   meshes.push_back(refusedCellMesh);
1175   MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
1176   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
1177   
1178   MEDCouplingFieldDouble* field1=MEDLoader::ReadFieldCell(fileName.c_str(),initialMesh->getName(),0,"VectorFieldOnCells",0,1);
1179   MEDCouplingFieldDouble* field2=MEDLoader::ReadFieldCell(refusedName.c_str(),refusedCellMesh->getName(),0,"VectorFieldOnCells",0,1);
1180   
1181   int nbcells=corr[1]->getNumberOfTuples();
1182   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
1183   //use corr to test equality of field
1184   DataArrayDouble* f1=field1->getArray();
1185   DataArrayDouble* f2=field2->getArray();
1186   if (_verbose>300) 
1187     {
1188       cout<<"\nf1 : "<<f1->reprZip();
1189       cout<<"\nf2 : "<<f2->reprZip(); //field2->advancedRepradvancedRepr();
1190       for (std::size_t i = 0; i < corr.size(); i++)
1191         cout << "\ncorr " << i << " : " << corr[i]->reprZip();
1192     
1193     }
1194   int nbequal=0;
1195   int nbcomp=field1->getNumberOfComponents();
1196   double* p1=f1->getPointer();
1197   double* p2=f2->getPointer();
1198   int* pc=corr[1]->getPointer();
1199   for (int i = 0; i < nbcells; i++)
1200     {
1201       int i1=pc[i]*nbcomp;
1202       int i2=i*nbcomp;
1203       for (int j = 0; j < nbcomp; j++)
1204         {
1205           if (p1[i1+j]==p2[i2+j]) nbequal++;
1206           //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j];
1207         }
1208     }
1209   CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp, nbequal);
1210   
1211   for (std::size_t i = 0; i < corr.size(); i++)
1212     corr[i]->decrRef();
1213   field1->decrRef();
1214   field2->decrRef();
1215   fusedCell->decrRef();
1216   refusedCellMesh->decrRef();
1217   cellMesh->decrRef();
1218 }
1219
1220 void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(std::string MetisOrScotch)
1221 {
1222   int res;
1223   string fileName,cmd,execName,sourceName,targetName,input;
1224   execName=getPartitionerExe();
1225   fileName=_file_name;
1226   fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnGaussNe.med");
1227   
1228   ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
1229   ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
1230   
1231   cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch;  //on same proc
1232   sourceName=fileName;
1233   targetName=fileName;
1234   targetName.replace(targetName.find(".med"),4,"_partitionedTo5_");
1235   cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
1236   if (_verbose) cout<<endl<<cmd<<endl;
1237   res=system(cmd.c_str());
1238   CPPUNIT_ASSERT_EQUAL(0, res);
1239   input=targetName+".xml";
1240   
1241   //merge split meshes and test equality
1242   cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch;  //on same proc
1243   sourceName=targetName+".xml";
1244   targetName=fileName;
1245   targetName.replace(targetName.find(".med"),4,"_remergedFrom5_");
1246   cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose);
1247   if (_verbose) cout<<endl<<cmd<<endl;
1248   res=system(cmd.c_str());
1249   CPPUNIT_ASSERT_EQUAL(0, res);
1250   
1251   string refusedName=targetName+"1.med";
1252   ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
1253   ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
1254   
1255   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
1256   
1257   std::vector<const MEDCouplingUMesh *> meshes;
1258   std::vector<DataArrayInt *> corr;
1259   meshes.push_back(cellMesh);
1260   refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9);
1261   meshes.push_back(refusedCellMesh);
1262   MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
1263   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
1264   
1265   MEDCouplingFieldDouble* field1=MEDLoader::ReadField(ON_GAUSS_NE,fileName.c_str(),initialMesh->getName(),0,"MyFieldOnGaussNE",5,6);
1266   MEDCouplingFieldDouble* field2=MEDLoader::ReadField(ON_GAUSS_NE,refusedName.c_str(),refusedCellMesh->getName(),0,"MyFieldOnGaussNE",5,6);
1267   
1268   int nbcells=corr[1]->getNumberOfTuples();
1269   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
1270   //use corr to test equality of field
1271   DataArrayDouble* f1=field1->getArray();
1272   DataArrayDouble* f2=field2->getArray();
1273   if (_verbose>300) 
1274     {
1275       cout << "\nf1 : " << f1->reprZip(); //123.4 for 12th cell,3rd component, 4th gausspoint
1276       cout << "\nf2 : " << f2->reprZip(); //field2->advancedRepradvancedRepr();
1277       for (std::size_t i = 0; i < corr.size(); i++)
1278         cout << "\ncorr " << i << " : " << corr[i]->reprZip();
1279     
1280     }
1281   int nbequal=0;
1282   int nbptgauss=8;
1283   int nbcomp=field1->getNumberOfComponents();
1284   double* p1=f1->getPointer();
1285   double* p2=f2->getPointer();
1286   int* pc=corr[1]->getPointer();
1287   for (int i = 0; i < nbcells; i++)
1288     {
1289       int i1=pc[i]*nbcomp*nbptgauss;
1290       int i2=i*nbcomp*nbptgauss;
1291       for (int j = 0; j < nbcomp*nbptgauss; j++)
1292         {
1293           if (p1[i1+j]==p2[i2+j]) nbequal++;
1294           //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j];
1295         }
1296     }
1297   CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp*nbptgauss, nbequal);
1298   
1299   for (std::size_t i = 0; i < corr.size(); i++)
1300     corr[i]->decrRef();
1301   field1->decrRef();
1302   field2->decrRef();
1303   fusedCell->decrRef();
1304   refusedCellMesh->decrRef();
1305   cellMesh->decrRef();
1306 }