Salome HOME
Merge branch 'agr/medcoupling_tool'
[tools/medcoupling.git] / src / MEDPartitioner / Test / MEDPARTITIONERTest.cxx
index 1a377236333fa069aaaafc4779fb85d3bc5f99e8..242de7f99266ad75db0d22995e50734b7ca82dd7 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 #include <cppunit/TestAssert.h>
 
 #include <sstream>
+#include <fstream>
 #include <cmath>
 #include <list>
 #include <stdexcept>
 #include <cstdlib>
 #include <vector>
+#include <unistd.h>
 
-#ifdef HAVE_MPI2
+#ifdef HAVE_MPI
 #include <mpi.h>
 #endif
 
@@ -83,19 +85,17 @@ void MEDPARTITIONERTest::setbigSize()
 std::string MEDPARTITIONERTest::getPartitionerExe() const
 {
   std::string execName;
-  if ( getenv("top_builddir")) // make distcheck
+  if ( getenv("MEDCOUPLING_ROOT_DIR") )
     {
-      execName = getenv("top_builddir");
-      execName += "/src/MEDPartitioner/medpartitioner";
-    }
-  else if ( getenv("MED_ROOT_DIR") )
-    {
-      execName=getenv("MED_ROOT_DIR");  //.../INSTALL/MED
-      execName+="/bin/salome/medpartitioner";
+      execName=getenv("MEDCOUPLING_ROOT_DIR");  //.../INSTALL/MED
+      execName+="/bin/medpartitioner";
     }
   else
     {
-      CPPUNIT_FAIL("Can't find medpartitioner, neither MED_ROOT_DIR nor top_builddir is set");
+      execName = get_current_dir_name();
+      execName += "/../../MEDPartitioner/medpartitioner";
+      if (! std::ifstream(execName.c_str()))
+        CPPUNIT_FAIL("Can't find medpartitioner, please set MEDCOUPLING_ROOT_DIR");
     }
   return execName;
 }
@@ -108,7 +108,7 @@ std::string MEDPARTITIONERTest::getPartitionerExe() const
 void MEDPARTITIONERTest::setUp()
 {
   this->_verbose=0;
-#if defined(HAVE_MPI2)
+#if defined(HAVE_MPI)
   if (MyGlobals::_Rank==-1)  //do once only
     {
       MPI_Init(0,0);
@@ -123,10 +123,10 @@ void MEDPARTITIONERTest::setUp()
 
   if (_verbose>10)
     {
-#if defined(HAVE_MPI2)
-      cout<<"\ndefined(HAVE_MPI2)"<<endl;
+#if defined(HAVE_MPI)
+      cout<<"\ndefined(HAVE_MPI)"<<endl;
 #else
-      cout<<"\nNOT defined(HAVE_MPI2)"<<endl;
+      cout<<"\nNOT defined(HAVE_MPI)"<<endl;
 #endif
 #if defined(MED_ENABLE_PARMETIS)
       cout<<"defined(MED_ENABLE_PARMETIS)"<<endl;
@@ -179,7 +179,7 @@ ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildCUBE3DMesh()
           ii=ii + _ni + 2 ;
           conn.push_back(ii);
           conn.push_back(ii-1);
-    
+
           ii=i + j*(_ni+1) + (k+1)*(_ni+1)*(_nj+1);
           conn.push_back(ii);
           conn.push_back(ii+1);
@@ -197,7 +197,7 @@ ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildCUBE3DMesh()
       cout << endl;
       cout << "\nnb conn " << (_ni)*(_nj)*(_nk)*8 << " " << conn.size() << endl;
       for (int i=0; i<(int)conn.size(); i=i+8)
-        { 
+        {
           for (int j=0; j<8; j++)
             cout << conn[i+j] << " ";
           cout << endl;
@@ -205,7 +205,7 @@ ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildCUBE3DMesh()
       cout << endl;
     }
   */
-  
+
   MEDCouplingUMesh *mesh=MEDCouplingUMesh::New();
   mesh->setMeshDimension(3);
   int nbc=conn.size()/8; //nb of cells
@@ -267,13 +267,13 @@ ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildCARRE3DMesh()
       cout<<endl;
       cout<<"\nnb conn "<<(_ni)*(_nj)*4<<" "<<conn.size()<<endl;
       for (int i=0; i<(int)conn.size(); i=i+4)
-        { 
+        {
           for (int j=0; j<4; j++) cout<<conn[i+j]<<" ";
           cout<<endl;
         }
       cout<<endl;
     }
-  
+
   MEDCouplingUMesh *mesh=MEDCouplingUMesh::New();
   mesh->setMeshDimension(2);
   int nbc=conn.size()/4; //nb of cells
@@ -335,14 +335,14 @@ ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildFACE3DMesh()
       cout<<endl;
       cout<<"\nnb conn "<<(_ni)*(_nj)*4<<" "<<conn.size()<<endl;
       for (int i=0; i<(int)conn.size(); i=i+4)
-        { 
+        {
           for (int j=0; j<4; j++)
             cout << conn[i+j] << " ";
           cout << endl;
         }
       cout << endl;
     }
-  
+
   MEDCouplingUMesh *mesh=MEDCouplingUMesh::New();
   mesh->setMeshDimension(2);
   int nbc=conn.size()/4; //nb of cells
@@ -415,7 +415,7 @@ MEDCouplingFieldDouble * MEDPARTITIONERTest::buildVecFieldOnNodes()
           field.push_back(j+.2);
           field.push_back(k+.3);
         }
-  
+
   MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(_file_name.c_str(),_mesh_name.c_str(),0);
   int nbOfNodes=mesh->getNumberOfNodes();
   MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME);
@@ -445,14 +445,14 @@ void MEDPARTITIONERTest::createTestMeshWithoutField()
     if (_verbose) cout<<endl<<_file_name<<" created"<<endl;
     if (_ntot<1000000) //too long
       {
-        MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name.c_str(),mesh->getName(),0);
+        MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name.c_str(),mesh->getName().c_str(),0);
         if (_verbose) cout<<_file_name<<" reread"<<endl;
         CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12));
         mesh_rw->decrRef();
       }
     mesh->decrRef();
   }
