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