]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
addition of the MEDPartitioner tool (rewriting of medsplitter with MEDCoupling library)
authorvbd <vbd>
Thu, 6 Jan 2011 17:27:05 +0000 (17:27 +0000)
committervbd <vbd>
Thu, 6 Jan 2011 17:27:05 +0000 (17:27 +0000)
28 files changed:
src/MEDPartitioner/MEDPARTITIONER.hxx [new file with mode: 0755]
src/MEDPartitioner/MEDPARTITIONER_Graph.cxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_Graph.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_MESHCollection.cxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_MESHCollection.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_MESHCollectionDriver.cxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_MESHCollectionDriver.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_MESHCollectionMedAsciiDriver.H [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_MESHCollectionMedAsciiDriver.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_MESHCollectionMedXMLDriver.H [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_MESHCollectionMedXMLDriver.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_METISGraph.cxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_METISGraph.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_SCOTCHGraph.cxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_SCOTCHGraph.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_SequentialTopology.cxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_SequentialTopology.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_SkyLineArray.cxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_SkyLineArray.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_Topology.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_UserGraph.cxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_UserGraph.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_utils.hxx [new file with mode: 0644]
src/MEDPartitioner/Makefile.am [new file with mode: 0644]

diff --git a/src/MEDPartitioner/MEDPARTITIONER.hxx b/src/MEDPartitioner/MEDPARTITIONER.hxx
new file mode 100755 (executable)
index 0000000..80e64b0
--- /dev/null
@@ -0,0 +1,38 @@
+ //  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  File   : MEDPARTITIONER.hxx
+//  Author : Alexander A. BORODIN
+//  Module : MED
+//  Exporting/Importing defines for Windows Platform
+//
+#ifndef MEDPARTITIONER_HXX_
+#define MEDPARTITIONER_HXX_
+
+#ifdef WNT
+# if defined MEDPARTITIONER_EXPORTS || defined medsplitter_EXPORTS
+#  define MEDPARTITIONER_EXPORT __declspec( dllexport )
+# else
+#  define MEDPARTITIONER_EXPORT __declspec( dllimport )
+# endif
+#else
+# define MEDPARTITIONER_EXPORT
+#endif
+
+#endif //MEDPARTITIONER_HXX_
diff --git a/src/MEDPartitioner/MEDPARTITIONER_Graph.cxx b/src/MEDPartitioner/MEDPARTITIONER_Graph.cxx
new file mode 100644 (file)
index 0000000..607aef3
--- /dev/null
@@ -0,0 +1,47 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "MEDPARTITIONER_Graph.hxx"
+
+using namespace MEDPARTITIONER;
+
+Graph::Graph(MEDPARTITIONER::MEDSKYLINEARRAY* array, int* edgeweight):m_graph(array),m_partition(0),m_edgeweight(edgeweight),m_cellweight(0)
+{
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+Graph::~Graph()
+{
+  if (m_partition)
+  {
+    delete m_partition;
+    m_partition=0;
+  }
+  if (m_graph)
+  {
+    delete m_graph;
+    m_graph=0;
+  }
+}
+
diff --git a/src/MEDPartitioner/MEDPARTITIONER_Graph.hxx b/src/MEDPartitioner/MEDPARTITIONER_Graph.hxx
new file mode 100644 (file)
index 0000000..50af471
--- /dev/null
@@ -0,0 +1,67 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef MEDPARTITIONER_GRAPH_HXX_
+#define MEDPARTITIONER_GRAPH_HXX_
+
+#include "MEDPARTITIONER.hxx"
+#include "MEDPARTITIONER_SkyLineArray.hxx"
+
+namespace MEDPARTITIONER {
+        
+class ParaDomainSelector;
+class MEDPARTITIONER_EXPORT Graph
+{
+  public:
+    typedef enum {METIS,SCOTCH} splitter_type;
+
+    Graph(){};
+
+    //creates a graph from a SKYLINEARRAY
+    Graph(MEDPARTITIONER::MEDSKYLINEARRAY* graph, int* edgeweight=0);
+
+    virtual ~Graph();
+
+    void setEdgesWeights(int* edgeweight){m_edgeweight=edgeweight;}
+    void setVerticesWeights(int* cellweight){m_cellweight=cellweight;}
+
+    //computes partitioning of the graph
+    virtual void partGraph(int ndomain, const std::string&, ParaDomainSelector* sel=0)=0;
+
+    //! returns the partitioning
+    const int* getPart() const {return m_partition->getValue();}
+
+    //! returns the number of graph vertices (which can correspond to the cells in the mesh!)
+    int nbVertices() const {return m_graph->getNumberOf();}
+
+    const MEDPARTITIONER::MEDSKYLINEARRAY* getGraph() const {return m_graph;}
+
+  protected:
+
+    MEDPARTITIONER::MEDSKYLINEARRAY* m_graph;
+
+    MEDPARTITIONER::MEDSKYLINEARRAY* m_partition;
+
+    int* m_edgeweight;  
+
+    int* m_cellweight;
+  };
+
+}
+#endif /*GRAPH_HXX_*/
diff --git a/src/MEDPartitioner/MEDPARTITIONER_MESHCollection.cxx b/src/MEDPartitioner/MEDPARTITIONER_MESHCollection.cxx
new file mode 100644 (file)
index 0000000..65addd7
--- /dev/null
@@ -0,0 +1,2159 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "MEDMEM_Exception.hxx"
+
+#include "MEDCouplingUMesh.hxx"
+#include "MEDPARTITIONER_utils.hxx" 
+
+#include "MEDPARTITIONER_Graph.hxx"
+
+#include "MEDPARTITIONER_Topology.hxx"
+#include "MEDPARTITIONER_ParallelTopology.hxx"
+#include "MEDPARTITIONER_SequentialTopology.hxx"
+#include "MEDPARTITIONER_ParaDomainSelector.hxx"
+//#include "MEDPARTITIONER_MeshSendReceive.hxx"
+//#include "MEDPARTITIONER_JointExchangeData.hxx"
+
+#include "MEDPARTITIONER_MESHCollection.hxx"
+#include "MEDPARTITIONER_MESHCollectionDriver.hxx"
+#include "MEDPARTITIONER_MESHCollectionMedXMLDriver.hxx"
+#include "MEDPARTITIONER_MESHCollectionMedAsciiDriver.hxx"
+
+#include "MEDPARTITIONER_UserGraph.hxx"
+
+#ifdef ENABLE_METIS
+#include "MEDPARTITIONER_METISGraph.hxx"
+#endif
+#ifdef ENABLE_SCOTCH
+#include "MEDPARTITIONER_SCOTCHGraph.hxx"
+#endif
+
+#include <vector>
+#include <string>
+
+#ifndef WNT
+# include <ext/hash_map>
+#else
+# include <hash_map>
+#endif
+#include <set>
+
+#include <iostream>
+#include <fstream>
+
+using namespace MEDPARTITIONER;
+
+#ifndef WNT
+using namespace __gnu_cxx;
+#else
+using namespace std;
+#endif
+
+//template inclusion
+//#include "MEDPARTITIONER_MESHCollection.H"
+
+MESHCollection::MESHCollection()
+  : _topology(0),
+    _owns_topology(false),
+    _driver(0),
+    _domain_selector( 0 ),
+    _i_non_empty_mesh(-1),
+    _driver_type(MEDPARTITIONER::MedXML),
+    _subdomain_boundary_creates(false),
+    _family_splitting(false),
+    _create_empty_groups(false)
+{
+}
+
+/*!constructor creating a new mesh collection (mesh series + topology)
+ *from an old collection and a new topology
+ * 
+ * On output, the constructor has built the meshes corresponding to the new mesh collection.
+ * The new topology has been updated so that face and node mappings are included.
+ * The families have been cast to their projections in the new topology.
+ * 
+ * \param initial_collection collection from which the data (coordinates, connectivity) are taken
+ * \param topology topology containing the cell mappings
+ */
+
+MESHCollection::MESHCollection(MESHCollection& initial_collection, Topology* topology, bool family_splitting, bool create_empty_groups)
+  : _name(initial_collection._name),
+    _topology(topology),
+    _owns_topology(false),
+    _driver(0),
+    _domain_selector( initial_collection._domain_selector ),
+    _i_non_empty_mesh(-1),
+    _driver_type(MEDPARTITIONER::MedXML),
+    _subdomain_boundary_creates(false),
+    _family_splitting(family_splitting),
+    _create_empty_groups(create_empty_groups)
+{
+  string mesh_name = initial_collection.getName();
+  _mesh.resize(_topology->nbDomain());
+       
+       //splitting the initial domains into smaller bits
+  
+       std::vector<std::vector<ParaMEDMEM::MEDCouplingUMesh*> > splitMeshes;
+  splitMeshes.resize(topology->nbDomain());
+  for (int inew=0; inew<topology->nbDomain();inew++)
+    splitMeshes[inew].resize(initial_collection.getTopology()->nbDomain());
+  
+  for (int iold=0; iold<initial_collection.getTopology()->nbDomain();iold++)
+    {
+      if (!isParallelMode() || initial_collection._domain_selector->isMyDomain(iold))
+        {
+          int size=(initial_collection._mesh)[iold]->getNumberOfCells();
+          std::vector<int> globalids(size);
+          initial_collection.getTopology()->getCellList(iold, &globalids[0]);
+          std::vector<int> ilocalnew(size);
+          std::vector<int> ipnew(size);
+          topology->convertGlobalCellList(&globalids[0],size,&ilocalnew[0],&ipnew[0]);
+          std::vector<std::vector<int> > ids(topology->nbDomain());
+          for (int i=0; i<ilocalnew.size();i++)
+            {
+              ids[ipnew[i]].push_back(i);
+            }
+          for (int inew=0;inew<topology->nbDomain();inew++)
+            {
+              splitMeshes[inew][iold]=(ParaMEDMEM::MEDCouplingUMesh*)(initial_collection.getMesh())[iold]->buildPartOfMySelf(&ids[inew][0],&ids[inew][0]+ids[inew].size(),true);
+              //              cout <<"small domain "<<iold<<" "<<inew<<" has "<<splitMeshes[inew][iold]->getNumberOfCells()<<" cells"<<endl;
+            }
+        }
+    }
+
+  if (isParallelMode())
+    {
+      //send/receive stuff
+    }
+  
+  //fusing the split meshes
+  for (int inew=0; inew<topology->nbDomain()   ;inew++)
+    {
+      std::vector<const ParaMEDMEM::MEDCouplingUMesh*> meshes(splitMeshes[inew].size());
+      for (int i=0; i< splitMeshes[inew].size();i++)
+        meshes[i]=splitMeshes[inew][i];
+      
+      if (!isParallelMode()||_domain_selector->isMyDomain(inew))
+        {
+          _mesh[inew]=ParaMEDMEM::MEDCouplingUMesh::mergeUMeshes(meshes);
+          _mesh[inew]->zipCoords();
+         
+          //          std::cout<<"creating mesh #"<<inew+1<<" with "<<_mesh[inew]->getNumberOfCells()<<" cells and "<<_mesh[inew]->getNumberOfNodes()<<" nodes"<<std::endl;
+        }
+      for (int i=0; i< splitMeshes[inew].size();i++)
+        splitMeshes[inew][i]->decrRef();
+    }  
+  std::multimap<pair<int,int>, pair<int,int> > nodeMapping;
+  createNodeMapping(initial_collection, nodeMapping);
+  castMeshes(initial_collection.getFaceMesh(), this->getFaceMesh(),initial_collection, nodeMapping);
+  int nbOfGroups =  initial_collection.getGroupMeshes(0).size();
+  _groupMesh.resize(nbOfGroups);
+  for (int igroup=0; igroup<nbOfGroups; igroup++)
+    {
+      castMeshes((initial_collection.getGroupMeshes())[igroup],
+                 (this->getGroupMeshes())[igroup],
+                 initial_collection, nodeMapping);
+      for (int inew=0; inew<_topology->nbDomain(); inew++)
+        _groupMesh[igroup][inew]->setName((initial_collection.getGroupMeshes())[igroup][0]->getName());
+    }
+}
+
+void MESHCollection::createNodeMapping( MESHCollection& initialCollection, std::multimap<pair<int,int>,pair<int,int> >& nodeMapping)
+{
+  for (int iold=0; iold<initialCollection.getTopology()->nbDomain();iold++)
+    {
+      std::map<pair<double,pair<double, double> >, int > nodeClassifier;
+      for (int inode=0; inode<initialCollection.getMesh(iold)->getNumberOfNodes(); inode++)
+        {
+          ParaMEDMEM::DataArrayDouble* coords = initialCollection.getMesh(iold)->getCoords();
+          double* coordsPtr=coords->getPointer()+initialCollection.getMesh(iold)->getMeshDimension()*inode;
+          pair<double, pair<double,double> > tripleDouble =std::make_pair(coordsPtr[0],std::make_pair(coordsPtr[1],coordsPtr[2]));
+          nodeClassifier.insert(make_pair(tripleDouble,inode));
+          
+        }
+      for (int inew=0; inew<_topology->nbDomain(); inew++)
+        {
+          for (int inode=0; inode<_mesh[inew]->getNumberOfNodes();inode++)
+            {
+              ParaMEDMEM::DataArrayDouble* coords = getMesh(inew)->getCoords();
+              double* coordsPtr=coords->getPointer()+inode*getMesh(inew)->getMeshDimension();
+              std::map<pair<double,pair<double, double> >, int >::iterator iter=
+                nodeClassifier.find(make_pair(coordsPtr[0],make_pair(coordsPtr[1],coordsPtr[2])));
+              nodeMapping.insert(make_pair(make_pair(iold,iter->second),make_pair(inew,inode)));
+              //              cout <<"("<<iold<<","<<iter->second<<")-->("<<inew<<","<<inode<<")"<<endl;
+            }
+        }
+    } 
+}
+
+/*!
+creates the face meshes on the new domains from the faces on the old domain and the node mapping
+faces at the interface are duplicated
+*/
+
+void MESHCollection::castMeshes(std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom,std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo, MESHCollection& initialCollection,const multimap<pair<int,int>,pair<int,int> >& nodeMapping)
+{
+
+  //splitMeshes structure will contain the partition of 
+  //the old faces on the new ones
+  // splitMeshes[4][2] contains the faces from old domain 2
+  // that have to be added to domain 4
+
+  vector< vector<ParaMEDMEM::MEDCouplingUMesh*> > splitMeshes;
+  int newSize=_topology->nbDomain();
+  splitMeshes.resize ( newSize );
+  for (int inew=0;inew<newSize;inew++)
+    {
+      splitMeshes[inew].resize(meshesCastFrom.size());
+    }
+
+
+  //loop over the old domains to analyse the faces and decide 
+  //on which new domain they belong
+         for (int iold=0; iold<meshesCastFrom.size();iold++)
+    {
+      vector<vector<int> > newFaceMeshesIds(newSize);
+      for (int ielem=0;ielem<meshesCastFrom[iold]->getNumberOfCells();ielem++)
+        {
+          std::vector<int> nodes;
+          meshesCastFrom[iold]->getNodeIdsOfCell(ielem,nodes);
+          
+          map <int,int> faces;
+          //      cout<<"----------------"<<endl;
+          //analysis of one face
+          for (int inode=0;inode<nodes.size();inode++)
+            {
+              typedef multimap<pair<int,int>,pair<int,int> >::const_iterator MI;
+              pair <MI,MI> myRange = nodeMapping.equal_range(make_pair(iold,nodes[inode]));
+              //                cout << iold <<" " <<nodes[inode]<<endl;
+              for (MI iter=myRange.first; iter!=myRange.second; iter++)
+                {
+                  if (faces.find(iter->second.first)==faces.end())
+                    faces[iter->second.first]=1;
+                  else
+                    faces[iter->second.first]++;
+                  //                    cout<<"idomain" << iter->second.first<<" facemapping "<<faces[iter->second.first]<<endl;
+                }
+            }
+          
+          for (map<int,int>::iterator iter=faces.begin();
+               iter!=faces.end();
+               iter++)
+            {
+              if (iter->second==nodes.size())
+                newFaceMeshesIds[iter->first].push_back(ielem);
+            }
+        }        
+      
+      //creating the splitMeshes from the face ids
+      for (int inew=0;inew<_topology->nbDomain();inew++)
+        {
+          //          cout<<"nb faces "<<newFaceMeshesIds[inew].size()<<endl;
+          splitMeshes[inew][iold]=(ParaMEDMEM::MEDCouplingUMesh*)(meshesCastFrom[iold]->buildPartOfMySelf(&newFaceMeshesIds[inew][0],&newFaceMeshesIds[inew][0]+newFaceMeshesIds[inew].size(),true));
+        }
+    }
+      
+// send/receive stuff
+
+
+//recollecting the bits of splitMeshes to fuse them into one
+  meshesCastTo.resize(newSize);
+  for (int inew=0; inew < newSize;inew++)
+    {
+      vector<const ParaMEDMEM::MEDCouplingUMesh*> myMeshes(meshesCastFrom.size());
+      for (int iold=0; iold < meshesCastFrom.size();iold++)
+        {
+          myMeshes[iold]=splitMeshes[inew][iold];
+          cout<<"number of nodes"<<splitMeshes[inew][iold]->getNumberOfNodes()<<endl;
+          cout<<"number of cells"<<splitMeshes[inew][iold]->getNumberOfCells()<<endl;
+          cout<<"dimension "<<splitMeshes[inew][iold]->getMeshDimension()<<endl;
+          
+        }
+      meshesCastTo[inew]=ParaMEDMEM::MEDCouplingUMesh::mergeUMeshes(myMeshes);
+      meshesCastTo[inew]->zipCoords();
+      for (int iold=0; iold < meshesCastFrom.size();iold++)
+             splitMeshes[inew][iold]->decrRef();
+      cout<<"creating face mesh #"<<inew<<" with "<<meshesCastTo[inew]->getNumberOfCells()<<" cells and "<<meshesCastTo[inew]->getNumberOfNodes()<<" nodes"<<endl;
+    }
+}
+
+
+/*! constructing the MESH collection from a distributed file
+ *
+ * \param filename name of the master file containing the list of all the MED files
+ */
+MESHCollection::MESHCollection(const string& filename)
+  : _topology(0),
+    _owns_topology(true),
+    _driver(0),
+    _domain_selector( 0 ),
+    _i_non_empty_mesh(-1),
+    _driver_type(MEDPARTITIONER::Undefined),
+    _subdomain_boundary_creates(false),
+    _family_splitting(false),
+    _create_empty_groups(false)
+{
+  char filenamechar[256];
+  strcpy(filenamechar,filename.c_str());
+  try
+    {
+      _driver=new MESHCollectionMedXMLDriver(this);
+      _driver->read (filenamechar);
+      _driver_type = MedXML;
+
+    }
+  catch(MEDMEM::MEDEXCEPTION){
+    delete _driver;
+    try
+      {
+        _driver=new MESHCollectionMedAsciiDriver(this);
+        _driver->read (filenamechar);
+        _driver_type=MedAscii;
+      }
+    catch(MEDMEM::MEDEXCEPTION&)
+      {
+        delete _driver;
+        throw MEDMEM::MEDEXCEPTION("file does not comply with any recognized format");
+      }
+  }
+  for ( int idomain = 0; idomain < _mesh.size(); ++idomain )
+    if ( _mesh[idomain] && _mesh[idomain]->getNumberOfNodes() > 0 )
+      _i_non_empty_mesh = idomain;
+}
+
+/*! Constructing the MESH collection from selected domains of a distributed file
+ * 
+ * \param filename  - name of the master file containing the list of all the MED files
+ * \param domainSelector - selector of domains to load
+ */
+MESHCollection::MESHCollection(const string& filename, ParaDomainSelector& domainSelector)
+  : _topology(0),
+    _owns_topology(true),
+    _driver(0),
+    _domain_selector( domainSelector.nbProcs() > 1 ? & domainSelector : 0 ),
+    _i_non_empty_mesh(-1),
+    _driver_type(MEDPARTITIONER::Undefined),
+    _subdomain_boundary_creates(false),
+    _family_splitting(false),
+    _create_empty_groups(false)
+{
+  try
+    {
+      _driver=new MESHCollectionMedXMLDriver(this);
+      _driver->read ( (char*)filename.c_str(), _domain_selector );
+      _driver_type = MedXML;
+    }
+  catch(MEDMEM::MEDEXCEPTION&)
+    {
+      delete _driver;
+      try
+        {
+          _driver=new MESHCollectionMedAsciiDriver(this);
+          _driver->read ( (char*)filename.c_str(), _domain_selector );
+          _driver_type=MedAscii;
+        }
+      catch(MEDMEM::MEDEXCEPTION&)
+        {
+          delete _driver;
+          throw MEDMEM::MEDEXCEPTION("file does not comply with any recognized format");
+        }
+    }
+  if ( isParallelMode() )
+    // to know nb of cells on each proc to compute global cell ids from locally global
+    _domain_selector->gatherNbOf( getMesh() );
+
+  // find non-empty domain mesh
+  for ( int idomain = 0; idomain < _mesh.size(); ++idomain )
+    if ( _mesh[idomain] && _mesh[idomain]->getNumberOfNodes() > 0 )
+      _i_non_empty_mesh = idomain;
+}
+
+/*! constructing the MESH collection from a sequential MED-file
+ * 
+ * \param filename MED file
+ * \param meshname name of the mesh that is to be read
+ */
+MESHCollection::MESHCollection(const string& filename, const string& meshname)
+  : _name(meshname),
+    _topology(0),
+    _owns_topology(true),
+    _driver(0),
+    _domain_selector( 0 ),
+    _i_non_empty_mesh(-1),
+    _driver_type(MEDPARTITIONER::MedXML),
+    _subdomain_boundary_creates(false),
+    _family_splitting(false),
+    _create_empty_groups(false)
+{
+  char filenamechar[256];
+  char meshnamechar[256];
+  strcpy(filenamechar,filename.c_str());
+  strcpy(meshnamechar,meshname.c_str());
+  try // avoid memory leak in case of inexistent filename
+    {
+      retrieveDriver()->readSeq (filenamechar,meshnamechar);
+    }
+  catch ( MED_EXCEPTION& e )
+    {
+      if ( _driver ) delete _driver; _driver=0;
+      throw e;
+    }
+  if ( _mesh[0] && _mesh[0]->getNumberOfNodes() > 0 )
+    _i_non_empty_mesh = 0;
+}
+
+MESHCollection::~MESHCollection()
+{
+  for (int i=0; i<_mesh.size();i++)
+    if (_mesh[i]!=0) {/*delete*/ _mesh[i]->decrRef(); }
+  for (int i=0; i<_faceMesh.size();i++)
+    if (_mesh[i]!=0) {/*delete*/ _faceMesh[i]->decrRef(); }
+  for (int i=0; i<_groupMesh.size();i++)
+    for (int j=0; j<_groupMesh[i].size(); j++)
+      _groupMesh[i][j]->decrRef();
+  for (int i=0; i<_connect_zones.size();i++)
+    if (_connect_zones[i]!=0) {delete _connect_zones[i];}
+  if (_driver !=0) {delete _driver; _driver=0;}
+  if (_topology!=0 && _owns_topology) {delete _topology; _topology=0;}
+}
+
+
+/*! constructing the MESH collection from a file
+ * 
+ * The method creates as many MED-files as there are domains in the 
+ * collection. It also creates a master file that lists all the MED files.
+ * The MED files created in ths manner contain joints that describe the 
+ * connectivity between subdomains.
+ * 
+ * \param filename name of the master file that will contain the list of the MED files
+ * 
+ */
+void MESHCollection::write(const string& filename)
+{
+  //building the connect zones necessary for writing joints
+  cout<<"Building Connect Zones"<<endl;
+//   if (_topology->nbDomain()>1)
+//     buildConnectZones();
+  cout <<"End of connect zones building"<<endl;
+  //suppresses link with driver so that it can be changed for writing
+  if (_driver!=0)delete _driver;
+  _driver=0;
+
+  char filenamechar[256];
+  strcpy(filenamechar,filename.c_str());
+  retrieveDriver()->write (filenamechar, _domain_selector);
+}
+
+/*! creates or gets the link to the collection driver
+ */
+MESHCollectionDriver* MESHCollection::retrieveDriver()
+{
+  if (_driver==0)
+    {
+      switch(_driver_type)
+        {
+        case MedXML:
+          _driver=new MESHCollectionMedXMLDriver(this);
+          break;
+        case MedAscii:
+          _driver=new MESHCollectionMedAsciiDriver(this);
+          break;
+        default:
+          throw MEDMEM::MEDEXCEPTION("Unrecognized driver");
+        }
+    }
+
+  return _driver;
+}
+
+
+/*! gets an existing driver
+ * 
+ */
+MESHCollectionDriver* MESHCollection::getDriver() const
+{
+  return _driver;
+}
+// /*! retrieves the mesh dimension*/
+ int MESHCollection::getMeshDimension() const
+ {
+   return _i_non_empty_mesh < 0 ? -1 : _mesh[_i_non_empty_mesh]->getMeshDimension();
+ }
+
+ vector<ParaMEDMEM::MEDCouplingUMesh*>& MESHCollection::getMesh() 
+ {
+   return _mesh;
+ }
+ vector<ParaMEDMEM::MEDCouplingUMesh*>& MESHCollection::getFaceMesh() 
+ {
+   return _faceMesh;
+ }
+vector<vector<ParaMEDMEM::MEDCouplingUMesh*> >& MESHCollection::getGroupMeshes() 
+ {
+   return _groupMesh;
+ }
+ParaMEDMEM::MEDCouplingUMesh* MESHCollection::getMesh(int idomain)
+{
+  return _mesh[idomain];
+}
+
+ParaMEDMEM::MEDCouplingUMesh* MESHCollection::getFaceMesh(int idomain)
+{
+  return _faceMesh[idomain];
+}
+vector<ParaMEDMEM::MEDCouplingUMesh*>& MESHCollection::getGroupMeshes(int idomain)
+{
+  return _groupMesh[idomain];
+}
+ vector<MEDPARTITIONER::CONNECTZONE*>& MESHCollection::getCZ()
+ {
+   return _connect_zones;
+ }
+
+Topology* MESHCollection::getTopology() const 
+ {
+   return _topology;
+ }
+
+void MESHCollection::setTopology(Topology* topo)
+ {
+   if (_topology!=0)
+   {
+     throw MEDMEM::MEDEXCEPTION("Erreur : topology is already set");
+   }
+   else
+     _topology = topo;
+ }
+
+
+/*! Method creating the cell graph
+ * 
+ * \param array returns the pointer to the structure that contains the graph 
+ * \param edgeweight returns the pointer to the table that contains the edgeweights
+ *        (only used if indivisible regions are required)
+ */
+
+void MESHCollection::buildCellGraph(MEDPARTITIONER::MEDSKYLINEARRAY* & array,int *& edgeweights )
+{
+
+  multimap< int, int > node2cell;
+  multimap< int, int > cell2cell;
+
+  //looking for reverse nodal connectivity i global numbering
+  for (int idomain=0; idomain<_topology->nbDomain();idomain++)
+    {
+      ParaMEDMEM::DataArrayInt* index=ParaMEDMEM::DataArrayInt::New();
+      ParaMEDMEM::DataArrayInt* revConn=ParaMEDMEM::DataArrayInt::New();
+      _mesh[idomain]->getReverseNodalConnectivity(revConn,index);
+      int* index_ptr=index->getPointer();
+      ParaMEDMEM::DataArrayInt* globalRevConn=revConn->deepCpy();
+      _topology->convertCellToGlobal(idomain,
+                                     revConn->getPointer(),
+                                     index_ptr[_mesh[idomain]->getNumberOfNodes()],
+                                     globalRevConn->getPointer());
+
+      int min=10000000,max=-1;
+      for (int i=0; i< index_ptr[_mesh[idomain]->getNumberOfNodes()];i++)
+        {
+          if (revConn->getPointer()[i]<min) min=revConn->getPointer()[i];
+          if (revConn->getPointer()[i]>max) max=revConn->getPointer()[i];
+        }
+      cout <<"min:"<<min<<" max:"<<max<<endl;
+      int* globalNodeIds=new int[_mesh[idomain]->getNumberOfNodes()];
+      _topology->getNodeList(idomain,globalNodeIds);
+     
+      int* globalRevConnPtr=globalRevConn->getPointer();
+      for (int i=0; i<_mesh[idomain]->getNumberOfNodes();i++)
+        {
+          for (int icell=index_ptr[i]; icell<index_ptr[i+1];icell++)
+            node2cell.insert(make_pair(globalNodeIds[i],globalRevConnPtr[icell]));
+        }
+      globalRevConn->decrRef();
+      revConn->decrRef();
+      index->decrRef();
+      delete[]globalNodeIds;
+    }
+
+  //creating graph arcs (cell to cell relations)
+  //arcs are stored in terms of (index,value) notation
+  // 0 3 5 6 6
+  // 1 2 3 2 3 3 
+  // means 6 arcs (0,1), (0,2), (0,3), (1,2), (1,3), (2,3)
+  // in present version arcs are not doubled but reflexive (1,1) arcs are present for each cell
+  for (int inode=0; inode<_topology->nbNodes();inode++)
+    {
+      typedef multimap<int,int>::const_iterator MI;
+      pair <MI,MI> myRange = node2cell.equal_range(inode);
+      for (MI cell1=myRange.first; cell1!=myRange.second; cell1++)
+        {
+          for (MI cell2 = myRange.first; cell2!=myRange.second; cell2++)
+            {
+              if (cell1->second!=cell2->second) cell2cell.insert(make_pair(cell1->second,cell2->second));
+            }
+        }
+    }
+
+  //filling up index and value to create skylinearray structure
+
+  multimap<int,int>::const_iterator iter;
+
+  iter=cell2cell.begin();
+  vector <int> index,value;
+  index.push_back(0);
+  while (iter != cell2cell.end())
+    {
+      multimap<int,int>::const_iterator next_iter = cell2cell.upper_bound(iter->first);
+      int size=0;
+      for (multimap<int,int>::const_iterator current_iter=iter; current_iter!=next_iter; current_iter++)
+        {
+          value.push_back(current_iter->second);
+          size++;
+        }
+      index.push_back(index[index.size()-1]+size);
+
+      
+      iter=next_iter;
+    }
+
+  array=new MEDPARTITIONER::MEDSKYLINEARRAY(index,value);
+  cout<<"taille du graphe créé "<<array->getNumberOf()<<endl;
+//   int cell_number=1;
+//   int node_number=1;
+//   for (int i=0; i<_topology->nbDomain(); i++)
+//     {
+//       cell_number+=_topology->getCellNumber(i);
+//       node_number+=_topology->getNodeNumber(i);
+//     }
+//   //list of cells for a given node
+//   //vector< vector<int> > node2cell(node_number);
+//   map< int, vector<int> > node2cell;
+
+//   //list of nodes for a given cell
+//   //vector< vector <int> > cell2node(cell_number);
+//   map< int, vector <int> > cell2node;
+
+//   //  map<MED_EN::medGeometryElement,int*> type_cell_list;
+
+//   //tagging for the indivisible regions
+//   int* indivisible_tag=0;
+//   bool has_indivisible_regions=false;
+// //   if (!_indivisible_regions.empty())
+// //     {
+// //       has_indivisible_regions=true;
+// //       indivisible_tag=new int[_topology->nbCells()];
+// //       treatIndivisibleRegions(indivisible_tag);
+// //     }
+
+//   fillGlobalConnectivity(node2cell, cell2node );
+
+//   cout << "beginning of skyline creation"<<endl;
+//   //creating the MEDMEMSKYLINEARRAY containing the graph
+
+//   int* size = new int[_topology->nbCells()];
+//   int** temp=new int*[_topology->nbCells()];
+//   int** temp_edgeweight=0;
+// //   if (has_indivisible_regions)
+// //     temp_edgeweight=new int*[_topology->nbCells()];
+
+//   int cell_glob_shift = 0;
+
+//   // Get connection to cells on other procs
+//   multimap< int, int > loc2dist; // global cell ids on this proc -> other proc cells
+//   if ( isParallelMode() )
+//     {
+//       cell_glob_shift = _domain_selector->getProcShift();
+
+//       set<int> loc_domains; // domains on this proc
+//       for ( int idom = 0; idom < _mesh.size(); ++idom )
+//         if ( _mesh[ idom ] )
+//           loc_domains.insert( idom );
+
+//       for ( int idom = 0; idom < _mesh.size(); ++idom )
+//         {
+//           if ( !_mesh[idom] ) continue;
+//           vector<int> loc2glob_corr; // pairs of corresponding cells (loc_loc & glob_dist)
+//           retrieveDriver()->readLoc2GlobCellConnect(idom, loc_domains, _domain_selector, loc2glob_corr);
+//           //MEDMEM::STRING out;
+//           for ( int i = 0; i < loc2glob_corr.size(); i += 2 )
+//             {
+//               int glob_here  = _topology->convertCellToGlobal(idom,loc2glob_corr[i]); 
+//               int glob_there = loc2glob_corr[i+1]; 
+//               loc2dist.insert ( make_pair( glob_here, glob_there));
+//               //out << glob_here << "-" << glob_there << " ";
+//             }
+//           //cout << "\nRank " << _domain_selector->rank() << ": BndCZ: " << out << endl;
+//         }
+//     }
+
+//   //going across all cells
+
+//   map<int,int> cells_neighbours;
+//   for (int i=0; i< _topology->nbCells(); i++)
+//     {
+
+
+//       vector<int> cells(50);
+
+//       //     /*// cout << "size cell2node "<<cell2node[i+1].size()<<endl;
+//       //      for (vector<int>::const_iterator iternode=cell2node[i+1].begin();
+//       //            iternode!=cell2node[i+1].end();
+//       //            iternode++)
+//       //        {
+//       //          int nodeid=*iternode;
+//       //       //   cout << "size node2cell "<<node2cell[nodeid].size()<<endl;
+//       //          for (vector<int>::const_iterator iter=node2cell[nodeid].begin();
+//       //             iter != node2cell[nodeid].end();
+//       //             iter++)
+//       //              cells_neighbours[*iter]++;
+//       //        }*/
+
+//       for (int inode=0; inode< cell2node[i+1].size(); inode++)
+//         {
+//           int nodeid=cell2node[i+1][inode];
+//           //   cout << "size node2cell "<<node2cell[nodeid].size()<<endl;
+//           for (int icell=0; icell<node2cell[nodeid].size();icell++)
+//             cells_neighbours[node2cell[nodeid][icell]]++;
+//         }
+//       size[i]=0;
+//       int dimension = getMeshDimension();
+//       cells.clear();
+
+//       for (map<int,int>::const_iterator iter=cells_neighbours.begin(); iter != cells_neighbours.end(); iter++)  
+//         {
+//           if (iter->second >= dimension && iter->first != i+1) 
+//             {
+//               cells.push_back(iter->first + cell_glob_shift);
+//               //       cells[isize++]=iter->first;
+//             }
+//         }
+//       // add neighbour cells from distant domains
+//       multimap< int, int >::iterator loc_dist = loc2dist.find( i+1 );
+//       for (; loc_dist!=loc2dist.end() && loc_dist->first==( i+1 ); ++loc_dist )
+//         cells.push_back( loc_dist->second );
+
+//       size[i]=cells.size();
+//       //   size[i]=isize;
+
+//       //cout << cells.size()<<endl;
+//       //cout << cells_neighbours.size()<<endl;
+
+//       temp[i]=new int[size[i]];
+// //       if (has_indivisible_regions)
+// //         temp_edgeweight[i]=new int[size[i]];
+//       //    
+//       int itemp=0;
+
+//       // memcpy(temp[i],cells,isize*sizeof(int));
+
+//       for (vector<int>::const_iterator iter=cells.begin(); iter!=cells.end();iter++)
+//         //for(int j=0; j<isize; j++)
+//         {
+//           temp[i][itemp]=*iter;
+//           //temp[i][itemp]=cells[j];
+//  //          if (has_indivisible_regions)
+// //             {
+// //               int tag1 = indivisible_tag[(i+1)-1];
+// //               //int tag2 = indivisible_tag[iter->first-1];
+// //               int tag2 = indivisible_tag[*iter-1];
+// //               if (tag1==tag2 && tag1!=0)
+// //                 temp_edgeweight[i][itemp]=_topology->nbCells()*100000;
+// //               else
+// //                 temp_edgeweight[i][itemp]=1;
+// //             } 
+//           itemp++;
+//         }
+//       cells_neighbours.clear();
+//     }
+//   cout <<"end of graph definition"<<endl;
+//   int* index=new int[_topology->nbCells()+1];
+//   index[0]=1;
+//   for (int i=0; i<_topology->nbCells(); i++)
+//     index[i+1]=index[i]+size[i];
+
+//   node2cell.clear();
+//   cell2node.clear();
+//   // if (indivisible_tag!=0) delete [] indivisible_tag;
+
+//   //SKYLINEARRAY structure holding the cell graph
+//   array= new MEDMEM::MEDSKYLINEARRAY(_topology->nbCells(),index[_topology->nbCells()]-index[0]);
+//   array->setIndex(index);
+
+//   for (int i=0; i<_topology->nbCells(); i++)
+//     {
+//       array->setI(i+1,temp[i]);
+//       delete[]temp[i];
+//     }
+
+//   {// DEBUG
+//     //     MEDMEM::STRING out;
+//     //     const int* index= array->getIndex();
+//     //     const int* value =array->getValue();
+//     //     out << "\nRank " << (_domain_selector?_domain_selector->rank():0) << ": Index: ";
+//     //     for ( int i = 0; i <= array->getNumberOf(); ++i )
+//     //       out << index[i] << " ";
+//     //     out << "\nRank " << (_domain_selector?_domain_selector->rank():0) << ": Value: ";
+//     //     for ( int i = 0; i < array->getLength(); ++i )
+//     //       out << value[i] << " ";
+//     //     cout << out << endl;
+//   }
+// //   if (has_indivisible_regions)
+// //     {
+// //       edgeweights=new int[array->getLength()];
+// //       for (int i=0; i<_topology->nbCells(); i++)
+// //         {
+// //           for (int j=index[i]; j<index[i+1];j++)
+// //             edgeweights[j-1]=temp_edgeweight[i][j-index[i]];
+// //           delete[] temp_edgeweight[i];  
+// //         }
+// //       delete[]temp_edgeweight;
+// //     }
+//   delete[] index;
+//   delete[] temp;
+//   delete[] size;
+
+  cout<< "end of graph creation"<<endl;
+}
+
+/*! Creates the partition corresponding to the cell graph and the partition number
+ * 
+ * \param nbdomain number of subdomains for the newly created graph
+ * 
+ * returns a topology based on the new graph
+ */
+Topology* MESHCollection::createPartition(int nbdomain, 
+                                          Graph::splitter_type split, 
+                                          const string& options_string,
+                                          int* user_edge_weights,
+                                          int* user_vertices_weights)
+{
+  if (nbdomain <1) throw MEDMEM::MEDEXCEPTION("Number of subdomains must be >0");
+  MEDPARTITIONER::MEDSKYLINEARRAY* array=0;
+  int* edgeweights=0;
+
+  cout<<"Building cell graph";
+  //   if ( _domain_selector )
+  //     buildCellGraphParallel(array,edgeweights);
+  //   else
+  buildCellGraph(array,edgeweights);
+  Graph* cellGraph;
+  switch (split)
+    {
+    case Graph::METIS:
+#ifdef ENABLE_METIS
+      cellGraph=(Graph*)(new METISGraph(array,edgeweights));
+#else
+      throw MEDMEM::MEDEXCEPTION("METIS Graph is not available. Check your products, please.");
+#endif
+      break;
+    case Graph::SCOTCH:
+#ifdef ENABLE_SCOTCH
+      cellGraph=(Graph*)(new SCOTCHGraph(array,edgeweights));
+#else
+      throw MEDMEM::MEDEXCEPTION("SCOTCH Graph is not available. Check your products, please.");
+#endif
+      break;
+    }
+
+  //!user-defined weights
+  if (user_edge_weights!=0) 
+    cellGraph->setEdgesWeights(user_edge_weights);
+  if (user_vertices_weights!=0)
+    cellGraph->setVerticesWeights(user_vertices_weights);
+
+  cout<<"Partitioning graph";
+  cellGraph->partGraph(nbdomain,options_string,_domain_selector);
+
+  // DEBUG
+  //   MEDMEM::STRING out("RESULT GRAPH #");
+  //   out << (_domain_selector?_domain_selector->rank():0) << ": ";
+  //   const int* part = cellGraph->getPart();
+  //   int n = cellGraph->nbVertices();
+  //   for ( int e=0; e < n; ++e )
+  //     out << part[e] <<" ";
+  //   cout << out << endl;
+  
+
+  cout<<"Building new topology";
+  //cellGraph is a shared pointer 
+  Topology* topology = new ParallelTopology (cellGraph, nbdomain, getMeshDimension());
+
+  //cleaning
+  if (edgeweights!=0) delete[] edgeweights;
+  // if (array!=0) delete array;
+  cout<<"End of partition creation";
+  delete cellGraph;
+
+  return topology;
+}
+
+/*! Creates a topology for a partition specified by the user
+ * 
+ * \param table user-specified partition (for each cell contains the domain number from 0 to n-1)
+ * 
+ * returns a topology based on the new partition
+ */
+Topology* MESHCollection::createPartition(const int* partition)
+{
+  MEDPARTITIONER::MEDSKYLINEARRAY* array=0;
+  int* edgeweights=0;
+
+  buildCellGraph(array,edgeweights);
+  Graph* cellGraph;
+  set<int> domains;
+  for (int i=0; i<_topology->nbCells(); i++)
+    {
+      domains.insert(partition[i]);
+    }
+  int nbdomain=domains.size();
+  
+  cellGraph=(Graph*)(new UserGraph(array, partition, _topology->nbCells()));
+  
+  //cellGraph is a shared pointer 
+  Topology* topology = new ParallelTopology (cellGraph, nbdomain, getMeshDimension());
+  
+  //  if (array!=0) delete array;
+  delete cellGraph;
+  return topology;
+}
+
+
+/*! building Connect Zones for storing the informations
+ * of the connectivity 
+ * 
+ * The connect zones are created for every domain that has common nodes with 
+ * domain \a idomain
+ * 
+ * \param idomain domain number for which the connect zones are created
+ * */
+
+// void MESHCollection::buildConnectZones(int idomain)
+// {
+//   // constructing node/node correspondencies
+//   vector<MEDMEM::MEDSKYLINEARRAY*> node_node_correspondency;
+//   node_node_correspondency.resize(_topology->nbDomain());
+
+//   cout << "Computing node/node corresp"<<endl;
+
+//   _topology->computeNodeNodeCorrespondencies(idomain, node_node_correspondency );
+
+//   for (int idistant=0; idistant< _topology->nbDomain(); idistant++)
+//   {
+//     // on regarde si une correspondance noeud/noeud a été trouvée 
+//     // entre idomain et idistant
+//     // si oui, on crée une connectzone
+//     if (node_node_correspondency[idistant]!=0)
+//     {
+//       MEDMEM::CONNECTZONE* cz= new MEDMEM::CONNECTZONE();
+//       cz->setLocalMesh(_mesh[idomain]);
+//       cz->setDistantMesh(_mesh[idistant]);
+//       cz->setLocalDomainNumber(idomain);
+//       cz->setDistantDomainNumber(idistant);
+//       cz-> setName ("Connect zone defined by PARTITIONER");
+//       cz->setNodeCorresp(node_node_correspondency[idistant]);
+//       _connect_zones.push_back(cz);  
+//     }
+//   }
+//   cout << "Computing node/node corresp"<<endl;
+
+//   vector<MEDMEM::MEDSKYLINEARRAY*> cell_cell_correspondency;
+//   cell_cell_correspondency.resize(_topology->nbDomain());
+//   _topology->computeCellCellCorrespondencies(idomain, cell_cell_correspondency, _cell_graph.get());
+
+//   for (int idistant=0; idistant< _topology->nbDomain(); idistant++)
+//   {
+//     //the connect zone has been created by the node/node computation
+//     if (cell_cell_correspondency[idistant]!=0)
+//     {
+//       MEDMEM::CONNECTZONE* cz=0;
+//       for (int icz=0; icz<_connect_zones.size();icz++)
+//         if (_connect_zones[icz]->getLocalDomainNumber()==idomain &&
+//             _connect_zones[icz]->getDistantDomainNumber()==idistant)
+//           cz = _connect_zones[icz];
+//       if (cz!=0) 
+//         cz->setEntityCorresp(MED_EN::MED_CELL,MED_EN::MED_CELL, cell_cell_correspondency[idistant]);
+//       else 
+//         throw MEDEXCEPTION("MESHCollection::buildConnectZones() -A connect zone should exist");   
+//       //delete cell_cell_correspondency[idistant];
+//     }
+
+//   }
+// }
+
+// //================================================================================
+// /*!
+//  * \brief Adds a group of joint faces
+//  *  \param loc_face_ids - local numbers of faces
+//  *  \param idomian - domain index where faces are local
+//  *  \param idistant - the other domain index
+//  */
+// //================================================================================
+
+// void MESHCollection::addJointGroup(const std::vector<int>& loc_face_ids, int idomain, int idistant)
+// {
+//   MEDMEM::MESHING* meshing = dynamic_cast<MEDMEM::MESHING*> (_mesh[idomain]);
+//   MED_EN::medEntityMesh constituent_entity = getSubEntity();
+
+//   MEDMEM::STRING jointname("joint_");
+//   jointname<<idistant+1;
+
+//   MEDMEM::GROUP * tmp_grp = new GROUP, * joint_group = tmp_grp;
+//   // try to find already present group with such a name
+//   //  vector<MEDMEM::GROUP*> groups = meshing->getGroups( constituent_entity );
+//   //  for ( int g = 0; g < groups.size(); ++g )
+//   //    if ( groups[g]->getName() == jointname.str() )
+//   //    {
+//   //      joint_group = groups[g];
+//   //      break;
+//   //    }
+//   // assure uniqueness of group name
+//   bool unique = false;
+//   vector<MEDMEM::GROUP*> groups = meshing->getGroups( constituent_entity );
+//   do
+//   {
+//     unique = true;
+//     for ( int g = 0; unique && g < groups.size(); ++g )
+//       unique = ( groups[g]->getName() != jointname );
+//     if ( !unique )
+//       jointname << "_" << idomain+1;
+//   }
+//   while ( !unique );
+//   joint_group->setName(jointname);
+//   joint_group->setMesh(meshing);
+//   joint_group->setEntity(constituent_entity);
+//   map<MED_EN::medGeometryElement, vector<int> > joint_types;
+
+//   int nbfaces = loc_face_ids.size();
+//   for (int i=0; i<nbfaces; i++)
+//   {    
+//     MED_EN::medGeometryElement type = meshing->getElementType(constituent_entity,loc_face_ids[i]);
+//     joint_types[type].push_back(loc_face_ids[i]);
+//   }
+//   joint_group->setNumberOfGeometricType(joint_types.size());
+//   MED_EN::medGeometryElement* types=new MED_EN::medGeometryElement[joint_types.size()];
+//   int* nb_in_types=new int[joint_types.size()];
+//   int* group_index=new int[joint_types.size()+1];
+
+//   group_index[0]=1;
+//   int itype=0;
+//   int iface =0;
+//   int* group_value=new int[nbfaces];
+//   for (map<MED_EN::medGeometryElement, vector<int> >::const_iterator iterj=joint_types.begin();
+//        iterj != joint_types.end();
+//        iterj++)
+//   {
+//     nb_in_types[itype]=(iterj->second).size();
+//     types[itype]=iterj->first;
+//     itype++;
+//     group_index[itype]=group_index[itype-1]+(iterj->second).size();
+//     for (int i=0; i<  (iterj->second).size(); i++)
+//       group_value[iface++]=(iterj->second)[i];
+//   }
+//   joint_group->setGeometricType(types);
+//   joint_group->setNumberOfElements(nb_in_types);
+//   joint_group->setNumber(group_index, group_value, /*shallowCopy=*/true);
+//   delete[] types;
+//   delete[] nb_in_types;
+
+//   if ( joint_group == tmp_grp )
+//     meshing->addGroup(*tmp_grp);
+//   tmp_grp->removeReference();
+// }
+
+// /*! building Connect Zones for storing the informations
+//  * of the connectivity 
+//  * */
+
+// void MESHCollection::buildConnectZones()
+// {
+//   vector <map <MED_EN::medGeometryElement, vector<MEDPARTITIONER_FaceModel*> > > face_map(_topology->nbDomain());
+//   map< pair<int,int>, MEDMEM::MEDSKYLINEARRAY*> cell_corresp_here;
+
+//   MED_EN::medEntityMesh constituent_entity = getSubEntity();
+
+//   if ( isParallelMode() )
+//   {
+//     buildConnectZonesBetweenProcs(face_map, cell_corresp_here);
+//   }
+
+//   cout << "Computing node/node corresp"<<endl;
+
+//   //Creating nodes
+//   for (int idomain=0; idomain<_topology->nbDomain(); idomain++)
+//   {
+
+//     // constructing node/node correspondencies
+//     vector<MEDMEM::MEDSKYLINEARRAY*> node_node_correspondency(_topology->nbDomain());
+//     _topology->computeNodeNodeCorrespondencies(idomain, node_node_correspondency );
+
+//     for (int idistant=0; idistant< _topology->nbDomain(); idistant++)
+//     {
+//       // on regarde si une correspondance noeud/noeud a été trouvée 
+//       // entre idomain et idistant
+//       // si oui, on crée une connectzone
+//       if (node_node_correspondency[idistant]!=0)
+//       {
+//         MEDMEM::CONNECTZONE* cz= new MEDMEM::CONNECTZONE();
+//         cz->setLocalMesh(_mesh[idomain]);
+//         cz->setDistantMesh(_mesh[idistant]);
+//         cz->setLocalDomainNumber(idomain);
+//         cz->setDistantDomainNumber(idistant);
+//         cz-> setName ("Connect zone defined by PARTITIONER");
+//         cz->setNodeCorresp(node_node_correspondency[idistant]);
+//         _connect_zones.push_back(cz);  
+//       }
+//     }
+//   }
+//   cout << "Computing face corresp"<<endl;
+
+//   //creating faces if required 
+//   if (_subdomain_boundary_creates)
+//   {
+//     int global_face_id = _topology->getFaceNumber()+1;
+//     //int global_face_id = _topology->getMaxGlobalFace()+1;
+
+//     map <pair<int,int>, vector<int> > faces_in_joint;
+
+//     if ( !isParallelMode() )
+//       // taking faces that are already present in the mesh into account
+//       for (int idomain=0; idomain<_topology->nbDomain(); idomain++)
+//       {
+//         getFaces(idomain,face_map[idomain]); 
+//       }
+
+//     // creating faces that are located at the interface between
+//     // subdomains 
+
+//     vector <int> nb_added_groups( _topology->nbDomain(), 0 );
+
+//     for (int idomain=0; idomain<_topology->nbDomain(); idomain++)
+//     {
+//       vector<MEDMEM::MEDSKYLINEARRAY*> cell_cell_correspondency( _topology->nbDomain() );
+//       if ( !isParallelMode() )
+//         _topology->computeCellCellCorrespondencies(idomain, cell_cell_correspondency, _cell_graph.get());
+
+//       for (int idistant=0; idistant< _topology->nbDomain(); idistant++)
+//       {
+//         if (idistant <= idomain) continue;
+
+//         MEDMEM::MEDSKYLINEARRAY* cell_correspondency = 0;
+//         if ( isParallelMode() )
+//           cell_correspondency = cell_corresp_here[ make_pair (idomain,idistant)];
+//         else
+//           cell_correspondency = cell_cell_correspondency[idistant];
+
+//         //the connect zone has been created by the node/node computation
+
+//         if ( cell_correspondency )
+//         {
+//           int nbcells      = cell_correspondency->getNumberOf();
+//           const int* index = cell_correspondency->getIndex();
+//           const int* value = cell_correspondency->getValue();
+//           if ( isParallelMode() )
+//             global_face_id = _domain_selector->getFisrtGlobalIdOfSubentity( idomain, idistant );
+
+//           for (int ilocal=0; ilocal<nbcells; ilocal++)
+//           { 
+//             for (int icelldistant = index[ilocal]; icelldistant < index[ilocal+1]; icelldistant++)
+//             {
+//               int distant_id = value[icelldistant-1];
+//               MEDPARTITIONER_FaceModel* face = getCommonFace(idomain,ilocal+1,idistant,distant_id,global_face_id);
+//               face_map[idomain][face->getType()].push_back(face);
+//               MEDPARTITIONER_FaceModel* face2 = getCommonFace(idistant,distant_id,idomain, ilocal+1,global_face_id);
+//               face_map[idistant][face->getType()].push_back(face2);
+//               faces_in_joint[make_pair(idomain,idistant)].push_back(global_face_id);
+//               global_face_id++;
+//             } 
+//           }
+//         }
+
+//       }
+//       //cleaning up
+//       for (int idistant=0; idistant< _topology->nbDomain(); idistant++)
+//         delete cell_cell_correspondency[idistant];
+//     }
+
+
+//     _topology->recreateFaceMapping(face_map);
+
+//     //transforming the face_map into a constituent entity connectivity
+//     for (int idomain=0; idomain< _topology->nbDomain();idomain++) 
+//     {
+//       int nbtypes = face_map[idomain].size();
+//       vector<medGeometryElement> types;
+//       vector <int> nb_elems;
+//       vector <int*> conn;
+
+//       MEDMEM::MESHING* meshing = dynamic_cast<MEDMEM::MESHING*> (_mesh[idomain]);
+//       if ( !meshing->getConnectivityptr() )
+//         continue; // no cells in idomain
+
+//       for (map <medGeometryElement, vector<MEDPARTITIONER_FaceModel*> >::const_iterator iter= face_map[idomain].begin();
+//            iter != face_map[idomain].end(); iter ++)
+//       {
+//         types.push_back(iter->first);
+//         int nb_elem_in_type = (iter->second).size();
+//         nb_elems.push_back(nb_elem_in_type);
+//         int nb_node_per_type=(iter->first)%100;
+//         int* connectivity= new int [nb_node_per_type*nb_elem_in_type];
+//         for (int ielem=0; ielem<nb_elem_in_type; ielem++)
+//         {
+//           for (int inode=0;  inode<nb_node_per_type; inode++)
+//             connectivity[ielem*nb_node_per_type+inode]=(*(iter->second)[ielem])[inode];
+//         }
+//         conn.push_back(connectivity);
+
+//       }
+//       //setting the faces in the mesh
+//       meshing->setNumberOfTypes(nbtypes,constituent_entity);
+//       meshing->setTypes(&types[0],constituent_entity);
+//       meshing->setNumberOfElements(&nb_elems[0],constituent_entity);
+
+//       for (int itype=0; itype<nbtypes; itype++)
+//       {
+//         meshing->setConnectivity(conn[itype], constituent_entity, types[itype]);
+//         delete[]conn[itype];
+//       }
+//       for (int idistant =0; idistant<_topology->nbDomain(); idistant++)
+//       {
+//         map <pair<int,int>, vector<int> >::iterator iter;
+//         iter = faces_in_joint.find(make_pair(idomain,idistant));
+//         if (iter == faces_in_joint.end())
+//         {
+//           iter = faces_in_joint.find (make_pair(idistant,idomain));
+//           if (iter == faces_in_joint.end()) 
+//             continue;
+//         }
+
+//         int nbfaces = (iter->second).size();   
+//         vector<int> face_joint(nbfaces*2);
+//         MEDMEM::CONNECTZONE* cz=0;
+//         for (int icz=0; icz<_connect_zones.size();icz++)
+//           if (_connect_zones[icz]->getLocalDomainNumber()==idomain &&
+//               _connect_zones[icz]->getDistantDomainNumber()==idistant)
+//             cz = _connect_zones[icz];
+
+//         int nbtotalfaces= _topology->getFaceNumber(idomain);
+
+//         //creating arrays for the MEDSKYLINEARRAY structure containing the joint
+//         int* index =new int[nbtotalfaces+1];
+//         for (int i=0; i<nbtotalfaces+1;i++)
+//           index[i]=0;
+//         int*value=new int[nbfaces];
+
+//         map<int,int> faces;
+//         vector<int> local_faces( nbfaces );
+//         for (int iface=0; iface<nbfaces; iface++)
+//         {
+//           int iglobal = (iter->second)[iface];
+//           int localid=_topology->convertGlobalFace(iglobal,idomain);
+//           int distantid=_topology->convertGlobalFace(iglobal,idistant);
+//           faces.insert(make_pair(localid,distantid));
+//           local_faces[iface]=localid;
+//         }
+
+//         int iloc=0;
+//         index[0]=1;
+//         for (map<int,int>::const_iterator iter=faces.begin(); 
+//              iter != faces.end();
+//              iter++)
+//         {
+//           index[iter->first]=1;
+//           value[iloc++]=iter->second;            
+//         }
+
+//         for (int i=0; i<nbtotalfaces;i++)
+//           index[i+1]+=index[i];
+//         bool shallowcopy=true;  
+//         MEDMEM::MEDSKYLINEARRAY* skarray=new MEDMEM::MEDSKYLINEARRAY(nbtotalfaces,nbfaces,index,value,shallowcopy);  
+
+//         if (cz!=0)  
+//           cz->setEntityCorresp(constituent_entity,constituent_entity,skarray);              
+//         else 
+//           throw MEDEXCEPTION("MESHCollection::buildConnectZones() -A connect zone should exist");            
+//         // Creating a group of the faces constituting the joint
+//         addJointGroup( local_faces, idomain, idistant );
+//         nb_added_groups[ idomain ]++;
+//       }
+//     }
+
+//     if ( isParallelMode() )
+//     {
+//       // Now all faces have got local ids and we can receive local ids from other procs.
+//       // Set face/face data to zones with other procs and create a group
+//       for (int icz=0; icz<_connect_zones.size();icz++)
+//       {
+//         MEDMEM::CONNECTZONE* cz=_connect_zones[icz];
+//         if ( _domain_selector->isMyDomain( cz->getDistantDomainNumber()) ) continue;
+        
+//         int glob_id = _domain_selector->getFisrtGlobalIdOfSubentity( cz->getLocalDomainNumber(),
+//                                                                      cz->getDistantDomainNumber());
+//         int nb_cz_faces = _domain_selector->getNbCellPairs( cz->getDistantDomainNumber(),
+//                                                             cz->getLocalDomainNumber());
+//         vector< int > loc_ids_here( nb_cz_faces );
+//         for ( int i = 0; i < nb_cz_faces; ++i )
+//           loc_ids_here[i] = _topology->convertGlobalFace(glob_id++,cz->getLocalDomainNumber());
+
+//         int* loc_ids_dist = _domain_selector->exchangeSubentityIds( cz->getLocalDomainNumber(),
+//                                                                     cz->getDistantDomainNumber(),
+//                                                                     loc_ids_here );
+//         int nb_faces_here= _topology->getFaceNumber(cz->getLocalDomainNumber());
+//         int* face_index = new int[ nb_faces_here+1 ];
+//         face_index[0]=1;
+//         for ( int loc_id = 0, i = 0; loc_id < nb_faces_here; ++loc_id)
+//         {
+//           face_index[ loc_id+1 ] = face_index[ loc_id ];
+//           if ( i < loc_ids_here.size() && loc_ids_here[i] == loc_id+1 )
+//           {
+//             face_index[ loc_id+1 ]++;
+//             i++;
+//           }
+//         }
+//         MEDMEM::MEDSKYLINEARRAY* skarray=
+//           new MEDMEM::MEDSKYLINEARRAY(nb_faces_here, nb_cz_faces, face_index, loc_ids_dist, true);
+//         cz->setEntityCorresp(constituent_entity,constituent_entity,skarray);
+
+//         addJointGroup( loc_ids_here, cz->getLocalDomainNumber(), cz->getDistantDomainNumber());
+//         nb_added_groups[ cz->getLocalDomainNumber() ]++;
+//       }
+//     }
+
+//     for (int idomain=0; idomain<_topology->nbDomain(); idomain++)
+//     {
+//       // delete face_map
+//       for (map <medGeometryElement, vector<MEDPARTITIONER_FaceModel*> >::const_iterator iter= face_map[idomain].begin();
+//            iter != face_map[idomain].end(); iter ++)
+//         for (int i=0; i<(iter->second).size();i++)
+//           delete (iter->second)[i];
+
+//       if ( nb_added_groups[ idomain ] > 0 &&
+//            _mesh[idomain]->getNumberOfFamilies( constituent_entity ) > 0 )
+//         // needed because if there were face families before, driver won't
+//         // create families from just added groups (see MEDMEM_MedMeshDriver22.cxx:3330),
+//         // actually it is a bug of driver - it must check presence of groups in families
+//         _mesh[idomain]->createFamilies(); 
+//     }
+//   }
+
+//   if ( isParallelMode() )
+//     // Excange info on types of constituent_entity needed while writing joints
+//     // to get ids local in geom type for distant procs
+//     _domain_selector->gatherEntityTypesInfo( _mesh, constituent_entity );
+
+//   cout << "Computing cell/cell corresp"<<endl;
+
+//   //Creating cell/cell correspondencies
+//   for (int idomain=0;idomain<_topology->nbDomain();idomain++)
+//   {
+//     vector<MEDMEM::MEDSKYLINEARRAY*> cell_cell_correspondency( _topology->nbDomain() );
+//     if ( !isParallelMode() )
+//       _topology->computeCellCellCorrespondencies(idomain,cell_cell_correspondency,_cell_graph.get());
+
+//     for (int idistant=0; idistant< _topology->nbDomain(); idistant++)
+//     {
+//       MEDMEM::MEDSKYLINEARRAY* cell_correspondency = 0;
+//       if ( isParallelMode() )
+//         cell_correspondency = cell_corresp_here[ make_pair (idomain,idistant)];
+//       else
+//         cell_correspondency = cell_cell_correspondency[idistant];
+
+//       //the connect zone has been created by the node/node computation
+//       if ( cell_correspondency )
+//       {
+//         MEDMEM::CONNECTZONE* cz=0;
+//         for (int icz=0; icz<_connect_zones.size();icz++)
+//           if (_connect_zones[icz]->getLocalDomainNumber()==idomain &&
+//               _connect_zones[icz]->getDistantDomainNumber()==idistant)
+//             cz = _connect_zones[icz];
+//         if (cz!=0)  
+//           cz->setEntityCorresp(MED_EN::MED_CELL,MED_EN::MED_CELL, cell_correspondency);
+//         else 
+//           throw MEDEXCEPTION("MESHCollection::buildConnectZones() -A connect zone should exist");   
+//       }
+//     }
+//   }
+// }
+
+// /*! building Connect Zones for storing the informations
+//  * of the connectivity in the parallel mode
+//  * */
+
+// void MESHCollection::buildConnectZonesBetweenProcs(TGeom2FacesByDomian & face_map,
+//                                                    map< pair<int,int>, MEDMEM::MEDSKYLINEARRAY*> & cell_cell_correspondency_here)
+// {
+//   using namespace MED_EN;
+
+//   // graph over all procs
+//   auto_ptr<Graph> global_graph( _domain_selector->gatherGraph( _cell_graph.get() ));
+
+//   vector< vector< JointExchangeData > > joints_of_domain( _topology->nbDomain() );
+
+//   for (int idomain=0; idomain<_topology->nbDomain(); idomain++)
+//   {
+//     if ( !_domain_selector->isMyDomain( idomain )) continue;
+
+//     vector< JointExchangeData > & joints = joints_of_domain[ idomain ];
+//     joints.resize( _topology->nbDomain() );
+
+//     // Find corresponding cells on other procs
+
+//     const int* gra_index = global_graph->getGraph()->getIndex();
+//     const int* gra_value = global_graph->getGraph()->getValue();
+//     const int* partition = global_graph->getPart();
+//     const int dj = gra_index[0];
+
+//     vector< int > glob_cells_here( _topology->getCellNumber( idomain ));
+//     _topology->getCellList( idomain, & glob_cells_here[0]);
+//     for ( int loc_here = 0; loc_here < glob_cells_here.size(); ++loc_here )
+//     {
+//       int glob_here = glob_cells_here[ loc_here ];
+//       for ( int j = gra_index[ glob_here-1 ]; j < gra_index[ glob_here ]; ++j )
+//       {
+//         int glob_neighbor = gra_value[ j-dj ];
+//         int neighbor_dom = partition[ glob_neighbor-1 ];
+//         if ( neighbor_dom == idomain ) continue;
+
+//         if ( _domain_selector->isMyDomain( neighbor_dom ))
+//         {
+//           joints[ neighbor_dom ].addCellCorrespondence
+//             (_mesh[idomain], neighbor_dom, idomain, glob_neighbor, glob_here, loc_here + 1,
+//              _topology->convertGlobalCell(glob_neighbor).second );
+//         }
+//         else
+//         {
+//           joints[ neighbor_dom ].addCellCorrespondence
+//             (_mesh[idomain], neighbor_dom, idomain, glob_neighbor, glob_here, loc_here + 1 );
+//         }
+//       }
+//     }
+//   }
+//   global_graph.reset(); // free memory
+
+//   // set joints in a queue to exchange
+//   typedef map< int, JointExchangeData* > TOrderedJoints;
+//   TOrderedJoints queue;
+//   for (int idomain=0; idomain<_topology->nbDomain(); idomain++)
+//   {
+//     if ( !_domain_selector->isMyDomain( idomain )) continue;
+
+//     vector< JointExchangeData > & joints = joints_of_domain[ idomain ];
+//     for (int idist=0; idist<_topology->nbDomain(); ++idist )
+//     {
+//       JointExchangeData& joint = joints[idist];
+
+//       int nb_cell_pairs = joint.nbCellPairs();
+//       if ( nb_cell_pairs == 0 )
+//         continue;
+//       else
+//         _domain_selector->setNbCellPairs( nb_cell_pairs, idist, idomain );
+
+//       joint.setMeshes( idist, _mesh[idist], idomain, _mesh[idomain] );
+
+//       if ( _domain_selector->isMyDomain( idist ))
+//       {
+//         // a joint on this proc
+//         cell_cell_correspondency_here[ make_pair( idomain, idist )] = joint.makeCellCorrespArray();
+//       }
+//       else
+//       {
+//         // a joint with distant proc
+//         joint.setConnectivity( & ((MEDMEM::MeshFuse*)_mesh[idomain])->getNodeNumbers()[0] );
+//         int order = _domain_selector->jointId( idomain, idist );
+//         queue[ order ] = & joint;
+//       }
+//     }
+//   }
+//   // gather info on cell geom types needed to exchange joints
+//   _domain_selector->gatherEntityTypesInfo( _mesh, MED_EN::MED_CELL );
+
+//   // gather info on nb of sub-entities to compute their global numbers for joints
+//   _domain_selector->gatherNbOf( getSubEntity(), _mesh );
+//   _domain_selector->gatherNbCellPairs();
+//   if ( _subdomain_boundary_creates )
+//   {
+//     // taking faces that are already present in the mesh into account
+//     for (int idomain=0; idomain<_topology->nbDomain(); idomain++)
+//       if ( _domain_selector->isMyDomain( idomain ))
+//         getFaces(idomain,face_map[idomain]);
+//   }
+//   else
+//   {
+//     face_map.clear(); // mark for the joint not to create faces
+//   }
+
+//   // exchange joint data with other procs and make CONNECTZONEs
+//   TOrderedJoints::iterator ord_joint = queue.begin();
+//   for ( ; ord_joint != queue.end(); ++ord_joint )
+//   {
+//     JointExchangeData* joint = ord_joint->second;
+
+//     _domain_selector->exchangeJoint( joint );
+//     if ( _subdomain_boundary_creates )
+//     {
+//       int first_sub_id = _domain_selector->getFisrtGlobalIdOfSubentity( joint->localDomain(),
+//                                                                         joint->distantDomain() );
+//       joint->setFisrtGlobalIdOfSubentity( first_sub_id );
+//     }
+//     _connect_zones.push_back ( joint->makeConnectZone( face_map ));
+//   }
+// }
+
+// /*! projects old collection families on new collection families
+//  */
+// void MESHCollection::castFamilies(const MESHCollection& old_collection)
+// {
+//   vector <list<int> > element_array  (_topology->nbDomain());
+
+//   //loop on old domains to create groups out of the existing families
+//   if (_family_splitting)
+//     for (int idomain=0; idomain < old_collection._topology->nbDomain(); idomain++)
+//       old_collection.getMesh(idomain)->createGroups();
+
+//   //definition of the entities array which 
+//   //defines the entities over which the information is cast
+//   MED_EN::medEntityMesh entities[3];
+//   entities[0]=MED_EN::MED_NODE;
+//   entities[1]=getSubEntity();
+//   entities[2]=MED_EN::MED_CELL;
+
+//   for (int ientity=0; ientity<=2;ientity++)
+//   {
+
+//     //int nbgroups = old_collection.getMesh(0)->getNumberOfGroups(entities[ientity]);
+
+//     map <string, set<int> > group_map;
+//     for (int idomain=0; idomain < old_collection._topology->nbDomain(); idomain++)
+//     {
+//       if ( !old_collection.getMesh(idomain) ) continue;
+//       for (int igroup=0; igroup<old_collection.getMesh(idomain)->getNumberOfGroups(entities[ientity]); igroup++)
+//       {
+//         //retrieves a group
+//         MEDMEM::GROUP* group = (old_collection.getMesh(idomain)->getGroups(entities[ientity]))[igroup];
+//         //increments the number of groups if it is a new group
+//         //if (group_map.find(group->getName())==group_map.end())
+
+//         group_map[group->getName()].insert(idomain);
+//         //   group_map.insert(make_pair(group->getName(), idomain);
+
+//       }   
+//     }
+//     int nbgroups=group_map.size();
+//     vector <int> igroupold(old_collection._topology->nbDomain(),0);
+//     map<string,set<int> >::const_iterator iter=group_map.begin();
+
+//     for (int igroup=0; igroup<nbgroups; igroup++)
+//     {
+//       vector <const MEDMEM::SUPPORT*> old_supports(old_collection._topology->nbDomain());
+//       string group_name = iter->first;
+//       iter++; 
+
+//       //parameters stored for passing group description
+//       // from the old meshes to the new ones
+
+//       for (int idomain=0; idomain < old_collection._topology->nbDomain(); idomain++)
+//       {
+//         //                for (set<int>::iterator iter=group_map[group_name].begin(); iter!=group_map[group_name].end(); iter++)
+//         //                cout << *iter<<" ";
+//         //                cout <<endl;
+//         if (group_map[group_name].find(idomain)==group_map[group_name].end()) continue;
+
+//         //retrieves the group igroup on domain idomain
+//         MEDMEM::GROUP* group = (old_collection.getMesh(idomain)->getGroups(entities[ientity]))[igroupold[idomain]];
+//         old_supports[idomain] = static_cast<const MEDMEM::SUPPORT*> (group);
+//         igroupold[idomain]++;
+//       }
+
+//       vector <MEDMEM::GROUP*>new_groups(_topology->nbDomain());
+//       vector <MEDMEM::SUPPORT*> new_supports(_topology->nbDomain());
+//       for (int i=0; i<_topology->nbDomain(); i++)
+//       {
+//         new_groups[i]=new MEDMEM::GROUP();
+//         new_supports[i]=static_cast<MEDMEM::SUPPORT*>(new_groups[i]);
+//       }
+//       castSupport(old_collection,old_supports,new_supports);      
+
+//       //creating new groups from the previous list of elements
+//       for (int idomain=0; idomain <_topology->nbDomain(); idomain++)
+//       {
+//         MEDMEM::MESHING* mesh_builder=static_cast<MEDMEM::MESHING*> (_mesh[idomain]);
+//         if ( new_supports[idomain] )
+//           mesh_builder->addGroup(*new_groups[idomain]);
+//       }
+//       //groups are copied by the addGroup method,
+//       //so they can be safely deleted here
+//       for (int i=0; i<_topology->nbDomain(); i++)
+//       {
+//         if ( new_supports[i] ) new_groups[i]->removeReference();
+//       }
+
+//     }// on groups
+//   }//on entities
+// }
+
+
+// void MESHCollection::castSupport(const MESHCollection& old_collection, vector<const MEDMEM::SUPPORT*>& old_support, vector<MEDMEM::SUPPORT*>& new_support)
+// {
+
+//   if (old_collection._topology->nbDomain() != old_support.size())
+//   {
+//     throw MED_EXCEPTION(STRING("Error : wrong call to MESHCollection::castSupport"));
+//   }
+//   vector <list<int> > element_array  (_topology->nbDomain());
+
+//   //parameters stored for passing description
+//   // from the old meshes to the new ones
+//   string name;
+//   string description;
+//   MED_EN::medEntityMesh entity;
+//   vector <string> support_name(1);
+//   support_name[0]="support";
+//   for (int inew=0; inew< _topology->nbDomain(); inew++)
+//     element_array[inew].clear();
+
+//   for (int idomain=0; idomain < old_collection._topology->nbDomain(); idomain++)
+//   {
+//     //retrieves the group igroup on domain idomain
+//     const MEDMEM::SUPPORT* support = old_support[idomain];
+//     if (old_support[idomain]==0) continue;
+//     name = support->getName();
+//     description=support->getDescription();
+//     int nbelem = support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
+//     if (nbelem==0 && !_create_empty_groups) continue;
+
+//     int* list_of_elems;
+//     if (support->isOnAllElements())
+//     {
+//       list_of_elems = new int[nbelem];
+//       for (int i=0; i<nbelem;i++)
+//         list_of_elems[i]=i+1;
+//     }
+//     else
+//       list_of_elems = const_cast<int*> (support->getNumber(MED_EN::MED_ALL_ELEMENTS));
+
+//     int* array=new int[nbelem];
+//     int* ip=0;
+//     int* local=0;
+//     int* full_array=0;
+//     entity = support->getEntity();
+//     int size;
+
+//     switch (entity)
+//     {
+//     case MED_EN::MED_CELL :
+//       ip=new int[nbelem];
+//       local= new int[nbelem];
+//       size=nbelem;
+//       old_collection.getTopology()->convertCellToGlobal(idomain,list_of_elems,nbelem,array);
+//       _topology->convertGlobalCellList(array,nbelem,local,ip);
+//       for (int i=0; i<nbelem; i++)
+//         //              cell_arrays[ip[i]][local[i]]=id;
+//       {
+//         //          cout <<"(glob,ip,iloc)/nbelem"<<array[i]<<" "<<ip[i]<<" "<<local[i]<<"/"<<nbelem<<endl;
+//         element_array[ip[i]].push_back(local[i]);
+//       }
+//       break;
+//     case MED_EN::MED_FACE :
+//     case MED_EN::MED_EDGE :
+//       old_collection.getTopology()->convertFaceToGlobal(idomain,list_of_elems,nbelem,array);
+//       _topology->convertGlobalFaceListWithTwins(array,nbelem,local,ip,full_array,size);
+//       for (int i=0; i<size; i++)
+//         element_array[ip[i]].push_back(local[i]);
+//       delete[] full_array;  
+//       break;
+//     case MED_EN::MED_NODE :
+//       old_collection.getTopology()->convertNodeToGlobal(idomain,list_of_elems,nbelem,array);
+//       _topology->convertGlobalNodeListWithTwins(array,nbelem,local,ip,full_array,size);
+//       for (int i=0; i<size; i++)
+//         element_array[ip[i]].push_back(local[i]);
+//       delete[] full_array;
+//       break;
+
+//     }
+//     delete[] ip;
+//     delete[] local;
+//     delete[] array;
+
+//     if (support->isOnAllElements()) delete[] list_of_elems;
+//   }
+
+//   //creating new groups from the previous list of elements
+//   for (int idomain=0; idomain <_topology->nbDomain(); idomain++)
+//   {
+//     if ( _mesh[idomain]->getNumberOfNodes() < 1 || 
+//          (element_array[idomain].empty() && !_create_empty_groups))
+//     {
+//       new_support[idomain]->removeReference();
+//       new_support[idomain]=0;
+//       continue;
+//     }
+//     MEDMEM::SUPPORT* support= new_support[idomain];
+//     support->setName(name);
+//     support->setMesh(_mesh[idomain]);
+//     support->setDescription(description);
+//     support->setEntity(entity);
+
+//     element_array[idomain].sort();
+//     element_array[idomain].unique();
+
+//     if ( element_array[idomain].empty() )
+//     {
+//       support->setNumberOfGeometricType(0);
+//     }
+//     else
+//     {
+//       if (entity != MED_EN::MED_NODE)
+//         support->fillFromElementList(element_array[idomain]);
+//       else
+//       {
+//         support->fillFromNodeList(element_array[idomain]);
+//       }
+//     }
+//   }
+// }
+
+// void MESHCollection::castField(const MESHCollection& old_collection, const string& fieldname, int itnumber, int ordernumber)
+// {
+//   int type=old_collection.getDriver()->getFieldType(fieldname);
+//   char field_char[80];
+//   strcpy(field_char,fieldname.c_str());
+
+//   if (type ==0)
+//     castFields<int>(old_collection, field_char, itnumber, ordernumber);
+//   else
+//     castFields<double>(old_collection, field_char, itnumber, ordernumber);
+// }
+
+// void MESHCollection::castAllFields(const MESHCollection& initial_collection)
+// {
+//   vector <string> field_names;
+//   vector <int> iternumber;
+//   vector <int> ordernumber;
+//   vector <int> types;
+//   initial_collection.getDriver()->readFileStruct(field_names,iternumber,ordernumber,types);
+
+//   for (int i=0; i<field_names.size(); i++)
+//   {
+//     char field_char[80];
+//     strcpy(field_char,field_names[i].c_str());
+
+//     // choosing whether the field is of int or double type
+//     if (types[i] ==0)
+//       castFields<int>(initial_collection, field_char, iternumber[i], ordernumber[i]);
+//     else
+//       castFields<double>(initial_collection, field_char, iternumber[i], ordernumber[i]);
+//   }
+// }
+
+// //! \param initial_collection mesh collection before the redistribution stage
+// //! \param idomain domain number on the new collection
+// //! \param entity dimension of the treated nodes (0 : cell, 1 : face in 3d, edge in 2d, 2: edge in 3d)
+// void MESHCollection::createNodalConnectivity(const MESHCollection& initial_collection,int idomain, int entity)
+// {
+
+       
+//   int dimension=0;
+//   int nb_elems=0;
+//   ParaMEDMEM::MEDCouplingUMesh* mesh_builder = m_mesh[idomain];
+
+//   //creating arrays for storing global numbers and cell types
+//   switch (entity)
+//   {
+//   case MED_EN::MED_CELL:
+//     dimension=initial_collection.getMeshDimension();
+//     nb_elems=m_topology->getCellNumber(idomain);
+//     break;
+//   case MED_EN::MED_EDGE:
+//   case MED_EN::MED_FACE:
+//     dimension=initial_collection.getMeshDimension()-1;
+//     nb_elems=m_topology->getFaceNumber(idomain);
+//     break;
+//   default:
+//     nb_elems=0;
+//     break;
+//   }
+
+//   if (nb_elems == 0) return;
+//   SCRUTE_MED(nb_elems);
+
+
+//   int *list= new int[nb_elems];
+//   MED_EN::medGeometryElement *cell_type_list= new MED_EN::medGeometryElement[nb_elems];
+
+
+//   //      cout << "Beginning of retrieval "<<endl;
+//   //retrieving global id list
+//   switch (entity)
+//   {
+//   case MED_EN::MED_CELL:
+//     m_topology->getCellList(idomain,list);
+//     break;
+//   case MED_EN::MED_EDGE:
+//   case MED_EN::MED_FACE:
+//     m_topology->getFaceList(idomain,list);
+//     break;
+//   default:
+
+//     break;
+//   }
+
+//   //retrieving cell_types
+//   initial_collection.getTypeList(list,nb_elems,entity,cell_type_list);
+//   //      cout <<"end of type retrieval"<<endl;
+//   //vector containing the number of cells per type
+//   type_numbers.clear();
+//   for (int icell=0; icell<nb_elems; icell++)
+//   {
+//     map<MED_EN::medGeometryElement,int>::iterator iter= type_numbers.find(cell_type_list[icell]);
+//     if (iter!=type_numbers.end())
+//       (iter->second)++;
+//     else
+//       type_numbers[cell_type_list[icell]]=1;
+
+//   }
+//   //cout << "Nombre de tetras"<<type_numbers[304]<<endl;
+//   int nb_present_types=type_numbers.size();
+
+//   //setting the list of cells for each type
+//   map<MED_EN::medGeometryElement,int> index;
+
+//   map<MED_EN::medGeometryElement,int*> type_cell_list;
+
+//   MED_EN::MESH_ENTITIES::const_iterator currentEntity;
+//   std::map<MED_EN::medGeometryElement,int>::const_iterator iter;
+//   //currentEntity  = MED_EN::meshEntities.find(entity);
+//   for (iter = type_numbers.begin();iter != type_numbers.end(); iter++)    
+//   {
+//     MED_EN::medGeometryElement type = iter->first;
+//     if (!isDimensionOK(type,dimension)) continue;
+//     //if (iter->second==0) continue;
+//     index[type]=0;
+//     type_cell_list[type]=new int[type_numbers[type]];
+//     // cout << "type :"<<type<<" nb:"<<type_numbers[type]<<endl;
+//   }
+
+//   for (int icell=0; icell<nb_elems; icell++)
+//   {
+//     type_cell_list[cell_type_list[icell]][index[cell_type_list[icell]]++]=list[icell];
+//   }
+
+//   delete[]list;
+//   delete[]cell_type_list;
+
+//   //setting the list of present ypes
+//   int* present_type_numbers=new int[nb_present_types];
+//   MED_EN::medGeometryElement* type_array = new MED_EN::medGeometryElement[nb_present_types];
+//   MESSAGE_MED("Nb de types presents "<<nb_present_types);
+//   int itype=0;
+//   for (iter = type_numbers.begin();iter != type_numbers.end(); iter++)  
+//   {
+//     MED_EN::medGeometryElement type = iter->first;
+//     if (!isDimensionOK(type,dimension)) continue;
+
+//     type_array[itype]=type;
+
+//     present_type_numbers[itype]=type_numbers[type];
+
+//     MESSAGE_MED("Nombre d'elements de type "<<type<<" : "<<type_numbers[type]);
+//     itype++;
+//   }
+
+//   //retrieving connectivity in global numbering for each typeinitial_collection.getMesh(iold)->get
+//   map<MED_EN::medGeometryElement,int*> type_connectivity;
+//   vector<int> polygon_conn;
+//   vector<int> polygon_conn_index;
+//   vector<int> polyhedron_conn;
+//   vector<int> polyhedron_conn_index;
+//   vector<int> polyhedron_face_index;
+
+//   //Treating nodes
+
+//     DataArrayInt* conn_index = (initial_collection.getMesh())[idomain].getConnIndex();
+//     DataArrayInt* index=(initial_collection.getMesh())[idomain].getIndex();
+       
+       
+//   _topology->convertGlobalCellList(cell_list,nb_cells,local,ip);
+//   for (iter = type_numbers.begin();iter != type_numbers.end(); iter++)  
+//   {
+//     MED_EN::medGeometryElement type = iter->first;
+
+
+//     if (!isDimensionOK(type,dimension)) continue;
+//     //if (type_numbers[type]==0) continue;
+//     if (type != MED_EN::MED_POLYGON && type != MED_EN::MED_POLYHEDRA)
+//     {
+//       int nbnode_per_type = (int)type%100;
+//       type_connectivity[type]=new int[type_numbers[type]*nbnode_per_type];
+//       initial_collection.getNodeConnectivity(type_cell_list[type],type_numbers[type],entity,type,type_connectivity[type]);
+//     }
+//     else if (type == MED_EN::MED_POLYGON && dimension==2)
+//     {
+//       initial_collection.getPolygonNodeConnectivity(type_cell_list[type],type_numbers[type],entity,polygon_conn,polygon_conn_index);
+//       //type_connectivity[type]=&polygon_conn[0];
+//     }
+//     else if (type == MED_EN::MED_POLYHEDRA && dimension==3)
+//     {
+//       initial_collection.getPolyhedraNodeConnectivity(type_cell_list[type],type_numbers[type],entity,polyhedron_conn,
+//                                                       polyhedron_conn_index, polyhedron_face_index);
+//       //type_connectivity[type]=&polygon_conn[0];
+//     }
+//     delete[] type_cell_list[type];
+//   }
+
+//   //creating node mapping 
+//   //!TODO : compute the total number of nodes 
+//   if (entity==MED_EN::MED_CELL)
+//   {
+//     m_topology->createNodeMapping(type_connectivity,type_numbers,polygon_conn,polygon_conn_index,
+//                                   polyhedron_conn,polyhedron_conn_index,polyhedron_face_index,idomain);
+//   }
+
+//   //converting node global numberings to local numberings
+//   //for (iter = (*currentEntity).second.begin();iter != (*currentEntity).second.end(); iter++)
+//   for (iter = type_numbers.begin();iter != type_numbers.end(); iter++)  
+//   {
+//     MED_EN::medGeometryElement type = iter->first;
+
+//     if (!isDimensionOK(type, dimension)) continue;
+//     if (type_numbers[type]==0) continue;
+//     if (type != MED_EN::MED_POLYGON && type != MED_EN::MED_POLYHEDRA)
+//     {
+//       int nbnode_per_type = (int)type%100;
+//       m_topology->convertToLocal2ndVersion(type_connectivity[type],type_numbers[type]*nbnode_per_type,idomain);
+//     }
+//     else if (type == MED_EN::MED_POLYGON && dimension==2)
+//     {
+//       int nbpoly = type_numbers[type]; 
+//       m_topology->convertToLocal2ndVersion(&polygon_conn[0], polygon_conn_index[nbpoly]-1, idomain);  
+//     }
+//     else if (type == MED_EN::MED_POLYHEDRA && dimension==3)
+//     {
+//       int nbpoly = type_numbers[type]; 
+//       m_topology->convertToLocal2ndVersion(&polyhedron_conn[0], polyhedron_face_index[polyhedron_conn_index[nbpoly]-1]-1, idomain);  
+//     }
+
+//   }
+
+
+//   //writing coordinates
+//   if (entity==MED_EN::MED_CELL)   
+//   {
+//     //setting coordinates from initial_collection coordinates
+//     int nbnode=m_topology->getNodeNumber(idomain);
+//     MESSAGE_MED("Number of nodes on domain "<< idomain <<" : "<<nbnode);
+
+//     double* coordinates=new double[initial_collection.getSpaceDimension()*nbnode];
+//     int* node_list=new int[nbnode];
+//     m_topology->getNodeList(idomain,node_list);
+//     initial_collection.getCoordinates(node_list,nbnode,coordinates);
+//     delete[] node_list;
+
+//     // redundant specification of number of nodes is required!! MED imperfection, sorry...  
+
+//     mesh_builder->setNumberOfNodes(nbnode);
+//     //TODO : change MEDMEM so that it accepts a direct setting of coordinates
+//     // (in the present version, it is deep-copied)
+//     mesh_builder->setCoordinates(initial_collection.getSpaceDimension(),
+//                                  m_topology->getNodeNumber(idomain), coordinates, initial_collection.getSystem(),
+//                                  MED_EN::MED_FULL_INTERLACE);
+//     delete [] coordinates;
+//   }
+
+//   int nb_plain_types=0;
+//   for (iter = type_numbers.begin();iter != type_numbers.end(); iter++) 
+//   {
+//     MED_EN::medGeometryElement type = iter->first;
+
+//     if (!isDimensionOK(type, dimension)) continue;
+//     if (type_numbers[type]==0) continue;
+//     if (type != MED_EN::MED_POLYGON && type != MED_EN::MED_POLYHEDRA)
+//       nb_plain_types++;
+//   }
+//   mesh_builder->setNumberOfTypes(nb_plain_types,entity);
+//   mesh_builder->setTypes(type_array,entity);
+//   mesh_builder->setNumberOfElements(present_type_numbers,entity);
+//   if (entity==MED_EN::MED_CELL)
+//     mesh_builder->setMeshDimension(dimension);
+
+//   delete[]present_type_numbers;
+//   delete[]type_array;
+//   //setting node connectivities
+//   for (iter = type_numbers.begin();iter != type_numbers.end(); iter++)  
+//   {
+//     MED_EN::medGeometryElement type = iter->first;
+
+//     if (!isDimensionOK(type,dimension)) continue;
+//     if (type_numbers[type]==0) continue;
+
+//     if (type != MED_EN::MED_POLYHEDRA && type != MED_EN::MED_POLYGON)
+//     {
+//       mesh_builder->setConnectivity(type_connectivity[type],entity,type);
+//       delete[] type_connectivity[type];
+//     }
+//     else if (type == MED_EN::MED_POLYGON && dimension ==2)
+//     {
+//       mesh_builder->setPolygonsConnectivity(&polygon_conn_index[0],
+//                                             &polygon_conn[0],
+//                                             type_numbers[type],
+//                                             entity);
+//     }
+//     else if (type == MED_EN::MED_POLYHEDRA && dimension ==3)
+//     {
+//       mesh_builder->setPolyhedraConnectivity(&polyhedron_conn_index[0],
+//                                              &polyhedron_face_index[0],
+//                                              &polyhedron_conn[0],
+//                                              type_numbers[type],
+//                                              entity);
+
+//     }
+//   }
+//   MESSAGE_MED("end of createNodalConnectivity");
+// }
+
+
+// /*! retrieves the faces that are present in a mesh and stores them in a 
+//  * dynamic structure made of a map of MEDPARTITIONER_FaceModel
+//  * 
+//  * \param idomain domain id on which the faces are collected
+//  * \param face_map container storing the faces 
+//  */
+// void MESHCollection::getFaces(int idomain, 
+//                               map<MED_EN::medGeometryElement, vector<MEDPARTITIONER_FaceModel*> >& face_map)                     
+// {
+//   MED_EN::medEntityMesh constituent_entity = getSubEntity();
+//   const medGeometryElement* types;
+//   try
+//   {
+//     types = _mesh[idomain]->getTypes(constituent_entity);
+//   }
+//   catch(MEDEXCEPTION&){ return;}
+
+//   int nbtypes  = _mesh[idomain]->getNumberOfTypes(constituent_entity);
+//   const int* global_numbering= _mesh[idomain]->getGlobalNumberingIndex(constituent_entity);
+//   int* conn = const_cast<int*> (_mesh[idomain]->getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL,constituent_entity, MED_EN::MED_ALL_ELEMENTS));
+//   for (int itype=0; itype<nbtypes; itype++)
+//   {
+//     for (int iface=global_numbering[itype]; iface<global_numbering[itype+1]; iface++)
+//     {
+//       MEDPARTITIONER_FaceModel* face_model = new MEDPARTITIONER_FaceModel();
+//       MED_EN::medGeometryElement type =  types[itype];
+//       face_model->setType(type);
+//       int nbnodes = type%100;
+//       face_model->setNbNodes(nbnodes);
+//       face_model->setGlobal(_topology->convertFaceToGlobal(idomain,iface));
+//       for (int i=0; i<nbnodes; i++)
+//       {
+//         (*face_model)[i]=*conn++;
+//       }
+//       face_map[type].push_back(face_model);
+//     }
+//   }
+// }
+
+// /*! retrieves the face that is common to two cells located on two different processors
+//  * 
+//  * \param ip1 domain id for cell 1
+//  * \param ilocal1 cell id for cell 1
+//  * \param ip2 domain id for cell 2
+//  * \param ilocal2 cell id for cell 2
+//  * \param face_index global index for the newly created face 
+//  */
+// MEDPARTITIONER_FaceModel* MESHCollection::getCommonFace(int ip1,int ilocal1,int ip2,int ilocal2,int face_index)
+// {
+//   MED_EN::medGeometryElement type1 = _mesh[ip1]->getElementType(MED_EN::MED_CELL,ilocal1);
+//   MEDMEM::CELLMODEL celltype1 (type1);
+
+//   const int* conn_index1 =  _mesh[ip1]->getConnectivityIndex(MED_EN::MED_NODAL,MED_EN::MED_CELL);
+//   const int* conn1 = _mesh[ip1]->getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL,MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS);
+
+//   // MED_EN::medGeometryElement type2 = _mesh[ip2]->getElementType(MED_EN::MED_CELL,ilocal2);
+//   //MEDMEM::CELLTYPE celltype2 (type2);
+//   const int* conn_index2 =  _mesh[ip2]->getConnectivityIndex(MED_EN::MED_NODAL,MED_EN::MED_CELL);
+//   const int* conn2 = _mesh[ip2]->getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL,MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS);
+
+//   vector<int> nodes1, nodes1_local;
+//   vector<int> nodes2;
+//   for (int i=  conn_index1[ilocal1-1]; i<conn_index1[ilocal1]; i++)
+//   {
+//     nodes1.push_back(_topology->convertNodeToGlobal(ip1,*(conn1+i-1)));
+//     nodes1_local.push_back( conn1[i-1] );
+//   }
+//   for (int i=  conn_index2[ilocal2-1]; i<conn_index2[ilocal2]; i++)
+//     nodes2.push_back(_topology->convertNodeToGlobal(ip2,*(conn2+i-1)));
+
+//   return MEDPARTITIONER_FaceModel::getCommonFace( &nodes1[0], &nodes1_local[0], celltype1,
+//                                                &nodes2[0], nodes2.size(),  face_index);
+// }
+
+// //================================================================================
+// /*!
+//  * \brief Makes a face common for two given cells
+//  *  \param nodes1 - globl nodes of the first cell
+//  *  \param nodes1_local - local nodes of the first cell
+//  *  \param celltype1 - cell model of the first cell
+//  *  \param nodes2 - globl nodes of the second cell
+//  *  \param nb_nodes2 - nb of nodes of the second cell
+//  *  \param global_id - id of the new common face
+//  */
+// //================================================================================
+
+// MEDPARTITIONER_FaceModel*
+// MEDPARTITIONER_FaceModel::getCommonFace(const int*               nodes1,
+//                                      const int*               nodes1_local,
+//                                      const MEDMEM::CELLMODEL& celltype1,
+//                                      const int*               nodes2,
+//                                      int                      nb_nodes2,
+//                                      int                      global_id)
+// {
+//   int nbfaces= celltype1.getNumberOfConstituents(1);
+//   int ** faces = celltype1.getConstituents(1);
+//   MED_EN::medGeometryElement* types = celltype1.getConstituentsType(1);
+//   int iface=0;
+//   int dimension=celltype1.getDimension();
+
+//   while (iface<nbfaces)
+//   {
+//     //SCRUTE_MED (iface);
+//     int nbnodes= types[iface]%100;
+//     const int* nodes = celltype1.getNodesConstituent(1,iface+1);
+//     int common_nodes=0;
+//     for (int i=0; i<nbnodes;i++)
+//     {
+//       for (int i2=0; i2<nb_nodes2; i2++)
+//       {
+//         if (nodes1[nodes[i]-1]==nodes2[i2]) common_nodes++;
+//       }     
+//     }
+//     if (common_nodes>=dimension) break;
+//     iface++;
+//   }
+
+//   if (iface==nbfaces)
+//     throw MEDEXCEPTION("MEDPARTITIONER::getCommonFace - No common face found !");
+
+//   MEDPARTITIONER_FaceModel* face_model = new MEDPARTITIONER_FaceModel;
+//   face_model->setType(types[iface]);
+//   int nbnodes = types[iface]%100;
+//   face_model->setNbNodes(nbnodes);
+//   face_model->setGlobal(global_id); 
+//   for (int i=0; i<nbnodes; i++)
+//     (*face_model)[i]=nodes1_local[faces[iface][i]-1];
+
+//   return face_model;
+// }
diff --git a/src/MEDPartitioner/MEDPARTITIONER_MESHCollection.hxx b/src/MEDPartitioner/MEDPARTITIONER_MESHCollection.hxx
new file mode 100644 (file)
index 0000000..de08250
--- /dev/null
@@ -0,0 +1,270 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef __MEDPARTITIONER_MESHCOLLECTION_HXX__
+#define __MEDPARTITIONER_MESHCOLLECTION_HXX__
+
+#include "MEDPARTITIONER.hxx"
+
+#include "MEDPARTITIONER_Graph.hxx"
+//#include "MEDPARTITIONER_FaceModel.hxx"
+//#include "boost/shared_ptr.hpp"
+#include <vector>
+#include <map>
+
+namespace ParaMEDMEM
+{
+  class MEDCouplingUMesh;
+}
+
+namespace MEDPARTITIONER
+{
+
+  class Topology;
+  class MESHCollectionDriver;
+  class ParaDomainSelector;
+  class MEDSKYLINEARRAY;
+  class CONNECTZONE;
+
+  typedef enum{MedAscii, MedXML, Undefined} DriverType;
+
+  
+  class MEDPARTITIONER_EXPORT MESHCollection
+  {
+
+  public:
+
+    //Default constructor
+    MESHCollection();
+
+    //Constructing from an existing mesh and a new topology
+    MESHCollection(MESHCollection&, Topology*, bool family_splitting=false, bool create_empty_groups=false);
+
+    //Constructing the mesh collection from a file
+    MESHCollection(const std::string& filename);
+
+    //Constructing the mesh collection from a file
+    MESHCollection(const std::string& filename, ParaDomainSelector& domainSelector);
+
+    //Constructing the mesh collection from a file
+    MESHCollection(const std::string& filename, const std::string& meshname);
+
+    ~MESHCollection();
+        
+    bool isParallelMode() const { return _domain_selector; }
+        
+    //writing to a distributed file
+    void write(const std::string& filename);
+
+    //getting the driver
+    MESHCollectionDriver* retrieveDriver();
+    MESHCollectionDriver* getDriver() const;
+    void setDriverType(MEDPARTITIONER::DriverType type) {_driver_type=type;}
+
+    //creation of the cell graph
+    void buildCellGraph(MEDPARTITIONER::MEDSKYLINEARRAY* & array,int *& edgeweights );
+
+    //creation and partition of the associated graph
+    Topology* createPartition(int nbdomain, Graph::splitter_type type = Graph::METIS,
+                              const std::string& ="", int* edgeweights=0, int* verticesweights=0);
+
+    //creation of a user specified partition
+    Topology* createPartition(const int* partition);
+
+   //  //retrieving list of types
+//       void getTypeList(int* cell_list,int nb_cells,MED_EN::medEntityMesh entity,
+//                      MED_EN::medGeometryElement* type_list) const ;
+
+//     //getting list of coordinates
+//     void getCoordinates(int* node_list,int nb_nodes, double* coordinates) const ;
+
+//     //getting connectivities
+//     void getNodeConnectivity( const int*  cell_list,int nb_cells,MED_EN::medEntityMesh,MED_EN::medGeometryElement type, int* type_connectivity) const ;
+//     void getPolygonNodeConnectivity(const int* cell_list,int nb_cells,MED_EN::medEntityMesh entity,
+//                                     vector<int>& type_connectivity, vector<int>& connectivity_index) const;
+//     void getPolyhedraNodeConnectivity(const int* cell_list,int nb_cells,MED_EN::medEntityMesh entity,
+//                                       vector<int>& type_connectivity, vector<int>& connectivity_index, vector<int>& face_connectivity_index) const;
+
+//     void getFaceConnectivity( const int*  cell_list,int nb_cells,MED_EN::medEntityMesh,MED_EN::medGeometryElement type, int* type_connectivity) const ;
+
+//     //void getFaceConnectivity( const int*  cell_list,int nb_cells,MED_EN::medGeometryElement type, int* type_connectivity) const ;
+
+//     //getting mesh dimension
+     int getMeshDimension() const ;
+
+//     //getting space dimension
+//     int getSpaceDimension() const ;
+
+//     //getting system of coordinates
+//     std::string getSystem() const;
+
+//     //getting name of the mesh
+//     std::string getMeshName() const;
+
+//     //return constituent entity
+//     MED_EN::medEntityMesh getSubEntity() const;
+
+//     //getting a reference to mesh vector
+     std::vector<ParaMEDMEM::MEDCouplingUMesh*>& getMesh() ;
+     std::vector<ParaMEDMEM::MEDCouplingUMesh*>& getFaceMesh() ;
+     std::vector<std::vector<ParaMEDMEM::MEDCouplingUMesh*> >&getGroupMeshes();
+     ParaMEDMEM::MEDCouplingUMesh* getMesh(int idomain);
+     ParaMEDMEM::MEDCouplingUMesh* getFaceMesh(int idomain);
+     std::vector<ParaMEDMEM::MEDCouplingUMesh*>& getGroupMeshes(int idomain);
+
+//     //getting a reference to a domain mesh
+//     MEDMEM::MESH* getMesh(int) const;
+
+//     //getting a reference to connect zones vector
+    std::vector<MEDPARTITIONER::CONNECTZONE*>& getCZ();
+
+    //getting a pointer to topology
+    Topology* getTopology() const ;
+
+
+    //settig a new topology
+    void setTopology(Topology* topology);
+
+    //getting/setting the name of the global mesh (as opposed 
+    //to the name of a subdomain \a nn, which is name_nn) 
+    std::string getName() const {return _name;}
+    void setName(const std::string& name) {_name=name;}
+
+    //getting/setting the description of the global mesh
+    std::string getDescription() const {return _description;}
+    void setDescription(const std::string& name) { _description=name;}
+
+    //creates the node mapping between an old collection and the present one
+    void createNodeMapping( MESHCollection& initialCollection, std::multimap<std::pair<int,int>,std::pair<int,int> >& nodeMapping);
+
+    //creates faces on the new collection
+    void castFaceMeshes( MESHCollection& initialCollection,const std::multimap<std::pair<int,int>,std::pair<int,int> >& nodeMapping);
+
+    //creates faces on the new collection
+    void castMeshes(std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshCastFrom,std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshCastTo,   MESHCollection& initialCollection,const std::multimap<std::pair<int,int>,std::pair<int,int> >& nodeMapping);
+
+    //!transfers families from an old MESHCollection to new mesh
+               //    void castFamilies(const MESHCollection& old_collection);
+
+    //void castSupport(const MESHCollection& old_collection, std::vector<const MEDMEM::SUPPORT*>& old_support, std::vector<MEDMEM::SUPPORT*>& new_support);
+
+//     //!casts all the fields to the new mesh collection
+//     void castAllFields(const MESHCollection& old_collection);
+
+//     //!casts one specific field to the new mesh collection
+//     void castField(const MESHCollection& old_collection, const string& fieldname, int itnumber, int ordernumber);
+
+//     //choosing a group to be indivisible
+//     void setIndivisibleGroup(const string& a);
+
+//     //!constructing connect zones
+//     // void buildConnectZones(int idomain);
+//     void buildConnectZones();
+//     void buildConnectZonesBetweenProcs(std::vector <std::map <MED_EN::medGeometryElement, std::vector<MEDPARTITIONER_FaceModel*> > > &, map< pair<int,int>, MEDPARTITIONER::MEDSKYLINEARRAY*> & local_cell_cell_correspondency);
+
+//     void addJointGroup(const std::vector<int>&, int idomain, int idistant);
+
+//     static bool isDimensionOK(MED_EN::medGeometryElement type, int dim)
+//     {
+//       return ((type/100 == dim) || (dim==2 && type == MED_EN::MED_POLYGON) || (dim==3 && type == MED_EN::MED_POLYHEDRA));
+//     }
+//     void setSubdomainBoundaryCreates(bool flag) {  _subdomain_boundary_creates=flag;}
+//     bool getSubdomainBoundaryCreates(){return _subdomain_boundary_creates;}
+
+//     void setFamilySplitting(bool flag){_family_splitting=flag;}
+//     bool getFamilySplitting(){return _family_splitting;}
+
+//     void setCreateEmptyGroups(bool flag){_create_empty_groups=flag;}
+//     bool getCreateEmptyGroups(){return _create_empty_groups;}
+
+
+  private:
+
+ //    //!creates connectivities for a domain and an entity (face or cell)
+//     void createNodalConnectivity(const MESHCollection & initial_collection, int idomain, MED_EN::medEntityMesh entity);
+
+//     //!creates the tags for indivisible groups
+//     void treatIndivisibleRegions(int* tag);
+
+//     //!projects a field from an old collection to the present one
+//     //!field is identified by (name, dt, it)
+//     template <class T>
+//     void castFields(const MESHCollection& old_collection, const string& fieldname, int itnumber, int ordernumber);
+
+//     void getFaces(int idomain, std::map<MED_EN::medGeometryElement, std::vector<MEDPARTITIONER_FaceModel*> >&);
+
+//     MEDPARTITIONER_FaceModel* getCommonFace(int ip1,int ilocal1,int ip2,int ilocal2,int face_index);
+
+//     template<class TID2CONN>
+//     void fillGlobalConnectivity(TID2CONN & node2cell, TID2CONN & cell2node );
+
+    //!link to mesh_collection topology
+    Topology*                         _topology;
+
+    //!control over topology
+    bool                              _owns_topology;
+
+    //!link to graph
+    //    Graph*          _cell_graph;
+
+    //! Driver for read/write operations
+    MESHCollectionDriver*             _driver;
+
+    //! Parallelizer - mark of parallel execution mode
+    ParaDomainSelector*               _domain_selector;
+
+    //!links to meshes
+    std::vector<ParaMEDMEM::MEDCouplingUMesh*>        _mesh;
+    std::vector<ParaMEDMEM::MEDCouplingUMesh*>        _faceMesh;
+    std::vector< std::vector<ParaMEDMEM::MEDCouplingUMesh*> >        _groupMesh;
+    
+    //!index of a non empty mesh within _mesh (in parallel mode all of meshes can be empty)
+    int                               _i_non_empty_mesh;
+
+    //!links to connectzones
+    std::vector<MEDPARTITIONER::CONNECTZONE*> _connect_zones;
+
+    //!list of groups that are not to be splitted
+    std::vector<std::string>          _indivisible_regions;
+
+    //!name of global mesh
+    std::string                            _name;
+
+    //!description of global mesh
+    std::string                            _description;
+
+    //! specifies the driver associated to the collection
+    DriverType                        _driver_type;
+
+    /*! flag specifying that the splitter should create boundary constituent entity
+      so that they are written in joints*/
+    bool                              _subdomain_boundary_creates;
+
+        /*! flag specifying that families must be preserved by the
+                splitting*/
+    bool                              _family_splitting;
+
+        /*! flag specifying that groups must be created on all domains, 
+                even if they are empty*/
+    bool                              _create_empty_groups;
+  };
+
+}//of namespace
+
+#endif /*MESHCOLLECTION_*/
diff --git a/src/MEDPartitioner/MEDPARTITIONER_MESHCollectionDriver.cxx b/src/MEDPartitioner/MEDPARTITIONER_MESHCollectionDriver.cxx
new file mode 100644 (file)
index 0000000..3a6aa35
--- /dev/null
@@ -0,0 +1,697 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include <vector>
+#include <string>
+#include <map>
+#include <set>
+
+#include <iostream>
+#include <fstream>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#include <sys/time.h>
+#include "MEDCouplingUMesh.hxx"
+#include "MEDLoader.hxx"
+#include "MEDMEM_Exception.hxx"
+extern "C" {
+#include "med.h"
+}
+//MEDPARTITIONER includes
+#include "MEDPARTITIONER_ConnectZone.hxx"
+#include "MEDPARTITIONER_Topology.hxx"
+#include "MEDPARTITIONER_ParallelTopology.hxx"
+#include "MEDPARTITIONER_SequentialTopology.hxx"
+#include "MEDPARTITIONER_MESHCollectionDriver.hxx"
+#include "MEDPARTITIONER_MESHCollection.hxx"
+#include "MEDPARTITIONER_ParaDomainSelector.hxx"
+
+using namespace MEDPARTITIONER;
+
+//template inclusion
+//#include "MEDPARTITIONER_MESHCollectionDriver.H"
+
+med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE+2] = { MED_POINT1,
+                                                             MED_SEG2,
+                                                             MED_SEG3,
+                                                             MED_TRIA3,
+                                                             MED_TRIA6,
+                                                             MED_QUAD4,
+                                                             MED_QUAD8,
+                                                             MED_TETRA4,
+                                                             MED_TETRA10,
+                                                             MED_HEXA8,
+                                                             MED_HEXA20,
+                                                             MED_PENTA6,
+                                                             MED_PENTA15,
+                                                             MED_PYRA5,
+                                                             MED_PYRA13,
+                                                             MED_POLYGONE,
+                                                             MED_POLYEDRE };
+
+MESHCollectionDriver::MESHCollectionDriver(MESHCollection* collection):_collection(collection)
+{
+}
+
+
+/*!reads a unique MED File v>=2.1
+ * and mounts the corresponding mesh in memory
+ *\param filename binary file
+ *\param meshname mesh name in the MED file
+ * */
+int MESHCollectionDriver::readSeq(char* filename, char* meshname)
+{
+  //const char* LOC = "MEDPARTITIONER::MESHCollectionDriver::readSeq()";
+  //  BEGIN_OF_MED(LOC);
+
+  _filename.resize(1);
+  _filename[0]=string(filename);
+  //puts the only mesh in the mesh vector
+  (_collection->getMesh()).push_back(MEDLoader::ReadUMeshFromFile(filename, meshname, 0));
+  (_collection->getFaceMesh()).push_back(MEDLoader::ReadUMeshFromFile(filename,meshname,-1));
+
+  //reading groups
+  vector<string> groupNames = MEDLoader::GetMeshGroupsNames(filename,meshname);
+  (_collection->getGroupMeshes()).resize(groupNames.size());
+  
+  for (int i=0; i< groupNames.size();i++)
+    {
+      vector<string> myGroup;
+      myGroup.push_back(groupNames[i]);
+      (_collection->getGroupMeshes())[i].push_back(MEDLoader::ReadUMeshFromGroups(filename,meshname,-1,myGroup));
+    }
+
+
+  _collection->setName(meshname);
+  (_collection->getCZ()).clear();
+  vector<int*> cellglobal,nodeglobal,faceglobal;
+  cellglobal.resize(1);
+  nodeglobal.resize(1);
+  faceglobal.resize(1);
+  cellglobal[0]=0;
+  nodeglobal[0]=0;
+  faceglobal[0]=0;
+  //creation of topology from mesh 
+  //connectzone argument is 0
+  ParallelTopology* aPT = new ParallelTopology
+    ((_collection->getMesh()), (_collection->getCZ()), cellglobal, nodeglobal, faceglobal);
+  _collection->setTopology(aPT);
+  //  END_OF_MED(LOC);
+  return 0;
+}
+
+// /*!
+//  * Reads the file structure to determine the list
+//  * of all the available fields
+//  *
+//  * \param field_names, vector<string> containing the field names
+//  * \param iternumber, vector<int> containing the iteration numbers
+//  * \param ordernumber, vector<int> containing the order numbers
+//  * \param types, vector<int> containing 0 for int fields and 1 for double fields
+//  * 
+//  */
+
+// void MESHCollectionDriver::readFileStruct(vector <string>&  field_names,vector<int>& iternumber,vector <int>&  ordernumber, vector <int>& types)
+// {
+//   const char* LOC = "MEDPARTITIONER::MESHCollectionDriver::readFileStruct()";
+//   BEGIN_OF_MED(LOC);
+
+//   const MEDMEM::MED med_struct (MEDMEM::MED_DRIVER,_filename[0]);
+//   int nb_fields = med_struct.getNumberOfFields();
+
+//   MESSAGE_MED("found "<<nb_fields<<" fields in file")
+//     deque<string> names = med_struct.getFieldNames();
+//   for (int ifield = 0; ifield < nb_fields; ifield++)
+//   {
+//     deque<MEDMEM::DT_IT_> dtit=med_struct.getFieldIteration(names[ifield]);
+
+//     for (deque<MEDMEM::DT_IT_>::const_iterator iter =dtit.begin(); iter!=dtit.end(); iter++)
+//     {
+//       field_names.push_back(names[ifield]);
+//       iternumber.push_back(iter->dt);
+//       ordernumber.push_back(iter->it);  
+
+//       // testing whether the field is of double or int type   
+//       MEDMEM::FIELD_* field = med_struct.getField(names[ifield],iter->dt,iter->it);
+//       if (dynamic_cast<MEDMEM::FIELD<double>*>(field))
+//         types.push_back(1);
+//       else
+//         types.push_back(0);
+
+//     }
+//   }
+//   END_OF_MED(LOC);
+// }
+
+// //!retrieves the type of a field for a given fieldname
+// int MESHCollectionDriver::getFieldType(const string& fieldname)
+// {
+//   const char* LOC = "MEDPARTITIONER::MESHCollectionDriver::getFieldType()";
+//   BEGIN_OF_MED(LOC);
+//   const MEDMEM::MED med_struct (MEDMEM::MED_DRIVER,_filename[0]);
+
+//   deque<MEDMEM::DT_IT_> dtit=med_struct.getFieldIteration(fieldname);
+//   deque<MEDMEM::DT_IT_>::const_iterator iter =dtit.begin();
+
+//   // testing whether the field is of double or int type   
+//   MEDMEM::FIELD_* field = med_struct.getField(fieldname,iter->dt,iter->it);
+
+//   END_OF_MED(LOC);
+
+//   if (dynamic_cast<MEDMEM::FIELD<double>*>(field))
+//     return 1;
+//   else
+//     return 0;     
+
+// }
+// namespace
+// {
+// //================================================================================
+// /*!
+//  * \brief Structure used in the method below
+//  */
+// struct TJointData
+// {
+//   char             _name[MED_TAILLE_NOM+1];
+//   int              _nb_couples;
+//   med_int _distant_domain;
+//   med_geometrie_element _geo_local, _geo_dist;
+// };
+// }
+
+// //================================================================================
+// /*!
+//  * \brief Read CELL-CELL correspondences of joints with domains on other procs
+//  *  \param idomain - domain index to return correspondence for
+//  *  \param loc_domains - domians on this pocessor
+//  *  \param domain_selector - info on cell distribution among procs
+//  *  \param loc2glob_corr - out, correspondence pairs where distant ids are global
+//  */
+// //================================================================================
+
+// void MESHCollectionDriver::readLoc2GlobCellConnect(int                 idomain,
+//                                                    const set<int>&     loc_domains,
+//                                                    ParaDomainSelector* domain_selector,
+//                                                    vector<int> &       loc2glob_corr)
+// {
+//   using namespace med_2_3;
+//   med_err err;
+
+//   // find joints of domains touching idomain and loaded on other processors
+
+//   TJointData joint;
+//   list< TJointData > joints;
+//   int total_nb_couples = 0;
+
+//   MEDMEM::MESH* loc_mesh = _collection->getMesh()[idomain];
+//   char* meshname = (char*) _meshname[idomain].c_str();
+//   char* filename = (char*) _filename[idomain].c_str();
+//   //cout << "#" << domain_selector->rank() << ": mesh - " << meshname << endl;
+
+//     med_idt fid = MEDouvrir( filename, MED_LECTURE);
+//   int njoint = MEDnJoint(fid, meshname);
+//   for (int ijoint=0; ijoint<njoint; ijoint++)
+//   {
+//     char joint_description[MED_TAILLE_DESC+1], name_distant[MED_TAILLE_NOM+1];
+
+//     err = MEDjointInfo(fid, meshname, ijoint+1, joint._name, 
+//                        joint_description, &joint._distant_domain, name_distant);
+//     if ( err || loc_domains.count( joint._distant_domain ))
+//       continue;  // distant is on this proc
+
+//     MED_EN::medGeometryElement* types = loc_mesh->getTypesWithPoly(MED_EN::MED_CELL);
+//     int                       nbtypes = loc_mesh->getNumberOfTypesWithPoly(MED_EN::MED_CELL);
+//     const list<MED_EN::medGeometryElement>& all_types = MED_EN::meshEntities[ MED_EN::MED_CELL ];
+//     for (int itype=0; itype<nbtypes;itype++)
+//     {
+//       joint._geo_local = (med_geometrie_element) types[itype];
+//       list<MED_EN::medGeometryElement>::const_iterator dist_type = all_types.begin();
+//       for ( ; dist_type != all_types.end(); ++dist_type )
+//       {
+//         if ( !_collection->isDimensionOK( *dist_type, loc_mesh->getMeshDimension() ))
+//           continue;
+//         joint._geo_dist = (med_geometrie_element) *dist_type;
+//         joint._nb_couples = MEDjointnCorres(fid, meshname, joint._name,
+//                                             MED_MAILLE, joint._geo_local,
+//                                             MED_MAILLE, joint._geo_dist );
+//         if ( joint._nb_couples > 0 )
+//         {
+//           joints.push_back( joint );
+//           total_nb_couples += joint._nb_couples;
+//         }
+//       }
+//     }
+//     delete [] types;
+//   }
+
+//   // read cell pairs of found joints and replace distant local ids with global ones
+
+//   loc2glob_corr.resize( 2 * total_nb_couples );
+//   if ( total_nb_couples > 0 )
+//   {
+//     int* cell_corresp = & loc2glob_corr[0];
+
+//     list< TJointData >::iterator jnt = joints.begin();
+//     for ( ; jnt != joints.end(); ++jnt )
+//     {
+//       // read cell couples
+//       if ( MEDjointLire( fid, meshname, jnt->_name,
+//                          cell_corresp, 2 * jnt->_nb_couples,
+//                          MED_MAILLE, jnt->_geo_local,
+//                          MED_MAILLE, jnt->_geo_dist ) < 0 ) continue;
+
+//       // distant local ids -> global ids
+//       if ( int shift_to_global = domain_selector->getDomainShift( jnt->_distant_domain ))
+//         for ( int i = 0 ; i < jnt->_nb_couples; ++i )
+//           cell_corresp[ 2*i + 1 ] += shift_to_global;
+
+//       cell_corresp += 2 * jnt->_nb_couples;
+//     }
+//   }
+//   MEDfermer( fid );
+// }
+
+//================================================================================
+/*!
+ * \brief Return mesh dimension from distributed med file had being read
+ */
+//================================================================================
+
+// int MESHCollectionDriver::readMeshDimension() const
+// {
+//   const char* LOC = "MESHCollectionDriver::readMeshDimension(): ";
+//   if ( _filename.empty() || _meshname.empty() )
+//     throw MEDMEM::MED_EXCEPTION( "file name or mesh name not available");
+
+//   MEDMEM::MED med(MEDMEM::MED_DRIVER, _filename[0]);
+//   if ( MEDMEM::MESH* mesh = med.getMesh( _meshname[0] ))
+//     return mesh->getMeshDimension();
+  
+//   throw MEDMEM::MED_EXCEPTION( MEDMEM::STRING(LOC) << "mesh name is invalid");
+// }
+
+void MESHCollectionDriver::readSubdomain(vector<int*>& cellglobal,
+                                         vector<int*>& faceglobal,
+                                         vector<int*>& nodeglobal, int idomain)
+{
+//   const char* LOC = "MEDPARTITIONER::MESHCollectionDriver::readSubdomain()";
+//   BEGIN_OF_MED(LOC);
+  char file[256];
+  char meshname[MED_TAILLE_NOM+1];
+
+  strcpy(meshname,_meshname[idomain].c_str());
+  strcpy(file,_filename[idomain].c_str());
+  cout << "Reading "<<_meshname[idomain]<<" in "<<_filename[idomain]<<endl;
+  //(_collection->getMesh())[idomain]=new MEDMEM::MESH(MEDMEM::MED_DRIVER,file, meshname);
+  (_collection->getMesh())[idomain]=MEDLoader::ReadUMeshFromFile(file,meshname,0);
+  (_collection->getFaceMesh())[idomain]=MEDLoader::ReadUMeshFromFile(file,meshname,-1);
+
+  //reading groups
+  vector<string> groupNames = MEDLoader::GetMeshGroupsNames(file,meshname);
+  if (idomain==0)
+      (_collection->getGroupMeshes()).resize(groupNames.size());
+  
+  for (int i=0; i< groupNames.size();i++)
+    {
+      vector<string> myGroup;
+      myGroup.push_back(groupNames[i]);
+      (_collection->getGroupMeshes())[i].push_back(MEDLoader::ReadUMeshFromGroups(file,meshname,-1,myGroup));
+    }
+
+  cout <<"End of Read"<<endl;
+  //reading MEDPARTITIONER::CONNECTZONEs NODE/NODE and CELL/CELL
+  med_idt fid = MEDouvrir(file,MED_LECTURE);
+  med_int njoint = MEDnJoint(fid, meshname);
+  for (int ijoint=0; ijoint<njoint; ijoint++)
+  {
+    int distant;
+    char joint_description[MED_TAILLE_DESC+1];
+    char name[MED_TAILLE_NOM+1];
+    char name_distant[MED_TAILLE_NOM+1];
+
+    int ncorr = MEDjointInfo(fid,meshname, ijoint+1, name, 
+                                      joint_description,
+                                      &distant, name_distant);
+
+    for (int ic=0; ic<ncorr; ic++)
+    {
+      med_entite_maillage cor_typent_local;
+      med_geometrie_element cor_typgeo_local;
+      med_entite_maillage cor_typent_dist;
+      med_geometrie_element cor_typgeo_dist;
+
+
+      int ncouples;
+      ncouples = MEDjointTypeCorres(fid, meshname, name, ic+1,
+                                             &cor_typent_local,  &cor_typgeo_local,
+                                             &cor_typent_dist, &cor_typgeo_dist
+                                             );
+      int* node_corresp=new int[ncouples];
+      if (cor_typent_local == MED_NOEUD && cor_typent_dist == MED_NOEUD)
+      {
+
+        MEDjointLire(fid, meshname, name,
+                              node_corresp,ncouples,
+                              cor_typent_local,  cor_typgeo_local,
+                              cor_typent_dist, cor_typgeo_dist
+                              );
+      }
+      //constructing the connect zone and adding it to the connect zone list
+      MEDPARTITIONER::CONNECTZONE* cz = new MEDPARTITIONER::CONNECTZONE();
+      cz->setName(string(name));
+      cz->setDescription(joint_description);
+      cz->setLocalDomainNumber(idomain);
+      cz->setDistantDomainNumber(distant);
+      cz->setLocalMesh((_collection->getMesh())[idomain]);
+      cz->setDistantMesh((_collection->getMesh())[distant]);
+      cz->setNodeCorresp(node_corresp,ncouples);
+      (_collection->getCZ()).push_back(cz);
+
+    }//loop on correspom_topology->nbDomain())ndances
+  }//loop on joints 
+
+  // Reading global numbering
+  // à faire dans MEDLoader 
+
+  //  MEDCouplingFieldDouble globalcell=MEDLoader::GetGlobalNumbering(file,meshname,0);
+
+
+   MEDfermer(fid);
+
+   //  END_OF_MED(LOC);
+}
+
+void MESHCollectionDriver::writeSubdomain(int idomain, int nbdomains, char* distfilename,
+                                          ParaDomainSelector* domain_selector)
+{
+  //build connect zones
+  //      if (nbdomains>1)
+  //  _collection->buildConnectZones(idomain);
+
+  //  MESSAGE_MED(" Number of connect zones "<<(_collection->getCZ()).size());
+
+  //writing connect zones in joints
+
+  med_idt fid = MEDouvrir(distfilename,MED_LECTURE_ECRITURE);  
+
+  int index_joint=0;
+
+
+  for (int icz=0; icz<(_collection->getCZ()).size(); icz++)
+  {
+    if ((_collection->getCZ())[icz]->getLocalDomainNumber()==idomain)
+    {
+      med_err error;
+      int idistant=(_collection->getCZ())[icz]->getDistantDomainNumber();
+      char joint_name[MED_TAILLE_NOM+1];
+      sprintf(joint_name,"joint_%i",idistant+1);
+      char desc[MED_TAILLE_DESC+1];
+      sprintf(desc,"connect_zone_%d",icz+1);
+
+      char distant_name[MED_TAILLE_NOM+1];
+      //sprintf(distant_name,"domain_%i",(_collection->getCZ())[icz]->getDistantDomainNumber());
+
+      //        sprintf(distant_name,(_collection->getMesh())[idistant]->getName().c_str());
+      sprintf(distant_name,"domain_%i",idistant);
+      char mesh_name[MED_TAILLE_NOM+1];
+
+      strcpy (mesh_name, (_collection->getMesh())[idomain]->getName());
+      //      SCRUTE_MED((_collection->getMesh())[idomain]->getName());
+      error = MEDjointCr(fid,mesh_name, joint_name, desc, 
+                                  idistant, distant_name);
+      if (error==-1) cout << "erreur creation de joint "<<endl;
+
+      /////////////////////////////////////////
+      //writing node/node correspondency
+      /////////////////////////////////////////
+      int nbnodes=(_collection->getCZ())[icz]->getNodeNumber();
+      int* node_corresp=const_cast<int*>((_collection->getCZ())[icz]->getNodeCorrespValue());
+
+      /* Nodes are reordered so that the ordering on the local and the distant domain
+         correspond. The chosen order is the natural ordering on the domain
+         with lowest proc id*/
+      // if (_collection->getSubdomainBoundaryCreates())
+//         if (idomain<idistant)
+//           jointSort(node_corresp, nbnodes, true);
+//         else
+//           jointSort(node_corresp, nbnodes, false);
+
+      error=
+        MEDjointEcr(fid, mesh_name, joint_name, node_corresp, nbnodes,
+                             MED_NOEUD, MED_POINT1,MED_NOEUD, MED_POINT1);
+      if (error==-1) cout << "erreur creation de joint "<<endl;
+
+      //writing cell/cell joint      
+//      writeElementJoint(MED_EN::MED_CELL, icz, idomain, idistant, mesh_name,joint_name,fid);
+      //writing face/face joint
+//       if (_collection->getSubdomainBoundaryCreates())
+//       {
+//         MED_EN::medEntityMesh constituent_entity =
+//           (_collection->getMeshDimension()==3)?MED_EN::MED_FACE:MED_EN::MED_EDGE;
+//         writeElementJoint(constituent_entity, icz, idomain, idistant, mesh_name,joint_name,fid);                 
+//       }                   
+      index_joint++;
+    }
+  }
+  
+  char meshchar[MED_TAILLE_NOM+1];
+  strcpy(meshchar,(_collection->getMesh())[idomain]->getName());
+  
+  // Writing cell global numbering
+//   // 
+//   {
+//     int ncell=_collection->getTopology()->getCellNumber(idomain);
+//     int* array=new int[ncell];
+//     _collection->getTopology()->getCellList(idomain,array);
+//     int offset=0;
+
+   //  MED_EN::MESH_ENTITIES::const_iterator currentEntity;
+//     list<MED_EN::medGeometryElement>::const_iterator iter;
+//     currentEntity  = MED_EN::meshEntities.find(MED_EN::MED_CELL);
+
+//     int nbtypes = (_collection->getMesh())[idomain]->getNumberOfTypesWithPoly(MED_EN::MED_CELL);
+//     MED_EN::medGeometryElement* types =(_collection->getMesh())[idomain]->getTypesWithPoly(MED_EN::MED_CELL);
+//     for (int itype=0; itype<nbtypes;itype++)
+//     {
+//       MED_EN::medGeometryElement type=types[itype];
+//       if (!_collection->isDimensionOK(type,_collection->getMeshDimension())) continue;
+//       int ntype = (_collection->getMesh())[idomain]->getNumberOfElementsWithPoly(MED_EN::MED_CELL,type);
+//       if (ntype==0) continue;
+//       MEDglobalNumEcr(fid,meshchar, array+offset, ntype,
+//                                MED_MAILLE, (med_geometrie_element)type);
+//       offset+=ntype;
+
+//     }
+//    delete[] types;
+  //   delete[] array;
+  //  }
+
+//   MED_EN::medEntityMesh constituent_entity;
+//   if (_collection->getMeshDimension()==3)
+//     constituent_entity=MED_EN::MED_FACE;
+//   else if (_collection->getMeshDimension()==2)
+//     constituent_entity=MED_EN::MED_EDGE;
+//   else throw MEDEXCEPTION("Wrong dimension");
+
+
+//   //writing face global numbering
+//   {
+//     int * array;
+//     int offset=0;
+//     int nface= _collection->getTopology()->getFaceNumber(idomain);
+//     if (nface >0)
+//       array=new int[nface];
+//     _collection->getTopology()->getFaceList(idomain,array);
+
+//     int nbfacetypes = (_collection->getMesh())[idomain]->getNumberOfTypesWithPoly(constituent_entity);
+//     MED_EN::medGeometryElement* facetypes;
+//     if (nbfacetypes>0) 
+//       facetypes =(_collection->getMesh())[idomain]->getTypesWithPoly(constituent_entity);
+
+//     for (int itype=0; itype<nbfacetypes;itype++)
+//     {
+//       MED_EN::medGeometryElement type=facetypes[itype];
+//       if (!_collection->isDimensionOK(type,_collection->getMeshDimension()-1)) continue;
+
+//       int ntype = (_collection->getMesh())[idomain]->getNumberOfElementsWithPoly(constituent_entity,type);
+//       if (ntype==0) continue;
+//       MEDglobalNumEcr(fid,meshchar, array+offset, ntype,
+//                                MED_MAILLE, (med_geometrie_element)type);
+
+//       offset+=ntype;
+//     }
+//     if (nface>0) delete[] array;
+//     if (nbfacetypes>0) delete[] facetypes;
+//   }
+
+
+//   //writing node global numbering
+//   {
+//     int nnode=_collection->getTopology()->getNodeNumber(idomain);
+//     int* array = new int[nnode];
+//     _collection->getTopology()->getNodeList(idomain,array);
+//     MEDglobalNumEcr(fid,meshchar, array, nnode,
+//                              MED_NOEUD, MED_POINT1);
+//     delete[] array;
+//   }
+
+  MEDfermer(fid);
+  std::cout<<"End of writing"<<std::endl;
+
+}
+
+// void MESHCollectionDriver::writeElementJoint(medEntityMesh entity ,
+//                                              int icz, 
+//                                              int idomain, 
+//                                              int idistant, 
+//                                              char* mesh_name, 
+//                                              char* joint_name,  
+//                                              med_idt fid )
+// {
+//   //////////////////////////////////////////
+//   //writing cell/cell correspondency
+//   //////////////////////////////////////////
+//   int nbcells=(_collection->getCZ())[icz]->getEntityCorrespNumber(entity,entity);
+//   const int* index = (_collection->getCZ())[icz]->getEntityCorrespIndex(entity,entity);
+//   const int* value = (_collection->getCZ())[icz]->getEntityCorrespValue(entity,entity);
+//   if ( nbcells==0 ) return; // e.g. domains have 1 common node
+
+//   map <pair <MED_EN::medGeometryElement, MED_EN::medGeometryElement> , vector<int> > cellmap;
+//   map <MED_EN::medGeometryElement, int> local_offset;
+//   map <MED_EN::medGeometryElement, int> distant_offset;
+
+//   //definition of the local offsets for the types present on local
+//   //and distant domains
+//   // for a mesh containing 2 triangles and 3 quads
+//   //local_offset[TRIA3]=0
+//   //local_offset[QUAD4]=2
+
+//   int nb_types_local=(_collection->getMesh())[idomain]-> getNumberOfTypes(entity);
+//   const MED_EN::medGeometryElement* local_types = (_collection->getMesh())[idomain]->getTypes(entity);
+//   const int* local_gni = (_collection->getMesh())[idomain]-> getGlobalNumberingIndex(entity);
+//   for (int i=0; i< nb_types_local; i++)
+//   {
+//     local_offset[local_types[i]]=local_gni[i]-1;
+//   }                                      
+
+//   int nb_types_distant=(_collection->getMesh())[idistant]-> getNumberOfTypes(entity);
+//   const MED_EN::medGeometryElement* distant_types = (_collection->getMesh())[idistant]->getTypes(entity);
+//   const int* distant_gni = (_collection->getMesh())[idistant]-> getGlobalNumberingIndex(entity);
+//   for (int i=0; i< nb_types_distant; i++)
+//   {
+//     distant_offset[distant_types[i]]=distant_gni[i]-1;
+//   } 
+
+//   if (nb_types_local==1 && nb_types_distant==1)
+//   {
+//     MED_EN::medGeometryElement local_type =  (_collection->getMesh())[idomain]->getElementType(entity,1);
+//     MED_EN::medGeometryElement distant_type = (_collection->getMesh())[idistant]->getElementType(entity,1);
+//     vector<int> corresp;
+//     for (int i=0; i<nbcells; i++)
+//       for (int icol = index[i]-1; icol<index[i+1]-1; icol++)
+//       {
+//         corresp.push_back(i+1);
+//         corresp.push_back(value[icol]);
+//       }
+//     int size_joint = corresp.size()/2;
+//     MEDjointEcr(fid, mesh_name, joint_name, &corresp[0], 
+//                          size_joint, MED_MAILLE,
+//                          (med_geometrie_element)local_type    ,MED_MAILLE, 
+//                          (med_geometrie_element)distant_type    );
+//   }
+//   else
+//   {
+//     //classifying all the cell/cell relationships into geomtype/geomtype relationships
+//     //there exists a vector for each geomtype/geomtype pair
+//     // the vectors are stored in cellmap, a std::map with a pair<geomtype,geomtype> key 
+
+//     for (int i=0; i<nbcells; i++)
+//       for (int icol = index[i]-1; icol<index[i+1]-1; icol++)
+//       {
+//         MED_EN::medGeometryElement local_type =  (_collection->getMesh())[idomain]->getElementType(entity,i+1);
+//         MED_EN::medGeometryElement distant_type = (_collection->getMesh())[idistant]->getElementType(entity,value[icol]);
+
+//         cellmap[make_pair(local_type, distant_type)].push_back(i+1-local_offset[local_type]);
+//         cellmap[make_pair(local_type, distant_type)].push_back(value[icol]-distant_offset[distant_type]);
+
+//       }
+//     map <pair <MED_EN::medGeometryElement, MED_EN::medGeometryElement> , vector<int> >::const_iterator iter;
+
+//     //going through all the (geom,geom) pairs and writing the joints
+//     for (iter= cellmap.begin(); iter != cellmap.end(); iter++)
+//     {
+//       int size= iter->second.size();
+//       int *corresp = new int[size];
+//       for (int ind=0; ind < size; ind++)
+//         corresp[ind]=(iter->second)[ind];
+//       med_geometrie_element local_geo_elem=(med_geometrie_element)iter->first.first;
+//       med_geometrie_element distant_geo_elem=(med_geometrie_element)iter->first.second;
+//       int size_joint=size/2;
+//       //med_err error =
+//       MEDjointEcr(fid, mesh_name, joint_name, corresp, size_joint, MED_MAILLE,
+//                            local_geo_elem,MED_MAILLE, distant_geo_elem);
+//       delete[] corresp;
+//     }
+//     // MED v 2.3.1 returns an error code when
+//     // writing a joint that is already present in the file.
+//     // Also, it returns an error code if a joint
+//     // concerns 3D elements.
+//     // Until these two items are not
+//     // changed, the following line must be commented out
+
+//     //if (error==-1) throw MEDEXCEPTION("Error filling joint");
+
+
+//   }
+// }
+
+// void MESHCollectionDriver::jointSort(int* elems, int nbelems, bool is_first)
+// {
+//   //filling an ordered structure with the elem ids
+//   map <int,int> nodemap;
+//   if (is_first)
+//     for (int i=0; i<nbelems; i++) 
+//       nodemap.insert(make_pair(elems[2*i],elems[2*i+1]));
+
+//   else
+//     for (int i=0; i<nbelems; i++)
+//       nodemap.insert(make_pair(elems[2*i+1],elems[2*i]));
+
+//   int* ptr_elems=elems;      
+
+//   //filling the vector in appropriate order 
+//   for (map<int,int>::const_iterator iter=nodemap.begin(); iter!=nodemap.end(); iter++)
+//   {
+//     if (is_first)
+//     {
+//       *ptr_elems++=iter->first; 
+//       *ptr_elems++=iter->second;
+//     }
+//     else
+//     {
+//       *ptr_elems++=iter->second;
+//       *ptr_elems++=iter->first;
+//     }
+//   }    
+  
+
+//}
diff --git a/src/MEDPartitioner/MEDPARTITIONER_MESHCollectionDriver.hxx b/src/MEDPartitioner/MEDPARTITIONER_MESHCollectionDriver.hxx
new file mode 100644 (file)
index 0000000..e53765d
--- /dev/null
@@ -0,0 +1,86 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef MEDPARTITIONER_MESHCOLLECTIONDRIVER_HXX_
+#define MEDPARTITIONER_MESHCOLLECTIONDRIVER_HXX_
+
+#include "MEDPARTITIONER.hxx"
+
+namespace MEDPARTITIONER
+{
+  class MESHCollection;
+  class ParaDomainSelector;
+
+  class MEDPARTITIONER_EXPORT MESHCollectionDriver
+  {
+  public:
+
+    MESHCollectionDriver(MESHCollection*);
+    virtual ~MESHCollectionDriver(){}
+
+    virtual int read(char*, ParaDomainSelector* sel=0)=0;
+    int readSeq(char*,char*);
+
+    virtual void write(char*, ParaDomainSelector* sel=0)=0;
+//     virtual void readFields (vector <MEDMEM::FIELD<int> *>& filenames, char* fieldname,
+//                              int itnumber, int ordernumber) =0;
+//     virtual void readFields (vector <MEDMEM::FIELD<double> *>& filenames, char* fieldname,
+//                              int itnumber, int ordernumber) =0;
+//     virtual void writeFields(vector <MEDMEM::FIELD<int> *>& filenames, char* fieldname)=0;
+//     virtual void writeFields(vector <MEDMEM::FIELD<double> *>& filenames, char* fieldname)=0;
+
+//     void readFileStruct(vector <string>&  field_names,vector<int>& iternumber,vector <int>&  ordernumber,vector <int> & types);
+
+//     int getFieldType(const std::string& fieldname);
+//     //  void exportFamily(vector<int*>,MED_EN::medEntityMesh, const string& name);
+
+//     void readLoc2GlobCellConnect(int idomain, const set<int>& loc_domains, ParaDomainSelector* ds,
+//                                  vector<int> & loc2glob_corr);
+
+//    int readMeshDimension() const;
+
+  protected:
+
+    void readSubdomain(vector<int*>& cellglobal,
+                       vector<int*>& faceglobal,
+                       vector<int*>& nodeglobal, int idomain);
+    void writeSubdomain(int idomain,int nbdomain, char*filename,
+                        ParaDomainSelector* domain_selector);
+
+//     void writeElementJoint(medEntityMesh entity ,
+//                            int icz, 
+//                            int idomain, 
+//                            int idistant, 
+//                            char* mesh_name, 
+//                            char* joint_name,  
+//                            med_2_3::med_idt fid );
+//     void jointSort(int* elems, int nbelems, bool is_first);
+
+
+
+    MESHCollection* _collection;
+
+    std::vector <std::string> _filename;
+    std::vector <std::string> _meshname;
+
+  };
+
+}
+
+
+#endif /*MESHCOLLECTIONDRIVER_HXX_*/
diff --git a/src/MEDPartitioner/MEDPARTITIONER_MESHCollectionMedAsciiDriver.H b/src/MEDPartitioner/MEDPARTITIONER_MESHCollectionMedAsciiDriver.H
new file mode 100644 (file)
index 0000000..c253b58
--- /dev/null
@@ -0,0 +1,66 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef MEDSPLITTER_MESHCOLLECTIONMEDASCIIDRIVER_H
+#define MEDSPLITTER_MESHCOLLECTIONMEDASCIIDRIVER_H
+
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+/*!reads a distributed field
+ * 
+ * \param fields vector of fields (one field per subdomain)
+ * \param fieldname name of the field
+ * \param itnumber number of iteration
+ * \param ordernumber internal number inside the iteration
+ * */
+template <class T>
+void MESHCollectionMedAsciiDriver::_readFields(vector<MEDMEM::FIELD<T>* >& fields,char* fieldname, int itnumber, int ordernumber)
+{
+  for (int i=0; i<_collection->getMesh().size(); i++)
+  {
+    char filename[256];
+    strcpy(filename,_filename[i].c_str());
+    cout << "maillage : " << filename << " champ : " << fieldname << endl;
+    //    MEDMEM::FIELD<T>* field = new MEDMEM::FIELD<T>(MEDMEM::MED_DRIVER,filename,fieldname,itnumber,ordernumber);
+    fields.push_back (new MEDMEM::FIELD<T>(MEDMEM::MED_DRIVER,filename,fieldname,itnumber,ordernumber));
+  }
+}
+
+
+/*!writes a distributed field
+ * 
+ * \param fields vector of fields (one field per subdomain)
+ * \param fieldname name of the field
+ * */
+template <class T>
+void MESHCollectionMedAsciiDriver::_writeFields(vector<MEDMEM::FIELD<T>* >& fields,char* fieldname)
+{
+  for (int i=0; i<_collection->getMesh().size(); i++)
+  {
+    char filename[256];
+    strcpy(filename,_filename[i].c_str());
+    int driverid = fields[i]->addDriver(MEDMEM::MED_DRIVER, filename, fieldname);
+    fields[i]->write(driverid);    
+  }
+}
+
+#endif
diff --git a/src/MEDPartitioner/MEDPARTITIONER_MESHCollectionMedAsciiDriver.hxx b/src/MEDPartitioner/MEDPARTITIONER_MESHCollectionMedAsciiDriver.hxx
new file mode 100644 (file)
index 0000000..ba45f22
--- /dev/null
@@ -0,0 +1,76 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef MESHCOLLECTIONMEDASCIIDRIVER_HXX_
+#define MESHCOLLECTIONMEDASCIIDRIVER_HXX_
+
+#include "MEDPARTITIONER_MESHCollectionDriver.hxx"
+
+namespace MEDPARTITIONER
+{
+  class MESHCollection;
+
+  class MESHCollectionMedAsciiDriver:public MESHCollectionDriver
+  {
+  public:
+
+    MESHCollectionMedAsciiDriver(MESHCollection*);
+    virtual ~MESHCollectionMedAsciiDriver(){}
+
+    int read(char*, ParaDomainSelector* sel=0);
+
+    void write(char*, ParaDomainSelector* sel=0);
+
+//     void readFields(vector <MEDMEM::FIELD<int> *>& filenames, char* fieldname,
+//                     int itnumber, int ordernumber)
+//     {
+//       _readFields(filenames,fieldname,itnumber,ordernumber);
+//     }
+//     void readFields(vector <MEDMEM::FIELD<double> *>& filenames, char* fieldname,
+//                     int itnumber, int ordernumber)
+//     {
+//       _readFields(filenames,fieldname,itnumber,ordernumber);
+//     }
+
+//     void writeFields(vector <MEDMEM::FIELD<int> *>& filenames, char* fieldname)
+//     {
+//       _writeFields( filenames, fieldname);
+//     }
+
+//     void writeFields(vector <MEDMEM::FIELD<double> *>& filenames, char* fieldname)
+//     {
+//       _writeFields( filenames, fieldname);
+//     }
+
+
+  private :
+//     template <class T> void _readFields(vector <MEDMEM::FIELD<T> *>& filenames, char* fieldname,
+//                                         int itnumber, int ordernumber);
+
+//     template <class T>
+//     void _writeFields(vector <MEDMEM::FIELD<T> *>& filenames, char* fieldname);
+
+
+
+    std::string _master_filename;
+  };
+
+}
+
+
+#endif /*MESHCOLLECTIONDRIVER_HXX_*/
diff --git a/src/MEDPartitioner/MEDPARTITIONER_MESHCollectionMedXMLDriver.H b/src/MEDPartitioner/MEDPARTITIONER_MESHCollectionMedXMLDriver.H
new file mode 100644 (file)
index 0000000..5d8710b
--- /dev/null
@@ -0,0 +1,122 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef MEDSPLITTER_MESHCOLLECTIONMEDXMLDRIVER_H
+#define MEDSPLITTER_MESHCOLLECTIONMEDXMLDRIVER_H
+
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+
+
+/*!reads a distributed field
+ * 
+ * \param fields vector of fields (one field per subdomain)
+ * \param fieldname name of the field
+ * \param itnumber number of iteration
+ * \param ordernumber internal number inside the iteration
+ * */
+template <class T>
+void MESHCollectionMedXMLDriver::_readFields(vector<MEDMEM::FIELD<T>* >& fields,char* fieldname, int itnumber, int ordernumber)
+{
+  for (int i=0; i<_collection->getMesh().size(); i++)
+  {
+    char filename[256];
+    strcpy(filename,_filename[i].c_str());
+    cout << "maillage : " << filename << " champ : " << fieldname << endl;
+    //    MEDMEM::FIELD<T>* field = new MEDMEM::FIELD<T>(MEDMEM::MED_DRIVER,filename,fieldname,itnumber,ordernumber);
+    fields.push_back (new MEDMEM::FIELD<T>(MEDMEM::MED_DRIVER,filename,fieldname,itnumber,ordernumber));
+  }
+}
+
+
+/*!writes a distributed field
+ * 
+ * \param fields vector of fields (one field per subdomain)
+ * \param fieldname name of the field
+ * */
+template <class T>
+void MESHCollectionMedXMLDriver::_writeFields(vector<MEDMEM::FIELD<T>* >& fields,char* fieldname)
+{
+  xmlDocPtr master_doc=xmlParseFile(_master_filename.c_str());
+
+  if (!master_doc)    
+    throw MEDEXCEPTION("MEDSPLITTER writeFields - Master File does not exist");
+
+  //number of domains
+
+  xmlXPathContextPtr xpathCtx = xmlXPathNewContext(master_doc);
+  xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression(BAD_CAST "//mapping/mesh", xpathCtx);
+  //assuming there is only one mesh in the XML file
+  xmlNodePtr mesh_node= xpathObj->nodesetval->nodeTab[0];
+
+  //adds the field to the master file if necessary
+  bool exist_field =false;
+  xpathObj = xmlXPathEvalExpression(BAD_CAST "//mapping/mesh/field", xpathCtx);
+  //assuming there is only one mesh in the XML file
+  int field_nr =  xpathObj->nodesetval->nodeNr;
+  for (int i=0; i<field_nr; i++)
+  {
+    //field node has only one property
+    if ( strcmp((const char*)xpathObj->nodesetval->nodeTab[i]->properties->children->content, fieldname)==0)
+      exist_field = true;
+  }
+
+  xmlNodePtr field_node;
+  if (!exist_field)
+  {
+    field_node = xmlNewChild(mesh_node, 0, BAD_CAST "field",0);
+    xmlNewProp(field_node,BAD_CAST "name",BAD_CAST fieldname);
+  }
+
+
+  for (int i=0; i<_collection->getMesh().size(); i++)
+  {
+    char filename[256];
+    strcpy(filename,_filename[i].c_str());
+    int driverid = fields[i]->addDriver(MEDMEM::MED_DRIVER, filename, fieldname);
+    fields[i]->write(driverid);
+
+    //adds the partition to the master file if the field had not been 
+    //added already
+    if (!exist_field)
+    {
+      xmlNodePtr chunk_node= xmlNewChild(field_node,0,BAD_CAST "chunk",0);
+      char id[8];
+      sprintf(id,"%d",i+1);
+      xmlNewProp(chunk_node,BAD_CAST "subdomain",BAD_CAST id);
+      //xmlNewProp(chunk_node,BAD_CAST "name", BAD_CAST fieldname);
+      //xmlNodePtr fieldname_node=
+      xmlNewChild(chunk_node,0,BAD_CAST "name", BAD_CAST fieldname);
+    }
+  }
+  //Writing file
+  xmlKeepBlanksDefault(0);
+  xmlSaveFormatFileEnc(_master_filename.c_str(), master_doc, "UTF-8", 1);
+
+  //Clean up
+  xmlXPathFreeContext(xpathCtx); 
+  xmlFreeDoc(master_doc);
+  //xmlCleanupParser();
+
+}
+
+#endif
diff --git a/src/MEDPartitioner/MEDPARTITIONER_MESHCollectionMedXMLDriver.hxx b/src/MEDPartitioner/MEDPARTITIONER_MESHCollectionMedXMLDriver.hxx
new file mode 100644 (file)
index 0000000..a36b562
--- /dev/null
@@ -0,0 +1,76 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef MESHCOLLECTIONMEDXMLDRIVER_HXX_
+#define MESHCOLLECTIONMEDXMLDRIVER_HXX_
+
+#include "MEDPARTITIONER_MESHCollectionDriver.hxx"
+
+namespace MEDPARTITIONER
+{
+  class MESHCollection;
+
+  class MESHCollectionMedXMLDriver:public MESHCollectionDriver
+  {
+  public:
+
+    MESHCollectionMedXMLDriver(MESHCollection*);
+    virtual ~MESHCollectionMedXMLDriver(){}
+
+
+    int read(char*, ParaDomainSelector* sel=0);
+
+    void write(char*, ParaDomainSelector* sel=0);
+
+//     void readFields(vector <MEDMEM::FIELD<int> *>& filenames, char* fieldname,
+//                     int itnumber, int ordernumber)
+//     {
+//       _readFields(filenames,fieldname,itnumber,ordernumber);
+//     }
+//     void readFields(vector <MEDMEM::FIELD<double> *>& filenames, char* fieldname,
+//                     int itnumber, int ordernumber)
+//     {
+//       _readFields(filenames,fieldname,itnumber,ordernumber);
+//     }
+
+//     void writeFields(vector <MEDMEM::FIELD<double> *>& filenames, char* fieldname)
+//     {
+//       _writeFields( filenames, fieldname);
+//     }
+//     void writeFields(vector <MEDMEM::FIELD<int> *>& filenames, char* fieldname)
+//     {
+//       _writeFields( filenames, fieldname);
+//     }
+
+
+
+  private :
+
+ //    template <class T> void _readFields(vector <MEDMEM::FIELD<T> *>& filenames, char* fieldname,
+//                                         int itnumber, int ordernumber);
+
+//     template <class T>
+//     void _writeFields(vector <MEDMEM::FIELD<T> *>& filenames, char* fieldname);
+
+    std::string _master_filename;
+  };
+
+}
+
+
+#endif /*MESHCOLLECTIONDRIVER_HXX_*/
diff --git a/src/MEDPartitioner/MEDPARTITIONER_METISGraph.cxx b/src/MEDPartitioner/MEDPARTITIONER_METISGraph.cxx
new file mode 100644 (file)
index 0000000..2c86aac
--- /dev/null
@@ -0,0 +1,120 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifdef ENABLE_PARMETIS
+#include <parmetis.h>
+#endif
+extern "C" {
+#include <metis.h>
+}
+#include "MEDPARTITIONER_METISGraph.hxx"
+#include "MEDPARTITIONER_ParaDomainSelector.hxx"
+#include "MEDMEM_Exception.hxx"
+using namespace MEDPARTITIONER;
+
+METISGraph::METISGraph():Graph()
+{
+}
+
+METISGraph::METISGraph(MEDPARTITIONER::MEDSKYLINEARRAY* graph, int* edgeweight)
+  :Graph(graph,edgeweight)
+{
+}
+
+METISGraph::~METISGraph()
+{
+}
+
+void METISGraph::partGraph(int                 ndomain,
+                           const std::string&       options_string,
+                           ParaDomainSelector* parallelizer)
+{
+  // number of graph vertices
+  int n = m_graph->getNumberOf();
+
+  //graph
+  int * xadj=const_cast<int*>(m_graph->getIndex());
+  int * adjncy = const_cast<int*>(m_graph->getValue());
+  //constraints
+  int * vwgt=m_cellweight;
+  int * adjwgt=m_edgeweight;
+  int wgtflag=(m_edgeweight!=0)?1:0+(m_cellweight!=0)?2:0;
+
+  //base 0 or 1
+  int base=0;
+
+  //ndomain
+  int nparts = ndomain;
+
+  //options
+  int options[5]={0,0,0,0,0};
+
+  // output parameters
+  int edgecut;
+  int* partition = new int[n];
+
+  if (nparts >1)
+  {
+    if ( parallelizer )
+    {
+#ifdef ENABLE_PARMETIS
+      // distribution of vertices of the graph among the processors
+      int * vtxdist = parallelizer ? parallelizer->getNbVertOfProcs() : 0;
+      MPI_Comm comm = MPI_COMM_WORLD;
+
+      ParMETIS_PartKway( vtxdist, xadj, adjncy, vwgt, adjwgt, &wgtflag,
+                         &base, &nparts, options, &edgecut, partition, &comm );
+#else
+      throw MEDMEM::MEDEXCEPTION("ParMETIS is not available. Check your products, please.");
+#endif
+    }
+    else
+    {
+    
+      if (options_string != "k")
+        METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
+                                 &base, &nparts, options, &edgecut, partition);
+      else
+        METIS_PartGraphKway(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
+                            &base, &nparts, options, &edgecut, partition);
+    }
+  }
+  else
+  {
+    for (int i=0; i<n; i++)
+      partition[i]=0;
+  }
+  std::vector<int> index(n+1);
+  std::vector<int> value(n);
+  index[0]=0;
+  for (int i=0; i<n; i++)
+  {
+    index[i+1]=index[i]+1;
+    value[i]=partition[i];
+  }
+
+  delete[]partition;
+
+  //creating a skylinearray with no copy of the index and partition array
+  // the fifth argument true specifies that only the pointers are passed 
+  //to the object
+  
+  m_partition = new MEDPARTITIONER::MEDSKYLINEARRAY(index,value);
+}
+
diff --git a/src/MEDPartitioner/MEDPARTITIONER_METISGraph.hxx b/src/MEDPartitioner/MEDPARTITIONER_METISGraph.hxx
new file mode 100644 (file)
index 0000000..0a96964
--- /dev/null
@@ -0,0 +1,37 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef METISGRAPH_HXX_
+#define METISGRAPH_HXX_
+
+#include "MEDPARTITIONER_Graph.hxx"
+#include <string>
+namespace MEDPARTITIONER {
+  class MEDSKYLINEARRAY;
+  class MEDPARTITIONER_EXPORT METISGraph:public Graph
+  {
+  public:
+    METISGraph();
+    METISGraph(MEDPARTITIONER::MEDSKYLINEARRAY*, int* edgeweight=0);
+    virtual ~METISGraph();
+    void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector* sel=0);
+    //private:
+    //  const MEDMEM::MEDSKYLINEARRAY* m_graph;
+  };
+}
+#endif /*METISGRAPH_HXX_*/
diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx b/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx
new file mode 100644 (file)
index 0000000..1c0a660
--- /dev/null
@@ -0,0 +1,667 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File      : MEDSPLITTER_ParaDomainSelector.cxx
+// Created   : Wed Jun 24 12:39:59 2009
+// Author    : Edward AGAPOV (eap)
+
+#include "MEDCouplingUMesh.hxx"
+#include "MEDMEM_Exception.hxx"
+#include "MEDPARTITIONER_ParaDomainSelector.hxx"
+
+#include "MEDPARTITIONER_UserGraph.hxx"
+#include "MEDPARTITIONER_JointExchangeData.hxx"
+
+//#include <MEDMEM_Meshing.hxx>
+#include <MEDMEM_DriversDef.hxx>
+
+#include <iostream>
+#include <numeric>
+
+#ifdef HAVE_MPI2
+#include <mpi.h>
+#endif
+
+#ifndef WIN32
+#include <sys/sysinfo.h>
+#endif
+
+using namespace MEDPARTITIONER;
+using namespace MED_EN;
+using namespace std;
+
+//================================================================================
+/*!
+ * \brief Constructor. Find out my rank and world size
+ */
+//================================================================================
+
+ParaDomainSelector::ParaDomainSelector(bool mesure_memory)
+  :_rank(0),_world_size(1), _nb_result_domains(-1), _mesure_memory(mesure_memory),
+   _init_time(0.0), _init_memory(0), _max_memory(0)
+{
+#ifdef HAVE_MPI2
+  MPI_Comm_size(MPI_COMM_WORLD,&_world_size) ;
+  MPI_Comm_rank(MPI_COMM_WORLD,&_rank) ;
+  _init_time = MPI_Wtime();
+#endif
+  evaluateMemory();
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+ParaDomainSelector::~ParaDomainSelector()
+{
+}
+
+//================================================================================
+/*!
+ * \brief Return true if is running on different hosts
+ */
+//================================================================================
+
+bool ParaDomainSelector::isOnDifferentHosts() const
+{
+  evaluateMemory();
+  if ( _world_size < 2 )
+    return false;
+
+#ifdef HAVE_MPI2
+  char name_here[ MPI_MAX_PROCESSOR_NAME+1 ], name_there[ MPI_MAX_PROCESSOR_NAME+1 ];
+  int size;
+  MPI_Get_processor_name( name_here, &size);
+
+  int next_proc = (rank() + 1) % nbProcs();
+  int prev_proc = (rank() - 1 + nbProcs()) % nbProcs();
+  int tag  = 1111111;
+
+  MPI_Status status;
+  MPI_Sendrecv((void*)&name_here[0],  MPI_MAX_PROCESSOR_NAME, MPI_CHAR, next_proc, tag,
+               (void*)&name_there[0], MPI_MAX_PROCESSOR_NAME, MPI_CHAR, prev_proc, tag,
+               MPI_COMM_WORLD, &status);
+  return string(name_here) != string(name_there);
+#endif
+}
+
+//================================================================================
+/*!
+ * \brief Return true if the domain with domainIndex is to be loaded on this proc
+ *  \param domainIndex - index of mesh domain
+ *  \retval bool - to load or not
+ */
+//================================================================================
+
+bool ParaDomainSelector::isMyDomain(int domainIndex) const
+{
+  evaluateMemory();
+  return (_rank == getProccessorID( domainIndex ));
+}
+
+//================================================================================
+/*!
+ * \brief Return processor id where the domain with domainIndex resides
+ *  \param domainIndex - index of mesh domain
+ *  \retval int - processor id
+ */
+//================================================================================
+
+int ParaDomainSelector::getProccessorID(int domainIndex) const
+{
+  evaluateMemory();
+  return ( domainIndex % _world_size );
+}
+
+//================================================================================
+/*!
+ * \brief Gather info on nb of entities on each processor and return total nb.
+ *
+ * Is called
+ * 1) for MED_CELL to know global id shift for domains at graph construction;
+ * 2) for sub-entity to know total nb of sub-entities before creating those of joints
+ */
+//================================================================================
+
+int ParaDomainSelector::gatherNbOf(
+                                   //MED_EN::medEntityMesh        entity,
+                                   const vector<ParaMEDMEM::MEDCouplingUMesh*>& domain_meshes)
+{
+  evaluateMemory();
+
+  // get nb of elems of each domain mesh
+  int nb_domains = domain_meshes.size();
+  vector<int> nb_elems( nb_domains, 0 );
+  for ( int i = 0; i < nb_domains; ++i )
+    if ( domain_meshes[i] )
+      nb_elems[i] = domain_meshes[i]->getNumberOfCells();
+
+  // receive nb of elems from other procs
+  vector<int> all_nb_elems( nb_domains );
+#ifdef HAVE_MPI2
+  MPI_Allreduce((void*)&nb_elems[0], (void*)&all_nb_elems[0], nb_domains,
+                MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+#endif
+  int total_nb = std::accumulate( all_nb_elems.begin(), all_nb_elems.end(), 0 );
+
+  vector<int>& elem_shift_by_domain  = _cell_shift_by_domain;
+
+  // fill elem_shift_by_domain
+
+  vector< int > ordered_nbs, domain_order( nb_domains );
+  ordered_nbs.push_back(0);
+  for ( int iproc = 0; iproc < nbProcs(); ++iproc )
+    for ( int idomain = 0; idomain < nb_domains; ++idomain )
+      if ( getProccessorID( idomain ) == iproc )
+      {
+        domain_order[ idomain ] = ordered_nbs.size() - 1;
+        ordered_nbs.push_back( ordered_nbs.back() + all_nb_elems[idomain] );
+      }
+  elem_shift_by_domain.resize( nb_domains+1, 0 );
+  for ( int idomain = 0; idomain < nb_domains; ++idomain )
+    elem_shift_by_domain[ idomain ] = ordered_nbs[ domain_order[ idomain ]];
+
+  elem_shift_by_domain.back() = ordered_nbs.back(); // to know total nb of elements
+
+  //  if ( entity == MED_CELL )
+  {
+    // fill _nb_vert_of_procs
+    _nb_vert_of_procs.resize( _world_size+1, 0 );
+    for ( int i = 0; i < nb_domains; ++i )
+    {
+      int rank = getProccessorID( i );
+      _nb_vert_of_procs[ rank+1 ] += all_nb_elems[ i ];
+    }
+    _nb_vert_of_procs[0] = 1; // base = 1
+    for ( int i = 1; i < _nb_vert_of_procs.size(); ++i )
+      _nb_vert_of_procs[ i ] += _nb_vert_of_procs[ i-1 ]; // to CSR format
+  }
+//   else
+//   {
+//     // to compute global ids of faces in joints
+//     //_total_nb_faces = total_nb;
+//   }
+
+//   if ( !_rank) {
+//     MEDMEM::STRING out("_nb_vert_of_procs :");
+//     for ( int i = 0; i < _nb_vert_of_procs.size(); ++i )
+//       out << _nb_vert_of_procs[i] << " ";
+//     std::cout << out << std::endl;
+//   }
+//   if ( !_rank) {
+//     MEDMEM::STRING out("elem_shift_by_domain :");
+//     for ( int i = 0; i < elem_shift_by_domain.size(); ++i )
+//       out << elem_shift_by_domain[i] << " ";
+//     std::cout << out << std::endl;
+//   }
+
+  evaluateMemory();
+
+  return total_nb;
+}
+
+//================================================================================
+/*!
+ * \brief Return distribution of the graph vertices among the processors
+ *  \retval int* - array conatining nb of vertices on all processors
+ *
+ * gatherNbOf( MED_CELL ) must be called before.
+ * The result array is to be used as the first arg of ParMETIS_V3_PartKway() and
+ * is freed by ParaDomainSelector.
+ */
+//================================================================================
+
+#define gatherNbOf_NOT_CALLED(meth) throw MED_EXCEPTION \
+("ParaDomainSelector::" #meth "(): gatherNbOf( MED_CELL ) must be called before")
+
+int* ParaDomainSelector::getNbVertOfProcs() const
+{
+  evaluateMemory();
+  if ( _nb_vert_of_procs.empty() )
+    gatherNbOf_NOT_CALLED(getNbVertOfProcs);
+
+  return (int*) & _nb_vert_of_procs[0];
+}
+//================================================================================
+/*!
+ * \brief Return nb of cells in domains with lower index.
+ *
+ * gatherNbOf( MED_CELL ) must be called before.
+ * Result added to local id on given domain gives id in the whole distributed mesh
+ */
+//================================================================================
+
+int ParaDomainSelector::getDomainShift(int domainIndex) const
+{
+  evaluateMemory();
+  if ( _cell_shift_by_domain.empty() )
+    gatherNbOf_NOT_CALLED(getDomainShift);
+
+  return _cell_shift_by_domain[ domainIndex ];
+}
+
+//================================================================================
+/*!
+ * \brief Return nb of cells on processors with lower rank.
+ *
+ * gatherNbOf( MED_CELL ) must be called before.
+ * Result added to global id on this processor gives id in the whole distributed mesh
+ */
+//================================================================================
+
+int ParaDomainSelector::getProcShift() const
+{
+  evaluateMemory();
+  if ( _nb_vert_of_procs.empty() )
+    gatherNbOf_NOT_CALLED(getProcShift);
+
+  return _nb_vert_of_procs[_rank]-1;
+}
+
+//================================================================================
+/*!
+ * \brief Gather graphs from all processors into one
+ */
+//================================================================================
+
+auto_ptr<Graph> ParaDomainSelector::gatherGraph(const Graph* graph) const
+{
+  Graph* glob_graph = 0;
+
+  evaluateMemory();
+#ifdef HAVE_MPI2
+
+  // ---------------
+  // Gather indices
+  // ---------------
+
+  vector<int> index_size_of_proc( nbProcs() ); // index sizes - 1
+  for ( int i = 1; i < _nb_vert_of_procs.size(); ++i )
+    index_size_of_proc[i-1] = _nb_vert_of_procs[ i ] - _nb_vert_of_procs[ i-1 ];
+
+  int index_size = 1 + _cell_shift_by_domain.back();
+  int* graph_index = new int[ index_size ];
+  const int* index = graph->getGraph()->getIndex();
+  int* proc_index_displacement = (int*) & _nb_vert_of_procs[0];
+
+  MPI_Allgatherv((void*) (index+1),         // send local index except first 0 (or 1)
+                 index_size_of_proc[_rank], // index size on this proc
+                 MPI_INT,
+                 (void*) graph_index,       // receive indices
+                 & index_size_of_proc[0],   // index size on each proc
+                 proc_index_displacement,   // displacement of each proc index
+                 MPI_INT,
+                 MPI_COMM_WORLD);
+  graph_index[0] = index[0]; // it is not overwritten thanks to proc_index_displacement[0]==1
+
+  // get sizes of graph values on each proc by the got indices of graphs
+  vector< int > value_size_of_proc( nbProcs() ), proc_value_displacement(1,0);
+  for ( int i = 0; i < nbProcs(); ++i )
+  {
+    if ( index_size_of_proc[i] > 0 )
+      value_size_of_proc[i] = graph_index[ proc_index_displacement[ i+1 ]-1 ] - graph_index[0];
+    else
+      value_size_of_proc[i] = 0;
+    proc_value_displacement.push_back( proc_value_displacement.back() + value_size_of_proc[i] );
+  }
+  
+  // update graph_index
+  for ( int i = 1; i < nbProcs(); ++i )
+  {
+    int shift = graph_index[ proc_index_displacement[i]-1 ]-graph_index[0];
+    for ( int j = proc_index_displacement[i]; j < proc_index_displacement[i+1]; ++j )
+      graph_index[ j ] += shift;
+  }
+  
+  // --------------
+  // Gather values
+  // --------------
+
+  int value_size = graph_index[ index_size-1 ] - graph_index[ 0 ];
+  int* graph_value = new int[ value_size ];
+  const int* value = graph->getGraph()->getValue();
+
+  MPI_Allgatherv((void*) value,                // send local value
+                 value_size_of_proc[_rank],    // value size on this proc
+                 MPI_INT,
+                 (void*) graph_value,          // receive values
+                 & value_size_of_proc[0],      // value size on each proc
+                 & proc_value_displacement[0], // displacement of each proc value
+                 MPI_INT,
+                 MPI_COMM_WORLD);
+
+  // -----------------
+  // Gather partition
+  // -----------------
+
+  int * partition = new int[ _cell_shift_by_domain.back() ];
+  const int* part = graph->getPart();
+  
+  MPI_Allgatherv((void*) part,              // send local partition
+                 index_size_of_proc[_rank], // index size on this proc
+                 MPI_INT,
+                 (void*)(partition-1),      // -1 compensates proc_index_displacement[0]==1
+                 & index_size_of_proc[0],   // index size on each proc
+                 proc_index_displacement,   // displacement of each proc index
+                 MPI_INT,
+                 MPI_COMM_WORLD);
+
+  // -----------
+  // Make graph
+  // -----------
+
+  MEDMEM::MEDSKYLINEARRAY* array =
+    new MEDMEM::MEDSKYLINEARRAY( index_size-1, value_size, graph_index, graph_value, true );
+
+  glob_graph = new UserGraph( array, partition, index_size-1 );
+
+  evaluateMemory();
+
+  delete [] partition;
+
+#endif // HAVE_MPI2
+
+  return auto_ptr<Graph>( glob_graph );
+}
+
+//================================================================================
+/*!
+ * \brief Sets global numbering for the entity.
+ *
+ * This method must be once called for MED_CELL before exchangeJoint() calls
+ */
+//================================================================================
+
+// void ParaDomainSelector::gatherEntityTypesInfo(vector<ParaMEDMEM::MEDCouplingUMesh*>& domain_meshes,
+//                                                MED_EN::medEntityMesh  entity)
+// {
+//   const list<medGeometryElement> & all_types = meshEntities[ entity ];
+
+//   evaluateMemory();
+
+//   // Put nb of elements of the entity of all domains in one vector
+//   // and by the way find out mesh dimension
+
+//   vector<int> nb_of_type( domain_meshes.size() * all_types.size(), 0 );
+//   int mesh_dim = -1, space_dim = -1;
+
+//   for ( int idomain = 0; idomain < domain_meshes.size(); ++idomain )
+//   {
+//     if ( !isMyDomain(idomain)) continue;
+
+//     int* domain_nbs = & nb_of_type[ idomain * all_types.size()];
+
+//     list<medGeometryElement>::const_iterator type = all_types.begin();
+//     for ( int t = 0; type != all_types.end(); ++t,++type )
+//       domain_nbs[t] = domain_meshes[idomain]->getNumberOfCells();
+
+//     int i_mesh_dim = domain_meshes[idomain]->getMeshDimension();
+//     int i_space_dim = domain_meshes[idomain]->getSpaceDimension();
+//     if ( mesh_dim < i_mesh_dim && i_mesh_dim <= 3 )
+//       mesh_dim = i_mesh_dim;
+//     if ( space_dim < i_space_dim && i_space_dim <= 3 )
+//       space_dim = i_space_dim;
+//   }
+
+//   // Receive nbs from other procs
+
+//   vector< int > nb_recv( nb_of_type.size() );
+// #ifdef HAVE_MPI2
+//   MPI_Allreduce((void*)&nb_of_type[0], (void*)&nb_recv[0], nb_of_type.size(),
+//                 MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+// #endif
+
+//   // Set info to meshes of distant domains
+
+//   for ( int idomain = 0; idomain < domain_meshes.size(); ++idomain )
+//   {
+//     if ( isMyDomain(idomain)) continue;
+
+//     MEDMEM::MESHING* meshing = (MEDMEM::MESHING*) domain_meshes[idomain];
+//     if ( meshing->getMeshDimension() < mesh_dim )
+//     {
+//       meshing->setMeshDimension( mesh_dim );
+//       meshing->setSpaceDimension( space_dim );
+//     }
+
+//     vector< medGeometryElement > types;
+//     vector< int >                nb_elems;
+
+//     int* domain_nbs = & nb_recv[ idomain * all_types.size()];
+
+//     list<medGeometryElement>::const_iterator type = all_types.begin();
+//     for ( int t = 0; type != all_types.end(); ++t,++type )
+//     {
+//       if ( domain_nbs[t]==0 ) continue;
+//       types.push_back( *type );
+//       nb_elems.push_back( domain_nbs[t] );
+//     }
+//     meshing->setNumberOfTypes( types.size(), entity );
+//     if ( !types.empty() )
+//     {
+//       meshing->setTypes           ( & types[0], entity );
+//       meshing->setNumberOfElements( & nb_elems[0], entity );
+//     }
+//   }
+//   evaluateMemory();
+// }
+
+//================================================================================
+/*!
+ * \brief Set nb of cell/cell pairs in a joint between domains
+ */
+//================================================================================
+
+void ParaDomainSelector::setNbCellPairs( int nb_cell_pairs, int dist_domain, int loc_domain )
+{
+  // This method is needed for further computing global numbers of faces in joint.
+  // Store if both domains are on this proc else on one of procs only
+  if ( isMyDomain( dist_domain ) || dist_domain < loc_domain )
+  {
+    if ( _nb_cell_pairs_by_joint.empty() )
+      _nb_cell_pairs_by_joint.resize( _nb_result_domains*(_nb_result_domains+1), 0);
+
+    int joint_id = jointId( loc_domain, dist_domain );
+    _nb_cell_pairs_by_joint[ joint_id ] = nb_cell_pairs;
+  }
+  evaluateMemory();
+}
+
+//================================================================================
+/*!
+ * \brief Return nb of cell/cell pairs in a joint between domains on different procs
+ */
+//================================================================================
+
+int ParaDomainSelector::getNbCellPairs( int dist_domain, int loc_domain ) const
+{
+  evaluateMemory();
+
+  int joint_id = jointId( loc_domain, dist_domain );
+  return _nb_cell_pairs_by_joint[ joint_id ];
+}
+
+//================================================================================
+/*!
+ * \brief Gather size of each joint
+ */
+//================================================================================
+
+void ParaDomainSelector::gatherNbCellPairs()
+{
+  const char* LOC = "MEDPARTITIONER::ParaDomainSelector::gatherNbCellPairs(): ";
+  if ( _nb_cell_pairs_by_joint.empty() )
+    _nb_cell_pairs_by_joint.resize( _nb_result_domains*(_nb_result_domains+1), 0);
+  evaluateMemory();
+
+  vector< int > send_buf = _nb_cell_pairs_by_joint;
+#ifdef HAVE_MPI2
+  MPI_Allreduce((void*)&send_buf[0],
+                (void*)&_nb_cell_pairs_by_joint[0],
+                _nb_cell_pairs_by_joint.size(),
+                MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+#endif
+  // check that the set nbs of cell pairs are correct,
+  // namely that each joint is treated on one proc only
+  for ( int j = 0; j < _nb_cell_pairs_by_joint.size(); ++j )
+    if ( _nb_cell_pairs_by_joint[j] != send_buf[j] && send_buf[j]>0 )
+      throw MED_EXCEPTION("invalid nb of cell pairs");
+}
+
+//================================================================================
+/*!
+ * \brief Send-receive joint data
+ */
+//================================================================================
+
+// void ParaDomainSelector::exchangeJoint( JointExchangeData* joint ) const
+// {
+//   vector<int> send_data, recv_data( joint->serialize( send_data ));
+
+//   int dest = getProccessorID( joint->distantDomain() );
+//   int tag  = 1001 + jointId( joint->localDomain(), joint->distantDomain() );
+  
+// #ifdef HAVE_MPI2
+//   MPI_Status status;
+//   MPI_Sendrecv((void*)&send_data[0], send_data.size(), MPI_INT, dest, tag,
+//                (void*)&recv_data[0], recv_data.size(), MPI_INT, dest, tag,
+//                MPI_COMM_WORLD, &status);  
+// #endif
+
+//   joint->deserialize( recv_data );
+// }
+
+//================================================================================
+/*!
+ * \brief Return the first global id of sub-entity for the joint
+ */
+//================================================================================
+
+int ParaDomainSelector::getFisrtGlobalIdOfSubentity( int loc_domain, int dist_domain ) const
+{
+  // total_nb_faces includes faces existing before creation of joint faces
+  // (got in gatherNbOf( MED_FACE )).
+  evaluateMemory();
+
+  int total_nb_faces = _face_shift_by_domain.empty() ? 0 : _face_shift_by_domain.back();
+  int id = total_nb_faces + 1;
+
+  if ( _nb_cell_pairs_by_joint.empty() )
+    throw MED_EXCEPTION("MEDPARTITIONER::ParaDomainSelector::getFisrtGlobalIdOfSubentity(), "
+                        "gatherNbCellPairs() must be called before");
+  int joint_id = jointId( loc_domain, dist_domain );
+  for ( int j = 0; j < joint_id; ++j )
+    id += _nb_cell_pairs_by_joint[ j ];
+
+  return id;
+}
+
+//================================================================================
+/*!
+ * \brief Send-receive local ids of joint faces
+ */
+//================================================================================
+
+int* ParaDomainSelector::exchangeSubentityIds( int loc_domain, int dist_domain,
+                                               const vector<int>& loc_ids_here ) const
+{
+  int* loc_ids_dist = new int[ loc_ids_here.size()];
+  int dest = getProccessorID( dist_domain );
+  int tag  = 2002 + jointId( loc_domain, dist_domain );
+#ifdef HAVE_MPI2
+  MPI_Status status;
+  MPI_Sendrecv((void*)&loc_ids_here[0], loc_ids_here.size(), MPI_INT, dest, tag,
+               (void*) loc_ids_dist,    loc_ids_here.size(), MPI_INT, dest, tag,
+               MPI_COMM_WORLD, &status);  
+#endif
+  evaluateMemory();
+
+  return loc_ids_dist;
+}
+
+//================================================================================
+/*!
+ * \brief Return identifier for a joint
+ */
+//================================================================================
+
+int ParaDomainSelector::jointId( int local_domain, int distant_domain ) const
+{
+  evaluateMemory();
+  if (_nb_result_domains < 0)
+    throw MED_EXCEPTION("ParaDomainSelector::jointId(): setNbDomains() must be called before()");
+
+  if ( local_domain < distant_domain )
+    swap( local_domain, distant_domain );
+  return local_domain * _nb_result_domains + distant_domain;
+}
+
+//================================================================================
+/*!
+ * \brief Return domain order so that first go domains on proc 0 and so n
+ */
+//================================================================================
+
+// int ParaDomainSelector::getDomianOrder(int idomain, int nb_domains) const
+// {
+//   return nb_domains / nbProcs() * getProccessorID( idomain ) + idomain / nbProcs();
+// }
+
+//================================================================================
+/*!
+ * \brief Return time passed from construction in seconds
+ */
+//================================================================================
+
+double ParaDomainSelector::getPassedTime() const
+{
+#ifdef HAVE_MPI2
+  return MPI_Wtime() - _init_time;
+#else
+  return 0.0;
+#endif
+}
+
+//================================================================================
+/*!
+ * \brief Evaluate current memory usage and return the maximal one in KB
+ */
+//================================================================================
+
+int ParaDomainSelector::evaluateMemory() const
+{
+  if ( _mesure_memory )
+  {
+    int used_memory = 0;
+#ifndef WIN32
+    struct sysinfo si;
+    int err = sysinfo( &si );
+    if ( !err )
+      used_memory =
+        (( si.totalram - si.freeram + si.totalswap - si.freeswap ) * si.mem_unit ) / 1024;
+#endif
+    if ( used_memory > _max_memory )
+      ((ParaDomainSelector*) this)->_max_memory = used_memory;
+
+    if ( !_init_memory )
+      ((ParaDomainSelector*) this)->_init_memory = used_memory;
+  }
+  return _max_memory - _init_memory;
+}
diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.hxx b/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.hxx
new file mode 100644 (file)
index 0000000..ee502b4
--- /dev/null
@@ -0,0 +1,151 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File      : MEDPARTITIONER_ParaDomainSelector.hxx
+// Created   : Wed Jun 24 12:18:58 2009
+// Author    : Edward AGAPOV (eap)
+
+
+#ifndef __MEDPARTITIONER_ParaDomainSelector_HXX__
+#define __MEDPARTITIONER_ParaDomainSelector_HXX__
+
+#include "MEDPARTITIONER.hxx"
+
+#include <MEDMEM_define.hxx>
+
+#include <memory>
+#include <vector>
+
+namespace ParaMEDMEM
+{
+  class MEDCouplingUMesh;
+}
+
+
+namespace MEDPARTITIONER
+{
+  class Graph;
+  class JointExchangeData;
+
+/*!
+ * \brief Communication helper in parallel mode
+ */
+class MEDPARTITIONER_EXPORT ParaDomainSelector
+{
+public:
+
+  ParaDomainSelector(bool mesure_memory=false);
+  ~ParaDomainSelector();
+
+  //!< return processor rank
+  int rank() const { return _rank; }
+
+  //!< return number of processors
+  int nbProcs() const { return _world_size; }
+
+  // Return true if is running on different hosts
+  bool isOnDifferentHosts() const;
+
+  // Return true if the domain with domainIndex is to be loaded on this proc
+  bool isMyDomain(int domainIndex) const;
+
+  // Return processor id where the domain with domainIndex resides
+  int getProccessorID(int domainIndex) const;
+
+
+  //!< Set nb of required domains. (Used to sort joints via jointId())
+  void setNbDomains(int nb) { _nb_result_domains = nb; }
+
+  // Return identifier for a joint
+  int jointId( int local_domain, int distant_domain ) const;
+
+  // Return domain order
+  //int getDomianOrder(int domainIndex, int nb_domains) const;
+
+
+  // Collect nb of entities on procs and return total nb
+  int gatherNbOf(
+                 //MED_EN::medEntityMesh entity, 
+const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& domain_meshes);
+
+  // Return distribution of the graph vertices among the processors
+  int* getNbVertOfProcs() const;
+
+  // Return nb of cells on processors with lower rank
+  int getProcShift() const;
+
+  // Return nb of cells in domains with lower index
+  int getDomainShift(int domainIndex) const;
+
+//   // Return nb of sub-entities in domains with lower index
+//   int getDomainSubentityShift(int domainIndex) const;
+
+  // Gather graphs from all processors into one
+  std::auto_ptr<Graph> gatherGraph(const Graph* graph) const;
+
+  // Set types and number of elements of the entity to all meshes
+//   void gatherEntityTypesInfo(std::vector<ParaMEDMEM::MEDCouplingUMesh*>& domain_meshes,
+//                              MED_EN::medEntityMesh       entity);
+
+  // Set nb of cell/cell pairs in a joint between domains
+  void setNbCellPairs( int nb_cell_pairs, int dist_domain, int loc_domain );
+
+  // Gather size of each proc/proc joint
+  void gatherNbCellPairs();
+
+  // Return nb of cell/cell pairs in a joint between domains on different procs
+  int getNbCellPairs( int dist_domain, int loc_domain ) const;
+
+  // Send-receive joint data
+  //  void exchangeJoint( JointExchangeData* joint ) const;
+
+  // Return the first global id of sub-entity for the joint
+  int getFisrtGlobalIdOfSubentity( int loc_domain, int dist_domain ) const;
+
+  // Send-receive local ids of joint faces
+  int* exchangeSubentityIds( int loc_domain, int dist_domain,
+                             const std::vector<int>& loc_ids_here ) const;
+
+  // Return time passed from construction in seconds
+  double getPassedTime() const;
+
+  // Evaluate current memory usage and return the maximal one in KB
+  int evaluateMemory() const;
+
+private:
+
+  int _rank, _world_size; // my rank and nb of processors
+
+  int _nb_result_domains; // required nb of domains
+
+  //int _total_nb_faces; // nb of faces in the whole mesh without proc/proc joint faces
+
+  std::vector< int > _nb_cell_pairs_by_joint;
+
+  std::vector< int > _nb_vert_of_procs; // graph vertices
+  std::vector< int > _cell_shift_by_domain;
+  std::vector< int > _face_shift_by_domain;
+
+  double _init_time;
+  bool   _mesure_memory;
+  int    _init_memory, _max_memory;
+};
+
+}
+
+#endif
diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx b/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx
new file mode 100644 (file)
index 0000000..1735e3a
--- /dev/null
@@ -0,0 +1,1250 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include <set>
+#include <map>
+#include <vector>
+#ifndef WNT
+# include <ext/hash_map>
+#else
+# include <hash_map>
+#endif
+
+#include "MEDPARTITIONER_MESHCollection.hxx"
+#include "MEDPARTITIONER_Topology.hxx"
+#include "MEDPARTITIONER_Graph.hxx"
+#include "MEDPARTITIONER_ParallelTopology.hxx"
+#include "MEDPARTITIONER_ConnectZone.hxx"
+
+#include "MEDCouplingUMesh.hxx"
+#include "MEDMEM_Exception.hxx"
+#include "MEDMEM_Utilities.hxx"
+
+#ifndef WNT
+using namespace __gnu_cxx;
+#else
+using namespace std;
+#endif
+
+using namespace MEDPARTITIONER;
+
+//empty constructor
+ParallelTopology::ParallelTopology():m_nb_domain(0),m_mesh_dimension(0)
+{}
+
+//!constructing topology according to mesh collection
+ParallelTopology::ParallelTopology(const vector<ParaMEDMEM::MEDCouplingUMesh*>& meshes, 
+                                                                                                                                        const vector<MEDPARTITIONER::CONNECTZONE*>& cz,
+                                   vector<int*>& cellglobal,
+                                   vector<int*>& nodeglobal,
+                                   vector<int*>& faceglobal):m_nb_domain(meshes.size())/*,m_mesh_dimension(meshes[0]->getMeshDimension())*/
+{
+
+  int index_global=0;
+  int index_node_global=0;
+  int index_face_global=0;
+
+  m_nb_cells.resize(m_nb_domain);
+  m_nb_nodes.resize(m_nb_domain);
+       //  m_nb_faces.resize(m_nb_domain);
+
+  m_loc_to_glob.resize(m_nb_domain);
+  m_node_loc_to_glob.resize(m_nb_domain);
+       //  m_face_loc_to_glob.resize(m_nb_domain);
+
+  //MED_EN::medEntityMesh constituent_entity;
+
+  bool parallel_mode = false;
+  for (int idomain=0; !parallel_mode && idomain<m_nb_domain; idomain++)
+    parallel_mode = (!meshes[idomain]);
+
+  for (int idomain=0; idomain<m_nb_domain; idomain++)
+  {
+    if ( !meshes[idomain] )
+      continue;
+    m_mesh_dimension = meshes[idomain]->getMeshDimension();
+    //constituent_entity = (m_mesh_dimension == 3 ? MED_EN::MED_FACE : MED_EN::MED_EDGE );
+
+    //creating cell maps
+    m_nb_cells[idomain]=meshes[idomain]->getNumberOfCells();
+    //    cout << "Nb cells (domain "<<idomain<<") = "<<m_nb_cells[idomain];
+    m_loc_to_glob[idomain].resize(m_nb_cells[idomain]);
+
+    if (cellglobal[idomain]==0 || parallel_mode)
+    {
+      MESSAGE_MED("Creating global numbering"); 
+      //creating global numbering from scratch
+      for (int i=0; i<m_nb_cells[idomain]; i++)
+      {
+       
+        m_glob_to_loc[index_global]=make_pair(idomain,i);
+        //m_loc_to_glob[make_pair(idomain,i+1)]=index_global;
+        m_loc_to_glob[idomain][i]=index_global;
+        //        cout<<"glob:"<<index_global<<" --> ("<<idomain<<","<<i+1<<")"<<endl;
+        index_global++;
+      }
+    }
+    //using global numbering coming from a previous numbering
+    else
+    {
+      MESSAGE_MED("Using former global numbering");
+      for (int i=0; i<m_nb_cells[idomain]; i++)
+      {
+        int global=cellglobal[idomain][i];
+        m_glob_to_loc[global]=make_pair(idomain,i);
+        //m_loc_to_glob[make_pair(idomain,i+1)]=global;
+        m_loc_to_glob[idomain][i]=global;
+        index_global++;
+        //        cout<<"glob:"<<global<<" --> ("<<idomain<<","<<i+1<<")"<<endl;
+      }
+    }
+
+    //cas sequentiel
+    if (m_nb_domain==1)
+    {
+      m_nb_total_cells=index_global;
+      m_nb_cells[0]=index_global;
+      m_node_loc_to_glob[idomain].resize(meshes[idomain]->getNumberOfNodes());
+      for (int i=0; i<meshes[idomain]->getNumberOfNodes(); i++)
+      {
+        m_node_glob_to_loc.insert(make_pair(i,make_pair(0,i)));
+        //m_node_loc_to_glob.insert(make_pair(make_pair(0,i+1), i+1));
+        m_node_loc_to_glob[0][i]=i;
+      }
+      m_nb_total_nodes=meshes[idomain]->getNumberOfNodes();   
+      m_nb_nodes[0]=m_nb_total_nodes; 
+
+      //      meshes[idomain]->getConnectivity(MED_EN::MED_FULL_INTERLACE, MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); 
+    //   int nbfaces=meshes[idomain]->getNumberOfElementsWithPoly(constituent_entity,MED_EN::MED_ALL_ELEMENTS);
+//       m_face_loc_to_glob[idomain].resize(nbfaces);
+//       for (int i=0; i<nbfaces; i++)
+//       {
+//         m_face_glob_to_loc.insert(make_pair(i+1,make_pair(0,i+1)));
+//         //m_face_loc_to_glob.insert(make_pair(make_pair(0,i+1), i+1));
+//         m_face_loc_to_glob[0][i]=i+1;
+//       }
+//       m_nb_total_faces=nbfaces;   
+//       m_nb_faces[0]=nbfaces;
+      MESSAGE_MED ("nb total cells "<< m_nb_total_cells);
+      MESSAGE_MED("nb total nodes "<< m_nb_total_nodes);  
+  //     MESSAGE_MED("nb total faces "<< m_nb_total_faces);  
+      return;
+    }
+
+    //creating node maps
+    m_nb_nodes[idomain]=meshes[idomain]->getNumberOfNodes();
+    hash_map <int,pair<int,int> > local2distant;
+    m_node_loc_to_glob[idomain].resize(m_nb_nodes[idomain]);
+    for (int icz=0; icz<cz.size(); icz++)
+    {
+      if (cz[icz]->getLocalDomainNumber() == idomain && 
+          cz[icz]->getLocalDomainNumber()>cz[icz]->getDistantDomainNumber())
+      {
+        int nb_node= cz[icz]->getNodeNumber();
+        const int* node_corresp=cz[icz]->getNodeCorrespValue();
+        int distant_ip = cz[icz]->getDistantDomainNumber();
+        for (int i=0; i< nb_node; i++)
+        {
+          int local= node_corresp[i*2];
+          int distant = node_corresp[i*2+1];
+          local2distant.insert(make_pair(local, make_pair(distant_ip,distant)));    
+        }
+      }
+    }
+    // setting mappings for all nodes
+    if (nodeglobal[idomain]==0)
+    {
+      for (int inode=0; inode<m_nb_nodes[idomain]; inode++)
+      {
+        if (local2distant.find(inode)==local2distant.end())
+        {
+          index_node_global++;
+          m_node_glob_to_loc.insert(make_pair(index_node_global,make_pair(idomain,inode)));
+          //m_node_loc_to_glob[make_pair(idomain,inode+1)]=index_node_global;
+          m_node_loc_to_glob[idomain][inode]=index_node_global;
+        }   
+        else
+        {
+          int ip = (local2distant.find(inode)->second).first;
+          int distant = (local2distant.find(inode)->second).second;
+          //int global_number=m_loc_to_glob[make_pair(ip,distant)];
+          int global_number=m_loc_to_glob[ip][distant];
+          m_node_glob_to_loc.insert(make_pair(global_number,make_pair(idomain,inode)));
+          //m_node_loc_to_glob[make_pair(idomain,inode+1)]=global_number;
+          m_node_loc_to_glob[idomain][inode]=global_number;
+        } 
+      }
+    }
+    //using former node numbering
+    else
+    {//       cout << "("<<idomain<<","<<i+1<<")->"<<i+1<<endl;
+      for (int inode=0; inode<m_nb_nodes[idomain]; inode++)
+      {
+        int global_number=nodeglobal[idomain][inode];
+        //        cout << "global_number "<<global_number<<endl;
+        m_node_glob_to_loc.insert(make_pair(global_number,make_pair(idomain,inode)));
+        //m_node_loc_to_glob[make_pair(idomain,inode+1)]=global_number;
+        m_node_loc_to_glob[idomain][inode]=global_number;
+      }
+    }
+
+
+    //creating  dimension d-1 component mappings
+
+    //    meshes[idomain]->getConnectivity(MED_EN::MED_FULL_INTERLACE, MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); 
+//     m_nb_faces[idomain]=meshes[idomain]->getNumberOfElementsWithPoly(constituent_entity,MED_EN::MED_ALL_ELEMENTS);
+//     MESSAGE_MED ("Nb faces domain " << idomain<<m_nb_faces[idomain]);
+//     m_face_loc_to_glob[idomain].resize(m_nb_faces[idomain]);
+//     local2distant.clear();
+//     for (int icz=0; icz<cz.size(); icz++)
+//     {
+//       if (cz[icz]->getLocalDomainNumber() == idomain && 
+//           cz[icz]->getLocalDomainNumber()>cz[icz]->getDistantDomainNumber())
+//       {
+//         int nb_face= cz[icz]->getFaceNumber();
+//         const int* face_corresp=cz[icz]->getFaceCorrespValue();
+//         int distant_ip = cz[icz]->getDistantDomainNumber();
+//         for (int i=0; i< nb_face; i++)
+//         {
+//           int local= face_corresp[i*2];
+//           int distant = face_corresp[i*2+1];
+//           local2distant.insert(make_pair(local, make_pair(distant_ip,distant)));    
+//         }
+//       }
+//     }
+//     // setting mappings for all faces
+//     if (faceglobal[idomain]==0)
+//     {
+//       for (int iface=0; iface<m_nb_faces[idomain]; iface++)
+//       {
+//         if (local2distant.find(iface+1)==local2distant.end())
+//         {
+//           index_face_global++;
+//           m_face_glob_to_loc.insert(make_pair(index_face_global,make_pair(idomain,iface+1)));
+//           //m_face_loc_to_glob[make_pair(idomain,iface+1)]=index_face_global;
+//           m_face_loc_to_glob[idomain][iface]=index_face_global;
+//         }   
+//         else
+//         {
+//           int ip = (local2distant.find(iface+1)->second).first;
+//           int distant = (local2distant.find(iface+1)->second).second;
+//           //int global_number=m_loc_to_glob[make_pair(ip,distant)];
+//           int global_number=m_loc_to_glob[ip][distant-1];
+//           m_face_glob_to_loc.insert(make_pair(global_number,make_pair(idomain,iface+1)));
+//           //m_face_loc_to_glob[make_pair(idomain,iface+1)]=global_number;
+//           m_face_loc_to_glob[idomain][iface]=global_number;
+//         } 
+//       }
+//     }     
+//     //using former face numbering
+//     else
+//     {
+//       for (int iface=0; iface<m_nb_faces[idomain]; iface++)
+//       {
+//         int global_number=faceglobal[idomain][iface];
+//         //cout << "dom: "<< idomain << " read glob face " << global_number << endl;
+//         //SCRUTE_MED(global_number);
+//         m_face_glob_to_loc.insert(make_pair(global_number,make_pair(idomain,iface+1)));
+//         //m_face_loc_to_glob[make_pair(idomain,iface+1)]=global_number;
+//         m_face_loc_to_glob[idomain][iface]=global_number;
+//       }
+//     }     
+
+  }
+
+  m_nb_total_cells=index_global;
+  m_nb_total_nodes=index_node_global;   
+  m_nb_total_faces=index_face_global;
+  SCRUTE_MED(m_nb_total_cells);
+  SCRUTE_MED(m_nb_total_faces);
+  SCRUTE_MED(m_nb_total_nodes);
+
+}
+
+
+//!constructing ParallelTopology from an old topology and a graph
+ParallelTopology::ParallelTopology(Graph* graph, int nb_domain, int mesh_dimension):
+  m_nb_domain(nb_domain),
+  m_nb_cells(graph->nbVertices()),
+  m_mesh_dimension(mesh_dimension)
+{
+  m_nb_cells.resize(m_nb_domain);
+  m_nb_nodes.resize(m_nb_domain);
+  m_nb_faces.resize(m_nb_domain);
+
+  m_loc_to_glob.resize(m_nb_domain);
+  m_node_loc_to_glob.resize(m_nb_domain);
+  m_face_loc_to_glob.resize(m_nb_domain);
+
+  // used in parallel mode only
+  m_cell_loc_to_glob_fuse.resize(m_nb_domain);
+  m_face_loc_to_glob_fuse.resize(m_nb_domain);
+
+  for (int i=0; i<m_nb_domain; i++)
+    m_nb_cells[i]=0;  
+
+  const int* part = graph-> getPart();
+  m_nb_total_cells= graph->nbVertices();
+  
+  for (int icell=0; icell<m_nb_total_cells; icell++)
+  {
+    int idomain = part[icell];
+    m_nb_cells[idomain]++;
+    //m_loc_to_glob[make_pair(idomain,m_nb_cells[idomain])]=icell+1;
+    m_loc_to_glob[idomain].push_back(icell);
+    m_glob_to_loc[icell]=make_pair(idomain,m_nb_cells[idomain]);
+
+  }
+  for (int idomain=0; idomain<m_nb_domain; idomain++)
+    MESSAGE_MED("Nombre de cellules dans le domaine "<< idomain <<" : "<<m_nb_cells[idomain]); 
+
+  SCRUTE_MED(m_nb_total_cells);
+
+}
+
+ParallelTopology::~ParallelTopology()
+{
+} 
+
+/*!Converts a list of global node numbers
+ * to a distributed array with local cell numbers.
+ * 
+ * If a node in the list is represented on several domains,
+ * only the first value is returned
+ * */
+void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, int* local, int* ip)
+{
+  if (m_node_glob_to_loc.empty()) 
+    throw MEDMEM::MEDEXCEPTION("convertGlobalNodeList - Node mapping has not yet been built");
+  for (int i=0; i< nbnode; i++)
+  {
+    pair<int,int> local_node = m_node_glob_to_loc.find(node_list[i])->second;
+    ip[i]=local_node.first;
+    local[i]=local_node.second;
+  }
+}
+
+/*!Converts a list of global node numbers on domain ip
+ * to a distributed array with local cell numbers.
+ * 
+ * If a node in the list is represented on several domains,
+ * only the value with domain ip is returned
+ * 
+ * */
+void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, int* local, int ip)
+{
+  if (m_node_glob_to_loc.empty()) 
+    throw MEDMEM::MEDEXCEPTION("convertGlobalNodeList - Node mapping has not yet been built");
+
+  for (int i=0; i< nbnode; i++)
+  {
+    typedef hash_multimap<int,pair<int,int> >::iterator mmiter;
+    pair<mmiter,mmiter> range=m_node_glob_to_loc.equal_range(node_list[i]);
+    for (mmiter it=range.first; it !=range.second; it++)
+    { 
+      int ipfound=(it->second).first;
+      if (ipfound==ip)
+        local[i]=(it->second).second;
+    }
+  }
+} 
+
+/*!Converts a list of global node numbers
+ * to a distributed array with local cell numbers.
+ * 
+ * If a node in the list is represented on several domains,
+ * all the values are put in the array
+ * */
+void ParallelTopology::convertGlobalNodeListWithTwins(const int* node_list, int nbnode, int*& local, int*& ip,int*& full_array, int& size)
+{
+  if (m_node_glob_to_loc.empty()) 
+    throw MEDMEM::MEDEXCEPTION("convertGlobalNodeList - Node mapping has not yet been built");
+
+  size=0;
+  for (int i=0; i< nbnode; i++)
+  {
+    int count= m_node_glob_to_loc.count(node_list[i]);
+    //      if (count > 1) 
+    //        cout << "noeud " << node_list[i]<< " doublon d'ordre " << count<<endl;
+    size+=count;
+  }
+  int index=0;
+  ip=new int[size];
+  local=new int[size];
+  full_array=new int[size];
+  for (int i=0; i< nbnode; i++)
+  {
+    typedef hash_multimap<int,pair<int,int> >::iterator mmiter;
+    pair<mmiter,mmiter> range=m_node_glob_to_loc.equal_range(node_list[i]);
+    for (mmiter it=range.first; it !=range.second; it++)
+    { 
+      ip[index]=(it->second).first;
+      local[index]=(it->second).second;
+      full_array [index]=node_list[i];
+      index++;
+    }
+
+  }
+}
+
+/*!Converts a list of global face numbers
+ * to a distributed array with local face numbers.
+ * 
+ * If a face in the list is represented on several domains,
+ * all the values are put in the array
+ * */
+void ParallelTopology::convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array,int& size)
+{
+  size=0;
+  for (int i=0; i< nbface; i++)
+  {
+    //int count = m_face_glob_to_loc.count(face_list[i]);
+    //if (count >1) MESSAGE_MED("face en doublon "<<face_list[i]);
+    size+= m_face_glob_to_loc.count(face_list[i]);
+  }
+  int index=0;
+  ip=new int[size];
+  local=new int[size];
+  full_array=new int[size];
+  for (int i=0; i< nbface; i++)
+  {
+    typedef hash_multimap<int,pair<int,int> >::iterator mmiter;
+    pair<mmiter,mmiter> range=m_face_glob_to_loc.equal_range(face_list[i]);
+    for (mmiter it=range.first; it !=range.second; it++)
+    { 
+      ip[index]=(it->second).first;
+      local[index]=(it->second).second;
+      full_array[index]=face_list[i];
+      index++;
+    }
+
+  }
+}
+
+//!converts a list of global cell numbers
+//!to a distributed array with local cell numbers 
+void ParallelTopology::convertGlobalCellList(const int* cell_list, int nbcell, int* local, int* ip)
+{
+  for (int i=0; i< nbcell; i++)
+  {
+    hash_map<int, pair<int,int> >::const_iterator iter = m_glob_to_loc.find(cell_list[i]);
+    ip[i]=(iter->second).first;
+    local[i]=(iter->second).second;
+  }
+}
+
+/*!Converts a list of global face numbers
+ * to a distributed array with local face numbers
+ */ 
+void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, int* local, int* ip)
+{
+  for (int i=0; i< nbface; i++)
+  {
+    hash_map<int, pair<int,int> >::const_iterator iter = m_face_glob_to_loc.find(face_list[i]);
+    if (iter == m_face_glob_to_loc.end())
+    {
+      throw MED_EXCEPTION("convertGlobalFaceList - Face  not found");
+    }
+    ip[i]=(iter->second).first;
+    local[i]=(iter->second).second;
+    //    cout << " in convertGlobalFAceList face global "<<face_list[i]<<" -> ("<<ip[i]<<","<<local[i]<<")"<<endl;
+  }
+}
+
+/*!Converts a list of global node numbers on domain ip
+ * to a distributed array with local cell numbers.
+ * 
+ * If a node in the list is represented on several domains,
+ * only the value with domain ip is returned
+ * 
+ * */
+void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, int* local, int ip)
+{
+  for (int i=0; i< nbface; i++)
+  {
+    typedef hash_multimap<int,pair<int,int> >::iterator mmiter;
+    pair<mmiter,mmiter> range=m_face_glob_to_loc.equal_range(face_list[i]);
+    for (mmiter it=range.first; it !=range.second; it++)
+    { 
+      int ipfound=(it->second).first;
+      if (ipfound==ip)
+        local[i]=(it->second).second; 
+
+    }
+  }
+} 
+
+
+////creating node mapping 
+// void ParallelTopology::createNodeMapping(map<MED_EN::medGeometryElement,int*>& type_connectivity,
+//                                          map<MED_EN::medGeometryElement,int>& present_type_numbers,
+//                                          vector<int>& polygon_conn,
+//                                          vector<int>& polygon_conn_index,
+//                                          vector<int>& polyhedron_conn,
+//                                          vector<int>& polyhedron_conn_index,
+//                                          vector<int>& polyhedron_face_index,
+//                                          int idomain)
+// {
+//   set<int> local_numbers;
+//   int local_index=0;
+
+//   map<MED_EN::medGeometryElement,int>::const_iterator iter;
+//   for (iter = present_type_numbers.begin(); iter!=present_type_numbers.end();iter++)
+//   {
+//     int type=iter->first;
+//     int nodes_per_type= type%100;
+
+//     if (!((type/100==m_mesh_dimension)
+//           ||(type==MED_EN::MED_POLYGON && m_mesh_dimension==2)
+//           ||(type==MED_EN::MED_POLYHEDRA && m_mesh_dimension==3))) continue;
+
+//     if (type != MED_EN::MED_POLYGON && type != MED_EN::MED_POLYHEDRA)
+//     {
+//       for (int icell=0; icell<present_type_numbers[type]; icell++)
+//       {
+//         for (int inode=0; inode<nodes_per_type; inode++)
+//         {
+//           int global=type_connectivity[type][icell*nodes_per_type+inode];
+//           if(local_numbers.find(global)==local_numbers.end())
+//           {
+//             local_index++;
+//             local_numbers.insert(global);
+//             //m_node_loc_to_glob.insert(make_pair(make_pair(idomain,local_index),global));
+//             m_node_loc_to_glob[idomain].push_back(global);
+//             m_node_glob_to_loc.insert(make_pair(global,make_pair(idomain,local_index)));
+//             //          cout << "node : global ="<<global<<" local =("<<idomain<<","<<local_index<<")"<<endl;         
+//           }
+//         }
+
+//       }
+//     }
+//     else if (type== MED_EN::MED_POLYGON)
+//     {
+//       for (int icell=0; icell<polygon_conn_index.size()-1; icell++)
+//       {
+//         for (int inode=polygon_conn_index[icell]; inode<polygon_conn_index[icell+1]; inode++)
+//         {
+//           int global=polygon_conn[inode-1];
+//           if(local_numbers.find(global)==local_numbers.end())
+//           {
+//             local_index++;
+//             local_numbers.insert(global);
+//             //m_node_loc_to_glob.insert(make_pair(make_pair(idomain,local_index),global));
+//             m_node_loc_to_glob[idomain].push_back(global);
+//             m_node_glob_to_loc.insert(make_pair(global,make_pair(idomain,local_index)));
+//             //          cout << "node : global ="<<global<<" local =("<<idomain<<","<<local_index<<")"<<endl;         
+//           }
+//         }
+
+//       }
+//     }
+//     else if (type==MED_EN::MED_POLYHEDRA)
+//     {
+//       for (int icell=0; icell<polyhedron_conn_index.size()-1; icell++)
+//       {
+//         for (int iface = polyhedron_conn_index[icell];
+//              iface < polyhedron_conn_index[icell+1];
+//              iface++)
+//           for (int inode=polyhedron_face_index[iface-1];
+//                inode<polyhedron_face_index[iface]; inode++)
+//           {
+//             int global=polyhedron_conn[inode-1];
+//             if(local_numbers.find(global)==local_numbers.end())
+//             {
+//               local_index++;
+//               local_numbers.insert(global);
+//               //m_node_loc_to_glob.insert(make_pair(make_pair(idomain,local_index),global));
+//               m_node_loc_to_glob[idomain].push_back(global);
+//               m_node_glob_to_loc.insert(make_pair(global,make_pair(idomain,local_index)));
+//               //          cout << "node : global ="<<global<<" local =("<<idomain<<","<<local_index<<")"<<endl;         
+//             }
+//           }
+
+
+//       }
+//     }
+
+//   }
+//   m_nb_nodes[idomain]=local_index;
+// }
+
+//================================================================================
+/*!
+ * \brief Return true if the domain mesh contains a cell based on given global nodes
+ */
+//================================================================================
+
+// bool ParallelTopology::hasCellWithNodes( const MESHCollection& new_collection,
+//                                          int                   domain,
+//                                          const set<int>&       globNodes)
+// {
+//   // convert global nodes to local in the given domain
+//   set<int> nodes;
+//   set<int>::const_iterator n = globNodes.begin();
+//   for ( ; n != globNodes.end(); ++n )
+//     nodes.insert( convertGlobalNode( *n, domain ));
+
+//   const MED_EN::medConnectivity connType = MED_EN::MED_NODAL;
+//   const MED_EN::medEntityMesh   entity   = MED_EN::MED_CELL;
+
+//   // loop on all types of cells
+//   const MEDMEM::MESH* mesh = new_collection.getMesh( domain );
+//   int nbTypes = mesh->getNumberOfTypesWithPoly( entity );
+//   MED_EN::medGeometryElement * types = mesh->getTypesWithPoly( entity );
+//   for ( int t = 0; t < nbTypes; ++t )
+//   {
+//     // get connectivity
+//     if ( !mesh->existConnectivityWithPoly( connType, entity ))
+//       continue;
+//     int nbCell = mesh->getNumberOfElementsWithPoly( entity, types[t] );
+//     const int *conn, *index;
+//     switch ( types[t] )
+//     {
+//     case MED_EN::MED_POLYGON:
+//       conn  = mesh->getPolygonsConnectivity( connType, entity );
+//       index = mesh->getPolygonsConnectivityIndex( connType, entity );
+//       break;
+//     case MED_EN::MED_POLYHEDRA:
+//       conn  = mesh->getPolyhedronConnectivity( connType );
+//       index = mesh->getPolyhedronFacesIndex();
+//       nbCell = mesh->getNumberOfPolyhedronFaces();
+//       break;
+//     default:
+//       conn  = mesh->getConnectivity(MED_EN::MED_FULL_INTERLACE,connType, entity, types[t]);
+//       index = mesh->getConnectivityIndex(connType, entity);
+//     }
+//     // find a cell containing the first of given nodes,
+//     // then check if the found cell contains all the given nodes
+//     const int firstNode = *nodes.begin();
+//     for ( int i = 0; i < nbCell; ++i )
+//     {
+//       for ( int j = index[i]-1; j < index[i+1]-1; ++j )
+//         if ( conn[j] == firstNode )
+//         {
+//           int nbSame = 0;
+//           for ( j = index[i]-1; j < index[i+1]-1; ++j )
+//             nbSame += nodes.count( conn[j] );
+//           if ( nbSame == nodes.size() )
+//             return true;
+//           break;
+//         }
+//     }
+//   }
+//   delete [] types;
+//   return false;
+// }
+
+////creating face mapping 
+// void ParallelTopology::createFaceMapping(const MESHCollection& initial_collection,
+//                                          const MESHCollection& new_collection)
+//   //                     map<MED_EN::medGeometryElement,int*>& type_list,
+//   //                     map<MED_EN::medGeometryElement,int>& present_type_numbers,
+//   //                     int idomain
+
+// {
+//   // containers for the new topology
+//   vector<int> new_counts(m_nb_domain,0);
+//   vector<int> domain_counts(m_nb_domain,0);
+//   const Topology* old_topology=initial_collection.getTopology();
+//   int nb_domain_old=old_topology->nbDomain();
+//   int global_index=old_topology->getFaceNumber();
+//   //cout << "nb faces = " << global_index << endl;
+//   set <pair<int, pair<int,int> > > global_treated;
+
+//   //definition of the d-1 constituent for the considered mesh dimension
+//   MED_EN::medEntityMesh constituent_entity;
+//   switch (m_mesh_dimension)
+//   {
+//   case 3:
+//     constituent_entity= MED_EN::MED_FACE;
+//     break;
+//   case 2:
+//     constituent_entity = MED_EN::MED_EDGE;
+//     break;
+//   }
+
+//   for (int iold=0; iold<nb_domain_old;iold++)
+//   {
+//     if ( !initial_collection.getMesh(iold) ) continue;
+//     int nbplainface = initial_collection.getMesh(iold)->getNumberOfElements(constituent_entity,MED_EN::MED_ALL_ELEMENTS);
+//     int nbtotalface = initial_collection.getMesh(iold)->getNumberOfElementsWithPoly(constituent_entity,MED_EN::MED_ALL_ELEMENTS);
+//     SCRUTE_MED(nbplainface);
+//     SCRUTE_MED(nbtotalface);  
+//     const int* face_conn;
+//     const int* face_offset;
+//     const int* poly_conn;
+//     const int* poly_index;
+//     if (nbtotalface >0)
+//     {
+//       if (nbplainface >0)
+//       {
+//         face_conn = initial_collection.getMesh(iold)->getConnectivity(MED_EN::MED_FULL_INTERLACE,
+//                                                                       MED_EN::MED_NODAL,constituent_entity,MED_EN::MED_ALL_ELEMENTS);
+//         face_offset = initial_collection.getMesh(iold)->getConnectivityIndex(MED_EN::MED_NODAL,constituent_entity);
+//       }
+//       if (nbtotalface > nbplainface)
+//       {
+//         poly_conn = initial_collection.getMesh(iold)->getPolygonsConnectivity(MED_EN::MED_NODAL,constituent_entity);
+//         poly_index = initial_collection.getMesh(iold)->getPolygonsConnectivityIndex(MED_EN::MED_NODAL,constituent_entity);
+//       }
+
+//     }
+//     else 
+//     {
+//       face_conn=0;
+//       face_offset=0;
+//     }
+//     for (int iface=0;iface<nbtotalface; iface++)
+//     {
+//       int global_face_number = old_topology->convertFaceToGlobal(iold,iface+1);
+
+//       //      int inode = face_offset[iface];
+//       for (int i=0; i<m_nb_domain; i++) domain_counts[i]=0;
+//       set <int> nodes;
+//       int nbnodes;
+//       if (iface<nbplainface)
+//       {
+//         nbnodes=face_offset[iface+1]-face_offset[iface];
+//         for (int inode= face_offset[iface];inode < face_offset[iface+1]; inode++)
+//         {
+//           int node=face_conn[inode-1];
+
+//           int global = old_topology->convertNodeToGlobal(iold,node);
+//           //        cout << "global node "<<global<<"ip "<<iold<< "noeud"<<node<<endl;
+//           nodes.insert(global);
+//           typedef hash_multimap<int,pair<int,int> >::iterator mmiter;
+//           pair<mmiter,mmiter> range=m_node_glob_to_loc.equal_range(global);
+
+//           int ip;
+//           for (mmiter it=range.first; it !=range.second; it++)
+//           { 
+//             ip=(it->second).first;
+//             domain_counts[ip]++;
+//           }
+//         }
+//       }
+//       else 
+//       {
+//         nbnodes =poly_index[iface-nbplainface+1]- poly_index[iface-nbplainface];
+//         for (int inode= poly_index[iface-nbplainface];inode < poly_index[iface-nbplainface+1]; inode++)
+//         {
+//           int node=poly_conn[inode-1];
+//           //   SCRUTE_MED(node);
+//           int global = old_topology->convertNodeToGlobal(iold,node);
+//           //        cout << "global node "<<global<<"ip "<<iold<< "noeud"<<node<<endl;
+//           // SCRUTE_MED(global);
+//           nodes.insert(global);
+//           typedef hash_multimap<int,pair<int,int> >::iterator mmiter;
+//           pair<mmiter,mmiter> range=m_node_glob_to_loc.equal_range(global);
+
+//           int ip;
+//           for (mmiter it=range.first; it !=range.second; it++)
+//           { 
+//             ip=(it->second).first;
+//             domain_counts[ip]++;
+//           }
+//         }
+//       }
+//       set<int>::const_iterator iter_node = nodes.begin();
+//       int numbers[3];
+//       numbers[2]=0; // for segments
+//       for (int i=0; i<nbnodes; i++)
+//       {
+//         numbers[i]=*iter_node;
+//         iter_node++;
+//       }
+//       set <pair<int, pair<int,int> > > ::iterator iter_triplets;
+//       pair<int, pair<int,int> > triplet = make_pair(numbers[0],make_pair(numbers[1],numbers[2]));
+//       iter_triplets=global_treated.find(triplet);
+//       if (iter_triplets==global_treated.end())
+//       {
+//         global_treated.insert(triplet);
+//         //  int nbnodes=face_offset[iface+1]-face_offset[iface];
+//         if (global_face_number == -1) 
+//         {
+//           global_index++;
+//           global_face_number=global_index;
+
+//         }
+//         //  SCRUTE_MED(nbnodes);
+
+//         for (int inew=0;inew<m_nb_domain;inew++)
+//         {
+//           //     SCRUTE_MED(domain_counts[inew]);
+//           if(domain_counts[inew]==nbnodes)
+//           {
+//             if ( !hasCellWithNodes( new_collection, inew, nodes ))
+//               continue; // 0020861: EDF 1387 MED: Result of medsplitter gives standalone triangles
+
+//             new_counts[inew]++;
+//             m_face_glob_to_loc.insert(make_pair(global_face_number,make_pair(inew,new_counts[inew])));
+//             //m_face_loc_to_glob.insert(make_pair(make_pair(inew,new_counts[inew]),global_face_number));
+//             m_face_loc_to_glob[inew].push_back(global_face_number);
+//           }
+//         }
+//         //cout << "global_face_number = " << global_face_number << endl;
+//       }
+//     }
+//   }
+
+//   for (int inew=0;inew<m_nb_domain;inew++)
+//   {
+//     m_nb_faces[inew]=new_counts[inew];
+//     MESSAGE_MED(" Nb faces ["<<inew<<"]="<<m_nb_faces[inew]);
+//   }
+//   MESSAGE_MED(" total number of faces"<<getFaceNumber());
+// }
+
+////creating node mapping 
+// void ParallelTopology::createFaceMapping2ndversion(const MESHCollection& initial_collection)
+
+// {
+//   // containers for the new topology
+//   vector<int> new_counts(m_nb_domain,0);
+//   vector<int> domain_counts(m_nb_domain,0);
+//   const Topology* old_topology=initial_collection.getTopology();
+//   int nb_domain_old=old_topology->nbDomain();
+//   //int global_index=old_topology->getFaceNumber();
+//   //  set <pair<int, pair<int,int> > > global_treated;
+
+//   //definition of the d-1 constituent for the considered mesh dimension
+//   MED_EN::medEntityMesh constituent_entity;
+//   switch (m_mesh_dimension)
+//   {
+//   case 3:
+//     constituent_entity= MED_EN::MED_FACE;
+//     break;
+//   case 2:
+//     constituent_entity = MED_EN::MED_EDGE;
+//     break;
+//   }
+
+//   for (int iold=0; iold<nb_domain_old;iold++)
+//   {
+//     int nbcell=old_topology->getCellNumber(iold);
+
+//     const int* face_conn = initial_collection.getMesh(iold)->
+//       getConnectivity(MED_EN::MED_FULL_INTERLACE,
+//                       MED_EN::MED_DESCENDING,MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS);
+//     const int* face_offset = initial_collection.getMesh(iold)->
+//       getConnectivityIndex(MED_EN::MED_DESCENDING,MED_EN::MED_CELL);
+//     MESSAGE_MED("end of connectivity calculation");
+//     set<int> global_treated;
+//     for (int icell=0; icell<nbcell; icell++)
+//     {
+//       int global_cell_number=old_topology->convertCellToGlobal(iold,icell+1);
+//       int inew = getCellDomainNumber(global_cell_number);
+
+//       for (int iface = face_offset[icell]; iface < face_offset[icell+1]; iface++)
+//       {
+//         int global_face_number=old_topology->convertFaceToGlobal(iold,abs(face_conn[iface-1]));
+//         if (global_treated.find (global_face_number)==global_treated.end())
+//         {
+//           new_counts[inew]++;
+//           m_face_glob_to_loc.insert(make_pair(global_face_number,make_pair(inew,new_counts[inew])));
+
+//           //m_face_loc_to_glob.insert(make_pair(make_pair(inew,new_counts[inew]),global_face_number));
+//           m_face_loc_to_glob[inew].push_back(global_face_number);
+//           global_treated.insert(global_face_number);
+
+//         }
+//       }
+//     }
+//   }
+
+
+//   for (int inew=0;inew<m_nb_domain;inew++)
+//   {
+//     m_nb_faces[inew]=new_counts[inew];
+//     //  cout << " Nb faces ["<<inew<<"]="<<m_nb_faces[inew]<<endl;
+//   }
+//   MESSAGE_MED(" total number of faces"<<getFaceNumber());
+// }
+
+
+//replacing a table of global numbering with a table with local numberings
+// type_connectivity contains global connectivity for each type in input
+// type_connectivity contains local connectivity for each type in output
+// void ParallelTopology::convertToLocal(map<MED_EN::medGeometryElement,int*>& type_connectivity,
+//                                       map<MED_EN::medGeometryElement,int>& present_type_numbers,
+//                                       int idomain,
+//                                       MED_EN::medEntityMesh entity)
+// {
+//   int dimension;
+//   switch (entity)
+//   {
+//   case MED_EN::MED_CELL:
+//     dimension=m_mesh_dimension;
+//     break;
+//   case MED_EN::MED_FACE:
+//     dimension=2;
+//     break;
+//   case MED_EN::MED_EDGE:
+//     dimension=1;
+//     break;
+//   } 
+
+//   MED_EN::MESH_ENTITIES::const_iterator currentEntity;
+//   list<MED_EN::medGeometryElement>::const_iterator iter;
+//   currentEntity  = MED_EN::meshEntities.find(MED_EN::MED_CELL);
+
+//   for (iter = (*currentEntity).second.begin();iter != (*currentEntity).second.end(); iter++)
+//   {
+//     MED_EN::medGeometryElement type = (*iter);
+//     if (type/100 != dimension) continue;
+//     for (int inode=0; inode<present_type_numbers[type]*(type%100); inode++)
+//     {
+//       //      cout <<" inode :"<<inode<< " global = "<<type_connectivity[type][inode];
+//       int global = type_connectivity[type][inode];
+//       typedef hash_multimap<int,pair<int,int> >::iterator mmiter;
+//       pair<mmiter,mmiter> range=m_node_glob_to_loc.equal_range(global);
+//       for (mmiter it=range.first; it !=range.second; it++)
+//       {
+//         if ((it->second).first==idomain)
+//           type_connectivity[type][inode]=(it->second).second;
+//       }
+//       //      cout << " local = " <<type_connectivity[type][inode]<<endl;
+//     }
+
+//   }
+// }
+
+//replacing a table of global numbering with a table with local numberings
+// type_connectivity contains global connectivity for each type in input
+// type_connectivity contains local connectivity for each type in output
+void ParallelTopology::convertToLocal2ndVersion(int* nodes, int nbnodes, int idomain)
+{
+  for (int inode=0; inode<nbnodes; inode++)
+  {
+    //      cout <<" inode :"<<inode<< " global = "<<type_connectivity[type][inode];
+    int global = nodes[inode];
+    typedef hash_multimap<int,pair<int,int> >::iterator mmiter;
+    pair<mmiter,mmiter> range=m_node_glob_to_loc.equal_range(global);
+    for (mmiter it=range.first; it !=range.second; it++)
+    {
+      if ((it->second).first==idomain)
+        nodes[inode]=(it->second).second;
+    }        
+  }
+}
+
+
+//! computing arrays with node/node correspondencies
+// void ParallelTopology::computeNodeNodeCorrespondencies(int idomain, vector<MEDMEM::MEDSKYLINEARRAY*>& corr) const
+// {
+//   vector <int> sizes (m_nb_domain,0);
+//   vector <int*> values (m_nb_domain);
+//   for (int i=0; i<m_nb_domain; i++)
+//   {
+//     values[i]=0;
+//   }
+
+//   for (int inode=0; inode<m_nb_nodes[idomain]; inode++)
+//   {
+//     //int global = (m_node_loc_to_glob.find(make_pair(idomain,inode+1)))->second;
+//     int global = m_node_loc_to_glob[idomain][inode];
+//     typedef hash_multimap<int,pair<int,int> >::const_iterator mm;
+//     pair<mm,mm> range = m_node_glob_to_loc.equal_range(global);
+//     for (mm it=range.first; it !=range.second; it++)
+//     {
+//       int id = (it->second).first;
+//       if (id !=idomain)
+//       {
+//         sizes[id]++;
+//       }
+//     }
+//   }
+
+//   for (int ip=0; ip<m_nb_domain; ip++)
+//   {
+//     if (sizes[ip]>0)
+//       values[ip]=new int[2*sizes[ip]];
+//     sizes[ip]=0;
+//   }
+
+
+//   for (int inode=0; inode<m_nb_nodes[idomain]; inode++)
+//   {
+//     //int global = (m_node_loc_to_glob.find(make_pair(idomain,inode+1)))->second;
+//     int global = m_node_loc_to_glob[idomain][inode];
+//     typedef hash_multimap<int,pair<int,int> >::const_iterator mm;
+//     pair<mm,mm> range = m_node_glob_to_loc.equal_range(global);
+//     for (mm it=range.first; it !=range.second; it++)
+//     {
+//       int id = (it->second).first;
+//       if (id !=idomain)
+//       {
+//         values[id][sizes[id]*2]=inode+1;
+//         values[id][sizes[id]*2+1]=(it->second).second;
+//         sizes[id]++;
+//       }
+//     }
+//   }
+
+//   for (int i=0; i< m_nb_domain; i++)
+//   {
+//     if (sizes[i]!=0)
+//     {
+//       int* index = new int[sizes[i]+1];
+//       for (int j=0; j<sizes[i]+1; j++)
+//         index[j]=j+1;
+//       corr[i]=new MEDMEM::MEDSKYLINEARRAY(sizes[i],2*sizes[i],index,values[i]);
+//       delete[] index;
+//       delete[] values[i];
+//     }
+//   }
+// }
+
+//================================================================================
+/*!
+ * \brief computing arrays with cell/cell correspondencies
+ *  \param idomain - domain for which to compute correspondencies
+ *  \param corr - out correspondencies
+ *  \param graph - graph containing new cell distribution among domains
+ *  \param id_shift - shitf to get cell id global on this processor from id global
+ *                    over all procs
+ */
+//================================================================================
+
+// void ParallelTopology::computeCellCellCorrespondencies(int idomain, vector<MEDMEM::MEDSKYLINEARRAY*>& corr, const Graph* graph) const
+// {
+//   vector <int> sizes (m_nb_domain,0);
+//   vector <int*> values (m_nb_domain);
+//   for (int i=0; i<m_nb_domain; i++)
+//   {
+//     values[i]=0;
+//   }
+
+//   vector <hash_multimap<int,int> > cell_corresp;
+//   //TODO : remplacer int* par une map <int,int>
+//   //  vector<int*  > number_of_connections(m_nb_domain);
+//   //  vector<map<int,int> > number_of_connections;
+//   vector<map<int,int> > number_of_connections;
+//   cell_corresp.resize(m_nb_domain);
+//   number_of_connections.resize(m_nb_domain);
+//   //  for (int i=0; i<m_nb_domain; i++)
+//   //    {
+//   //      //    cell_corresp[i]=new multimap<int,int>;
+//   //      if (m_nb_cells[i] >0)
+//   //        {
+//   //          number_of_connections[i]=new int[m_nb_cells[idomain]];
+//   //          for (int j=0; j<m_nb_cells[idomain]; j++)
+//   //            number_of_connections[i][j]=0;
+//   //        }
+//   //    }
+
+//   const MEDMEM::MEDSKYLINEARRAY* skylinegraph = graph->getGraph();
+
+//   const int* index=skylinegraph->getIndex();
+//   const int* value=skylinegraph->getValue();
+
+//   TGlob2DomainLoc::const_iterator gl_do_lo_end = m_glob_to_loc.end();
+
+//   for (int icell=0; icell<m_nb_cells[idomain]; icell++)
+//   {
+//     int global= m_loc_to_glob[idomain][icell];
+//     for (int ii=index[global-1]-1; ii<index[global]-1; ii++)
+//     {
+//       int distant_global=value[ii];
+
+//       const pair<int,int>& local = m_glob_to_loc.find(distant_global)->second;
+
+//       if (local.first != idomain)
+//       {
+//         cell_corresp[local.first].insert(make_pair(icell+1,local.second));
+//         //              number_of_connections[local.first][icell]++;
+//         if (number_of_connections[local.first].find(icell)==number_of_connections[local.first].end())
+//           number_of_connections[local.first].insert(make_pair(icell,1));
+//         else
+//           number_of_connections[local.first][icell]++;
+
+//       }
+//     }
+//   }
+
+//   for (int inew=0; inew<m_nb_domain; inew++)
+//   {
+//     if (inew==idomain || number_of_connections[inew].empty()) continue;
+
+//     int* new_index=new int[m_nb_cells[idomain]+1];
+//     new_index[0]=1;
+//     for (int i=0; i<m_nb_cells[idomain]; i++)
+//     {
+
+//       if (number_of_connections[inew].find(i)!=number_of_connections[inew].end())
+//         new_index[i+1]=new_index[i]+number_of_connections[inew][i];
+//       else
+//         new_index[i+1]=new_index[i];
+//     }
+//     int* new_value;
+//     if (new_index[m_nb_cells[idomain]]-1 > 0)
+//       new_value=new int[new_index[m_nb_cells[idomain]]-1];
+//     else 
+//       new_value=0;
+
+//     int value_i=0;
+
+//     //      hash_multimap<int,int>::iterator iter=cell_corresp[inew].begin();
+
+//     for (int i=0; i<m_nb_cells[idomain]; i++)
+//     {
+//       //          for (int j=new_index[i];j<new_index[i+1];j++,value_i++,iter++)
+//       //            new_value[value_i]=iter->second;
+
+//       typedef hash_multimap<int,int>::iterator mmiter;
+//       pair<mmiter,mmiter> range=cell_corresp[inew].equal_range(i+1);
+//       for (mmiter it=range.first; it!=range.second; it++)
+//       {
+//         new_value[value_i]=it->second;
+//         value_i++;
+//       }
+//     }
+//     if (value_i>0)    
+//     {
+//       corr[inew] = new MEDMEM::MEDSKYLINEARRAY(m_nb_cells[idomain], new_index[m_nb_cells[idomain]]-1, new_index,new_value,true);
+//     }
+//     else 
+//     {
+//       corr[inew]=0;
+//       if (new_value !=0) delete[]new_value;
+//       delete[]new_index;
+//     }   
+
+//   }
+
+  //    for (int inew=0; inew<m_nb_domain; inew++)
+  //    if (m_nb_cells[inew]>0)
+  //      delete[] number_of_connections[inew];
+
+//}
+
+//================================================================================
+/*!
+ * \brief Return max global face number
+ */
+//================================================================================
+
+int ParallelTopology::getMaxGlobalFace() const
+{
+  int max = 0;
+  TGlob2LocsMap::const_iterator g_l_l = m_face_glob_to_loc.begin();
+  for ( ; g_l_l != m_face_glob_to_loc.end(); ++g_l_l )
+    if ( g_l_l->first > max )
+      max = g_l_l->first;
+  return max;
+}
+
+// void ParallelTopology::recreateFaceMapping(const TGeom2FacesByDomian& face_map)
+// {
+//   m_face_glob_to_loc.clear();
+//   for (int i=0; i<m_nb_domain;i++)
+//     m_face_loc_to_glob[i].clear();
+
+//   for (int idomain=0; idomain<m_nb_domain; idomain++)
+//   {
+//     int ilocal=1;
+//     TGeom2Faces::const_iterator iter = face_map[idomain].begin();
+//     for (; iter != face_map[idomain].end(); iter++)
+//     {
+//       for (int i=0; i< (iter->second).size(); i++)
+//       {
+//         MEDPARTITIONER_FaceModel* face = (iter->second)[i];
+//         //cout << "global :"<<face->getGlobal()<<" - "<<ilocal<<endl;
+//         m_face_glob_to_loc.insert(make_pair(face->getGlobal(),make_pair(idomain,ilocal)));
+//         m_face_loc_to_glob[idomain].push_back(face->getGlobal());
+//         ilocal++;
+//       }
+//     }
+//     m_nb_faces[idomain] =ilocal-1;
+//   }
+// }
+
+//================================================================================
+/*!
+ * \brief Recreating cell and node mapping after send-reveive and fusion of domain meshes
+ */
+//================================================================================
+
+// void ParallelTopology::recreateMappingAfterFusion(const vector<MEDMEM::MESH*>& meshes)
+// {
+//   const char* LOC = "ParallelTopology::recreateMappingAfterFusion(): ";
+
+//   m_glob_to_loc.clear();
+//   m_node_glob_to_loc.clear();
+//   m_face_glob_to_loc.clear();
+
+//   for (int idomain=0; idomain<m_nb_domain; idomain++)
+//   {
+//     m_nb_cells[idomain] = m_nb_nodes[idomain] = m_nb_faces[idomain] = 0;
+//     m_loc_to_glob[idomain].clear();
+//     m_node_loc_to_glob[idomain].clear();
+//     m_face_loc_to_glob[idomain].clear();
+    
+//     if ( !meshes[idomain]->getCoordinateptr() ) continue; // empty domian
+
+//     //creating cell maps
+
+//     m_nb_cells[idomain]=meshes[idomain]->getNumberOfElementsWithPoly(MED_EN::MED_CELL,
+//                                                                      MED_EN::MED_ALL_ELEMENTS);
+//     if ( m_cell_loc_to_glob_fuse[idomain].size() != m_nb_cells[idomain] )
+//       throw MED_EXCEPTION(MEDMEM::STRING(LOC)<<" invalid nb of fused cells");
+
+//     m_loc_to_glob[idomain].swap( m_cell_loc_to_glob_fuse[idomain] );
+
+//     for (int i=0; i<m_nb_cells[idomain]; i++)
+//     {
+//       int global=m_loc_to_glob[idomain][i];
+//       m_glob_to_loc[global]=make_pair(idomain,i+1);
+//     }
+
+//     //creating node maps
+
+//     m_nb_nodes[idomain]=meshes[idomain]->getNumberOfNodes();
+//     m_node_loc_to_glob[idomain] = ((MEDMEM::MeshFuse*)meshes[idomain])->getNodeNumbers();
+//     if ( m_node_loc_to_glob[idomain].size() != m_nb_nodes[idomain] )
+//       throw MED_EXCEPTION(MEDMEM::STRING(LOC)<<" invalid nb of fused nodes");
+
+//     // setting mappings for all nodes
+//     for (int inode=0; inode<m_nb_nodes[idomain]; inode++)
+//     {
+//       int global_number=m_node_loc_to_glob[idomain][inode];
+//       m_node_glob_to_loc.insert(make_pair(global_number,make_pair(idomain,inode+1)));
+//     }
+
+
+//     //creating dimension d-1 component mappings
+
+//     MED_EN::medEntityMesh constituent_entity =
+//       (m_mesh_dimension == 3 ? MED_EN::MED_FACE : MED_EN::MED_EDGE );
+//     m_nb_faces[idomain] = meshes[idomain]->getNumberOfElementsWithPoly(constituent_entity,
+//                                                                        MED_EN::MED_ALL_ELEMENTS);
+//     if ( m_face_loc_to_glob_fuse[idomain].size() != m_nb_faces[idomain] )
+//       throw MED_EXCEPTION(MEDMEM::STRING(LOC)<<" invalid nb of fused faces of domain "<< idomain
+//                           << ": expect " << m_nb_faces[idomain]
+//                           << " but have " << m_face_loc_to_glob_fuse[idomain].size());
+
+//     m_face_loc_to_glob[idomain].swap( m_face_loc_to_glob_fuse[idomain] );
+
+//     for (int iface=0; iface<m_nb_faces[idomain]; iface++)
+//     {
+//       int global_number=m_face_loc_to_glob[idomain][iface];
+//       m_face_glob_to_loc.insert(make_pair(global_number,make_pair(idomain,iface+1)));
+//     }
+//   }
+
+//}
diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.hxx b/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.hxx
new file mode 100644 (file)
index 0000000..38e04b7
--- /dev/null
@@ -0,0 +1,403 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef PARALLELTOPOLOGY_HXX_
+#define PARALLELTOPOLOGY_HXX_
+
+#include <set>
+#include <vector>
+#include <ext/hash_map>
+//#include "boost/shared_ptr.hpp"
+
+#include "MEDPARTITIONER_Topology.hxx"
+
+namespace __gnu_cxx
+{
+  template<> struct hash< pair<int,int> >
+  {
+    size_t operator()( const pair<int,int>& x ) const
+    {
+      return hash< int >()( x.first*1000000+x.second );
+    }
+  };
+}
+
+using namespace std;
+namespace MEDPARTITIONER {
+
+  class Graph;
+  class MESHCollection;
+  class MEDPARTITIONER_FaceModel;
+
+  class ParallelTopology:public Topology
+  {
+
+  public:
+
+    ParallelTopology();
+
+    ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>&,
+                     const std::vector<MEDPARTITIONER::CONNECTZONE*>&,
+                     std::vector<int*>&,
+                     std::vector<int*>&,
+                     std::vector<int*>&);
+
+    ParallelTopology(Graph* graph, int nbdomain, int mesh_dimension);
+
+    ~ParallelTopology();
+    //!converts a list of global cell numbers
+    //!to a distributed array with local cell numbers
+    void convertGlobalNodeList(const int*, int,int*,int*);
+    void convertGlobalNodeList(const int*, int,int*,int);
+    void convertGlobalNodeListWithTwins(const int* face_list, int nbnode, int*& local, int*& ip, int*& full_array, int& size);
+
+    //!converts a list of global node numbers
+    //!to a distributed array with local cell numbers
+    void convertGlobalCellList(const int*, int , int*, int *);
+
+    //!converts a list of global face numbers
+    //!to a distributed array with local face numbers
+    void convertGlobalFaceList(const int*, int , int*, int *);  
+    void convertGlobalFaceList(const int*, int , int*, int);  
+    void convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array,int& size);
+
+    //!creating node mapping 
+
+//     void createNodeMapping(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
+//                            std::map<MED_EN::medGeometryElement,int>& present_type_numbers,
+//                            std::vector<int>& conn,
+//                            std::vector<int>& conn_index,
+//                            std::vector<int>& polyhedron_conn,
+//                            std::vector<int>& polyhedron_conn_index,
+//                            std::vector<int>& polyhedron_face_index,
+//                            int idomain);
+
+    //  void createFaceMapping(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
+    //               std::map<MED_EN::medGeometryElement,int>& present_type_numbers,
+    //               int idomain);          
+
+//     void createFaceMapping(const MESHCollection &, const MESHCollection&);
+//     void createFaceMapping2ndversion(const MESHCollection &);
+
+//     //!converting node global numberings to local numberings
+//     void convertToLocal(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
+//                         std::map<MED_EN::medGeometryElement,int>& present_type_numbers,
+//                         int idomain,
+//                         MED_EN::medEntityMesh entity);
+    void convertToLocal2ndVersion(int* nodes, int nbnodes, int idomain);
+
+
+
+    //! computing arrays with node/node correspondencies
+    //    void computeNodeNodeCorrespondencies(int nbdomain,std::vector<MEDPARTITIONER::MEDSKYLINEARRAY*>& ) const;
+
+    //! computing arrays with node/node correspondencies
+    //    void computeCellCellCorrespondencies(int nbdomain,std::vector<MEDPARTITIONER::MEDSKYLINEARRAY*>&, const Graph*) const;
+
+    //! retrieving Graph
+    //  boost::shared_ptr<Graph> getGraph() const;
+
+
+    //!converting node local numbering to global
+    inline  int convertNodeToGlobal(int ip,int icell) const
+    {
+      //return m_node_loc_to_glob.find(make_pair(ip,icell))->second;
+      return m_node_loc_to_glob[ip][icell];
+    }
+
+    //!converting face local numbering to global
+    inline  int convertFaceToGlobal(int ip,int iface) const
+    {
+      //     if (m_face_loc_to_glob.find(make_pair(ip,icell))==m_face_loc_to_glob.end())
+      //       return -1;
+      //     else
+      //return m_face_loc_to_glob.find(make_pair(ip,icell))->second;
+      return m_face_loc_to_glob[ip][iface];
+    }
+
+    //converting cell global numbering to local
+    inline  int convertCellToGlobal(int ip,int icell) const
+    {
+      //     if (m_loc_to_glob.find(make_pair(ip,icell))==m_loc_to_glob.end())
+      //       return -1;
+      //     else
+      //return m_loc_to_glob.find(make_pair(ip,icell))->second;
+      return m_loc_to_glob[ip][icell];
+    }
+
+    inline  void convertNodeToGlobal(int ip, const int* local, int n, int* global)const
+    {
+      for (int i=0; i<n; i++)
+        global[i]=m_node_loc_to_glob[ip][local[i]];
+      //global[i]=m_node_loc_to_glob.find(make_pair(ip,local[i]))->second;
+    }
+
+    inline  void convertCellToGlobal(int ip, const int* local, int n, int* global)const
+    {
+      for (int i=0; i<n; i++)
+        global[i]=m_loc_to_glob[ip][local[i]];  
+      //global[i]=m_loc_to_glob.find(make_pair(ip,local[i]))->second;
+    }
+
+    inline  void convertFaceToGlobal(int ip, const int* local, int n, int* global)const
+    {
+      for (int i=0; i<n; i++)
+      {
+        global[i]=m_face_loc_to_glob[ip][local[i]];
+        //          if (m_face_loc_to_glob.find(make_pair(ip,local[i]))==m_face_loc_to_glob.end())
+        //            {
+        //              cout << "problem : face # "<< local[i] << " of processor "<< ip<< " was not found in mapping loc2glob"<<endl; 
+        //              global[i]=-1;
+        //            }
+        //          else
+        //            global[i]=m_face_loc_to_glob.find(make_pair(ip,local[i]))->second;
+      }
+    }
+
+    inline  int nbDomain() const
+    {
+      return m_nb_domain;
+    }
+
+    int nbCells() const
+    {
+      return m_nb_total_cells;
+    }
+    int nbNodes() const
+    {return m_nb_total_nodes;}
+
+    inline  int nbCells( int idomain) const
+    {
+      return m_nb_cells[idomain];
+    }
+
+
+
+
+    //!retrieving number of nodes
+    inline  int getNodeNumber(int idomain) const
+    {
+      return m_nb_nodes[idomain];
+    }
+
+    inline  int getNodeNumber() const
+    {
+      if (m_node_glob_to_loc.empty()) return 0;
+      set <int> keys;
+      for (__gnu_cxx::hash_multimap<int, pair<int,int> >::const_iterator iter= m_node_glob_to_loc.begin();
+           iter!=m_node_glob_to_loc.end();
+           iter++) {
+        keys.insert(iter->first);
+      }
+      return keys.size();
+    }
+
+    //!retrieving list of nodes in global numbers
+    inline  void getNodeList(int idomain, int* list) const
+    {
+      for (int i=0; i<m_nb_nodes[idomain];i++)
+      {
+        list[i]=m_node_loc_to_glob[idomain][i];
+        //list[i]=(m_node_loc_to_glob.find(make_pair(idomain,i+1)))->second;
+      }
+    }
+
+    //!< retrieving cell numbers after fusing in parallel mode
+    std::vector<int> & getFusedCellNumbers(int idomain)
+    {
+      return m_cell_loc_to_glob_fuse[idomain];
+    }
+    const std::vector<int> & getFusedCellNumbers(int idomain) const
+    {
+      return m_cell_loc_to_glob_fuse[idomain];
+    }
+
+    //!< retrieving face numbers after fusing in parallel mode
+    std::vector<int> & getFusedFaceNumbers(int idomain)
+    {
+      return m_face_loc_to_glob_fuse[idomain];
+    }
+    const std::vector<int> & getFusedFaceNumbers(int idomain) const
+    {
+      return m_face_loc_to_glob_fuse[idomain];
+    }
+
+
+    //!retrieving number of nodes
+    inline  int getCellNumber(int idomain) const
+    {
+      return m_nb_cells[idomain];
+    }
+
+    inline  int getCellDomainNumber(int global) const
+    {
+      return (m_glob_to_loc.find(global)->second).first;
+    }
+
+    //!retrieving list of nodes in global numbers
+    inline  void getCellList(int idomain, int* list) const
+    {
+      for (int i=0; i<m_nb_cells[idomain];i++)
+      {
+        list[i]=m_loc_to_glob[idomain][i];
+        //list[i]=(m_loc_to_glob.find(make_pair(idomain,i+1)))->second;
+      }
+
+    }
+
+    inline int getFaceNumber(int idomain) const
+    {
+      return m_nb_faces[idomain];
+    }
+
+    inline  int getFaceNumber() const
+    {
+      if (m_face_glob_to_loc.empty()) return 0;
+      set <int> keys;
+      for (__gnu_cxx::hash_multimap<int, pair<int,int> >::const_iterator iter= m_face_glob_to_loc.begin();
+           iter!=m_face_glob_to_loc.end();
+           iter++) {
+        keys.insert(iter->first);
+      }
+      return keys.size();
+    }
+
+
+    //!retrieving list of faces in global numbers
+    inline  void getFaceList(int idomain, int* list) const
+    {
+      for (int i=0; i<m_nb_faces[idomain];i++)
+      {
+        list[i]=m_face_loc_to_glob[idomain][i];
+        //list[i]=(m_face_loc_to_glob.find(make_pair(idomain,i+1)))->second;
+      }
+
+    }
+
+    //! converting a global cell number to a local representation (domain + local number)
+    inline std::pair<int,int> convertGlobalCell(int iglobal) const
+    {
+      return m_glob_to_loc.find(iglobal)->second;
+    }
+
+    inline int convertGlobalFace(int iglobal, int idomain)
+    {
+      typedef __gnu_cxx::hash_multimap<int, pair<int,int> >::const_iterator MMiter;
+      std::pair<MMiter,MMiter> eq = m_face_glob_to_loc.equal_range(iglobal);
+      for (MMiter it=eq.first; it != eq.second; it++)
+      {
+        //        SCRUTE_MED (it->second.first);
+        //SCRUTE_MED (idomain);
+        if (it->second.first == idomain) return it->second.second;
+
+      }
+      return -1;
+    }
+
+    inline int convertGlobalNode(int iglobal, int idomain)
+    {
+      typedef __gnu_cxx::hash_multimap<int, pair<int,int> >::const_iterator MMiter;
+      pair<MMiter,MMiter> eq = m_node_glob_to_loc.equal_range(iglobal);
+      for (MMiter it=eq.first; it != eq.second; it++)
+      {
+        if (it->second.first == idomain) return it->second.second;
+      }
+      return -1;
+    }
+    //!adding a face to the topology
+    inline void appendFace(int idomain, int ilocal, int iglobal)
+    {
+      m_face_loc_to_glob[idomain].push_back(iglobal);
+      m_face_glob_to_loc.insert(make_pair(iglobal,make_pair(idomain,ilocal)));
+    }
+
+    //return max global face number
+    int getMaxGlobalFace() const;
+
+
+    //!recreating a face mapping from scratch
+    //    void recreateFaceMapping(const TGeom2FacesByDomain& face_map);
+
+    // recreating cell and node mapping after send-reveive and fusion of domain meshes
+    //    virtual void recreateMappingAfterFusion(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& );
+
+
+
+  private:
+
+    bool hasCellWithNodes( const MESHCollection&, int dom, const std::set<int>& nodes );
+
+
+  private:
+    //!mapping global -> local
+    typedef __gnu_cxx::hash_map<int,std::pair<int,int> > TGlob2DomainLoc;
+    TGlob2DomainLoc m_glob_to_loc;
+
+    //  bool is_equal_pair (pair<int,int> a, pair<int,int> b){
+    //      return  (a.first==b.first && a.second==b.second);
+    // }
+    //!mapping local -> global
+    //map<pair<int,int>,int> m_loc_to_glob;
+
+    //
+    //__gnu_cxx::hash_map<pair<int,int>,int, __gnu_cxx::hash<pair<int,int> > > m_loc_to_glob;
+    std::vector<std::vector<int> >  m_loc_to_glob;
+    //!mapping global -> local
+    __gnu_cxx::hash_multimap<int,std::pair<int,int> > m_node_glob_to_loc;
+
+    //!mapping local -> global
+    //  map<pair<int,int>,int> m_node_loc_to_glob;
+    //__gnu_cxx::hash_map<pair<int,int>,int, __gnu_cxx::hash<pair<int,int> > > m_node_loc_to_glob;
+    std::vector<std::vector <int> > m_node_loc_to_glob;
+
+    // global numbers in parallel mode
+    std::vector<std::vector <int> > m_cell_loc_to_glob_fuse; // glob nums after fusing
+    std::vector<std::vector <int> > m_face_loc_to_glob_fuse; // glob nums after fusing
+
+
+    //!mapping global -> local
+    typedef __gnu_cxx::hash_multimap<int,std::pair<int,int> > TGlob2LocsMap;
+    TGlob2LocsMap m_face_glob_to_loc;
+
+    //!mapping local -> global
+    //__gnu_cxx::hash_map<pair<int,int>,int, __gnu_cxx::hash<pair<int,int> > > m_face_loc_to_glob;
+    std::vector<std::vector <int> > m_face_loc_to_glob;
+
+    //map<pair<int,int>,int> m_face_loc_to_glob;
+
+    std::vector<int> m_nb_cells;
+
+    std::vector<int> m_nb_nodes;
+
+    std::vector<int> m_nb_faces;
+
+    int m_nb_total_cells;
+
+    int m_nb_total_nodes;
+
+    int m_nb_total_faces;
+
+    int m_nb_domain;
+
+    int m_mesh_dimension;
+
+  };
+
+
+}
+#endif /*PARALLELTOPOLOGY_HXX_*/
diff --git a/src/MEDPartitioner/MEDPARTITIONER_SCOTCHGraph.cxx b/src/MEDPartitioner/MEDPARTITIONER_SCOTCHGraph.cxx
new file mode 100644 (file)
index 0000000..9c6abb7
--- /dev/null
@@ -0,0 +1,105 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include <cstdio>
+extern "C" {
+#define restrict
+#include "bin/scotch.h"
+}
+#include "MEDPARTITIONER_Graph.hxx"
+#include "MEDPARTITIONER_SCOTCHGraph.hxx"
+
+using namespace MEDPARTITIONER;
+  
+SCOTCHGraph::SCOTCHGraph():Graph()
+{
+}
+
+SCOTCHGraph::SCOTCHGraph(MEDPARTITIONER::MEDSKYLINEARRAY* graph, int* edgeweight):Graph(graph,edgeweight)
+{
+}
+
+SCOTCHGraph::~SCOTCHGraph()
+{
+}
+
+void SCOTCHGraph::partGraph(int ndomain, const std::string& options_string, ParaDomainSelector* sel)
+{
+  // number of graph vertices
+  int n = m_graph->getNumberOf();
+
+  //graph
+  int * xadj=const_cast<int*>(m_graph->getIndex());
+  int * adjncy = const_cast<int*>(m_graph->getValue());
+
+  //ndomain
+  int nparts = ndomain;
+
+  // output parameters
+  int* partition = new int[n+1];
+
+  SCOTCH_Graph scotch_graph;
+
+  SCOTCH_graphInit(&scotch_graph);
+
+
+  SCOTCH_graphBuild(&scotch_graph,
+                    1, //premier indice 1
+                    n, // nb of graph nodes
+                    xadj,
+                    0,
+                    m_cellweight, //graph vertices loads
+                    0,
+                    xadj[n], // number of edges
+                    adjncy,
+                    m_edgeweight);
+
+  SCOTCH_Strat scotch_strategy;           
+  SCOTCH_stratInit(&scotch_strategy);
+
+  //!user-defined options for the strategy
+  if (options_string!="")
+    SCOTCH_stratGraphMap(&scotch_strategy,options_string.c_str());
+
+
+  if (nparts>1)           
+    SCOTCH_graphPart(&scotch_graph,nparts,&scotch_strategy,partition);
+  else
+    // partition for 1 subdomain
+    for (int i=0; i<n+1; i++)
+      partition[i]=0;
+
+  SCOTCH_stratExit(&scotch_strategy);
+  SCOTCH_graphExit(&scotch_graph);
+
+    std::vector<int> index(n+1);
+  std::vector<int> value(n);
+  index[0]=0;
+  for (int i=0; i<n; i++)
+  {
+    index[i+1]=index[i]+1;
+    value[i]=partition[i];
+  }
+
+  //creating a skylinearray with no copy of the index and partition array
+  // the fifth argument true specifies that only the pointers are passed 
+  //to the object
+  
+  m_partition = new MEDPARTITIONER::MEDSKYLINEARRAY(index,value);
+
+}
diff --git a/src/MEDPartitioner/MEDPARTITIONER_SCOTCHGraph.hxx b/src/MEDPartitioner/MEDPARTITIONER_SCOTCHGraph.hxx
new file mode 100644 (file)
index 0000000..008bc69
--- /dev/null
@@ -0,0 +1,38 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef MEDPARTITIONER_SCOTCHGRAPH_HXX_
+#define MEDPARTITIONER_SCOTCHGRAPH_HXX_
+
+#include "MEDPARTITIONER.hxx"
+#include <string>
+
+namespace MEDPARTITIONER {
+  class MEDSKYLINEARRAY;
+  class MEDPARTITIONER_EXPORT SCOTCHGraph:public Graph
+  {
+  public:
+    SCOTCHGraph();
+    SCOTCHGraph(MEDPARTITIONER::MEDSKYLINEARRAY*, int* edgeweight=0);
+    virtual ~SCOTCHGraph();
+    void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector* sel=0);
+    //private:
+    //  const MEDMEM::MEDSKYLINEARRAY* m_graph;
+  };
+}
+#endif /*SCOTCHGRAPH_HXX_*/
diff --git a/src/MEDPartitioner/MEDPARTITIONER_SequentialTopology.cxx b/src/MEDPartitioner/MEDPARTITIONER_SequentialTopology.cxx
new file mode 100644 (file)
index 0000000..3076ae4
--- /dev/null
@@ -0,0 +1,82 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "MEDMEM_SkyLineArray.hxx"
+#include "MEDMEM_ConnectZone.hxx"
+#include "MEDMEM_DriversDef.hxx"
+#include "MEDMEM_Mesh.hxx"
+#include "MEDMEM_Exception.hxx"
+
+#include "MEDPARTITIONER_Topology.hxx"
+#include "MEDPARTITIONER_SequentialTopology.hxx"
+
+using namespace MEDPARTITIONER;
+  
+SequentialTopology::SequentialTopology(){throw MEDEXCEPTION("SequentialTopology - not implemented yet");}
+
+SequentialTopology::SequentialTopology(std::vector<MEDMEM::MESH*>, std::vector<MEDMEM::CONNECTZONE*>){throw MEDEXCEPTION("SequentialTopology - not implemented yet");}
+
+//!converts a list of global cell numbers
+//!to a distributed array with local cell numbers
+void SequentialTopology::convertGlobalNodeList(const int*, int,int*,int*){}
+
+//!converts a list of global node numbers
+//!to a distributed array with local cell numbers
+void SequentialTopology::convertGlobalCellList(const int*, int , int*, int *){}
+
+//number of doamins
+int SequentialTopology::nbDomain() const
+{
+  return 0;
+}
+
+//number of cells
+int SequentialTopology::nbCells() const
+{
+  return 0;
+}
+
+//number of cells on a specific domain
+int SequentialTopology::nbCells(int idomain) const
+{
+  return 0;
+}
+
+//!creating node mapping 
+void SequentialTopology::createNodeMapping(vector<int*> type_connectivity,int* present_type_numbers, int idomain){}
+
+//!converting node global numberings to local numberings
+void SequentialTopology::convertToLocal(vector<int*> type_connectivity,int* present_type_numbers){}
+
+//!retrieving number of nodes
+int SequentialTopology::getNodeNumber(int idomain) const
+{
+  return 0;
+}
+
+//!retrieving list of nodes
+void SequentialTopology::getNodeList(int idomain, int* list) const{}
+
+//!retrieving number of cells
+int SequentialTopology::getCellNumber(int idomain) const
+{
+  return 0;
+}
+
+//!retrieving list of cells
+void SequentialTopology::getCellList(int idomain, int* list) const{}
diff --git a/src/MEDPartitioner/MEDPARTITIONER_SequentialTopology.hxx b/src/MEDPartitioner/MEDPARTITIONER_SequentialTopology.hxx
new file mode 100644 (file)
index 0000000..765819b
--- /dev/null
@@ -0,0 +1,90 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef SequentialTOPOLOGY_HXX_
+#define SequentialTOPOLOGY_HXX_
+
+#include "MEDPARTITIONER.hxx"
+
+namespace MEDPARTITIONER {
+  class SequentialTopology:public Topology
+  {
+
+  public:
+
+    SequentialTopology();
+    SequentialTopology(std::vector<ParaMEDMEM::MEDCouplingUMesh*>, std::vector<MEDPARTITIONER::CONNECTZONE*>);
+
+    //!converts a list of global cell numbers
+    //!to a distributed array with local cell numbers
+    void convertGlobalNodeList(const int*, int,int*,int*);
+
+    //!converts a list of global node numbers
+    //!to a distributed array with local cell numbers
+    void convertGlobalCellList(const int*, int , int*, int *);
+
+    //number of doamins
+    int nbDomain() const;
+
+    //number of cells
+    int nbCells() const;
+
+    //number of cells on a specific domain
+    int nbCells(int idomain) const;
+
+    //!creating node mapping 
+    void createNodeMapping(vector<int*> type_connectivity,int* present_type_numbers, int idomain);
+
+    //!converting node global numberings to local numberings
+    void convertToLocal(vector<int*> type_connectivity,int* present_type_numbers);
+
+    //!retrieving number of nodes
+    int getNodeNumber(int idomain) const ;
+
+    //!retrieving list of nodes
+    void getNodeList(int idomain, int* list) const;
+
+    //!retrieving number of cells
+    int getCellNumber(int idomain) const ;
+
+    //!retrieving list of cells
+    void getCellList(int idomain, int* list) const;
+
+  private:
+    //!mapping global -> local
+    map<int,pair<int,int> > m_glob_to_loc;
+
+    //!mapping local -> global
+    map<pair<int,int>,int> m_loc_to_glob;
+
+    //!mapping global -> local
+    multimap<int,pair<int,int> > m_node_glob_to_loc;
+
+    //!mapping local -> global
+    map<pair<int,int>,int> m_node_loc_to_glob;
+
+    vector<int> m_nb_cells;
+
+    vector<int> m_nb_nodes;
+
+    int m_nb_total_cells;
+
+    int m_nb_total_nodes;
+  };
+}
+#endif /*SequentialTOPOLOGY_HXX_*/
diff --git a/src/MEDPartitioner/MEDPARTITIONER_SkyLineArray.cxx b/src/MEDPartitioner/MEDPARTITIONER_SkyLineArray.cxx
new file mode 100644 (file)
index 0000000..20cfd4c
--- /dev/null
@@ -0,0 +1,56 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "MEDPARTITIONER_SkyLineArray.hxx"
+#include "MEDMEM_Utilities.hxx"
+#include <vector>
+
+
+using namespace MEDPARTITIONER;
+
+MEDSKYLINEARRAY::MEDSKYLINEARRAY()
+{
+  MESSAGE_MED("Constructeur MEDSKYLINEARRAY sans parametre");
+}
+
+MEDSKYLINEARRAY::MEDSKYLINEARRAY(const MEDSKYLINEARRAY &myArray)
+{
+  _index=myArray._index;
+  _value=myArray._value;
+}
+
+MEDSKYLINEARRAY::~MEDSKYLINEARRAY()
+{
+  MESSAGE_MED("Destructeur ~MEDSKYLINEARRAY");
+
+  //if (_index != NULL) delete [] _index;
+  //if (_value != NULL) delete [] _value;
+}
+
+
+MEDSKYLINEARRAY::MEDSKYLINEARRAY(const std::vector<int>& index, const std::vector<int>& value)
+{
+  _value=value;
+  _index=index;
+}
+
+
diff --git a/src/MEDPartitioner/MEDPARTITIONER_SkyLineArray.hxx b/src/MEDPartitioner/MEDPARTITIONER_SkyLineArray.hxx
new file mode 100644 (file)
index 0000000..21d6fff
--- /dev/null
@@ -0,0 +1,83 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+# ifndef __MEDPARTITIONER_MEDSKYLINEARRAY_H__
+# define __MEDPARTITIONER_MEDSKYLINEARRAY_H__
+
+#include "MEDPARTITIONER.hxx"
+
+#include <vector>
+
+namespace MEDPARTITIONER {
+class MEDPARTITIONER_EXPORT MEDSKYLINEARRAY
+{
+private :
+  std::vector<int> _index;
+  std::vector<int> _value;
+
+public :
+  // Attention, avec ce constructeur, il n'est possible de remplir le MEDSKYLINEARRAY 
+  MEDSKYLINEARRAY();
+
+  // Constructeur par recopie
+  MEDSKYLINEARRAY( const MEDSKYLINEARRAY &myArray );
+
+  // Avec ce constructeur la mémoire pour le tableau  de valeur et le
+  // tableau d'index est réservée. Il suffit d'effectuer les séquences
+  // d'appels suivantes pour initialiser le MEDSKYLINEARRAY
+  // 1) setIndex(index) puis <count> fois setI(i,&listValeurN°I) avec i dans 1..count
+  //    rem :   listValeurN°I est dupliquée
+  // 2) appeler <length> fois setIJ(i,j,valeur) avec i dans 1..count et avec j dans 1..count
+  MEDSKYLINEARRAY( const std::vector<int>& index, const std::vector<int>& value );
+
+
+  ~MEDSKYLINEARRAY();
+  //void setMEDSKYLINEARRAY( const int count, const int length, int* index , int* value ) ;
+
+  inline int  getNumberOf()       const;
+  inline int  getLength()         const;
+  inline const int*  getIndex()   const;
+  inline const int*  getValue()   const;
+};
+
+// ---------------------------------------
+//              Methodes Inline
+// ---------------------------------------
+inline int MEDSKYLINEARRAY::getNumberOf() const
+{
+  return _index.size()-1;
+}
+inline int MEDSKYLINEARRAY::getLength() const
+{
+  return _value.size() ;
+}
+inline const int*  MEDSKYLINEARRAY::getIndex() const
+{
+  return (const int*)(&_index[0]) ;
+} 
+inline const int*  MEDSKYLINEARRAY::getValue() const
+{
+  return (const int*)(&_value[0]) ;
+} 
+}
+# endif
diff --git a/src/MEDPartitioner/MEDPARTITIONER_Topology.hxx b/src/MEDPartitioner/MEDPARTITIONER_Topology.hxx
new file mode 100644 (file)
index 0000000..a38bdda
--- /dev/null
@@ -0,0 +1,173 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef MEDPARTITIONER_TOPOLOGY_HXX_
+#define MEDPARTITIONER_TOPOLOGY_HXX_
+
+//#include "MEDMEM_define.hxx"
+
+//#include "boost/shared_ptr.hpp"
+
+#include <map>
+#include <vector>
+
+namespace MEDPARTITIONER
+{
+  class CONNECTZONE;
+  class MEDSKYLINEARRAY;
+}
+namespace ParaMEDMEM {
+  class MEDCouplingUMesh;
+}
+
+namespace MEDPARTITIONER {
+
+  class Graph;
+  class MESHCollection;
+  class MEDPARTITIONER_FaceModel;
+  
+  //  typedef std::map<MED_EN::medGeometryElement, std::vector<MEDPARTITIONER_FaceModel*> > TGeom2Faces;
+  //  typedef std::vector< TGeom2Faces > TGeom2FacesByDomain;
+  
+  class Topology
+  {
+  public:
+    Topology(){}
+    Topology(std::vector<ParaMEDMEM::MEDCouplingUMesh*>, std::vector<MEDPARTITIONER::CONNECTZONE*>){}
+    
+    virtual ~Topology(){}
+    
+    //!converts a list of global cell numbers
+    //!to a distributed array with local cell numbers
+    virtual void convertGlobalNodeList(const int* list, int nb, int* local, int*ip)=0;
+    virtual void convertGlobalNodeList(const int* list, int nb, int* local, int ip)=0;
+    //!converts a list of global node numbers
+    //!to a distributed array with local cell numbers
+    virtual void convertGlobalCellList(const int*list , int nb, int* local, int*ip)=0;
+    
+    //!converts a list of global face numbers
+    //!to a distributed array with local face numbers
+    virtual void convertGlobalFaceList(const int*list , int nb, int* local, int*ip)=0;
+    virtual void convertGlobalFaceList(const int*list , int nb, int* local, int ip)=0;
+    virtual void convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array, int& size)=0;
+    virtual void convertGlobalNodeListWithTwins(const int* face_list, int nbnode, int*& local, int*& ip, int*& full_array, int& size)=0;
+    
+
+    //number of doamins
+    virtual int nbDomain() const =0;
+    
+    //number of cells
+    virtual int nbCells() const=0;
+
+    //number of nodes
+    virtual int nbNodes() const=0;
+    
+    //number of cells on a specific domain
+    virtual int nbCells(int idomain) const=0;
+    
+    //   ////creating node mapping 
+    //     virtual void createNodeMapping(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
+    //                                    std::map<MED_EN::medGeometryElement,int>& present_type_numbers,
+    //                                    std::vector<int>& polygon_conn,
+//                                    std::vector<int>& polygon_conn_index,
+//                                    std::vector<int>& polyhedron_conn,
+//                                    std::vector<int>& polyhedron_conn_index,
+//                                    std::vector<int>& polyhedron_face_index,
+//                                    int domain)=0;
+    
+    ////creating face mapping 
+    //  virtual void createFaceMapping(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
+    //                    std::map<MED_EN::medGeometryElement,int>& present_type_numbers,int domain)=0;
+    //      
+    //    virtual void createFaceMapping(const MESHCollection&,const MESHCollection&)=0;
+    
+    //   //converting node global numberings to local numberings
+    //     virtual void convertToLocal(std::map<MED_EN::medGeometryElement,int*>& type_connectivity,
+    //                                 std::map<MED_EN::medGeometryElement,int>& present_type_numbers,
+    //                                 int idomain,
+    //                                 MED_EN::medEntityMesh entity)=0;
+    //converting node global numberings to local numberings
+    virtual void convertToLocal2ndVersion(int*,int,int)=0;
+    
+    virtual int convertNodeToGlobal(int ip,int icell)const=0;
+    virtual int convertFaceToGlobal(int ip,int icell)const=0;
+    virtual int convertCellToGlobal(int ip,int icell)const=0;
+    
+    virtual void convertNodeToGlobal(int ip,const int* local, int n, int* global)const=0 ;
+    virtual void convertCellToGlobal(int ip,const int* local, int n, int* global)const=0 ;
+    virtual void convertFaceToGlobal(int ip,const int* local, int n, int* global)const=0 ;
+    
+    //retrieving number of nodes
+    virtual int getNodeNumber(int idomain) const =0;
+    virtual int getNodeNumber() const=0;
+    //retrieving list of nodes
+    virtual void getNodeList(int idomain, int* list) const =0;
+    
+    virtual std::vector<int> & getFusedCellNumbers(int idomain) = 0;
+    virtual const std::vector<int> & getFusedCellNumbers(int idomain) const = 0;
+    
+    virtual std::vector<int> & getFusedFaceNumbers(int idomain) = 0;
+    virtual const std::vector<int> & getFusedFaceNumbers(int idomain) const = 0;
+    
+    //retrieving number of nodes
+    virtual int getCellNumber(int idomain) const =0;
+    
+    //retrieving list of nodes
+    virtual void getCellList(int idomain, int* list) const =0;
+    
+    //retrieving number of faces
+    virtual int getFaceNumber(int idomain) const =0;
+    virtual int getFaceNumber()const =0;
+    
+    //retrieving list of nodes
+    virtual void getFaceList(int idomain, int* list) const =0;
+    
+    //adding a face to the mapping
+    virtual void appendFace(int idomain, int ilocal, int iglobal)=0;
+    
+    //return max global face number
+    virtual int getMaxGlobalFace()const=0;
+    
+    //return next free global face number
+    //virtual int nextGlobalFace(int start_num) const=0;
+    
+    //!converting a global cell number to a local representation
+    virtual std::pair<int,int> convertGlobalCell(int iglobal) const =0;
+    
+    //converting a global face number to a local representation
+    virtual int convertGlobalFace(int iglobal, int idomain)=0;
+    
+    //converting a global node number to a local representation
+    virtual int convertGlobalNode(int iglobal, int idomain)=0;
+    
+    //! computing arrays with node/node correspondencies
+    //    virtual void computeNodeNodeCorrespondencies(int nbdomain, std::vector<MEDPARTITIONER::MEDSKYLINEARRAY*>&) const =0;
+    
+    //! computing arrays with cell/cell correspondencies
+    //    virtual void computeCellCellCorrespondencies(int nbdomain, std::vector<MEDPARTITIONER::MEDSKYLINEARRAY*>&, const Graph*) const =0;
+    
+    
+    //!recreating a face mapping from scratch
+    //    virtual void recreateFaceMapping(const TGeom2FacesByDomain& )=0;
+
+    //!recreating cell and node mapping after send-reveive and fusion of domain meshes
+    //    virtual void recreateMappingAfterFusion(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& ) = 0;
+  };
+}
+
+#endif /*TOPOLOGY_HXX_*/
diff --git a/src/MEDPartitioner/MEDPARTITIONER_UserGraph.cxx b/src/MEDPartitioner/MEDPARTITIONER_UserGraph.cxx
new file mode 100644 (file)
index 0000000..9cbaead
--- /dev/null
@@ -0,0 +1,54 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "MEDPARTITIONER_Graph.hxx"
+#include "MEDPARTITIONER_UserGraph.hxx"
+#include <iostream>
+#include <vector>
+using namespace MEDPARTITIONER;
+
+/*! constructor that allows to specify the desired partition
+ * \param partition as table giving the domain number for each cell 
+ *        (domain numbers range from 0 to ndomain-1
+ * \param n number of cells in the mesh
+ */
+UserGraph::UserGraph(MEDPARTITIONER::MEDSKYLINEARRAY* array, const int* partition, int n):Graph(array,0)
+{
+
+  std::vector<int> index(n+1),value(n);
+
+  index[0]=0;
+  for (int i=0; i<n; i++)
+  {
+    index[i+1]=index[i]+1;
+    value[i]=partition[i];
+  }
+
+  m_partition = new MEDPARTITIONER::MEDSKYLINEARRAY(index,value);
+
+}
+
+UserGraph::~UserGraph()
+{
+}
+
+void UserGraph::partGraph(int ndomain, const std::string& options, ParaDomainSelector* sel)
+{
+  std::cerr<<"MEDPARTITIONER::UserGraph::partGraph() should not have to be used"<<std::endl;
+}
+
diff --git a/src/MEDPartitioner/MEDPARTITIONER_UserGraph.hxx b/src/MEDPartitioner/MEDPARTITIONER_UserGraph.hxx
new file mode 100644 (file)
index 0000000..0eb26a8
--- /dev/null
@@ -0,0 +1,38 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef MEDPARTITIONER_USERGRAPH_HXX_
+#define MEDPARTITIONER_USERGRAPH_HXX_
+
+#include "MEDPARTITIONER.hxx"
+#include "MEDPARTITIONER_Graph.hxx"
+#include <string>
+namespace MEDPARTITIONER
+{
+  class MEDSKYLINEARRAY;
+  class ParaDomainSelector;
+  class MEDPARTITIONER_EXPORT UserGraph : public Graph
+  {
+  public:
+    UserGraph(MEDPARTITIONER::MEDSKYLINEARRAY*, const int*, int);
+    virtual ~UserGraph();
+    void partGraph(int, const std::string& options=std::string(""), ParaDomainSelector* sel=0);
+  };
+}
+
+#endif /*MEDPARTITIONER_USERGRAPH_HXX_*/
diff --git a/src/MEDPartitioner/MEDPARTITIONER_utils.hxx b/src/MEDPartitioner/MEDPARTITIONER_utils.hxx
new file mode 100644 (file)
index 0000000..1bb7d30
--- /dev/null
@@ -0,0 +1,32 @@
+//  Copyright (C) 2007-2010  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef MEDPARTITIONER_UTILS_HXX_
+#define MEDPARTITIONER_UTILS_HXX_
+
+#include <string>
+
+namespace MEDPARTITIONER {
+  std::string trim(std::string& s,const std::string& drop = " ")
+  {
+    std::string r=s.erase(s.find_last_not_of(drop)+1);
+    return r.erase(0,r.find_first_not_of(drop));
+  }
+
+}
+#endif /*MEDPARTITIONER_UTILS_HXX_*/
diff --git a/src/MEDPartitioner/Makefile.am b/src/MEDPartitioner/Makefile.am
new file mode 100644 (file)
index 0000000..8f47d93
--- /dev/null
@@ -0,0 +1,130 @@
+  #  Copyright (C) 2007-2010  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.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+#  MED MEDMEM : MED files in memory
+#
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# this directory must be recompiled before Test folder
+
+if CPPUNIT_IS_OK
+ SUBDIRS=. 
+endif
+
+lib_LTLIBRARIES= libmedsplitter.la
+
+salomeinclude_HEADERS= \
+MEDPARTITIONER_Topology.hxx \
+MEDPARTITIONER_MESHCollection.hxx \
+MEDPARTITIONER_MESHCollectionDriver.H \
+MEDPARTITIONER_MESHCollectionMedXMLDriver.H \
+MEDPARTITIONER_MESHCollectionMedAsciiDriver.H \
+MEDPARTITIONER_MESHCollectionDriver.hxx \
+MEDPARTITIONER_MESHCollectionMedXMLDriver.hxx \
+MEDPARTITIONER_MESHCollectionMedAsciiDriver.hxx \
+MEDPARTITIONER_ParallelTopology.hxx \
+MEDPARTITIONER_FaceModel.hxx \
+MEDPARTITIONER_Graph.hxx\
+MEDPARTITIONER_UserGraph.hxx\
+MEDPARTITIONER_SequentialTopology.hxx \
+MEDPARTITIONER_utils.hxx \
+MEDPARTITIONER.hxx \
+MEDPARTITIONER_ParaDomainSelector.hxx \
+MEDPARTITIONER_ConnectZone.hxx \
+MEDPARTITIONER_SkyLineArray.hxx
+
+if MED_ENABLE_METIS
+    salomeinclude_HEADERS+= MEDPARTITIONER_METISGraph.hxx
+endif
+if MED_ENABLE_SCOTCH
+    salomeinclude_HEADERS+= MEDPARTITIONER_SCOTCHGraph.hxx
+endif
+
+dist_libmedsplitter_la_SOURCES= \
+MEDPARTITIONER_MESHCollection.cxx \
+MEDPARTITIONER_MESHCollectionDriver.cxx \
+MEDPARTITIONER_MESHCollectionMedXMLDriver.cxx \
+MEDPARTITIONER_MESHCollectionMedAsciiDriver.cxx \
+MEDPARTITIONER_ParallelTopology.cxx \
+MEDPARTITIONER_Graph.cxx\
+MEDPARTITIONER_UserGraph.cxx\
+MEDPARTITIONER_ParaDomainSelector.cxx \
+MEDPARTITIONER_JointExchangeData.cxx \
+MEDPARTITIONER_SkyLineArray.cxx \
+MEDPARTITIONER_ConnectZone.cxx
+
+if MED_ENABLE_METIS
+    dist_libmedsplitter_la_SOURCES+= MEDPARTITIONER_METISGraph.cxx
+endif
+if MED_ENABLE_SCOTCH
+    dist_libmedsplitter_la_SOURCES+= MEDPARTITIONER_SCOTCHGraph.cxx
+endif
+
+libmedsplitter_la_CPPFLAGS= $(MPI_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \
+       $(BOOST_CPPFLAGS) $(LIBXML_INCLUDES) \
+       -I$(srcdir)/../MEDMEM -I$(srcdir)/../MEDWrapper/V2_1/Core \
+       -I$(srcdir)/../INTERP_KERNEL/Bases -I$(srcdir)/../MEDCoupling \
+  -I$(srcdir)/../MEDLoader
+
+libmedsplitter_la_LDFLAGS= 
+#libmedsplitter_la_LDFLAGS= $(MED2_LIBS) $(HDF5_LIBS) $(STDLIB) $(LIBXML_LIBS) \
+#      ../MEDMEM/libmedmem.la ../MEDWrapper/V2_1/Core/libmed_V2_1.la
+
+if MED_ENABLE_PARMETIS
+  libmedsplitter_la_CPPFLAGS+= $(PARMETIS_CPPFLAGS)
+  libmedsplitter_la_LDFLAGS+= $(PARMETIS_LIBS)
+endif
+if MED_ENABLE_METIS
+  libmedsplitter_la_CPPFLAGS+= $(METIS_CPPFLAGS)
+  libmedsplitter_la_LDFLAGS+= $(METIS_LIBS)
+endif
+if MED_ENABLE_SCOTCH
+  libmedsplitter_la_CPPFLAGS+= $(SCOTCH_CPPFLAGS)
+  libmedsplitter_la_LDFLAGS+= $(SCOTCH_LIBS)
+endif
+if MED_ENABLE_KERNEL
+  libmedsplitter_la_CPPFLAGS+= ${KERNEL_CXXFLAGS}
+  libmedsplitter_la_LDFLAGS+= ${KERNEL_LDFLAGS} -lSALOMELocalTrace 
+endif
+
+libmedsplitter_la_LDFLAGS+= $(MED2_LIBS) $(HDF5_LIBS) $(STDLIB) $(LIBXML_LIBS) $(MPI_LIBS) \
+       ../MEDMEM/libmedmem.la  ../INTERP_KERNEL/libinterpkernel.la ../MEDCoupling/libmedcoupling.la ../MEDLoader/libmedloader.la 
+
+# Executables targets
+bin_PROGRAMS= medsplitter
+
+dist_medsplitter_SOURCES= medsplitter.cxx
+
+medsplitter_CPPFLAGS= $(libmedsplitter_la_CPPFLAGS)
+medsplitter_LDADD= $(libmedsplitter_la_LDFLAGS) -lm $(BOOST_LIBS) libmedsplitter.la
+if MED_ENABLE_KERNEL
+  medsplitter_LDADD+= -lSALOMEBasics
+endif
+
+if MPI_IS_OK
+  bin_PROGRAMS+=medsplitter_para
+  dist_medsplitter_para_SOURCES= medsplitter_para.cxx
+  medsplitter_para_CPPFLAGS= $(medsplitter_CPPFLAGS)
+  medsplitter_para_LDADD= $(medsplitter_LDADD)
+endif
+
+OBSOLETE_FILES = \
+       MEDPARTITIONER_SequentialTopology.cxx \
+       test_HighLevelAPI.cxx
+
+EXTRA_DIST += $(OBSOLETE_FILES)