]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Addition of methods on advanced mesh comparison.
authorageay <ageay>
Tue, 24 Aug 2010 09:27:52 +0000 (09:27 +0000)
committerageay <ageay>
Tue, 24 Aug 2010 09:27:52 +0000 (09:27 +0000)
26 files changed:
src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx
src/MEDCoupling/MEDCouplingCMesh.cxx
src/MEDCoupling/MEDCouplingCMesh.hxx
src/MEDCoupling/MEDCouplingExtrudedMesh.cxx
src/MEDCoupling/MEDCouplingExtrudedMesh.hxx
src/MEDCoupling/MEDCouplingFieldDouble.cxx
src/MEDCoupling/MEDCouplingFieldDouble.hxx
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingMemArray.txx
src/MEDCoupling/MEDCouplingMesh.cxx
src/MEDCoupling/MEDCouplingMesh.hxx
src/MEDCoupling/MEDCouplingPointSet.cxx
src/MEDCoupling/MEDCouplingPointSet.hxx
src/MEDCoupling/MEDCouplingPointSet.txx
src/MEDCoupling/MEDCouplingRemapper.cxx
src/MEDCoupling/MEDCouplingRemapper.hxx
src/MEDCoupling/MEDCouplingTimeDiscretization.cxx
src/MEDCoupling/MEDCouplingTimeDiscretization.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling/MEDCouplingUMeshDesc.cxx
src/MEDCoupling/MEDCouplingUMeshDesc.hxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingDataForTest.py
src/MEDCoupling_Swig/libMEDCoupling_Swig.i

index d91a8e16f931e537f5c992906060b8b6e40c738f..7dd470af86c013005a08ccc7d332e91d364c76bc 100644 (file)
@@ -32,6 +32,7 @@ namespace ParaMEDMEM
     MEDCouplingAutoRefCountObjectPtr(T *ptr):_ptr(ptr) { }
     ~MEDCouplingAutoRefCountObjectPtr() { destroyPtr(); }
     MEDCouplingAutoRefCountObjectPtr &operator=(const MEDCouplingAutoRefCountObjectPtr& other) { destroyPtr(); referPtr(other._ptr); return *this; }
+    MEDCouplingAutoRefCountObjectPtr &operator=(T *ptr) { destroyPtr(); _ptr=ptr; return *this; }
     T *operator->() { return _ptr ; }
     const T *operator->() const { return _ptr; }
     T& operator*() { return *_ptr; }
index 4de2ee693ae65b325a7a5d02e37b52574f49408d..fdd7ced5ab626647d3cd7789b3eff1e9e6b43969 100644 (file)
@@ -147,11 +147,6 @@ void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
       }
 }
 
-bool MEDCouplingCMesh::isStructured() const
-{
-  return true;
-}
-
 int MEDCouplingCMesh::getNumberOfCells() const
 {
   int ret=1;
index 9c64a06cb18f8c3cc5c23abfbb91fdeee4c81940..3919f776ab7e941fea4a46494c4982897962e512 100644 (file)
@@ -40,7 +40,6 @@ namespace ParaMEDMEM
     void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
                               DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception);
     void checkCoherency() const throw(INTERP_KERNEL::Exception);
-    bool isStructured() const;
     int getNumberOfCells() const;
     int getNumberOfNodes() const;
     int getSpaceDimension() const;
index 0aaedbc4e1ce676759a23446bc82e62319481f24..1d8b85a5c3c9b693988d7dd8262f8ae35992e539 100644 (file)
@@ -120,11 +120,6 @@ MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh&
     }
 }
 
-bool MEDCouplingExtrudedMesh::isStructured() const
-{
-  return false;
-}
-
 int MEDCouplingExtrudedMesh::getNumberOfCells() const
 {
   return _mesh2D->getNumberOfCells()*_mesh1D->getNumberOfCells();
index 70df7b2a871349543f91051aff24919a03f61ebf..50cc24ec07ced3eeb8c095116a11840e7429e666 100644 (file)
@@ -39,7 +39,6 @@ namespace ParaMEDMEM
     static MEDCouplingExtrudedMesh *New();
     MEDCouplingMeshType getType() const;
     void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
-    bool isStructured() const;
     int getNumberOfCells() const;
     int getNumberOfNodes() const;
     int getSpaceDimension() const;
index 4fc80438a377490cf0d2cf20f951f6468b2ee2b2..d682581179da3c9d7e06c60f6094540a549de134 100644 (file)
@@ -60,6 +60,19 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfT
   return ret;
 }
 
+/*!
+ * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason).
+ */
+void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
+{
+  if(other)
+    {
+      setName(other->_name.c_str());
+      setDescription(other->_desc.c_str());
+      _time_discr->copyTinyStringsFrom(*other->_time_discr);
+    }
+}
+
 bool MEDCouplingFieldDouble::isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const
 {
   const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
@@ -577,7 +590,8 @@ bool MEDCouplingFieldDouble::mergeNodes(double eps) throw(INTERP_KERNEL::Excepti
     throw INTERP_KERNEL::Exception("Invalid mesh to apply mergeNodes on it !");
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
   bool ret;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes(eps,ret);
+  int ret2;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes(eps,ret,ret2);
   if(!ret)//no nodes have been merged.
     return ret;
   std::vector<DataArrayDouble *> arrays;
index 3e418c657ede2fbe4ba74e269c722b5bdc475de8..72a8a43e620fa99cb24da3ab409986015d1671d3 100644 (file)
@@ -32,6 +32,7 @@ namespace ParaMEDMEM
   {
   public:
     static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=NO_TIME);
+    void copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception);
     bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const;
     bool areCompatibleForMerge(const MEDCouplingField *other) const;
     bool areStrictlyCompatible(const MEDCouplingField *other) const;
index 24c1bb171e49860b87c44c6d59d69798419cdc70..10bcd4333a311887f9c256b4feacb3a3dd09b5dc 100644 (file)
@@ -75,6 +75,11 @@ void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
   declareAsNew();
 }
 
+void DataArrayDouble::fillWithZero()
+{
+  _mem.fillWithValue(0.);
+}
+
 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
 {
   if(!areInfoEquals(other))
@@ -387,6 +392,21 @@ void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
   declareAsNew();
 }
 
