]> SALOME platform Git repositories - modules/med.git/commitdiff
Salome HOME
0022875: EDF 7690 MED: Creating joints with medpartitioner in the MEDCoupling API
authorimn <imn@opencascade.com>
Tue, 19 May 2015 11:59:01 +0000 (14:59 +0300)
committervsr <vsr@opencascade.com>
Wed, 3 Jun 2015 16:49:00 +0000 (19:49 +0300)
54 files changed:
src/CMakeLists.txt
src/CTestTestfileInstallMEDCoupling.cmake
src/MEDCoupling/CMakeLists.txt
src/MEDCoupling/MEDCouplingSkyLineArray.cxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingSkyLineArray.hxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDLoader/CMakeLists.txt
src/MEDLoader/MEDFileData.cxx
src/MEDLoader/MEDFileField.cxx
src/MEDLoader/MEDFileJoint.cxx [new file with mode: 0644]
src/MEDLoader/MEDFileJoint.hxx [new file with mode: 0644]
src/MEDLoader/MEDFileMesh.cxx
src/MEDLoader/MEDFileMesh.hxx
src/MEDLoader/Swig/MEDLoaderCommon.i
src/MEDLoader/Swig/MEDLoaderTest3.py
src/MEDPartitioner/CMakeLists.txt
src/MEDPartitioner/MEDPARTITIONER_ConnectZone.cxx
src/MEDPartitioner/MEDPARTITIONER_ConnectZone.hxx
src/MEDPartitioner/MEDPARTITIONER_Graph.cxx
src/MEDPartitioner/MEDPARTITIONER_Graph.hxx
src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.cxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.hxx [new file with mode: 0644]
src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx
src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx
src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx
src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.hxx
src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx
src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx
src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx
src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx
src/MEDPartitioner/MEDPARTITIONER_MetisGraph.hxx
src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx
src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx
src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx
src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx
src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.hxx
src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.cxx
src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.hxx
src/MEDPartitioner/MEDPARTITIONER_SkyLineArray.cxx [deleted file]
src/MEDPartitioner/MEDPARTITIONER_SkyLineArray.hxx [deleted file]
src/MEDPartitioner/MEDPARTITIONER_Topology.hxx
src/MEDPartitioner/MEDPARTITIONER_UserGraph.cxx
src/MEDPartitioner/MEDPARTITIONER_UserGraph.hxx
src/MEDPartitioner/MEDPARTITIONER_Utils.cxx
src/MEDPartitioner/MEDPARTITIONER_Utils.hxx
src/MEDPartitioner/medpartitioner.cxx
src/MEDPartitioner_Swig/CMakeLists.txt [new file with mode: 0644]
src/MEDPartitioner_Swig/CTestTestfileInstall.cmake [new file with mode: 0644]
src/MEDPartitioner_Swig/MEDPartitioner.i [new file with mode: 0644]
src/MEDPartitioner_Swig/MEDPartitionerCommon.i [new file with mode: 0644]
src/MEDPartitioner_Swig/MEDPartitionerTest.py [new file with mode: 0644]

index c4296a583f2d3b850e06cde0e2422405fc5ecbef..d3d23be80ca6cebcf88771b42e46efed587aadd8 100644 (file)
@@ -34,6 +34,9 @@ IF(NOT SALOME_MED_MICROMED)
   ENDIF(SALOME_MED_ENABLE_RENUMBER)
   IF(SALOME_MED_ENABLE_PARTITIONER)
     ADD_SUBDIRECTORY(MEDPartitioner)
+    IF(SALOME_MED_ENABLE_PYTHON)
+      ADD_SUBDIRECTORY(MEDPartitioner_Swig)
+    ENDIF(SALOME_MED_ENABLE_PYTHON)
   ENDIF(SALOME_MED_ENABLE_PARTITIONER)
   IF(SALOME_BUILD_TESTS)
     ADD_SUBDIRECTORY(INTERP_KERNELTest)
index a838c7e848709de2e61e2f9eab13a48063a3151b..e9effc1faed8b7bb93f4da8c455f9121c7987526 100644 (file)
@@ -31,4 +31,5 @@ SUBDIRS(MEDLoader/Swig)
 SUBDIRS(MEDPartitioner)
 #SUBDIRS(ParaMEDMEM_Swig)
 #SUBDIRS(ParaMEDMEMTest)
+SUBDIRS(MEDPartitioner_Swig)
 SUBDIRS(RENUMBER_Swig)
index 085f404226ce77d6d922e5bec65f1751bc779023..014f69a410c65171c84bc7a535bf6cf9d32f90b4 100644 (file)
@@ -59,6 +59,7 @@ SET(medcoupling_SOURCES
   MEDCouplingAMRAttribute.cxx
   MEDCouplingMatrix.cxx
   MEDCouplingPartDefinition.cxx
+  MEDCouplingSkyLineArray.cxx
   )
 
 SET(medcouplingremapper_SOURCES
diff --git a/src/MEDCoupling/MEDCouplingSkyLineArray.cxx b/src/MEDCoupling/MEDCouplingSkyLineArray.cxx
new file mode 100644 (file)
index 0000000..87f1bae
--- /dev/null
@@ -0,0 +1,102 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// 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 "MEDCouplingSkyLineArray.hxx"
+
+using namespace ParaMEDMEM;
+
+MEDCouplingSkyLineArray::MEDCouplingSkyLineArray():
+  _index( DataArrayInt::New() ), _value( DataArrayInt::New() )
+{
+}
+
+MEDCouplingSkyLineArray::MEDCouplingSkyLineArray(const MEDCouplingSkyLineArray &myArray)
+{
+  _index=myArray._index;
+  _value=myArray._value;
+}
+
+MEDCouplingSkyLineArray::~MEDCouplingSkyLineArray()
+{
+}
+
+MEDCouplingSkyLineArray::MEDCouplingSkyLineArray(DataArrayInt* index, DataArrayInt* value)
+{
+  set( index, value );
+}
+
+MEDCouplingSkyLineArray::MEDCouplingSkyLineArray( const std::vector<int>& index,
+                                                  const std::vector<int>& value ):
+  _index( DataArrayInt::New() ), _value( DataArrayInt::New() )
+{
+  _index->reserve( index.size() );
+  _index->insertAtTheEnd( index.begin(), index.end() );
+  _value->reserve( value.size() );
+  _value->insertAtTheEnd( value.begin(), value.end() );
+}
+
+void MEDCouplingSkyLineArray::set( DataArrayInt* index, DataArrayInt* value )
+{
+  _index=index;
+  _value=value;
+  if ( (DataArrayInt*)_index ) _index->incrRef();
+  else                         _index = DataArrayInt::New();
+  if ( (DataArrayInt*)_value ) _value->incrRef();
+  else                         _value = DataArrayInt::New();
+}
+
+DataArrayInt* MEDCouplingSkyLineArray::getIndexArray() const
+{
+  return ((MEDCouplingSkyLineArray*)this)->_index;
+}
+
+DataArrayInt* MEDCouplingSkyLineArray::getValueArray() const
+{
+  return ((MEDCouplingSkyLineArray*)this)->_value;
+}
+
+std::string MEDCouplingSkyLineArray::simpleRepr() const
+{
+  std::ostringstream oss;
+  oss << "MEDCouplingSkyLineArray" << std::endl;
+  oss << "   Nb of items: " << getNumberOf() << std::endl;
+  oss << "   Nb of values: " << getLength() << std::endl;
+  oss << "   Index:" << std::endl;
+  oss << "   ";
+  const int * i = _index->begin();
+  for ( ; i != _index->end(); ++i )
+    oss << *i << " ";
+  oss << std::endl;
+  oss << "   Value:" << std::endl;
+  oss << "   ";
+  const int * v = _value->begin();
+  int cnt = 0;
+  for ( i = _index->begin(); v != _value->end(); ++v, ++cnt )
+    {
+      if ( cnt == *i )
+        {
+          oss << "| ";
+          ++i;
+        }
+      oss << *v << " ";
+    }
+  oss << std::endl;
+
+  return oss.str();
+}
diff --git a/src/MEDCoupling/MEDCouplingSkyLineArray.hxx b/src/MEDCoupling/MEDCouplingSkyLineArray.hxx
new file mode 100644 (file)
index 0000000..c12dc6b
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// 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 __PARAMEDMEM_MEDCOUPLINGSKYLINEARRAY_HXX__
+#define __PARAMEDMEM_MEDCOUPLINGSKYLINEARRAY_HXX__
+
+#include "MEDCoupling.hxx"
+#include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+
+#include <vector>
+
+namespace ParaMEDMEM
+{
+  class MEDCOUPLING_EXPORT MEDCouplingSkyLineArray
+  {
+  private:
+    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _index;
+    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _value;
+  public:
+    MEDCouplingSkyLineArray();
+    MEDCouplingSkyLineArray( const MEDCouplingSkyLineArray &myArray );
+    MEDCouplingSkyLineArray( const std::vector<int>& index, const std::vector<int>& value );
+    MEDCouplingSkyLineArray( DataArrayInt* index, DataArrayInt* value );
+    ~MEDCouplingSkyLineArray();
+
+    void set( DataArrayInt* index, DataArrayInt* value );
+
+    int getNumberOf() const { return _index->getNbOfElems()-1; }
+    int getLength()   const { return _value->getNbOfElems(); }
+    const int* getIndex() const { return _index->begin(); }
+    const int* getValue() const { return _value->begin(); }
+
+    DataArrayInt* getIndexArray() const;
+    DataArrayInt* getValueArray() const;
+
+    std::string simpleRepr() const;
+  };
+}
+# endif
index ab7425894fa69455c86532f7c5f1c1f388a1babd..4f7ee4b68cf06d06e5dcc1e131a7924fa19ec505 100644 (file)
@@ -22,6 +22,7 @@
 #include "MEDCoupling1GTUMesh.hxx"
 #include "MEDCouplingMemArray.txx"
 #include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingSkyLineArray.hxx"
 #include "CellModel.hxx"
 #include "VolSurfUser.txx"
 #include "InterpolationUtils.hxx"
@@ -8679,6 +8680,82 @@ DataArrayInt *MEDCouplingUMesh::buildUnionOf3DMesh() const
   return ret.retn();
 }
 