-  
+
   {
     vector<const ParaMEDMEM::MEDCouplingUMesh*> meshes;
     MEDCouplingUMesh * mesh1 = buildCUBE3DMesh();
@@ -465,8 +465,8 @@ void MEDPARTITIONERTest::createTestMeshWithoutField()
     meshes.push_back(mesh1);
     meshes.push_back(mesh2);
     MEDLoader::WriteUMeshes(_file_name_with_faces.c_str(), meshes, true);
-  
-    ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(_file_name_with_faces.c_str(), mesh1->getName());
+
+    ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(_file_name_with_faces.c_str(), mesh1->getName().c_str());
     DataArrayInt* FacesFam=DataArrayInt::New();
     FacesFam->alloc(mfm->getSizeAtLevel(-1),1);
     FacesFam->fillWithValue(-1);
@@ -487,7 +487,7 @@ void MEDPARTITIONERTest::createTestMeshWithoutField()
     mfm->write(_file_name_with_faces.c_str(),0);
     FacesFam->decrRef();
     CellsFam->decrRef();
-  
+
     /*ce truc marche pas!
       ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(_file_name_with_faces.c_str(), mesh1->getName());
       vector<const ParaMEDMEM::MEDCouplingUMesh*> ms;
@@ -495,24 +495,25 @@ void MEDPARTITIONERTest::createTestMeshWithoutField()
       mfm->setGroupsFromScratch(-1, ms);
       mfm->write(_file_name_with_faces.c_str(),0);
     */
-  
+
     if (_verbose) cout<<endl<<_file_name_with_faces<<" created"<<endl;
     if (_ntot<1000000) //too long
       {
-        MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name_with_faces.c_str(),mesh1->getName(),0);
+        MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name_with_faces.c_str(),mesh1->getName().c_str(),0);
         if (_verbose) cout<<_file_name_with_faces<<" reread"<<endl;
         CPPUNIT_ASSERT(mesh1->isEqual(mesh_rw,1e-12));
         mesh_rw->decrRef();
       }
     mesh1->decrRef();
     mesh2->decrRef();
+    mfm->decrRef();
   }
-   
+
   {
     MEDCouplingUMesh * mesh = buildCARRE3DMesh();
     MEDLoader::WriteUMesh(_file_name2.c_str(),mesh,true);
     if (_verbose) cout<<endl<<_file_name2<<" created"<<endl;
-    MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name2.c_str(),mesh->getName(),0);
+    MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name2.c_str(),mesh->getName().c_str(),0);
     if (_verbose) cout<<_file_name2<<" reread"<<endl;
     CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12));
     mesh_rw->decrRef();
