]> SALOME platform Git repositories - modules/med.git/commitdiff
Salome HOME
Implementation of equivalences in MEDFileMesh.
authorAnthony Geay <anthony.geay@edf.fr>
Mon, 30 Nov 2015 12:44:05 +0000 (13:44 +0100)
committerCédric Aguerre <cedric.aguerre@edf.fr>
Wed, 2 Dec 2015 12:39:37 +0000 (13:39 +0100)
medtool/src/MEDLoader/CMakeLists.txt
medtool/src/MEDLoader/MEDFileData.cxx
medtool/src/MEDLoader/MEDFileMesh.cxx
medtool/src/MEDLoader/MEDFileMesh.hxx
medtool/src/MEDLoader/MEDFileMeshLL.cxx
medtool/src/MEDLoader/MEDFileMeshLL.hxx
medtool/src/MEDLoader/Swig/MEDLoaderCommon.i
medtool/src/MEDLoader/Swig/MEDLoaderTest3.py
src/MEDLoader/MEDFileEquivalence.cxx [new file with mode: 0644]
src/MEDLoader/MEDFileEquivalence.hxx [new file with mode: 0644]

index db1729fc26645137bb77403a10d68bd7d8e073c0..3c4e10bfdfd1c310a7b4a1379b014d806b9a0f38 100644 (file)
@@ -63,6 +63,7 @@ SET(medloader_SOURCES
   MEDFileMeshLL.cxx
   MEDFileField.cxx
   MEDFileJoint.cxx
+  MEDFileEquivalence.cxx
   MEDFileParameter.cxx
   MEDFileData.cxx
   MEDFileFieldOverView.cxx
index a979b38f503a22e2f763c2a1dddf60db46b5f6cc..ca2b84aa3eab6ead493bfdf063d49435e13cdae8 100644 (file)
@@ -43,8 +43,7 @@ MEDFileData *MEDFileData::deepCpy() const
   MEDCouplingAutoRefCountObjectPtr<MEDFileParameters> params;
   if((const MEDFileParameters *)_params)
     params=_params->deepCpy();
-  MEDCouplingAutoRefCountObjectPtr<MEDFileJoints> joints;
-  MEDCouplingAutoRefCountObjectPtr<MEDFileData> ret=MEDFileData::New();
+  MEDCouplingAutoRefCountObjectPtr<MEDFileData> ret(MEDFileData::New());
   ret->_fields=fields; ret->_meshes=meshes; ret->_params=params;
   return ret.retn();
 }
index a2ae032871d70674789e26da910fcacff1ad5cdc..761578f27e1bcb356624dfb06bbd581ceca35316 100644 (file)
@@ -59,7 +59,9 @@ std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
 
 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
 {
-  return std::vector<const BigMemoryObject *>();
+  std::vector<const BigMemoryObject *> ret(1);
+  ret[0]=(const MEDFileEquivalences *)_equiv;
+  return ret;
 }
 
 /*!
@@ -86,28 +88,23 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect
   int dt,it;
   std::string dummy2;
   MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
+  MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> ret;
   switch(meshType)
   {
     case UNSTRUCTURED:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
-        ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
-        ret->loadJointsFromFile(fid);
-        return (MEDFileUMesh *)ret.retn();
+        ret=MEDFileUMesh::New();
+        break;
       }
     case CARTESIAN:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
-        ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
-        ret->loadJointsFromFile(fid);
-        return (MEDFileCMesh *)ret.retn();
+        ret=MEDFileCMesh::New();
+        break;
       }
     case CURVE_LINEAR:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
-        ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs);
-        ret->loadJointsFromFile(fid);
-        return (MEDFileCurveLinearMesh *)ret.retn();
+        ret=MEDFileCurveLinearMesh::New();
+        break;
       }
     default:
       {
@@ -115,6 +112,8 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
   }
+  ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
+  return ret.retn();
 }
 
 /*!
@@ -142,28 +141,23 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN
   int dummy0,dummy1;
   std::string dummy2;
   MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
+  MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> ret;
   switch(meshType)
   {
     case UNSTRUCTURED:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
-        ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
-        ret->loadJointsFromFile(fid,joints);
-        return (MEDFileUMesh *)ret.retn();
+        ret=MEDFileUMesh::New();
+        break;
       }
     case CARTESIAN:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
-        ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
-        ret->loadJointsFromFile(fid,joints);
-        return (MEDFileCMesh *)ret.retn();
+        ret=MEDFileCMesh::New();
+        break;
       }
     case CURVE_LINEAR:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
-        ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
-        ret->loadJointsFromFile(fid,joints);
-        return (MEDFileCurveLinearMesh *)ret.retn();
+        ret=MEDFileCurveLinearMesh::New();
+        break;
       }
     default:
       {
@@ -171,6 +165,8 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
   }
+  ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
+  return ret.retn();
 }
 
 /*!
@@ -187,6 +183,10 @@ void MEDFileMesh::write(med_idt fid) const
   if(_name.empty())
     throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
   writeLL(fid);
+  writeJoints(fid);
+  const MEDFileEquivalences *eqs(_equiv);
+  if(eqs)
+    eqs->write(fid);
 }
 
 /*!
@@ -252,6 +252,8 @@ bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wha
     return false;
   if(!areFamsEqual(other,what))
     return false;
+  if(!areEquivalencesEqual(other,what))
+    return false;
   return true;
 }
 
@@ -1987,6 +1989,13 @@ std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
   return mLev->getDistributionOfTypes();
 }
 
+void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  loadLL(fid,mName,dt,it,mrs);
+  loadJointsFromFile(fid);
+  loadEquivalences(fid);
+}
+
 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
 {
   famArr->applyLin(offset>0?1:-1,offset,0);
@@ -2232,6 +2241,7 @@ MEDFileMesh *MEDFileUMesh::createNewEmpty() const
 MEDFileMesh *MEDFileUMesh::deepCpy() const
 {
   MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
+  ret->deepCpyEquivalences(*this);
   if((const DataArrayDouble*)_coords)
     ret->_coords=_coords->deepCpy();
   if((const DataArrayInt*)_fam_coords)
@@ -2410,9 +2420,8 @@ MEDFileUMesh::MEDFileUMesh()
 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 try
 {
-    loadUMeshFromFile(fid,mName,dt,it,mrs);
-    loadJointsFromFile(fid);
-  }
+    loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
+}
 catch(INTERP_KERNEL::Exception& e)
 {
     throw e;
@@ -2422,7 +2431,7 @@ catch(INTERP_KERNEL::Exception& e)
  * This method loads only a part of specified cells (given by range of cell ID per geometric type)
  * See MEDFileUMesh::LoadPartOf for detailed description.
  *
- * \sa loadUMeshFromFile
+ * \sa loadLL
  */
 void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
@@ -2470,12 +2479,49 @@ void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfRe
     _joints = MEDFileJoints::New( fid, _name );
 }
 
+void MEDFileMesh::loadEquivalences(med_idt fid)
+{
+  int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
+  if(nbOfEq>0)
+    _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
+}
+
+void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
+{
+  const MEDFileEquivalences *equiv(other._equiv);
+  if(equiv)
+    _equiv=equiv->deepCpy(this);
+}
+
+bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
+{
+  const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
+  if(!thisEq && !otherEq)
+    return true;
+  if(thisEq && otherEq)
+    return thisEq->isEqual(otherEq,what);
+  else
+    {
+      what+="Equivalence differs : defined in this and not in other (or reversely) !";
+      return false;
+    }
+}
+
+void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
+{
+  const MEDFileEquivalences *equiv(_equiv);
+  if(!equiv)
+    return ;
+  oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
+  _equiv->getRepr(oss);
+}
+
 /*!
  * \brief Return number of joints, which is equal to number of adjacent mesh domains
  */
-int MEDFileMesh::getNumberOfJoints()
+int MEDFileMesh::getNumberOfJoints() const
 {
-  return ( (MEDFileJoints*) _joints ) ? _joints->getNumberOfJoints() : 0;
+  return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
 }
 
 /*!
@@ -2501,7 +2547,7 @@ void MEDFileMesh::setJoints( MEDFileJoints* joints )
  *
  * \sa loadPartUMeshFromFile
  */
-void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   MEDFileUMeshL2 loaderl2;
   ParaMEDMEM::MEDCouplingMeshType meshType;