+void DataArrayInt::fillWithZero()
+{
+  _mem.fillWithValue(0);
+}
+
+void DataArrayInt::transformWithIndArr(const int *indArr)
+{
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component !");
+  int nbOfTuples=getNumberOfTuples();
+  int *pt=getPointer();
+  for(int i=0;i<nbOfTuples;i++)
+    pt[i]=indArr[pt[i]];
+}
+
 bool DataArrayInt::isEqual(const DataArrayInt& other) const
 {
   if(!areInfoEquals(other))
@@ -429,6 +449,23 @@ DataArrayInt *DataArrayInt::renumber(const int *old2New) const
   return ret;
 }
 
+/*!
+ * This method checks that 'this' is with numberofcomponents == 1 and that it is equal to
+ * stdext::iota() of size getNumberOfTuples. This method is particalary usefull for DataArrayInt instances
+ * that represents a renumbering array to check the real need in renumbering. 
+ */
+bool DataArrayInt::isIdentity() const
+{
+  if(getNumberOfComponents()!=1)
+    return false;
+  int nbOfTuples=getNumberOfTuples();
+  const int *pt=getConstPointer();
+  for(int i=0;i<nbOfTuples;i++,pt++)
+    if(*pt!=i)
+      return false;
+  return true;
+}
+
 DataArrayDouble *DataArrayInt::convertToDblArr() const
 {
   DataArrayDouble *ret=DataArrayDouble::New();
index e355c610bbe965b7bff52514a9a24f35b93b5971..945d7b70c5570fbb45e32121fbdb04aeacd39c55 100644 (file)
@@ -60,6 +60,7 @@ namespace ParaMEDMEM
     T operator[](int id) const { return _pointer.getConstPointer()[id]; }
     T& operator[](int id) { return _pointer.getPointer()[id]; }
     bool isEqual(const MemArray<T>& other, T prec) const;
+    void fillWithValue(const T& val);
     void alloc(int nbOfElements);
     void reAlloc(int newNbOfElements);
     void useArray(const T *array, bool ownership, DeallocType type, int nbOfElem);
@@ -109,6 +110,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayDouble *deepCopy() const;
     MEDCOUPLING_EXPORT DataArrayDouble *performCpy(bool deepCpy) const;
     MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo);
+    MEDCOUPLING_EXPORT void fillWithZero();
     MEDCOUPLING_EXPORT bool isEqual(const DataArrayDouble& other, double prec) const;
     //!alloc or useArray should have been called before.
     MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples);
@@ -150,11 +152,14 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *performCpy(bool deepCpy) const;
     MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT bool isEqual(const DataArrayInt& other) const;
+    MEDCOUPLING_EXPORT void fillWithZero();
+    MEDCOUPLING_EXPORT void transformWithIndArr(const int *indArr);
     //!alloc or useArray should have been called before.
     MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples);
     MEDCOUPLING_EXPORT DataArrayDouble *convertToDblArr() const;
     MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New);
     MEDCOUPLING_EXPORT DataArrayInt *renumber(const int *old2New) const;
+    MEDCOUPLING_EXPORT bool isIdentity() const;
     MEDCOUPLING_EXPORT DataArrayInt *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void getTuple(int tupleId, int *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); }
     MEDCOUPLING_EXPORT int getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; }
index 476f147aeb1d505f42160008474826792ca3bf47..cff97d05a44be215df76cf5df7728677e4967356 100644 (file)
@@ -92,6 +92,13 @@ namespace ParaMEDMEM
         return false;
     return true;
   }
+  
+  template<class T>
+  void MemArray<T>::fillWithValue(const T& val)
+  {
+    T *pt=_pointer.getPointer();
+    std::fill(pt,pt+_nb_of_elem,val);
+  }
 
   template<class T>
   void MemArray<T>::alloc(int nbOfElements)
index d9900e51d5671b98e0818f917f2656a7e724cd10..cf181274f82b14a6cd6957e82886b3736a4afe7d 100644 (file)
 
 using namespace ParaMEDMEM;
 
+/*!
+ * This method is only for ParaMEDMEM in ParaFIELD constructor.
+ */
+bool MEDCouplingMesh::isStructured() const
+{
+  return getType()==CARTESIAN;
+}
+
+bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const
+{
+  return _name==other->_name;
+}
+
 /*!
  * This method checks geo equivalence between two meshes : 'this' and 'other'.
  * If no exception is throw 'this' and 'other' are geometrically equivalent regarding 'levOfCheck' level.
index 4ca8f572607b972b9ce40e10213bab33d06b11c7..dfb54ce215e87a10eef87cfc0287e1ab0e79ec30 100644 (file)
@@ -49,9 +49,10 @@ namespace ParaMEDMEM
     const char *getName() const { return _name.c_str(); }
     virtual MEDCouplingMesh *deepCpy() const = 0;
     virtual MEDCouplingMeshType getType() const = 0;
+    bool isStructured() const;
     virtual void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
     // comparison methods
-    virtual bool isEqual(const MEDCouplingMesh *other, double prec) const { return _name==other->_name; }
+    virtual bool isEqual(const MEDCouplingMesh *other, double prec) const;
     virtual void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
                                       DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) = 0;
     virtual void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception);
@@ -59,7 +60,6 @@ namespace ParaMEDMEM
                              DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception);
     //
     virtual void checkCoherency() const throw(INTERP_KERNEL::Exception) = 0;
-    virtual bool isStructured() const = 0;
     virtual int getNumberOfCells() const = 0;
     virtual int getNumberOfNodes() const = 0;
     virtual int getSpaceDimension() const = 0;
index b9c07a98b472909c58973069767933778041a145..142b0e1123c13dee209fdaa6fb605824ceeb6277 100644 (file)
@@ -73,11 +73,6 @@ void MEDCouplingPointSet::updateTime()
     }
 }
 
-bool MEDCouplingPointSet::isStructured() const
-{
-  return false;
-}
-
 void MEDCouplingPointSet::setCoords(DataArrayDouble *coords)
 {
   if( coords != _coords )
@@ -135,13 +130,34 @@ bool MEDCouplingPointSet::areCoordsEqual(const MEDCouplingPointSet& other, doubl
   return _coords->isEqual(*other._coords,prec);
 }
 
+/*!
+ * This method is typically the base method used for implementation of mergeNodes. This method computes this permutation array using as input,
+ * This method is const ! So this method simply computes the array, no permutation of nodes is done.
+ * a precision 'precision' and a 'limitNodeId' that is the node id so that every nodes which id is strictly lower than 'limitNodeId' will not be merged.
+ * To desactivate this advanced feature put -1 to this argument.
+ * @param areNodesMerged output parameter that states if some nodes have been "merged" in returned array
+ * @param newNbOfNodes output parameter too this is the maximal id in returned array to avoid to recompute it.
+ */
+DataArrayInt *MEDCouplingPointSet::buildPermArrayForMergeNode(int limitNodeId, double precision, bool& areNodesMerged, int& newNbOfNodes) const
+{
+  DataArrayInt *comm,*commI;
+  findCommonNodes(limitNodeId,precision,comm,commI);
+  int oldNbOfNodes=getNumberOfNodes();
+  DataArrayInt *ret=buildNewNumberingFromCommNodesFrmt(comm,commI,newNbOfNodes);
+  areNodesMerged=(oldNbOfNodes!=newNbOfNodes);
+  comm->decrRef();
+  commI->decrRef();
+  return ret;
+}
+
 /*!
  * This methods searches for each node n1 nodes in _coords that are less far than 'prec' from n1. if any these nodes are stored in params
  * comm and commIndex.
+ * @param limitNodeId is the limit node id. All nodes which id is strictly lower than 'limitNodeId' will not be merged.
  * @param comm out parameter (not inout)
  * @param commIndex out parameter (not inout)
  */