+/*!
+ * \brief Creates a graph of cell neighbors
+ *  \return MEDCouplingSkyLineArray * - an sky line array the user should delete.
+ *  In the sky line array, graph arcs are stored in terms of (index,value) notation.
+ *  For example
+ *  - index:  0 3 5 6 6
+ *  - value:  1 2 3 2 3 3
+ *  means 6 arcs (0,1), (0,2), (0,3), (1,2), (1,3), (2,3)
+ *  Arcs are not doubled but reflexive (1,1) arcs are present for each cell
+ */
+MEDCouplingSkyLineArray *MEDCouplingUMesh::generateGraph() const
+{
+  checkConnectivityFullyDefined();
+
+  int meshDim = this->getMeshDimension();
+  ParaMEDMEM::DataArrayInt* indexr=ParaMEDMEM::DataArrayInt::New();
+  ParaMEDMEM::DataArrayInt* revConn=ParaMEDMEM::DataArrayInt::New();
+  this->getReverseNodalConnectivity(revConn,indexr);
+  const int* indexr_ptr=indexr->getConstPointer();
+  const int* revConn_ptr=revConn->getConstPointer();
+
+  const ParaMEDMEM::DataArrayInt* index;
+  const ParaMEDMEM::DataArrayInt* conn;
+  conn=this->getNodalConnectivity(); // it includes a type as the 1st element!!!
+  index=this->getNodalConnectivityIndex();
+  int nbCells=this->getNumberOfCells();
+  const int* index_ptr=index->getConstPointer();
+  const int* conn_ptr=conn->getConstPointer();
+
+  //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
+
+  //warning here one node have less than or equal effective number of cell with it
+  //but cell could have more than effective nodes
+  //because other equals nodes in other domain (with other global inode)
+  std::vector <int> cell2cell_index(nbCells+1,0);
+  std::vector <int> cell2cell;
+  cell2cell.reserve(3*nbCells);
+
+  for (int icell=0; icell<nbCells;icell++)
+    {
+      std::map<int,int > counter;
+      for (int iconn=index_ptr[icell]+1; iconn<index_ptr[icell+1];iconn++)
+        {
+          int inode=conn_ptr[iconn];
+          for (int iconnr=indexr_ptr[inode]; iconnr<indexr_ptr[inode+1];iconnr++)
+            {
+              int icell2=revConn_ptr[iconnr];
+              std::map<int,int>::iterator iter=counter.find(icell2);
+              if (iter!=counter.end()) (iter->second)++;
+              else counter.insert(std::make_pair(icell2,1));
+            }
+        }
+      for (std::map<int,int>::const_iterator iter=counter.begin();
+           iter!=counter.end(); iter++)
+        if (iter->second >= meshDim)
+          {
+            cell2cell_index[icell+1]++;
+            cell2cell.push_back(iter->first);
+          }
+    }
+  indexr->decrRef();
+  revConn->decrRef();
+  cell2cell_index[0]=0;
+  for (int icell=0; icell<nbCells;icell++)
+    cell2cell_index[icell+1]=cell2cell_index[icell]+cell2cell_index[icell+1];
+
+  //filling up index and value to create skylinearray structure
+  MEDCouplingSkyLineArray* array=new MEDCouplingSkyLineArray(cell2cell_index,cell2cell);
+  return array;
+}
+
 /*!
  * This method put in zip format into parameter 'zipFrmt' in full interlace mode.
  * This format is often asked by INTERP_KERNEL algorithms to avoid many indirections into coordinates array.
index fff81f7c505aef62d06b4ac31b6a76d77b1817f7..e3bb9c6d75de91841a4ba76e12d226728a52a1c5 100644 (file)
@@ -35,6 +35,7 @@ namespace ParaMEDMEM
   class MEDCouplingUMeshCellIterator;
   class MEDCoupling1SGTUMesh;
   class MEDCoupling1GTUMesh;
+  class MEDCouplingSkyLineArray;
 
   class MEDCouplingUMesh : public MEDCouplingPointSet
   {
@@ -271,6 +272,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *buildUnionOf2DMesh() const;
     MEDCOUPLING_EXPORT DataArrayInt *buildUnionOf3DMesh() const;
     MEDCOUPLING_EXPORT DataArrayInt *orderConsecutiveCells1D() const;
+    MEDCOUPLING_EXPORT MEDCouplingSkyLineArray *generateGraph() const;
   private:
     MEDCouplingUMesh();
     MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy);
index 2b2e7da291254ca5c06416d18d43ceddb6ea0514..98c6f9e0c8f757cc734d816ad1750ab58c42d74a 100644 (file)
@@ -16633,6 +16633,67 @@ class MEDCouplingBasicsTest(unittest.TestCase):
             pass
         pass
 
+    def testMEDCouplingSkyLineArray(self):
+        index = DataArrayInt([ 0, 3, 5, 6, 6 ])
+        value = DataArrayInt([ 1, 2, 3, 2, 3, 3 ])
+
+        sla0 = MEDCouplingSkyLineArray()
+        self.assertEqual( -1, sla0.getNumberOf() )
+        self.assertEqual( 0,  sla0.getLength() )
+        sla0.set( index, value )
+        self.assertTrue( index.isEqual( sla0.getIndexArray() ))
+        self.assertTrue( value.isEqual( sla0.getValueArray() ))
+        self.assertEqual( 4, sla0.getNumberOf() )
+        self.assertEqual( 6, sla0.getLength() )
+
+        sla1 = MEDCouplingSkyLineArray( index, value )
+        self.assertTrue( index.isEqual( sla1.getIndexArray() ))
+        self.assertTrue( value.isEqual( sla1.getValueArray() ))
+        self.assertEqual( 4, sla1.getNumberOf() )
+        self.assertEqual( 6, sla1.getLength() )
+
+        sla2 = MEDCouplingSkyLineArray( sla1 )
+        self.assertTrue( index.isEqual( sla2.getIndexArray() ))
+        self.assertTrue( value.isEqual( sla2.getValueArray() ))
+        self.assertEqual( 4, sla2.getNumberOf() )
+        self.assertEqual( 6, sla2.getLength() )
+
+        indexVec = ivec(); indexVec.reserve( len( index ))
+        for i in index: indexVec.push_back( i[0] )
+        valueVec = ivec(); valueVec.reserve( len( value ))
+        for i in value: valueVec.push_back( i[0] )
+        sla3 = MEDCouplingSkyLineArray( indexVec, valueVec )
+        self.assertTrue( index.isEqual( sla3.getIndexArray() ))
+        self.assertTrue( value.isEqual( sla3.getValueArray() ))
+        self.assertEqual( 4, sla3.getNumberOf() )
+        self.assertEqual( 6, sla3.getLength() )
+
+        pass
+   
+    def testMEDCouplingUMeshgenerateGraph(self):
+        # cartesian mesh 3x3
+        arr=DataArrayDouble(4) ; arr.iota()
+        c=MEDCouplingCMesh() ; c.setCoords(arr,arr)
+        m=c.buildUnstructured()
+        graph = m.generateGraph()
+        # 0 1 2
+        # 3 4 5
+        # 6 7 8
+        valRef=[ 0,1,3,
+                 0,1,2,4,
+                 1,2,5,
+                 0,3,4,6,
+                 1,3,4,5,7,
+                 2,4,5,8,
+                 3,6,7,
+                 4,6,7,8,
+                 5,7,8]
+        self.assertEqual(valRef,list(graph.getValueArray().getValues()));
+
+        indRef=[0, 3, 7, 10, 14, 19, 23, 26, 30, 33]
+        self.assertEqual(indRef,list(graph.getIndexArray().getValues()));
+        pass
+
     pass
 
 if __name__ == '__main__':
index 22cd189214186fed689ec7b61c0878d2204cebb8..24920cc8e8bb4bb09f50232747827ae2827883d4 100644 (file)
@@ -44,6 +44,7 @@
 #include "MEDCouplingAMRAttribute.hxx"
 #include "MEDCouplingMatrix.hxx"
 #include "MEDCouplingPartDefinition.hxx"
+#include "MEDCouplingSkyLineArray.hxx"
 #include "MEDCouplingTypemaps.i"
 
 #include "InterpKernelAutoPtr.hxx"
@@ -309,6 +310,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::MEDCouplingUMesh::ComputeRangesFromTypeDistribution;
 %newobject ParaMEDMEM::MEDCouplingUMesh::buildUnionOf2DMesh;
 %newobject ParaMEDMEM::MEDCouplingUMesh::buildUnionOf3DMesh;
+%newobject ParaMEDMEM::MEDCouplingUMesh::generateGraph;
 %newobject ParaMEDMEM::MEDCouplingUMesh::orderConsecutiveCells1D;
 %newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTreeFast;
 %newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic;
@@ -1136,6 +1138,28 @@ namespace ParaMEDMEM
     //
     static bool AreAlmostEqual(const std::vector<double>& v1, const std::vector<double>& v2, double eps);
   };
+
+  class MEDCouplingSkyLineArray
+  {
+  public:
+    MEDCouplingSkyLineArray();
+    MEDCouplingSkyLineArray( const MEDCouplingSkyLineArray &myArray );
+    MEDCouplingSkyLineArray( DataArrayInt* index, DataArrayInt* value );
+    MEDCouplingSkyLineArray( const std::vector<int>& index, const std::vector<int>& value );
+  
+    void set( DataArrayInt* index, DataArrayInt* value );
+    int getNumberOf() const;
+    int getLength() const;
+    DataArrayInt* getIndexArray() const;
+    DataArrayInt* getValueArray() const;
+      %extend 
+         {
+           std::string __str__() const throw(INTERP_KERNEL::Exception)
+           {
+             return self->simpleRepr();
+           }
+         }
+  };
 }
 
 %include "MEDCouplingFieldDiscretization.i"
@@ -1783,6 +1807,7 @@ namespace ParaMEDMEM
     DataArrayInt *convertNodalConnectivityToStaticGeoTypeMesh() const throw(INTERP_KERNEL::Exception);
     DataArrayInt *buildUnionOf2DMesh() const throw(INTERP_KERNEL::Exception);
     DataArrayInt *buildUnionOf3DMesh() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingSkyLineArray *generateGraph() const throw(INTERP_KERNEL::Exception);
     DataArrayInt *orderConsecutiveCells1D() const throw(INTERP_KERNEL::Exception);
     DataArrayDouble *getBoundingBoxForBBTreeFast() const throw(INTERP_KERNEL::Exception);
     DataArrayDouble *getBoundingBoxForBBTree2DQuadratic(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception);
index 5b8d96c098e8caeadf35b8e8e0cdde2a3a7ee7e7..40538ed309cac37c8f19b4c1bd2a0ea8b5c22ab5 100644 (file)
@@ -62,6 +62,7 @@ SET(medloader_SOURCES
   MEDFileBasis.cxx
   MEDFileMeshLL.cxx
   MEDFileField.cxx
+  MEDFileJoint.cxx
   MEDFileParameter.cxx
   MEDFileData.cxx
   MEDFileFieldOverView.cxx
index b9a6a20bad281c7a53ebfb9860a87ff28dfeb965..a979b38f503a22e2f763c2a1dddf60db46b5f6cc 100644 (file)
@@ -43,6 +43,7 @@ MEDFileData *MEDFileData::deepCpy() const
   MEDCouplingAutoRefCountObjectPtr<MEDFileParameters> params;
   if((const MEDFileParameters *)_params)
     params=_params->deepCpy();
+  MEDCouplingAutoRefCountObjectPtr<MEDFileJoints> joints;
   MEDCouplingAutoRefCountObjectPtr<MEDFileData> ret=MEDFileData::New();
   ret->_fields=fields; ret->_meshes=meshes; ret->_params=params;
   return ret.retn();
index d89c3ea9d097fc049da16ca8d468d065d2cd5704..8b54ffacf3455c784875f6315f5e1e1eb9a25e34 100644 (file)
@@ -4346,10 +4346,10 @@ std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA>
       for(std::vector<TypeOfField>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
         allEnt.insert(*it2);
     }
-       if(allEnt.size()!=1)
-         throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : this field is expected to be defined only on one spatial discretization !");
-       if(nbOfMDPGT==0)
-         throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !");
+  if(allEnt.size()!=1)
+    throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : this field is expected to be defined only on one spatial discretization !");
+  if(nbOfMDPGT==0)
+    throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !");
   if(nbOfMDPGT==1)
     {
       std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > ret0(1);
diff --git a/src/MEDLoader/MEDFileJoint.cxx b/src/MEDLoader/MEDFileJoint.cxx
new file mode 100644 (file)
index 0000000..bbd24ce
--- /dev/null
@@ -0,0 +1,838 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// 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 "MEDFileJoint.hxx"
+#include "MEDFileUtilities.hxx"
+#include "MEDLoader.hxx"
+#include "MEDLoaderBase.hxx"
+
+#include "CellModel.hxx"
+#include "InterpKernelAutoPtr.hxx"
+
+extern med_geometry_type                 typmai[MED_N_CELL_FIXED_GEO];
+extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
+extern med_geometry_type                 typmai3[34];
+
+using namespace ParaMEDMEM;
+
+std::size_t MEDFileJointCorrespondence::getHeapMemorySizeWithoutChildren() const
+{
+  return sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>);
+}
+
+std::vector<const BigMemoryObject *> MEDFileJointCorrespondence::getDirectChildrenWithNull() const
+{
+  return std::vector<const BigMemoryObject *>();
+}
+
+MEDFileJointCorrespondence::MEDFileJointCorrespondence():
+  _is_nodal( true ),
+  _loc_geo_type( INTERP_KERNEL::NORM_ERROR ),
+  _rem_geo_type( INTERP_KERNEL::NORM_ERROR )
+{
+}
+
+/*!
+ * Constructor.
+ *  \param [in] correspondence - correspondence.
+ *  \param [in] is_nodal - is the correspondence of cells or nodes.
+ *  \param [in] loc_geo_type - the local geometry type of correspondence.
+ *  \param [in] rem_geo_type - the remote geometry type of correspondence.
+ */
+MEDFileJointCorrespondence::MEDFileJointCorrespondence(DataArrayInt* correspondence,
+                                                       bool          isNodal,
+                                                       INTERP_KERNEL::NormalizedCellType loc_geo_type,
+                                                       INTERP_KERNEL::NormalizedCellType rem_geo_type):
+  _is_nodal( isNodal ),
+  _loc_geo_type( loc_geo_type ),
+  _rem_geo_type( rem_geo_type )
+{
+  MEDFileJointCorrespondence::setCorrespondence( correspondence );
+}
+
+MEDFileJointCorrespondence* MEDFileJointCorrespondence::New(DataArrayInt* correspondence,
+                                                            INTERP_KERNEL::NormalizedCellType loc_geo_type,
+                                                            INTERP_KERNEL::NormalizedCellType rem_geo_type)
+{
+  return new MEDFileJointCorrespondence(correspondence, /*isNodal=*/false, loc_geo_type, rem_geo_type );
+}
+
+/*!
+ * Returns a new MEDFileJointCorrespondence of nodes
+ */
+MEDFileJointCorrespondence *MEDFileJointCorrespondence::New(DataArrayInt* correspondence)
+{
+  return new MEDFileJointCorrespondence(correspondence);
+}
+
+/*!
+ * Returns a new undefined MEDFileJointCorrespondence
+ */
+
+MEDFileJointCorrespondence *MEDFileJointCorrespondence::New()
+{
+  return new MEDFileJointCorrespondence();
+}
+
+/*!
+ * Writes \a this joint into a MED file specified by its name.
+ *  \param [in] fileName - the MED file name.
+ *  \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
+ *          - 2 - erase; an existing file is removed.
+ *          - 1 - append; same data should not be present in an existing file.
+ *          - 0 - overwrite; same data present in an existing file is overwritten.
+ *  \param [in] order - order.
+ *  \param [in] iteration - iteration.
+ *  \throw If the mesh name is not set.
+ *  \throw If \a mode == 1 and the same data is present in an existing file.
+ */
+void MEDFileJointCorrespondence::write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const
+{
+  med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
+
+  std::ostringstream oss; oss << "MEDFileJointCorrespondence : error on attempt to write in file : \"" << fileName << "\"";
+  MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
+
+  if (( !_is_nodal ) &&
+      ( _loc_geo_type == INTERP_KERNEL::NORM_ERROR ||
+        _rem_geo_type == INTERP_KERNEL::NORM_ERROR ))
+    {
+      throw INTERP_KERNEL::Exception( "Geometric type not specified for a cell Joint" );
+    }
+
+  if ( (const DataArrayInt *)_correspondence )
+    {
+      writeLL(fid, localMeshName, jointName, order, iteration);
+    }
+  else
+    {
+      throw INTERP_KERNEL::Exception("MEDFileJointCorrespondence::write : correspondence array not defined");
+    }
+}
+
+void MEDFileJointCorrespondence::writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const
+{
+  if ( _is_nodal )
+    {
+      MEDsubdomainCorrespondenceWr(fid, localMeshName.c_str(), jointName.c_str(),
+                                   order, iteration,
+                                   MED_NODE, MED_NONE,
+                                   MED_NODE, MED_NONE,
+                                   _correspondence->getNbOfElems()/2,
+                                   _correspondence->getConstPointer());
+    }
+  else
+    {
+      MEDsubdomainCorrespondenceWr(fid, localMeshName.c_str(), jointName.c_str(),
+                                   order, iteration,
+                                   MED_CELL, typmai3[ _loc_geo_type ],
+                                   MED_CELL, typmai3[ _rem_geo_type ],
+                                   _correspondence->getNbOfElems()/2,
+                                   _correspondence->getConstPointer());
+    }
+}
+
+void MEDFileJointCorrespondence::setCorrespondence(DataArrayInt *corr)
+{
+  _correspondence=corr;
+  if ( corr )
+    corr->incrRef();
+}
+
+/*!
+ * Checks if \a this and another mesh are equal.
+ *  \param [in] other - the mesh to compare with.
+ *  \return bool - \c true if the meshes are equal, \c false, else.
+ */
+bool MEDFileJointCorrespondence::isEqual(const MEDFileJointCorrespondence *other) const
+{
+  if(_is_nodal!=other->_is_nodal)
+    return false;
+  if(_loc_geo_type!=other->_loc_geo_type)
+    return false;
+  if(_rem_geo_type!=other->_rem_geo_type)
+    return false;
+  if(!_correspondence->isEqual(*other->_correspondence))
+    return false;
+  return true;
+}
+
+MEDFileJointCorrespondence *MEDFileJointCorrespondence::deepCpy() const
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> ret=new MEDFileJointCorrespondence(*this);
+  return ret.retn();
+}
+
+MEDFileJointCorrespondence *MEDFileJointCorrespondence::shallowCpy() const
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> ret=new MEDFileJointCorrespondence(*this);
+  return ret.retn();
+}
+
+/*!
+ * Returns a string describing \a this mesh. This description includes the correspondence and
+ * the number correspondence.
+ *  \return std::string - the joint information string.
+ */
+std::string MEDFileJointCorrespondence::simpleRepr() const
+{
+  std::ostringstream oss;
+  oss << "(*************************************)\n(* JOINT_CORRESPOND INFORMATION: *)\n(*************************************)\n";
+  oss << "- entity type of the correspondence : " << ( getIsNodal() ? "NODE" : "CELL" ) << "\n";
+  oss << "- Local geometry type of the correspondence : " << INTERP_KERNEL::CellModel::GetCellModel( _loc_geo_type ).getRepr() << "\n";
+  oss << "- Remote geometry type of the correspondence : " << INTERP_KERNEL::CellModel::GetCellModel( _rem_geo_type ).getRepr() << "\n";
+  if ( (const DataArrayInt *)_correspondence )
+    {
+      oss << "- Number entity of the correspondence : " << getCorrespondence()->getNumberOfTuples() << "\n";
+
+      const DataArrayInt* tmp=getCorrespondence();
+      oss << "- Correspondence : <<";
+      for(const int *it=tmp->begin();it!=tmp->end();it++)
+        oss<< *it << " ";
+    }
+  else
+    {
+      oss << "- Number entity of the correspondence : 0\n";
+    }
+  oss << std::endl;
+  return oss.str();
+}
+
+
+MEDFileJointOneStep::MEDFileJointOneStep():_order(-1),_iteration(-1)
+{
+}
+
+std::size_t MEDFileJointOneStep::getHeapMemorySizeWithoutChildren() const
+{
+  return _correspondences.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>);
+}
+
+std::vector<const BigMemoryObject *> MEDFileJointOneStep::getDirectChildrenWithNull() const
+{
+  return std::vector<const BigMemoryObject *>();
+}
+
+MEDFileJointOneStep *MEDFileJointOneStep::New(int dt, int it)
+{
+  MEDFileJointOneStep* j = new MEDFileJointOneStep();
+  j->setOrder( dt );
+  j->setIteration( it );
+  return j;
+}
+
+/*!
+ * Returns a new MEDFileJointOneStep.
+ *  \param [in] fileName - the name of MED file to read.
+ *  \param [in] mName - the name of the mesh to read.
+ *  \param [in] jointName - the joint name.
+ *  \param [in] num - the number of an iteration.
+ *  \return MEDFileMesh * - a new instance of MEDFileJointOneStep.
+ *  \throw If the file is not readable.
+ *  \throw If there is no mesh with given attributes in the file.
+ */
+MEDFileJointOneStep *MEDFileJointOneStep::New(const std::string& fileName, const std::string& mName, const std::string& jointName, int num)
+{
+  MEDFileUtilities::CheckFileForRead(fileName);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY);
+  return new MEDFileJointOneStep(fid, mName, jointName, num);
+}
+
+MEDFileJointOneStep* MEDFileJointOneStep::New(med_idt fid, const std::string& mName, const std::string& jointName, int num)
+{
+  return new MEDFileJointOneStep( fid, mName, jointName, num);
+}
+
+MEDFileJointOneStep::MEDFileJointOneStep(med_idt fid, const std::string& mName, const std::string& jointName, int num)
+{
+  int order, iteration, ncorrespondence;
+  MEDsubdomainComputingStepInfo(fid, mName.c_str(), jointName.c_str(), num, &order, &iteration, &ncorrespondence);
+  MEDFileJointOneStep::setOrder(order);
+  MEDFileJointOneStep::setIteration(iteration);
+  for ( int cur_it = 1; cur_it <= ncorrespondence; ++cur_it )
+    {
+      int num_entity;
+      med_entity_type loc_ent_type, rem_ent_type;
+      med_geometry_type loc_geo_type, rem_geo_type;
+      MEDsubdomainCorrespondenceSizeInfo(fid, mName.c_str(), jointName.c_str(), order, iteration, cur_it,
+                                         &loc_ent_type, &loc_geo_type, &rem_ent_type, &rem_geo_type, &num_entity);
+      if ( num_entity > 0 )
+        {
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> correspondence=DataArrayInt::New();
+          correspondence->alloc(num_entity*2, 1);
+          MEDsubdomainCorrespondenceRd(fid, mName.c_str(), jointName.c_str(), order, iteration, loc_ent_type,
+                                       loc_geo_type, rem_ent_type, rem_geo_type, correspondence->getPointer());
+          MEDFileJointCorrespondence *cor=MEDFileJointCorrespondence::New();
+          cor->setIsNodal( loc_ent_type == MED_NODE );
+          cor->setLocalGeometryType ( convertGeometryType( loc_geo_type ));
+          cor->setRemoteGeometryType( convertGeometryType( rem_geo_type ));
+          cor->setCorrespondence( correspondence );
+          _correspondences.push_back(cor);
+        }
+    }
+}
+
+/*!
+ * Writes \a this joint into a MED file specified by its name.
+ *  \param [in] fileName - the MED file name.
+ *  \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
+ * - 2 - erase; an existing file is removed.
+ * - 1 - append; same data should not be present in an existing file.
+ * - 0 - overwrite; same data present in an existing file is overwritten.
+ *  \throw If the mesh name is not set.
+ *  \throw If \a mode == 1 and the same data is present in an existing file.
+ */
+void MEDFileJointOneStep::write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName) const
+{
+  med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
+  std::ostringstream oss; oss << "MEDFileJointOneStep : error on attempt to write in file : \"" << fileName << "\"";
+  MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
+  if ( _correspondences.empty() )
+    throw INTERP_KERNEL::Exception("MEDFileJointOneStep::write : no correspondences defined !");
+  writeLL(fid, localMeshName, jointName);
+}
+
+void MEDFileJointOneStep::writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName) const
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++)
+    {
+      (*it)->writeLL(fid, localMeshName, jointName, getOrder(), getIteration());
+    }
+}
+
+void MEDFileJointOneStep::pushCorrespondence(MEDFileJointCorrespondence* correspondence)
+{
+  if(!correspondence)
+    throw INTERP_KERNEL::Exception("MEDFileJointCorrespondence::pushCorrespondence : invalid input pointer ! should be different from 0 !");
+  _correspondences.push_back(correspondence);
+  correspondence->incrRef();
+}
+
+int MEDFileJointOneStep::getNumberOfCorrespondences() const
+{
+  return _correspondences.size();
+}
+
+/** Return a borrowed reference (caller is not responsible) */
+MEDFileJointCorrespondence *MEDFileJointOneStep::getCorrespondenceAtPos(int i) const
+{
+  if(i<0 || i>=(int)_correspondences.size())
+    {
+      std::ostringstream oss; oss << "MEDFileJointOneStep::getCorrespondenceAtPos : invalid correspondence id given in parameter ! Should be in [0;" << _correspondences.size() << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  const MEDFileJointCorrespondence* ret = _correspondences[i];
+  return const_cast<MEDFileJointCorrespondence *>( ret );
+}
+
+/*!
+ * Checks if \a this and another Joint are equal.
+ *  \param [in] other - the Joint to compare with.
+ *  \return bool - \c true if the Joints are equal, \c false, else.
+ */
+bool MEDFileJointOneStep::isEqual(const MEDFileJointOneStep *other) const
+{
+  if(_order!=other->_order)
+    return false;
+  if(_iteration!=other->_iteration)
+    return false;
+  if ( getNumberOfCorrespondences() != other->getNumberOfCorrespondences() )
+    return false;
+
+  std::vector<int> found( getNumberOfCorrespondences(), false );
+  for(int i=0; i<getNumberOfCorrespondences(); i++)
+    {
+      int j;
+      for(j=0; j<getNumberOfCorrespondences(); j++)
+        {
+          if ( !found[ j ] &&
+               getCorrespondenceAtPos(i)->isEqual(other->getCorrespondenceAtPos(j)))
+            {
+              found[ j ] = true;
+              break;
+            }
+        }
+      if ( j == getNumberOfCorrespondences() )
+        return false;
+    }
+  return true;
+}
+
+MEDFileJointOneStep *MEDFileJointOneStep::deepCpy() const
+{
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> > correspondences(_correspondences.size());
+  std::size_t i=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++,i++)
+    if((const MEDFileJointCorrespondence *)*it)
+      correspondences[i]=(*it)->deepCpy();
+  MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> ret= new MEDFileJointOneStep;
+  ret->_correspondences=correspondences;
+  return ret.retn();
+}
+
+MEDFileJointOneStep *MEDFileJointOneStep::shallowCpy() const
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> ret=new MEDFileJointOneStep(*this);
+  return ret.retn();
+}
+
+/*!
+ * Returns a string describing \a this Joint. This description includes the correspondence and
+ * the number of correspondences.
+ *  \return std::string - the joint information string.
+ */
+std::string MEDFileJointOneStep::simpleRepr() const
+{
+  std::ostringstream oss;
+  oss << "(*************************************)\n(* JOINT_ONE_STEP INFORMATION: *)\n(*************************************)\n";
+  oss << "- Number of the correspondences : <<" << _correspondences.size() << ">>\n";
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++)
+    {
+      oss << (*it)->simpleRepr();
+    }
+  return oss.str();
+}
+INTERP_KERNEL::NormalizedCellType MEDFileJointOneStep::convertGeometryType(med_geometry_type geotype)
+{
+  INTERP_KERNEL::NormalizedCellType result=INTERP_KERNEL::NORM_ERROR;
+  for(int i=0; i<MED_N_CELL_FIXED_GEO; i++)
+    {
+      if (typmai[i]==geotype)
+        {
+          result=typmai2[i];
+          break;
+        }
+    }
+  return result;
+}
+std::size_t MEDFileJoint::getHeapMemorySizeWithoutChildren() const
+{
+  return _joint.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep>);
+}
+
+std::vector<const BigMemoryObject *> MEDFileJoint::getDirectChildrenWithNull() const
+{
+  return std::vector<const BigMemoryObject *>();
+}
+
+MEDFileJoint *MEDFileJoint::New()
+{
+  return new MEDFileJoint();
+}
+
+MEDFileJoint *MEDFileJoint::New(const std::string& fileName, const std::string& mName, int curJoint)
+{
+  MEDFileUtilities::CheckFileForRead(fileName);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY);
+  return new MEDFileJoint(fid,mName,curJoint);
+}
+
+MEDFileJoint *MEDFileJoint::New(med_idt fid, const std::string& mName, int curJoint)
+{
+  return new MEDFileJoint(fid,mName,curJoint);
+}
+
+MEDFileJoint *MEDFileJoint::New(const std::string& jointName, const std::string& locMeshName, const std::string& remoteMeshName, int remoteMeshNum)
+{
+  MEDFileJoint* j = new MEDFileJoint();
+  j->setJointName( jointName );
+  j->setLocalMeshName( locMeshName );
+  j->setRemoteMeshName( remoteMeshName );
+  j->setDomainNumber( remoteMeshNum );
+  return j;
+}
+
+MEDFileJoint::MEDFileJoint()
+{
+}
+
+/*!
+ * Returns a new MEDFileJoint holding the mesh data that has been read from a given MED
+ * file. The Joint to load is specified by mesh name and a Joint iteration.
+ *  \param [in] fileName - the name of MED file to read.
+ *  \param [in] mName - the name of the mesh to read.
+ *  \param [in] curJoint - the iteration number of current joint.
+ *  \return MEDFileJoint * - a new instance of MEDFileJoint.
+ *  \throw If the file is not readable.
+ *  \throw If there is no mesh with given attributes in the file.
+ */
+MEDFileJoint::MEDFileJoint(med_idt fid, const std::string& mName, int curJoint)
+{
+  INTERP_KERNEL::AutoPtr<char> joint_name=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
+  INTERP_KERNEL::AutoPtr<char> desc_name=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
+  INTERP_KERNEL::AutoPtr<char> rem_mesh_name=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
+  int domain_number=0, nstep=0, nocstpncorrespondence=0;
+  MEDsubdomainJointInfo(fid,mName.c_str(), curJoint, joint_name, desc_name, &domain_number,rem_mesh_name,
+                        &nstep, &nocstpncorrespondence);
+  setLocalMeshName(mName);
+  setRemoteMeshName(MEDLoaderBase::buildStringFromFortran(rem_mesh_name,MED_NAME_SIZE));
+  setDescription(MEDLoaderBase::buildStringFromFortran(desc_name,MED_COMMENT_SIZE));
+  setJointName(MEDLoaderBase::buildStringFromFortran(joint_name,MED_NAME_SIZE));
+  setDomainNumber(domain_number);
+  for(int cur_step=1; cur_step <= nstep; ++cur_step)
+    {
+      MEDFileJointOneStep *cor=MEDFileJointOneStep::New(fid, mName.c_str(), getJointName(), cur_step);
+      _joint.push_back(cor);
+    }
+}
+
+/*!
+ * Writes \a this joint into a MED file specified by its name.
+ *  \param [in] fileName - the MED file name.
+ *  \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
+ * - 2 - erase; an existing file is removed.
+ * - 1 - append; same data should not be present in an existing file.
+ * - 0 - overwrite; same data present in an existing file is overwritten.
+ *  \throw If the mesh name is not set.
+ *  \throw If \a mode == 1 and the same data is present in an existing file.
+ */
+void MEDFileJoint::write(const std::string& fileName, int mode) const
+{
+  med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
+  std::ostringstream oss; oss << "MEDFileJoint : error on attempt to write in file : \"" << fileName << "\"";
+  MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
+  write(fid);
+}
+
+void MEDFileJoint::write(med_idt fid) const
+{
+  // if ( _loc_mesh_name.empty() )
+  //   throw INTERP_KERNEL::Exception("MEDFileJoint::write : name of a local mesh not defined!");
+  MEDsubdomainJointCr(fid,getLocalMeshName().c_str(),getJointName().c_str(),getDescription().c_str(),getDomainNumber(),getRemoteMeshName().c_str());
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> >::const_iterator it=_joint.begin();it!=_joint.end();it++) {
+    (*it)->writeLL(fid, getLocalMeshName(),getJointName());
+  }
+}
+
+void MEDFileJoint::pushStep(MEDFileJointOneStep* step)
+{
+  if(!step)
+    throw INTERP_KERNEL::Exception("MEDFileJoint::pushStep : invalid input pointer ! should be different from 0 !");
+  _joint.push_back(step);
+  step->incrRef();
+}
+
+int MEDFileJoint::getNumberOfSteps() const
+{
+  return _joint.size();
+}
+
+/** Return a borrowed reference (caller is not responsible) */
+MEDFileJointOneStep *MEDFileJoint::getStepAtPos(int i) const
+{
+  if(i<0 || i>=(int)_joint.size())
+    {
+      std::ostringstream oss; oss << "MEDFileJoint::getStepAtPos : invalid step id given in parameter ! Should be in [0;" << _joint.size() << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  const MEDFileJointOneStep* ret = _joint[i];
+  return const_cast<MEDFileJointOneStep *>( ret );
+}
+
+/*!
+ * Checks if \a this and another Joint are equal.
+ *  \param [in] other - the Joint to compare with.
+ *  \return bool - \c true if the Joints are equal, \c false, else.
+ */
+bool MEDFileJoint::isEqual(const MEDFileJoint *other) const
+{
+  if(_loc_mesh_name!=other->_loc_mesh_name)
+    return false;
+  if(_joint_name!=other->_joint_name)
+    return false;
+  if(_desc_name!=other->_desc_name)
+      return false;
+  if(_rem_mesh_name!=other->_rem_mesh_name)
+    return false;
+  if(_domain_number!=other->_domain_number)
+    return false;
+  std::vector<int> found( getNumberOfSteps(), false );
+  for(int i=0; i<getNumberOfSteps(); i++)
+    {
+      int j;
+      for(j=0; j<getNumberOfSteps(); j++)
+        {
+          if ( !found[ j ] &&
+            getStepAtPos(i)->isEqual(other->getStepAtPos(j)))
+            {
+              found[ j ] = true;
+              break;
+            }
+        }
+      if ( j == getNumberOfSteps() )
+        return false;
+    }
+  return true;
+}
+
+MEDFileJoint *MEDFileJoint::deepCpy() const
+{
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> > joint(_joint.size());
+  std::size_t i=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> >::const_iterator it=_joint.begin();it!=_joint.end();it++,i++)
+    if((const MEDFileJointOneStep *)*it)
+      joint[i]=(*it)->deepCpy();
+  MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> ret=MEDFileJoint::New();
+  ret->_joint=joint;
+  return ret.retn();
+}
+
+MEDFileJoint *MEDFileJoint::shallowCpy() const
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> ret=new MEDFileJoint(*this);
+  return ret.retn();
+}
+
+bool MEDFileJoint::changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
+{
+  for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
+    {
+      if((*it).first==_joint_name)
+        {
+          _joint_name=(*it).second;
+          return true;
+        }
+    }
+  return false;
+}
+
+/*!
+ * Returns a string describing \a this mesh. This description includes the correspondence and
+ * the number correspondence.
+ *  \return std::string - the joint information string.
+ */
+std::string MEDFileJoint::simpleRepr() const
+{
+  std::ostringstream oss;
+  oss << "(*************************************)\n(* JOINT INFORMATION: *)\n(*************************************)\n";
+  oss << "- Local Mesh name : <<" << getLocalMeshName() << ">>\n";
+  oss << "- Remote Mesh name : <<" << getRemoteMeshName() << ">>\n";
+  oss << "- Description : <<" << getDescription() << ">>\n";
+  oss << "- Joint name : <<" << getJointName() << ">>\n";
+  oss << "- Domain number : " << getDomainNumber() << "\n";
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> >::const_iterator it=_joint.begin();it!=_joint.end();it++)
+    {
+      oss << (*it)->simpleRepr();
+    }
+  return oss.str();
+}
+
+MEDFileJoints *MEDFileJoints::New()
+{
+  return new MEDFileJoints;
+}
+
+MEDFileJoints *MEDFileJoints::New(const std::string& fileName, const std::string& meshName)
+{
+  MEDFileUtilities::CheckFileForRead(fileName);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY);
+  return new MEDFileJoints( fid, meshName );
+}
+
+MEDFileJoints *MEDFileJoints::New(med_idt fid, const std::string& meshName)
+{
+  return new MEDFileJoints( fid, meshName );
+}
+
+void MEDFileJoints::write(med_idt fid) const
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++)
+    {
+      (*it)->write(fid);
+    }
+}
+
+void MEDFileJoints::write(const std::string& fileName, int mode) const
+{
+  med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
+  std::ostringstream oss; oss << "MEDFileJoints : error on attempt to write in file : \"" << fileName << "\"";
+  MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
+  write(fid);
+}
+
+std::string MEDFileJoints::getMeshName() const
+{
+  for ( size_t i = 0; i <= _joints.size(); ++i )
+    if ( (const MEDFileJoint*) _joints[i] )
+      return _joints[i]->getLocalMeshName();
+
+  return "";
+}
+
+int MEDFileJoints::getNumberOfJoints() const
+{
+  return _joints.size();
+}
+
+/** Return a borrowed reference (caller is not responsible) */
+MEDFileJoint *MEDFileJoints::getJointAtPos(int i) const
+{
+  if(i<0 || i>=(int)_joints.size())
+    {
+      std::ostringstream oss; oss << "MEDFileJoints::getJointAtPos : invalid joint id given in parameter ! Should be in [0;" << _joints.size() << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  const MEDFileJoint* ret = _joints[i];
+  return const_cast<MEDFileJoint *>( ret );
+}
+
+
+/** Return a borrowed reference (caller is not responsible) */
+MEDFileJoint *MEDFileJoints::getJointWithName(const std::string& jname) const
+{
+  std::vector<std::string> js=getJointsNames();
+  std::vector<std::string>::iterator it=std::find(js.begin(),js.end(),jname);
+  if(it==js.end())
+    {
+      std::ostringstream oss; oss << "MEDFileJoints::getJointWithName : Joint  \"" << jname << "\" does not exist in this ! Existing are : ";
+      std::copy(js.begin(),js.end(),std::ostream_iterator<std::string>(oss," "));
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  return getJointAtPos((int)std::distance(js.begin(),it));
+}
+
+std::vector<std::string> MEDFileJoints::getJointsNames() const
+{
+  std::vector<std::string> ret(_joints.size());
+  int i=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++,i++)
+    {
+      const MEDFileJoint *f=(*it);
+      if(f)
+        {
+          ret[i]=f->getJointName();
+        }
+      else
+        {
+          std::ostringstream oss; oss << "MEDFileJoints::getJointsNames : At rank #" << i << " joint is not defined !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  return ret;
+}
+
+bool MEDFileJoints::changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
+{
+  bool ret=false;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> >::iterator it=_joints.begin();it!=_joints.end();it++)
+    {
+      MEDFileJoint *cur(*it);
+      if(cur)
+        ret=cur->changeJointNames(modifTab) || ret;
+    }
+  return ret;
+}
+
+void MEDFileJoints::resize(int newSize)
+{
+  _joints.resize(newSize);
+}
+
+void MEDFileJoints::pushJoint(MEDFileJoint *joint)
+{
+  if(!joint)
+    throw INTERP_KERNEL::Exception("MEDFileJoints::pushJoint() : invalid input pointer ! should be different from 0 !");
+  if ( !_joints.empty() &&
+       _joints[0]->getLocalMeshName() != joint->getLocalMeshName() )
+    throw INTERP_KERNEL::Exception("MEDFileJoints::pushJoint() : different names of local meshes ! should be equal !");
+
+  _joints.push_back(joint);
+  joint->incrRef();
+}
+
+void MEDFileJoints::setJointAtPos(int i, MEDFileJoint *joint)
+{
+  if(!joint)
+    throw INTERP_KERNEL::Exception("MEDFileJoints::setJointAtPos : invalid input pointer ! should be different from 0 !");
+  if(i>=(int)_joints.size())
+    _joints.resize(i+1);
+  _joints[i]=joint;
+  joint->incrRef();
+}
+
+void MEDFileJoints::destroyJointAtPos(int i)
+{
+  if(i<0 || i>=(int)_joints.size())
+    {
+      std::ostringstream oss; oss << "MEDFileJoints::destroyJointAtPos : Invalid given id in input (" << i << ") should be in [0," << _joints.size() << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  _joints.erase(_joints.begin()+i);
+}
+
+MEDFileJoints::MEDFileJoints()
+{
+}
+
+MEDFileJoints::MEDFileJoints(med_idt fid, const std::string& meshName)
+{
+  int num_joint=MEDnSubdomainJoint(fid, meshName.c_str() );
+  for(int i = 1; i <= num_joint; i++)
+    _joints.push_back(MEDFileJoint::New(fid,meshName,i));
+}
+
+MEDFileJoints *MEDFileJoints::deepCpy() const
+{
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> > joints(_joints.size());
+  std::size_t i=0;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++,i++)
+    if((const MEDFileJoint *)*it)
+      joints[i]=(*it)->deepCpy();
+  MEDCouplingAutoRefCountObjectPtr<MEDFileJoints> ret=MEDFileJoints::New();
+  ret->_joints=joints;
+  return ret.retn();
+}
+
+std::size_t MEDFileJoints::getHeapMemorySizeWithoutChildren() const
+{
+  return _joints.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileJoint>));
+}
+
+std::vector<const BigMemoryObject *> MEDFileJoints::getDirectChildrenWithNull() const
+{
+  std::vector<const BigMemoryObject *> ret;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++)
+    ret.push_back((const MEDFileJoint *)*it);
+  return ret;
+}
+
+std::string MEDFileJoints::simpleRepr() const
+{
+  std::ostringstream oss;
+  oss << "(*****************)\n(* MEDFileJoints *)\n(*****************)\n\n";
+  simpleReprWithoutHeader(oss);
+  return oss.str();
+}
+
+void MEDFileJoints::simpleReprWithoutHeader(std::ostream& oss) const
+{
+  int nbOfJoints=getNumberOfJoints();
+  oss << "There are " << nbOfJoints << " joints with the following names : \n";
+  std::vector<std::string> jns=getJointsNames();
+  for(int i=0;i<nbOfJoints;i++)
+    oss << "  - #" << i << " \"" << jns[i] << "\"\n";
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++)
+    {
+      oss << (*it)->simpleRepr();
+    }
+}
diff --git a/src/MEDLoader/MEDFileJoint.hxx b/src/MEDLoader/MEDFileJoint.hxx
new file mode 100644 (file)
index 0000000..1d32312
--- /dev/null
@@ -0,0 +1,194 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// 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 __MEDFILEJOINT_HXX__
+#define __MEDFILEJOINT_HXX__
+
+#include "MEDLoaderDefines.hxx"
+#include "MEDFileUtilities.hxx"
+#include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+
+namespace ParaMEDMEM
+{
+/*!
+ * \brief Joint Correspondence enumerates pairs of corresponding entities of a
+ *        certain geometrical type in adjacent mesh domains.
+ *        Correspondence of nodes is constructed when you specify no cell type,
+ *        else Correspondence of cells is constructed.
+ */
+class MEDFileJointCorrespondence : public RefCountObject, public MEDFileWritable
+{
+public:
+  MEDLOADER_EXPORT static MEDFileJointCorrespondence *New();
+  MEDLOADER_EXPORT static MEDFileJointCorrespondence *New(DataArrayInt* correspondence); // nodes
+  MEDLOADER_EXPORT static MEDFileJointCorrespondence *New(DataArrayInt* correspondence,  // cells
+                                                          INTERP_KERNEL::NormalizedCellType loc_geo_type,
+                                                          INTERP_KERNEL::NormalizedCellType rem_geo_type);
+  MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
+  MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
+  MEDLOADER_EXPORT MEDFileJointCorrespondence *deepCpy() const;
+  MEDLOADER_EXPORT MEDFileJointCorrespondence *shallowCpy() const;
+  MEDLOADER_EXPORT bool isEqual(const MEDFileJointCorrespondence *other) const;
+  MEDLOADER_EXPORT void setIsNodal(bool isNodal) { _is_nodal = isNodal; }
+  MEDLOADER_EXPORT bool getIsNodal() const { return _is_nodal; }
+  MEDLOADER_EXPORT void setLocalGeometryType(INTERP_KERNEL::NormalizedCellType type) { _loc_geo_type=type; }
+  MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType getLocalGeometryType() const { return _loc_geo_type; }
+  MEDLOADER_EXPORT void setRemoteGeometryType(INTERP_KERNEL::NormalizedCellType type) { _rem_geo_type=type; }
+  MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType getRemoteGeometryType() const { return _rem_geo_type; }
+  MEDLOADER_EXPORT void setCorrespondence(DataArrayInt *corr);
+  MEDLOADER_EXPORT const DataArrayInt *getCorrespondence() const { return _correspondence; }
+  MEDLOADER_EXPORT void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const;
+
+  MEDLOADER_EXPORT std::string simpleRepr() const;
+  MEDLOADER_EXPORT void writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const;
+private:
+  MEDFileJointCorrespondence();
+  MEDFileJointCorrespondence(DataArrayInt*                     correspondence,
+                             bool                              is_nodal = true,
+                             INTERP_KERNEL::NormalizedCellType loc_geo_type = INTERP_KERNEL::NORM_ERROR,
+                             INTERP_KERNEL::NormalizedCellType rem_geo_type = INTERP_KERNEL::NORM_ERROR);
+private:
+  bool                                           _is_nodal;
+  INTERP_KERNEL::NormalizedCellType              _loc_geo_type;
+  INTERP_KERNEL::NormalizedCellType              _rem_geo_type;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _correspondence;
+};
+
+/*!
+ * \brief Joint of one iteration holds correspondences of entities of all types
+ */
+class MEDFileJointOneStep : public RefCountObject, public MEDFileWritable
+{
+public:
+  MEDLOADER_EXPORT static MEDFileJointOneStep *New(int dt=-1, int it=-1);
+  MEDLOADER_EXPORT static MEDFileJointOneStep *New(const std::string& fileName, const std::string& mName, const std::string& jointName, int number=1);
+  MEDLOADER_EXPORT static MEDFileJointOneStep *New(med_idt fid, const std::string& mName, const std::string& jointName, int number=1);
+  MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
+  MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
+  MEDLOADER_EXPORT MEDFileJointOneStep *deepCpy() const;
+  MEDLOADER_EXPORT MEDFileJointOneStep *shallowCpy() const;
+  MEDLOADER_EXPORT bool isEqual(const MEDFileJointOneStep *other) const;
+  MEDLOADER_EXPORT void setOrder(int order) { _order=order; }
+  MEDLOADER_EXPORT int getOrder() const { return _order; }
+  MEDLOADER_EXPORT void setIteration(int it) { _iteration=it; }
+  MEDLOADER_EXPORT int getIteration() const { return _iteration; }
+  MEDLOADER_EXPORT void pushCorrespondence(MEDFileJointCorrespondence* correspondence);
+  MEDLOADER_EXPORT int getNumberOfCorrespondences() const;
+  MEDLOADER_EXPORT MEDFileJointCorrespondence *getCorrespondenceAtPos(int i) const;
+
+  MEDLOADER_EXPORT void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName) const;
+
+  MEDLOADER_EXPORT std::string simpleRepr() const;
+  MEDLOADER_EXPORT void writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName) const;
+private:
+  MEDFileJointOneStep();
+  MEDFileJointOneStep(med_idt fid, const std::string& mName, const std::string& jointName, int number);
+  MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType convertGeometryType(med_geometry_type geotype);
+protected:
+  int _order;
+  int _iteration;
+private:
+  std::vector<MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> > _correspondences;
+};
+
+/*!
+ * \brief Joint holds a sequence of joints of different iterations relating to
+ *        a pair of mesh domains: a local one and a distant one
+ */
+class MEDFileJoint : public RefCountObject, public MEDFileWritable
+{
+public:
+    MEDLOADER_EXPORT static MEDFileJoint *New();
+    MEDLOADER_EXPORT static MEDFileJoint *New(const std::string& fileName, const std::string& mName, int num);
+    MEDLOADER_EXPORT static MEDFileJoint *New(med_idt fid, const std::string& mName, int num);
+    MEDLOADER_EXPORT static MEDFileJoint *New(const std::string& jointName, const std::string& locMeshName, const std::string& remoteMeshName, int remoteMeshNum );
+    MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
+    MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
+    MEDLOADER_EXPORT MEDFileJoint *deepCpy() const;
+    MEDLOADER_EXPORT MEDFileJoint *shallowCpy() const;
+    MEDLOADER_EXPORT bool isEqual(const MEDFileJoint *other) const;
+    MEDLOADER_EXPORT void setLocalMeshName(const std::string& name) { _loc_mesh_name=name; }
+    MEDLOADER_EXPORT std::string getLocalMeshName() const { return _loc_mesh_name; }
+    MEDLOADER_EXPORT void setRemoteMeshName(const std::string& name) { _rem_mesh_name=name; }
+    MEDLOADER_EXPORT std::string getRemoteMeshName() const { return _rem_mesh_name; }
+    MEDLOADER_EXPORT void setDescription(const std::string& name) { _desc_name=name; }
+    MEDLOADER_EXPORT std::string getDescription() const { return _desc_name; }
+    MEDLOADER_EXPORT void setJointName(const std::string& name) { _joint_name=name; }
+    MEDLOADER_EXPORT std::string getJointName() const { return _joint_name; }
+    MEDLOADER_EXPORT bool changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab);
+    MEDLOADER_EXPORT void setDomainNumber(const int& number) { _domain_number=number; }
+    MEDLOADER_EXPORT int getDomainNumber() const { return _domain_number; }
+    MEDLOADER_EXPORT void pushStep(MEDFileJointOneStep* step);
+    MEDLOADER_EXPORT int getNumberOfSteps() const;
+    MEDLOADER_EXPORT MEDFileJointOneStep *getStepAtPos(int i) const;
+
+    MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const;
+    MEDLOADER_EXPORT void write(med_idt fid) const;
+
+    MEDLOADER_EXPORT std::string simpleRepr() const;
+  private:
+    MEDFileJoint();
+    MEDFileJoint(med_idt fid, const std::string& mName, int num);
+  private:
+    std::string _loc_mesh_name;
+    std::string _joint_name;
+    std::string _desc_name;
+    int _domain_number;
+    std::string _rem_mesh_name;
+    std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> > _joint;
+  };
+
+  /*!
+   * \brief Joints of a mesh domain relating to all other mesh domains
+   */
+  class MEDFileJoints : public RefCountObject, public MEDFileWritable
+  {
+  public:
+    MEDLOADER_EXPORT static MEDFileJoints *New();
+    MEDLOADER_EXPORT static MEDFileJoints *New(const std::string& fileName, const std::string& meshName);
+    MEDLOADER_EXPORT static MEDFileJoints *New(med_idt fid, const std::string& meshName);
+    MEDLOADER_EXPORT MEDFileJoints *deepCpy() const;
+    MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
+    MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
+    MEDLOADER_EXPORT std::string simpleRepr() const;
+    MEDLOADER_EXPORT void simpleReprWithoutHeader(std::ostream& oss) const;
+    MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const;
+    MEDLOADER_EXPORT void write(med_idt fid) const;
+    MEDLOADER_EXPORT std::string getMeshName() const;
+    MEDLOADER_EXPORT int getNumberOfJoints() const;
+    MEDLOADER_EXPORT MEDFileJoint *getJointAtPos(int i) const;
+    MEDLOADER_EXPORT MEDFileJoint *getJointWithName(const std::string& jname) const;
+    MEDLOADER_EXPORT std::vector<std::string> getJointsNames() const;
+    MEDLOADER_EXPORT bool changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab);
+    //
+    MEDLOADER_EXPORT void resize(int newSize);
+    MEDLOADER_EXPORT void pushJoint(MEDFileJoint *joint);
+    MEDLOADER_EXPORT void setJointAtPos(int i, MEDFileJoint *joint);
+    MEDLOADER_EXPORT void destroyJointAtPos(int i);
+  private:
+    ~MEDFileJoints() { }
+    MEDFileJoints();
+    MEDFileJoints(med_idt fid, const std::string& meshName);
+  private:
+    std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> > _joints;
+  };
+}
+
+#endif
index 83599d14f37b2971fa3d98e2a5fdaf335eb7a6a2..5ce3bfee0591f061d5958df0a8adecee583ea420 100644 (file)
@@ -91,18 +91,21 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
         ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