@@ -552,7 +553,7 @@ void MEDPARTITIONERTest::createHugeTestMesh(int ni, int nj, int nk, int nbx, int
   <mapping>\n$tagMesh \
   </mapping>\n \
 </root>\n";
-  
+
   string tagSubfiles, tagSubfile="\
     <subfile id=\"$xyz\">\n \
       <name>$fileName</name>\n \
@@ -564,7 +565,7 @@ void MEDPARTITIONERTest::createHugeTestMesh(int ni, int nj, int nk, int nbx, int
         <name>testMesh</name>\n \
       </chunk>\n \
     </mesh>\n";
-  
+
   int xyz=1;
   string sxyz;
   DataArrayDouble* coordsInit=mesh->getCoords()->deepCpy();
@@ -572,7 +573,7 @@ void MEDPARTITIONERTest::createHugeTestMesh(int ni, int nj, int nk, int nbx, int
   double deltax=cooFin[0]-cooDep[0];
   double deltay=cooFin[1]-cooDep[1];
   double deltaz=cooFin[2]-cooDep[2];
-  
+
   double dz=0.;
   for (int z=0; z<nbz; z++)
     {
@@ -585,7 +586,7 @@ void MEDPARTITIONERTest::createHugeTestMesh(int ni, int nj, int nk, int nbx, int
               string fileName;
               sxyz=IntToStr(xyz);
               fileName="tmp_testMeshHuge_"+IntToStr(_ni)+"x"+IntToStr(_nj)+"x"+IntToStr(_nk)+"_"+sxyz+".med";
-        
+
               DataArrayDouble* coords=mesh->getCoords();
               //int nbOfComp=coords->getNumberOfComponents();  //be 3D
               int nbOfTuple=coords->getNumberOfTuples();
@@ -599,11 +600,11 @@ void MEDPARTITIONERTest::createHugeTestMesh(int ni, int nj, int nk, int nbx, int
                 }
 
               MEDLoader::WriteUMesh(fileName.c_str(),mesh,true);
-        
+
               tagSubfiles+=tagSubfile;
               tagSubfiles.replace(tagSubfiles.find("$xyz"),4,sxyz);
               tagSubfiles.replace(tagSubfiles.find("$fileName"),9,fileName);
-        
+
               tagMeshes+=tagMesh;
               tagMeshes.replace(tagMeshes.find("$xyz"),4,sxyz);
               xyz++;
@@ -614,7 +615,7 @@ void MEDPARTITIONERTest::createHugeTestMesh(int ni, int nj, int nk, int nbx, int
       dz+=deltaz;
     }
   coordsInit->decrRef();
-  
+
   tagXml.replace(tagXml.find("$subdomainNumber"),16,sxyz);
   tagXml.replace(tagXml.find("$tagSubfile"),11,tagSubfiles);
   tagXml.replace(tagXml.find("$tagMesh"),8,tagMeshes);
@@ -625,8 +626,9 @@ void MEDPARTITIONERTest::createHugeTestMesh(int ni, int nj, int nk, int nbx, int
   f<<tagXml;
   f.close();
   //cout<<"\n"<<tagXml<<endl;
-  if (_verbose) 
+  if (_verbose)
     cout<<endl<<nameFileXml<<" created"<<endl;
+  mesh->decrRef();
 }
 
 void MEDPARTITIONERTest::createTestMeshWithVecFieldOnCells()
@@ -642,7 +644,7 @@ void MEDPARTITIONERTest::createTestMeshWithVecFieldOnCells()
     if (_verbose) cout<<endl<<name<<" created"<<endl;
     if (_ntot<1000000) //too long
       {
-        MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name.c_str(),f1->getMesh()->getName(),0,f1->getName(),0,1);
+        MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name.c_str(),f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1);
         //DataArrayDouble *res=f2->getArray();
         if (_verbose) cout<<name<<" reread"<<endl;
         //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12));
@@ -664,17 +666,17 @@ void MEDPARTITIONERTest::createTestMeshWithVecFieldOnCells()
     f3->setDescription("MyDescriptionNE");
     DataArrayDouble *array=DataArrayDouble::New();
     //int nb=f1->getMesh()->getNumberOfNodes();
-  
+
     /*8 pt de gauss by cell
       int nb=f3->getMesh()->getNumberOfCells()*8;
       array->alloc(nb,2);
       double *ptr=array->getPointer();
       for (int i=0; i<nb*2; i=i+2) {ptr[i]=(double)(i/8) ; ptr[i]=2.*(double)(i/8);}
     */
-  
+
     //more nbptgauss=8 by default needs set MEDCouplingFieldDiscretizationPerCell
     //theory: (may be) http://www.code-aster.org/V2/doc/v9/fr/man_r/r3/r3.06.03.pdf
-    int nbptgauss=8; //nb pt de gauss by cell 
+    int nbptgauss=8; //nb pt de gauss by cell
     int nbcell=f3->getMesh()->getNumberOfCells();
     int nb=nbcell*nbptgauss;
     int nbcomp=2;
@@ -701,7 +703,7 @@ void MEDPARTITIONERTest::createTestMeshWithVecFieldOnCells()
     if (_ntot<1000000) //too long
       {
         MEDCouplingFieldDouble* f4=MEDLoader::ReadField(ON_GAUSS_NE,
-                                                        name.c_str(), f3->getMesh()->getName(), 0, "MyFieldOnGaussNE", 5, 6);
+                                                        name.c_str(), f3->getMesh()->getName().c_str(), 0, "MyFieldOnGaussNE", 5, 6);
         if (_verbose) cout<<"MyFieldOnGaussNE reread"<<endl;
         f4->decrRef();
       }
@@ -715,7 +717,7 @@ void MEDPARTITIONERTest::createTestMeshWithVecFieldOnCells()
     if (_verbose) cout<<endl<<name<<" created"<<endl;
     if (_ntot<1000000) //too long
       {
-        MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name.c_str(),f1->getMesh()->getName(),0,f1->getName(),0,1);
+        MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name.c_str(),f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1);
         if (_verbose) cout<<name<<" reread"<<endl;
         //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); assertion failed!!
         f2->decrRef();
@@ -733,7 +735,7 @@ void MEDPARTITIONERTest::createTestMeshWithVecFieldOnNodes()
   if (_verbose) cout<<endl<<name<<" created"<<endl;
   if (_ntot<1000000) //too long
     {
-      MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldNode(name.c_str(),f1->getMesh()->getName(),0,f1->getName(),0,1);
+      MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldNode(name.c_str(),f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1);
       if (_verbose) cout<<name<<" reread"<<endl;
       //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); assertion failed!!
       f2->decrRef();
@@ -746,12 +748,12 @@ void MEDPARTITIONERTest::verifyTestMeshWithVecFieldOnNodes()
   string name=_file_name;
   name.replace(name.find(".med"),4,"_WithVecFieldOnNodes.med");
   MEDCouplingUMesh * m=MEDLoader::ReadUMeshFromFile(name.c_str(),_mesh_name.c_str(),0);
-  const std::set<INTERP_KERNEL::NormalizedCellType>& types=m->getAllTypes();
+  std::set<INTERP_KERNEL::NormalizedCellType> types(m->getAllGeoTypes());
   if (_verbose)
     {
       cout<<"\n types in "<<name<<" : ";
       //for (std::set<INTERP_KERNEL::NormalizedCellType>::iterator t=types.begin(); t!=types.end(); ++t) cout<<" "<<*t;
-      for (std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator t=types.begin(); t!=types.end(); ++t) 
+      for (std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator t=types.begin(); t!=types.end(); ++t)
         {
           //INTERP_KERNEL::CellModel essai=INTERP_KERNEL::CellModel::GetCellModel(*t);
           cout<<" "<<(INTERP_KERNEL::CellModel::GetCellModel(*t)).getRepr();
@@ -759,7 +761,7 @@ void MEDPARTITIONERTest::verifyTestMeshWithVecFieldOnNodes()
       cout<<endl;
     }
   m->decrRef();
-  
+
   MEDFileUMesh * mf = MEDFileUMesh::New(_file_name.c_str(),_mesh_name.c_str(),-1,-1);
   vector<int> lev;
   lev=mf->getNonEmptyLevels();
@@ -837,7 +839,7 @@ void MEDPARTITIONERTest::testMeshCollectionSinglePartitionMetis()
   bool empty_groups=false;
   MEDPARTITIONER::ParaDomainSelector parallelizer(false);
   MEDPARTITIONER::MeshCollection collection(fileName,parallelizer);
-  
+
   MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology();
   aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector());
   //Creating the graph and partitioning it
@@ -845,13 +847,13 @@ void MEDPARTITIONERTest::testMeshCollectionSinglePartitionMetis()
   new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS) );
   //Creating a new mesh collection from the partitioning
   MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups);