-void MEDCouplingPointSet::findCommonNodes(DataArrayInt *&comm, DataArrayInt *&commIndex, double prec) const
+void MEDCouplingPointSet::findCommonNodes(int limitNodeId, double prec, DataArrayInt *&comm, DataArrayInt *&commIndex) const
 {
   comm=DataArrayInt::New();
   commIndex=DataArrayInt::New();
@@ -163,13 +179,13 @@ void MEDCouplingPointSet::findCommonNodes(DataArrayInt *&comm, DataArrayInt *&co
   switch(spaceDim)
     {
     case 3:
-      findCommonNodesAlg<3>(bbox,nbNodesOld,prec,c,cI);
+      findCommonNodesAlg<3>(bbox,nbNodesOld,limitNodeId,prec,c,cI);
       break;
     case 2:
-      findCommonNodesAlg<2>(bbox,nbNodesOld,prec,c,cI);
+      findCommonNodesAlg<2>(bbox,nbNodesOld,limitNodeId,prec,c,cI);
       break;
     case 1:
-      findCommonNodesAlg<1>(bbox,nbNodesOld,prec,c,cI);
+      findCommonNodesAlg<1>(bbox,nbNodesOld,limitNodeId,prec,c,cI);
       break;
     default:
       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords. Must be 1,2 or 3.");
index 85d565f5548a8ce239ae31fc5c565573b9d851b1..ac69fee23de501617eef9499ffe7b55d8b5e8a0b 100644 (file)
@@ -43,7 +43,6 @@ namespace ParaMEDMEM
     ~MEDCouplingPointSet();
   public:
     void updateTime();
-    bool isStructured() const;
     int getNumberOfNodes() const;
     int getSpaceDimension() const;
     void setCoords(DataArrayDouble *coords);
@@ -52,8 +51,9 @@ namespace ParaMEDMEM
     void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
     bool isEqual(const MEDCouplingMesh *other, double prec) const;
     bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const;
-    virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged) = 0;
-    void findCommonNodes(DataArrayInt *&comm, DataArrayInt *&commIndex, double prec) const;
+    virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0;
+    DataArrayInt *buildPermArrayForMergeNode(int limitNodeId, double precision, bool& areNodesMerged, int& newNbOfNodes) const;
+    void findCommonNodes(int limitNodeId, double prec, DataArrayInt *&comm, DataArrayInt *&commIndex) const;
     DataArrayInt *buildNewNumberingFromCommNodesFrmt(const DataArrayInt *comm, const DataArrayInt *commIndex,
                                                      int& newNbOfNodes) const;
     void getBoundingBox(double *bbox) const;
@@ -64,6 +64,7 @@ namespace ParaMEDMEM
     void scale(const double *point, double factor);
     void changeSpaceDimension(int newSpaceDim) throw(INTERP_KERNEL::Exception);
     void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
+    virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) = 0;
     void findNodesOnPlane(const double *pt, const double *vec, double eps, std::vector<int>& nodes) const throw(INTERP_KERNEL::Exception);
     static DataArrayDouble *mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2);
     static MEDCouplingPointSet *buildInstanceFromMeshType(MEDCouplingMeshType type);
@@ -95,7 +96,7 @@ namespace ParaMEDMEM
     static bool isButterfly2DCell(const std::vector<double>& res, bool isQuad);
     template<int SPACEDIM>
     void findCommonNodesAlg(std::vector<double>& bbox,
-                            int nbNodes, double prec, std::vector<int>& c, std::vector<int>& cI) const;
+                            int nbNodes, int limitNodeId, double prec, std::vector<int>& c, std::vector<int>& cI) const;
   protected:
     DataArrayDouble *_coords;
   };
