From: ageay Date: Mon, 8 Apr 2013 11:06:34 +0000 (+0000) Subject: Bug correction on substractInPlaceDM X-Git-Tag: V6_main_FINAL~189 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=562779aa361c645c75befed6d8a79334abc2ff87;p=tools%2Fmedcoupling.git Bug correction on substractInPlaceDM --- diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx index 1180cf43c..f47e0d579 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx @@ -355,6 +355,8 @@ void MEDCouplingFieldDiscretization::getCellIdsHavingGaussLocalization(int locId void MEDCouplingFieldDiscretization::RenumberEntitiesFromO2NArr(double eps, const int *old2NewPtr, int newNbOfEntity, DataArrayDouble *arr, const char *msg) { + if(!arr) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::RenumberEntitiesFromO2NArr : input array is NULL !"); int oldNbOfElems=arr->getNumberOfTuples(); int nbOfComp=arr->getNumberOfComponents(); int newNbOfTuples=newNbOfEntity; diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index 7d303c54e..09f49923a 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -436,8 +436,10 @@ void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool /*! * This method performs a clone of mesh and a renumbering of underlying nodes of it. The number of nodes remains not compulsory the same as renumberCells method. * The values of field are impacted in consequence to have the same geometrical field. + * + * \sa MEDCouplingFieldDouble::renumberNodesWithoutMesh */ -void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception) +void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps) throw(INTERP_KERNEL::Exception) { const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); if(!meshC) @@ -445,15 +447,17 @@ void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg) throw(INTERP_KE int nbOfNodes=meshC->getNumberOfNodes(); MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); int newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1; - renumberNodesWithoutMesh(old2NewBg,newNbOfNodes); + renumberNodesWithoutMesh(old2NewBg,newNbOfNodes,eps); meshC2->renumberNodes(old2NewBg,newNbOfNodes); setMesh(meshC2); } /*! * \b WARNING : use this method with lot of care ! - * This method performs half job of MEDCouplingFieldDouble::renumberNodes. That is to say no permutation of cells is done on underlying mesh. - * That is to say, the field content is changed by this method. + * ** WARNING : in case of throw the content in array can be partially modified until the exception raises ** + * This method performs half job of MEDCouplingFieldDouble::renumberNodes. That is to say no permutation of nodes is done on underlying mesh. + * That is to say, the field content is changed by this method. As the API suggests, this method can performs the half job of nodes contraction. + * That's why an epsilon is given to specify a threshold of error in case of two nodes are merged but the difference of values on these nodes are higher than \a eps. */ void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps) throw(INTERP_KERNEL::Exception) { @@ -1375,21 +1379,21 @@ void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector_mesh is not defined or other an exeption will be throw. */ -void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception) +void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps) throw(INTERP_KERNEL::Exception) { if(_mesh==0 || other==0) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !"); DataArrayInt *cellCor=0,*nodeCor=0; - other->checkGeoEquivalWith(_mesh,levOfCheck,prec,cellCor,nodeCor); + other->checkGeoEquivalWith(_mesh,levOfCheck,precOnMesh,cellCor,nodeCor); MEDCouplingAutoRefCountObjectPtr cellCor2(cellCor),nodeCor2(nodeCor); if(cellCor) renumberCellsWithoutMesh(cellCor->getConstPointer(),false); if(nodeCor) - renumberNodesWithoutMesh(nodeCor->getConstPointer(),_mesh->getNumberOfNodes()); + renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps); setMesh(const_cast(other)); } @@ -1398,14 +1402,18 @@ void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, * No interpolation will be done here only an analyze of two underlying mesh will be done to see if the meshes are geometrically equivalent. If yes, the eventual renumbering will be done and operator-= applyed after. * This method requires that 'f' and \a this are coherent (check coherency) and that 'f' and \a this would be coherent for a merge. * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method. + * \param [in] precOnMesh precision for the mesh comparison between \c this->getMesh() and \c f->getMesh() + * \param [in] eps the precision on values that can appear in case of */ -void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception) +void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps) throw(INTERP_KERNEL::Exception) { checkCoherency(); + if(!f) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : input field is NULL !"); f->checkCoherency(); if(!areCompatibleForMerge(f)) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::diffWith : Fields are not compatible ; unable to apply mergeFields on them !"); - changeUnderlyingMesh(f->getMesh(),levOfCheck,prec); + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : Fields are not compatible ; unable to apply mergeFields on them !"); + changeUnderlyingMesh(f->getMesh(),levOfCheck,precOnMesh,eps); operator-=(*f); } @@ -1500,7 +1508,7 @@ bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals) thr { const MEDCouplingUMesh *meshC=dynamic_cast(_mesh); if(!meshC) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !"); + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipConnectivity : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !"); if(!((const MEDCouplingFieldDiscretization *)_type)) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipConnectivity !"); MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingUMesh *)meshC->deepCpy()); diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx index d74464c13..577f54e4b 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -53,7 +53,7 @@ namespace ParaMEDMEM bool areCompatibleForMeld(const MEDCouplingFieldDouble *other) const; void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); void renumberCellsWithoutMesh(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); - void renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception); + void renumberNodes(const int *old2NewBg, double eps=1e-15) throw(INTERP_KERNEL::Exception); void renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps=1e-15) throw(INTERP_KERNEL::Exception); DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception); @@ -139,8 +139,8 @@ namespace ParaMEDMEM void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); void serialize(DataArrayInt *&dataInt, std::vector& arrays) const; // - void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception); - void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception); + void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps=1e-15) throw(INTERP_KERNEL::Exception); + void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps=1e-15) throw(INTERP_KERNEL::Exception); bool mergeNodes(double eps, double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); bool mergeNodes2(double eps, double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); bool zipCoords(double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index b47211df3..f07d9843f 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -2890,8 +2890,8 @@ namespace ParaMEDMEM void setTimeValue(double val) throw(INTERP_KERNEL::Exception); void setEndTimeValue(double val) throw(INTERP_KERNEL::Exception); void updateTime() const throw(INTERP_KERNEL::Exception); - void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception); - void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception); + void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps=1e-15) throw(INTERP_KERNEL::Exception); + void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps=1e-15) throw(INTERP_KERNEL::Exception); bool mergeNodes(double eps, double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); bool mergeNodes2(double eps, double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); bool zipCoords(double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); @@ -3204,7 +3204,7 @@ namespace ParaMEDMEM self->renumberCells(da2->getConstPointer(),check); } } - void renumberNodes(PyObject *li) throw(INTERP_KERNEL::Exception) + void renumberNodes(PyObject *li, double eps=1e-15) throw(INTERP_KERNEL::Exception) { void *da=0; int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); @@ -3212,7 +3212,7 @@ namespace ParaMEDMEM { int size; INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - self->renumberNodes(tmp); + self->renumberNodes(tmp,eps); } else { @@ -3220,7 +3220,7 @@ namespace ParaMEDMEM if(!da2) throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); da2->checkAllocated(); - self->renumberNodes(da2->getConstPointer()); + self->renumberNodes(da2->getConstPointer(),eps); } }