+        ret->loadJointsFromFile(fid);
         return (MEDFileUMesh *)ret.retn();
       }
     case CARTESIAN:
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
         ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
+        ret->loadJointsFromFile(fid);
         return (MEDFileCMesh *)ret.retn();
       }
     case CURVE_LINEAR:
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
         ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs);
+        ret->loadJointsFromFile(fid);
         return (MEDFileCurveLinearMesh *)ret.retn();
       }
     default:
@@ -121,13 +124,16 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect
  *  \param [in] mName - the name of the mesh to read.
  *  \param [in] dt - the number of a time step.
  *  \param [in] it - the number of an iteration.
+ *  \param [in] joints - the sub-domain joints to use instead of those that can be read
+ *          from the MED file. Usually this joints are those just read by another iteration
+ *          of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
  *  \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
  *          mesh using decrRef() as it is no more needed. 
  *  \throw If the file is not readable.
  *  \throw If there is no mesh with given attributes in the file.
  *  \throw If the mesh in the file is of a not supported type.
  */
-MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
 {
   MEDFileUtilities::CheckFileForRead(fileName);
   ParaMEDMEM::MEDCouplingMeshType meshType;
@@ -141,18 +147,21 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
         ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
+        ret->loadJointsFromFile(fid,joints);
         return (MEDFileUMesh *)ret.retn();
       }
     case CARTESIAN:
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
         ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
+        ret->loadJointsFromFile(fid,joints);
         return (MEDFileCMesh *)ret.retn();
       }
     case CURVE_LINEAR:
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
         ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
+        ret->loadJointsFromFile(fid,joints);
         return (MEDFileCurveLinearMesh *)ret.retn();
       }
     default:
@@ -2401,7 +2410,8 @@ MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it
 try
 {
     loadUMeshFromFile(fid,mName,dt,it,mrs);
-}
+    loadJointsFromFile(fid);
+  }
 catch(INTERP_KERNEL::Exception& e)
 {
     throw e;
@@ -2429,6 +2439,62 @@ void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName,
   dispatchLoadedPart(fid,loaderl2,mName,mrs);
 }
 
+/*!
+ * \brief Write joints in a file
+ */
+void MEDFileMesh::writeJoints(med_idt fid) const
+{
+  if ( (const MEDFileJoints*) _joints )
+    _joints->write(fid);
+}
+
+/*!
+ * \brief Load joints in a file or use provided ones
+ */
+//================================================================================
+/*!
+ * \brief Load joints in a file or use provided ones
+ *  \param [in] fid - MED file descriptor
+ *  \param [in] toUseInstedOfReading - optional joints to use instead of reading,
+ *          Usually this joints are those just read by another iteration
+ *          of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
+ */
+//================================================================================
+
+void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
+{
+  if ( toUseInstedOfReading )
+    setJoints( toUseInstedOfReading );
+  else
+    _joints = MEDFileJoints::New( fid, _name );
+}
+
+/*!
+ * \brief Return number of joints, which is equal to number of adjacent mesh domains
+ */
+int MEDFileMesh::getNumberOfJoints()
+{
+  return ( (MEDFileJoints*) _joints ) ? _joints->getNumberOfJoints() : 0;
+}
+
+/*!
+ * \brief Return joints with all adjacent mesh domains
+ */
+MEDFileJoints * MEDFileMesh::getJoints() const
+{
+  return (MEDFileJoints*) & (*_joints);
+}
+
+void MEDFileMesh::setJoints( MEDFileJoints* joints )
+{
+  if ( joints != _joints )
+    {
+      _joints = joints;
+      if ( joints )
+        joints->incrRef();
+    }
+}
+
 /*!
  * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
  *
@@ -2448,7 +2514,6 @@ void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int
     }
   loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
   dispatchLoadedPart(fid,loaderl2,mName,mrs);
-
 }
 
 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
@@ -2515,6 +2580,8 @@ void MEDFileUMesh::writeLL(med_idt fid) const
     if((const MEDFileUMeshSplitL1 *)(*it)!=0)
       (*it)->write(fid,meshName,mdim);
   MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
+
+  writeJoints(fid);
 }
 
 /*!
@@ -5924,6 +5991,7 @@ MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it
 try
 {
     loadCMeshFromFile(fid,mName,dt,it,mrs);
+    loadJointsFromFile(fid);
 }
 catch(INTERP_KERNEL::Exception& e)
 {
@@ -6009,6 +6077,8 @@ void MEDFileCMesh::writeLL(med_idt fid) const
   //
   std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
   MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
+
+  writeJoints(fid);
 }
 
 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
@@ -6176,6 +6246,7 @@ MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& m
 try
 {
     loadCLMeshFromFile(fid,mName,dt,it,mrs);
+    loadJointsFromFile(fid);
 }
 catch(INTERP_KERNEL::Exception& e)
 {
@@ -6215,6 +6286,8 @@ void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
   //
   std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
   MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
+
+  writeJoints(fid);
 }
 
 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
@@ -6320,13 +6393,41 @@ void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
   _mesh_one_ts[0]=mesh1TimeStep;
 }
 
+MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
+{
+  if ( MEDFileMesh* m = getOneTimeStep() )
+    return m->getJoints();
+  return 0;
+}
+
+/*!
+ * \brief Set Joints that are common to all time-stamps
+ */
+void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+    {
+      (*it)->setJoints( joints );
+    }
+}
+
 void MEDFileMeshMultiTS::write(med_idt fid) const
 {
+  MEDFileJoints * joints = getJoints();
+  bool jointsWritten = false;
+
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
     {
+      if ( jointsWritten )
+        const_cast<MEDFileMesh&>(**it).setJoints( 0 );
+      else
+        jointsWritten = true;
+
       (*it)->copyOptionsFrom(*this);
       (*it)->write(fid);
     }
+
+  ((MEDFileMeshMultiTS*)this)->setJoints( joints ); // restore joints
 }
 
 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
@@ -6339,9 +6440,16 @@ void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
 }
 
 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
-{//for the moment to be improved
-  _mesh_one_ts.resize(1);
-  _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
+{
+  MEDFileJoints* joints = 0;
+  if ( !_mesh_one_ts.empty() && getOneTimeStep() )
+    {
+      // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
+      joints = getOneTimeStep()->getJoints();
+    }
+
+  _mesh_one_ts.clear();  //for the moment to be improved
+  _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
 }
 
 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
@@ -6464,6 +6572,16 @@ std::vector<std::string> MEDFileMeshes::getMeshesNames() const
     }
   return ret;
 }
+/*const MEDFileJoints* MEDFileMeshes::getJoints() const
+{
+  const MEDFileJoints *ret=_joints;
+  if(!ret)
+  {
+    std::ostringstream oss; oss << "MEDFileMeshes::getJoints : joints is not defined !";
+    throw INTERP_KERNEL::Exception(oss.str().c_str());
+  }
+  return ret;
+}*/
 
 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
 {
index 1f3defa38e1848e94ba8e3559424e27458e63a4a..2bb997d34aa6bfc77919f64c47907d99e9165580 100644 (file)
@@ -26,6 +26,7 @@
 #include "MEDFileUtilities.hxx"
 #include "MEDCouplingPartDefinition.hxx"
 #include "MEDFileMeshReadSelector.hxx"
+#include "MEDFileJoint.hxx"
 
 #include <map>
 #include <list>
@@ -39,7 +40,7 @@ namespace ParaMEDMEM
   {
   public:
     MEDLOADER_EXPORT static MEDFileMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0);
-    MEDLOADER_EXPORT static MEDFileMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0);
+    MEDLOADER_EXPORT static MEDFileMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0, MEDFileJoints* joints=0);
     MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
     MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
     MEDLOADER_EXPORT virtual MEDFileMesh *createNewEmpty() const = 0;
@@ -169,6 +170,9 @@ namespace ParaMEDMEM
     MEDLOADER_EXPORT virtual DataArrayInt *getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum=false) const;
     // tools
     MEDLOADER_EXPORT virtual bool unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) = 0;
+    MEDLOADER_EXPORT int                  getNumberOfJoints();
+    MEDLOADER_EXPORT MEDFileJoints *getJoints() const;
+    MEDLOADER_EXPORT void                 setJoints( MEDFileJoints* joints );
   protected:
     MEDFileMesh();
     //! protected because no way in MED file API to specify this name
@@ -187,6 +191,8 @@ namespace ParaMEDMEM
     static std::string FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created);
     static std::string CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid);
     static int PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt);
+    void writeJoints(med_idt fid) const;
+    void loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading=0);
   protected:
     int _order;
     int _iteration;
@@ -197,6 +203,7 @@ namespace ParaMEDMEM
     mutable std::string _univ_name;
     bool _univ_wr_status;
     std::string _desc_name;
+    MEDCouplingAutoRefCountObjectPtr<MEDFileJoints> _joints;
   protected:
     std::map<std::string, std::vector<std::string> > _groups;
     std::map<std::string,int> _families;
@@ -478,6 +485,8 @@ namespace ParaMEDMEM
     MEDLOADER_EXPORT void write(med_idt fid) const;
     MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const;
     MEDLOADER_EXPORT void setOneTimeStep(MEDFileMesh *mesh1TimeStep);
+    MEDLOADER_EXPORT MEDFileJoints *getJoints() const;
+    MEDLOADER_EXPORT void                 setJoints( MEDFileJoints* joints );
   private:
     ~MEDFileMeshMultiTS() { }
     void loadFromFile(const std::string& fileName, const std::string& mName);
index 901bea448b6d50a975b42dc0ab811b2946e7a387..b4132f8ca797f04b315fb2a235cbd9b131525f8f 100644 (file)
@@ -27,6 +27,7 @@
 
 %{
 #include "MEDLoader.hxx"
+#include "MEDFileJoint.hxx"
 #include "MEDFileMesh.hxx"
 #include "MEDFileField.hxx"
 #include "MEDFileParameter.hxx"
@@ -93,6 +94,7 @@ using namespace ParaMEDMEM;
 %newobject ParaMEDMEM::MEDFileMesh::getNodeFamiliesArr;
 %newobject ParaMEDMEM::MEDFileMesh::getAllFamiliesIdsReferenced;
 %newobject ParaMEDMEM::MEDFileMesh::computeAllFamilyIdsInUse;
+%newobject ParaMEDMEM::MEDFileData::getJoints;
 %newobject ParaMEDMEM::MEDFileStructuredMesh::getImplicitFaceMesh;
 %newobject ParaMEDMEM::MEDFileUMesh::New;
 %newobject ParaMEDMEM::MEDFileUMesh::LoadPartOf;
@@ -191,6 +193,21 @@ using namespace ParaMEDMEM;
 %newobject ParaMEDMEM::MEDFileParameters::getParamWithName;
 %newobject ParaMEDMEM::MEDFileParameters::__getitem__;
 
+%newobject ParaMEDMEM::MEDFileJointCorrespondence::New;
+%newobject ParaMEDMEM::MEDFileJointCorrespondence::deepCpy;
+%newobject ParaMEDMEM::MEDFileJointCorrespondence::shallowCpy;
+%newobject ParaMEDMEM::MEDFileJointOneStep::New;
+%newobject ParaMEDMEM::MEDFileJointOneStep::deepCpy;
+%newobject ParaMEDMEM::MEDFileJointOneStep::shallowCpy;
+%newobject ParaMEDMEM::MEDFileJoint::New;
+%newobject ParaMEDMEM::MEDFileJoint::deepCpy;
+%newobject ParaMEDMEM::MEDFileJoint::shallowCpy;
+%newobject ParaMEDMEM::MEDFileJoints::New;
+%newobject ParaMEDMEM::MEDFileJoints::deepCpy;
+%newobject ParaMEDMEM::MEDFileJoints::getJointAtPos;
+%newobject ParaMEDMEM::MEDFileJoints::getJointWithName;
+%newobject ParaMEDMEM::MEDFileJoints::__getitem__;
+
 %newobject ParaMEDMEM::SauvWriter::New;
 %newobject ParaMEDMEM::SauvReader::New;
 %newobject ParaMEDMEM::SauvReader::loadInMEDFileDS;
@@ -219,6 +236,10 @@ using namespace ParaMEDMEM;
 %feature("unref") MEDFileParameterDouble1TS "$this->decrRef();"
 %feature("unref") MEDFileParameterMultiTS "$this->decrRef();"
 %feature("unref") MEDFileParameters "$this->decrRef();"
+%feature("unref") MEDFileJointCorrespondence "$this->decrRef();"
+%feature("unref") MEDFileJointOneStep "$this->decrRef();"
+%feature("unref") MEDFileJoint "$this->decrRef();"
+%feature("unref") MEDFileJoints "$this->decrRef();"
 %feature("unref") MEDFileData "$this->decrRef();"
 %feature("unref") SauvReader "$this->decrRef();"
 %feature("unref") SauvWriter "$this->decrRef();"
@@ -476,6 +497,208 @@ namespace ParaMEDMEM
       }
     }
   };
+  class MEDFileJointCorrespondence : public RefCountObject, public MEDFileWritable
+  {
+  public:
+    static MEDFileJointCorrespondence *New() throw(INTERP_KERNEL::Exception);
+    static MEDFileJointCorrespondence *New(DataArrayInt* correspondence) // nodes
+      throw(INTERP_KERNEL::Exception);
+    static MEDFileJointCorrespondence *New(DataArrayInt* correspondence,  // cells
+                                           INTERP_KERNEL::NormalizedCellType loc_geo_type,
+                                           INTERP_KERNEL::NormalizedCellType rem_geo_type)
+      throw(INTERP_KERNEL::Exception);
+    std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
+    MEDFileJointCorrespondence *deepCpy() const;
+    MEDFileJointCorrespondence *shallowCpy() const;
+    void setIsNodal(bool isNodal);
+    bool getIsNodal() const;
+    bool isEqual(const MEDFileJointCorrespondence *other) const;
+    void setLocalGeometryType(INTERP_KERNEL::NormalizedCellType type);
+    INTERP_KERNEL::NormalizedCellType getLocalGeometryType() const;
+    void setRemoteGeometryType(INTERP_KERNEL::NormalizedCellType type);
+    INTERP_KERNEL::NormalizedCellType getRemoteGeometryType() const;
+    void setCorrespondence(DataArrayInt *corr) throw(INTERP_KERNEL::Exception);
+    const DataArrayInt *getCorrespondence() const throw(INTERP_KERNEL::Exception);
+    void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const throw(INTERP_KERNEL::Exception);
+    std::string simpleRepr() const throw(INTERP_KERNEL::Exception);
+    %extend
+    {
+      MEDFileJointCorrespondence()
+      {
+        return MEDFileJointCorrespondence::New();
+      }
+      MEDFileJointCorrespondence(DataArrayInt* correspondence) throw(INTERP_KERNEL::Exception)
+      {
+        return MEDFileJointCorrespondence::New(correspondence);
+      }
+      MEDFileJointCorrespondence(DataArrayInt* correspondence,  // cells
+                                 INTERP_KERNEL::NormalizedCellType loc_geo_type,
+                                 INTERP_KERNEL::NormalizedCellType rem_geo_type) throw(INTERP_KERNEL::Exception)
+      {
+        return MEDFileJointCorrespondence::New(correspondence, loc_geo_type, rem_geo_type);
+      }
+
+      std::string __str__() const throw(INTERP_KERNEL::Exception)
+      {
+        return self->simpleRepr();
+      }
+    }
+  };
+
+  class MEDFileJointOneStep : public RefCountObject, public MEDFileWritable
+  {
+  public:
+    static MEDFileJointOneStep *New(int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception);
+    static MEDFileJointOneStep *New(const std::string& fileName, const std::string& mName, const std::string& jointName, int number=1) throw(INTERP_KERNEL::Exception);
+    MEDFileJointOneStep *deepCpy() const;
+    MEDFileJointOneStep *shallowCpy() const;
+    bool isEqual(const MEDFileJointOneStep *other) const;
+    void setOrder(int order);
+    int getOrder() const;
+    void setIteration(int it);
+    int getIteration() const;
+    void pushCorrespondence(MEDFileJointCorrespondence* correspondence);
+    int getNumberOfCorrespondences() const;
+    MEDFileJointCorrespondence *getCorrespondenceAtPos(int i) const;
+    void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName) const throw(INTERP_KERNEL::Exception);
+    std::string simpleRepr() const throw(INTERP_KERNEL::Exception);
+    %extend
+    {
+      MEDFileJointOneStep()
+      {
+        return MEDFileJointOneStep::New();
+      }
+
+      MEDFileJointOneStep(const std::string& fileName, const std::string& mName, const std::string& jointName, int number) throw(INTERP_KERNEL::Exception)
+      {
+        return MEDFileJointOneStep::New(fileName,mName,jointName,number);
+      }
+
+      std::string __str__() const throw(INTERP_KERNEL::Exception)
+      {
+        return self->simpleRepr();
+      }
+    }
+  };
+  class MEDFileJoint : public RefCountObject, public MEDFileWritable
+  {
+  public:
+    static MEDFileJoint *New() throw(INTERP_KERNEL::Exception);
+    static MEDFileJoint *New(const std::string& fileName, const std::string& mName, int num) throw(INTERP_KERNEL::Exception);
+    static MEDFileJoint *New(const std::string& jointName, const std::string& locMeshName, const std::string& remoteMeshName, int remoteMeshNum ) throw(INTERP_KERNEL::Exception);
+    MEDFileJoint *deepCpy() const;
+    MEDFileJoint *shallowCpy() const;
+    bool isEqual(const MEDFileJoint *other) const;
+    void setLocalMeshName(const std::string& name);
+    std::string getLocalMeshName() const;
+    void setRemoteMeshName(const std::string& name);
+    std::string getRemoteMeshName() const;
+    void setDescription(const std::string& name);
+    std::string getDescription() const;
+    void setJointName(const std::string& name);
+    std::string getJointName() const;
+    bool changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception);
+    void setDomainNumber(const int& number);
+    int getDomainNumber() const;
+    void pushStep(MEDFileJointOneStep* step);
+    int getNumberOfSteps() const;
+    MEDFileJointOneStep *getStepAtPos(int i) const;
+    void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception);
+    std::string simpleRepr() const;
+    %extend
+    {
+      MEDFileJoint()
+      {
+        return MEDFileJoint::New();
+      }
+      
+      MEDFileJoint(const std::string& fileName, const std::string& mName, int num) throw(INTERP_KERNEL::Exception)
+      {
+        return MEDFileJoint::New(fileName,mName,num);
+      }
+
+      std::string __str__() const throw(INTERP_KERNEL::Exception)
+      {
+        return self->simpleRepr();
+      }
+    }
+  };
+
+  class MEDFileJoints : public RefCountObject, public MEDFileWritable
+  {
+  public:
+    static MEDFileJoints *New() throw(INTERP_KERNEL::Exception);
+    static MEDFileJoints *New(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception);
+    MEDFileJoints *deepCpy() const;
+    std::string simpleRepr() const;
+    void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception);
+    std::string getMeshName() const;
+    int getNumberOfJoints() const;
+    std::vector<std::string> getJointsNames() const;
+    bool changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception);
+    void resize(int newSize) throw(INTERP_KERNEL::Exception);
+    void pushJoint(MEDFileJoint *joint);
+    void setJointAtPos(int i, MEDFileJoint *joint) throw(INTERP_KERNEL::Exception);
+    void destroyJointAtPos(int i) throw(INTERP_KERNEL::Exception);
+    %extend
+    {
+      MEDFileJoints()
+      {
+        return MEDFileJoints::New();
+      }
+      
+      MEDFileJoints(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception)
+      {
+        return MEDFileJoints::New(fileName,meshName);
+      }
+
+      std::string __str__() const throw(INTERP_KERNEL::Exception)
+      {
+        return self->simpleRepr();
+      }
+
+      MEDFileJoint *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception)
+      {
+        if(PyInt_Check(obj))
+          {
+            MEDFileJoint *ret=self->getJointAtPos(InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfJoints()));
+            if(ret)
+              ret->incrRef();
+            return ret;
+          }
+        else if(PyString_Check(obj))
+          {
+            MEDFileJoint *ret=self->getJointWithName(PyString_AsString(obj));
+            if(ret)
+              ret->incrRef();
+            return ret;
+          }
+        else
+          throw INTERP_KERNEL::Exception("MEDFileJoints::__getitem__ : only integer or string with meshname supported !");
+      }
+
+      int __len__() const throw(INTERP_KERNEL::Exception)
+      {
+        return self->getNumberOfJoints();
+      }
+
+      MEDFileJoint *getJointAtPos(int i) const throw(INTERP_KERNEL::Exception)
+      {
+        MEDFileJoint *ret=self->getJointAtPos(i);
+        if(ret)
+          ret->incrRef();
+        return ret;
+      }
+
+      MEDFileJoint *getJointWithName(const std::string& paramName) const throw(INTERP_KERNEL::Exception)
+      {
+        MEDFileJoint *ret=self->getJointWithName(paramName);
+        if(ret)
+          ret->incrRef();
+        return ret;
+      }
+    }
+  };
 
   class MEDFileMesh : public RefCountObject, public MEDFileWritable
   {
@@ -590,6 +813,9 @@ namespace ParaMEDMEM
     virtual DataArrayInt *getNodeGroupsArr(const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception);
     virtual DataArrayInt *getNodeFamilyArr(const std::string& fam, bool renum=false) const throw(INTERP_KERNEL::Exception);
     virtual DataArrayInt *getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum=false) const throw(INTERP_KERNEL::Exception);