index 300aab2352ec854ec68fea03008ee153aa86a438..bae1955669521d800191c474531e4e76168d8ce1 100644 (file)
@@ -29,7 +29,7 @@ namespace ParaMEDMEM
 {
   template<int SPACEDIM>
   void MEDCouplingPointSet::findCommonNodesAlg(std::vector<double>& bbox,
-                                               int nbNodes, double prec,
+                                               int nbNodes, int limitNodeId, double prec,
                                                std::vector<int>& c, std::vector<int>& cI) const
   {
     const double *coordsPtr=_coords->getConstPointer();
@@ -52,8 +52,9 @@ namespace ParaMEDMEM
             std::vector<int> commonNodes;
             for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
               if(*it!=i)
-                if(INTERP_KERNEL::distance2<SPACEDIM>(coordsPtr+SPACEDIM*i,coordsPtr+SPACEDIM*(*it))<prec2)
-                  commonNodes.push_back(*it);
+                if(*it>=limitNodeId)
+                  if(INTERP_KERNEL::distance2<SPACEDIM>(coordsPtr+SPACEDIM*i,coordsPtr+SPACEDIM*(*it))<prec2)
+                    commonNodes.push_back(*it);
             if(!commonNodes.empty())
               {
                 cI.push_back(cI.back()+commonNodes.size()+1);
index 071dc783539db062103cee0faeb143f19a96fa1e..3337b8b4e1a711c5f0a6fe851bbe0a1a54b41152 100644 (file)
@@ -146,7 +146,7 @@ bool MEDCouplingRemapper::setOptionDouble(const std::string& key, double value)
   return INTERP_KERNEL::InterpolationOptions::setOptionDouble(key,value);
 }
 
-bool MEDCouplingRemapper::setOptionString(const std::string& key, std::string& value)
+bool MEDCouplingRemapper::setOptionString(const std::string& key, const std::string& value)
 {
   return INTERP_KERNEL::InterpolationOptions::setOptionString(key,value);
 }
index 473ba0c827ffe70f31f7cf94b43cd2af2abcc47d..14d402d0365d5a45e3db4e631866af24db86ea7a 100644 (file)
@@ -50,7 +50,7 @@ namespace ParaMEDMEM
     MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception);
     MEDCOUPLINGREMAPPER_EXPORT bool setOptionInt(const std::string& key, int value);
     MEDCOUPLINGREMAPPER_EXPORT bool setOptionDouble(const std::string& key, double value);
-    MEDCOUPLINGREMAPPER_EXPORT bool setOptionString(const std::string& key, std::string& value);
+    MEDCOUPLINGREMAPPER_EXPORT bool setOptionString(const std::string& key, const std::string& value);
   public:
     MEDCOUPLINGREMAPPER_EXPORT static void printMatrix(const std::vector<std::map<int,double> >& m);
   private:
index b8da1c8121860a0776afcb013fb62cdfb1552406..cb5d7e6f63a3b3a3807dfa68c7ee8499f7307bc3 100644 (file)
@@ -59,6 +59,12 @@ void MEDCouplingTimeDiscretization::copyTinyAttrFrom(const MEDCouplingTimeDiscre
   _time_tolerance=other._time_tolerance;
 }
 
+void MEDCouplingTimeDiscretization::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other)
+{
+  if(_array && other._array)
+    _array->copyStringInfoFrom(*other._array);
+}
+
 void MEDCouplingTimeDiscretization::checkCoherency() const throw(INTERP_KERNEL::Exception)
 {
   if(!_array)
@@ -1091,6 +1097,16 @@ void MEDCouplingTwoTimeSteps::copyTinyAttrFrom(const MEDCouplingTimeDiscretizati
   _end_it=otherC._end_it;
 }
 
+void MEDCouplingTwoTimeSteps::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other)
+{
+  MEDCouplingTimeDiscretization::copyTinyStringsFrom(other);
+  const MEDCouplingTwoTimeSteps* otherC=dynamic_cast<const MEDCouplingTwoTimeSteps* >(&other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("Trying to operate copyTinyStringsFrom on different field type (two times//one time) !");
+  if(_end_array && otherC->_end_array)
+    _end_array->copyStringInfoFrom(*otherC->_end_array);
+}
+
 DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() const
 {
   return _end_array;
index bdf62a4ad6b64a9cfa8ebcb65e021117fe335d37..232f008b8f8a59593dfe89658803fdab6bda7389 100644 (file)
@@ -41,6 +41,7 @@ namespace ParaMEDMEM
     void updateTime();
     static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type);
     virtual void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other);
+    virtual void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other);
     virtual void checkCoherency() const throw(INTERP_KERNEL::Exception);
     virtual bool areCompatible(const MEDCouplingTimeDiscretization *other) const;
     virtual bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const;
@@ -239,6 +240,7 @@ namespace ParaMEDMEM
   public:
     void updateTime();
     void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other);
+    void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other);
     DataArrayDouble *getEndArray() const;
     void checkCoherency() const throw(INTERP_KERNEL::Exception);
     bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const;
index 8fb502ee6ef3e82fd284508eb8f1d21bc038deaf..d3e93fb91fc8b199579787da0b6c4c8586a2decb 100644 (file)
@@ -216,24 +216,32 @@ void MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int ce
   const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Two meshes are not not unstructured !");
-  checkFastEquivalWith(other,prec);
+  MEDCouplingMesh::checkFastEquivalWith(other,prec);
   if(_types!=otherC->_types)
     throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Types are not equal !");
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=mergeUMeshes(this,otherC);
   bool areNodesMerged;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m->mergeNodes(prec,areNodesMerged);
+  int newNbOfNodes;
+  int oldNbOfNodes=getNumberOfNodes();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m->buildPermArrayForMergeNode(oldNbOfNodes,prec,areNodesMerged,newNbOfNodes);
+  //mergeNodes
   if(!areNodesMerged)
     throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Nodes are incompatible ! ");
-  int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfNodes());
-  const int *pt=std::find_if(da->getConstPointer()+getNumberOfNodes(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),maxId));
+  const int *pt=std::find_if(da->getConstPointer()+oldNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),oldNbOfNodes-1));
   if(pt!=da->getConstPointer()+da->getNbOfElems())
     throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some nodes in other are not in this !");
-  nodeCor=DataArrayInt::New();
-  nodeCor->alloc(otherC->getNumberOfNodes(),1);
-  std::copy(da->getConstPointer()+getNumberOfNodes(),da->getConstPointer()+da->getNbOfElems(),nodeCor->getPointer());
+  m->renumberNodes(da->getConstPointer(),newNbOfNodes);
+  //
+  nodeCor=da->substr(oldNbOfNodes);
+  da=m->mergeNodes(prec,areNodesMerged,newNbOfNodes);
+  if(nodeCor->isIdentity())
+    {
+      nodeCor->decrRef();
+      nodeCor=0;
+    }
   //
   da=m->zipConnectivityTraducer(cellCompPol);
-  maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells());
+  int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells());
   pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),maxId));
   if(pt!=da->getConstPointer()+da->getNbOfElems())
     {
@@ -243,6 +251,11 @@ void MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int ce
   cellCor=DataArrayInt::New();
   cellCor->alloc(otherC->getNumberOfCells(),1);
   std::copy(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),cellCor->getPointer());