-  
+
   //example to create files
   //MyGlobals::_General_Informations.clear();
   //MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=Merge"));
   //if (MyGlobals::_Verbose>100) cout << "generalInformations : \n"<<ReprVectorOfString(MyGlobals::_General_Informations);
   //new_collection.write("ttmp")
-  
+
   CPPUNIT_ASSERT(new_collection.isParallelMode());
   CPPUNIT_ASSERT_EQUAL(3, new_collection.getMeshDimension());
   CPPUNIT_ASSERT(new_collection.getName()==collection.getName());
@@ -870,10 +872,10 @@ void MEDPARTITIONERTest::testMeshCollectionComplexPartitionMetis()
   bool empty_groups=false;
   MEDPARTITIONER::ParaDomainSelector parallelizer(false);
   MEDPARTITIONER::MeshCollection collection(fileName,parallelizer);
-  
+
   MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology();
   aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector());
-  
+
   for (int ndomains=2 ; ndomains<=16 ; ndomains++)
     {
       //Creating the graph and partitioning it
@@ -881,7 +883,7 @@ void MEDPARTITIONERTest::testMeshCollectionComplexPartitionMetis()
       new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS) );
       //Creating a new mesh collection from the partitioning
       MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups);
-      
+
       CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes());
       CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes());
       CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells());
@@ -891,7 +893,7 @@ void MEDPARTITIONERTest::testMeshCollectionComplexPartitionMetis()
 
 void MEDPARTITIONERTest::testMetisSmallSize()
 {
-#if !defined(HAVE_MPI2)
+  //#if !defined(HAVE_MPI)
   setSmallSize();
   createTestMeshes();
   std::string MetisOrScotch("metis");
@@ -899,7 +901,7 @@ void MEDPARTITIONERTest::testMetisSmallSize()
   verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch);
   verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch);
   verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch);
-#endif
+  //#endif
 }
 #endif
 
@@ -919,7 +921,7 @@ void MEDPARTITIONERTest::testMeshCollectionSinglePartitionScotch()
   bool empty_groups=false;
   MEDPARTITIONER::ParaDomainSelector parallelizer(false);
   MEDPARTITIONER::MeshCollection collection(fileName,parallelizer);
-  
+
   MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology();
   aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector());
   //Creating the graph and partitioning it
@@ -927,13 +929,13 @@ void MEDPARTITIONERTest::testMeshCollectionSinglePartitionScotch()
   new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH) );
   //Creating a new mesh collection from the partitioning
   MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups);
-  
+
   //example to create files
   //MyGlobals::_General_Informations.clear();
   //MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=Merge"));
   //if (MyGlobals::_Verbose>100) cout << "generalInformations : \n"<<ReprVectorOfString(MyGlobals::_General_Informations);
   //new_collection.write("ttmp")
-  
+
   CPPUNIT_ASSERT(new_collection.isParallelMode());
   CPPUNIT_ASSERT_EQUAL(3, new_collection.getMeshDimension());
   CPPUNIT_ASSERT(new_collection.getName()==collection.getName());
@@ -952,10 +954,10 @@ void MEDPARTITIONERTest::testMeshCollectionComplexPartitionScotch()
   bool empty_groups=false;
   MEDPARTITIONER::ParaDomainSelector parallelizer(false);
   MEDPARTITIONER::MeshCollection collection(fileName,parallelizer);
-  
+
   MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology();
   aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector());