+    int getNumberOfJoints();
+    MEDFileJoints *getJoints();
+    void           setJoints( MEDFileJoints* joints );
     %extend
        {
          std::string __str__() const throw(INTERP_KERNEL::Exception)
index 2682b2dd9baf1aef722ef277754b65919cb07bbb..bb5ec84d4312db52600e4630feca9335a8c82afc 100644 (file)
@@ -4360,5 +4360,131 @@ class MEDLoaderTest(unittest.TestCase):
         pass
 
     pass
+    def testMEDFileJoint1(self):
+        fileName="Pyfile88.med"
+        coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0)])
+        coo.setInfoOnComponents(["x [cm]","y [cm]","z [cm]"])
+        mm=MEDFileUMesh()
+        mm.setCoords(coo)
+        mm.setName("maa1")
+        mm.setDescription("un maillage")
+        mm.write(fileName,2)
+        node_correspond=MEDFileJointCorrespondence(DataArrayInt([1,2,3,4,5,6,7,8]))
+        cell_correspond=MEDFileJointCorrespondence(DataArrayInt([9,10,11,12]),NORM_TRI3,NORM_TRI3)
+        one_step_joint=MEDFileJointOneStep()
+        one_step_joint.pushCorrespondence(cell_correspond)
+        one_step_joint.pushCorrespondence(node_correspond)
+        one_joint=MEDFileJoint()
+        one_joint.pushStep(one_step_joint)
+        one_joint.setLocalMeshName("maa1")
+        one_joint.setRemoteMeshName("maa1")
+        one_joint.setDescription("joint_description")
+        one_joint.setJointName("joint_1")
+        one_joint.setDomainNumber(1)
+        self.assertEqual( one_joint.getLocalMeshName(), "maa1")
+        self.assertEqual( one_joint.getRemoteMeshName(), "maa1")
+        self.assertEqual( one_joint.getDescription(), "joint_description")
+        self.assertEqual( one_joint.getJointName(), "joint_1")
+        self.assertEqual( one_joint.getDomainNumber(), 1)
+        joints=MEDFileJoints()
+        joints.pushJoint(one_joint);
+        joints.write(fileName,0)
+        # read back
+        jointsR=MEDFileJoints(fileName,mm.getName())
+        self.assertEqual( jointsR.getNumberOfJoints(), 1 )
+        jR = jointsR.getJointAtPos(0)
+        self.assertTrue( jR.isEqual( one_joint ))
+        self.assertRaises( InterpKernelException, jointsR.getJointAtPos,1)
+        self.assertRaises( InterpKernelException, jointsR.destroyJointAtPos,1)
+        jointsR.destroyJointAtPos(0)
+        
+    pass
+    def testMEDFileJoint2(self):
+        fileNameWr="Pyfile89.med"
+        coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0)])
+        coo.setInfoOnComponents(["x [cm]","y [cm]","z [cm]"])
+        mm=MEDFileUMesh()
+        mm.setCoords(coo)
+        mm.setName("maa1")
+        mm.setDescription("un maillage")
+        node_correspond=MEDFileJointCorrespondence(DataArrayInt([13,14,15,16]))
+        cell_correspond=MEDFileJointCorrespondence(DataArrayInt([17,18]),NORM_TETRA4,NORM_PENTA6)
+        one_step_joint=MEDFileJointOneStep()
+        two_step_joint=MEDFileJointOneStep()
+        one_joint=MEDFileJoint()
+        two_joint=MEDFileJoint()
+        one_step_joint.pushCorrespondence(node_correspond)
+        one_joint.pushStep(one_step_joint)
+        two_step_joint.pushCorrespondence(cell_correspond)
+        two_step_joint.pushCorrespondence(node_correspond)
+        two_joint.pushStep(two_step_joint)
+        one_joint.setLocalMeshName("maa1")
+        one_joint.setRemoteMeshName("maa1")
+        one_joint.setDescription("joint_description_1")
+        one_joint.setJointName("joint_1")
+        one_joint.setDomainNumber(1)
+        two_joint.setLocalMeshName("maa1")
+        two_joint.setRemoteMeshName("maa1")
+        two_joint.setDescription("joint_description_2")
+        two_joint.setJointName("joint_2")
+        two_joint.setDomainNumber(2)
+        joints=MEDFileJoints()
+        joints.pushJoint(one_joint)
+        joints.pushJoint(two_joint)
+        mm.setJoints( joints )
+        mm.write(fileNameWr,2)
+        #
+        mm=MEDFileMesh.New(fileNameWr)
+        self.assertEqual( mm.getNumberOfJoints(), 2)
+        jointsR = mm.getJoints();
+        self.assertEqual( jointsR.getMeshName(), mm.getName() )
+        self.assertEqual( len( jointsR ), 2 )
+        jointR1 = jointsR[0]
+        jointR2 = jointsR[1]
+        self.assertFalse( jointR1 is None )
+        self.assertFalse( jointR2 is None )
+        self.assertTrue( jointR1.isEqual( one_joint ))
+        self.assertTrue( jointR2.isEqual( two_joint ))
+        pass
+
+    def testMEDFileJoint1(self):
+        node_correspond=MEDFileJointCorrespondence(DataArrayInt([1,2,3,4,5,6,7,8]))
+        cell_correspond=MEDFileJointCorrespondence(DataArrayInt([9,10,11,12]),NORM_TRI3,NORM_TRI3)
+        cell_correspon2=MEDFileJointCorrespondence(DataArrayInt([9,10,11]),NORM_TRI3,NORM_TRI3)
+        cell_correspon3=MEDFileJointCorrespondence(DataArrayInt([9,10,11,12]),NORM_TRI3,NORM_QUAD4)
+        joint1st_1=MEDFileJointOneStep()
+        joint1st_1.pushCorrespondence(cell_correspond)
+        joint1st_1.pushCorrespondence(node_correspond)
+        joint1st_2=MEDFileJointOneStep()
+        joint1st_2.pushCorrespondence(cell_correspond)
+        joint1st_2.pushCorrespondence(node_correspond)
+        joint1st_3=MEDFileJointOneStep()
+        joint1st_3.pushCorrespondence(node_correspond)
+        joint1st_3.pushCorrespondence(cell_correspond)
+        joint1st_4=MEDFileJointOneStep()
+        joint1st_4.pushCorrespondence(cell_correspond)
+        joint1st_5=MEDFileJointOneStep()
+        joint1st_5.pushCorrespondence(cell_correspon2)
+        joint1st_6=MEDFileJointOneStep()
+        joint1st_6.pushCorrespondence(cell_correspon3)
+        self.assertTrue( joint1st_1.isEqual( joint1st_2 ))
+        self.assertTrue( joint1st_1.isEqual( joint1st_3 ))
+        self.assertFalse( joint1st_1.isEqual( joint1st_4 ))
+        self.assertFalse( joint1st_4.isEqual( joint1st_5 ))
+        self.assertFalse( joint1st_4.isEqual( joint1st_6 ))
+        one_joint=MEDFileJoint()
+        one_joint.pushStep(joint1st_1)
+        one_joint.setLocalMeshName("maa1")
+        one_joint.setRemoteMeshName("maa2")
+        one_joint.setDescription("joint_description")
+        one_joint.setJointName("joint_1")
+        one_joint.setDomainNumber(1)
+        self.assertEqual( "maa1", one_joint.getLocalMeshName())
+        self.assertEqual( "maa2", one_joint.getRemoteMeshName())
+        self.assertEqual( "joint_description", one_joint.getDescription())
+        self.assertEqual( 1, one_joint.getDomainNumber())
+        self.assertEqual( "joint_1", one_joint.getJointName())
+        pass
+    pass
 
 unittest.main()
index d6003437cbce7a10332d1476c9bce0acea283cdf..2404e49f9c37b54b1c0c42cce152d1621757fe79 100644 (file)
@@ -78,8 +78,8 @@ SET(medpartitionercpp_HEADERS_HXX
   MEDPARTITIONER.hxx
   MEDPARTITIONER_ParaDomainSelector.hxx
   MEDPARTITIONER_ConnectZone.hxx
-  MEDPARTITIONER_SkyLineArray.hxx
   MEDPARTITIONER_Topology.hxx
+  MEDPARTITIONER_MEDPartitioner.hxx
   )
 
 SET(medpartitionercpp_SOURCES
@@ -93,8 +93,8 @@ SET(medpartitionercpp_SOURCES
   MEDPARTITIONER_Utils.cxx
   MEDPARTITIONER_ParaDomainSelector.cxx
   MEDPARTITIONER_ConnectZone.cxx
-  MEDPARTITIONER_SkyLineArray.cxx
   MEDPARTITIONER_metis.c
+  MEDPARTITIONER_MEDPartitioner.cxx
   )
 
 SET(medpartitionercpp_LDFLAGS
index 155526dbfb2ffcada861f7702c3fb61710db8efe..78fd1a0f49658cd085b8f1455f9f1e5b7a902239 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <map>
 
+using namespace ParaMEDMEM;
+
 MEDPARTITIONER::ConnectZone::ConnectZone():
   _name("")
   ,_description("")
@@ -35,7 +37,7 @@ MEDPARTITIONER::ConnectZone::~ConnectZone()
 {
   delete _node_corresp;
   delete _face_corresp;
-  for(std::map < std::pair <int, int>,SkyLineArray * >::iterator iter=_entity_corresp.begin(); iter!=_entity_corresp.end();iter++)
+  for(std::map < std::pair <int, int>,MEDCouplingSkyLineArray * >::iterator iter=_entity_corresp.begin(); iter!=_entity_corresp.end();iter++)
     {
       delete iter->second;
     }
@@ -84,7 +86,7 @@ ParaMEDMEM::MEDCouplingUMesh *MEDPARTITIONER::ConnectZone::getDistantMesh() cons
 
 bool MEDPARTITIONER::ConnectZone::isEntityCorrespPresent(int localEntity, int distantEntity) const
 {
-  typedef std::map<std::pair<int,int>, SkyLineArray*>::const_iterator map_iter;
+  typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter;
   for(map_iter iter=_entity_corresp.begin(); iter != _entity_corresp.end(); iter++)
     {
       if ((iter->first).first==localEntity && (iter->first).second==distantEntity)
@@ -108,6 +110,11 @@ int MEDPARTITIONER::ConnectZone::getNodeNumber() const
   return _node_corresp->getNumberOf();
 }
 
+const ParaMEDMEM::MEDCouplingSkyLineArray * MEDPARTITIONER::ConnectZone::getNodeCorresp() const
+{
+  return _node_corresp;
+}
+
 const int *MEDPARTITIONER::ConnectZone::getFaceCorrespIndex() const
 {
   return _face_corresp->getIndex();
@@ -123,56 +130,88 @@ int MEDPARTITIONER::ConnectZone::getFaceNumber() const
   return _face_corresp->getNumberOf();
 }
 
+const ParaMEDMEM::MEDCouplingSkyLineArray * MEDPARTITIONER::ConnectZone::getFaceCorresp() const
+{
+  return _face_corresp;
+}
+
 const int *MEDPARTITIONER::ConnectZone::getEntityCorrespIndex(int localEntity,
-                                               int distantEntity) const
+                                                              int distantEntity) const
 {
-  typedef std::map<std::pair<int,int>, SkyLineArray*>::const_iterator map_iter;
+  typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter;
 
   for(map_iter iter=_entity_corresp.begin();iter!=_entity_corresp.end();iter++)
-    {
-      if ((iter->first).first==localEntity && (iter->first).second==distantEntity)
-        return iter->second->getIndex();
-    }
+  {
+    if ((iter->first).first==localEntity && (iter->first).second==distantEntity)
+      return iter->second->getIndex();
+  }
   return 0;
 }
 
 const int *MEDPARTITIONER::ConnectZone::getEntityCorrespValue(int localEntity,
-                                               int distantEntity) const
+                                                              int distantEntity) const
 {
-  typedef std::map<std::pair<int,int>, SkyLineArray*>::const_iterator map_iter;
+  typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter;
 
   for (map_iter iter=_entity_corresp.begin();iter!=_entity_corresp.end();iter++)
-    {
-      if ((iter->first).first==localEntity && (iter->first).second==distantEntity)
-        return iter->second->getValue();
-    }
+  {
+    if ((iter->first).first==localEntity && (iter->first).second==distantEntity)
+      return iter->second->getValue();
+  }
   return 0;
 }
 
 int MEDPARTITIONER::ConnectZone::getEntityCorrespNumber(int localEntity,
-                                        int distantEntity) const
+                                                        int distantEntity) const
 {
-  typedef std::map<std::pair<int,int>, SkyLineArray*>::const_iterator map_iter;
+  typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter;
 
   for(map_iter iter=_entity_corresp.begin();iter!=_entity_corresp.end();iter++)
-    {
-      if((iter->first).first==localEntity && (iter->first).second==distantEntity)
-        return iter->second->getNumberOf();
-    }
+  {
+    if((iter->first).first==localEntity && (iter->first).second==distantEntity)
+      return iter->second->getNumberOf();
+  }
   return 0;
 }
 
 int MEDPARTITIONER::ConnectZone::getEntityCorrespLength(int localEntity,
-                                        int distantEntity) const
+                                                        int distantEntity) const
 {
-  typedef std::map<std::pair<int,int>, SkyLineArray*>::const_iterator map_iter;
-  
+  typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter;
+
   for (map_iter iter=_entity_corresp.begin(); iter != _entity_corresp.end(); iter++)
+  {
+    if ((iter->first).first==localEntity && (iter->first).second==distantEntity)
+      return iter->second->getLength();
+  }
+  return 0;
+}
+
+const ParaMEDMEM::MEDCouplingSkyLineArray *
+MEDPARTITIONER::ConnectZone::getEntityCorresp(int localEntity, int distantEntity) const
+{
+  typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter;
+
+  for (map_iter iter=_entity_corresp.begin(); iter != _entity_corresp.end(); iter++)
+  {
+    if ((iter->first).first==localEntity && (iter->first).second==distantEntity)
+      return iter->second;
+  }
+  return 0;
+}
+
+std::vector< std::pair< int,int > > MEDPARTITIONER::ConnectZone::getEntities() const
+{
+  std::vector< std::pair< int,int > > types;
+
+  std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator
+    iter = _entity_corresp.begin();
+  for ( ; iter != _entity_corresp.end(); iter++)
     {
-      if ((iter->first).first==localEntity && (iter->first).second==distantEntity)
-        return iter->second->getLength();
+      types.push_back( iter->first );
     }
-  return 0;
+
+  return types;
 }
 
 void MEDPARTITIONER::ConnectZone::setName(const std::string& name) 
@@ -207,33 +246,44 @@ void MEDPARTITIONER::ConnectZone::setDistantMesh(ParaMEDMEM::MEDCouplingUMesh *
 
 /*! transforms an int array containing 
  * the node-node connections
- * to a SkyLineArray
+ * to a MEDCouplingSkyLineArray
  */
-void MEDPARTITIONER::ConnectZone::setNodeCorresp(int * nodeCorresp, int nbnode)
+void MEDPARTITIONER::ConnectZone::setNodeCorresp(const int * nodeCorresp, int nbnode)
 {
-  std::vector<int> index(nbnode+1),value(2*nbnode);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> indexArr( DataArrayInt::New() );
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> valueArr( DataArrayInt::New() );
+  indexArr->alloc( nbnode+1 );
+  valueArr->alloc( 2*nbnode );
+  int * index = indexArr->getPointer();
+  int * value = valueArr->getPointer();
   for (int i=0; i<nbnode; i++)
     {
       index[i]=2*i;
-      value[2*i]=nodeCorresp[2*i];
+      value[2*i  ]=nodeCorresp[2*i];
       value[2*i+1]=nodeCorresp[2*i+1];
     }
   index[nbnode]=2*nbnode;
-  _node_corresp = new SkyLineArray(index,value);
+  setNodeCorresp( new MEDCouplingSkyLineArray( indexArr, valueArr ));
 }
 
-void MEDPARTITIONER::ConnectZone::setNodeCorresp(SkyLineArray* array)
+void MEDPARTITIONER::ConnectZone::setNodeCorresp(MEDCouplingSkyLineArray* array)
 {
+  if ( _node_corresp ) delete _node_corresp;
   _node_corresp = array;
 }
 
 /*! transforms an int array containing 
  * the face-face connections
- * to a SkyLineArray
+ * to a MEDCouplingSkyLineArray
  */
-void MEDPARTITIONER::ConnectZone::setFaceCorresp(int * faceCorresp, int nbface)
+void MEDPARTITIONER::ConnectZone::setFaceCorresp(const int * faceCorresp, int nbface)
 {
-  std::vector<int> index(nbface+1),value(2*nbface);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> indexArr( DataArrayInt::New() );
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> valueArr( DataArrayInt::New() );
+  indexArr->alloc( nbface+1 );
+  valueArr->alloc( 2*nbface );
+  int * index = indexArr->getPointer();
+  int * value = valueArr->getPointer();
   for (int i=0; i<nbface; i++)
     {
       index[i]=2*i;
@@ -241,43 +291,47 @@ void MEDPARTITIONER::ConnectZone::setFaceCorresp(int * faceCorresp, int nbface)
       value[2*i+1]=faceCorresp[2*i+1];
     }
   index[nbface]=2*nbface;
-  _face_corresp = new MEDPARTITIONER::SkyLineArray(index,value);
+  setFaceCorresp( new MEDCouplingSkyLineArray( indexArr, valueArr ));
 }
 
-void MEDPARTITIONER::ConnectZone::setFaceCorresp(SkyLineArray* array)
+void MEDPARTITIONER::ConnectZone::setFaceCorresp(MEDCouplingSkyLineArray* array)
 {
+  if ( _face_corresp ) delete _face_corresp;
   _face_corresp = array;
 }
 
 /*! transforms an int array containing 
  * the entity-entity connections
- * to a SkyLineArray
+ * to a MEDCouplingSkyLineArray
  * 
- * the resulting SkyLineArray is put in the map
+ * the resulting MEDCouplingSkyLineArray is put in the map
  */
 void MEDPARTITIONER::ConnectZone::setEntityCorresp(int localEntity, int distantEntity,
-                                                   int *entityCorresp, int nbentity)
+                                                   const int *entityCorresp, int nbentity)
 { 
-  std::vector<int> index(nbentity+1),value(2*nbentity);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> indexArr( DataArrayInt::New() );
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> valueArr( DataArrayInt::New() );
+  indexArr->alloc( nbentity+1 );
+  valueArr->alloc( 2*nbentity );
+  int * index = indexArr->getPointer();
+  int * value = valueArr->getPointer();
   for (int i=0; i<nbentity; i++)
     {
       index[i]=2*i;
-      value[2*i]=entityCorresp[2*i];
+      value[2*i  ]=entityCorresp[2*i];
       value[2*i+1]=entityCorresp[2*i+1];
     }
   index[nbentity]=2*nbentity;
-  _entity_corresp[std::make_pair(localEntity,distantEntity)] = new SkyLineArray(index,value);
+  setEntityCorresp( localEntity, distantEntity, new MEDCouplingSkyLineArray(indexArr,valueArr));
 }
 
 void MEDPARTITIONER::ConnectZone::setEntityCorresp(int localEntity, int distantEntity,
-                                                   SkyLineArray *array)
+                                                   MEDCouplingSkyLineArray *array)
 {
-  _entity_corresp[std::make_pair(localEntity,distantEntity)]=array;
+  ParaMEDMEM::MEDCouplingSkyLineArray * nullArray = 0;
+  std::map < std::pair <int,int>, ParaMEDMEM::MEDCouplingSkyLineArray * >::iterator it;
+  it = _entity_corresp.insert
+    ( std::make_pair( std::make_pair(localEntity,distantEntity), nullArray )).first;
+  if ( it->second != nullArray ) delete it->second;
+  it->second = array;
 }
-
-
-
-
-
-
-
index 83190cbee787d83fdabd968fc8b9820a21f180ed..8c1626dfdf3e23c52016bc4a45a7655344d0dbb0 100644 (file)
 
 #include "MEDPARTITIONER.hxx"
 #include "MEDCouplingUMesh.hxx"
-#include "MEDPARTITIONER_SkyLineArray.hxx"
+#include "MEDCouplingSkyLineArray.hxx"
 
 #include <map>
+#include <vector>
 #include <string>
 
 namespace MEDPARTITIONER
@@ -47,9 +48,11 @@ namespace MEDPARTITIONER
     const int *getNodeCorrespIndex() const;
     const int *getNodeCorrespValue() const;
     int getNodeNumber() const;
+    const ParaMEDMEM::MEDCouplingSkyLineArray * getNodeCorresp() const;
     const int *getFaceCorrespIndex() const;
     const int *getFaceCorrespValue() const;
     int getFaceNumber() const;
+    const ParaMEDMEM::MEDCouplingSkyLineArray * getFaceCorresp() const;
     const int *getEntityCorrespIndex(int localEntity,
                                      int distantEntity) const;
     const int *getEntityCorrespValue(int localEntity,
@@ -58,6 +61,10 @@ namespace MEDPARTITIONER
                                int distantEntity) const;
     int getEntityCorrespLength(int localEntity,
                                int distantEntity) const;
+    const ParaMEDMEM::MEDCouplingSkyLineArray * getEntityCorresp(int localEntity,
+                                                                 int distantEntity) const;
+    std::vector< std::pair< int,int > > getEntities() const;
+
     void setName(const std::string& name) ;
     void setDescription(const std::string& description) ;
     void setDistantDomainNumber(int distantDomainNumber) ;
@@ -65,14 +72,14 @@ namespace MEDPARTITIONER
     void setLocalMesh(ParaMEDMEM::MEDCouplingUMesh * localMesh) ;
     void setDistantMesh(ParaMEDMEM::MEDCouplingUMesh * distantMesh) ;
 
-    void setNodeCorresp(int * nodeCorresp, int nbnode);
-    void setNodeCorresp(MEDPARTITIONER::SkyLineArray* array);
-    void setFaceCorresp(int * faceCorresp, int nbface);
-    void setFaceCorresp(MEDPARTITIONER::SkyLineArray* array);
+    void setNodeCorresp(const int * nodeCorresp, int nbnode);
+    void setNodeCorresp(ParaMEDMEM::MEDCouplingSkyLineArray* array);
+    void setFaceCorresp(const int * faceCorresp, int nbface);
+    void setFaceCorresp(ParaMEDMEM::MEDCouplingSkyLineArray* array);
     void setEntityCorresp(int localEntity, int distantEntity,
-                          int * entityCorresp, int nbentity);
+                          const int * entityCorresp, int nbentity);
     void setEntityCorresp(int localEntity, int distantEntity,
-                          MEDPARTITIONER::SkyLineArray *array);
+                          ParaMEDMEM::MEDCouplingSkyLineArray *array);
   private :
     std::string _name;
     std::string _description;
@@ -82,10 +89,10 @@ namespace MEDPARTITIONER
     ParaMEDMEM::MEDCouplingUMesh * _local_mesh;
     ParaMEDMEM::MEDCouplingUMesh * _distant_mesh;
 
-    SkyLineArray * _node_corresp;
-    SkyLineArray * _face_corresp;
+    ParaMEDMEM::MEDCouplingSkyLineArray * _node_corresp;
+    ParaMEDMEM::MEDCouplingSkyLineArray * _face_corresp;
   
-    std::map < std::pair <int,int>, SkyLineArray * > _entity_corresp;
+    std::map < std::pair <int,int>, ParaMEDMEM::MEDCouplingSkyLineArray * > _entity_corresp;
   };
 }
 # endif
index a2a4b2feb7713e13081162931e000d8df5d98c05..62a273a6a1738643e3f21db967b74a482117ad4e 100644 (file)
@@ -19,7 +19,9 @@
 
 #include "MEDPARTITIONER_Graph.hxx"
 
-MEDPARTITIONER::Graph::Graph(MEDPARTITIONER::SkyLineArray *array, int *edgeweight):_graph(array),_partition(0),_edge_weight(edgeweight),_cell_weight(0)
+#include <set>
+
+MEDPARTITIONER::Graph::Graph(ParaMEDMEM::MEDCouplingSkyLineArray *array, int *edgeweight):_graph(array),_partition(0),_edge_weight(edgeweight),_cell_weight(0)
 {
 }
 
@@ -28,3 +30,15 @@ MEDPARTITIONER::Graph::~Graph()
   delete _partition;
   delete _graph;
 }
+
+int MEDPARTITIONER::Graph::nbDomains() const
+{
+  std::set<int> domains;
+  if ( _partition )
+    if ( ParaMEDMEM::DataArrayInt* array = _partition->getValueArray() )
+    {
+      for ( const int * dom = array->begin(); dom != array->end(); ++dom )
+        domains.insert( *dom );
+    }
+  return domains.size();
+}
index 6aaef4ba759f8ab3d8d05d33f6faeda51436cd86..33ea6760104f0712299e31779817159758dd1943 100644 (file)
 #define __MEDPARTITIONER_GRAPH_HXX__
 
 #include "MEDPARTITIONER.hxx"
-#include "MEDPARTITIONER_SkyLineArray.hxx"
+#include "MEDCouplingSkyLineArray.hxx"
 
 #include <string>
 
+namespace ParaMEDMEM
+{
+  class MEDCouplingSkyLineArray;
+}
+
 namespace MEDPARTITIONER 
 {
   class ParaDomainSelector;
@@ -33,28 +38,32 @@ namespace MEDPARTITIONER
   public:
     typedef enum {METIS,SCOTCH} splitter_type;
 
-    Graph() { }
+    Graph(){};
     //creates a graph from a SKYLINEARRAY
-    Graph(MEDPARTITIONER::SkyLineArray* graph, int* edgeweight=0);
+    Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight=0);
     virtual ~Graph();
 
     void setEdgesWeights(int *edgeweight) { _edge_weight=edgeweight; }
     void setVerticesWeights(int *cellweight) { _cell_weight=cellweight; }
     
     //computes partitioning of the graph
-    virtual void partGraph(int ndomain, const std::string&, ParaDomainSelector *sel=0) = 0;
+    virtual void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0) = 0;
     
     //returns the partitioning
     const int *getPart() const { return _partition->getValue(); }
     
     //returns the number of graph vertices (which can correspond to the cells in the mesh!)
     int nbVertices() const { return _graph->getNumberOf(); }
+
+    // returns nb of domains in _partition
+    int nbDomains() const;
     
-    const SkyLineArray *getGraph() const { return _graph; }
+    const ParaMEDMEM::MEDCouplingSkyLineArray *getGraph() const { return _graph; }
+    const ParaMEDMEM::MEDCouplingSkyLineArray *getPartition() const { return _partition; }
 
   protected:
-    SkyLineArray* _graph;
-    SkyLineArray* _partition;
+    ParaMEDMEM::MEDCouplingSkyLineArray* _graph;
+    ParaMEDMEM::MEDCouplingSkyLineArray* _partition;
     int* _edge_weight;  
     int* _cell_weight;
   };
diff --git a/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.cxx b/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.cxx
new file mode 100644 (file)
index 0000000..4ecca4e
--- /dev/null
@@ -0,0 +1,159 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// 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_MEDPartitioner.hxx"
+#include "MEDPARTITIONER_MeshCollection.hxx"
+#include "MEDPARTITIONER_Topology.hxx"
+#include "MEDPARTITIONER_ParaDomainSelector.hxx"
+#include "MEDPARTITIONER_ParallelTopology.hxx"
+#include "MEDPARTITIONER_Utils.hxx"
+#include "MEDPARTITIONER_Graph.hxx"
+#include "MEDPARTITIONER_MetisGraph.hxx"
+#include "MEDPARTITIONER_ScotchGraph.hxx"
+#include "MEDPARTITIONER_MeshCollectionDriver.hxx"
+#include "MEDCouplingUMesh.hxx"
+
+#include <iostream>
+#include <vector>
+
+MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const std::string& filename, int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory):
+  _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 )
+{
+  MyGlobals::_World_Size = 1;
+  MyGlobals::_Rank = 0;
+  MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces;
+  MyGlobals::_Create_Joints = create_joints;
+
+  ParaDomainSelector parallelizer(mesure_memory);
+  _input_collection=new MeshCollection(filename,parallelizer);
+  _input_collection->setParaDomainSelector( &parallelizer );
+
+  MEDPARTITIONER::ParallelTopology* aPT =
+    (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology();
+  aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() );
+  _input_collection->prepareFieldDescriptions();
+  createPartitionCollection(ndomains, library, creates_boundary_faces, create_joints, mesure_memory);
+
+  parallelizer.evaluateMemory();
+}
+
+MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const ParaMEDMEM::MEDFileData* filedata, int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory):
+  _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 )
+{
+  MyGlobals::_World_Size = 1;
+  MyGlobals::_Rank = 0;
+  MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces;
+  MyGlobals::_Create_Joints = create_joints;
+
+  ParaDomainSelector parallelizer(mesure_memory);
+  _input_collection=new MeshCollection();
+  _input_collection->setParaDomainSelector( &parallelizer );
+  _input_collection->retrieveDriver()->readMEDFileData(filedata);
+
+  MEDPARTITIONER::ParallelTopology* aPT =
+    (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology();
+  aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() );
+  _input_collection->prepareFieldDescriptions();
+  createPartitionCollection(ndomains, library, creates_boundary_faces, create_joints, mesure_memory);
+
+  parallelizer.evaluateMemory();
+}
+
+MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const ParaMEDMEM::MEDFileData* filedata, MEDPARTITIONER ::Graph* graph, bool creates_boundary_faces, bool create_joints, bool mesure_memory):
+  _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 )
+{
+  MyGlobals::_World_Size = 1;
+  MyGlobals::_Rank = 0;
+  MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces;
+  MyGlobals::_Create_Joints = create_joints;
+
+  ParaDomainSelector parallelizer(mesure_memory);
+  _input_collection=new MeshCollection();
+  _input_collection->setParaDomainSelector( &parallelizer );
+  _input_collection->retrieveDriver()->readMEDFileData(filedata);
+
+  MEDPARTITIONER::ParallelTopology* aPT =
+    (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology();
+  aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() );
+  _input_collection->prepareFieldDescriptions();
+
+  _new_topology = new MEDPARTITIONER::ParallelTopology( graph, aPT, graph->nbDomains(), _input_collection->getMeshDimension() );
+  _output_collection=new MeshCollection(*_input_collection,_new_topology,false,false);
+  _output_collection->filterFaceOnCell();
+
+  parallelizer.evaluateMemory();
+}
+
+MEDPARTITIONER::MEDPartitioner::~MEDPartitioner()
+{
+  delete _input_collection; _input_collection = 0;
+  delete _output_collection; _output_collection = 0;
+  delete _new_topology; _new_topology = 0;
+}
+
+void MEDPARTITIONER::MEDPartitioner::createPartitionCollection(int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory)
+{
+  //ParallelTopology* aPT = (ParallelTopology*) _input_collection->getTopology();
+  if (library == "metis")
+    _new_topology = _input_collection->createPartition(ndomains,MEDPARTITIONER::Graph::METIS);
+  else
+    _new_topology = _input_collection->createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH);
+  _output_collection=new MeshCollection(*_input_collection,_new_topology,false,false);
+  _output_collection->filterFaceOnCell();
+}
+
+void MEDPARTITIONER::MEDPartitioner::write(const std::string& filename)
+{
+  ParaDomainSelector parallelizer(false);
+  _output_collection->setParaDomainSelector( &parallelizer );
+  _output_collection->write(filename);
+  parallelizer.evaluateMemory();
+}
+
+ParaMEDMEM::MEDFileData* MEDPARTITIONER::MEDPartitioner::getMEDFileData()
+{
+  return _output_collection->retrieveDriver()->getMEDFileData();
+}
+
+MEDPARTITIONER::Graph* MEDPARTITIONER::MEDPartitioner::Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, Graph::splitter_type split, int* edgeweight)
+{
+  MEDPARTITIONER::Graph* cellGraph=0;
+  ParaMEDMEM::MEDCouplingSkyLineArray* arr = new ParaMEDMEM::MEDCouplingSkyLineArray(graph->getIndexArray(), graph->getValueArray());
+  switch (split)
+    {
+    case Graph::METIS:
+      if ( !cellGraph )
+        {
+#ifdef MED_ENABLE_METIS
+          cellGraph=new METISGraph(arr,edgeweight);
+#endif
+        }
+      if ( !cellGraph )
+        throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : PARMETIS/METIS is not available. Check your products, please.");
+      break;
+    case Graph::SCOTCH:
+#ifdef MED_ENABLE_SCOTCH
+      cellGraph=new SCOTCHGraph(arr,edgeweight);
+#else
+      throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : SCOTCH is not available. Check your products, please.");
+#endif
+      break;
+    }
+  return cellGraph;
+}
diff --git a/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.hxx b/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.hxx
new file mode 100644 (file)
index 0000000..d7c31ff
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// 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_MEDPARTITIONER_HXX__
+#define __MEDPARTITIONER_MEDPARTITIONER_HXX__
+
+#include "MEDPARTITIONER_Graph.hxx"
+
+#include <map>
+#include <vector>
+
+namespace ParaMEDMEM
+{
+  class DataArrayInt;
+  class MEDFileData;
+  class MEDCouplingSkyLineArray;
+}
+
+namespace MEDPARTITIONER
+{
+  class Topology;
+  class MeshCollection;
+  class ParaDomainSelector;
+  class Graph;
+  
+  class MEDPartitioner
+  {
+  public:
+    MEDPartitioner(const std::string& filename, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false);
+    MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false);
+    MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, Graph* graph, bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false);
+    static MEDPARTITIONER::Graph* Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, Graph::splitter_type split=Graph::METIS, int* edgeweight=0);
+    void write(const std::string& filename);
+    ParaMEDMEM::MEDFileData* getMEDFileData();
+    ~MEDPartitioner();
+
+    ParaMEDMEM::MEDFileData *convertToMEDFileData(MeshCollection* meshcollection);
+    void createPartitionCollection(int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory);
+
+  private:
+    MeshCollection* _input_collection;
+    MeshCollection* _output_collection;
+    Topology*       _new_topology;
+  };
+}
+#endif
index 8678cf7866505f86879f54c447e6319251191c88..ec806a93b700c8135e1c89c15288a416636bbd50 100644 (file)
 //
 
 #include "MEDPARTITIONER_MeshCollection.hxx"
+
+#include "MEDPARTITIONER_ConnectZone.hxx"
+#include "MEDPARTITIONER_Graph.hxx"
 #include "MEDPARTITIONER_MeshCollectionDriver.hxx"
-#include "MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx"
 #include "MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx"
+#include "MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx"
 #include "MEDPARTITIONER_ParaDomainSelector.hxx"
-#include "MEDPARTITIONER_Topology.hxx"
 #include "MEDPARTITIONER_ParallelTopology.hxx"
+#include "MEDPARTITIONER_Topology.hxx"
+#include "MEDPARTITIONER_UserGraph.hxx"
+#include "MEDPARTITIONER_Utils.hxx" 
 
 #ifdef HAVE_MPI
 #include "MEDPARTITIONER_JointFinder.hxx"
 #endif
 
-#include "MEDPARTITIONER_Graph.hxx"
-#include "MEDPARTITIONER_UserGraph.hxx"
-#include "MEDPARTITIONER_Utils.hxx" 
-
-#include "MEDLoaderBase.hxx"
-#include "MEDLoader.hxx"
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+#include "MEDCouplingFieldDouble.hxx"
 #include "MEDCouplingMemArray.hxx"
-#include "MEDCouplingUMesh.hxx"
 #include "MEDCouplingNormalizedUnstructuredMesh.hxx"
-#include "MEDCouplingFieldDouble.hxx"
-#include "PointLocator3DIntersectorP0P0.hxx"
-
-#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+#include "MEDCouplingUMesh.hxx"
+#include "MEDLoader.hxx"
+#include "MEDLoaderBase.hxx"
 
 #ifdef HAVE_MPI
 #include <mpi.h>
