From: ageay Date: Wed, 18 Jul 2012 15:44:34 +0000 (+0000) Subject: isEqual gives information about diffs X-Git-Tag: V6_main_FINAL~578 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=3eb28e09846cbf6f6b0a891e26465731a65aa3e3;p=tools%2Fmedcoupling.git isEqual gives information about diffs --- diff --git a/src/MEDCoupling/MEDCouplingCMesh.cxx b/src/MEDCoupling/MEDCouplingCMesh.cxx index a07680998..883b4c9ca 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCMesh.cxx @@ -124,22 +124,36 @@ void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(I _z_array->copyStringInfoFrom(*otherC->_z_array); } -bool MEDCouplingCMesh::isEqual(const MEDCouplingMesh *other, double prec) const +bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::isEqualIfNotWhy : input other pointer is null !"); const MEDCouplingCMesh *otherC=dynamic_cast(other); if(!otherC) - return false; - if(!MEDCouplingMesh::isEqual(other,prec)) + { + reason="mesh given in input is not castable in MEDCouplingCMesh !"; + return false; + } + if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason)) return false; const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array}; + std::ostringstream oss; oss.precision(15); for(int i=0;i<3;i++) { if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0)) - return false; - if(thisArr[i]) - if(!thisArr[i]->isEqual(*otherArr[i],prec)) + { + oss << "Only one CMesh between the two this and other has its coordinates of rank" << i << " defined !"; + reason=oss.str(); return false; + } + if(thisArr[i]) + if(!thisArr[i]->isEqualIfNotWhy(*otherArr[i],prec,reason)) + { + oss << "Coordinates DataArrayDouble of rank #" << i << " differ :"; + reason.insert(0,oss.str()); + return false; + } } return true; } diff --git a/src/MEDCoupling/MEDCouplingCMesh.hxx b/src/MEDCoupling/MEDCouplingCMesh.hxx index 643edb8e0..d80a3e2a3 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.hxx +++ b/src/MEDCoupling/MEDCouplingCMesh.hxx @@ -38,7 +38,7 @@ namespace ParaMEDMEM void updateTime() const; MEDCouplingMeshType getType() const { return CARTESIAN; } void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); - bool isEqual(const MEDCouplingMesh *other, double prec) const; + bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx index 68a468874..71a7e65c8 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx @@ -152,21 +152,40 @@ MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::clone(bool recDeepCpy) const return new MEDCouplingExtrudedMesh(*this,recDeepCpy); } -bool MEDCouplingExtrudedMesh::isEqual(const MEDCouplingMesh *other, double prec) const +bool MEDCouplingExtrudedMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::isEqualIfNotWhy : input other pointer is null !"); const MEDCouplingExtrudedMesh *otherC=dynamic_cast(other); + std::ostringstream oss; if(!otherC) + { + reason="mesh given in input is not castable in MEDCouplingExtrudedMesh !"; + return false; + } + if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason)) return false; - if(!MEDCouplingMesh::isEqual(other,prec)) - return false; - if(!_mesh2D->isEqual(otherC->_mesh2D,prec)) - return false; - if(!_mesh1D->isEqual(otherC->_mesh1D,prec)) - return false; - if(!_mesh3D_ids->isEqual(*otherC->_mesh3D_ids)) - return false; + if(!_mesh2D->isEqualIfNotWhy(otherC->_mesh2D,prec,reason)) + { + reason.insert(0,"Mesh2D unstructured meshes differ : "); + return false; + } + if(!_mesh1D->isEqualIfNotWhy(otherC->_mesh1D,prec,reason)) + { + reason.insert(0,"Mesh1D unstructured meshes differ : "); + return false; + } + if(!_mesh3D_ids->isEqualIfNotWhy(*otherC->_mesh3D_ids,reason)) + { + reason.insert(0,"Mesh3D ids DataArrayInt instances differ : "); + return false; + } if(_cell_2D_id!=otherC->_cell_2D_id) - return false; + { + oss << "Cell 2D id of the two extruded mesh differ : this = " << _cell_2D_id << " other = " << otherC->_cell_2D_id; + reason=oss.str(); + return false; + } return true; } diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx index cee97c467..fa3a3e1d9 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx @@ -45,7 +45,7 @@ namespace ParaMEDMEM int getMeshDimension() const; MEDCouplingMesh *deepCpy() const; MEDCouplingExtrudedMesh *clone(bool recDeepCpy) const; - bool isEqual(const MEDCouplingMesh *other, double prec) const; + bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling/MEDCouplingField.cxx b/src/MEDCoupling/MEDCouplingField.cxx index 9b0daf593..05bdd4e9e 100644 --- a/src/MEDCoupling/MEDCouplingField.cxx +++ b/src/MEDCoupling/MEDCouplingField.cxx @@ -21,25 +21,57 @@ #include "MEDCouplingMesh.hxx" #include "MEDCouplingFieldDiscretization.hxx" +#include + using namespace ParaMEDMEM; -bool MEDCouplingField::isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const +bool MEDCouplingField::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception) { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualIfNotWhy : other instance is NULL !"); + std::ostringstream oss; oss.precision(15); if(_name!=other->_name) - return false; + { + oss << "Field names differ : this name = \"" << _name << "\" and other name = \"" << other->_name << "\" !"; + reason=oss.str(); + return false; + } if(_desc!=other->_desc) - return false; + { + oss << "Field descriptions differ : this description = \"" << _desc << "\" and other description = \"" << other->_desc << "\" !"; + reason=oss.str(); + return false; + } if(_nature!=other->_nature) - return false; - if(!_type->isEqual(other->_type,valsPrec)) - return false; + { + oss << "Field nature differ : this nature = \"" << MEDCouplingNatureOfField::getRepr(_nature) << "\" and other nature = \"" << MEDCouplingNatureOfField::getRepr(other->_nature) << "\" !"; + reason=oss.str(); + return false; + } + if(!_type->isEqualIfNotWhy(other->_type,valsPrec,reason)) + { + reason.insert(0,"Spatial discretizations differ :"); + return false; + } if(_mesh==0 && other->_mesh==0) return true; if(_mesh==0 || other->_mesh==0) - return false; + { + reason="Only one field between the two this and other has its underlying mesh defined !"; + return false; + } if(_mesh==other->_mesh) return true; - return _mesh->isEqual(other->_mesh,meshPrec); + bool ret=_mesh->isEqualIfNotWhy(other->_mesh,meshPrec,reason); + if(!ret) + reason.insert(0,"Underlying meshes of fields differ for the following reason : "); + return ret; +} + +bool MEDCouplingField::isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const +{ + std::string tmp; + return isEqualIfNotWhy(other,meshPrec,valsPrec,tmp); } bool MEDCouplingField::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const diff --git a/src/MEDCoupling/MEDCouplingField.hxx b/src/MEDCoupling/MEDCouplingField.hxx index 87e052597..d0246b1cd 100644 --- a/src/MEDCoupling/MEDCouplingField.hxx +++ b/src/MEDCoupling/MEDCouplingField.hxx @@ -45,6 +45,7 @@ namespace ParaMEDMEM virtual void checkCoherency() const throw(INTERP_KERNEL::Exception) = 0; virtual bool areCompatibleForMerge(const MEDCouplingField *other) const; virtual bool areStrictlyCompatible(const MEDCouplingField *other) const; + virtual bool isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception); virtual bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const; virtual bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; void setMesh(const ParaMEDMEM::MEDCouplingMesh *mesh); diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx index 3e3a5e082..64fcc5d31 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx @@ -92,6 +92,12 @@ TypeOfField MEDCouplingFieldDiscretization::getTypeOfFieldFromStringRepr(const c throw INTERP_KERNEL::Exception("Representation does not match with any field discretization !"); } +bool MEDCouplingFieldDiscretization::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const +{ + std::string reason; + return isEqualIfNotWhy(other,eps,reason); +} + bool MEDCouplingFieldDiscretization::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const { return isEqual(other,eps); @@ -347,10 +353,13 @@ const char *MEDCouplingFieldDiscretizationP0::getRepr() const return REPR; } -bool MEDCouplingFieldDiscretizationP0::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const +bool MEDCouplingFieldDiscretizationP0::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const { const MEDCouplingFieldDiscretizationP0 *otherC=dynamic_cast(other); - return otherC!=0; + bool ret=otherC!=0; + if(!ret) + reason="Spatial discrtization of this is ON_CELLS, which is not the case of other."; + return ret; } int MEDCouplingFieldDiscretizationP0::getNumberOfTuples(const MEDCouplingMesh *mesh) const @@ -528,10 +537,13 @@ const char *MEDCouplingFieldDiscretizationP1::getRepr() const return REPR; } -bool MEDCouplingFieldDiscretizationP1::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const +bool MEDCouplingFieldDiscretizationP1::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const { const MEDCouplingFieldDiscretizationP1 *otherC=dynamic_cast(other); - return otherC!=0; + bool ret=otherC!=0; + if(!ret) + reason="Spatial discrtization of this is ON_NODES, which is not the case of other."; + return ret; } /*! @@ -748,16 +760,22 @@ void MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(const MEDCoupl throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell has a discretization per cell but it's not matching the underlying mesh !"); } -bool MEDCouplingFieldDiscretizationPerCell::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const +bool MEDCouplingFieldDiscretizationPerCell::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const { const MEDCouplingFieldDiscretizationPerCell *otherC=dynamic_cast(other); if(!otherC) - return false; + { + reason="Spatial discrtization of this is ON_GAUSS, which is not the case of other."; + return false; + } if(_discr_per_cell==0) return otherC->_discr_per_cell==0; if(otherC->_discr_per_cell==0) return false; - return _discr_per_cell->isEqual(*otherC->_discr_per_cell); + bool ret=_discr_per_cell->isEqualIfNotWhy(*otherC->_discr_per_cell,reason); + if(!ret) + reason.insert(0,"Field discretization per cell DataArrayInt given the discid per cell :"); + return ret; } bool MEDCouplingFieldDiscretizationPerCell::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const @@ -830,19 +848,29 @@ TypeOfField MEDCouplingFieldDiscretizationGauss::getEnum() const return TYPE; } -bool MEDCouplingFieldDiscretizationGauss::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const +bool MEDCouplingFieldDiscretizationGauss::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const { const MEDCouplingFieldDiscretizationGauss *otherC=dynamic_cast(other); if(!otherC) - return false; - if(!MEDCouplingFieldDiscretizationPerCell::isEqual(other,eps)) + { + reason="Spatial discrtization of this is ON_GAUSS, which is not the case of other."; + return false; + } + if(!MEDCouplingFieldDiscretizationPerCell::isEqualIfNotWhy(other,eps,reason)) return false; if(_loc.size()!=otherC->_loc.size()) - return false; + { + reason="Gauss spatial discretization : localization sizes differ"; + return false; + } std::size_t sz=_loc.size(); for(std::size_t i=0;i_loc[i],eps)) - return false; + { + std::ostringstream oss; oss << "Gauss spatial discretization : Localization #" << i << " differ from this to other."; + reason=oss.str(); + return false; + } return true; } @@ -1457,10 +1485,13 @@ const char *MEDCouplingFieldDiscretizationGaussNE::getRepr() const return REPR; } -bool MEDCouplingFieldDiscretizationGaussNE::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const +bool MEDCouplingFieldDiscretizationGaussNE::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const { const MEDCouplingFieldDiscretizationGaussNE *otherC=dynamic_cast(other); - return otherC!=0; + bool ret=otherC!=0; + if(!ret) + reason="Spatial discrtization of this is ON_GAUSS_NE, which is not the case of other."; + return ret; } int MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples(const MEDCouplingMesh *mesh) const diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx index 44aa5a9c6..a247db3e2 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx @@ -45,7 +45,8 @@ namespace ParaMEDMEM void updateTime() const; static TypeOfField getTypeOfFieldFromStringRepr(const char *repr) throw(INTERP_KERNEL::Exception); virtual TypeOfField getEnum() const = 0; - virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const = 0; + virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; + virtual bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const = 0; virtual bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; virtual MEDCouplingFieldDiscretization *clone() const = 0; virtual std::string getStringRepr() const = 0; @@ -107,7 +108,7 @@ namespace ParaMEDMEM MEDCouplingFieldDiscretization *clone() const; std::string getStringRepr() const; const char *getRepr() const; - bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; + bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; int getNumberOfTuples(const MEDCouplingMesh *mesh) const; int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; @@ -139,7 +140,7 @@ namespace ParaMEDMEM MEDCouplingFieldDiscretization *clone() const; std::string getStringRepr() const; const char *getRepr() const; - bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; + bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; int getNumberOfTuples(const MEDCouplingMesh *mesh) const; int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; @@ -180,7 +181,7 @@ namespace ParaMEDMEM ~MEDCouplingFieldDiscretizationPerCell(); void updateTime() const; void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception); - bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; + bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); void checkNoOrphanCells() const throw(INTERP_KERNEL::Exception); @@ -196,7 +197,7 @@ namespace ParaMEDMEM public: MEDCouplingFieldDiscretizationGauss(); TypeOfField getEnum() const; - bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; + bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; MEDCouplingFieldDiscretization *clone() const; std::string getStringRepr() const; @@ -262,7 +263,7 @@ namespace ParaMEDMEM MEDCouplingFieldDiscretization *clone() const; std::string getStringRepr() const; const char *getRepr() const; - bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; + bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; int getNumberOfTuples(const MEDCouplingMesh *mesh) const; int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index cce56f0a9..945645119 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -190,15 +190,23 @@ std::string MEDCouplingFieldDouble::advancedRepr() const return ret.str(); } -bool MEDCouplingFieldDouble::isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const +bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception) { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::isEqualIfNotWhy : other instance is NULL !"); const MEDCouplingFieldDouble *otherC=dynamic_cast(other); if(!otherC) + { + reason="field given in input is not castable in MEDCouplingFieldDouble !"; + return false; + } + if(!MEDCouplingField::isEqualIfNotWhy(other,meshPrec,valsPrec,reason)) return false; - if(!MEDCouplingField::isEqual(other,meshPrec,valsPrec)) - return false; - if(!_time_discr->isEqual(otherC->_time_discr,valsPrec)) - return false; + if(!_time_discr->isEqualIfNotWhy(otherC->_time_discr,valsPrec,reason)) + { + reason.insert(0,"In FieldDouble time discretizations differ :"); + return false; + } return true; } @@ -237,12 +245,13 @@ bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other */ bool MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const { + std::string tmp; if(!MEDCouplingField::areStrictlyCompatible(other)) return false; const MEDCouplingFieldDouble *otherC=dynamic_cast(other); if(!otherC) return false; - if(!_time_discr->areStrictlyCompatible(otherC->_time_discr)) + if(!_time_discr->areStrictlyCompatible(otherC->_time_discr,tmp)) return false; return true; } diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx index 67d9f8d11..4d86fd3f8 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -40,7 +40,7 @@ namespace ParaMEDMEM void copyTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception); std::string simpleRepr() const; std::string advancedRepr() const; - bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const; + bool isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception); bool isEqualWithoutConsideringStr(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 8dae06d62..b8e4fb098 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -118,13 +118,39 @@ void DataArray::copyPartOfStringInfoFrom2(const std::vector& compoIds, cons setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str()); } -bool DataArray::areInfoEquals(const DataArray& other) const +bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const { + std::ostringstream oss; if(_nb_of_tuples!=other._nb_of_tuples) - return false; + { + oss << "Number of tuples of DataArray mismatch : this number of tuples=" << _nb_of_tuples << " other number of tuples=" << other._nb_of_tuples; + reason=oss.str(); + return false; + } if(_name!=other._name) - return false; - return _info_on_compo==other._info_on_compo; + { + oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !"; + reason=oss.str(); + return false; + } + if(_info_on_compo!=other._info_on_compo) + { + oss << "Components DataArray mismatch : \nThis components="; + for(std::vector::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++) + oss << "\"" << *it << "\","; + oss << "\nOther components="; + for(std::vector::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++) + oss << "\"" << *it << "\","; + reason=oss.str(); + return false; + } + return true; +} + +bool DataArray::areInfoEquals(const DataArray& other) const +{ + std::string tmp; + return areInfoEqualsIfNotWhy(other,tmp); } void DataArray::reprWithoutNameStream(std::ostream& stream) const @@ -685,16 +711,23 @@ void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const _mem.reprZip(getNumberOfComponents(),stream); } -bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const +bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const { - if(!areInfoEquals(other)) + if(!areInfoEqualsIfNotWhy(other,reason)) return false; - return _mem.isEqual(other._mem,prec); + return _mem.isEqual(other._mem,prec,reason); +} + +bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const +{ + std::string tmp; + return isEqualIfNotWhy(other,prec,tmp); } bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const { - return _mem.isEqual(other._mem,prec); + std::string tmp; + return _mem.isEqual(other._mem,prec,tmp); } void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception) @@ -3457,16 +3490,23 @@ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const return ret; } -bool DataArrayInt::isEqual(const DataArrayInt& other) const +bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const { - if(!areInfoEquals(other)) + if(!areInfoEqualsIfNotWhy(other,reason)) return false; - return _mem.isEqual(other._mem,0); + return _mem.isEqual(other._mem,0,reason); +} + +bool DataArrayInt::isEqual(const DataArrayInt& other) const +{ + std::string tmp; + return isEqualIfNotWhy(other,tmp); } bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const { - return _mem.isEqual(other._mem,0); + std::string tmp; + return _mem.isEqual(other._mem,0,tmp); } bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception) diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index a7c1b4e04..f045b28a6 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -62,7 +62,7 @@ namespace ParaMEDMEM MemArray &operator=(const MemArray& other); T operator[](int id) const { return _pointer.getConstPointer()[id]; } T& operator[](int id) { return _pointer.getPointer()[id]; } - bool isEqual(const MemArray& other, T prec) const; + bool isEqual(const MemArray& other, T prec, std::string& reason) const; void repr(int sl, std::ostream& stream) const; void reprZip(int sl, std::ostream& stream) const; void fillWithValue(const T& val); @@ -92,6 +92,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom2(const std::vector& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const; MEDCOUPLING_EXPORT bool areInfoEquals(const DataArray& other) const; MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; MEDCOUPLING_EXPORT std::string getName() const { return _name; } @@ -166,6 +167,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const; MEDCOUPLING_EXPORT bool isEqual(const DataArrayDouble& other, double prec) const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const; MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const; //!alloc or useArray should have been called before. MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception); @@ -335,6 +337,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo); MEDCOUPLING_EXPORT bool isEqual(const DataArrayInt& other) const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const; MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayInt& other) const; MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling/MEDCouplingMemArray.txx b/src/MEDCoupling/MEDCouplingMemArray.txx index efca549b5..2278e579d 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.txx +++ b/src/MEDCoupling/MEDCouplingMemArray.txx @@ -79,21 +79,34 @@ namespace ParaMEDMEM } template - bool MemArray::isEqual(const MemArray& other, T prec) const + bool MemArray::isEqual(const MemArray& other, T prec, std::string& reason) const { + std::ostringstream oss; oss.precision(15); if(_nb_of_elem!=other._nb_of_elem) - return false; + { + oss << "Number of elements in coarse data of DataArray mismatch : this=" << _nb_of_elem << " other=" << other._nb_of_elem; + reason=oss.str(); + return false; + } const T *pt1=_pointer.getConstPointer(); const T *pt2=other._pointer.getConstPointer(); if(pt1==0 && pt2==0) return true; if(pt1==0 || pt2==0) - return false; + { + oss << "coarse data pointer is defined for only one DataArray instance !"; + reason=oss.str(); + return false; + } if(pt1==pt2) return true; for(int i=0;i<_nb_of_elem;i++) if(pt1[i]-pt2[i]<-prec || (pt1[i]-pt2[i])>prec) - return false; + { + oss << "The content of data differs at pos #" << i << " of coarse data ! this[i]=" << pt1[i] << " other[i]=" << pt2[i]; + reason=oss.str(); + return false; + } return true; } diff --git a/src/MEDCoupling/MEDCouplingMesh.cxx b/src/MEDCoupling/MEDCouplingMesh.cxx index e6996122e..c96f539ad 100644 --- a/src/MEDCoupling/MEDCouplingMesh.cxx +++ b/src/MEDCoupling/MEDCouplingMesh.cxx @@ -50,10 +50,54 @@ bool MEDCouplingMesh::isStructured() const return getType()==CARTESIAN; } -bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const +bool MEDCouplingMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) { - return _name==other->_name && _description==other->_description && _iteration==other->_iteration - && _order==other->_order && _time_unit==other->_time_unit && fabs(_time-other->_time)<1e-12; + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingMesh::isEqualIfNotWhy : other instance is NULL !"); + std::ostringstream oss; oss.precision(15); + if(_name!=other->_name) + { + oss << "Mesh names differ : this name = \"" << _name << "\" and other name = \"" << other->_name << "\" !"; + reason=oss.str(); + return false; + } + if(_description!=other->_description) + { + oss << "Mesh descriptions differ : this description = \"" << _description << "\" and other description = \"" << other->_description << "\" !"; + reason=oss.str(); + return false; + } + if(_iteration!=other->_iteration) + { + oss << "Mesh iterations differ : this iteration = \"" << _iteration << "\" and other iteration = \"" << other->_iteration << "\" !"; + reason=oss.str(); + return false; + } + if(_order!=other->_order) + { + oss << "Mesh orders differ : this order = \"" << _order << "\" and other order = \"" << other->_order << "\" !"; + reason=oss.str(); + return false; + } + if(_time_unit!=other->_time_unit) + { + oss << "Mesh time units differ : this time unit = \"" << _time_unit << "\" and other time unit = \"" << other->_time_unit << "\" !"; + reason=oss.str(); + return false; + } + if(fabs(_time-other->_time)>=1e-12) + { + oss << "Mesh times differ : this time = \"" << _time << "\" and other time = \"" << other->_time << "\" !"; + reason=oss.str(); + return false; + } + return true; +} + +bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) +{ + std::string tmp; + return isEqualIfNotWhy(other,prec,tmp); } /*! diff --git a/src/MEDCoupling/MEDCouplingMesh.hxx b/src/MEDCoupling/MEDCouplingMesh.hxx index 282715ec5..6a754e1a2 100644 --- a/src/MEDCoupling/MEDCouplingMesh.hxx +++ b/src/MEDCoupling/MEDCouplingMesh.hxx @@ -61,7 +61,8 @@ namespace ParaMEDMEM virtual void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); virtual void copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); // comparison methods - virtual bool isEqual(const MEDCouplingMesh *other, double prec) const; + virtual bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); + virtual bool isEqual(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const = 0; virtual void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) = 0; diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index 0611c6342..9754bd296 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -109,14 +109,19 @@ void MEDCouplingPointSet::copyTinyStringsFrom(const MEDCouplingMesh *other) thro _coords->copyStringInfoFrom(*otherC->_coords); } -bool MEDCouplingPointSet::isEqual(const MEDCouplingMesh *other, double prec) const +bool MEDCouplingPointSet::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::isEqualIfNotWhy : null mesh instance in input !"); const MEDCouplingPointSet *otherC=dynamic_cast(other); if(!otherC) + { + reason="mesh given in input is not castable in MEDCouplingPointSet !"; + return false; + } + if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason)) return false; - if(!MEDCouplingMesh::isEqual(other,prec)) - return false; - if(!areCoordsEqual(*otherC,prec)) + if(!areCoordsEqualIfNotWhy(*otherC,prec,reason)) return false; return true; } @@ -131,15 +136,27 @@ bool MEDCouplingPointSet::isEqualWithoutConsideringStr(const MEDCouplingMesh *ot return true; } -bool MEDCouplingPointSet::areCoordsEqual(const MEDCouplingPointSet& other, double prec) const +bool MEDCouplingPointSet::areCoordsEqualIfNotWhy(const MEDCouplingPointSet& other, double prec, std::string& reason) const { if(_coords==0 && other._coords==0) return true; if(_coords==0 || other._coords==0) - return false; + { + reason="Only one PointSet between the two this and other has coordinate defined !"; + return false; + } if(_coords==other._coords) return true; - return _coords->isEqual(*other._coords,prec); + bool ret=_coords->isEqualIfNotWhy(*other._coords,prec,reason); + if(!ret) + reason.insert(0,"Coordinates DataArray do not match : "); + return ret; +} + +bool MEDCouplingPointSet::areCoordsEqual(const MEDCouplingPointSet& other, double prec) const +{ + std::string tmp; + return areCoordsEqualIfNotWhy(other,prec,tmp); } bool MEDCouplingPointSet::areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const diff --git a/src/MEDCoupling/MEDCouplingPointSet.hxx b/src/MEDCoupling/MEDCouplingPointSet.hxx index 18b200ec6..13f994872 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.hxx +++ b/src/MEDCoupling/MEDCouplingPointSet.hxx @@ -60,8 +60,9 @@ namespace ParaMEDMEM DataArrayDouble *getCoords() { return _coords; } DataArrayDouble *getCoordinatesAndOwner() const; void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); - bool isEqual(const MEDCouplingMesh *other, double prec) const; + bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + bool areCoordsEqualIfNotWhy(const MEDCouplingPointSet& other, double prec, std::string& reason) const; bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const; bool areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const; virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0; diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx index c9c237275..62df2db49 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx @@ -104,16 +104,28 @@ bool MEDCouplingTimeDiscretization::areCompatible(const MEDCouplingTimeDiscretiz return true; } -bool MEDCouplingTimeDiscretization::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingTimeDiscretization::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const { + std::ostringstream oss; oss.precision(15); if(_time_unit!=other->_time_unit) - return false; + { + oss << "Field discretizations differ : this time unit = \"" << _time_unit << "\" and other time unit = \"" << other->_time_unit << "\" !"; + reason=oss.str(); + return false; + } if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) - return false; + { + oss << "Field discretizations differ : this time tolerance = \"" << _time_tolerance << "\" and other time tolerance = \"" << other->_time_tolerance << "\" !"; + reason=oss.str(); + return false; + } if(_array==0 && other->_array==0) return true; if(_array==0 || other->_array==0) - return false; + { + reason="Field discretizations differ : Only one timediscretization between the two this and other has a DataArrayDouble for values defined"; + return false; + } if(_array->getNumberOfComponents()!=other->_array->getNumberOfComponents()) return false; if(_array->getNumberOfTuples()!=other->_array->getNumberOfTuples()) @@ -165,18 +177,25 @@ bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(const MEDCouplin return true; } -bool MEDCouplingTimeDiscretization::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const +bool MEDCouplingTimeDiscretization::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const { - if(!areStrictlyCompatible(other)) + if(!areStrictlyCompatible(other,reason)) return false; if(_array==other->_array) return true; - return _array->isEqual(*other->_array,prec); + return _array->isEqualIfNotWhy(*other->_array,prec,reason); +} + +bool MEDCouplingTimeDiscretization::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const +{ + std::string reason; + return isEqualIfNotWhy(other,prec,reason); } bool MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const { - if(!areStrictlyCompatible(other)) + std::string tmp; + if(!areStrictlyCompatible(other,tmp)) return false; if(_array==other->_array) return true; @@ -801,12 +820,15 @@ bool MEDCouplingNoTimeLabel::areCompatible(const MEDCouplingTimeDiscretization * return otherC!=0; } -bool MEDCouplingNoTimeLabel::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingNoTimeLabel::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const { - if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other)) + if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) return false; const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - return otherC!=0; + bool ret=otherC!=0; + if(!ret) + reason.insert(0,"time discretization of this is NO_TIME, other has a different time discretization."); + return ret; } bool MEDCouplingNoTimeLabel::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const @@ -833,12 +855,15 @@ bool MEDCouplingNoTimeLabel::areCompatibleForMeld(const MEDCouplingTimeDiscretiz return otherC!=0; } -bool MEDCouplingNoTimeLabel::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const +bool MEDCouplingNoTimeLabel::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) - return false; - return MEDCouplingTimeDiscretization::isEqual(other,prec); + { + reason="This has time discretization NO_TIME, other not."; + return false; + } + return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); } bool MEDCouplingNoTimeLabel::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const @@ -1211,12 +1236,15 @@ bool MEDCouplingWithTimeStep::areCompatible(const MEDCouplingTimeDiscretization return otherC!=0; } -bool MEDCouplingWithTimeStep::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingWithTimeStep::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const { - if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other)) + if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) return false; const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - return otherC!=0; + bool ret=otherC!=0; + if(!ret) + reason.insert(0,"time discretization of this is ONE_TIME, other has a different time discretization."); + return ret; } bool MEDCouplingWithTimeStep::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const @@ -1243,18 +1271,34 @@ bool MEDCouplingWithTimeStep::areCompatibleForMeld(const MEDCouplingTimeDiscreti return otherC!=0; } -bool MEDCouplingWithTimeStep::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const +bool MEDCouplingWithTimeStep::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); + std::ostringstream oss; oss.precision(15); if(!otherC) - return false; + { + reason="This has time discretization ONE_TIME, other not."; + return false; + } if(_iteration!=otherC->_iteration) - return false; + { + oss << "iterations differ. this iteration=" << _iteration << " other iteration=" << otherC->_iteration; + reason=oss.str(); + return false; + } if(_order!=otherC->_order) - return false; + { + oss << "orders differ. this order=" << _order << " other order=" << otherC->_order; + reason=oss.str(); + return false; + } if(std::fabs(_time-otherC->_time)>_time_tolerance) - return false; - return MEDCouplingTimeDiscretization::isEqual(other,prec); + { + oss << "times differ. this time=" << _time << " other time=" << otherC->_time; + reason=oss.str(); + return false; + } + return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); } bool MEDCouplingWithTimeStep::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const @@ -1647,12 +1691,15 @@ bool MEDCouplingConstOnTimeInterval::areCompatible(const MEDCouplingTimeDiscreti return otherC!=0; } -bool MEDCouplingConstOnTimeInterval::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingConstOnTimeInterval::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const { - if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other)) + if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) return false; const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - return otherC!=0; + bool ret=otherC!=0; + if(!ret) + reason.insert(0,"time discretization of this is CONST_ON_TIME_INTERVAL, other has a different time discretization."); + return ret; } bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const @@ -1679,24 +1726,52 @@ bool MEDCouplingConstOnTimeInterval::areCompatibleForMeld(const MEDCouplingTimeD return otherC!=0; } -bool MEDCouplingConstOnTimeInterval::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const +bool MEDCouplingConstOnTimeInterval::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); + std::ostringstream oss; oss.precision(15); if(!otherC) - return false; + { + reason="This has time discretization CONST_ON_TIME_INTERVAL, other not."; + return false; + } if(_start_iteration!=otherC->_start_iteration) - return false; + { + oss << "start iterations differ. this start iteration=" << _start_iteration << " other start iteration=" << otherC->_start_iteration; + reason=oss.str(); + return false; + } if(_start_order!=otherC->_start_order) - return false; + { + oss << "start orders differ. this start order=" << _start_order << " other start order=" << otherC->_start_order; + reason=oss.str(); + return false; + } if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) - return false; + { + oss << "start times differ. this start time=" << _start_time << " other start time=" << otherC->_start_time; + reason=oss.str(); + return false; + } if(_end_iteration!=otherC->_end_iteration) - return false; + { + oss << "end iterations differ. this end iteration=" << _end_iteration << " other end iteration=" << otherC->_end_iteration; + reason=oss.str(); + return false; + } if(_end_order!=otherC->_end_order) - return false; + { + oss << "end orders differ. this end order=" << _end_order << " other end order=" << otherC->_end_order; + reason=oss.str(); + return false; + } if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) - return false; - return MEDCouplingTimeDiscretization::isEqual(other,prec); + { + oss << "end times differ. this end time=" << _end_time << " other end time=" << otherC->_end_time; + reason=oss.str(); + return false; + } + return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); } bool MEDCouplingConstOnTimeInterval::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const @@ -2008,27 +2083,55 @@ void MEDCouplingTwoTimeSteps::checkCoherency() const throw(INTERP_KERNEL::Except throw INTERP_KERNEL::Exception("The number of tuples mismatch between the start and the end arrays !"); } -bool MEDCouplingTwoTimeSteps::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const +bool MEDCouplingTwoTimeSteps::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const { + std::ostringstream oss; const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(other); if(!otherC) - return false; + { + reason="This has time discretization LINEAR_TIME, other not."; + return false; + } if(_start_iteration!=otherC->_start_iteration) - return false; - if(_end_iteration!=otherC->_end_iteration) - return false; + { + oss << "start iterations differ. this start iteration=" << _start_iteration << " other start iteration=" << otherC->_start_iteration; + reason=oss.str(); + return false; + } if(_start_order!=otherC->_start_order) - return false; - if(_end_order!=otherC->_end_order) - return false; + { + oss << "start orders differ. this start order=" << _start_order << " other start order=" << otherC->_start_order; + reason=oss.str(); + return false; + } if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) - return false; + { + oss << "start times differ. this start time=" << _start_time << " other start time=" << otherC->_start_time; + reason=oss.str(); + return false; + } + if(_end_iteration!=otherC->_end_iteration) + { + oss << "end iterations differ. this end iteration=" << _end_iteration << " other end iteration=" << otherC->_end_iteration; + reason=oss.str(); + return false; + } + if(_end_order!=otherC->_end_order) + { + oss << "end orders differ. this end order=" << _end_order << " other end order=" << otherC->_end_order; + reason=oss.str(); + return false; + } if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) - return false; + { + oss << "end times differ. this end time=" << _end_time << " other end time=" << otherC->_end_time; + reason=oss.str(); + return false; + } if(_end_array!=otherC->_end_array) - if(!_end_array->isEqual(*otherC->_end_array,prec)) + if(!_end_array->isEqualIfNotWhy(*otherC->_end_array,prec,reason)) return false; - return MEDCouplingTimeDiscretization::isEqual(other,prec); + return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); } bool MEDCouplingTwoTimeSteps::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const @@ -2275,12 +2378,15 @@ bool MEDCouplingLinearTime::areCompatible(const MEDCouplingTimeDiscretization *o return true; } -bool MEDCouplingLinearTime::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingLinearTime::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const { - if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other)) + if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) return false; const MEDCouplingLinearTime *otherC=dynamic_cast(other); - return otherC!=0; + bool ret=otherC!=0; + if(!ret) + reason.insert(0,"time discretization of this is LINEAR_TIME, other has a different time discretization."); + return ret; } bool MEDCouplingLinearTime::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx index 65eefb105..6dab084c3 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx @@ -46,10 +46,11 @@ namespace ParaMEDMEM 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; + virtual bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; virtual bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; virtual bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; virtual bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; + virtual bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; virtual bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; virtual bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; virtual MEDCouplingTimeDiscretization *buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const; @@ -171,10 +172,10 @@ namespace ParaMEDMEM void multiplyEqual(const MEDCouplingTimeDiscretization *other); MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; void divideEqual(const MEDCouplingTimeDiscretization *other); - bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; + bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; + bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; @@ -231,10 +232,10 @@ namespace ParaMEDMEM void multiplyEqual(const MEDCouplingTimeDiscretization *other); MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; void divideEqual(const MEDCouplingTimeDiscretization *other); - bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; + bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; + bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; @@ -287,11 +288,11 @@ namespace ParaMEDMEM void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD); MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; + bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; + bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception); void getValueForTime(double time, const std::vector& vals, double *res) const; @@ -353,7 +354,7 @@ namespace ParaMEDMEM const DataArrayDouble *getEndArray() const; DataArrayDouble *getEndArray(); void checkCoherency() const throw(INTERP_KERNEL::Exception); - bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; + bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; void checkNoTimePresence() const throw(INTERP_KERNEL::Exception); void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception); @@ -402,7 +403,7 @@ namespace ParaMEDMEM void checkCoherency() const throw(INTERP_KERNEL::Exception); MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; + bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 7d1e226fe..4a4beb309 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -304,29 +304,60 @@ std::set MEDCouplingUMesh::getAllGeoTypes() c * This method is a method that compares 'this' and 'other'. * This method compares \b all attributes, even names and component names. */ -bool MEDCouplingUMesh::isEqual(const MEDCouplingMesh *other, double prec) const +bool MEDCouplingUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isEqualIfNotWhy : input other pointer is null !"); + std::ostringstream oss; oss.precision(15); const MEDCouplingUMesh *otherC=dynamic_cast(other); if(!otherC) - return false; - if(!MEDCouplingPointSet::isEqual(other,prec)) + { + reason="mesh given in input is not castable in MEDCouplingUMesh !"; + return false; + } + if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason)) return false; if(_mesh_dim!=otherC->_mesh_dim) - return false; + { + oss << "umesh dimension mismatch : this mesh dimension=" << _mesh_dim << " other mesh dimension=" << otherC->_mesh_dim; + reason=oss.str(); + return false; + } if(_types!=otherC->_types) - return false; + { + oss << "umesh geometric type mismatch :\nThis geometric types are :"; + for(std::set::const_iterator iter=_types.begin();iter!=_types.end();iter++) + { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); oss << cm.getRepr() << ", "; } + oss << "\nOther geometric types are :"; + for(std::set::const_iterator iter=otherC->_types.begin();iter!=otherC->_types.end();iter++) + { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); oss << cm.getRepr() << ", "; } + reason=oss.str(); + return false; + } if(_nodal_connec!=0 || otherC->_nodal_connec!=0) if(_nodal_connec==0 || otherC->_nodal_connec==0) - return false; + { + reason="Only one UMesh between the two this and other has its nodal connectivity DataArrayInt defined !"; + return false; + } if(_nodal_connec!=otherC->_nodal_connec) - if(!_nodal_connec->isEqual(*otherC->_nodal_connec)) - return false; + if(!_nodal_connec->isEqualIfNotWhy(*otherC->_nodal_connec,reason)) + { + reason.insert(0,"Nodal connectivity DataArrayInt differ : "); + return false; + } if(_nodal_connec_index!=0 || otherC->_nodal_connec_index!=0) if(_nodal_connec_index==0 || otherC->_nodal_connec_index==0) - return false; + { + reason="Only one UMesh between the two this and other has its nodal connectivity index DataArrayInt defined !"; + return false; + } if(_nodal_connec_index!=otherC->_nodal_connec_index) - if(!_nodal_connec_index->isEqual(*otherC->_nodal_connec_index)) - return false; + if(!_nodal_connec_index->isEqualIfNotWhy(*otherC->_nodal_connec_index,reason)) + { + reason.insert(0,"Nodal connectivity index DataArrayInt differ : "); + return false; + } return true; } diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index 209e5fa3d..ae98b9ff6 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -42,7 +42,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT MEDCouplingUMesh *clone(bool recDeepCpy) const; MEDCOUPLING_EXPORT void updateTime() const; MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return UNSTRUCTURED; } - MEDCOUPLING_EXPORT bool isEqual(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index a1daae784..6d08f9d06 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -624,7 +624,19 @@ namespace ParaMEDMEM return ret; } - PyObject *buildPart(PyObject *li) const throw(INTERP_KERNEL::Exception) + PyObject *isEqualIfNotWhy(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) + { + std::string ret1; + bool ret0=self->isEqualIfNotWhy(other,prec,ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); + return ret; + } + + PyObject *buildPart(PyObject *li) const throw(INTERP_KERNEL::Exception) { void *da=0; int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); @@ -2744,6 +2756,18 @@ namespace ParaMEDMEM return convertDblArrToPyList(vals,self->getNbOfElems()); } + PyObject *isEqualIfNotWhy(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception) + { + std::string ret1; + bool ret0=self->isEqualIfNotWhy(other,prec,ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); + return ret; + } + PyObject *getValuesAsTuple() throw(INTERP_KERNEL::Exception) { const double *vals=self->getPointer(); @@ -4387,6 +4411,18 @@ namespace ParaMEDMEM return convertIntArrToPyList(vals,self->getNbOfElems()); } + PyObject *isEqualIfNotWhy(const DataArrayInt& other, double prec) const throw(INTERP_KERNEL::Exception) + { + std::string ret1; + bool ret0=self->isEqualIfNotWhy(other,ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); + return ret; + } + PyObject *getValuesAsTuple() throw(INTERP_KERNEL::Exception) { const int *vals=self->getPointer(); @@ -5965,6 +6001,18 @@ namespace ParaMEDMEM return convertMesh(ret1, SWIG_POINTER_OWN | 0 ); } + PyObject *isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec) const throw(INTERP_KERNEL::Exception) + { + std::string ret1; + bool ret0=self->isEqualIfNotWhy(other,meshPrec,valsPrec,ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); + return ret; + } + PyObject *buildSubMeshData(PyObject *li) const throw(INTERP_KERNEL::Exception) { DataArrayInt *ret1=0;