-  
+
   for (int ndomains=2 ; ndomains<=16 ; ndomains++)
     {
       //Creating the graph and partitioning it
@@ -963,7 +965,7 @@ void MEDPARTITIONERTest::testMeshCollectionComplexPartitionScotch()
       new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH) );
       //Creating a new mesh collection from the partitioning
       MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups);
-      
+
       CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes());
       CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes());
       CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells());
@@ -973,7 +975,7 @@ void MEDPARTITIONERTest::testMeshCollectionComplexPartitionScotch()
 
 void MEDPARTITIONERTest::testScotchSmallSize()
 {
-#if !defined(HAVE_MPI2)
+  //#if !defined(HAVE_MPI)
   setSmallSize();
   createTestMeshes();
   std::string MetisOrScotch("scotch");
@@ -981,7 +983,7 @@ void MEDPARTITIONERTest::testScotchSmallSize()
   verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch);
   verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch);
   verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch);
-#endif
+  //#endif
 }
 #endif
 
@@ -989,13 +991,13 @@ void MEDPARTITIONERTest::launchMetisOrScotchMedpartitionerOnTestMeshes(std::stri
 {
   int res;
   string cmd,execName,sourceName,targetName;
-  
+
   execName=getPartitionerExe();
-  
+
   cmd="which "+execName+" 2>/dev/null 1>/dev/null";  //no trace
   res=system(cmd.c_str());
   CPPUNIT_ASSERT_EQUAL_MESSAGE(execName + " - INVALID PATH TO medpartitioner", 0, res);
-  
+
   cmd=execName+" --ndomains=2 --split-method="+MetisOrScotch;  //on same proc
   sourceName=_file_name;
   targetName=_file_name;
@@ -1004,7 +1006,7 @@ void MEDPARTITIONERTest::launchMetisOrScotchMedpartitionerOnTestMeshes(std::stri
   if (_verbose) cout<<endl<<cmd<<endl;
   res=system(cmd.c_str());
   CPPUNIT_ASSERT_EQUAL(0, res);
-  
+
   cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on less proc
   sourceName=_file_name;
   targetName=_file_name;
@@ -1013,7 +1015,7 @@ void MEDPARTITIONERTest::launchMetisOrScotchMedpartitionerOnTestMeshes(std::stri
   if (_verbose) cout<<endl<<cmd<<endl;
   res=system(cmd.c_str());
   CPPUNIT_ASSERT_EQUAL(0, res);
-  
+
   cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch;  //on 1 proc
   sourceName=targetName+".xml";
   targetName=_file_name;
@@ -1031,7 +1033,7 @@ void MEDPARTITIONERTest::launchMetisOrScotchMedpartitionerOnTestMeshes(std::stri
   if (_verbose) cout<<endl<<cmd<<endl;
   res=system(cmd.c_str());
   CPPUNIT_ASSERT_EQUAL(0, res);
-}  
+}
 
 void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std::string MetisOrScotch)
 {
@@ -1039,11 +1041,11 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std
   string fileName,cmd,execName,sourceName,targetName,input;
   execName=getPartitionerExe();
   fileName=_file_name_with_faces;
-  
+
   ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
   ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
   ParaMEDMEM::MEDCouplingUMesh* faceMesh=initialMesh->getLevelM1Mesh(false);
-  
+
   cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch;  //on same proc
   sourceName=fileName;
   targetName=fileName;
@@ -1053,7 +1055,7 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std
   res=system(cmd.c_str());
   CPPUNIT_ASSERT_EQUAL(0, res);
   input=targetName+".xml";
-  
+
   MEDPARTITIONER::ParaDomainSelector parallelizer(false);
   MEDPARTITIONER::MeshCollection collection(input,parallelizer);
   CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension());
@@ -1063,14 +1065,14 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std
   for (std::size_t i = 0; i < cellMeshes.size(); i++)
     nbcells+=cellMeshes[i]->getNumberOfCells();
   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
-  
+
   std::vector<ParaMEDMEM::MEDCouplingUMesh*>faceMeshes=collection.getFaceMesh();
   CPPUNIT_ASSERT_EQUAL(5, (int) faceMeshes.size());
   int nbfaces=0;
   for (std::size_t i=0; i < faceMeshes.size(); i++)
     nbfaces+=faceMeshes[i]->getNumberOfCells();
   CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), nbfaces);
-  
+
   //merge split meshes and test equality
   cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch;  //on same proc
   sourceName=targetName+".xml";
@@ -1080,25 +1082,25 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std
   if (_verbose) cout<<endl<<cmd<<endl;
   res=system(cmd.c_str());
   CPPUNIT_ASSERT_EQUAL(0, res);
-  
+
   string refusedName=targetName+"1.med";
   ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
   ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
   ParaMEDMEM::MEDCouplingUMesh* refusedFaceMesh=refusedMesh->getLevelM1Mesh(false);
-  
+
   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
   CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), refusedFaceMesh->getNumberOfCells());
-  
+
   /*not the good job
     ParaMEDMEM::MEDCouplingMesh* mergeCell=cellMesh->mergeMyselfWith(refusedCellMesh);
     CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), mergeCell->getNumberOfCells());
-  
+
     ParaMEDMEM::MEDCouplingMesh* mergeFace=faceMesh->mergeMyselfWith(refusedFaceMesh);
     CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), mergeFace->getNumberOfCells());
-  
+
     CPPUNIT_ASSERT(faceMesh->isEqual(refusedFaceMesh,1e-12));
   */