@@ -2582,8 +2628,6 @@ 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);
 }
 
 /*!
@@ -2943,6 +2987,7 @@ std::string MEDFileUMesh::simpleRepr() const
     }
   oss << std::endl << std::endl;
   getFamilyRepr(oss);
+  getEquivalencesRepr(oss);
   return oss.str();
 }
 
@@ -3416,6 +3461,13 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(
   return sp->getGeoTypes();
 }
 
+int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
+{
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
+  const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
+  return sp->getNumberOfCellsWithType(ct);
+}
+
 /*!
  * This method extracts from whole family field ids the part relative to the input parameter \a gt.
  * \param [in] gt - the geometric type for which the family field is asked.
@@ -5659,6 +5711,14 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoType
   }
 }
 
+int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
+{
+  if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
+    return 0;
+  else
+    return getNumberOfCellsAtLevel(0);
+}
+
 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
 {
   if(st.getNumberOfItems()!=1)
@@ -5962,6 +6022,7 @@ MEDFileMesh *MEDFileCMesh::createNewEmpty() const
 MEDFileMesh *MEDFileCMesh::deepCpy() const
 {
   MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
+  ret->deepCpyEquivalences(*this);
   if((const MEDCouplingCMesh*)_cmesh)
     ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
   ret->deepCpyAttributes();
@@ -6022,15 +6083,14 @@ MEDFileCMesh::MEDFileCMesh()
 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 try
 {
-    loadCMeshFromFile(fid,mName,dt,it,mrs);
-    loadJointsFromFile(fid);
+    loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
 }
 catch(INTERP_KERNEL::Exception& e)
 {
     throw e;
 }
 
-void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   ParaMEDMEM::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
@@ -6110,8 +6170,6 @@ 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
@@ -6180,6 +6238,7 @@ MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
 {
   MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
+  ret->deepCpyEquivalences(*this);
   if((const MEDCouplingCurveLinearMesh*)_clmesh)
     ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
   ret->deepCpyAttributes();
@@ -6278,8 +6337,7 @@ MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 try
 {
-    loadCLMeshFromFile(fid,mName,dt,it,mrs);
-    loadJointsFromFile(fid);
+    loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
 }
 catch(INTERP_KERNEL::Exception& e)
 {
@@ -6320,11 +6378,9 @@ 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)
+void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   ParaMEDMEM::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
index 87ffb429a08903a41fee7b988b9755b77634e42a..65c39d1c2791546b47d9ffd1e8506db781c47b1b 100644 (file)
@@ -27,6 +27,7 @@
 #include "MEDCouplingPartDefinition.hxx"
 #include "MEDFileMeshReadSelector.hxx"
 #include "MEDFileJoint.hxx"
+#include "MEDFileEquivalence.hxx"
 
 #include <map>
 #include <list>
@@ -62,7 +63,7 @@ namespace ParaMEDMEM
     MEDLOADER_EXPORT int getIteration() const { return _iteration; }
     MEDLOADER_EXPORT void setTimeValue(double time) { _time=time; }
     MEDLOADER_EXPORT void setTime(int dt, int it, double time) { _time=time; _iteration=dt; _order=it; }
-    MEDLOADER_EXPORT double getTime(int& dt, int& it) { dt=_iteration; it=_order; return _time; }
+    MEDLOADER_EXPORT double getTime(int& dt, int& it) const { dt=_iteration; it=_order; return _time; }
     MEDLOADER_EXPORT double getTimeValue() const { return _time; }
     MEDLOADER_EXPORT void setTimeUnit(const std::string& unit) { _dt_unit=unit; }
     MEDLOADER_EXPORT std::string getTimeUnit() const { return _dt_unit; }
@@ -73,6 +74,7 @@ namespace ParaMEDMEM
     MEDLOADER_EXPORT virtual int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const = 0;
     MEDLOADER_EXPORT virtual void releaseImplicitPartIfAny() const = 0;
     MEDLOADER_EXPORT virtual std::vector<INTERP_KERNEL::NormalizedCellType> getGeoTypesAtLevel(int meshDimRelToMax) const = 0;
+    MEDLOADER_EXPORT virtual int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const = 0;
     MEDLOADER_EXPORT virtual std::vector<int> getNonEmptyLevels() const = 0;
     MEDLOADER_EXPORT virtual std::vector<int> getNonEmptyLevelsExt() const = 0;
     MEDLOADER_EXPORT virtual std::vector<int> getFamArrNonEmptyLevelsExt() const = 0;
@@ -170,9 +172,13 @@ 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 int getNumberOfJoints() const;
     MEDLOADER_EXPORT MEDFileJoints *getJoints() const;
-    MEDLOADER_EXPORT void                 setJoints( MEDFileJoints* joints );
+    MEDLOADER_EXPORT void setJoints( MEDFileJoints* joints );
+    MEDFileEquivalences *getEquivalences() { return _equiv; }
+    const MEDFileEquivalences *getEquivalences() const { return _equiv; }
+    void killEquivalences() { _equiv=(MEDFileEquivalences *)0; }
+    void initializeEquivalences() { _equiv=MEDFileEquivalences::New(this); }
   protected:
     MEDFileMesh();
     //! protected because no way in MED file API to specify this name
@@ -185,6 +191,8 @@ namespace ParaMEDMEM
     virtual void appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames);
     virtual void changeFamilyIdArr(int oldId, int newId) = 0;
     virtual std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > getAllNonNullFamilyIds() const = 0;
+    virtual void loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) = 0;
+    void loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
     void addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr);
     static void TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp);
     static void ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames);
@@ -192,7 +200,11 @@ namespace ParaMEDMEM
     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);
+    void loadJointsFromFile(med_idt fid, MEDFileJoints *toUseInstedOfReading=0);
+    void loadEquivalences(med_idt fid);
+    void deepCpyEquivalences(const MEDFileMesh& other);
+    bool areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const;
+    void getEquivalencesRepr(std::ostream& oss) const;
   protected:
     int _order;
     int _iteration;
@@ -204,6 +216,7 @@ namespace ParaMEDMEM
     bool _univ_wr_status;
     std::string _desc_name;
     MEDCouplingAutoRefCountObjectPtr<MEDFileJoints> _joints;
+    MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalences> _equiv;
   protected:
     std::map<std::string, std::vector<std::string> > _groups;
     std::map<std::string,int> _families;
@@ -249,6 +262,7 @@ namespace ParaMEDMEM
     MEDLOADER_EXPORT int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const;
     MEDLOADER_EXPORT void releaseImplicitPartIfAny() const;
     MEDLOADER_EXPORT std::vector<INTERP_KERNEL::NormalizedCellType> getGeoTypesAtLevel(int meshDimRelToMax) const;
+    MEDLOADER_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const;
     MEDLOADER_EXPORT void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const;
     MEDLOADER_EXPORT std::vector<int> getNonEmptyLevels() const;
     MEDLOADER_EXPORT std::vector<int> getNonEmptyLevelsExt() const;
@@ -317,7 +331,7 @@ namespace ParaMEDMEM
     MEDFileUMesh();
     MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
     void loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0);
-    void loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
+    void loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
     void dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs);
     const MEDFileUMeshSplitL1 *getMeshAtLevSafe(int meshDimRelToMaxExt) const;
     MEDFileUMeshSplitL1 *getMeshAtLevSafe(int meshDimRelToMaxExt);
@@ -374,6 +388,7 @@ namespace ParaMEDMEM
     MEDLOADER_EXPORT void releaseImplicitPartIfAny() const;
     MEDLOADER_EXPORT MEDCoupling1SGTUMesh *getImplicitFaceMesh() const;
     MEDLOADER_EXPORT std::vector<INTERP_KERNEL::NormalizedCellType> getGeoTypesAtLevel(int meshDimRelToMax) const;
+    MEDLOADER_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const;
     MEDLOADER_EXPORT void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const;
     MEDLOADER_EXPORT virtual const MEDCouplingStructuredMesh *getStructuredMesh() const = 0;
     // tools
@@ -433,7 +448,7 @@ namespace ParaMEDMEM
     MEDFileCMesh();
     void synchronizeTinyInfoOnLeaves() const;
     MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
-    void loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
+    void loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
   private:
     MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> _cmesh;
   };
@@ -464,7 +479,7 @@ namespace ParaMEDMEM
     const MEDCouplingStructuredMesh *getStructuredMesh() const;
     void synchronizeTinyInfoOnLeaves() const;
     void writeLL(med_idt fid) const;
-    void loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);//to imp
+    void loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);//to imp
   private:
     MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> _clmesh;
   };
index 8fad6bf6ff89e36f3cc7fe4002686296848277d8..6adf254964d1c03f3ad41456bf17c14fbf111e02 100644 (file)
@@ -911,6 +911,11 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMeshSplitL1::getGeoTypes(
   return _m_by_types.getGeoTypes();
 }
 
+int MEDFileUMeshSplitL1::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
+{
+  return _m_by_types.getNumberOfCellsWithType(ct);
+}
+
 MEDCouplingUMesh *MEDFileUMeshSplitL1::getWholeMesh(bool renum) const
 {
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp;
@@ -1268,6 +1273,22 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMeshAggregateCompute::get
     return _m->getAllGeoTypesSorted();
 }
 
+int MEDFileUMeshAggregateCompute::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
+{
+  if(_mp_time>=_m_time)
+    {
+      for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
+        {
+          const MEDCoupling1GTUMesh *elt(*it);
+          if(elt && elt->getCellModelEnum()==ct)
+            return elt->getNumberOfCells();
+        }
+      return 0;
+    }
+  else
+    return _m->getNumberOfCellsWithType(ct);
+}
+
 std::vector<MEDCoupling1GTUMesh *> MEDFileUMeshAggregateCompute::retrievePartsWithoutComputation() const
 {
   if(_mp_time<_m_time)
index b6872efc7763691dbd9daf02c69ea300d45f3bf4..a65e0c106467cbc2e98a12a59522439cee57a364 100644 (file)
@@ -158,6 +158,7 @@ namespace ParaMEDMEM
     int getNumberOfCells() const;
     std::vector<MEDCoupling1GTUMesh *> getParts() const;
     std::vector<INTERP_KERNEL::NormalizedCellType> getGeoTypes() const;
+    int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const;
     std::vector<MEDCoupling1GTUMesh *> retrievePartsWithoutComputation() const;
     MEDCoupling1GTUMesh *retrievePartWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const;
     void getStartStopOfGeoTypeWithoutComputation(INTERP_KERNEL::NormalizedCellType gt, int& start, int& stop) const;
@@ -221,6 +222,7 @@ namespace ParaMEDMEM
     int getNumberOfCells() const;
     bool isMeshStoredSplitByType() const { return _m_by_types.isStoredSplitByType(); }
     std::vector<INTERP_KERNEL::NormalizedCellType> getGeoTypes() const;
+    int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const;
     std::vector<MEDCoupling1GTUMesh *> getDirectUndergroundSingleGeoTypeMeshes() const { return _m_by_types.retrievePartsWithoutComputation(); }
     MEDCoupling1GTUMesh *getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const { return _m_by_types.retrievePartWithoutComputation(gt); }
     DataArrayInt *extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const;
index 85d65699b06e1be2b983c81274d64f7b5d6a0b02..310810e2007f6e0ce2d0d29167b03aa0f140afae 100644 (file)
@@ -36,6 +36,7 @@
 #include "MEDFileField.hxx"
 #include "MEDFileParameter.hxx"
 #include "MEDFileData.hxx"
+#include "MEDFileEquivalence.hxx"
 #include "MEDFileMeshReadSelector.hxx"
 #include "MEDFileFieldOverView.hxx"
 #include "MEDLoaderTypemaps.i"
@@ -99,6 +100,7 @@ using namespace ParaMEDMEM;
 %newobject ParaMEDMEM::MEDFileMesh::getNodeFamiliesArr;
 %newobject ParaMEDMEM::MEDFileMesh::getAllFamiliesIdsReferenced;
 %newobject ParaMEDMEM::MEDFileMesh::computeAllFamilyIdsInUse;
+%newobject ParaMEDMEM::MEDFileMesh::getEquivalences;
 %newobject ParaMEDMEM::MEDFileData::getJoints;
 %newobject ParaMEDMEM::MEDFileStructuredMesh::getImplicitFaceMesh;
 %newobject ParaMEDMEM::MEDFileUMesh::New;
@@ -211,6 +213,15 @@ using namespace ParaMEDMEM;
 %newobject ParaMEDMEM::MEDFileJoints::getJointAtPos;
 %newobject ParaMEDMEM::MEDFileJoints::getJointWithName;
 %newobject ParaMEDMEM::MEDFileJoints::__getitem__;
+%newobject ParaMEDMEM::MEDFileEquivalences::getEquivalence;
+%newobject ParaMEDMEM::MEDFileEquivalences::getEquivalenceWithName;
+%newobject ParaMEDMEM::MEDFileEquivalences::appendEmptyEquivalenceWithName;
+%newobject ParaMEDMEM::MEDFileEquivalencePair::initCell;
+%newobject ParaMEDMEM::MEDFileEquivalencePair::initNode;
+%newobject ParaMEDMEM::MEDFileEquivalencePair::getCell;
+%newobject ParaMEDMEM::MEDFileEquivalencePair::getNode;
+%newobject ParaMEDMEM::MEDFileEquivalenceData::getArray;
+%newobject ParaMEDMEM::MEDFileEquivalenceCell::getArray;
 
 %newobject ParaMEDMEM::SauvWriter::New;
 %newobject ParaMEDMEM::SauvReader::New;
@@ -244,6 +255,12 @@ using namespace ParaMEDMEM;
 %feature("unref") MEDFileJointOneStep "$this->decrRef();"
 %feature("unref") MEDFileJoint "$this->decrRef();"
 %feature("unref") MEDFileJoints "$this->decrRef();"
+%feature("unref") MEDFileEquivalences "$this->decrRef();"
+%feature("unref") MEDFileEquivalencePair "$this->decrRef();"
+%feature("unref") MEDFileEquivalenceBase "$this->decrRef();"
+%feature("unref") MEDFileEquivalenceData "$this->decrRef();"
+%feature("unref") MEDFileEquivalenceCell "$this->decrRef();"
+%feature("unref") MEDFileEquivalenceNode "$this->decrRef();"
 %feature("unref") MEDFileData "$this->decrRef();"
 %feature("unref") SauvReader "$this->decrRef();"
 %feature("unref") SauvWriter "$this->decrRef();"
@@ -501,6 +518,7 @@ namespace ParaMEDMEM
       }
     }
   };
+
   class MEDFileJointCorrespondence : public RefCountObject, public MEDFileWritable
   {
   public:
@@ -584,6 +602,7 @@ namespace ParaMEDMEM
       }
     }
   };
+
   class MEDFileJoint : public RefCountObject, public MEDFileWritable
   {
   public:
@@ -703,6 +722,141 @@ namespace ParaMEDMEM
       }
     }
   };
+  
+  class MEDFileEquivalenceBase : public RefCountObject
+  {
+  private:
+    MEDFileEquivalenceBase();
+  };
+
+  class MEDFileEquivalenceData : public MEDFileEquivalenceBase
+  {
+  private:
+    MEDFileEquivalenceData();
+  public:
+    void setArray(DataArrayInt *data);
+    %extend
+    {
+      DataArrayInt *getArray()
+      {
+        DataArrayInt *ret(self->getArray());
+        if(ret) ret->incrRef();
+        return ret;
+      }
+    }
+  };
+
+  class MEDFileEquivalenceNode : public MEDFileEquivalenceData
+  {
+  private:
+    MEDFileEquivalenceNode();
+  };
+
+  class MEDFileEquivalenceCell : public MEDFileEquivalenceBase
+  {
+  private:
+    MEDFileEquivalenceCell();
+  public:
+    void clear();
+    std::size_t size() const;
+    void setArray(int meshDimRelToMax, DataArrayInt *da) throw(INTERP_KERNEL::Exception);
+    void setArrayForType(INTERP_KERNEL::NormalizedCellType type, DataArrayInt *da) throw(INTERP_KERNEL::Exception);
+    %extend
+    {
+      DataArrayInt *getArray(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
+      {
+        DataArrayInt *ret(self->getArray(type));
+        if(ret) ret->incrRef();
+        return ret;
+      }
+      
+      PyObject *getTypes() const throw(INTERP_KERNEL::Exception)
+      {
+        std::vector<INTERP_KERNEL::NormalizedCellType> result(self->getTypes());
+        std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator iL=result.begin();
+        PyObject *res=PyList_New(result.size());
+        for(int i=0;iL!=result.end(); i++, iL++)
+          PyList_SetItem(res,i,PyInt_FromLong(*iL));
+        return res;
+      }
+    }
+  };
+
+  class MEDFileEquivalencePair : public RefCountObject
+  {
+  private:
+    MEDFileEquivalencePair();
+  public:
+    std::string getName() const;
+    void setName(const std::string& name);
+    std::string getDescription() const;
+    void setDescription(const std::string& descr);
+    void setArray(int meshDimRelToMaxExt, DataArrayInt *da);;
+    %extend
+    {
+      MEDFileEquivalenceCell *initCell()
+      {
+        MEDFileEquivalenceCell *ret(self->initCell());
+        if(ret) ret->incrRef();
+        return ret;
+      }
+
+      MEDFileEquivalenceNode *initNode()
+      {
+        MEDFileEquivalenceNode *ret(self->initNode());
+        if(ret) ret->incrRef();
+        return ret;
+      }
+      
+      MEDFileEquivalenceCell *getCell()
+      {
+        MEDFileEquivalenceCell *ret(self->getCell());
+        if(ret) ret->incrRef();
+        return ret;
+      }
+      
+      MEDFileEquivalenceNode *getNode()
+      {
+        MEDFileEquivalenceNode *ret(self->getNode());
+        if(ret) ret->incrRef();
+        return ret;
+      }
+    }
+  };
+  
+  class MEDFileEquivalences : public RefCountObject
+  {
+  private:
+    MEDFileEquivalences();
+  public:
+    int size() const;
+    std::vector<std::string> getEquivalenceNames() const throw(INTERP_KERNEL::Exception);
+    void killEquivalenceWithName(const std::string& name) throw(INTERP_KERNEL::Exception);
+    void killEquivalenceAt(int i) throw(INTERP_KERNEL::Exception);
+    void clear();
+    %extend
+    {
+      MEDFileEquivalencePair *getEquivalence(int i) throw(INTERP_KERNEL::Exception)
+      {
+        MEDFileEquivalencePair *ret(self->getEquivalence(i));
+        if(ret) ret->incrRef();
+        return ret;
+      }
+      MEDFileEquivalencePair *getEquivalenceWithName(const std::string& name) throw(INTERP_KERNEL::Exception)
+      {
+        MEDFileEquivalencePair *ret(self->getEquivalenceWithName(name));
+        if(ret) ret->incrRef();
+        return ret;
+      }
+
+      MEDFileEquivalencePair *appendEmptyEquivalenceWithName(const std::string& name) throw(INTERP_KERNEL::Exception)
+      {
+        MEDFileEquivalencePair *ret(self->appendEmptyEquivalenceWithName(name));
+        if(ret) ret->incrRef();
+        return ret;
+      }
+    }
+  };
 
   class MEDFileMesh : public RefCountObject, public MEDFileWritable
   {
@@ -734,6 +888,7 @@ namespace ParaMEDMEM
     virtual bool hasImplicitPart() const throw(INTERP_KERNEL::Exception);
     virtual int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception);
     virtual void releaseImplicitPartIfAny() const throw(INTERP_KERNEL::Exception);
+    virtual int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const throw(INTERP_KERNEL::Exception);
     virtual std::vector<int> getFamArrNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception);
     virtual std::vector<int> getNumArrNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception);
     virtual std::vector<int> getNameArrNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception);
@@ -819,7 +974,9 @@ namespace ParaMEDMEM
     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 );
+    void setJoints( MEDFileJoints* joints );
+    void initializeEquivalences();
+    void killEquivalences();
     %extend
        {
          std::string __str__() const throw(INTERP_KERNEL::Exception)
@@ -989,6 +1146,13 @@ namespace ParaMEDMEM
            PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(ret3),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
            return ret;
          }
+
+         MEDFileEquivalences *getEquivalences() throw(INTERP_KERNEL::Exception)
+         {
+           MEDFileEquivalences *ret(self->getEquivalences());
+           if(ret) ret->incrRef();
+           return ret;
+         }
        }
   };
 
index ce9e0e076d575eea8713ddafb5b52451c582336a..ec4cf31325e5949012c55491be78d69222de43e2 100644 (file)
@@ -4653,6 +4653,62 @@ class MEDLoaderTest(unittest.TestCase):
       self.assertTrue(mesh.isEqual(mm2,1e-12)[0])
       pass
 
+    def testMEDFileEquivalence1(self):
+      """ First check of equivalence implementation in MEDFileMesh"""
+      fileName="Pyfile97.med"
+      meshName="M_01"
+      mm=MEDFileUMesh()
+      coo=DataArrayDouble([(0,0,0),(6,0,0),(19,0,0),(36,0,0),(0,4,0),(6,4,0),(19,4,0),(36,4,0),(0,13,0),(6,13,0),(19,13,0),(36,13,0),(0,24,0),(6,24,0),(19,24,0),(36,24,0),(0,0,6),(6,0,6),(19,0,6),(36,0,6),(0,4,6),(6,4,6),(19,4,6),(36,4,6),(0,13,6),(6,13,6),(19,13,6),(36,13,6),(0,24,6),(6,24,6),(19,24,6),(36,24,6),(6,0,3),(6,2,0),(12.5,0,0),(19,0,3),(19,2,0),(6,4,3),(12.5,4,0),(19,4,3),(6,2,6),(12.5,0,6),(19,2,6),(12.5,4,6),(6,2,3),(12.5,0,3),(12.5,2,0),(19,2,3),(12.5,4,3),(12.5,2,6),(12.5,2,3)])
+      coo.setInfoOnComponents(["X [Sans_unite]","Y [Sans_unite]","Z [Sans_unite]"])
+      connQ4=DataArrayInt([1,17,21,5,2,18,22,6,21,5,6,22,1,32,44,33,17,40,44,32,21,37,44,40,5,33,44,37,2,35,47,36,18,42,47,35,22,39,47,42,6,36,47,39,21,37,48,43,5,38,48,37,6,39,48,38,22,43,48,39])
+      m1=MEDCoupling1SGTUMesh(meshName,NORM_QUAD4) ; m1.setCoords(coo) ; m1.setNodalConnectivity(connQ4) ; mm[-1]=m1
+      connH8=DataArrayInt([20,16,17,21,4,0,1,5,22,18,19,23,6,2,3,7,24,20,21,25,8,4,5,9,25,21,22,26,9,5,6,10,26,22,23,27,10,6,7,11,28,24,25,29,12,8,9,13,29,25,26,30,13,9,10,14,30,26,27,31,14,10,11,15,21,40,49,43,37,44,50,48,40,17,41,49,44,32,45,50,49,41,18,42,50,45,35,47,43,49,42,22,48,50,47,39,44,32,45,50,33,1,34,46,37,44,50,48,5,33,46,38,48,50,47,39,38,46,36,6,50,45,35,47,46,34,2,36])
+      m0=MEDCoupling1SGTUMesh(meshName,NORM_HEXA8) ; m0.setCoords(coo) ; m0.setNodalConnectivity(connH8) ; mm[0]=m0
+      mm.getFamilyFieldAtLevel(-1)[:]=-2
+      mm.getFamilyFieldAtLevel(0)[:]=0
+      mm.addFamily("HOMARD________-1",-1)
+      mm.addFamily("HOMARD________-2",-2)
+      mm.addFamily("HOMARD________-3",-3)
+      mm.setFamiliesIdsOnGroup("HOMARD",[-1,-2,-3])
+      
+      eqName="MAILLES_A_RECOLLER_APRES_HOMARD"
+      descEq="Cette equivalence decrit les mailles a recoller. Dans chaque correspondance, le premier numero est celui de la maille coupee ; le second numero est celui d'une des petites mailles en regard."
+      mm.initializeEquivalences()
+      eqs=mm.getEquivalences()
+      eq0=eqs.appendEmptyEquivalenceWithName(eqName)
+      eq0.setDescription(descEq)
+      corr=DataArrayInt([(0,3),(0,4),(0,5),(0,6),(1,7),(1,8),(1,9),(1,10),(2,11),(2,12),(2,13),(2,14)])
+      eq0.setArray(-1,corr)
+      self.assertEqual(eq0.getCell().size(),1)
+      self.assertTrue(eq0.getCell().getArray(NORM_QUAD4).isEqual(corr))
+      eq0.getCell().clear()
+      self.assertEqual(eq0.getCell().size(),0)
+      eq0.getCell().setArrayForType(NORM_QUAD4,corr)
+      self.assertEqual(eq0.getCell().size(),1)
+      self.assertTrue(eq0.getCell().getArray(NORM_QUAD4).isEqual(corr))
+      mm.killEquivalences()
+      mm.initializeEquivalences()
+      eqs=mm.getEquivalences()
+      eq0=eqs.appendEmptyEquivalenceWithName(eqName)
+      eq0.setDescription(descEq)
+      c=eq0.initCell()
+      c.setArrayForType(NORM_QUAD4,corr)
+      self.assertEqual(eq0.getCell().size(),1)
+      self.assertTrue(eq0.getCell().getArray(NORM_QUAD4).isEqual(corr))
+      mm2=mm.deepCpy()
+      self.assertTrue(mm.isEqual(mm2,1e-12)[0])
+      self.assertEqual(mm2.getEquivalences().size(),1)
+      self.assertTrue(mm2.getEquivalences().getEquivalence(0).getCell().getArray(NORM_QUAD4).isEqual(corr))
+      mm2.getEquivalences().getEquivalence(0).getCell().getArray(NORM_QUAD4)[0,0]=2
+      self.assertTrue(not mm.isEqual(mm2,1e-12)[0])
+      mm2.getEquivalences().getEquivalence(0).getCell().getArray(NORM_QUAD4)[0,0]=0
+      self.assertTrue(mm.isEqual(mm2,1e-12)[0])
+      mm.write(fileName,2)
+      #
+      mm3=MEDFileMesh.New(fileName)
+      self.assertTrue(mm.isEqual(mm3,1e-12)[0])
+      pass
+
     pass
 
 if __name__ == "__main__":
diff --git a/src/MEDLoader/MEDFileEquivalence.cxx b/src/MEDLoader/MEDFileEquivalence.cxx
new file mode 100644 (file)
index 0000000..5f9ff6d
--- /dev/null
@@ -0,0 +1,769 @@
+// 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
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "MEDFileEquivalence.hxx"
+#include "MEDFileSafeCaller.txx"
+#include "MEDCouplingMemArray.hxx"
+#include "MEDLoaderBase.hxx"
+#include "MEDFileMesh.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];
+extern med_geometry_type typmainoeud[1];
+
+using namespace ParaMEDMEM;
+
+MEDFileEquivalencePair *MEDFileEquivalencePair::Load(MEDFileEquivalences *father, med_idt fid, const std::string& name, const std::string &desc)
+{
+  if(!father)
+    throw INTERP_KERNEL::Exception("MEDFileEquivalencePair::Load : father is NULL ! Should not !");
+  MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> ret(new MEDFileEquivalencePair(father,name,desc));
+  ret->load(fid);
+  return ret.retn();
+}
+
+void MEDFileEquivalencePair::write(med_idt fid) const
+{
+  std::string meshName(getFather()->getMeshName());
+  INTERP_KERNEL::AutoPtr<char> meshName2(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
+  INTERP_KERNEL::AutoPtr<char> name(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
+  INTERP_KERNEL::AutoPtr<char> desc(MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE));
+  MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_NAME_SIZE,meshName2,getFather()->getMesh()->getTooLongStrPolicy());
+  MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,name,getFather()->getMesh()->getTooLongStrPolicy());
+  MEDLoaderBase::safeStrCpy(_description.c_str(),MED_COMMENT_SIZE,desc,getFather()->getMesh()->getTooLongStrPolicy());
+  MEDFILESAFECALLERWR0(MEDequivalenceCr,(fid,meshName2,name,desc));
+  const MEDFileEquivalenceCell *cell(_cell);
+  if(cell)
+    cell->write(fid);
+  const MEDFileEquivalenceNode *node(_node);
+  if(node)
+    node->write(fid);
+}
+
+const MEDFileMesh *MEDFileEquivalencePair::getMesh() const
+{
+  return getFather()->getMesh();
+}
+
+MEDFileMesh *MEDFileEquivalencePair::getMesh()
+{
+  return getFather()->getMesh();
+}
+
+MEDFileEquivalencePair *MEDFileEquivalencePair::deepCpy(MEDFileEquivalences *father) const
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> ret(new MEDFileEquivalencePair(father,_name,_description));
+  const MEDFileEquivalenceCell *cell(_cell);
+  if(cell)
+    ret->_cell=cell->deepCpy(const_cast<MEDFileEquivalencePair *>(this));
+  const MEDFileEquivalenceNode *node(_node);
+  if(node)
+    ret->_node=node->deepCpy(const_cast<MEDFileEquivalencePair *>(this));
+  return ret.retn();
+}
+
+bool MEDFileEquivalencePair::isEqual(const MEDFileEquivalencePair *other, std::string& what) const
+{
+  if(_name!=other->_name)
+    {
+      std::ostringstream oss; oss << "Names differs : " << _name << " != " << other->_name << " !";
+      what=oss.str();
+      return false;
+    }
+  if(_description!=other->_description)
+    {
+       std::ostringstream oss; oss << "Description differs : " << _description << " != " << other->_description << " !";
+       what=oss.str();
+       return false;
+    }
+  const MEDFileEquivalenceCell *c1(_cell),*c2(other->_cell);
+  if((c1 && !c2) || (!c1 && c2))
+    {
+      std::ostringstream oss; oss << "Cell def of Equiv " << _name << " are defined for this and not for other (or reversely) !";
+      what=oss.str();
+      return false;
+    }
+  if(c1 && c2)
+    if(!c1->isEqual(c2,what))
+      return false;
+  const MEDFileEquivalenceNode *n1(_node),*n2(other->_node);
+  if((n1 && !n2) || (!n1 && n2))
+    {
+      std::ostringstream oss; oss << "Node def of Equiv " << _name << " are defined for this and not for other (or reversely) !";
+      what=oss.str();
+      return false;
+    }
+  if(n1 && n2)
+    if(!n1->isEqual(n2,what))
+      return false;
+  return true;
+}
+
+void MEDFileEquivalencePair::getRepr(std::ostream& oss) const
+{
+  const MEDFileEquivalenceNode *node(_node);
+  const MEDFileEquivalenceCell *cell(_cell);
+  oss << std::endl << "  name of equivalence : " << _name << std::endl;
+  oss << "  description of equivalence : " << _description << std::endl;
+  oss << "  Node : ";
+  if(!node)
+    oss << "None" << std::endl;
+  else
+    node->getRepr(oss);
+  oss << "  Cell : ";
+  if(!cell)
+    oss << "None" << std::endl;
+  else
+    cell->getRepr(oss);
+}
+
+MEDFileEquivalencePair *MEDFileEquivalencePair::New(MEDFileEquivalences *father, const std::string& name)
+{
+  return new MEDFileEquivalencePair(father,name,std::string());
+}
+
+std::vector<const BigMemoryObject *> MEDFileEquivalencePair::getDirectChildrenWithNull() const
+{
+  std::vector<const BigMemoryObject *> ret(2);
+  ret[0]=_cell; ret[1]=_node;
+  return ret;
+}
+
+void MEDFileEquivalencePair::setArray(int meshDimRelToMaxExt, DataArrayInt *da)
+{
+  if(meshDimRelToMaxExt>1)
+    throw INTERP_KERNEL::Exception("MEDFileEquivalencePair::setArray : meshDimRelToMaxExt must be in [1,0,-1,-2,-3] at most !");
+  if(meshDimRelToMaxExt==1)
+    {
+      MEDFileEquivalenceNode *node(_node);
+      if(!node)
+        {
+          _node=new MEDFileEquivalenceNode(this,0);
+          node=_node;
+        }
+      node->setArray(da);
+    }
+  else
+    {
+      MEDFileEquivalenceCell *cell(_cell);
+      if(!cell)
+        {
+          _cell=new MEDFileEquivalenceCell(this);
+          cell=_cell;
+        }
+      cell->setArray(meshDimRelToMaxExt,da);
+    }
+}
+
+/*!
+ * The returned pointer is a borrowed pointer.
+ */
+MEDFileEquivalenceCell *MEDFileEquivalencePair::initCell()
+{
+  _cell=new MEDFileEquivalenceCell(this);
+  return _cell;
+}
+
+/*!
+ * The returned pointer is a borrowed pointer.
+ */
+MEDFileEquivalenceNode *MEDFileEquivalencePair::initNode()
+{
+  _node=new MEDFileEquivalenceNode(this,0);
+  return _node;
+}
+
+std::size_t MEDFileEquivalencePair::getHeapMemorySizeWithoutChildren() const
+{
+  return 0;
+}
+
+void MEDFileEquivalencePair::load(med_idt fid)
+{
+  std::string meshName(_father->getMeshName());
+  int dt,it;
+  _father->getDtIt(dt,it);
+  med_int ncor;
+  MEDFILESAFECALLERRD0(MEDequivalenceCorrespondenceSize,(fid,meshName.c_str(),_name.c_str(),dt,it,MED_NODE,MED_NONE,&ncor));
+  if(ncor>0)
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da(DataArrayInt::New());
+      da->alloc(ncor*2);
+      MEDFILESAFECALLERRD0(MEDequivalenceCorrespondenceRd,(fid,meshName.c_str(),_name.c_str(),dt,it,MED_NODE,MED_NONE,da->getPointer()));
+      da->applyLin(1,-1);
+      da->rearrange(2);
+      MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceNode> node(new MEDFileEquivalenceNode(this,da));
+      _node=node;
+    }
+  _cell=MEDFileEquivalenceCell::Load(fid,this);
+}
+
+std::vector<const BigMemoryObject *> MEDFileEquivalences::getDirectChildrenWithNull() const
+{
+  std::size_t sz(_equ.size());
+  std::vector<const BigMemoryObject *> ret(sz);
+  for(std::size_t i=0;i<sz;i++)
+    ret[i]=_equ[i];
+  return ret;
+}
+
+std::size_t MEDFileEquivalences::getHeapMemorySizeWithoutChildren() const
+{
+  return sizeof(MEDFileEquivalences)+_equ.capacity()*sizeof(MEDFileEquivalencePair);
+}
+
+void MEDFileEquivalences::getDtIt(int &dt, int &it) const
+{
+  dt=_owner->getIteration(); it=_owner->getOrder();
+}
+
+std::string MEDFileEquivalences::getMeshName() const
+{
+  return _owner->getName();
+}
+
+void MEDFileEquivalences::pushEquivalence(MEDFileEquivalencePair *elt)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> elta(elt);
+  if(elt)
+    elt->incrRef();
+  _equ.push_back(elta);
+}
+
+MEDFileEquivalencePair *MEDFileEquivalences::getEquivalence(int i)
+{
+  int sz(size());
+  if(i<0 || i>=sz)
+    {
+      std::ostringstream oss; oss << "MEDFileEquivalences::getEquivalence : invalid id ! Must be in [0," << sz << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  return _equ[i];
+}
+
+MEDFileEquivalencePair *MEDFileEquivalences::getEquivalenceWithName(const std::string& name)
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> >::iterator it=_equ.begin();it!=_equ.end();it++)
+    {
+      MEDFileEquivalencePair *elt(*it);
+      if(elt)
+        {
+          if(elt->getName()==name)
+            return elt;
+        }
+    }
+  std::ostringstream oss; oss << "MEDFileEquivalences::getEquivalenceWithName : no equivalence with name \"" << name << "\" ! Must be in [ ";
+  std::vector<std::string> eqs(getEquivalenceNames());
+  std::copy(eqs.begin(),eqs.end(),std::ostream_iterator<std::string>(oss,", "));
+  oss << "] !";
+  throw INTERP_KERNEL::Exception(oss.str().c_str());
+}
+
+int MEDFileEquivalences::size() const
+{
+  return _equ.size();
+}
+
+std::vector<std::string> MEDFileEquivalences::getEquivalenceNames() const
+{
+  std::vector<std::string> ret;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> >::const_iterator it=_equ.begin();it!=_equ.end();it++)
+    {
+      const MEDFileEquivalencePair *elt(*it);
+      if(elt)
+        {
+          ret.push_back(elt->getName());
+        }
+    }
+  return ret;
+}
+
+MEDFileEquivalencePair *MEDFileEquivalences::appendEmptyEquivalenceWithName(const std::string& name)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> elt(MEDFileEquivalencePair::New(this,name));
+  _equ.push_back(elt);
+  return elt;
+}
+
+MEDFileEquivalences *MEDFileEquivalences::deepCpy(MEDFileMesh *owner) const
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalences> ret(new MEDFileEquivalences(owner));
+  ret->deepCpyFrom(*this);
+  return ret.retn();
+}
+
+bool MEDFileEquivalences::isEqual(const MEDFileEquivalences *other, std::string& what) const
+{
+  std::size_t sz(_equ.size());
+  if(sz!=other->_equ.size())
+    {
+      what="Equivalences differs : not same number !";
+      return false;
+    }
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const MEDFileEquivalencePair *thisp(_equ[i]),*otherp(other->_equ[i]);
+      if(!thisp && !otherp)
+        continue;
+      if(thisp && otherp)
+        {
+          if(!thisp->isEqual(otherp,what))
+            {
+              std::ostringstream oss; oss << "At Eq #" << i << " there is a difference !";
+              what=oss.str()+what;
+              return false;
+            }
+        }
+      else
+        {
+          std::ostringstream oss; oss << "At Eq #" << i << " defined in this not is other (or reversely) !";
+          what=oss.str()+what;
+          return false;
+        }
+    }
+}
+
+void MEDFileEquivalences::getRepr(std::ostream& oss) const
+{
+  std::size_t ii(0);
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> >::const_iterator it=_equ.begin();it!=_equ.end();it++,ii++)
+    {
+      const MEDFileEquivalencePair *elt(*it);
+      oss << "Equivalence #" << ii << " : " ;
+      if(elt)
+        elt->getRepr(oss);
+      else
+        oss << "None" << std::endl;
+    }
+}
+
+void MEDFileEquivalences::killEquivalenceWithName(const std::string& name)
+{
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> >::iterator it(_equ.begin());
+  for(;it!=_equ.end();it++)
+    {
+      const MEDFileEquivalencePair *elt(*it);
+      if(elt && elt->getName()==name)
+        break;
+    }
+  if(it==_equ.end())
+    {
+      std::ostringstream oss; oss << "MEDFileEquivalences::killEquivalenceWithName : Equivalence with name \"" << name << "\" not found !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  _equ.erase(it);
+}
+
+void MEDFileEquivalences::killEquivalenceAt(int i)
+{
+  int sz(size());
+  if(i<0 || i>=sz)
+    {
+      std::ostringstream oss; oss << "MEDFileEquivalences::killEquivalenceAt : Id must be in [0," << sz << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> >::iterator it(_equ.begin());
+  for(int j=0;j<i;it++,j++);
+  _equ.erase(it);
+}
+
+void MEDFileEquivalences::clear()
+{
+  _equ.clear();
+}
+
+void MEDFileEquivalences::write(med_idt fid) const
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> >::const_iterator it=_equ.begin();it!=_equ.end();it++)
+    {
+      const MEDFileEquivalencePair *elt(*it);
+      if(elt)
+        elt->write(fid);
+    }
+}
+
+int MEDFileEquivalences::PresenceOfEquivalences(med_idt fid, const std::string& meshName)
+{
+  med_int nequ(MEDnEquivalence(fid,meshName.c_str()));
+  return nequ;
+}
+
+MEDFileEquivalences *MEDFileEquivalences::Load(med_idt fid, int nbOfEq, MEDFileMesh *owner)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalences> ret(new MEDFileEquivalences(owner));
+  if(!owner)
+    throw INTERP_KERNEL::Exception("MEDFileEquivalences::Load : owner is NULL !");
+  std::string meshName(owner->getName());
+  for(int i=0;i<nbOfEq;i++)
+    {
+      INTERP_KERNEL::AutoPtr<char> equ(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
+      INTERP_KERNEL::AutoPtr<char> desc(MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE));
+      int nstep,nocstpncor;
+      MEDFILESAFECALLERRD0(MEDequivalenceInfo,(fid,meshName.c_str(),i+1,equ,desc,&nstep,&nocstpncor));
+      std::string eqName(MEDLoaderBase::buildStringFromFortran(equ,MED_NAME_SIZE)),eqDescName(MEDLoaderBase::buildStringFromFortran(desc,MED_COMMENT_SIZE));
+      MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> eqv(MEDFileEquivalencePair::Load(ret,fid,eqName,eqDescName));
+      ret->pushEquivalence(eqv);
+    }
+  return ret.retn();
+}
+
+void MEDFileEquivalences::CheckDataArray(const DataArrayInt *data)
+{
+  if(!data)
+    return;
+  data->checkAllocated();
+  if(data->getNumberOfComponents()!=2)
+    {
+      std::ostringstream oss; oss << "MEDFileEquivalences::CheckDataArray : Input DataArray must have 2 components !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+}
+
+void MEDFileEquivalences::deepCpyFrom(const MEDFileEquivalences& other)
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> >::const_iterator it=other._equ.begin();it!=other._equ.end();it++)
+    {
+      const MEDFileEquivalencePair *elt(*it);
+      MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> eltCpy;
+      if(elt)
+        {
+          eltCpy=elt->deepCpy(this);
+        }
+      _equ.push_back(eltCpy);
+    }
+}
+
+MEDFileEquivalenceBase::MEDFileEquivalenceBase(MEDFileEquivalencePair *father):_father(father)
+{
+}
+
+MEDFileEquivalenceData::MEDFileEquivalenceData(MEDFileEquivalencePair *owner, DataArrayInt *data):MEDFileEquivalenceBase(owner),_data(data)
+{
+  if(data)
+    data->incrRef();
+}
+
+void MEDFileEquivalenceData::setArray(DataArrayInt *data)
+{
+  MEDFileEquivalences::CheckDataArray(data);
+  _data=data;
+  if(data)
+    data->incrRef();
+}
+
+std::vector<const BigMemoryObject *> MEDFileEquivalenceData::getDirectChildrenWithNull() const
+{
+  std::vector<const BigMemoryObject *> ret(1);
+  ret[0]=_data;
+  return ret;
+}
+
+bool MEDFileEquivalenceData::isEqual(const MEDFileEquivalenceData *other, std::string& what) const
+{
+  const DataArrayInt *d1(_data),*d2(other->_data);
+  if((!d1 && d2) || (d1 && !d2))
+    {
+      what="Data array is defined in this not in other (or reversely) !";
+      return false;
+    }
+  if(d1 && d2)
+    {
+      if(!d1->isEqualIfNotWhy(*d2,what))
+        return false;
+    }
+  return true;
+}
+
+void MEDFileEquivalenceData::writeLL(med_idt fid, med_entity_type medtype, med_geometry_type medgt) const
+{
+  
+  const DataArrayInt *da(getArray());
+  if(!da)
+    return ;
+  MEDFileEquivalences::CheckDataArray(da);
+  const MEDFileMesh *mesh(getFather()->getMesh());
+  int dt,it;
+  mesh->getTime(dt,it);
+  std::string meshName(mesh->getName());
+  std::string equName(getFather()->getName());
+  INTERP_KERNEL::AutoPtr<char> meshName2(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
+  INTERP_KERNEL::AutoPtr<char> name(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
+  MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_NAME_SIZE,meshName2,getFather()->getMesh()->getTooLongStrPolicy());
+  MEDLoaderBase::safeStrCpy(equName.c_str(),MED_NAME_SIZE,name,getFather()->getMesh()->getTooLongStrPolicy());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da2(da->deepCpy()); da2->rearrange(1); da2->applyLin(1,1); da2->rearrange(2);
+  MEDFILESAFECALLERWR0(MEDequivalenceCorrespondenceWr,(fid,meshName2,name,dt,it,medtype,medgt,da2->getNumberOfTuples(),da2->begin()));
+}
+
+std::size_t MEDFileEquivalenceCellType::getHeapMemorySizeWithoutChildren() const
+{
+  return sizeof(MEDFileEquivalenceCellType);
+}
+
+MEDFileEquivalenceCellType *MEDFileEquivalenceCellType::deepCpy(MEDFileEquivalencePair *owner) const
+{
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
+  if(getArray())
+    da=getArray()->deepCpy();
+  return new MEDFileEquivalenceCellType(owner,_type,da);
+}
+
+bool MEDFileEquivalenceCellType::isEqual(const MEDFileEquivalenceCellType *other, std::string& what) const
+{
+  if(_type!=other->_type)
+    {
+      what="Geo types differs !";
+      return false;
+    }
+  return MEDFileEquivalenceData::isEqual(other,what);
+}
+
+void MEDFileEquivalenceCellType::getRepr(std::ostream& oss) const
+{
+  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(_type));
+  const DataArrayInt *da(getArray());
+  oss << cm.getRepr() << ":";
+  if(da)
+    oss << da->getNumberOfTuples() << " tuples";
+  else
+    oss << "no dataarray";
+  oss << ",";
+}
+
+void MEDFileEquivalenceCellType::write(med_idt fid) const
+{
+  writeLL(fid,MED_CELL,typmai3[_type]);
+}
+
+std::vector<const BigMemoryObject *> MEDFileEquivalenceCell::getDirectChildrenWithNull() const
+{
+  std::size_t sz(_types.size());
+  std::vector<const BigMemoryObject *> ret(sz);
+  for(std::size_t i=0;i<sz;i++)
+    ret[i]=_types[i];
+  return ret;
+}
+
+std::size_t MEDFileEquivalenceCell::getHeapMemorySizeWithoutChildren() const
+{
+  return sizeof(MEDFileEquivalenceCell)+_types.capacity()*sizeof(MEDFileEquivalenceCellType);
+}
+
+MEDFileEquivalenceCell *MEDFileEquivalenceCell::Load(med_idt fid, MEDFileEquivalencePair *owner)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceCell> ret(new MEDFileEquivalenceCell(owner));
+  ret->load(fid);
+  if(ret->size()>0)
+    return ret.retn();
+  else
+    return 0;
+}
+
+void MEDFileEquivalenceCell::write(med_idt fid) const
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceCellType> >::const_iterator it=_types.begin();it!=_types.end();it++)
+    {
+      const MEDFileEquivalenceCellType *ct(*it);
+      if(ct)
+        ct->write(fid);
+    }
+}
+
+MEDFileEquivalenceCell *MEDFileEquivalenceCell::deepCpy(MEDFileEquivalencePair *owner) const
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceCell> ret(new MEDFileEquivalenceCell(owner));
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceCellType> >::const_iterator it=_types.begin();it!=_types.end();it++)
+    {
+      const MEDFileEquivalenceCellType *elt(*it);
+      MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceCellType> eltCpy;
+      if(elt)
+        eltCpy=elt->deepCpy(owner);
+      ret->_types.push_back(eltCpy);
+    }
+  return ret.retn();
+}
+
+bool MEDFileEquivalenceCell::isEqual(const MEDFileEquivalenceCell *other, std::string& what) const
+{
+  std::size_t sz(_types.size());
+  if(sz!=other->_types.size())
+    {
+      std::ostringstream oss; oss << "Nb of geo types differs : " << sz << " != " << other->_types.size();
+      what=oss.str();
+      return false;
+    }
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const MEDFileEquivalenceCellType *ct1(_types[i]),*ct2(other->_types[i]);
+      if((ct1 && !ct2) || (!ct1 && ct2))
+        {
+          std::ostringstream oss; oss << "At gt #" << i << " this is defined not other (or reversely !)";
+          what=oss.str();
+          return false;
+        }
+      if(ct1 && ct2)
+        {
+          if(!ct1->isEqual(ct2,what))
+            {
+              std::ostringstream oss; oss << "At gt #" << i << " of Eq " << getFather()->getName() << " it differs !";
+              what=oss.str()+what;
+              return false;
+            }
+        }
+    }
+  return true;
+}
+
+void MEDFileEquivalenceCell::getRepr(std::ostream& oss) const
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceCellType> >::const_iterator it=_types.begin();it!=_types.end();it++)
+    {
+      const MEDFileEquivalenceCellType *elt(*it);
+      if(elt)
+        elt->getRepr(oss);
+    }
+}
+
+DataArrayInt *MEDFileEquivalenceCell::getArray(INTERP_KERNEL::NormalizedCellType type)
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceCellType> >::iterator it=_types.begin();it!=_types.end();it++)
+    {
+      MEDFileEquivalenceCellType *elt(*it);
+      if(elt && elt->getType()==type)
+        return elt->getArray();
+    }
+  std::ostringstream oss; oss << "MEDFileEquivalenceCell::getArray : In Equivalence \"" << getFather()->getName() << "\" the geotype " << type << " is not available !";
+  throw INTERP_KERNEL::Exception(oss.str().c_str());
+}
+
+void MEDFileEquivalenceCell::setArray(int meshDimRelToMax, DataArrayInt *da)
+{
+  if(!da)
+    return ;
+  MEDFileEquivalences::CheckDataArray(da);
+  MEDFileMesh *mm(getMesh());
+  int totalNbOfCells(mm->getNumberOfCellsAtLevel(meshDimRelToMax));
+  //
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(da->deepCpy()); tmp->rearrange(1);
+  int maxv,minv;
+  tmp->getMinMaxValues(minv,maxv);
+  if((minv<0 || minv>=totalNbOfCells) || (maxv<0 || maxv>=totalNbOfCells))
+    {
+      std::ostringstream oss; oss << "MEDFileEquivalenceCell::setArray : Input 2 component DataArray has incorrect values ! all values must be in [0," << totalNbOfCells << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  //
+  std::vector<INTERP_KERNEL::NormalizedCellType> gts(mm->getGeoTypesAtLevel(meshDimRelToMax));
+  int startId(0),endId;
+  std::vector<int> compS(1,0);
+  for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it=gts.begin();it!=gts.end();it++)
+    {
+      endId=startId+mm->getNumberOfCellsWithType(*it);
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da0(da->keepSelectedComponents(compS));
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids(da0->getIdsInRange(startId,endId));
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da1(da->selectByTupleIdSafe(ids->begin(),ids->end()));
+      da1->applyLin(1,-startId);
+      setArrayForType(*it,da1);
+      startId=endId;
+    }
+}
+
+void MEDFileEquivalenceCell::setArrayForType(INTERP_KERNEL::NormalizedCellType type, DataArrayInt *da)
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceCellType> >::iterator it=_types.begin();it!=_types.end();it++)
+    {
+      MEDFileEquivalenceCellType *elt(*it);
+      if(elt && elt->getType()==type)
+        {
+          elt->setArray(da);
+          return ;
+        }
+    }
+  MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceCellType> newElt(new MEDFileEquivalenceCellType(getFather(),type,da));
+  _types.push_back(newElt);
+}
+
+std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileEquivalenceCell::getTypes() const
+{
+  std::vector<INTERP_KERNEL::NormalizedCellType> ret;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceCellType> >::const_iterator it=_types.begin();it!=_types.end();it++)
+    {
+      const MEDFileEquivalenceCellType *elt(*it);
+      if(elt)
+        ret.push_back(elt->getType());
+    }
+  return ret;
+}
+
+void MEDFileEquivalenceCell::load(med_idt fid)
+{
+  std::string meshName(getFather()->getFather()->getMeshName()),name(getName());
+  int dt,it;
+  getFather()->getFather()->getDtIt(dt,it);
+  for(int i=0;i<MED_N_CELL_FIXED_GEO;i++)
+    {
+      med_int ncor;
+      MEDFILESAFECALLERRD0(MEDequivalenceCorrespondenceSize,(fid,meshName.c_str(),name.c_str(),dt,it,MED_CELL,typmai[i],&ncor));
+      if(ncor>0)
+        {
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da(DataArrayInt::New());
+          da->alloc(ncor*2);
+          MEDFILESAFECALLERRD0(MEDequivalenceCorrespondenceRd,(fid,meshName.c_str(),name.c_str(),dt,it,MED_CELL,typmai[i],da->getPointer()));
+          da->applyLin(1,-1);
+          da->rearrange(2);
+          MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceCellType> ct(new MEDFileEquivalenceCellType(getFather(),typmai2[i],da));
+          _types.push_back(ct);
+        }
+    }
+}
+
+std::size_t MEDFileEquivalenceNode::getHeapMemorySizeWithoutChildren() const
+{
+  return sizeof(MEDFileEquivalenceNode);
+}
+
+void MEDFileEquivalenceNode::write(med_idt fid) const
+{
+  writeLL(fid,MED_NODE,MED_NONE);
+}
+
+MEDFileEquivalenceNode *MEDFileEquivalenceNode::deepCpy(MEDFileEquivalencePair *owner) const
+{
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
+  if(getArray())
+    da=getArray()->deepCpy();
+  MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceNode> ret(new MEDFileEquivalenceNode(owner,da));
+  return ret.retn();
+}
+
+bool MEDFileEquivalenceNode::isEqual(const MEDFileEquivalenceNode *other, std::string& what) const
+{
+  return MEDFileEquivalenceData::isEqual(other,what);
+}
+
+void MEDFileEquivalenceNode::getRepr(std::ostream& oss) const
+{
+  const DataArrayInt *da(getArray());
+  if(!da)
+    oss << " No dataarray defined !" << std::endl;
+  else
+    oss << da->getNumberOfTuples() << " tuples in node equivalence." << std::endl;
+}
diff --git a/src/MEDLoader/MEDFileEquivalence.hxx b/src/MEDLoader/MEDFileEquivalence.hxx
new file mode 100644 (file)
index 0000000..bcf1490
--- /dev/null
@@ -0,0 +1,202 @@
+// 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
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __MEDFILEEQUIVALENCE_HXX__
+#define __MEDFILEEQUIVALENCE_HXX__
+
+#include "MEDLoaderDefines.hxx"
+#include "MEDCouplingRefCountObject.hxx"
+#include "MEDCouplingMemArray.hxx"
+#include "MEDFileUtilities.hxx"
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+
+#include <vector>
+
+namespace ParaMEDMEM
+{
+  class MEDFileEquivalenceCell;
+  class MEDFileEquivalenceNode;
+  class MEDFileEquivalences;
+  class MEDFileMesh;
+
+  class MEDFileEquivalencePair : public RefCountObject
+  {
+  public:
+    static MEDFileEquivalencePair *Load(MEDFileEquivalences *father, med_idt fid, const std::string& name, const std::string &desc);
+    void write(med_idt fid) const;
+    const MEDFileEquivalences *getFather() const { return _father; }
+    MEDFileEquivalences *getFather() { return _father; }
+    const MEDFileMesh *getMesh() const;
+    MEDFileMesh *getMesh();
+    MEDFileEquivalencePair *deepCpy(MEDFileEquivalences *father) const;
+    bool isEqual(const MEDFileEquivalencePair *other, std::string& what) const;
+    void getRepr(std::ostream& oss) const;
+    static MEDFileEquivalencePair *New(MEDFileEquivalences *father, const std::string& name);
+    MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
+    MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
+  public:
+    MEDLOADER_EXPORT std::string getName() const { return _name; }
+    MEDLOADER_EXPORT void setName(const std::string& name) { _name=name; }
+    MEDLOADER_EXPORT std::string getDescription() const { return _description; }
+    MEDLOADER_EXPORT void setDescription(const std::string& descr) { _description=descr; }
+    MEDLOADER_EXPORT MEDFileEquivalenceCell *initCell();
+    MEDLOADER_EXPORT MEDFileEquivalenceNode *initNode();
+    MEDLOADER_EXPORT MEDFileEquivalenceCell *getCell() { return _cell; }
+    MEDLOADER_EXPORT MEDFileEquivalenceNode *getNode() { return _node; }
+    MEDLOADER_EXPORT void setArray(int meshDimRelToMaxExt, DataArrayInt *da);
+  private:
+    MEDFileEquivalencePair(MEDFileEquivalences *father, const std::string& name, const std::string& desc):_father(father),_name(name),_description(desc) { }
+    void load(med_idt fid);
+  private:
+    MEDFileEquivalences *_father;
+    std::string _name;
+    std::string _description;
+    MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceCell> _cell;
+    MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceNode> _node;
+  };
+
+  class MEDFileEquivalences : public RefCountObject
+  {
+  public:
+    MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
+    MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
+    MEDLOADER_EXPORT const MEDFileMesh *getMesh() const { return _owner; }
+    MEDLOADER_EXPORT MEDFileMesh *getMesh() { return _owner; }
+    void getDtIt(int &dt, int &it) const;
+    std::string getMeshName() const;
+    void pushEquivalence(MEDFileEquivalencePair *elt);
+    static MEDFileEquivalences *New(MEDFileMesh *owner) { return new MEDFileEquivalences(owner); }
+    MEDFileEquivalences *deepCpy(MEDFileMesh *owner) const;
+    bool isEqual(const MEDFileEquivalences *other, std::string& what) const;
+    void getRepr(std::ostream& oss) const;
+  public:
+    MEDLOADER_EXPORT MEDFileEquivalencePair *getEquivalence(int i);
+    MEDLOADER_EXPORT MEDFileEquivalencePair *getEquivalenceWithName(const std::string& name);
+    MEDLOADER_EXPORT int size() const;
+    MEDLOADER_EXPORT std::vector<std::string> getEquivalenceNames() const;
+    MEDLOADER_EXPORT MEDFileEquivalencePair *appendEmptyEquivalenceWithName(const std::string& name);
+    MEDLOADER_EXPORT void killEquivalenceWithName(const std::string& name);
+    MEDLOADER_EXPORT void killEquivalenceAt(int i);
+    MEDLOADER_EXPORT void clear();
+  public:
+    void write(med_idt fid) const;
+    static int PresenceOfEquivalences(med_idt fid, const std::string& meshName);
+    static MEDFileEquivalences *Load(med_idt fid, int nbOfEq, MEDFileMesh *owner);
+    static void CheckDataArray(const DataArrayInt *data);
+  private:
+    MEDFileEquivalences(MEDFileMesh *owner):_owner(owner) { }
+    void deepCpyFrom(const MEDFileEquivalences& other);
+  private:
+    MEDFileMesh *_owner;
+    std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalencePair> > _equ;
+  };
+
+  class MEDFileEquivalenceBase : public RefCountObject
+  {
+  protected:
+    MEDFileEquivalenceBase(MEDFileEquivalencePair *father);
+    const MEDFileEquivalencePair *getFather() const { return _father; }
+    MEDFileEquivalencePair *getFather() { return _father; }
+    const MEDFileMesh *getMesh() const { return getFather()->getMesh(); }
+    MEDFileMesh *getMesh() { return getFather()->getMesh(); }
+  protected:
+    ~MEDFileEquivalenceBase() { }
+  private:
+    MEDFileEquivalencePair *_father;
+  };
+
+  class MEDFileEquivalenceData : public MEDFileEquivalenceBase
+  {
+  public:
+    MEDFileEquivalenceData(MEDFileEquivalencePair *owner, DataArrayInt *data);
+    MEDLOADER_EXPORT void setArray(DataArrayInt *data);
+    MEDLOADER_EXPORT const DataArrayInt *getArray() const { return _data; }
+    MEDLOADER_EXPORT DataArrayInt *getArray() { return _data; }
+    MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
+    bool isEqual(const MEDFileEquivalenceData *other, std::string& what) const;
+  protected:
+    void writeLL(med_idt fid, med_entity_type medtype, med_geometry_type medgt) const;
+  protected:
+    ~MEDFileEquivalenceData() { }
+  protected:
+    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _data;
+  };
+
+  class MEDFileEquivalenceCellType : public MEDFileEquivalenceData
+  {
+  public:
+    MEDFileEquivalenceCellType(MEDFileEquivalencePair *owner, INTERP_KERNEL::NormalizedCellType type, DataArrayInt *data):MEDFileEquivalenceData(owner,data),_type(type) { }
+    MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
+    INTERP_KERNEL::NormalizedCellType getType() const { return _type; }
+    MEDFileEquivalenceCellType *deepCpy(MEDFileEquivalencePair *owner) const;
+    bool isEqual(const MEDFileEquivalenceCellType *other, std::string& what) const;
+    void getRepr(std::ostream& oss) const;
+  public:
+    void write(med_idt fid) const;
+  private:
+    ~MEDFileEquivalenceCellType() { }
+  private:
+    INTERP_KERNEL::NormalizedCellType _type;
+  };
+
+  class MEDFileEquivalenceCell : public MEDFileEquivalenceBase
+  {
+  public:
+    MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
+    MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
+    static MEDFileEquivalenceCell *Load(med_idt fid, MEDFileEquivalencePair *owner);
+    void write(med_idt fid) const;
+    MEDFileEquivalenceCell *deepCpy(MEDFileEquivalencePair *owner) const;
+    bool isEqual(const MEDFileEquivalenceCell *other, std::string& what) const;
+    void getRepr(std::ostream& oss) const;
+  public:
+    MEDLOADER_EXPORT void clear() { _types.clear(); }
+    MEDLOADER_EXPORT std::size_t size() const { return _types.size(); }
+    MEDLOADER_EXPORT DataArrayInt *getArray(INTERP_KERNEL::NormalizedCellType type);
+    MEDLOADER_EXPORT void setArray(int meshDimRelToMax, DataArrayInt *da);
+    MEDLOADER_EXPORT void setArrayForType(INTERP_KERNEL::NormalizedCellType type, DataArrayInt *da);
+    MEDLOADER_EXPORT std::vector<INTERP_KERNEL::NormalizedCellType> getTypes() const;
+  public:
+    MEDFileEquivalenceCell(MEDFileEquivalencePair *owner):MEDFileEquivalenceBase(owner) { }
+  private:
+    ~MEDFileEquivalenceCell() { }
+  private:
+    void load(med_idt fid);
+    std::string getName() const { return getFather()->getName(); }
+  private:
+    std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileEquivalenceCellType> > _types;
+  };
+
+  class MEDFileEquivalenceNode : public MEDFileEquivalenceData
+  {
+  public:
+    MEDFileEquivalenceNode(MEDFileEquivalencePair *owner, DataArrayInt *data):MEDFileEquivalenceData(owner,data) { }
+    MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
+    void write(med_idt fid) const;
+    MEDFileEquivalenceNode *deepCpy(MEDFileEquivalencePair *owner) const;
+    bool isEqual(const MEDFileEquivalenceNode *other, std::string& what) const;
+    void getRepr(std::ostream& oss) const;
+  private:
+    ~MEDFileEquivalenceNode() { }
+  };
+}
+
+#endif
+