+  if(cellCor->isIdentity())
+    {
+      cellCor->decrRef();
+      cellCor=0;
+    }
 }
 
 /*!
@@ -513,6 +526,7 @@ DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer()
       newCoordsPtr=std::copy(oldCoordsPtr+spaceDim*(work-traducer),oldCoordsPtr+spaceDim*(work-traducer+1),newCoordsPtr);
       work++;
     }
+  newCoords->copyStringInfoFrom(*_coords);
   setCoords(newCoords);
   newCoords->decrRef();
   return ret;
@@ -586,7 +600,7 @@ bool MEDCouplingUMesh::areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int
       getCoordinatesOfNode(c1[0],n1);
       other->getCoordinatesOfNode(c2[0],n2);
       std::transform(n1.begin(),n1.end(),n2.begin(),n1.begin(),std::minus<double>());
-      std::transform(n1.begin(),n1.end(),n1.end(),std::ptr_fun<double,double>(fabs));
+      std::transform(n1.begin(),n1.end(),n1.begin(),std::ptr_fun<double,double>(fabs));
       if(*std::max_element(n1.begin(),n1.end())>prec)
         return false;
     }
@@ -759,21 +773,51 @@ DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType)
  * @param areNodesMerged if at least two nodes have been merged.
  * @return old to new node correspondance.
  */
-DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged)
+DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
 {
-  DataArrayInt *comm,*commI;
-  findCommonNodes(comm,commI,precision);
-  int newNbOfNodes;
-  int oldNbOfNodes=getNumberOfNodes();
-  DataArrayInt *ret=buildNewNumberingFromCommNodesFrmt(comm,commI,newNbOfNodes);
-  areNodesMerged=(oldNbOfNodes!=newNbOfNodes);
-  comm->decrRef();
-  commI->decrRef();
+  DataArrayInt *ret=buildPermArrayForMergeNode(-1,precision,areNodesMerged,newNbOfNodes);
   if(areNodesMerged)
     renumberNodes(ret->getConstPointer(),newNbOfNodes);
   return ret;
 }
 
+/*!
+ * This method tries to use 'other' coords and use it for 'this'. If no exception was thrown after the call of this method :
+ * this->_coords==other->_coords. If not a exception is thrown this remains unchanged.
+ */
+void MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception)
+{
+  DataArrayDouble *coords=other.getCoords();
+  if(!coords)
+    throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute : No coords specified in other !");
+  if(!_coords)
+    throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute : No coords specified in this whereas there is any in other !");
+  int thisNbOfNodes=getNumberOfNodes();
+  int otherNbOfNodes=other.getNumberOfNodes();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=mergeNodesArray(&other,this);
+  _coords->incrRef();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> oldCoords=_coords;
+  setCoords(newCoords);
+  bool areNodesMerged;
+  int newNbOfNodes;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=buildPermArrayForMergeNode(otherNbOfNodes,epsilon,areNodesMerged,newNbOfNodes);
+  if(!areNodesMerged)
+    {
+      setCoords(oldCoords);
+      throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute fails : no nodes are mergeable with specified given epsilon !");
+    }
+  int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+otherNbOfNodes);
+  const int *pt=std::find_if(da->getConstPointer()+otherNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),maxId));
+  if(pt!=da->getConstPointer()+da->getNbOfElems())
+    {
+      setCoords(oldCoords);
+      throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute fails : some nodes in this are not in other !");
+    }
+  setCoords(oldCoords);
+  renumberNodesInConn(da->getConstPointer()+otherNbOfNodes);
+  setCoords(coords);
+}
+
 /*!
  * build a sub part of 'this'. This sub part is defined by the cell ids contained in the array in [start,end).
  * @param start start of array containing the cell ids to keep.
@@ -918,6 +962,15 @@ void MEDCouplingUMesh::findBoundaryNodes(std::vector<int>& nodes) const
 void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes)
 {
   MEDCouplingPointSet::renumberNodes(newNodeNumbers,newNbOfNodes);
+  renumberNodesInConn(newNodeNumbers);
+}
+
+/*!
+ * This method renumbers nodes in connectivity only without any reference with coords.
+ * Use it with care !
+ */
+void MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbers)
+{
   int *conn=getNodalConnectivity()->getPointer();
   const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
   int nbOfCells=getNumberOfCells();
@@ -1788,6 +1841,7 @@ DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCoupli
             work=std::transform(vec,vec+3,retPtr+3*(i*oldNbOfNodes+j),work,std::plus<double>());
         }
     }
+  ret->copyStringInfoFrom(*getCoords());
   return ret;
 }
 
index abf4d7c0896656947603b0488a7daa067667b584..9a294e3fe4bb0ea03d0643d103c6c334897b03ca 100644 (file)
@@ -58,6 +58,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT int getNumberOfCells() const;
     MEDCOUPLING_EXPORT int getMeshDimension() const;
     MEDCOUPLING_EXPORT int getMeshLength() const;
+    MEDCOUPLING_EXPORT void computeTypes();
     //! size of returned tinyInfo must be always the same.
     MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const;
     MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector<int>& tinyInfo) const;
@@ -75,7 +76,8 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *zipConnectivityTraducer(int compType);
     MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const;
     MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const;
-    MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged);
+    MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes);
+    MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
@@ -125,9 +127,9 @@ namespace ParaMEDMEM
     MEDCouplingUMesh();
     MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCpy);
     ~MEDCouplingUMesh();
-    void computeTypes();
     void checkFullyDefined() const throw(INTERP_KERNEL::Exception);
     //tools
+    void renumberNodesInConn(const int *newNodeNumbers);
     MEDCouplingUMesh *buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const;
     DataArrayDouble *fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const;
     template<int SPACEDIM>
index 1e079858bfb56fd269d586891b86d39e045223c1..ec9f3e3c515da80d189b6bec3b021e9378e45a3c 100644 (file)
@@ -309,13 +309,18 @@ void MEDCouplingUMeshDesc::giveElemsInBoundingBox(const INTERP_KERNEL::DirectedB
   delete [] elem_bb;
 }
 
-DataArrayInt *MEDCouplingUMeshDesc::mergeNodes(double precision, bool& areNodesMerged)
+DataArrayInt *MEDCouplingUMeshDesc::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
 {
   //not implemented yet.
   areNodesMerged=false;
   return 0;
 }
 