-  
+
   std::vector<const MEDCouplingUMesh *> meshes;
   std::vector<DataArrayInt *> corr;
   meshes.push_back(cellMesh);
@@ -1106,7 +1108,7 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std
   meshes.push_back(refusedCellMesh);
   MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
-  
+
   meshes.resize(0);
   for (std::size_t i = 0; i < corr.size(); i++)
     corr[i]->decrRef();
@@ -1116,7 +1118,7 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std
   meshes.push_back(refusedFaceMesh);
   MEDCouplingUMesh* fusedFace=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
   CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), fusedFace->getNumberOfCells());
-  
+
   for (std::size_t i = 0; i < corr.size(); i++)
     corr[i]->decrRef();
   fusedFace->decrRef();
@@ -1124,7 +1126,9 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std
   faceMesh->decrRef();
   fusedCell->decrRef();
   refusedCellMesh->decrRef();
+  refusedMesh->decrRef();
   cellMesh->decrRef();
+  initialMesh->decrRef();
   //done in ~collection
   //for (int i = 0; i < faceMeshes.size(); i++) faceMeshes[i]->decrRef();
   //for (int i = 0; i < cellMeshes.size(); i++) cellMeshes[i]->decrRef();
@@ -1137,10 +1141,10 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnC
   execName=getPartitionerExe();
   fileName=_file_name;
   fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnCells.med");
-  
+
   ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
   ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
-  
+
   cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch;  //on same proc
   sourceName=fileName;
   targetName=fileName;
@@ -1150,7 +1154,7 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnC
   res=system(cmd.c_str());
   CPPUNIT_ASSERT_EQUAL(0, res);
   input=targetName+".xml";
-  
+
   //merge split meshes and test equality
   cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch;  //on same proc
   sourceName=targetName+".xml";
@@ -1160,13 +1164,13 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnC
   if (_verbose) cout<<endl<<cmd<<endl;
   res=system(cmd.c_str());
   CPPUNIT_ASSERT_EQUAL(0, res);
-  
+
   string refusedName=targetName+"1.med";
   ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
   ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
-  
+
   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
-  
+
   std::vector<const MEDCouplingUMesh *> meshes;
   std::vector<DataArrayInt *> corr;
   meshes.push_back(cellMesh);
@@ -1174,22 +1178,22 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnC
   meshes.push_back(refusedCellMesh);
   MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
-  
-  MEDCouplingFieldDouble* field1=MEDLoader::ReadFieldCell(fileName.c_str(),initialMesh->getName(),0,"VectorFieldOnCells",0,1);
-  MEDCouplingFieldDouble* field2=MEDLoader::ReadFieldCell(refusedName.c_str(),refusedCellMesh->getName(),0,"VectorFieldOnCells",0,1);
-  
+
+  MEDCouplingFieldDouble* field1=MEDLoader::ReadFieldCell(fileName.c_str(),initialMesh->getName().c_str(),0,"VectorFieldOnCells",0,1);
+  MEDCouplingFieldDouble* field2=MEDLoader::ReadFieldCell(refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"VectorFieldOnCells",0,1);
+
   int nbcells=corr[1]->getNumberOfTuples();
   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
   //use corr to test equality of field
   DataArrayDouble* f1=field1->getArray();
   DataArrayDouble* f2=field2->getArray();
-  if (_verbose>300) 
+  if (_verbose>300)
     {
       cout<<"\nf1 : "<<f1->reprZip();
       cout<<"\nf2 : "<<f2->reprZip(); //field2->advancedRepradvancedRepr();
       for (std::size_t i = 0; i < corr.size(); i++)
         cout << "\ncorr " << i << " : " << corr[i]->reprZip();
-    
+
     }
   int nbequal=0;
   int nbcomp=field1->getNumberOfComponents();
@@ -1207,14 +1211,16 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnC
         }
     }
   CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp, nbequal);
-  
+
   for (std::size_t i = 0; i < corr.size(); i++)
     corr[i]->decrRef();
   field1->decrRef();
   field2->decrRef();
   fusedCell->decrRef();
+  refusedMesh->decrRef();
   refusedCellMesh->decrRef();
   cellMesh->decrRef();
+  initialMesh->decrRef();
 }
 
 void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(std::string MetisOrScotch)
@@ -1224,10 +1230,10 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnG
   execName=getPartitionerExe();
   fileName=_file_name;
   fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnGaussNe.med");
-  
+
   ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str());
   ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false);
-  
+
   cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch;  //on same proc
   sourceName=fileName;
   targetName=fileName;
@@ -1237,7 +1243,7 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnG
   res=system(cmd.c_str());
   CPPUNIT_ASSERT_EQUAL(0, res);
   input=targetName+".xml";
-  
+
   //merge split meshes and test equality
   cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch;  //on same proc
   sourceName=targetName+".xml";
@@ -1247,13 +1253,13 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnG
   if (_verbose) cout<<endl<<cmd<<endl;
   res=system(cmd.c_str());
   CPPUNIT_ASSERT_EQUAL(0, res);
-  
+
   string refusedName=targetName+"1.med";
   ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str());
   ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false);
-  
+
   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells());