@@ -106,7 +105,9 @@ MEDPARTITIONER::MeshCollection::MeshCollection(MeshCollection& initialCollection
     _joint_finder(0)
 {
   std::vector<std::vector<std::vector<int> > > new2oldIds(initialCollection.getTopology()->nbDomain());
-  castCellMeshes(initialCollection, new2oldIds);
+  std::vector<ParaMEDMEM::DataArrayInt*> o2nRenumber;
+
+  castCellMeshes(initialCollection, new2oldIds, o2nRenumber );
 
   //defining the name for the collection and the underlying meshes
   setName(initialCollection.getName());
@@ -163,7 +164,7 @@ MEDPARTITIONER::MeshCollection::MeshCollection(MeshCollection& initialCollection
     std::cout << "treating groups" << std::endl;
   _family_info=initialCollection.getFamilyInfo();
   _group_info=initialCollection.getGroupInfo();
-  
+
 #ifdef HAVE_MPI
   if (MyGlobals::_Verbose>0 && MyGlobals::_World_Size>1)
     MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages
@@ -173,7 +174,7 @@ MEDPARTITIONER::MeshCollection::MeshCollection(MeshCollection& initialCollection
   castAllFields(initialCollection,"cellFieldDouble");
   if (_i_non_empty_mesh<0)
     {
-      for (int i=0; i<_mesh.size(); i++)
+      for (size_t i=0; i<_mesh.size(); i++)
         {
           if (_mesh[i])
             {
@@ -183,16 +184,28 @@ MEDPARTITIONER::MeshCollection::MeshCollection(MeshCollection& initialCollection
         }
     }
 
+  // find faces common with neighbor domains and put them in groups
+  buildBoundaryFaces();
+
+  //building the connect zones necessary for writing joints
+  buildConnectZones( nodeMapping, o2nRenumber, initialCollection.getTopology()->nbDomain() );
+
+  // delete o2nRenumber
+  for ( size_t i = 0; i < o2nRenumber.size(); ++i )
+    if ( o2nRenumber[i] )
+      o2nRenumber[i]->decrRef();
 }
 
 /*!
-  Creates the meshes using the topology underlying he mesh collection and the mesh data 
+  Creates the meshes using the topology underlying he mesh collection and the mesh data
   coming from the ancient collection
   \param initialCollection collection from which the data is extracted to create the new meshes
+  \param [out] o2nRenumber returns for each new domain a permutation array returned by sortCellsInMEDFileFrmt()
 */
 
 void MEDPARTITIONER::MeshCollection::castCellMeshes(MeshCollection& initialCollection,
-                                                    std::vector<std::vector<std::vector<int> > >& new2oldIds)
+                                                    std::vector<std::vector<std::vector<int> > >& new2oldIds,
+                                                    std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber)
 {
   if (MyGlobals::_Verbose>10)
     std::cout << "proc " << MyGlobals::_Rank << " : castCellMeshes" << std::endl;
@@ -203,6 +216,7 @@ void MEDPARTITIONER::MeshCollection::castCellMeshes(MeshCollection& initialColle
   int nbOldDomain=initialCollection.getTopology()->nbDomain();
   
   _mesh.resize(nbNewDomain);
+  o2nRenumber.resize(nbNewDomain,0);
   int rank=MyGlobals::_Rank;
   //splitting the initial domains into smaller bits
   std::vector<std::vector<ParaMEDMEM::MEDCouplingUMesh*> > splitMeshes;
@@ -266,22 +280,23 @@ void MEDPARTITIONER::MeshCollection::castCellMeshes(MeshCollection& initialColle
   for (int inew=0; inew<nbNewDomain ;inew++)
     {
       std::vector<const ParaMEDMEM::MEDCouplingUMesh*> meshes;
-    
+
       for (int i=0; i<(int)splitMeshes[inew].size(); i++)
-        if (splitMeshes[inew][i]!=0) 
+        if (splitMeshes[inew][i]!=0)
           if (splitMeshes[inew][i]->getNumberOfCells()>0)
             meshes.push_back(splitMeshes[inew][i]);
 
-           if (!isParallelMode()||_domain_selector->isMyDomain(inew))
+      if (!isParallelMode()||_domain_selector->isMyDomain(inew))
+        {
+          if (meshes.size()==0)
             {
-              if (meshes.size()==0) 
-                {
               _mesh[inew]=CreateEmptyMEDCouplingUMesh();
               std::cout << "WARNING : castCellMeshes fusing : no meshes try another number of processors" << std::endl;
             }
           else
             {
               _mesh[inew]=ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes(meshes);
+              o2nRenumber[inew]=_mesh[inew]->sortCellsInMEDFileFrmt();
               bool areNodesMerged;
               int nbNodesMerged;
               if (meshes.size()>1)
@@ -290,7 +305,6 @@ void MEDPARTITIONER::MeshCollection::castCellMeshes(MeshCollection& initialColle
                   array->decrRef(); // array is not used in this case
                 }
               _mesh[inew]->zipCoords();
-
             }
         }
       for (int i=0;i<(int)splitMeshes[inew].size();i++)
@@ -302,7 +316,7 @@ void MEDPARTITIONER::MeshCollection::castCellMeshes(MeshCollection& initialColle
 }
 
 /*!
-  \param initialCollection source mesh collection 
+  \param initialCollection source mesh collection
   \param nodeMapping structure containing the correspondency between nodes in the initial collection and the node(s) in the new collection
 */
 void MEDPARTITIONER::MeshCollection::createNodeMapping( MeshCollection& initialCollection, NodeMapping& nodeMapping)
@@ -936,6 +950,323 @@ void MEDPARTITIONER::MeshCollection::remapDoubleField(int inew, int iold,
     }
 }
 
+namespace
+{
+  using namespace ParaMEDMEM;
+  //================================================================================
+  /*!
+   * \brief Sort correspondence ids of one domain and permute ids of the other accordingly
+   *  \param [in,out] ids1 - ids of one domain
+   *  \param [in,out] ids2 - ids of another domain
+   *  \param [in] delta - a delta to change all ids
+   *  \param [in] removeEqual - to remove equal ids
+   *  \return DataArrayInt* - array of ids joined back
+   */
+  //================================================================================
+
+  DataArrayInt* sortCorrespondences( DataArrayInt* ids1,
+                                     DataArrayInt* ids2,
+                                     int           delta,
+                                     bool removeEqual = false)
+  {
+    // sort
+    MEDCouplingAutoRefCountObjectPtr< DataArrayInt > renumN2O = ids1->buildPermArrPerLevel();
+    ids1->renumberInPlaceR( renumN2O->begin() );
+    ids2->renumberInPlaceR( renumN2O->begin() );
+
+    if ( removeEqual )
+      {
+        ids1 = ids1->buildUnique();
+        ids2 = ids2->buildUnique();
+      }
+    if ( delta != 0 )
+      {
+        int * id = ids1->getPointer();
+        for ( ; id < ids1->end(); ++id )
+          ++(*id);
+        id = ids2->getPointer();
+        for ( ; id < ids2->end(); ++id )
+          ++(*id);
+      }
+
+    // join
+    DataArrayInt* ids12 = DataArrayInt::Meld( ids1, ids2 ); // two components
+    ids12->rearrange( 1 ); // make one component
+    return ids12;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Renumber ids according to mesh->sortCellsInMEDFileFrmt()
+   *  \param [in,out] ids - cell ids to renumber
+   *  \param [in] o2nRenumber - renumbering array in "Old to New" mode
+   */
+  //================================================================================
+
+  void renumber( DataArrayInt* ids, const DataArrayInt* o2nRenumber )
+  {
+    if ( !ids || !o2nRenumber )
+      return;
+    int *        id = ids->getPointer();
+    const int * o2n = o2nRenumber->getConstPointer();
+    for ( ; id < ids->end(); ++id )
+      {
+        *id = o2n[ *id ];
+      }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Fill up ConnectZone's stored in _topology with nodal correspondences
+ *  \param [in] nodeMapping - mapping between old nodes and new nodes
+ *              (iolddomain,ioldnode)->(inewdomain,inewnode)
+ *  \param [in] o2nRenumber - renumbering array returned by mesh->sortCellsInMEDFileFrmt()
+ *              per a new domain
+ *  \param [in] nbInitialDomains - nb of old domains
+ */
+//================================================================================
+
+void MEDPARTITIONER::MeshCollection::buildConnectZones( const NodeMapping& nodeMapping,
+                                                        const std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber,
+                                                        int                nbInitialDomains)
+{
+  if ( !MyGlobals::_Create_Joints || _topology->nbDomain() < 2 )
+    return;
+
+  if ( MyGlobals::_World_Size > 1 )
+    {
+      _topology->getCZ().clear();
+      return; // not implemented for parallel mode
+    }
+
+  //  at construction, _topology creates cell correspondences basing on Graph information,
+  // and here we
+  // 1) add node correspondences,
+  // 2) split cell correspondences by cell geometry types
+  // 3) sort ids to be in ascending order
+
+  const int nb_domains = _topology->nbDomain();
+
+  // ==================================
+  // 1) add node correspondences
+  // ==================================
+
+  std::vector< std::vector< std::vector< int > > > nodeCorresp( nb_domains );
+  for ( int idomain = 0; idomain < nb_domains; ++idomain )
+    {
+      nodeCorresp[ idomain ].resize( nb_domains );
+    }
+
+  NodeMapping::const_iterator nmIt1, nmIt2 = nodeMapping.begin();
+  for ( nmIt1 = nmIt2; nmIt1 != nodeMapping.end(); nmIt1 = nmIt2 )
+    {
+      // look for an "old" node mapped into several "new" nodes in different domains
+      int nbSameOld = 0;
+      while ( ++nmIt2 != nodeMapping.end() && nmIt2->first == nmIt1->first )
+        nbSameOld += ( nmIt2->second != nmIt1->second );
+
+      if ( nbSameOld > 0 )
+        {
+          NodeMapping::const_iterator nmEnd = nmIt2;
+          for ( ; true; ++nmIt1 )
+            {
+              nmIt2 = nmIt1;
+              if ( ++nmIt2 == nmEnd )
+                break;
+              int dom1  = nmIt1->second.first;
+              int node1 = nmIt1->second.second;
+              for ( ; nmIt2 != nmEnd; ++nmIt2 )
+                {
+                  int dom2  = nmIt2->second.first;
+                  int node2 = nmIt2->second.second;
+                  if ( dom1 != dom2 )
+                    {
+                      nodeCorresp[ dom1 ][ dom2 ].push_back( node1 );
+                      nodeCorresp[ dom1 ][ dom2 ].push_back( node2 );
+                      nodeCorresp[ dom2 ][ dom1 ].push_back( node2 );
+                      nodeCorresp[ dom2 ][ dom1 ].push_back( node1 );
+                    }
+                }
+            }
+        }
+    }
+
+  // add nodeCorresp to czVec
+
+  std::vector<MEDPARTITIONER::ConnectZone*>& czVec = _topology->getCZ();
+
+  for ( int idomain = 0; idomain < nb_domains; ++idomain )
+    {
+      for ( int idomainNear = 0; idomainNear < nb_domains; ++idomainNear )
+        {
+          std::vector< int > & corresp = nodeCorresp[ idomain ][ idomainNear ];
+          if ( corresp.empty() )
+            continue;
+
+          MEDPARTITIONER::ConnectZone* cz = 0;
+          for ( size_t i = 0; i < czVec.size() && !cz; ++i )
+            if ( czVec[i] &&
+                 czVec[i]->getLocalDomainNumber  () == idomain &&
+                 czVec[i]->getDistantDomainNumber() == idomainNear )
+              cz = czVec[i];
+
+          if ( !cz )
+            {
+              cz = new MEDPARTITIONER::ConnectZone();
+              cz->setName( "Nodal Connect Zone defined by MEDPARTITIONER" );
+              cz->setLocalDomainNumber  ( idomain );
+              cz->setDistantDomainNumber( idomainNear );
+              czVec.push_back(cz);
+            }
+
+          cz->setNodeCorresp( &corresp[0], corresp.size()/2 );
+        }
+    }
+
+  // ==========================================================
+  // 2) split cell correspondences by cell geometry types
+  // ==========================================================
+
+  for ( size_t i = 0; i < czVec.size(); ++i )
+    {
+      MEDPARTITIONER::ConnectZone* cz = czVec[i];
+      if ( !cz                                         ||
+           cz->getEntityCorrespNumber( 0,0 ) == 0      ||
+           cz->getLocalDomainNumber  () > (int)_mesh.size() ||
+           cz->getDistantDomainNumber() > (int)_mesh.size() )
+        continue;
+      ParaMEDMEM::MEDCouplingUMesh* mesh1 = _mesh[ cz->getLocalDomainNumber  () ];
+      ParaMEDMEM::MEDCouplingUMesh* mesh2 = _mesh[ cz->getDistantDomainNumber() ];
+
+      // separate ids of two domains
+      const ParaMEDMEM::MEDCouplingSkyLineArray *corrArray = cz->getEntityCorresp( 0, 0 );
+      const DataArrayInt* ids12 = corrArray->getValueArray();
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1, ids2, ids12Sorted;
+      ids1 = ids12->selectByTupleId2( 0, corrArray->getLength(), 2 );
+      ids2 = ids12->selectByTupleId2( 1, corrArray->getLength(), 2 );
+
+      // renumber cells according to mesh->sortCellsInMEDFileFrmt()
+      renumber( ids1, o2nRenumber[ cz->getLocalDomainNumber() ]);
+      renumber( ids2, o2nRenumber[ cz->getDistantDomainNumber() ]);
+
+      // check nb cell types
+      std::set<INTERP_KERNEL::NormalizedCellType> types1, types2;
+      types1 = mesh1->getTypesOfPart( ids1->begin(), ids1->end() );
+      types2 = mesh2->getTypesOfPart( ids2->begin(), ids2->end() );
+      if ( types1.size() < 1 || types2.size() < 1 )
+        continue; // parallel mode?
+
+      MEDPARTITIONER::ConnectZone* cz21 = 0; // zone 2 -> 1
+      for ( size_t j = 0; j < czVec.size() && !cz21; ++j )
+        if ( czVec[j] &&
+             czVec[j]->getLocalDomainNumber  () == cz->getDistantDomainNumber() &&
+             czVec[j]->getDistantDomainNumber() == cz->getLocalDomainNumber() )
+          cz21 = czVec[j];
+
+      if ( types1.size() == 1 && types2.size() == 1 ) // split not needed, only sort
+        {
+          ids12Sorted = sortCorrespondences( ids1, ids2, /*delta=*/1 );
+          cz->setEntityCorresp( *types1.begin(), *types2.begin(),
+                                ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 );
+
+          if ( cz21 )// set 2->1 correspondence
+          {
+            ids12Sorted = sortCorrespondences( ids2, ids1, /*delta=*/0 );
+            cz21->setEntityCorresp( *types2.begin(), *types1.begin(),
+                                    ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 );
+          }
+        }
+      else // split and sort
+        {
+          typedef std::pair< std::vector< int >, std::vector< int > > T2Vecs;
+          T2Vecs idsByType[ INTERP_KERNEL::NORM_MAXTYPE ][ INTERP_KERNEL::NORM_MAXTYPE ];
+          int t1, t2;
+
+          const int nbIds = ids1->getNbOfElems();
+          const int * p1 = ids1->begin(), * p2 = ids2->begin();
+          for ( int i = 0; i < nbIds; ++i )
+            {
+              t1 = mesh1->getTypeOfCell( p1[ i ]);
+              t2 = mesh2->getTypeOfCell( p2[ i ]);
+              T2Vecs & ids = idsByType[ t1 ][ t2 ];
+              ids.first .push_back( p1[ i ]);
+              ids.second.push_back( p1[ i ]);
+            }
+
+          const int maxType = int( INTERP_KERNEL::NORM_MAXTYPE );
+          for ( t1 = 0; t1 < maxType; ++t1 )
+            for ( t2 = 0; t2 < maxType; ++t2 )
+              {
+                T2Vecs & ids = idsByType[ t1 ][ t2 ];
+                if ( ids.first.empty() ) continue;
+                p1 = & ids.first[0];
+                p2 = & ids.second[0];
+                ids1->desallocate();
+                ids1->pushBackValsSilent( p1, p1+ids.first.size() );
+                ids2->desallocate();
+                ids2->pushBackValsSilent( p2, p2+ids.first.size() );
+                ids12Sorted = sortCorrespondences( ids1, ids2, /*delta=*/1 );
+
+                cz->setEntityCorresp( t1, t2,
+                                      ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 );
+
+                if ( cz21 )// set 2->1 correspondence
+                  {
+                    ids12Sorted = sortCorrespondences( ids2, ids1, /*delta=*/0 );
+                    cz21->setEntityCorresp( t2, t1,
+                                            ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 );
+                    break;
+                  }
+              }
+        }// split and sort
+
+      cz->setEntityCorresp( 0, 0, 0, 0 ); // erase ids computed by _topology
+      if ( cz21 )
+        cz21->setEntityCorresp( 0, 0, 0, 0 );
+
+    } // loop on czVec
+
+
+  // ==========================================
+  // 3) sort node ids to be in ascending order
+  // ==========================================
+
+  const bool removeEqual = ( nbInitialDomains > 1 );
+
+  for ( size_t i = 0; i < czVec.size(); ++i )
+    {
+      MEDPARTITIONER::ConnectZone* cz = czVec[i];
+      if ( !cz || cz->getNodeNumber() < 1 )
+        continue;
+      if ( cz->getDistantDomainNumber() < cz->getLocalDomainNumber() )
+        continue; // treat a pair of domains once
+
+      MEDPARTITIONER::ConnectZone* cz21 = 0; // zone 2 -> 1
+      for ( size_t j = 0; j < czVec.size() && !cz21; ++j )
+        if ( czVec[j] &&
+             czVec[j]->getLocalDomainNumber  () == cz->getDistantDomainNumber() &&
+             czVec[j]->getDistantDomainNumber() == cz->getLocalDomainNumber() )
+          cz21 = czVec[j];
+
+      // separate ids of two domains
+      const ParaMEDMEM::MEDCouplingSkyLineArray *corrArray = cz->getNodeCorresp();
+      const DataArrayInt *ids12 = corrArray->getValueArray();
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1, ids2, ids12Sorted;
+      ids1 = ids12->selectByTupleId2( 0, corrArray->getLength(), 2 );
+      ids2 = ids12->selectByTupleId2( 1, corrArray->getLength(), 2 );
+
+      ids12Sorted = sortCorrespondences( ids1, ids2, /*delta=*/0, removeEqual );
+      cz->setNodeCorresp( ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 );
+
+      if ( cz21 )// set 2->1 correspondence
+        {
+          ids12Sorted = sortCorrespondences( ids2, ids1, /*delta=*/0, false );
+          cz->setNodeCorresp( ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 );
+        }
+    }
+}
+
 //================================================================================
 /*!
  * \brief Find faces common with neighbor domains and put them in "JOINT_n_p_Faces"
@@ -943,8 +1274,11 @@ void MEDPARTITIONER::MeshCollection::remapDoubleField(int inew, int iold,
  */
 //================================================================================
 
-void MEDPARTITIONER::MeshCollection::buildConnectZones()
+void MEDPARTITIONER::MeshCollection::buildBoundaryFaces()
 {
+  if (_topology->nbDomain() < 2 || !_subdomain_boundary_creates )
+    return;
+
   if ( getMeshDimension() < 2 )
     return;
 
@@ -1129,7 +1463,7 @@ void MEDPARTITIONER::MeshCollection::createJointGroup( const std::vector< int >&
 
   // remove faces from the familyID-the family
   if ( familyID != 0 && famIDs )
-    for ( size_t i = 0; i < totalNbFaces; ++i )
+    for ( int i = 0; i < totalNbFaces; ++i )
       if ( famIDs[i] == familyID )
         famIDs[i] = 0;
 
@@ -1441,9 +1775,6 @@ MEDPARTITIONER::MeshCollection::~MeshCollection()
  */
 void MEDPARTITIONER::MeshCollection::write(const std::string& filename)
 {
-  //building the connect zones necessary for writing joints
-  if (_topology->nbDomain()>1 && _subdomain_boundary_creates )
-    buildConnectZones();
   //suppresses link with driver so that it can be changed for writing
   delete _driver;
   _driver=0;
@@ -1491,7 +1822,7 @@ int MEDPARTITIONER::MeshCollection::getMeshDimension() const
 int MEDPARTITIONER::MeshCollection::getNbOfLocalMeshes() const
 {
   int nb=0;
-  for (int i=0; i<_mesh.size(); i++)
+  for (size_t i=0; i<_mesh.size(); i++)
     {
       if (_mesh[i]) nb++;
     }
@@ -1501,7 +1832,7 @@ int MEDPARTITIONER::MeshCollection::getNbOfLocalMeshes() const
 int MEDPARTITIONER::MeshCollection::getNbOfLocalCells() const
 {
   int nb=0;
-  for (int i=0; i<_mesh.size(); i++)
+  for (size_t i=0; i<_mesh.size(); i++)
     {
       if (_mesh[i]) nb=nb+_mesh[i]->getNumberOfCells();
     }
@@ -1511,7 +1842,7 @@ int MEDPARTITIONER::MeshCollection::getNbOfLocalCells() const
 int MEDPARTITIONER::MeshCollection::getNbOfLocalFaces() const
 {
   int nb=0;
-  for (int i=0; i<_face_mesh.size(); i++)
+  for (size_t i=0; i<_face_mesh.size(); i++)
     {
       if (_face_mesh[i]) nb=nb+_face_mesh[i]->getNumberOfCells();
     }
@@ -1540,7 +1871,11 @@ ParaMEDMEM::MEDCouplingUMesh* MEDPARTITIONER::MeshCollection::getFaceMesh(int id
 
 std::vector<MEDPARTITIONER::ConnectZone*>& MEDPARTITIONER::MeshCollection::getCZ()
 {
-  return _connect_zones;
+  if ( _topology )
+    return _topology->getCZ();
+
+  static std::vector<MEDPARTITIONER::ConnectZone*> noCZ;
+  return noCZ;
 }
 
 MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::getTopology() const
@@ -1548,23 +1883,26 @@ MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::getTopology() const
   return _topology;
 }
 
-void MEDPARTITIONER::MeshCollection::setTopology(Topology* topo)
+void MEDPARTITIONER::MeshCollection::setTopology(Topology* topo, bool takeOwneship)
 {
   if (_topology!=0)
     {
       throw INTERP_KERNEL::Exception("topology is already set");
     }
   else
-    _topology = topo;
+    {
+      _topology = topo;
+      _owns_topology = takeOwneship;
+    }
 }
 
-/*! Method creating the cell graph in serial mode 
- * 
- * \param array returns the pointer to the structure that contains the graph 
+/*! Method creating the cell graph in serial mode
+ *
+ * \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 MEDPARTITIONER::MeshCollection::buildCellGraph(MEDPARTITIONER::SkyLineArray* & array, int *& edgeweights )
+void MEDPARTITIONER::MeshCollection::buildCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array, int *& edgeweights )
 {
 
   using std::map;
@@ -1583,106 +1921,10 @@ void MEDPARTITIONER::MeshCollection::buildCellGraph(MEDPARTITIONER::SkyLineArray
         vector<int> value;
         vector<int> index(1,0);
         
-        array=new MEDPARTITIONER::SkyLineArray(index,value);
+        array=new ParaMEDMEM::MEDCouplingSkyLineArray(index,value);
         return;
      }
-  
-  int meshDim = mesh->getMeshDimension();
-  
-   ParaMEDMEM::DataArrayInt* indexr=ParaMEDMEM::DataArrayInt::New();
-   ParaMEDMEM::DataArrayInt* revConn=ParaMEDMEM::DataArrayInt::New();
-   int nbNodes=mesh->getNumberOfNodes();
-   mesh->getReverseNodalConnectivity(revConn,indexr);
-   //problem saturation over 1 000 000 nodes for 1 proc
-   if (MyGlobals::_Verbose>100)
-      std::cout << "proc " << MyGlobals::_Rank << " : getReverseNodalConnectivity done on " << nbNodes << " nodes" << std::endl;
-   const int* indexr_ptr=indexr->getConstPointer();
-   const int* revConn_ptr=revConn->getConstPointer();
-   
-   const ParaMEDMEM::DataArrayInt* index;
-   const ParaMEDMEM::DataArrayInt* conn;
-   conn=mesh->getNodalConnectivity();
-   index=mesh->getNodalConnectivityIndex();
-   int nbCells=mesh->getNumberOfCells();
-    if (MyGlobals::_Verbose>100)
-      std::cout << "proc " << MyGlobals::_Rank << " : getNodalConnectivity done on " << nbNodes << " nodes" << std::endl;
-   const int* index_ptr=index->getConstPointer();
-   const int* conn_ptr=conn->getConstPointer();
-  //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
-  //warning here one node have less than or equal effective number of cell with it
-  //but cell could have more than effective nodes
-  //because other equals nodes in other domain (with other global inode)
-  if (MyGlobals::_Verbose>50)
-    std::cout<< "proc " << MyGlobals::_Rank << " : creating graph arcs on nbNodes " << _topology->nbNodes() << std::endl;
- vector <int> cell2cell_index(nbCells+1,0);
- vector <int> cell2cell;
- cell2cell.reserve(3*nbCells);
-
- for (int icell=0; icell<nbCells;icell++)
-   {
-      map<int,int > counter;
-      for (int iconn=index_ptr[icell]; iconn<index_ptr[icell+1];iconn++)
-      {
-          int inode=conn_ptr[iconn];
-          for (int iconnr=indexr_ptr[inode]; iconnr<indexr_ptr[inode+1];iconnr++)
-          {
-              int icell2=revConn_ptr[iconnr];
-              map<int,int>::iterator iter=counter.find(icell2); 
-              if (iter!=counter.end()) (iter->second)++;
-              else counter.insert(make_pair(icell2,1));
-          }
-      }
-      for (map<int,int>::const_iterator iter=counter.begin();
-              iter!=counter.end();
-              iter++)
-            if (iter->second >= meshDim)
-              {
-                cell2cell_index[icell+1]++;
-                cell2cell.push_back(iter->first);
-            }
-                    
-           
-   }
- indexr->decrRef();
- revConn->decrRef();
-
- cell2cell_index[0]=0;  
- for (int icell=0; icell<nbCells;icell++)
-     cell2cell_index[icell+1]=cell2cell_index[icell]+cell2cell_index[icell+1];
-   
-  
-  if (MyGlobals::_Verbose>50)
-    std::cout << "proc " << MyGlobals::_Rank << " : create skylinearray" << std::endl;
-
-  //filling up index and value to create skylinearray structure
-  array=new MEDPARTITIONER::SkyLineArray(cell2cell_index,cell2cell);
-
-  if (MyGlobals::_Verbose>100)
-    {
-      std::cout << "\nproc " << _domain_selector->rank() << " : end MeshCollection::buildCellGraph " <<
-        cell2cell_index.size()-1 << " " << cell2cell.size() << std::endl;
-      int max=cell2cell_index.size()>15?15:cell2cell_index.size();
-      if (cell2cell_index.size()>1)
-        {
-          for (int i=0; i<max; ++i)
-            std::cout<<cell2cell_index[i]<<" ";
-          std::cout << "... " << cell2cell_index[cell2cell_index.size()-1] << std::endl;
-          for (int i=0; i<max; ++i)
-            std::cout<< cell2cell[i] << " ";
-          int ll=cell2cell_index[cell2cell_index.size()-1]-1;
-          std::cout << "... (" << ll << ") " << cell2cell[ll-1] << " " << cell2cell[ll] << std::endl;
-        }
-    }
-  
+  array=mesh->generateGraph();
 }
 /*! Method creating the cell graph in multidomain mode
  * 
@@ -1690,7 +1932,7 @@ void MEDPARTITIONER::MeshCollection::buildCellGraph(MEDPARTITIONER::SkyLineArray
  * \param edgeweight returns the pointer to the table that contains the edgeweights
  *        (only used if indivisible regions are required)
  */
-void MEDPARTITIONER::MeshCollection::buildParallelCellGraph(MEDPARTITIONER::SkyLineArray* & array, int *& edgeweights )
+void MEDPARTITIONER::MeshCollection::buildParallelCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array, int *& edgeweights )
 {
   using std::multimap;
   using std::vector;
@@ -1858,7 +2100,7 @@ void MEDPARTITIONER::MeshCollection::buildParallelCellGraph(MEDPARTITIONER::SkyL
         }
     }
 
-  array=new MEDPARTITIONER::SkyLineArray(index,value);
+  array=new ParaMEDMEM::MEDCouplingSkyLineArray(index,value);
 
   if (MyGlobals::_Verbose>100)
     {
@@ -1887,44 +2129,44 @@ void MEDPARTITIONER::MeshCollection::buildParallelCellGraph(MEDPARTITIONER::SkyL
  * returns a topology based on the new graph
  */
 MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(int nbdomain,
-                                                                          Graph::splitter_type split, 
+                                                                          Graph::splitter_type split,
                                                                           const std::string& options_string,
                                                                           int *user_edge_weights,
                                                                           int *user_vertices_weights)
 {
   if (MyGlobals::_Verbose>10)
     std::cout << "proc " << MyGlobals::_Rank << " : MeshCollection::createPartition : Building cell graph" << std::endl;
-  
+
   if (nbdomain <1)
     throw INTERP_KERNEL::Exception("Number of subdomains must be > 0");
-  MEDPARTITIONER::SkyLineArray* array=0;
+  ParaMEDMEM::MEDCouplingSkyLineArray* array=0;
   int* edgeweights=0;
 
   if (_topology->nbDomain()>1 || isParallelMode())
     buildParallelCellGraph(array,edgeweights);
   else
     buildCellGraph(array,edgeweights);
-  
+
   Graph* cellGraph = 0;
   switch (split)
     {
     case Graph::METIS:
       if ( isParallelMode() && MyGlobals::_World_Size > 1 )
-      {
+        {
 #ifdef MED_ENABLE_PARMETIS
-        if (MyGlobals::_Verbose>10)
-          std::cout << "ParMETISGraph" << std::endl;
-        cellGraph=new ParMETISGraph(array,edgeweights);
+          if (MyGlobals::_Verbose>10)
+            std::cout << "ParMETISGraph" << std::endl;
+          cellGraph=new ParMETISGraph(array,edgeweights);
 #endif
-      }
+        }
       if ( !cellGraph )
-      {
+        {
 #ifdef MED_ENABLE_METIS
-        if (MyGlobals::_Verbose>10)
-          std::cout << "METISGraph" << std::endl;
-        cellGraph=new METISGraph(array,edgeweights);
+          if (MyGlobals::_Verbose>10)
+            std::cout << "METISGraph" << std::endl;
+          cellGraph=new METISGraph(array,edgeweights);
 #endif
-      }
+        }
       if ( !cellGraph )
         throw INTERP_KERNEL::Exception("MeshCollection::createPartition : PARMETIS/METIS is not available. Check your products, please.");
       break;
@@ -1971,7 +2213,7 @@ MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(int nb
  */
 MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(const int* partition)
 {
-  MEDPARTITIONER::SkyLineArray* array=0;
+  ParaMEDMEM::MEDCouplingSkyLineArray* array=0;
   int* edgeweights=0;
 
   if ( _topology->nbDomain()>1)
@@ -2052,6 +2294,10 @@ void MEDPARTITIONER::MeshCollection::prepareFieldDescriptions()
 //filter _field_descriptions to be in all procs compliant and equal
 {
   int nbfiles=MyGlobals::_File_Names.size(); //nb domains
+  if (nbfiles==0)
+    {
+      nbfiles=_topology->nbDomain();
+    }
   std::vector<std::string> r2;
   //from allgatherv then vector(procs) of serialised vector(fields) of vector(description) data
   for (int i=0; i<(int)_field_descriptions.size(); i++)
index 04a7083b259efde6c0e9f05c13873fc9bfd8ad14..a4eec9a4cfe99342ba8315900189d0be97fbbf58 100644 (file)
@@ -36,6 +36,7 @@ namespace ParaMEDMEM
 {
   class MEDCouplingUMesh;
   class DataArrayInt;
+  class MEDCouplingSkyLineArray;
 }
 
 namespace MEDPARTITIONER
@@ -43,7 +44,6 @@ namespace MEDPARTITIONER
   class Topology;
   class MeshCollectionDriver;
   class ParaDomainSelector;
-  class SkyLineArray;
   class ConnectZone;
   class JointFinder;
   
@@ -75,9 +75,9 @@ namespace MEDPARTITIONER
     void setDriverType(MEDPARTITIONER::DriverType type) { _driver_type=type; }
 
     //creation of the cell graph
-    void buildCellGraph(MEDPARTITIONER::SkyLineArray* & array,int *& edgeweights );
+    void buildCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array,int *& edgeweights );
    //creation of the cell graph
-    void buildParallelCellGraph(MEDPARTITIONER::SkyLineArray* & array,int *& edgeweights );
+    void buildParallelCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array,int *& edgeweights );
 
     //creation and partition of the associated graph
     Topology* createPartition(int nbdomain, Graph::splitter_type type = Graph::METIS,
@@ -122,8 +122,9 @@ namespace MEDPARTITIONER
     //getting a pointer to topology
     Topology* getTopology() const ;
     ParaDomainSelector* getParaDomainSelector() const { return _domain_selector; }
+    void setParaDomainSelector(ParaDomainSelector* pds) { _domain_selector = pds; }
     //setting a new topology
-    void setTopology(Topology* topology);
+    void setTopology(Topology* topology, bool takeOwneship);
 
     //getting/setting the name of the global mesh (as opposed 
     //to the name of a subdomain \a nn, which is name_nn) 
@@ -131,6 +132,8 @@ namespace MEDPARTITIONER
     void setName(const std::string& name) { _name=name; }
     void setDomainNames(const std::string& name);
 
+    void setNonEmptyMesh(int number) { _i_non_empty_mesh=number;}
+
     //getting/setting the description of the global mesh
     std::string getDescription() const { return _description; }
     void setDescription(const std::string& name) { _description=name; }
@@ -140,7 +143,8 @@ namespace MEDPARTITIONER
                            std::multimap<std::pair<int,int>,std::pair<int,int> >& nodeMapping);
     
     void castCellMeshes(MeshCollection& initialCollection, 
-                        std::vector<std::vector<std::vector<int> > >& new2oldIds);
+                        std::vector<std::vector<std::vector<int> > >& new2oldIds,
+                        std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber);
     
     //creates faces on the new collection
     void castFaceMeshes(MeshCollection& initialCollection,
@@ -148,7 +152,12 @@ namespace MEDPARTITIONER
                         std::vector<std::vector<std::vector<int> > >& new2oldIds);
 
     //constructing connect zones
-    void buildConnectZones();
+    void buildConnectZones( const NodeMapping& nodeMapping,
+                            const std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber,
+                            int nbInitialDomains );
+
+    // Find faces common with neighbor domains and put them in groups
+    void buildBoundaryFaces();
 
   private:
     void castIntField(std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom,
@@ -199,9 +208,6 @@ namespace MEDPARTITIONER
     //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;
-
     //family ids storages
     std::vector<ParaMEDMEM::DataArrayInt*> _cell_family_ids;
     std::vector<ParaMEDMEM::DataArrayInt*> _face_family_ids;
index 7c0358e568a3f8c45f2927a20befb9fae6328dc0..f13015f77052be75a3803a3212a9cf30748b8e70 100644 (file)
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-#include "MEDPARTITIONER_ParallelTopology.hxx"
 #include "MEDPARTITIONER_MeshCollectionDriver.hxx"
+
+#include "MEDPARTITIONER_ConnectZone.hxx"
 #include "MEDPARTITIONER_MeshCollection.hxx"
 #include "MEDPARTITIONER_ParaDomainSelector.hxx"
+#include "MEDPARTITIONER_ParallelTopology.hxx"
 #include "MEDPARTITIONER_Utils.hxx"
 
-#include "MEDCouplingUMesh.hxx"
 #include "MEDCouplingFieldDouble.hxx"
-#include "MEDLoader.hxx"
+#include "MEDCouplingRefCountObject.hxx"
+#include "MEDCouplingUMesh.hxx"
+#include "MEDFileField.hxx"
+#include "MEDFileJoint.hxx"
 #include "MEDFileMesh.hxx"
+#include "MEDLoader.hxx"
 
 #include <map>
 #include <set>
@@ -77,112 +82,71 @@ int MeshCollectionDriver::readSeq(const char* filename, const char* meshname)
   (_collection->getCZ()).clear();
   
   ParallelTopology* aPT = new ParallelTopology((_collection->getMesh()));
-  _collection->setTopology(aPT);
+  _collection->setTopology(aPT, true);
   _collection->setName(meshname);
   _collection->setDomainNames(meshname);
   return 0;
 }
 
 
-//================================================================================
-/*!
- * \brief Return mesh dimension from distributed med file had being read
- */
-//================================================================================
-
-void MeshCollectionDriver::readSubdomain(std::vector<int*>& cellglobal,
-                                         std::vector<int*>& faceglobal,
-                                         std::vector<int*>& nodeglobal, int idomain)
+void MeshCollectionDriver::readMEDFileData(const ParaMEDMEM::MEDFileData* filedata)
 {
-  std::string meshname=MyGlobals::_Mesh_Names[idomain];
-  std::string file=MyGlobals::_File_Names[idomain];
+  const int nbDomains = filedata->getMeshes()->getNumberOfMeshes();
+  _collection->getMesh()         .resize( nbDomains, 0 );
+  _collection->getFaceMesh()     .resize( nbDomains, 0 );
+  _collection->getCellFamilyIds().resize( nbDomains, 0 );
+  _collection->getFaceFamilyIds().resize( nbDomains, 0 );
 
-  ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(file,meshname);
-  std::vector<int> nonEmpty=mfm->getNonEmptyLevels();
-  
-  try 
-    { 
-      (_collection->getMesh())[idomain]=mfm->getLevel0Mesh(false); 
-      //reading families groups
-      ParaMEDMEM::DataArrayInt* cellIds(mfm->getFamilyFieldAtLevel(0)->deepCpy());
-      (_collection->getCellFamilyIds())[idomain]=cellIds;
-    }
-  catch(...)
-    { 
-      (_collection->getMesh())[idomain]=CreateEmptyMEDCouplingUMesh(); // or 0 if you want tests;
-      ParaMEDMEM::DataArrayInt* empty=ParaMEDMEM::DataArrayInt::New();
-      empty->alloc(0,1);
-      (_collection->getCellFamilyIds())[idomain]=empty;
-      std::cout << "\nNO Level0Mesh (Cells)\n";
+  for (int i=0; i<nbDomains; i++)
+    {
+      ParaMEDMEM::MEDFileUMesh *mfm = dynamic_cast<ParaMEDMEM::MEDFileUMesh *>(filedata->getMeshes()->getMeshAtPos(i));
+      readData(mfm,i);
+      if ( mfm && mfm->getMeshDimension() > 0 )
+        _collection->setNonEmptyMesh( i );
     }
-  try 
-    { 
-      if (nonEmpty.size()>1 && nonEmpty[1]==-1)
-        {
-          (_collection->getFaceMesh())[idomain]=mfm->getLevelM1Mesh(false);
-          //reading families groups
-          ParaMEDMEM::DataArrayInt* faceIds(mfm->getFamilyFieldAtLevel(-1)->deepCpy());
-          (_collection->getFaceFamilyIds())[idomain]=faceIds;
-          if (MyGlobals::_Verbose>10)
-            std::cout << "proc " << MyGlobals::_Rank << " : WITH Faces\n";
 
-        }
-      else
-        {
-          throw INTERP_KERNEL::Exception("no faces");
-        }
-    }
-  catch(...)
+  ParallelTopology* aPT = new ParallelTopology(_collection->getMesh());
+  _collection->setTopology(aPT, true);
+  if ( nbDomains > 0 )
     {
-      (_collection->getFaceMesh())[idomain]=CreateEmptyMEDCouplingUMesh(); // or 0 if you want test;
-      ParaMEDMEM::DataArrayInt* empty=ParaMEDMEM::DataArrayInt::New();
-      (_collection->getFaceFamilyIds())[idomain]=empty;
-      if (MyGlobals::_Verbose>10)
-        std::cout << "proc " << MyGlobals::_Rank << " : WITHOUT Faces\n";
+      _collection->setName( filedata->getMeshes()->getMeshAtPos(0)->getName() );
+      _collection->setDomainNames( _collection->getName() );
     }
-  
-  //reading groups
-  _collection->getFamilyInfo()=mfm->getFamilyInfo();
-  _collection->getGroupInfo()=mfm->getGroupInfo();
+  if ( ParaDomainSelector* domainSelector = _collection->getParaDomainSelector() )
+    if ( _collection->isParallelMode() )
+      {
+        //to know nb of cells on each proc to compute global cell ids from locally global
+        domainSelector->gatherNbOf(_collection->getMesh());
+      }
+}
 
+void MeshCollectionDriver::readFileData(std::string file,std::string meshname,int idomain) const
+{
+  ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(file,meshname);
+  readData(mfm,idomain);
   mfm->decrRef();
-  
-  std::vector<std::string> localInformation;
-  std::string str;
-  localInformation.push_back(str+"ioldDomain="+IntToStr(idomain));
-  localInformation.push_back(str+"meshName="+meshname);
-  MyGlobals::_General_Informations.push_back(SerializeFromVectorOfString(localInformation));
-  std::vector<std::string> localFields=BrowseAllFieldsOnMesh(file, meshname, idomain);
-  if (localFields.size()>0) 
-    MyGlobals::_Field_Descriptions.push_back(SerializeFromVectorOfString(localFields));
 }
 
-
-void MeshCollectionDriver::readSubdomain(int idomain)
+void MeshCollectionDriver::readData(ParaMEDMEM::MEDFileUMesh* mfm, int idomain) const
 {
-  std::string meshname=MyGlobals::_Mesh_Names[idomain];
-  std::string file=MyGlobals::_File_Names[idomain];
-
-  ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(file,meshname);
   std::vector<int> nonEmpty=mfm->getNonEmptyLevels();
-  
-  try 
-    { 
-      (_collection->getMesh())[idomain]=mfm->getLevel0Mesh(false); 
+  try
+    {
+      (_collection->getMesh())[idomain]=mfm->getLevel0Mesh(false);
       //reading families groups
       ParaMEDMEM::DataArrayInt* cellIds(mfm->getFamilyFieldAtLevel(0)->deepCpy());
       (_collection->getCellFamilyIds())[idomain]=cellIds;
     }
   catch(...)
-    { 
+    {
       (_collection->getMesh())[idomain]=CreateEmptyMEDCouplingUMesh(); // or 0 if you want tests;
       ParaMEDMEM::DataArrayInt* empty=ParaMEDMEM::DataArrayInt::New();
       empty->alloc(0,1);
       (_collection->getCellFamilyIds())[idomain]=empty;
       std::cout<<"\nNO Level0Mesh (Cells)\n";
     }
-  try 
-    { 
+  try
+    {
       if (nonEmpty.size()>1 && nonEmpty[1]==-1)
         {
           (_collection->getFaceMesh())[idomain]=mfm->getLevelM1Mesh(false);
@@ -205,12 +169,16 @@ void MeshCollectionDriver::readSubdomain(int idomain)
       if (MyGlobals::_Verbose>10)
         std::cout << "proc " << MyGlobals::_Rank << " : WITHOUT Faces\n";
     }
-  
   //reading groups
   _collection->getFamilyInfo()=mfm->getFamilyInfo();
   _collection->getGroupInfo()=mfm->getGroupInfo();
+}
 
-  mfm->decrRef();
+void MeshCollectionDriver::readSubdomain(int idomain)
+{
+  std::string meshname=MyGlobals::_Mesh_Names[idomain];
+  std::string file=MyGlobals::_File_Names[idomain];
+  readFileData(file,meshname,idomain);
   
   std::vector<std::string> localInformation;
   std::string str;
@@ -218,19 +186,16 @@ void MeshCollectionDriver::readSubdomain(int idomain)
   localInformation.push_back(str+"meshName="+meshname);
   MyGlobals::_General_Informations.push_back(SerializeFromVectorOfString(localInformation));
   std::vector<std::string> localFields=BrowseAllFieldsOnMesh(file, meshname, idomain);
-  if (localFields.size()>0) 
+  if (localFields.size()>0)
     MyGlobals::_Field_Descriptions.push_back(SerializeFromVectorOfString(localFields));
 }
 
-
-void MeshCollectionDriver::writeMedFile(int idomain, const std::string& distfilename) const
+ParaMEDMEM::MEDFileMesh* MeshCollectionDriver::getMesh(int idomain) const
 {
-  std::vector<const ParaMEDMEM::MEDCouplingUMesh*> meshes;
+  ParaMEDMEM::MEDFileUMesh* mfm = ParaMEDMEM::MEDFileUMesh::New();
+
   ParaMEDMEM::MEDCouplingUMesh* cellMesh=_collection->getMesh(idomain);
   ParaMEDMEM::MEDCouplingUMesh* faceMesh=_collection->getFaceMesh(idomain);
-  //ParaMEDMEM::MEDCouplingUMesh* faceMeshFilter=0;
-  
-  std::string finalMeshName=ExtractFromDescription(MyGlobals::_General_Informations[0], "finalMeshName=");
   // std::string cleFilter=Cle1ToStr("filterFaceOnCell",idomain);
   // ParaMEDMEM::DataArrayInt* filter=0;
   // if (_collection->getMapDataArrayInt().find(cleFilter)!=_collection->getMapDataArrayInt().end())
@@ -240,97 +205,160 @@ void MeshCollectionDriver::writeMedFile(int idomain, const std::string& distfile
   //     faceMeshFilter=(ParaMEDMEM::MEDCouplingUMesh *) faceMesh->buildPartOfMySelf(index,index+filter->getNbOfElems(),true);
   //     faceMesh=faceMeshFilter;
   //   }
+  // if (faceMeshFilter!=0)
+  //   faceMeshFilter->decrRef();
+  std::string finalMeshName="";
+  if (MyGlobals::_General_Informations.size()!=0)
+    {
+      std::size_t found=MyGlobals::_General_Informations[0].find("finalMeshName=");
+      if ((found!=std::string::npos) && (found>0))
+        {
+          finalMeshName=ExtractFromDescription(MyGlobals::_General_Informations[0], "finalMeshName=");
+        }
+    }
+  if (finalMeshName.empty())
+    {
+      finalMeshName=_collection->getName();
+    }
   cellMesh->setName(finalMeshName);
-  meshes.push_back(cellMesh);
-  
+  mfm->setMeshAtLevel( 0, cellMesh );
+
   faceMesh->checkCoherency();
   if (faceMesh->getNumberOfCells()>0)
     {
       faceMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-10);
-      meshes.push_back(faceMesh);
+      faceMesh->setName(finalMeshName);
+      mfm->setMeshAtLevel( -1, faceMesh );
     }
-  
-  //ParaMEDMEM::MEDCouplingUMesh* boundaryMesh=0;
+
+  // ParaMEDMEM::MEDCouplingUMesh* boundaryMesh=0;
   // if (MyGlobals::_Creates_Boundary_Faces>0)
   //   {
   //     //try to write Boundary meshes
   //     bool keepCoords=false; //TODO or true
   //     boundaryMesh=(ParaMEDMEM::MEDCouplingUMesh *) cellMesh->buildBoundaryMesh(keepCoords);
   //     boundaryMesh->setName("boundaryMesh");
-  //   }
-
-  MEDLoader::WriteUMeshes(distfilename, meshes, true);
-  // if (faceMeshFilter!=0)
-  //   faceMeshFilter->decrRef();
-
   // if (boundaryMesh!=0)
   //   {
   //     //doing that testMesh becomes second mesh sorted by alphabetical order of name
   //     MEDLoader::WriteUMesh(distfilename, boundaryMesh, false);
   //     boundaryMesh->decrRef();
   //   }
-  ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(distfilename, _collection->getMesh(idomain)->getName());
 
   mfm->setFamilyInfo(_collection->getFamilyInfo());
   mfm->setGroupInfo(_collection->getGroupInfo());
-
   std::string key=Cle1ToStr("faceFamily_toArray",idomain);
-  if ( meshes.size() == 2 &&
-      _collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end())
-    {
-      ParaMEDMEM::DataArrayInt *fam=_collection->getMapDataArrayInt().find(key)->second;
-      mfm->setFamilyFieldArr(-1,fam);
-    }
-
+  if ( faceMesh->getNumberOfCells()>0 && _collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end())
+    mfm->setFamilyFieldArr(-1,_collection->getMapDataArrayInt().find(key)->second);
   key=Cle1ToStr("cellFamily_toArray",idomain);
   if (_collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end())
     mfm->setFamilyFieldArr(0,_collection->getMapDataArrayInt().find(key)->second);
 
-  mfm->write(distfilename,0);
-  key="/inewFieldDouble="+IntToStr(idomain)+"/";
+  // add joints
 
-  std::map<std::string,ParaMEDMEM::DataArrayDouble*>::iterator it;
-  int nbfFieldFound=0;
-  for (it=_collection->getMapDataArrayDouble().begin() ; it!=_collection->getMapDataArrayDouble().end(); it++)
+  using ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr;
+  using ParaMEDMEM::MEDCouplingSkyLineArray;
+  using ParaMEDMEM::MEDFileJoint;
+  using ParaMEDMEM::MEDFileJointCorrespondence;
+  using ParaMEDMEM::MEDFileJointOneStep;
+  using ParaMEDMEM::MEDFileJoints;
+  using ParaMEDMEM::MEDFileJoints;
+
+  if ( _collection->getCZ().size() > 0 )
     {
-      std::string desc=(*it).first;
-      size_t found=desc.find(key);
-      if (found==std::string::npos)
-        continue;
-      if (MyGlobals::_Verbose>20)
-        std::cout << "proc " << MyGlobals::_Rank << " : write field " << desc << std::endl;
-      std::string meshName, fieldName;
-      int typeField, DT, IT, entity;
-      FieldShortDescriptionToData(desc, fieldName, typeField, entity, DT, IT);
-      double time=StrToDouble(ExtractFromDescription(desc, "time="));
-      int typeData=StrToInt(ExtractFromDescription(desc, "typeData="));
-      std::string entityName=ExtractFromDescription(desc, "entityName=");
-      ParaMEDMEM::MEDCouplingFieldDouble* field=0;
-      if (typeData!=6)
-        {
-          std::cout << "WARNING : writeMedFile : typeData " << typeData << " not implemented for fields\n";
-          continue;
-        }
-      if (entityName=="MED_CELL")
-        {
-          //there is a field of idomain to write
-          field=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME);
-        }
-      if (entityName=="MED_NODE_ELEMENT")
-        {
-          //there is a field of idomain to write
-          field=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_GAUSS_NE,ParaMEDMEM::ONE_TIME);
-        }
-      if (!field)
+      MEDCouplingAutoRefCountObjectPtr< MEDFileJoints > joints = MEDFileJoints::New();
+
+      for ( size_t i = 0; i < _collection->getCZ().size(); ++i )
         {
-          std::cout << "WARNING : writeMedFile : entityName " << entityName << " not implemented for fields\n";
-          continue;
+          ConnectZone* cz = _collection->getCZ()[i];
+          if ( !cz ||
+               cz->getLocalDomainNumber() != idomain )
+            continue;
+          {
+            std::ostringstream oss;
+            oss << "joint_" << cz->getDistantDomainNumber();
+            cz->setName( oss.str() );
+          }
+          {
+            std::ostringstream oss;
+            oss << "connect_zone_" << i;
+            cz->setDescription( oss.str() );
+          }
+
+          MEDCouplingAutoRefCountObjectPtr< MEDFileJoint>
+            joint = MEDFileJoint::New( cz->getName(), finalMeshName,
+                                       finalMeshName, cz->getDistantDomainNumber() );
+          joint->setDescription( cz->getDescription() );
+          joints->pushJoint( joint );
+
+          MEDCouplingAutoRefCountObjectPtr< MEDFileJointOneStep> j1st = MEDFileJointOneStep::New();
+          joint->pushStep( j1st );
+
+          const MEDCouplingSkyLineArray * nodeCorr = cz->getNodeCorresp();
+          if ( nodeCorr )
+            {
+              MEDCouplingAutoRefCountObjectPtr< MEDFileJointCorrespondence >
+                corr = MEDFileJointCorrespondence::New( nodeCorr->getValueArray() );
+              j1st->pushCorrespondence( corr );
+            }
+
+          std::vector< std::pair< int,int > > types = cz->getEntities();
+          INTERP_KERNEL::NormalizedCellType t1, t2;
+          for ( size_t it = 0; it < types.size(); ++it )
+            {
+              const MEDCouplingSkyLineArray * cellCorr =
+                cz->getEntityCorresp( types[it].first, types[it].second );
+              if ( cellCorr && cellCorr->getNumberOf() > 0 )
+                {
+                  t1 = INTERP_KERNEL::NormalizedCellType( types[it].first );
+                  t2 = INTERP_KERNEL::NormalizedCellType( types[it].second );
+                  MEDCouplingAutoRefCountObjectPtr< MEDFileJointCorrespondence>
+                    corr = MEDFileJointCorrespondence::New( cellCorr->getValueArray(), t1, t2 );
+                  j1st->pushCorrespondence( corr );
+                }
+            }
         }
-      nbfFieldFound++;
+      mfm->setJoints( joints );
+    }
+
+  return mfm;
+}
+
+ParaMEDMEM::MEDCouplingFieldDouble* MeshCollectionDriver::getField(std::string key, std::string description, ParaMEDMEM::DataArrayDouble* data, ParaMEDMEM::MEDFileMesh* mfm, int idomain) const
+{
+  std::string desc=description;
+  if (MyGlobals::_Verbose>20)
+    std::cout << "proc " << MyGlobals::_Rank << " : write field " << desc << std::endl;
+  std::string meshName, fieldName;
+  int typeField, DT, IT, entity;
+  FieldShortDescriptionToData(desc, fieldName, typeField, entity, DT, IT);
+  double time=StrToDouble(ExtractFromDescription(desc, "time="));
+  int typeData=StrToInt(ExtractFromDescription(desc, "typeData="));
+  std::string entityName=ExtractFromDescription(desc, "entityName=");
+  ParaMEDMEM::MEDCouplingFieldDouble* field=0;
+  if (typeData!=6)
+    {
+      std::cout << "WARNING : writeMedFile : typeData " << typeData << " not implemented for fields\n";
+    }
+  if (entityName=="MED_CELL")
+    {
+      //there is a field of idomain to write
+      field=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME);
+    }
+  if (entityName=="MED_NODE_ELEMENT")
+    {
+      //there is a field of idomain to write
+      field=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_GAUSS_NE,ParaMEDMEM::ONE_TIME);
+    }
+  if (!field)
+    {
+      std::cout << "WARNING : writeMedFile : entityName " << entityName << " not implemented for fields\n";
+    }
+  if (field && typeData==6)
+    {
       field->setName(fieldName);
-      field->setMesh(mfm->getLevel0Mesh(false));
-      ParaMEDMEM::DataArrayDouble *da=(*it).second;
-    
+      field->setMesh(mfm->getGenMeshAtLevel(0));
+      ParaMEDMEM::DataArrayDouble *da=data;
       //get information for components etc..
       std::vector<std::string> r1;
       r1=SelectTagsInVectorOfString(MyGlobals::_General_Informations,"fieldName="+fieldName);
@@ -341,17 +369,36 @@ void MeshCollectionDriver::writeMedFile(int idomain, const std::string& distfile
       int nbc=StrToInt(ExtractFromDescription(r1[0], "nbComponents="));
       if (nbc==da->getNumberOfComponents())
         {
-          for (int i=0; i<nbc; i++) 
+          for (int i=0; i<nbc; i++)
             da->setInfoOnComponent(i,ExtractFromDescription(r1[0], "componentInfo"+IntToStr(i)+"="));
         }
       else
         {
           std::cerr << "Problem On field " << fieldName << " : number of components unexpected " << da->getNumberOfComponents() << std::endl;
         }
-    
       field->setArray(da);
       field->setTime(time,DT,IT);
       field->checkCoherency();
+    }
+  return field;
+}
+
+void MeshCollectionDriver::writeMedFile(int idomain, const std::string& distfilename) const
+{
+  ParaMEDMEM::MEDFileMesh* mfm = getMesh( idomain );
+  mfm->write(distfilename,2);
+
+  std::string key="/inewFieldDouble="+IntToStr(idomain)+"/";
+  std::map<std::string,ParaMEDMEM::DataArrayDouble*>::iterator it;
+  int nbfFieldFound=0;
+  for (it=_collection->getMapDataArrayDouble().begin() ; it!=_collection->getMapDataArrayDouble().end(); it++)
+    {
+      size_t found=(*it).first.find(key);
+      if (found==std::string::npos)
+        continue;
+      ParaMEDMEM::MEDCouplingFieldDouble* field=0;
+      field = getField(key, (*it).first, (*it).second, mfm, idomain);
+      nbfFieldFound++;
       try
         {
           MEDLoader::WriteField(distfilename,field,false);
@@ -360,6 +407,8 @@ void MeshCollectionDriver::writeMedFile(int idomain, const std::string& distfile
         {
           //cout trying rewrite all data, only one field defined
           std::string tmp,newName=distfilename;
+          std::string fieldName;
+          fieldName=field->getName();
           tmp+="_"+fieldName+"_"+IntToStr(nbfFieldFound)+".med";
           newName.replace(newName.find(".med"),4,tmp);
           std::cout << "WARNING : writeMedFile : create a new file name with only one field because MEDLoader::WriteField throw:" << newName << std::endl;
@@ -368,3 +417,44 @@ void MeshCollectionDriver::writeMedFile(int idomain, const std::string& distfile
     }
   mfm->decrRef();
 }
+
+ParaMEDMEM::MEDFileData* MeshCollectionDriver::getMEDFileData()
+{
+  ParaMEDMEM::MEDFileData* newdata = ParaMEDMEM::MEDFileData::New();
+
+  ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDFileMeshes> meshes;
+  ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDFileFields> fields;
+  meshes = ParaMEDMEM::MEDFileMeshes::New();
+  fields = ParaMEDMEM::MEDFileFields::New();
+
+  for (size_t i=0; i<_collection->getMesh().size(); i++)
+    {
+      ParaMEDMEM::MEDFileMesh* mfm = getMesh( i );
+      meshes->pushMesh(mfm);
+
+      std::string key="/inewFieldDouble="+IntToStr(i)+"/";
+      std::map<std::string,ParaMEDMEM::DataArrayDouble*>::iterator it;
+      ParaMEDMEM::MEDFileFieldMultiTS* fieldsMTS = ParaMEDMEM::MEDFileFieldMultiTS::New();
+      for (it=_collection->getMapDataArrayDouble().begin() ; it!=_collection->getMapDataArrayDouble().end(); it++)
+        {
+          size_t found=(*it).first.find(key);
+          if (found==std::string::npos)
+            continue;
+          ParaMEDMEM::MEDCouplingFieldDouble* field=0;
+          field=getField(key, (*it).first, (*it).second, mfm, i);
+          ParaMEDMEM::MEDFileField1TS* f1ts = ParaMEDMEM::MEDFileField1TS::New();
+          f1ts->setFieldNoProfileSBT(field);
+          fieldsMTS->pushBackTimeStep(f1ts);
+
+          field->decrRef();
+          f1ts->decrRef();
+        }
+      fields->pushField(fieldsMTS);
+
+      fieldsMTS->decrRef();
+      mfm->decrRef();
+    }
+  newdata->setMeshes(meshes);
+  newdata->setFields(fields);
+  return newdata;
+}
index d4d3a41e205f87925a36c793836f87872c1e4e9c..d179d17acf17ba188ee0ea64a724813e8f9b28aa 100644 (file)
 #define __MEDPARTITIONER_MESHCOLLECTIONDRIVER_HXX__
 
 #include "MEDPARTITIONER.hxx"
-
+#include "MEDFileData.hxx"
 #include <vector>
 #include <string>
 
+namespace ParaMEDMEM
+{
+  class MEDFileData;
+}
+
 namespace MEDPARTITIONER
 {
   class MeshCollection;
@@ -37,12 +42,15 @@ namespace MEDPARTITIONER
     virtual ~MeshCollectionDriver() { }
     virtual int read(const char*, ParaDomainSelector* sel=0) = 0;
     int readSeq(const char*,const char*);
+    ParaMEDMEM::MEDFileData *getMEDFileData();
     virtual void write(const char*, ParaDomainSelector* sel=0) const = 0;
+    void readMEDFileData(const ParaMEDMEM::MEDFileData* filedata);
   protected:
-    void readSubdomain(std::vector<int*>& cellglobal,
-                       std::vector<int*>& faceglobal,
-                       std::vector<int*>& nodeglobal, int idomain);
     void readSubdomain(int idomain);
+    void readData(ParaMEDMEM::MEDFileUMesh* mfm, int idomain) const;
+    void readFileData(std::string file,std::string meshname,int idomain) const;
+    ParaMEDMEM::MEDFileMesh* getMesh(int idomain) const;
+    ParaMEDMEM::MEDCouplingFieldDouble* getField(std::string key, std::string description, ParaMEDMEM::DataArrayDouble* data, ParaMEDMEM::MEDFileMesh* mfm, int idomain) const;
     void writeMedFile(int idomain, const std::string& distfilename) const;
   protected:
     MeshCollection* _collection;
index b1ab04cd81a6255c37729146bfbe7c5ab6b7cfe9..4eb8360cba2a12b811c0785ad12a30ace2d2aae3 100644 (file)
@@ -52,6 +52,40 @@ MeshCollectionMedAsciiDriver::MeshCollectionMedAsciiDriver(MeshCollection* colle
  *\param filename ascii file containing the list of MED v2.3 files
  * */
 
+int MeshCollectionMedAsciiDriver::read(ParaMEDMEM::MEDFileData* filedata)
+{
+  readMEDFileData(filedata);
+
+  std::vector<MEDPARTITIONER::ConnectZone*> cz; // to fill from filedata
+  std::vector<int*> cellglobal;
+  std::vector<int*> nodeglobal;
+  std::vector<int*> faceglobal;
+  int size = (_collection->getMesh()).size();
+  cellglobal.resize(size);
+  nodeglobal.resize(size);
+  faceglobal.resize(size);
+  for ( int idomain = 0; idomain < size; ++idomain )
+    {
+      cellglobal[idomain]=0;
+      faceglobal[idomain]=0;
+      nodeglobal[idomain]=0;
+      if ( (_collection->getMesh())[idomain] && (_collection->getMesh())[idomain]->getNumberOfNodes() > 0 )
+        _collection->setNonEmptyMesh(idomain);
+    }
+  //creation of topology from mesh and connect zones
+  ParallelTopology* aPT = new ParallelTopology((_collection->getMesh()), cz, cellglobal, nodeglobal, faceglobal);
+  _collection->setTopology(aPT,true);
+
+  return 0;
+}
+
+/*!reads a MED File v>=2.3
+ * and mounts the corresponding meshes in memory
+ * the connect zones are created from the joints
+ *
+ *\param filename ascii file containing the list of MED v2.3 files
+ * */
+
 int MeshCollectionMedAsciiDriver::read(const char* filename, ParaDomainSelector* domainSelector)
 {
   //distributed meshes
@@ -105,7 +139,7 @@ int MeshCollectionMedAsciiDriver::read(const char* filename, ParaDomainSelector*
               throw INTERP_KERNEL::Exception("domain must be written from 1 to N in ASCII file descriptor");
             }
           if ( !domainSelector || domainSelector->isMyDomain(i))
-            readSubdomain(cellglobal,faceglobal,nodeglobal, i);
+            readSubdomain(i);
 
         } //loop on domains
     } //of try
@@ -116,7 +150,7 @@ int MeshCollectionMedAsciiDriver::read(const char* filename, ParaDomainSelector*
 
   //creation of topology from mesh and connect zones
   ParallelTopology* aPT = new ParallelTopology((_collection->getMesh()), (_collection->getCZ()), cellglobal, nodeglobal, faceglobal);
-  _collection->setTopology(aPT);
+  _collection->setTopology(aPT, true);
 
   for (int i=0; i<nbdomain; i++)
     {
@@ -127,7 +161,6 @@ int MeshCollectionMedAsciiDriver::read(const char* filename, ParaDomainSelector*
   return 0;
 }
 
-
 /*! writes the collection of meshes in a MED v2.3 file
  * with the connect zones being written as joints
  * \param filename name of the ascii file containing the meshes description
index 9148c9fe160860ed6560b5924fa51d64178b479a..699c0b25401012ade47c4c6cac1eb6663e5b1d23 100644 (file)
@@ -31,8 +31,9 @@ namespace MEDPARTITIONER
     MeshCollectionMedAsciiDriver(MeshCollection*);
     virtual ~MeshCollectionMedAsciiDriver() { }
     int read(const char*, ParaDomainSelector* sel=0);
+    int read(ParaMEDMEM::MEDFileData*);
     void write(const char*, ParaDomainSelector* sel=0) const;
-  private :
+  private:
     std::string _master_filename;
   };
 }
index 252ab0212fe6fee31b2e4afea1ec3fbcf065f08a..0fcb460be454ee8567135e42bd0ebdb07676a1b5 100644 (file)
@@ -169,7 +169,7 @@ int MeshCollectionMedXmlDriver::read(const char* filename, ParaDomainSelector* d
       //to know nb of cells on each proc to compute global cell ids from locally global
       domainSelector->gatherNbOf(_collection->getMesh());
     }
-  _collection->setTopology(aPT);
+  _collection->setTopology(aPT, true);
   _collection->setDomainNames(_collection->getName());
   return 0;
 }
@@ -245,7 +245,19 @@ void MeshCollectionMedXmlDriver::write(const char* filename, ParaDomainSelector*
   int nbdomains= _collection->getMesh().size();
 
   //loop on the domains
-  std::string finalMeshName=ExtractFromDescription(MyGlobals::_General_Informations[0], "finalMeshName=");
+  std::string finalMeshName="";
+  if (MyGlobals::_General_Informations.size()!=0)
+    {
+      std::size_t found=MyGlobals::_General_Informations[0].find("finalMeshName=");
+     if ((found!=std::string::npos) && (found>0))
+       {
+         finalMeshName=ExtractFromDescription(MyGlobals::_General_Informations[0], "finalMeshName=");
+       }
+    }
+  if (finalMeshName.empty())
+    {
+      finalMeshName=_collection->getName();
+    }
   for (int idomain=nbdomains-1; idomain>=0;idomain--)
     {
       std::string distfilename;
@@ -277,7 +289,7 @@ void MeshCollectionMedXmlDriver::write(const char* filename, ParaDomainSelector*
           node = xmlNewChild(mesh_node,0, BAD_CAST "chunk",0);
           xmlNewProp(node, BAD_CAST "subdomain", BAD_CAST buff);
           xmlNewChild(node,0,BAD_CAST "name", BAD_CAST finalMeshName.c_str());
-          //xmlNewChild(node,0,BAD_CAST "name", BAD_CAST (_collection->getMesh())[idomain]->getName());
+          //xmlNewChild(node,0,BAD_CAST "name", BAD_CAST ((_collection->getMesh())[idomain]->getName()).c_str());
         }
     }
   
index 1acf1bbd95950f711385033c3626cb8374c7aefa..d91ceda7ff4a550b4a9ba5754b477afae0ce357e 100644 (file)
@@ -36,7 +36,7 @@ METISGraph::METISGraph():Graph()
 {
 }
 
-METISGraph::METISGraph(MEDPARTITIONER::SkyLineArray* graph, int* edgeweight)
+METISGraph::METISGraph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight)
   :Graph(graph,edgeweight)
 {
 }
@@ -112,7 +112,7 @@ void METISGraph::partGraph(int ndomain,
   //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
-  _partition = new MEDPARTITIONER::SkyLineArray(index,value);
+  _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value);
 #endif
 }
 
index 75d6af14e7c3f7cc97be00372d1326c39a4f3a94..46bea277ecb08f632c54b733cbe2ac41791e418d 100644 (file)
@@ -30,7 +30,7 @@ namespace MEDPARTITIONER
   {
   public:
     METISGraph();
-    METISGraph(MEDPARTITIONER::SkyLineArray*, int *edgeweight=0);
+    METISGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, int *edgeweight=0);
     virtual ~METISGraph();
     void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0);
   };
index ab1c1b4264bd89cdb01d61a176204f8e5ea2ba95..18ca26082d6bddb3776614f0eb7598c07e670bd0 100644 (file)
@@ -38,7 +38,7 @@ ParMETISGraph::ParMETISGraph():Graph()
 {
 }
 
-ParMETISGraph::ParMETISGraph(MEDPARTITIONER::SkyLineArray* graph, int* edgeweight)
+ParMETISGraph::ParMETISGraph(MEDCouplingSkyLineArray* graph, int* edgeweight)
   :Graph(graph,edgeweight)
 {
 }
@@ -136,7 +136,7 @@ void ParMETISGraph::partGraph(int ndomain,
   //the fifth argument true specifies that only the pointers are passed 
   //to the object
   
-  _partition = new MEDPARTITIONER::SkyLineArray(index,value);
+  _partition = new MEDCouplingSkyLineArray(index,value);
 #endif
 }
 
index 178683eb3fbd3f901905a74179b7671ce91c0301..8b71b2833e31935ffddfe739fbb0958ece811b4b 100644 (file)
@@ -30,7 +30,7 @@ namespace MEDPARTITIONER
   {
   public:
     ParMETISGraph();
-    ParMETISGraph(MEDPARTITIONER::SkyLineArray*, int *edgeweight=0);
+    ParMETISGraph(MEDCouplingSkyLineArray*, int *edgeweight=0);
     virtual ~ParMETISGraph();
     void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0);
   };
index a5b8257c3ef39ad528657dfc63babeecf2796c3f..cf65b32e353122e2429796cfc8f547bc12e1582c 100644 (file)
@@ -370,8 +370,8 @@ std::auto_ptr<MEDPARTITIONER::Graph> MEDPARTITIONER::ParaDomainSelector::gatherG
   // Make graph
   // -----------
 
-  //   MEDPARTITIONER::SkyLineArray* array =
-  //     new MEDPARTITIONER::SkyLineArray( index_size-1, value_size, graph_index, graph_value, true );
+  //   MEDCouplingSkyLineArray* array =
+  //     new MEDCouplingSkyLineArray( index_size-1, value_size, graph_index, graph_value, true );
 
   //   glob_graph = new UserGraph( array, partition, index_size-1 );
 
index 658379ac26648adebde41c7635dec9044459a8c0..a8a4ab5bf1f4e000ca5622c9070fa86dfb54d619 100644 (file)
@@ -278,7 +278,7 @@ ParallelTopology::ParallelTopology(Graph* graph, Topology* oldTopology, int nb_d
 
   _nb_domain=nb_domain;
   _mesh_dimension=mesh_dimension;
-  
+
   if (MyGlobals::_Verbose>200)
     std::cout << "proc " << MyGlobals::_Rank << " : new topology oldNbDomain " <<
       oldTopology->nbDomain() << " newNbDomain " << _nb_domain << std::endl;
@@ -316,22 +316,79 @@ ParallelTopology::ParallelTopology(Graph* graph, Topology* oldTopology, int nb_d
 
   if (MyGlobals::_Verbose>300)
     for (int idomain=0; idomain<_nb_domain; idomain++)
-      std::cout << "proc " << MyGlobals::_Rank << " : nbCells in new domain " << idomain << " : " << _nb_cells[idomain] << std::endl; 
+      std::cout << "proc " << MyGlobals::_Rank << " : nbCells in new domain " << idomain << " : " << _nb_cells[idomain] << std::endl;
+
+  // JOINTs
+
+  if ( MyGlobals::_Create_Joints && nb_domain > 1 )
+    {
+      std::vector< std::vector< std::vector< int > > > cellCorresp( nb_domain );
+      for ( int idomain = 0; idomain < nb_domain; ++idomain )
+        {
+          cellCorresp[ idomain ].resize( nb_domain );
+        }
+      const ParaMEDMEM::MEDCouplingSkyLineArray* skylinegraph = graph->getGraph();
+      const int*  index = skylinegraph->getIndex();
+      const int*  value = skylinegraph->getValue();
+      const int nbCells = skylinegraph->getNumberOf();
+
+      for ( int iGlob = 0; iGlob < nbCells; ++iGlob )
+        {
+          int iGlobDom = part[ iGlob ];
+          for ( int i = index[ iGlob ]; i < index[ iGlob+1 ]; i++ )
+            {
+              int iGlobNear = value[ i ];
+              if ( iGlob > iGlobNear )
+                continue; // treat ( iGlob, iGlobNear ) pair once
+              int iGlobNearDom = part[ iGlobNear ];
+              if ( iGlobDom != iGlobNearDom )
+                {
+                  int iLoc     = convertGlobalCell( iGlob ).second     - 1; // to MEDCoupling fmt
+                  int iLocNear = convertGlobalCell( iGlobNear ).second - 1;
+                  cellCorresp[ iGlobDom ][ iGlobNearDom ].push_back( iLoc );
+                  cellCorresp[ iGlobDom ][ iGlobNearDom ].push_back( iLocNear );
+                  cellCorresp[ iGlobNearDom ][ iGlobDom ].push_back( iLocNear );
+                  cellCorresp[ iGlobNearDom ][ iGlobDom ].push_back( iLoc );
+                }
+            }
+        }
+      for ( int idomain = 0; idomain < nb_domain; ++idomain )
+        {
+          for ( int idomainNear = 0; idomainNear < nb_domain; ++idomainNear )
+            {
+              std::vector< int > & corresp = cellCorresp[ idomain ][ idomainNear ];
+              if ( corresp.empty() )
+                continue;
+              MEDPARTITIONER::ConnectZone* cz = new MEDPARTITIONER::ConnectZone();
+              cz->setName( "Connect Zone defined by MEDPARTITIONER" );
+              cz->setDistantDomainNumber( idomainNear );
+              cz->setLocalDomainNumber  ( idomain );
+              cz->setEntityCorresp( 0,0, &corresp[0], corresp.size()/2 );
+              _connect_zones.push_back( cz );
+            }
+        }
+    }
 }
 
 ParallelTopology::~ParallelTopology()
 {
-} 
+  for ( size_t i = 0; i < _connect_zones.size(); ++i )
+    {
+      delete _connect_zones[i];
+      _connect_zones[i] = 0;
+    }
+  _connect_zones.clear();
+}
 
 /*!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 (_node_glob_to_loc.empty()) 
+  if (_node_glob_to_loc.empty())
     throw INTERP_KERNEL::Exception("Node mapping has not yet been built");
   for (int i=0; i< nbnode; i++)
     {
@@ -600,6 +657,11 @@ int ParallelTopology::convertGlobalNode(int iglobal, int idomain)
   return -1;
 }
 
+std::vector<MEDPARTITIONER::ConnectZone*>& ParallelTopology::getCZ()
+{
+  return _connect_zones;
+}
+
 /*!
  * adding a face to the topology
  */
index bc81aa8a45df92c5ae4078027ea91b9b8854c286..5de3f4820fad6f10f060dbcbd1bb471faea0f57f 100644 (file)
@@ -147,6 +147,8 @@ namespace MEDPARTITIONER
 
     int convertGlobalNode(int iglobal, int idomain);
     
+    std::vector<MEDPARTITIONER::ConnectZone*>& getCZ();
+
     //adding a face to the topology
     void appendFace(int idomain, int ilocal, int iglobal);
 
@@ -161,10 +163,10 @@ namespace MEDPARTITIONER
     typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> > TGlob2DomainLoc;
 
     TGlob2DomainLoc _glob_to_loc;
-    std::vector<std::vector<int> >  _loc_to_glob;
-    INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> > _node_glob_to_loc;
+    TGlob2DomainLoc _node_glob_to_loc;
 
     //mapping local -> global
+    std::vector<std::vector<int> >  _loc_to_glob;
     std::vector<std::vector <int> > _node_loc_to_glob;
 
     // global numbers in parallel mode
@@ -185,6 +187,10 @@ namespace MEDPARTITIONER
     int _nb_total_faces;
     int _nb_domain;
     int _mesh_dimension;
+
+    //links to connectzones
+    std::vector<MEDPARTITIONER::ConnectZone*> _connect_zones;
+
   };
 }
 #endif
index 73fdd8265006c36277a4c5abe2ba10ad0a41c6e8..c8b9f5e76819dfa392e32bfe1f7a95068ea46361 100644 (file)
@@ -37,7 +37,7 @@ SCOTCHGraph::SCOTCHGraph():Graph()
 {
 }
 
-SCOTCHGraph::SCOTCHGraph(MEDPARTITIONER::SkyLineArray* graph, int* edgeweight):Graph(graph,edgeweight)
+SCOTCHGraph::SCOTCHGraph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight):Graph(graph,edgeweight)
 {
 }
 
@@ -110,6 +110,6 @@ void SCOTCHGraph::partGraph(int ndomain, const std::string& options_string, Para
   //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
-  _partition = new MEDPARTITIONER::SkyLineArray(index,value);
+  _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value);
 #endif
 }
index 39c6f964f93846601c2b8ca906daddc74beaabb5..ea6510b7d4e7a08126cb60b3852f81c10b040bce 100644 (file)
 
 namespace MEDPARTITIONER
 {
-  class SkyLineArray;
   class MEDPARTITIONER_EXPORT SCOTCHGraph : public Graph
   {
   public:
     SCOTCHGraph();
-    SCOTCHGraph(MEDPARTITIONER::SkyLineArray*, int* edgeweight=0);
+    SCOTCHGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, int* edgeweight=0);
     virtual ~SCOTCHGraph();
     void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector* sel=0);
   };
diff --git a/src/MEDPartitioner/MEDPARTITIONER_SkyLineArray.cxx b/src/MEDPartitioner/MEDPARTITIONER_SkyLineArray.cxx
deleted file mode 100644 (file)
index d53de21..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// 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 <vector>
-
-MEDPARTITIONER::SkyLineArray::SkyLineArray()
-{
-}
-
-MEDPARTITIONER::SkyLineArray::SkyLineArray(const SkyLineArray &myArray)
-{
-  _index=myArray._index;
-  _value=myArray._value;
-}
-
-MEDPARTITIONER::SkyLineArray::~SkyLineArray()
-{
-}
-
-
-MEDPARTITIONER::SkyLineArray::SkyLineArray(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
deleted file mode 100644 (file)
index 5610818..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// 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 SkyLineArray
-  {
-  private:
-    std::vector<int> _index;
-    std::vector<int> _value;
-  public:
-    /*! if used SkyLineArray will keep empty */
-    SkyLineArray();
-    SkyLineArray( const SkyLineArray &myArray );
-    SkyLineArray( const std::vector<int>& index, const std::vector<int>& value );
-    ~SkyLineArray();
-  
-    int getNumberOf() const { return _index.size()-1; }
-    int getLength() const { return _value.size() ; }
-    const int* getIndex() const { return (const int*)(&_index[0]); }
-    const int* getValue() const { return (const int*)(&_value[0]); }
-  };
-}
-# endif
index 9ea47e8891886302aa28ad7ab156c9e8a3bf1d48..018388c62e8fded252b8123b46968ab7ccb761f4 100644 (file)
@@ -34,7 +34,6 @@ namespace MEDPARTITIONER
 {
   class Graph;
   class ConnectZone;
-  class SkyLineArray;
   class MeshCollection;
   class MEDPARTITIONER_FaceModel;
     
@@ -105,6 +104,8 @@ namespace MEDPARTITIONER
     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;
+    /*! getting a reference to connect zones vector */
+    virtual std::vector<MEDPARTITIONER::ConnectZone*>& getCZ() = 0;
   };
 }
 
index 81d1fc66cf1fbc98aaa576379ecc68edb681bc33..a6070f245b8b9eb3b1c116c6744e116b99c360a5 100644 (file)
@@ -30,7 +30,7 @@ using namespace MEDPARTITIONER;
  *        (domain numbers range from 0 to ndomain-1
  * \param n number of cells in the mesh
  */
-UserGraph::UserGraph(MEDPARTITIONER::SkyLineArray *array, const int *partition, int n):Graph(array,0)
+UserGraph::UserGraph(ParaMEDMEM::MEDCouplingSkyLineArray *array, const int *partition, int n):Graph(array,0)
 {
 
   std::vector<int> index(n+1),value(n);
@@ -42,7 +42,7 @@ UserGraph::UserGraph(MEDPARTITIONER::SkyLineArray *array, const int *partition,
       value[i]=partition[i];
     }
 
-  _partition = new MEDPARTITIONER::SkyLineArray(index,value);
+  _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value);
 
 }
 
index 9fac944b1a3b80e45c0a70cc4be7c1e5504d990c..a6fc144a533652da445e34edbf6ab8433bc44f80 100644 (file)
 
 namespace MEDPARTITIONER
 {
-  class SkyLineArray;
+  class MEDCouplingSkyLineArray;
   class ParaDomainSelector;
   class MEDPARTITIONER_EXPORT UserGraph : public Graph
   {
   public:
-    UserGraph(MEDPARTITIONER::SkyLineArray*, const int*, int);
+    UserGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, const int*, int);
     virtual ~UserGraph();
     void partGraph(int, const std::string& options=std::string(""), ParaDomainSelector *sel=0);
   };
index ae61745577e5c21215a1c0e514942bc09c95def9..861da009d965b105aef0362625c433685ca46844 100644 (file)
@@ -45,6 +45,7 @@ int MEDPARTITIONER::MyGlobals::_World_Size=-1;
 int MEDPARTITIONER::MyGlobals::_Randomize=0;
 int MEDPARTITIONER::MyGlobals::_Atomize=0;
 int MEDPARTITIONER::MyGlobals::_Creates_Boundary_Faces=0;
+int MEDPARTITIONER::MyGlobals::_Create_Joints=0;
 std::vector<std::string> MEDPARTITIONER::MyGlobals::_File_Names;
 std::vector<std::string> MEDPARTITIONER::MyGlobals::_Mesh_Names;
 std::vector<std::string> MEDPARTITIONER::MyGlobals::_Field_Descriptions;
index f0a1b8270af0459457660e31a18bcc2f5a7f39fb..64fc0c2b9d8099a187521f86a57cd1070416bb9e 100644 (file)
@@ -127,6 +127,7 @@ namespace MEDPARTITIONER
     static int _Randomize;
     static int _Atomize;
     static int _Creates_Boundary_Faces;
+    static int _Create_Joints;
     static int _Is0verbose; //trace cout if rank 0 and verbose
     static std::vector<std::string> _File_Names;    //on [iold]
     static std::vector<std::string> _Mesh_Names;    //on [iold]
index cb6452057137dfd8b6bd76a12ec8f525e7e3c2e2..48b90a7d439836775a47a9cbf7c872b886eec9cd 100644 (file)
@@ -73,6 +73,7 @@ int main(int argc, char** argv)
   MyGlobals::_World_Size=1;
   MyGlobals::_Rank=0;
   MyGlobals::_Creates_Boundary_Faces=0;
+  MyGlobals::_Create_Joints=0;
 
   // Primitive parsing of command-line options
   string desc ("Available options of medpartitioner V1.0:\n"
@@ -86,6 +87,7 @@ int main(int argc, char** argv)
                "\t--split-method=<string>  : name of the splitting library (metis/scotch), default is metis\n"
 #endif
                "\t--creates-boundary-faces : creates boundary faces mesh in the output files\n"
+               "\t--creates-joints         : creates joints in the output files\n"
                "\t--dump-cpu-memory        : dumps passed CPU time and maximal increase of used memory\n"
                );
 
@@ -111,6 +113,7 @@ int main(int argc, char** argv)
       else if (TestArg(argv[i],"--split-method",value)) library=value;
       else if (TestArg(argv[i],"--ndomains",value)) ndomains=atoi(value.c_str());
       else if (TestArg(argv[i],"--creates-boundary-faces",value)) MyGlobals::_Creates_Boundary_Faces=1;
+      else if (TestArg(argv[i],"--create-joints",value)) MyGlobals::_Create_Joints=1;
       else if (TestArg(argv[i],"--dump-cpu-memory",value)) mesure_memory=true;
       else 
         {
@@ -151,6 +154,7 @@ int main(int argc, char** argv)
       cout << "  split-method = " << library << endl;
       cout << "  ndomains = " << ndomains << endl;
       cout << "  creates_boundary_faces = " << MyGlobals::_Creates_Boundary_Faces << endl;
+      cout << "  create-joints = " << MyGlobals::_Create_Joints<< endl;
       cout << "  dump-cpu-memory = " << mesure_memory<< endl;
       cout << "  verbose = " << MyGlobals::_Verbose << endl;
     }
diff --git a/src/MEDPartitioner_Swig/CMakeLists.txt b/src/MEDPartitioner_Swig/CMakeLists.txt
new file mode 100644 (file)
index 0000000..05c8140
--- /dev/null
@@ -0,0 +1,76 @@
+# Copyright (C) 2012-2015  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# 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(${SWIG_USE_FILE})
+
+ADD_DEFINITIONS(${PYTHON_DEFINITIONS})
+
+SET_SOURCE_FILES_PROPERTIES(MEDPartitioner.i PROPERTIES CPLUSPLUS ON)
+SET_SOURCE_FILES_PROPERTIES(MEDPartitioner.i PROPERTIES SWIG_DEFINITIONS "-shadow")
+SET(SWIG_MODULE_MEDPartitioner_EXTRA_FLAGS "${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY};-DWITHOUT_AUTOFIELD")
+
+SET (MEDPartitioner_SWIG_DPYS_FILES
+    MEDPartitionerCommon.i)
+
+INCLUDE_DIRECTORIES(
+  ${PYTHON_INCLUDE_DIRS}
+  ${PTHREAD_INCLUDE_DIR} # pthread dependancy due to python2.7 library
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_BINARY_DIR}
+  ${MEDFILE_INCLUDE_DIRS}
+  ${CMAKE_CURRENT_SOURCE_DIR}/../MEDPartitioner
+  ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling_Swig
+  ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling
+  ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader
+  ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader/Swig
+  ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL
+  ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases
+  ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D
+  ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval
+  ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints
+  )
+
+SWIG_ADD_MODULE(MEDPartitioner python MEDPartitioner.i)
+SWIG_LINK_LIBRARIES(MEDPartitioner ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} medpartitionercpp)
+
+IF(WIN32)
+  SET_TARGET_PROPERTIES(_MEDPartitioner PROPERTIES DEBUG_OUTPUT_NAME _MEDPartitioner_d)
+ENDIF(WIN32)
+INSTALL(TARGETS ${SWIG_MODULE_MEDPartitioner_REAL_NAME} DESTINATION ${SALOME_INSTALL_PYTHON})
+
+SET(PYFILES_TO_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/MEDPartitioner.py)
+INSTALL_AND_COMPILE_PYTHON_FILE("${PYFILES_TO_INSTALL}" ${SALOME_INSTALL_SCRIPT_PYTHON})
+
+INSTALL(FILES MEDPartitioner.i MEDPartitionerCommon.i DESTINATION ${SALOME_INSTALL_HEADERS})
+INSTALL(FILES MEDPartitionerTest.py DESTINATION ${SALOME_INSTALL_SCRIPT_PYTHON})
+
+SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env)
+ADD_TEST(MEDPartitionerTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDPartitionerTest.py)
+SET_TESTS_PROPERTIES(MEDPartitionerTest PROPERTIES ENVIRONMENT "${tests_env}")
+
+# Application tests
+
+SET(TEST_INSTALL_DIRECTORY ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDPartitioner_Swig)
+INSTALL(FILES MEDPartitionerTest.py DESTINATION ${TEST_INSTALL_DIRECTORY})
+
+INSTALL(FILES CTestTestfileInstall.cmake
+        DESTINATION ${TEST_INSTALL_DIRECTORY}
+        RENAME CTestTestfile.cmake)
+
+
diff --git a/src/MEDPartitioner_Swig/CTestTestfileInstall.cmake b/src/MEDPartitioner_Swig/CTestTestfileInstall.cmake
new file mode 100644 (file)
index 0000000..2100e6b
--- /dev/null
@@ -0,0 +1,21 @@
+# Copyright (C) 2015  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# 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
+#
+
+ADD_TEST(MEDPartitionerTest python MEDPartitionerTest.py)
+SET_TESTS_PROPERTIES(MEDPartitionerTest PROPERTIES LABELS "${COMPONENT_NAME}")
diff --git a/src/MEDPartitioner_Swig/MEDPartitioner.i b/src/MEDPartitioner_Swig/MEDPartitioner.i
new file mode 100644 (file)
index 0000000..13f6d9c
--- /dev/null
@@ -0,0 +1,140 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// 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 "MEDPartitionerCommon.i"
+
+
+// %pythoncode %{
+// def ParaMEDMEMDataArrayDoublenew(cls,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayDouble____new___(cls,args)
+// def ParaMEDMEMDataArrayDoubleIadd(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayDouble____iadd___(self, self, *args)
+// def ParaMEDMEMDataArrayDoubleIsub(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayDouble____isub___(self, self, *args)
+// def ParaMEDMEMDataArrayDoubleImul(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayDouble____imul___(self, self, *args)
+// def ParaMEDMEMDataArrayDoubleIdiv(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayDouble____idiv___(self, self, *args)
+// def ParaMEDMEMDataArrayDoubleIpow(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayDouble____ipow___(self, self, *args)
+// def ParaMEDMEMDataArrayIntnew(cls,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayInt____new___(cls,args)
+// def ParaMEDMEMDataArrayIntIadd(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayInt____iadd___(self, self, *args)
+// def ParaMEDMEMDataArrayIntIsub(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayInt____isub___(self, self, *args)
+// def ParaMEDMEMDataArrayIntImul(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayInt____imul___(self, self, *args)
+// def ParaMEDMEMDataArrayIntIdiv(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayInt____idiv___(self, self, *args)
+// def ParaMEDMEMDataArrayIntImod(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayInt____imod___(self, self, *args)
+// def ParaMEDMEMDataArrayIntIpow(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayInt____ipow___(self, self, *args)
+// def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayDoubleTuple____iadd___(self, self, *args)
+// def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayDoubleTuple____isub___(self, self, *args)
+// def ParaMEDMEMDataArrayDoubleTupleImul(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayDoubleTuple____imul___(self, self, *args)
+// def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayDoubleTuple____idiv___(self, self, *args)
+// def ParaMEDMEMDataArrayIntTupleIadd(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayIntTuple____iadd___(self, self, *args)
+// def ParaMEDMEMDataArrayIntTupleIsub(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayIntTuple____isub___(self, self, *args)
+// def ParaMEDMEMDataArrayIntTupleImul(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayIntTuple____imul___(self, self, *args)
+// def ParaMEDMEMDataArrayIntTupleIdiv(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayIntTuple____idiv___(self, self, *args)
+// def ParaMEDMEMDataArrayIntTupleImod(self,*args):
+//     import _MEDPartitioner
+//     return _MEDPartitioner.DataArrayIntTuple____imod___(self, self, *args)
+// %}
+
+
+// %pythoncode %{
+// DataArrayDouble.__new__=classmethod(ParaMEDMEMDataArrayDoublenew)
+// DataArrayDouble.__iadd__=ParaMEDMEMDataArrayDoubleIadd
+// DataArrayDouble.__isub__=ParaMEDMEMDataArrayDoubleIsub
+// DataArrayDouble.__imul__=ParaMEDMEMDataArrayDoubleImul
+// DataArrayDouble.__idiv__=ParaMEDMEMDataArrayDoubleIdiv
+// DataArrayDouble.__ipow__=ParaMEDMEMDataArrayDoubleIpow
+
+// DataArrayInt.__new__=classmethod(ParaMEDMEMDataArrayIntnew)
+// DataArrayInt.__iadd__=ParaMEDMEMDataArrayIntIadd
+// DataArrayInt.__isub__=ParaMEDMEMDataArrayIntIsub
+// DataArrayInt.__imul__=ParaMEDMEMDataArrayIntImul
+// DataArrayInt.__idiv__=ParaMEDMEMDataArrayIntIdiv
+// DataArrayInt.__imod__=ParaMEDMEMDataArrayIntImod
+// DataArrayInt.__ipow__=ParaMEDMEMDataArrayIntIpow
+
+// DataArrayDoubleTuple.__iadd__=ParaMEDMEMDataArrayDoubleTupleIadd
+// DataArrayDoubleTuple.__isub__=ParaMEDMEMDataArrayDoubleTupleIsub
+// DataArrayDoubleTuple.__imul__=ParaMEDMEMDataArrayDoubleTupleImul
+// DataArrayDoubleTuple.__idiv__=ParaMEDMEMDataArrayDoubleTupleIdiv
+
+// DataArrayIntTuple.__iadd__=ParaMEDMEMDataArrayIntTupleIadd
+// DataArrayIntTuple.__isub__=ParaMEDMEMDataArrayIntTupleIsub
+// DataArrayIntTuple.__imul__=ParaMEDMEMDataArrayIntTupleImul
+// DataArrayIntTuple.__idiv__=ParaMEDMEMDataArrayIntTupleIdiv
+// DataArrayIntTuple.__imod__=ParaMEDMEMDataArrayIntTupleImod
+
+// del ParaMEDMEMDataArrayDoublenew
+// del ParaMEDMEMDataArrayDoubleIadd
+// del ParaMEDMEMDataArrayDoubleIsub
+// del ParaMEDMEMDataArrayDoubleImul
+// del ParaMEDMEMDataArrayDoubleIdiv
+// del ParaMEDMEMDataArrayIntnew
+// del ParaMEDMEMDataArrayIntIadd
+// del ParaMEDMEMDataArrayIntIsub
+// del ParaMEDMEMDataArrayIntImul
+// del ParaMEDMEMDataArrayIntIdiv
+// del ParaMEDMEMDataArrayIntImod
+// del ParaMEDMEMDataArrayDoubleTupleIadd
+// del ParaMEDMEMDataArrayDoubleTupleIsub
+// del ParaMEDMEMDataArrayDoubleTupleImul
+// del ParaMEDMEMDataArrayDoubleTupleIdiv
+// del ParaMEDMEMDataArrayIntTupleIadd
+// del ParaMEDMEMDataArrayIntTupleIsub
+// del ParaMEDMEMDataArrayIntTupleImul
+// del ParaMEDMEMDataArrayIntTupleIdiv
+// del ParaMEDMEMDataArrayIntTupleImod
+// %}
diff --git a/src/MEDPartitioner_Swig/MEDPartitionerCommon.i b/src/MEDPartitioner_Swig/MEDPartitionerCommon.i
new file mode 100644 (file)
index 0000000..93a390a
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// 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
+//
+
+%module MEDPartitioner
+
+%include std_string.i
+
+%{
+#include "MEDFileData.hxx"
+
+#include "MEDPARTITIONER_MEDPartitioner.hxx"
+#include "MEDPARTITIONER.hxx"
+#include "MEDPARTITIONER_Graph.hxx"
+
+using namespace ParaMEDMEM;
+using namespace INTERP_KERNEL;
+using namespace MEDPARTITIONER;
+%}
+
+%feature("autodoc", "1");
+%feature("docstring");
+
+%newobject MEDPARTITIONER::MEDPartitioner::New;
+%newobject MEDPARTITIONER::MEDPartitioner::Graph;
+%newobject MEDPARTITIONER::MEDPartitioner::getMEDFileData;
+%feature("unref") ParaMEDMEM::MEDFileData "$this->decrRef();"
+
+%nodefaultctor;
+
+%rename (InterpKernelException) INTERP_KERNEL::Exception;
+
+namespace MEDPARTITIONER
+{
+  class Graph
+  {
+  public:
+    virtual void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0) throw(INTERP_KERNEL::Exception);
+    const ParaMEDMEM::MEDCouplingSkyLineArray *getGraph() const;
+    const ParaMEDMEM::MEDCouplingSkyLineArray *getPartition() const;
+    int nbVertices() const;
+  };
+
+  class MEDPartitioner
+  {
+  public:
+    MEDPartitioner(const std::string& filename, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false) throw(INTERP_KERNEL::Exception);
+    MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false) throw(INTERP_KERNEL::Exception);
+    MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, Graph* graph, bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false) throw(INTERP_KERNEL::Exception);
+    static MEDPARTITIONER::Graph* Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, Graph::splitter_type split=Graph::METIS, int* edgeweight=0) throw(INTERP_KERNEL::Exception);
+    ParaMEDMEM::MEDFileData* getMEDFileData() throw(INTERP_KERNEL::Exception);
+    void write(const std::string& filename) throw(INTERP_KERNEL::Exception);
+  };
+}
+
diff --git a/src/MEDPartitioner_Swig/MEDPartitionerTest.py b/src/MEDPartitioner_Swig/MEDPartitionerTest.py
new file mode 100644 (file)
index 0000000..8ad3c30
--- /dev/null
@@ -0,0 +1,100 @@
+# Copyright (C) 2012-2015  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# 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
+#
+
+from MEDPartitioner import *
+from MEDLoader import *
+import unittest
+from MEDLoaderDataForTest import MEDLoaderDataForTest
+
+class MEDPartitionerTest(unittest.TestCase):
+    def testPartition(self):
+        fname="PyPartitionTest.med"
+        data=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1()
+        data.write(fname,2)
+        part_file=MEDPartitioner(fname,2)
+        part_data=MEDPartitioner(data,2)
+        part_file.write("splitted_PyPartitionTest_1")
+        part_data.write("splitted_PyPartitionTest_2")
+        part_file_xml=MEDPartitioner("splitted_PyPartitionTest_1.xml")
+        part_data_xml=MEDPartitioner("splitted_PyPartitionTest_2.xml")
+        data1=part_file_xml.getMEDFileData()
+        data2=part_data_xml.getMEDFileData()
+        m1d=data1.getMeshes().getMeshAtPos(0)
+        m2d=data2.getMeshes().getMeshAtPos(0)
+        self.assertTrue(m1d.isEqual(m2d,1e-12))
+    pass
+    def testPartitionGraph(self):
+        data=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1()
+        m=data.getMeshes().getMeshAtPos(0)
+        graph=MEDPartitioner.Graph(m.getLevel0Mesh().generateGraph())
+        graph.partGraph(2)
+        tool=MEDPartitioner(data,graph)
+        data2=tool.getMEDFileData()
+        self.assertEqual( 2, data2.getMeshes().getNumberOfMeshes() )
+    pass
+    def testPartitionWithJoints(self):
+        # cartesian mesh 4x4
+        arr=DataArrayDouble(5) ; arr.iota()
+        c=MEDCouplingCMesh() ; c.setCoords(arr,arr)
+        m=c.buildUnstructured()
+        m.setName("mesh")
+        mm=MEDFileUMesh() 
+        mm.setMeshAtLevel(0,m)
+        ms=MEDFileMeshes() ; ms.pushMesh(mm)
+        data=MEDFileData()
+        data.setMeshes(ms)
+        part_file=MEDPartitioner(data,4,"metis",True,True,True)
+        data_file=part_file.getMEDFileData()
+        meshes=data_file.getMeshes()
+        self.assertEqual( 4, meshes.getNumberOfMeshes())
+        self.assertEqual( 3, meshes.getMeshAtPos(0).getJoints().getNumberOfJoints())
+        self.assertEqual( 3, meshes.getMeshAtPos(1).getJoints().getNumberOfJoints())
+        self.assertEqual( 3, meshes.getMeshAtPos(2).getJoints().getNumberOfJoints())
+        self.assertEqual( 3, meshes.getMeshAtPos(3).getJoints().getNumberOfJoints())        
+        joints=meshes.getMeshAtPos(0).getJoints()
+        self.assertEqual( 1, joints.getJointAtPos(0).getDomainNumber(), 1)
+        self.assertEqual( 2, joints.getJointAtPos(1).getDomainNumber(), 2)
+        self.assertEqual( 3, joints.getJointAtPos(2).getDomainNumber(), 3)
+        self.assertEqual( 2, joints.getJointAtPos(0).getStepAtPos(0).getNumberOfCorrespondences())
+        self.assertEqual( 2, joints.getJointAtPos(1).getStepAtPos(0).getNumberOfCorrespondences())
+        self.assertEqual( 1, joints.getJointAtPos(2).getStepAtPos(0).getNumberOfCorrespondences())
+        found=0
+        for ii in xrange(joints.getJointAtPos(0).getStepAtPos(0).getNumberOfCorrespondences()):
+            correspond=joints.getJointAtPos(0).getStepAtPos(0).getCorrespondenceAtPos(ii)
+            if correspond.getCorrespondence().isEqual(DataArrayInt([1,3,2,4])):
+                found+=1
+                self.assertEqual(NORM_QUAD4, correspond.getLocalGeometryType())
+                self.assertEqual(NORM_QUAD4, correspond.getRemoteGeometryType())
+            pass
+        pass
+        self.assertEqual(1,found)
+    pass
+    def testPartitionPartGraph(self):
+        arr=DataArrayDouble(5) ; arr.iota()
+        c=MEDCouplingCMesh() ; c.setCoords(arr,arr)
+        m=c.buildUnstructured()
+        part=MEDPartitioner.Graph(m.generateGraph())
+        part.partGraph(2)
+        a=part.getGraph()
+        p=part.getPartition()
+        self.assertTrue(isinstance(a,MEDCouplingSkyLineArray))
+        self.assertTrue(isinstance(p,MEDCouplingSkyLineArray))
+        self.assertTrue(part.nbVertices() > 0 )
+    pass
+unittest.main()