+void MEDCouplingUMeshDesc::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+}
+
 MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const
 {
   //not implemented yet.
index 3602d851f6e40abafcd2df214636c60a3eb50050..aaa147abfcadcdcbf18b4efe786c8858b4511eb6 100644 (file)
@@ -57,7 +57,8 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void unserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings);
     MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems);
     MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps, std::vector<int>& elems);
-    MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged);
+    MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes);
+    MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
index a86d7da0cb22862acfe9abe6a921d784ab4cfe36..dff4af8731ef3957d3f82e55aced97c002ab8ecd 100644 (file)
@@ -480,7 +480,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         #
         self.assertEqual(10,m6.getNumberOfCells());
         self.assertEqual(22,m6.getNumberOfNodes());
-        (arr,areNodesMerged)=m6.mergeNodes(1e-13);
+        (arr,areNodesMerged,newNbOfNodes)=m6.mergeNodes(1e-13);
         self.assertTrue(areNodesMerged);
         self.assertEqual(10,m6.getNumberOfCells());
         self.assertEqual(9,m6.getNumberOfNodes());
@@ -768,7 +768,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
 
     def testFindCommonNodes(self):
         targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1();
-        comm,commI=targetMesh.findCommonNodes(1e-10);
+        comm,commI=targetMesh.findCommonNodes(-1,1e-10);
         self.assertEqual(1,commI.getNumberOfTuples());
         self.assertEqual(0,comm.getNumberOfTuples());
         o2n,newNbOfNodes=targetMesh.buildNewNumberingFromCommNodesFrmt(comm,commI);
@@ -779,7 +779,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         #
         targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1();
         self.assertEqual(31,targetMesh.getNumberOfNodes());
-        comm,commI=targetMesh.findCommonNodes(1e-10);
+        comm,commI=targetMesh.findCommonNodes(-1,1e-10);
         self.assertEqual(3,commI.getNumberOfTuples());
         self.assertEqual(6,comm.getNumberOfTuples());
         commExpected=[1,27,28,29,23,30]
@@ -795,14 +795,14 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         #
         targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1();
         time=targetMesh.getTimeOfThis();
-        o2n,areNodesMerged=targetMesh.mergeNodes(1e-10);
+        o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10);
         targetMesh.updateTime();
         self.assertEqual(time,targetMesh.getTimeOfThis());
         self.assertTrue(not areNodesMerged);
         #
         targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1();
         time=targetMesh.getTimeOfThis();
-        o2n,areNodesMerged=targetMesh.mergeNodes(1e-10);
+        o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10);
         targetMesh.updateTime();
         self.assertTrue(time!=targetMesh.getTimeOfThis());
         self.assertTrue(areNodesMerged);
@@ -825,7 +825,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         targetMesh=MEDCouplingDataForTest.build2DTargetMeshMergeNode_1();
         self.assertEqual(18,targetMesh.getNumberOfNodes());
         time=targetMesh.getTimeOfThis();
-        o2n,areNodesMerged=targetMesh.mergeNodes(1e-10);
+        o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10);
         self.assertTrue(time!=targetMesh.getTimeOfThis());
         self.assertTrue(areNodesMerged);
         self.assertEqual(9,targetMesh.getNumberOfNodes());
@@ -881,7 +881,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         m3.checkCoherency();
         m4=MEDCouplingDataForTest.build2DTargetMeshMerged_1();
         self.assertTrue(m3.isEqual(m4,1.e-12));
-        da,isMerged=m3.mergeNodes(1.e-12);
+        da,isMerged,newNbOfNodes=m3.mergeNodes(1.e-12);
         self.assertEqual(11,m3.getNumberOfNodes());
         self.assertTrue(isMerged);
         pass
@@ -2376,6 +2376,213 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         expected2.sort()
         self.assertTrue(expected2==types2);
         pass
