From 999b10494c931d01a6922395cc0fa41286a32f43 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Fri, 5 Feb 2021 07:52:16 +0100 Subject: [PATCH] Implementation of basic mesh checker to detect avoidable errors --- src/MEDCoupling/MEDCouplingUMesh.cxx | 30 +++++++++++++++++-- src/MEDCoupling/MEDCouplingUMesh.hxx | 1 + .../MEDCouplingBasicsTest7.py | 13 ++++++++ src/MEDCoupling_Swig/MEDCouplingCommon.i | 1 + 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 5a763c2ee..a5a17f58c 100755 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -208,9 +208,13 @@ void MEDCouplingUMesh::checkConsistencyLight() const /*! * Checks if \a this mesh is well defined. If no exception is thrown by this method, - * then \a this mesh is most probably is writable, exchangeable and available for all + * then \a this mesh is informatically clean, most probably is writable, exchangeable and available for all * algorithms.
In addition to the checks performed by checkConsistencyLight(), this - * method thoroughly checks the nodal connectivity. + * method thoroughly checks the nodal connectivity. For more geometrical checking + * checkGeomConsistency method is better than this. + * + * \sa MEDCouplingUMesh::checkGeomConsistency + * * \param [in] eps - a not used parameter. * \throw If the mesh dimension is not set. * \throw If the coordinates array is not set (if mesh dimension != -1 ). @@ -286,6 +290,28 @@ void MEDCouplingUMesh::checkConsistency(double eps) const } } +/*! + * This method adds some geometrical checks in addition to the informatical check of checkConsistency method. + * This method in particular checks that a same node is not repeated several times in a cell. + * + * \throw If there is a presence a multiple same node ID in nodal connectivity of cell. + */ +void MEDCouplingUMesh::checkGeomConsistency(double eps) const +{ + this->checkConsistency(eps); + auto nbOfCells(getNumberOfCells()); + const mcIdType *ptr(_nodal_connec->begin()),*ptrI(_nodal_connec_index->begin()); + for(auto icell = 0 ; icell < nbOfCells ; ++icell) + { + std::set s(ptr+ptrI[icell]+1,ptr+ptrI[icell+1]); + if(s.size()==ptrI[icell+1]-ptrI[icell]-1) + continue; + std::ostringstream oss; oss << "MEDCouplingUMesh::checkGeomConsistency : for cell #" << icell << " presence of multiple same nodeID !"; + throw INTERP_KERNEL::Exception(oss.str()); + } +} + + /*! * Sets dimension of \a this mesh. The mesh dimension in general depends on types of * elements contained in the mesh. For more info on the mesh dimension see diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index c09784c41..137d1d077 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -57,6 +57,7 @@ namespace MEDCoupling MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; MEDCOUPLING_EXPORT void checkConsistencyLight() const; MEDCOUPLING_EXPORT void checkConsistency(double eps=1e-12) const; + MEDCOUPLING_EXPORT void checkGeomConsistency(double eps=1e-12) const; MEDCOUPLING_EXPORT void setMeshDimension(int meshDim); MEDCOUPLING_EXPORT void allocateCells(mcIdType nbOfCells=0); MEDCOUPLING_EXPORT void insertNextCell(INTERP_KERNEL::NormalizedCellType type, mcIdType size, const mcIdType *nodalConnOfCell); diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest7.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest7.py index 50157f5c6..bee9d2b3b 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest7.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest7.py @@ -923,6 +923,19 @@ class MEDCouplingBasicsTest7(unittest.TestCase): m.advancedRepr() repr(m) + def testCheckGeomConsistency0(self): + """Test of MEDCouplingUMesh.checkGeomConsistency""" + m = MEDCouplingUMesh("",2) + m.setCoords(DataArrayDouble([(0,0),(1,0),(2,0),(0,1),(1,1),(2,1)])) + m.allocateCells() + m.insertNextCell(NORM_TRI6,[0,1,2,3,4,5]) + m.insertNextCell(NORM_TRI6,[0,1,3,3,4,5]) + m.checkConsistency() + self.assertRaises(InterpKernelException,m.checkGeomConsistency) # cell1 is incorrect because node 3 is repeated twice + m.getNodalConnectivity()[10]=2 # replace 3 by 2 for cell#1 to fix the problem + m.checkConsistency() + m.checkGeomConsistency() # now m is OK + pass if __name__ == '__main__': diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index b6d35cfe6..31eedf2f9 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -2048,6 +2048,7 @@ namespace MEDCoupling static MEDCouplingUMesh *New(); static MEDCouplingUMesh *New(const char *meshName, int meshDim); void checkConsistencyLight() const; + void checkGeomConsistency(double eps=1e-12) const; void setMeshDimension(int meshDim); void allocateCells(int nbOfCells=0); void finishInsertingCells(); -- 2.39.2