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