From 7952cf1623aac0f3cfa54021391f70c344c15854 Mon Sep 17 00:00:00 2001 From: ageay Date: Tue, 24 Aug 2010 09:27:52 +0000 Subject: [PATCH] Addition of methods on advanced mesh comparison. --- .../MEDCouplingAutoRefCountObjectPtr.hxx | 1 + src/MEDCoupling/MEDCouplingCMesh.cxx | 5 - src/MEDCoupling/MEDCouplingCMesh.hxx | 1 - src/MEDCoupling/MEDCouplingExtrudedMesh.cxx | 5 - src/MEDCoupling/MEDCouplingExtrudedMesh.hxx | 1 - src/MEDCoupling/MEDCouplingFieldDouble.cxx | 16 +- src/MEDCoupling/MEDCouplingFieldDouble.hxx | 1 + src/MEDCoupling/MEDCouplingMemArray.cxx | 37 +++ src/MEDCoupling/MEDCouplingMemArray.hxx | 5 + src/MEDCoupling/MEDCouplingMemArray.txx | 7 + src/MEDCoupling/MEDCouplingMesh.cxx | 13 ++ src/MEDCoupling/MEDCouplingMesh.hxx | 4 +- src/MEDCoupling/MEDCouplingPointSet.cxx | 34 ++- src/MEDCoupling/MEDCouplingPointSet.hxx | 9 +- src/MEDCoupling/MEDCouplingPointSet.txx | 7 +- src/MEDCoupling/MEDCouplingRemapper.cxx | 2 +- src/MEDCoupling/MEDCouplingRemapper.hxx | 2 +- .../MEDCouplingTimeDiscretization.cxx | 16 ++ .../MEDCouplingTimeDiscretization.hxx | 2 + src/MEDCoupling/MEDCouplingUMesh.cxx | 90 +++++-- src/MEDCoupling/MEDCouplingUMesh.hxx | 6 +- src/MEDCoupling/MEDCouplingUMeshDesc.cxx | 7 +- src/MEDCoupling/MEDCouplingUMeshDesc.hxx | 3 +- src/MEDCoupling_Swig/MEDCouplingBasicsTest.py | 221 +++++++++++++++++- .../MEDCouplingDataForTest.py | 18 ++ src/MEDCoupling_Swig/libMEDCoupling_Swig.i | 31 ++- 26 files changed, 473 insertions(+), 71 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx b/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx index d91a8e16f..7dd470af8 100644 --- a/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx +++ b/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx @@ -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; } diff --git a/src/MEDCoupling/MEDCouplingCMesh.cxx b/src/MEDCoupling/MEDCouplingCMesh.cxx index 4de2ee693..fdd7ced5a 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCMesh.cxx @@ -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; diff --git a/src/MEDCoupling/MEDCouplingCMesh.hxx b/src/MEDCoupling/MEDCouplingCMesh.hxx index 9c64a06cb..3919f776a 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.hxx +++ b/src/MEDCoupling/MEDCouplingCMesh.hxx @@ -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; diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx index 0aaedbc4e..1d8b85a5c 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx @@ -120,11 +120,6 @@ MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& } } -bool MEDCouplingExtrudedMesh::isStructured() const -{ - return false; -} - int MEDCouplingExtrudedMesh::getNumberOfCells() const { return _mesh2D->getNumberOfCells()*_mesh1D->getNumberOfCells(); diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx index 70df7b2a8..50cc24ec0 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx @@ -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; diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index 4fc80438a..d68258117 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -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(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 meshC2((MEDCouplingPointSet *)meshC->deepCpy()); bool ret; - MEDCouplingAutoRefCountObjectPtr arr=meshC2->mergeNodes(eps,ret); + int ret2; + MEDCouplingAutoRefCountObjectPtr arr=meshC2->mergeNodes(eps,ret,ret2); if(!ret)//no nodes have been merged. return ret; std::vector arrays; diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx index 3e418c657..72a8a43e6 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -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; diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 24c1bb171..10bcd4333 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -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& 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]; } diff --git a/src/MEDCoupling/MEDCouplingMemArray.txx b/src/MEDCoupling/MEDCouplingMemArray.txx index 476f147ae..cff97d05a 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.txx +++ b/src/MEDCoupling/MEDCouplingMemArray.txx @@ -92,6 +92,13 @@ namespace ParaMEDMEM return false; return true; } + + template + void MemArray::fillWithValue(const T& val) + { + T *pt=_pointer.getPointer(); + std::fill(pt,pt+_nb_of_elem,val); + } template void MemArray::alloc(int nbOfElements) diff --git a/src/MEDCoupling/MEDCouplingMesh.cxx b/src/MEDCoupling/MEDCouplingMesh.cxx index d9900e51d..cf181274f 100644 --- a/src/MEDCoupling/MEDCouplingMesh.cxx +++ b/src/MEDCoupling/MEDCouplingMesh.cxx @@ -29,6 +29,19 @@ 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. diff --git a/src/MEDCoupling/MEDCouplingMesh.hxx b/src/MEDCoupling/MEDCouplingMesh.hxx index 4ca8f5726..dfb54ce21 100644 --- a/src/MEDCoupling/MEDCouplingMesh.hxx +++ b/src/MEDCoupling/MEDCouplingMesh.hxx @@ -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; diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index b9c07a98b..142b0e112 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -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."); diff --git a/src/MEDCoupling/MEDCouplingPointSet.hxx b/src/MEDCoupling/MEDCouplingPointSet.hxx index 85d565f55..ac69fee23 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.hxx +++ b/src/MEDCoupling/MEDCouplingPointSet.hxx @@ -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& 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& res, bool isQuad); template void findCommonNodesAlg(std::vector& bbox, - int nbNodes, double prec, std::vector& c, std::vector& cI) const; + int nbNodes, int limitNodeId, double prec, std::vector& c, std::vector& cI) const; protected: DataArrayDouble *_coords; }; diff --git a/src/MEDCoupling/MEDCouplingPointSet.txx b/src/MEDCoupling/MEDCouplingPointSet.txx index 300aab235..bae195566 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.txx +++ b/src/MEDCoupling/MEDCouplingPointSet.txx @@ -29,7 +29,7 @@ namespace ParaMEDMEM { template void MEDCouplingPointSet::findCommonNodesAlg(std::vector& bbox, - int nbNodes, double prec, + int nbNodes, int limitNodeId, double prec, std::vector& c, std::vector& cI) const { const double *coordsPtr=_coords->getConstPointer(); @@ -52,8 +52,9 @@ namespace ParaMEDMEM std::vector commonNodes; for(std::vector::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++) if(*it!=i) - if(INTERP_KERNEL::distance2(coordsPtr+SPACEDIM*i,coordsPtr+SPACEDIM*(*it))=limitNodeId) + if(INTERP_KERNEL::distance2(coordsPtr+SPACEDIM*i,coordsPtr+SPACEDIM*(*it)) >& m); private: diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx index b8da1c812..cb5d7e6f6 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx @@ -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(&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; diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx index bdf62a4ad..232f008b8 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx @@ -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; diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 8fb502ee6..d3e93fb91 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -216,24 +216,32 @@ void MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int ce const MEDCouplingUMesh *otherC=dynamic_cast(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 m=mergeUMeshes(this,otherC); bool areNodesMerged; - MEDCouplingAutoRefCountObjectPtr da=m->mergeNodes(prec,areNodesMerged); + int newNbOfNodes; + int oldNbOfNodes=getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr 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(),maxId)); + const int *pt=std::find_if(da->getConstPointer()+oldNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),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(),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()); - std::transform(n1.begin(),n1.end(),n1.end(),std::ptr_fun(fabs)); + std::transform(n1.begin(),n1.end(),n1.begin(),std::ptr_fun(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 newCoords=mergeNodesArray(&other,this); + _coords->incrRef(); + MEDCouplingAutoRefCountObjectPtr oldCoords=_coords; + setCoords(newCoords); + bool areNodesMerged; + int newNbOfNodes; + MEDCouplingAutoRefCountObjectPtr 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(),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& 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()); } } + ret->copyStringInfoFrom(*getCoords()); return ret; } diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index abf4d7c08..9a294e3fe 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -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& tinyInfo, std::vector& littleStrings) const; MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector& 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 diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx index 1e079858b..ec9f3e3c5 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx @@ -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. diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx index 3602d851f..aaa147abf 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx @@ -57,7 +57,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const double *bbox, double eps, std::vector& elems); MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps, std::vector& 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; diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index a86d7da0c..dff4af873 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -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 diff --git a/src/MEDCoupling_Swig/MEDCouplingDataForTest.py b/src/MEDCoupling_Swig/MEDCouplingDataForTest.py index b726e5618..d152e2a4b 100644 --- a/src/MEDCoupling_Swig/MEDCouplingDataForTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingDataForTest.py @@ -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 diff --git a/src/MEDCoupling_Swig/libMEDCoupling_Swig.i b/src/MEDCoupling_Swig/libMEDCoupling_Swig.i index a7a5360b1..9a3dba40d 100644 --- a/src/MEDCoupling_Swig/libMEDCoupling_Swig.i +++ b/src/MEDCoupling_Swig/libMEDCoupling_Swig.i @@ -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; -- 2.39.2