+
+    def testCheckGeoEquivalWith(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_3();
+        mesh2=MEDCouplingDataForTest.build2DTargetMesh_3();
+        #First test mesh1
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,0,1e-12);#deepEqual
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,1,1e-12);#fastEqual
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,10,1e-12);#deepEqual with geo permutations
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        #Second test mesh1 and mesh2 are 2 different meshes instance
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,0,1e-12);#deepEqual
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        #Third test : cell permutation by keeping the first the middle and the last as it is.
+        renum=[0,2,1,3,4,5,6,8,7,9]
+        mesh2.renumberCells(renum,False);
+        self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,0,1e-12);#deepEqual fails
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual do not see anything
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations
+        self.assertTrue(cellCor);
+        self.assertEqual(10,cellCor.getNumberOfTuples());
+        self.assertEqual(1,cellCor.getNumberOfComponents());
+        self.assertEqual(renum,cellCor.getValues())
+        self.assertTrue(nodeCor==None);
+        cellCor=0;
+        self.assertTrue(nodeCor==None);
+        #4th test : cell and node permutation by keeping the first the middle and the last as it is.
+        mesh2=MEDCouplingDataForTest.build2DTargetMesh_3();
+        renum2=[0,2,1,3,4,5,6,8,7,9,10]
+        mesh2.renumberCells(renum,False);
+        mesh2.renumberNodes(renum2,11);
+        cellCor=None
+        nodeCor=None
+        self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,0,1e-12);#deepEqual fails
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual do not see anything
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations
+        self.assertTrue(cellCor);
+        self.assertEqual(10,cellCor.getNumberOfTuples());
+        self.assertEqual(1,cellCor.getNumberOfComponents());
+        self.assertEqual(renum,cellCor.getValues())
+        self.assertTrue(nodeCor);
+        self.assertEqual(11,nodeCor.getNumberOfTuples());
+        self.assertEqual(1,nodeCor.getNumberOfComponents());
+        self.assertEqual(renum2,nodeCor.getValues())
+        cellCor=0;
+        nodeCor=0;
+        #5th test : modification of the last cell to check fastCheck detection.
+        mesh2=MEDCouplingDataForTest.build2DTargetMesh_3();
+        renum3=[0,2,1,3,4,5,6,8,9,7]
+        mesh2.renumberCells(renum3,False);
+        mesh2.renumberNodes(renum2,11);
+        cellCor=None
+        nodeCor=None
+        self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,0,1e-12)
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,1,1e-12)
+        self.assertTrue(cellCor==None);
+        self.assertTrue(nodeCor==None);
+        cellCor,nodeCor=mesh2.checkGeoEquivalWith(mesh1,10,1e-12);#deepEqual with geo permutations
+        self.assertTrue(cellCor!=None);
+        self.assertEqual(10,cellCor.getNumberOfTuples());
+        self.assertEqual(1,cellCor.getNumberOfComponents());
+        self.assertEqual(renum3,cellCor.getValues())
+        self.assertTrue(nodeCor!=None);
+        self.assertEqual(11,nodeCor.getNumberOfTuples());
+        self.assertEqual(1,nodeCor.getNumberOfComponents());
+        self.assertEqual(renum2,nodeCor.getValues());
+        pass
+
+    def testCheckGeoEquivalWith2(self):
+        mesh1=MEDCouplingDataForTest.build2DTargetMesh_4();
+        mesh2=MEDCouplingDataForTest.build2DTargetMesh_1();
+        cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);
+        self.assertEqual(None,cellCor);
+        self.assertNotEqual(None,nodeCor);
+        expected1=[0, 1, 3, 4, 5, 6, 7, 8, 9]
+        for i in xrange(9):
+            self.assertEqual(expected1[i],nodeCor.getIJ(i,0));
+            pass
+        pass
+
+    def testCopyTinyStringsFromOnFields(self):
+        m=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        nbOfCells=m.getNumberOfCells();
+        f=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME);
+        f.setMesh(m);
+        f.setName("a");
+        f.setDescription("b");
+        a1=DataArrayDouble.New();
+        a1.alloc(nbOfCells,2);
+        a1.fillWithZero();
+        a1.setInfoOnComponent(0,"c");
+        a1.setInfoOnComponent(1,"d");
+        a2=a1.deepCopy();
+        a2.setInfoOnComponent(0,"e");
+        a2.setInfoOnComponent(1,"f");
+        f.setArray(a1);
+        f.setEndArray(a2);
+        f.setEndTime(3.,3,4);
+        m.setName("g");
+        m.getCoords().setInfoOnComponent(0,"h");
+        m.getCoords().setInfoOnComponent(1,"i");
+        m.getCoords().setInfoOnComponent(2,"j");
+        #
+        f.checkCoherency();
+        f2=f.clone(True);
+        self.assertTrue(f2.isEqual(f,1e-12,1e-12));
+        f2.setName("smth");
+        self.assertTrue(not f2.isEqual(f,1e-12,1e-12));
+        f2.copyTinyStringsFrom(f);
+        self.assertTrue(f2.isEqual(f,1e-12,1e-12));
+        f2.setDescription("GGG");
+        self.assertTrue(not f2.isEqual(f,1e-12,1e-12));
+        f2.copyTinyStringsFrom(f);
+        self.assertTrue(f2.isEqual(f,1e-12,1e-12));
+        f2.getArray().setInfoOnComponent(0,"mmmm");
+        self.assertTrue(not f2.isEqual(f,1e-12,1e-12));
+        f2.copyTinyStringsFrom(f);
+        self.assertTrue(f2.isEqual(f,1e-12,1e-12));
+        f2.getEndArray().setInfoOnComponent(1,"mmmm");
+        self.assertTrue(not f2.isEqual(f,1e-12,1e-12));
+        f2.copyTinyStringsFrom(f);
+        self.assertTrue(f2.isEqual(f,1e-12,1e-12));
+        m2=m.clone(True);
+        self.assertTrue(m2.isEqual(m,1e-12));
+        m2.setName("123");
+        self.assertTrue(not m2.isEqual(m,1e-12));
+        m2.copyTinyStringsFrom(m);
+        self.assertTrue(m2.isEqual(m,1e-12));
+        m2.getCoords().setInfoOnComponent(1,"eee");
+        self.assertTrue(not m2.isEqual(m,1e-12));
+        m2.copyTinyStringsFrom(m);
+        self.assertTrue(m2.isEqual(m,1e-12));
+        pass
+
+    def testTryToShareSameCoordsPermute(self):
+        m=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1();
+        #self.assertTrue(m.getCoords()!=m2.getCoords());
+        m.tryToShareSameCoordsPermute(m2,1e-12);
+        #self.assertTrue(m.getCoords()==m2.getCoords());
+        self.assertTrue(m2.isEqual(m,1e-12));
+        renum1=[1,2,0,5,8,7,4,3,6]
+        m.renumberNodes(renum1,9);
+        #self.assertTrue(m.getCoords()!=m2.getCoords());
+        self.assertTrue(not m2.isEqual(m,1e-12));
+        m.tryToShareSameCoordsPermute(m2,1e-12);
+        #self.assertTrue(m.getCoords()==m2.getCoords());
+        self.assertTrue(m2.isEqual(m,1e-12));
+        pass
+
+    def testTryToShareSameCoordsPermute2(self):
+        m1=MEDCouplingDataForTest.build2DTargetMesh_4();
+        targetCoords=[-0.3,-0.3, 0.2,-0.3, -0.3,0.2, 0.2,0.2 ]
+        targetConn=[0,2,3,1]
+        m2=MEDCouplingUMesh.New();
+        m2.setMeshDimension(2);
+        m2.allocateCells(1);
+        m2.insertNextCell(NORM_QUAD4,4,targetConn[0:4])
+        m2.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,4,2);
+        m2.setCoords(myCoords);
+        m2.checkCoherency();
+        m1.checkCoherency();
+        #
+        expected1=[0.25,0.125,0.125,0.25,0.25]
+        f1=m1.getMeasureField(False);
+        f2=m2.getMeasureField(False);
+        self.assertEqual(5,f1.getArray().getNumberOfTuples());
+        self.assertEqual(1,f2.getArray().getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),12);
+            pass
+        self.assertAlmostEqual(expected1[0],f2.getIJ(0,0),12);
+        self.assertRaises(Exception,m1.tryToShareSameCoordsPermute,m2,1e-12);# <- here in this order the sharing is impossible.
+        # Let's go for deeper test of tryToShareSameCoordsPermute
+        m2.tryToShareSameCoordsPermute(m1,1e-12);
+        f1=m1.getMeasureField(False);
+        f2=m2.getMeasureField(False);
+        self.assertEqual(5,f1.getArray().getNumberOfTuples());
+        self.assertEqual(1,f2.getArray().getNumberOfTuples());
+        for i in xrange(5):
+            self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),12);
+            pass
+        self.assertAlmostEqual(expected1[0],f2.getIJ(0,0),12);
+        pass
     
     def setUp(self):
         pass