-  
+
   std::vector<const MEDCouplingUMesh *> meshes;
   std::vector<DataArrayInt *> corr;
   meshes.push_back(cellMesh);
@@ -1261,22 +1267,22 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnG
   meshes.push_back(refusedCellMesh);
   MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells());
-  
-  MEDCouplingFieldDouble* field1=MEDLoader::ReadField(ON_GAUSS_NE,fileName.c_str(),initialMesh->getName(),0,"MyFieldOnGaussNE",5,6);
-  MEDCouplingFieldDouble* field2=MEDLoader::ReadField(ON_GAUSS_NE,refusedName.c_str(),refusedCellMesh->getName(),0,"MyFieldOnGaussNE",5,6);
-  
+
+  MEDCouplingFieldDouble* field1=MEDLoader::ReadField(ON_GAUSS_NE,fileName.c_str(),initialMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6);
+  MEDCouplingFieldDouble* field2=MEDLoader::ReadField(ON_GAUSS_NE,refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6);
+
   int nbcells=corr[1]->getNumberOfTuples();
   CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells);
   //use corr to test equality of field
   DataArrayDouble* f1=field1->getArray();
   DataArrayDouble* f2=field2->getArray();
-  if (_verbose>300) 
+  if (_verbose>300)
     {
       cout << "\nf1 : " << f1->reprZip(); //123.4 for 12th cell,3rd component, 4th gausspoint
       cout << "\nf2 : " << f2->reprZip(); //field2->advancedRepradvancedRepr();
       for (std::size_t i = 0; i < corr.size(); i++)
         cout << "\ncorr " << i << " : " << corr[i]->reprZip();
-    
+
     }
   int nbequal=0;
   int nbptgauss=8;
@@ -1295,12 +1301,206 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnG
         }
     }
   CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp*nbptgauss, nbequal);
-  
+
   for (std::size_t i = 0; i < corr.size(); i++)
     corr[i]->decrRef();
   field1->decrRef();
   field2->decrRef();
   fusedCell->decrRef();
+  refusedMesh->decrRef();
   refusedCellMesh->decrRef();
   cellMesh->decrRef();