index b726e561876f09374d980b29e53d8d0eb2c55de6..d152e2a4b21a237f4bc9db43af093c99e0fa4f41 100644 (file)
@@ -304,6 +304,23 @@ class MEDCouplingDataForTest:
         ret.checkCoherency();
         return ret;
 
+    def build2DTargetMesh_4(cls):
+        targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]
+        targetConn=[0,4,5,1, 1,5,3, 5,6,2, 7,8,5,4, 8,9,6,5]
+        targetMesh=MEDCouplingUMesh.New();
+        targetMesh.setMeshDimension(2);
+        targetMesh.allocateCells(5);
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7])
+        targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14])
+        targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18])
+        targetMesh.finishInsertingCells();
+        myCoords=DataArrayDouble.New();
+        myCoords.setValues(targetCoords,10,2);
+        targetMesh.setCoords(myCoords);
+        return targetMesh;
+
     build2DTargetMesh_1=classmethod(build2DTargetMesh_1)
     build2DSourceMesh_1=classmethod(build2DSourceMesh_1)
     build3DTargetMesh_1=classmethod(build3DTargetMesh_1)
@@ -317,4 +334,5 @@ class MEDCouplingDataForTest:
     build1DTargetMesh_3=classmethod(build1DTargetMesh_3)
     build2DCurveTargetMesh_3=classmethod(build2DCurveTargetMesh_3)
     build2DTargetMesh_3=classmethod(build2DTargetMesh_3)
+    build2DTargetMesh_4=classmethod(build2DTargetMesh_4)
     pass
index a7a5360b14502c47634db6a63c2acec9a7504cb0..9a3dba40d98ce57ce4ef4654c74f299fa2e73758 100644 (file)
@@ -151,9 +151,10 @@ namespace ParaMEDMEM
     void setName(const char *name) { _name=name; }
     const char *getName() const { return _name.c_str(); }
     virtual MEDCouplingMeshType getType() const = 0;
-    virtual bool isEqual(const MEDCouplingMesh *other, double prec) const { return _name==other->_name; }
+    bool isStructured() const;
+    virtual bool isEqual(const MEDCouplingMesh *other, double prec) const;
+    virtual void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
     virtual void checkCoherency() const throw(INTERP_KERNEL::Exception) = 0;
-    virtual bool isStructured() const = 0;
     virtual int getNumberOfCells() const throw(INTERP_KERNEL::Exception) = 0;
     virtual int getNumberOfNodes() const throw(INTERP_KERNEL::Exception) = 0;
     virtual int getSpaceDimension() const throw(INTERP_KERNEL::Exception) = 0;
@@ -184,6 +185,16 @@ namespace ParaMEDMEM
            self->renumberCells(tmp,check);
            delete [] tmp;
          }
+
+         PyObject *checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec) const throw(INTERP_KERNEL::Exception)
+         {
+           DataArrayInt *cellCor, *nodeCor;
+           self->checkGeoEquivalWith(other,levOfCheck,prec,cellCor,nodeCor);
+           PyObject *res = PyList_New(2);
+           PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(cellCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, cellCor?SWIG_POINTER_OWN | 0:0 ));
+           PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(nodeCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, nodeCor?SWIG_POINTER_OWN | 0:0 ));
+           return res;
+         }
        }
   };
 }
@@ -200,12 +211,10 @@ namespace ParaMEDMEM
     {
     public:
       void updateTime();
-      bool isStructured() const;
       void setCoords(DataArrayDouble *coords);
       DataArrayDouble *getCoordinatesAndOwner() const;
       bool isEqual(const MEDCouplingMesh *other, double prec) const;
       bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const;
-      virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged) = 0;
       void getBoundingBox(double *bbox) const;
       void zipCoords();
       double getCaracteristicDimension() const;
@@ -213,6 +222,7 @@ namespace ParaMEDMEM
       void scale(const double *point, double factor);
       void changeSpaceDimension(int newSpaceDim) throw(INTERP_KERNEL::Exception);
       void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
+      virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) = 0;
       static DataArrayDouble *mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2);
       static MEDCouplingPointSet *buildInstanceFromMeshType(MEDCouplingMeshType type);
       virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const = 0;
@@ -242,10 +252,10 @@ namespace ParaMEDMEM
              return res;
            }
            
-           PyObject *findCommonNodes(double prec) const
+           PyObject *findCommonNodes(int limitNodeId, double prec) const
            {
              DataArrayInt *comm, *commIndex;
-             self->findCommonNodes(comm,commIndex,prec);
+             self->findCommonNodes(limitNodeId,prec,comm,commIndex);
              PyObject *res = PyList_New(2);
              PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(comm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
              PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(commIndex),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
@@ -375,8 +385,8 @@ namespace ParaMEDMEM
     DataArrayInt *getNodalConnectivityIndex() const;
     INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const;
     int getNumberOfNodesInCell(int cellId) const;
-    bool isStructured() const;
     int getMeshLength() const;
+    void computeTypes();
     //tools
     bool checkConsecutiveCellTypes() const;
     DataArrayInt *rearrange2ConsecutiveCellTypes();
@@ -415,10 +425,12 @@ namespace ParaMEDMEM
       PyObject *mergeNodes(double precision)
       {
         bool ret1;
-        DataArrayInt *ret0=self->mergeNodes(precision,ret1);
-        PyObject *res = PyList_New(2);
+        int ret2;
+        DataArrayInt *ret0=self->mergeNodes(precision,ret1,ret2);
+        PyObject *res = PyList_New(3);
         PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
         PyList_SetItem(res,1,SWIG_From_bool(ret1));
+        PyList_SetItem(res,2,SWIG_From_int(ret2));
         return res;
       }
       PyObject *checkButterflyCells()
@@ -731,6 +743,7 @@ namespace ParaMEDMEM
   {
   public:
     static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=NO_TIME);
+    void copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *clone(bool recDeepCpy) const;
     MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const;
     MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const;