+  initialMesh->decrRef();
+}
+
+//================================================================================
+/*!
+ * \brief Test for 0021756: [CEA 602] MEDPartitioner improvements
+ */
+//================================================================================
+
+void MEDPARTITIONERTest::testCreateBoundaryFaces2D()
+{
+  // Fixed complains are:
+  // - 2D is not available
+  // - groups and family handling is bugged (probably due to bug in the handling
+  //   of arrayTo in castIntField())
+  // - creates boundary faces option is not handled
+
+  // Create a 2D mesh in a file
+
+  const char fileName[] = "tmp_testCreateBoundaryFaces2D.med";
+
+  const int idFam1 = 3, idFam2 = 2;
+  int nbFam1, nbFam2, nbc;
+  {
+    const int nbX = 20, nbY = 15;
+    vector<int> conn;
+    vector<double> coor;
+    for (int j=0; j<=nbY; j++)
+      for (int i=0; i<=nbX; i++)
+        {
+          coor.push_back(i+.1);
+          coor.push_back(j+.2);
+        }
+    int ii;
+    for (int j=0; j<nbY; j++)
+      for (int i=0; i<nbX; i++)
+        {
+          ii=i + j*(nbX+1);
+          conn.push_back(ii);
+          conn.push_back(ii+1);
+          ii=ii + nbX + 2 ;
+          conn.push_back(ii);
+          conn.push_back(ii-1);
+        }
+    MEDCouplingUMesh *mesh=MEDCouplingUMesh::New();
+    mesh->setMeshDimension(2);
+
+    nbc=conn.size()/4; //nb of cells
+    mesh->allocateCells(nbc);
+    int* pConn = &conn[0];
+    for(int i=0; i<nbc; i++, pConn+=4)
+      mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,pConn);
+    mesh->finishInsertingCells();
+
+    int nbv=coor.size()/2; //nb of vertices
+    DataArrayDouble *myCoords=DataArrayDouble::New();
+    myCoords->useArray( &coor[0], /*ownership=*/false, CPP_DEALLOC, nbv, 2 );
+    mesh->setCoords(myCoords);
+    mesh->setName("FacesIn2D");
+    myCoords->decrRef();
+    mesh->checkCoherency();
+
+    // groups of cells
+    DataArrayInt* cellsFam=DataArrayInt::New();
+    cellsFam->alloc(nbc,1);
+    nbFam1 = nbc/3, nbFam2 = nbc/2;
+    int iE = 0;
+    for ( int i = 0; i < nbFam1; ++i ) cellsFam->getPointer()[ iE++ ] = idFam1;
+    for ( int i = 0; i < nbFam2; ++i ) cellsFam->getPointer()[ iE++ ] = idFam2;
+    for (            ; iE < nbc;     ) cellsFam->getPointer()[ iE++ ] = 0;
+    map<string,int> theFamilies;
+    theFamilies["FAMILLE_ZERO"]=0;
+    theFamilies["Family1"     ]=idFam1;
+    theFamilies["Family2"     ]=idFam2;
+    map<string, vector<string> > theGroups;
+    theGroups["Group1"].push_back("Family1");
+    theGroups["Group2"].push_back("Family2");
+
+    // write mesh
+    MEDFileUMesh * fileMesh = MEDFileUMesh::New();
+    fileMesh->setMeshAtLevel(0, mesh);
+    fileMesh->setFamilyInfo(theFamilies);
+    fileMesh->setGroupInfo(theGroups);
+    fileMesh->setFamilyFieldArr(0, cellsFam);
+    fileMesh->write(fileName,2);
+
+    cellsFam->decrRef();
+    mesh    ->decrRef();
+    fileMesh->decrRef();
+
+  } // mesh creation
+
+  // Partition the mesh into 4 parts
+
+  const int ndomains = 4;
+  ParaDomainSelector parallelizer(false);
+  MeshCollection collection(fileName,parallelizer);
+  ParallelTopology* aPT = (ParallelTopology*) collection.getTopology();
+  aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector());
+
+  std::auto_ptr< Topology > new_topo;
+#if defined(MED_ENABLE_METIS) || defined(MED_ENABLE_PARMETIS)
+  new_topo.reset( collection.createPartition(ndomains,Graph::METIS) );
+#endif
+#if defined(MED_ENABLE_SCOTCH)
+  if ( !new_topo.get() )
+    new_topo.reset( collection.createPartition(ndomains,Graph::SCOTCH) );
+#endif
+  if ( !new_topo.get() )
+    return;
+
+  // Check that "2D is available"
+
+  const char xmlName[] = "tmp_testCreateBoundaryFaces2D";
+  {
+    MyGlobals::_Creates_Boundary_Faces = true;
+    MeshCollection new_collection(collection,new_topo.get());
+
+    CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes());
+    CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes());
+    CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells());
+    CPPUNIT_ASSERT_EQUAL(0,collection.getNbOfLocalFaces());
+    CPPUNIT_ASSERT      (new_collection.getNbOfLocalFaces() > 0 );
+
+    MyGlobals::_General_Informations.clear();
+    MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=2D"));
+    new_collection.write( xmlName );
+  }
+
+  // Check that "groups and family handling is NOT bugged"
+
+  MeshCollection new_collection(std::string(xmlName)+".xml");
+  std::map< int, int > famId2nb; // count total nb of cells in divided families
+  std::map< int, int >::iterator id2nn;
+  {
+    const std::vector<ParaMEDMEM::DataArrayInt*>& famIdsVec = new_collection.getCellFamilyIds();
+    for ( size_t i = 0; i < famIdsVec.size(); ++i )
+      {
+        ParaMEDMEM::DataArrayInt* famIdsArr = famIdsVec[i];
+        for ( int j = famIdsArr->getNbOfElems()-1; j >= 0; --j )
+          {
+            id2nn = famId2nb.insert( make_pair( famIdsArr->getPointer()[j], 0 )).first;
+            id2nn->second++;
+          }
+      }
+  }
+  CPPUNIT_ASSERT_EQUAL( 3, (int) famId2nb.size() ); // 3 fams/groups in all
+  CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( 0      ));
+  CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( idFam1 ));
+  CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( idFam2 ));
+  CPPUNIT_ASSERT_EQUAL( nbFam1, famId2nb[ idFam1 ]);
+  CPPUNIT_ASSERT_EQUAL( nbFam2, famId2nb[ idFam2 ]);
+  CPPUNIT_ASSERT_EQUAL( nbc - nbFam1 - nbFam2, famId2nb[ 0 ]);
+
+  // Check that "creates boundary faces option is handled"
+
+  famId2nb.clear();
+  const std::vector<ParaMEDMEM::DataArrayInt*>& famIdsVec = new_collection.getFaceFamilyIds();
+  for ( size_t i = 0; i < famIdsVec.size(); ++i )
+    {
+      ParaMEDMEM::DataArrayInt* famIdsArr = famIdsVec[i];
+      for ( int j = famIdsArr->getNbOfElems()-1; j >= 0; --j )
+        {
+          id2nn = famId2nb.insert( make_pair( famIdsArr->getPointer()[j], 0 )).first;
+          id2nn->second++;
+        }
+    }
+
+  CPPUNIT_ASSERT( !famId2nb.empty() );
+
+  // for each "JOINT_n_p_..." group there must be "JOINT_p_n_..." group
+  // of the same size
+  std::map<std::string,int>& famName2id = new_collection.getFamilyInfo();
+  std::map<std::string,int>::iterator na2id = famName2id.begin(), na2id2;
+  std::set< int > okFamIds;
+  okFamIds.insert(0);
+  for ( ; na2id != famName2id.end(); ++na2id )
+    {
+      if ( okFamIds.count( na2id->second ) || na2id->first[0] != 'J')
+        continue;
+      na2id2 = na2id;
+      bool groupOK = false;
+      while ( !groupOK && ++na2id2 != famName2id.end() )
+        groupOK = ( na2id2->first.find_first_not_of( na2id->first ) == std::string::npos );
+
+      CPPUNIT_ASSERT( groupOK );
+      CPPUNIT_ASSERT( na2id->second != na2id2->second);
+      CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( na2id2->second ));
+      CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( na2id->second ));
+      CPPUNIT_ASSERT_EQUAL( (int) famId2nb[ na2id2->second ],
+                            (int) famId2nb[ na2id->second ]);
+      okFamIds.insert( na2id2->second );
+    }
 }