From: ageay Date: Tue, 18 Jun 2013 14:37:38 +0000 (+0000) Subject: On the road of addition of optimized unstructured mesh with a single geometric type. X-Git-Tag: B4CMakeModifs~62 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=80f7cb5a2e7e8cc675bf86c52eea13d289c8d1c2;p=modules%2Fmed.git On the road of addition of optimized unstructured mesh with a single geometric type. --- diff --git a/src/MEDCoupling/CMakeLists.txt b/src/MEDCoupling/CMakeLists.txt index f25bc2bf9..a7a715a8e 100644 --- a/src/MEDCoupling/CMakeLists.txt +++ b/src/MEDCoupling/CMakeLists.txt @@ -35,6 +35,7 @@ SET(medcoupling_SOURCES MEDCouplingField.cxx MEDCouplingFieldDouble.cxx MEDCouplingUMesh.cxx + MEDCoupling1GTUMesh.cxx MEDCouplingMemArray.cxx MEDCouplingMemArrayChar.cxx MEDCouplingTimeLabel.cxx diff --git a/src/MEDCoupling/MEDCoupling1GTUMesh.cxx b/src/MEDCoupling/MEDCoupling1GTUMesh.cxx index 41095ca40..b51665cf0 100644 --- a/src/MEDCoupling/MEDCoupling1GTUMesh.cxx +++ b/src/MEDCoupling/MEDCoupling1GTUMesh.cxx @@ -19,32 +19,45 @@ // Author : Anthony Geay (CEA/DEN) #include "MEDCoupling1GTUMesh.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" + +#include "SplitterTetra.hxx" using namespace ParaMEDMEM; -MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *meshName, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception) +MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):_cm(&cm) +{ + setName(name); +} + +MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm) +{ +} + +MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception) { if(type==INTERP_KERNEL::NORM_ERROR) throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !"); const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); if(!cm.isDynamic()) - return MEDCoupling1SGTUMesh::New(meshName,type); + return MEDCoupling1SGTUMesh::New(name,type); throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : not implemented yet !"); } const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const throw(INTERP_KERNEL::Exception) { - return _cm; + return *_cm; } INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const throw(INTERP_KERNEL::Exception) { - return _cm.getEnum(); + return _cm->getEnum(); } int MEDCoupling1GTUMesh::getMeshDimension() const { - return (int)_cm.getDimension(); + return (int)_cm->getDimension(); } /*! @@ -130,6 +143,15 @@ std::vector MEDCoupling1GTUMesh::getDistributionOfTypes() const throw(INTER * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType. * * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined + * + * \b Example1:
+ * - Before \a this has 3 cells \a profile contains [0,1,2] + * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty
+ * + * \b Example2:
+ * - Before \a this has 3 cells \a profile contains [1,2] + * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]]
+ */ void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) { @@ -137,6 +159,1205 @@ void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std:: throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !"); if(profile->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !"); + int nbTuples=profile->getNumberOfTuples(); + int nbOfCells=getNumberOfCells(); + code.resize(3); idsInPflPerType.resize(1); + code[0]=(int)getCellModelEnum(); code[1]=nbOfCells; + idsInPflPerType.resize(1); + if(profile->isIdentity() && nbTuples==nbOfCells) + { + code[2]=-1; + idsInPflPerType[0]=const_cast(profile); idsInPflPerType[0]->incrRef(); + idsPerType.clear(); + } + code[2]=0; + profile->checkAllIdsInRange(0,nbOfCells); + idsPerType.resize(1); + idsPerType[0]=const_cast(profile); idsPerType[0]->incrRef(); + idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1); +} + +/*! + * This method tries to minimize at most the number of deep copy. + * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return. + * + * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig + */ +DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) +{ + int nbOfCells=getNumberOfCells(); + if(code.size()!=3) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !"); + if(code[0]!=(int)getCellModelEnum()) + { + std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getCellModelEnum() << " (" << _cm->getRepr() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(code[2]==-1) + { + if(code[1]==nbOfCells) + return 0; + else + { + std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(code[2]!=0) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !"); + if(idsPerType.size()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !"); + const DataArrayInt *pfl=idsPerType[0]; + if(!pfl) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !"); + if(pfl->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !"); + pfl->checkAllIdsInRange(0,nbOfCells); + pfl->incrRef(); + return const_cast(pfl); +} + +void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); + m->writeVTKLL(ofs,cellData,pointData); +} + +std::string MEDCoupling1GTUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception) +{ + return std::string("UnstructuredGrid"); +} + +bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) +{ + if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason)) + return false; + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !"); + const MEDCoupling1GTUMesh *otherC=dynamic_cast(other); + if(!otherC) + { + reason="mesh given in input is not castable in MEDCouplingSGTUMesh !"; + return false; + } + if(&_cm!=&otherC->_cm) + { + reason="mismatch in geometric type !"; + return false; + } + return true; +} + +bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec)) + return false; + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !"); + const MEDCoupling1GTUMesh *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(&_cm!=&otherC->_cm) + return false; + return true; +} + +void MEDCoupling1GTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingPointSet::checkCoherency(); +} + +DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const +{ + MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); + MEDCouplingAutoRefCountObjectPtr ret=m->getBarycenterAndOwner(); + return ret.retn(); +} + +MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const +{ + MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); + MEDCouplingAutoRefCountObjectPtr ret=m->getMeasureField(isAbs); + ret->setMesh(this); + return ret.retn(); +} + +MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const +{ + MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); + MEDCouplingAutoRefCountObjectPtr ret=m->getMeasureFieldOnNode(isAbs); + ret->setMesh(this); + return ret.retn(); +} + +/*! + * to improve perf ! + */ +int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const +{ + MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); + return m->getCellContainingPoint(pos,eps); +} + +MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const +{ + MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); + MEDCouplingAutoRefCountObjectPtr ret=m->buildOrthogonalField(); + ret->setMesh(this); + return ret.retn(); +} + +DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const +{ + MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); + return m->getCellsInBoundingBox(bbox,eps); +} + +DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) +{ + MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); + return m->getCellsInBoundingBox(bbox,eps); +} + +MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const +{ + MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); + return m->buildFacePartOfMySelfNode(start,end,fullyIn); +} + +DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const +{ + MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); + return m->findBoundaryNodes(); +} + +MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const +{ + MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); + return m->buildBoundaryMesh(keepCoords); +} + +void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); + m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr); +} + +//== + +MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn) +{ + if(recDeepCpy) + { + const DataArrayInt *c(other._conn); + if(c) + _conn=c->deepCpy(); + } +} + +MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm) +{ +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception) +{ + if(type==INTERP_KERNEL::NORM_ERROR) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !"); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + if(cm.isDynamic()) + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static type are dealed here !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return new MEDCoupling1SGTUMesh(name,cm); +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const +{ + return new MEDCoupling1SGTUMesh(*this,recDeepCpy); +} + +void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !"); + const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !"); + setNodalConnectivity(otherC->getNodalConnectivity()); +} + +void MEDCoupling1SGTUMesh::updateTime() const +{ + MEDCoupling1GTUMesh::updateTime(); + const DataArrayInt *c(_conn); + if(c) + updateTimeWith(*c); +} + +std::size_t MEDCoupling1SGTUMesh::getHeapMemorySize() const +{ + std::size_t ret=0; + const DataArrayInt *c(_conn); + if(c) + ret+=c->getHeapMemorySize(); + return MEDCouplingPointSet::getHeapMemorySize()+ret; +} + +MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const +{ + return clone(true); +} + +bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !"); + std::ostringstream oss; oss.precision(15); + const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); + if(!otherC) + { + reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !"; + return false; + } + if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason)) + return false; + const DataArrayInt *c1(_conn),*c2(otherC->_conn); + if(c1==c2) + return true; + if(!c1 || !c2) + { + reason="in connectivity of single static geometric type exactly one among this and other is null !"; + return false; + } + if(!c1->isEqualIfNotWhy(*c2,reason)) + { + reason.insert(0,"Nodal connectivity DataArrayInt differ : "); + return false; + } + return true; +} + +bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !"); + const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec)) + return false; + const DataArrayInt *c1(_conn),*c2(otherC->_conn); + if(c1==c2) + return true; + if(!c1 || !c2) + return false; + if(!c1->isEqualWithoutConsideringStr(*c2)) + return false; + return true; +} + +void MEDCoupling1SGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + MEDCoupling1SGTUMesh::checkCoherency(); + const DataArrayInt *c1(_conn); + if(c1) + { + if(c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !"); + if(c1->getInfoOnComponent(0)!="") + throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !"); + c1->checkAllocated(); + } + else + throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !"); +} + +void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); + const DataArrayInt *c1(_conn); + int nbOfTuples=c1->getNumberOfTuples(); + int nbOfNodesPerCell=(int)_cm->getNumberOfNodes(); + if(nbOfTuples%nbOfNodesPerCell!=0) + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkCoherency1 : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfNodes=getNumberOfNodes(); + int nbOfCells=nbOfTuples/nbOfNodesPerCell; + const int *w(c1->begin()); + for(int i=0;i=nbOfNodes) + { + std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency1(eps); +} + +int MEDCoupling1SGTUMesh::getNumberOfCells() const +{ + int nbOfTuples=getNodalConnectivityLength(); + int nbOfNodesPerCell=getNumberOfNodesPerCell(); + if(nbOfTuples%nbOfNodesPerCell!=0) + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh:getNumberOfCells: : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return nbOfTuples/nbOfNodesPerCell; +} + +int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception) +{ + checkNonDynamicGeoType(); + return (int)_cm->getNumberOfNodes(); +} + +int MEDCoupling1SGTUMesh::getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception) +{ + const DataArrayInt *c1(_conn); + if(!c1) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : no connectivity set !"); + if(c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !"); + if(!c1->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !"); + return c1->getNumberOfTuples(); +} + +DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception) +{ + checkNonDynamicGeoType(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(getNumberOfCells(),1); + ret->fillWithValue((int)_cm->getNumberOfNodes()); + return ret.retn(); +} + +DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception) +{ + checkNonDynamicGeoType(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(getNumberOfCells(),1); + ret->fillWithValue((int)_cm->getNumberOfSons()); + return ret.retn(); +} + +void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const +{ + int sz=getNumberOfNodesPerCell(); + conn.resize(sz); + if(cellId>=0 && cellIdbegin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin()); + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception) +{ + if(_cm->isDynamic()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !"); +} + +std::string MEDCoupling1SGTUMesh::simpleRepr() const +{ + static const char msg0[]="No coordinates specified !"; + std::ostringstream ret; + ret << "Single static geometic type unstructured mesh with name : \"" << getName() << "\"\n"; + ret << "Description of mesh : \"" << getDescription() << "\"\n"; + int tmpp1,tmpp2; + double tt=getTime(tmpp1,tmpp2); + ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n"; + ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n"; + ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : "; + if(_coords!=0) + { + const int spaceDim=getSpaceDimension(); + ret << spaceDim << "\nInfo attached on space dimension : "; + for(int i=0;igetInfoOnComponent(i) << "\" "; + ret << "\n"; + } + else + ret << msg0 << "\n"; + ret << "Number of nodes : "; + if(_coords!=0) + ret << getNumberOfNodes() << "\n"; + else + ret << msg0 << "\n"; + ret << "Number of cells : "; + if((const DataArrayInt *)_conn) + { + if(_conn->isAllocated()) + { + if(_conn->getNumberOfComponents()==1) + ret << getNumberOfCells() << "\n"; + else + ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n"; + } + else + ret << "Nodal connectivity array specified but not allocated !" << "\n"; + } + else + ret << "No connectivity specified !" << "\n"; + ret << "Cell type : " << _cm->getRepr() << "\n"; + return ret.str(); +} + +std::string MEDCoupling1SGTUMesh::advancedRepr() const +{ + std::ostringstream ret; + ret << simpleRepr(); + ret << "\nCoordinates array : \n___________________\n\n"; + if(_coords) + _coords->reprWithoutNameStream(ret); + else + ret << "No array set !\n"; + ret << "\n\nConnectivity array : \n____________________\n\n"; + // + if((const DataArrayInt *)_conn) + { + if(_conn->isAllocated()) + { + if(_conn->getNumberOfComponents()==1) + { + int nbOfCells=getNumberOfCells(); + int sz=getNumberOfNodesPerCell(); + const int *connPtr=_conn->begin(); + for(int i=0;i(ret," ")); + ret << "\n"; + } + } + else + ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n"; + } + else + ret << "Nodal connectivity array specified but not allocated !" << "\n"; + } + else + ret << "No connectivity specified !" << "\n"; + return ret.str(); +} + +DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + int spaceDim=getSpaceDimension(); + int nbOfCells=getNumberOfCells(); + int nbOfNodes=getNumberOfNodes(); + ret->alloc(nbOfCells,spaceDim); + double *ptToFill=ret->getPointer(); + const double *coor=_coords->begin(); + const int *nodal=_conn->begin(); + int sz=getNumberOfNodesPerCell(); + double coeff=1./(double)sz; + for(int i=0;i=0 && *nodal()); + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies(),coeff)); + } + return ret.retn(); +} + +void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ + int nbCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::New(); + o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1); + if(check) + o2n=o2n->checkAndPreparePermutation(); + // + const int *conn=_conn->begin(); + MEDCouplingAutoRefCountObjectPtr n2o=o2n->invertArrayO2N2N2O(nbCells); + const int *n2oPtr=n2o->begin(); + MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); + newConn->alloc(_conn->getNumberOfTuples(),1); + newConn->copyStringInfoFrom(*_conn); + int sz=getNumberOfNodesPerCell(); + // + int *newC=newConn->getPointer(); + for(int i=0;i cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1); + int tmp=-1; + int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1; + std::vector fastFinder(sz,false); + for(const int *work=begin;work!=end;work++) + if(*work>=0 && *workbegin(); + int nbNodesPerCell=getNumberOfNodesPerCell(); + for(int i=0;i=0) + { + ref++; + if(fastFinder[conn[j]]) + nbOfHit++; + } + if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn)) + cellIdsKept->pushBackSilent(i); + } + cellIdsKeptArr=cellIdsKept.retn(); +} + +MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const +{ + if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED) + throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !"); + const MEDCoupling1SGTUMesh *otherC=static_cast(other); + return Merge1SGTUMeshes(this,otherC); +} + +MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName(),getMeshDimension()); + ret->setCoords(getCoords()); + const int *nodalConn=_conn->begin(); + int nbCells=getNumberOfCells(); + int nbNodesPerCell=getNumberOfNodesPerCell(); + int geoType=(int)getCellModelEnum(); + MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1); + int *cPtr=c->getPointer(); + for(int i=0;i cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1); + ret->setConnectivity(c,cI,true); + return ret.retn(); +} + +DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception) +{ + switch(policy) + { + case 0: + return simplexizePol0(); + case 1: + return simplexizePol1(); + case (int) INTERP_KERNEL::PLANAR_FACE_5: + return simplexizePlanarFace5(); + case (int) INTERP_KERNEL::PLANAR_FACE_6: + return simplexizePlanarFace6(); + default: + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::simplexize : unrecognized policy ! Must be :\n - 0 or 1 (only available for meshdim=2) \n - PLANAR_FACE_5, PLANAR_FACE_6 (only for meshdim=3)"); + } +} + +/*! + * \return DataArrayInt * - the permutation array in "Old to New" mode. For more + * info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller + * is to delete this array using decrRef() as it is no more needed. + */ +DataArrayInt *MEDCoupling1SGTUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) +{ + DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); + if(areNodesMerged) + renumberNodes(ret->getConstPointer(),newNbOfNodes); + return ret; +} + +/*! + * \return DataArrayInt * - the permutation array in "Old to New" mode. For more + * info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller + * is to delete this array using decrRef() as it is no more needed. + */ +DataArrayInt *MEDCoupling1SGTUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) +{ + DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); + if(areNodesMerged) + renumberNodes2(ret->getConstPointer(),newNbOfNodes); + return ret; +} + +/*! + * Removes unused nodes (the node coordinates array is shorten) and returns an array + * mapping between new and old node ids in "Old to New" mode. -1 values in the returned + * array mean that the corresponding old node is no more used. + * \return DataArrayInt * - a new instance of DataArrayInt of length \a + * this->getNumberOfNodes() before call of this method. The caller is to + * delete this array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If the nodal connectivity includes an invalid id. + * + * \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".
+ * \ref py_mcumesh_zipCoordsTraducer "Here is a Python example". + */ +DataArrayInt *MEDCoupling1SGTUMesh::zipCoordsTraducer() throw(INTERP_KERNEL::Exception) +{ + int newNbOfNodes=-1; + DataArrayInt *traducer=getNodeIdsInUse(newNbOfNodes); + renumberNodes(traducer->getConstPointer(),newNbOfNodes); + return traducer; +} + +/// @cond INTERNAL + +struct MEDCouplingAccVisit +{ + MEDCouplingAccVisit():_new_nb_of_nodes(0) { } + int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; } + int _new_nb_of_nodes; +}; + +/// @endcond + +/*! + * Finds nodes not used in any cell and returns an array giving a new id to every node + * by excluding the unused nodes, for which the array holds -1. The result array is + * a mapping in "Old to New" mode. + * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity. + * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a + * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1 + * if the node is unused or a new id else. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If the nodal connectivity includes an invalid id. + */ +DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception) +{ + nbrOfNodesInUse=-1; + int nbOfNodes=getNumberOfNodes(); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(nbOfNodes,1); + int *traducer=ret->getPointer(); + std::fill(traducer,traducer+nbOfNodes,-1); + const int *conn=_conn->begin(); + int nbNodesPerCell=getNumberOfNodesPerCell(); + for(int i=0;i=0 && conn[j]getNumberOfNodes(), in "Old to New" mode. + * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes. + * \throw If the nodal connectivity of cells is not defined. + */ +void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N) +{ + getNumberOfCells();//only to check that all is well defined. + _conn->renumberInPlace(newNodeNumbersO2N); + updateTime(); +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception) +{ + std::vector tmp(2); + tmp[0]=const_cast(mesh1); tmp[1]=const_cast(mesh2); + return Merge1SGTUMeshes(tmp); +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector& a) throw(INTERP_KERNEL::Exception) +{ + std::size_t sz=a.size(); + if(sz==0) + return Merge1SGTUMeshesLL(a); + for(std::size_t ii=0;iigetCellModel()); + for(std::size_t ii=0;iigetCellModel())!=cm) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > bb(sz); + std::vector< const MEDCoupling1SGTUMesh * > aa(sz); + int spaceDim=-3; + for(std::size_t i=0;igetCoords(); + if(coo) + spaceDim=coo->getNumberOfComponents(); + } + if(spaceDim==-3) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !"); + for(std::size_t i=0;ibuildSetInstanceFromThis(spaceDim); + aa[i]=bb[i]; + } + return Merge1SGTUMeshesLL(aa); +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector& a) throw(INTERP_KERNEL::Exception) +{ + if(a.empty()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !"); + std::vector::const_iterator it=a.begin(); + if(!(*it)) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of null instance !"); + int nbOfCells=(*it)->getNumberOfCells(); + const DataArrayDouble *coords=(*it)->getCoords(); + const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); + int nbNodesPerCell=(*it)->getNumberOfNodesPerCell(); + for(;it!=a.end();it++) + { + if(cm!=&((*it)->getCellModel())) + throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !"); + nbOfCells+=(*it)->getNumberOfCells(); + if(coords!=(*it)->getCoords()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !"); + } + MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh("merge",*cm)); + ret->setCoords(coords); + MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); + c->alloc(nbOfCells*nbNodesPerCell,1); + int *cPtr=c->getPointer(); + int offset=0; + for(it=a.begin();it!=a.end();it++) + { + int curConnLgth=(*it)->getNodalConnectivityLength(); + const int *curC=(*it)->_conn->begin(); + cPtr=std::copy(curC,curC+curConnLgth,cPtr); + } + // + ret->_conn=c; + return ret.retn(); +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector& a) throw(INTERP_KERNEL::Exception) +{ + if(a.empty()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !"); + std::vector::const_iterator it=a.begin(); + int nbOfCells=(*it)->getNumberOfCells(); + const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); + int nbNodesPerCell=(*it)->getNumberOfNodesPerCell(); + for(;it!=a.end();it++) + { + if(cm!=&((*it)->getCellModel())) + throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !"); + nbOfCells+=(*it)->getNumberOfCells(); + } + std::vector aps(a.size()); + std::copy(a.begin(),a.end(),aps.begin()); + MEDCouplingAutoRefCountObjectPtr pts=MergeNodesArray(aps); + MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh("merge",*cm)); + ret->setCoords(pts); + MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); + c->alloc(nbOfCells*nbNodesPerCell,1); + int *cPtr=c->getPointer(); + int offset=0; + for(it=a.begin();it!=a.end();it++) + { + int curConnLgth=(*it)->getNodalConnectivityLength(); + const int *curC=(*it)->_conn->begin(); + cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus(),offset)); + offset+=(*it)->getNumberOfNodes(); + } + // + ret->_conn=c; + return ret.retn(); +} + +MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const +{ + int ncell=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh(getName(),*_cm)); + ret->setCoords(_coords); + std::size_t nbOfElemsRet=std::distance(begin,end); + const int *inConn=_conn->getConstPointer(); + int sz=getNumberOfNodesPerCell(); + MEDCouplingAutoRefCountObjectPtr connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1); + int *connPtr=connRet->getPointer(); + for(const int *work=begin;work!=end;work++,connPtr+=sz) + { + if(*work>=0 && *work_conn=connRet; + ret->copyTinyInfoFrom(this); + return ret.retn(); +} + +MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const +{ + int ncell=getNumberOfCells(); + int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : "); + MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh(getName(),*_cm)); + ret->setCoords(_coords); + const int *inConn=_conn->getConstPointer(); + int sz=getNumberOfNodesPerCell(); + MEDCouplingAutoRefCountObjectPtr connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1); + int *connPtr=connRet->getPointer(); + int curId=start; + for(int i=0;i=0 && curId_conn=connRet; + ret->copyTinyInfoFrom(this); + return ret.retn(); +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh(getName(),*_cm)); + MEDCouplingAutoRefCountObjectPtr tmp1; + const DataArrayInt *nodalConn(_conn); + if(!nodalConn) + { + tmp1=DataArrayInt::New(); tmp1->alloc(0,1); + } + else + { + tmp1=_conn; + tmp1->incrRef(); + } + ret->_conn=tmp1; + if(!_coords) + { + MEDCouplingAutoRefCountObjectPtr coords=DataArrayDouble::New(); coords->alloc(0,spaceDim); + ret->setCoords(coords); + } + else + ret->setCoords(_coords); + return ret.retn(); +} + +DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception) +{ + int nbOfCells=getNumberOfCells(); + if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4) + return DataArrayInt::Range(0,nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1); + const int *c(_conn->begin()); + int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); + for(int i=0;i newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1); + const int *c(_conn->begin()); + int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); + for(int i=0;i newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1); + const int *c(_conn->begin()); + int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); + for(int i=0;i newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1); + const int *c(_conn->begin()); + int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); + for(int i=0;iisAllocated()) + { stream << " Coordinates set but not allocated !"; return ; } + stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl; + stream << "Number of nodes : " << _coords->getNumberOfTuples() << "."; + if(!(const DataArrayInt *)_conn) + { stream << std::endl << "Nodal connectivity NOT set !"; return ; } + if(_conn->isAllocated()) + { + if(_conn->getNumberOfComponents()==1) + stream << std::endl << "Number of cells : " << getNumberOfCells() << "."; + } +} + +void MEDCoupling1SGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception) +{ + if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined."); +} + +/*! + * First step of unserialization process. + */ +bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector& tinyInfo) const +{ + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !"); +} + +/*! + * Checks if \a this and \a other meshes are geometrically equivalent with high + * probability, else an exception is thrown. The meshes are considered equivalent if + * (1) meshes contain the same number of nodes and the same number of elements of the + * same types (2) three cells of the two meshes (first, last and middle) are based + * on coincident nodes (with a specified precision). + * \param [in] other - the mesh to compare with. + * \param [in] prec - the precision used to compare nodes of the two meshes. + * \throw If the two meshes do not match. + */ +void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingPointSet::checkFastEquivalWith(other,prec); + const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not not unstructured with single static geometric type !"); +} + +MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !"); + const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !"); + std::vector ms(2); + ms[0]=this; + ms[1]=otherC; + return Merge1SGTUMeshesOnSameCoords(ms); +} + +void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception) +{ + checkFullyDefined(); + int nbOfNodes=getNumberOfNodes(); + int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int)); + revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1); + std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0); + const int *conn=_conn->begin(); + int nbOfCells=getNumberOfCells(); + int nbOfEltsInRevNodal=0; + int nbOfNodesPerCell=getNumberOfNodesPerCell(); + for(int eltId=0;eltId=0 && conn[0]()); + conn=_conn->begin(); + int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int)); + revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1); + std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1); + for(int eltId=0;eltId(),-1))=eltId; + } + } +} + +/*! + * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null. + * This method tests, if the input \a nodalConn is not null, that : + * - it has one component. + * - the number of tuples compatible with the number of node per cell. + */ +void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception) +{ + if(!nodalConn) + { + _conn=nodalConn; + return; + } + const DataArrayInt *c1(nodalConn); + if(c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::setNodalConnectivity : input nodal connectivity array set must have exactly one component !"); + if(!c1->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::setNodalConnectivity : input nodal connectivity array must be allocated !"); + int nbTuples=c1->getNumberOfTuples(); + if(nbTuples%getNumberOfNodesPerCell()!=0) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::setNodalConnectivity : input nodal connectivity number of tuples is incompatible with geometric type !"); + nodalConn->incrRef(); + _conn=nodalConn; + declareAsNew(); +} + +/*! + * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it. + */ +DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception) +{ + const DataArrayInt *ret(_conn); + return const_cast(ret); +} + +/*! + * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted, + * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter. + * If a nodal connectivity previouly existed before the call of this method, it will be reset. + * + * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain. + */ +void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception) +{ + if(nbOfCells<0) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !"); + _conn=DataArrayInt::New(); + _conn->reserve(getNumberOfNodesPerCell()*nbOfCells); + declareAsNew(); +} + +/*! + * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ). + * + * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add. + * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add. + * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type + * attached to \a this. + * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before). + */ +void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception) +{ + int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd); + int ref=getNumberOfNodesPerCell(); + if(sz==ref) + { + DataArrayInt *c(_conn); + if(c) + c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd); + else + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !"); + } + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this ("; + oss << ref << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } } diff --git a/src/MEDCoupling/MEDCoupling1GTUMesh.hxx b/src/MEDCoupling/MEDCoupling1GTUMesh.hxx index 097224934..947f3e16a 100644 --- a/src/MEDCoupling/MEDCoupling1GTUMesh.hxx +++ b/src/MEDCoupling/MEDCoupling1GTUMesh.hxx @@ -35,7 +35,7 @@ namespace ParaMEDMEM class MEDCoupling1GTUMesh : public MEDCouplingPointSet { public: - MEDCOUPLING_EXPORT static MEDCoupling1GTUMesh *New(const char *meshName, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static MEDCoupling1GTUMesh *New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT const INTERP_KERNEL::CellModel& getCellModel() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getCellModelEnum() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getMeshDimension() const; @@ -48,61 +48,93 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT std::string getVTKDataSetType() const throw(INTERP_KERNEL::Exception); + // + 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 checkCoherency() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; + MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; + MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const; + MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps); + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; + MEDCOUPLING_EXPORT DataArrayInt *findBoundaryNodes() const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; + MEDCOUPLING_EXPORT void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception); + protected: + MEDCOUPLING_EXPORT MEDCoupling1GTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm); + MEDCOUPLING_EXPORT MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy); protected: - const INTERP_KERNEL::CellModel& _cm; + const INTERP_KERNEL::CellModel *_cm; }; class MEDCoupling1SGTUMesh : public MEDCoupling1GTUMesh { public: - MEDCOUPLING_EXPORT static MEDCoupling1GTUMesh *New(); - MEDCOUPLING_EXPORT static MEDCoupling1GTUMesh *New(const char *meshName, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED; } + // overload of TimeLabel and RefCountObject MEDCOUPLING_EXPORT void updateTime() const; MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; + // overload of MEDCouplingMesh + MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED; } MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() 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); - MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception);//tony + MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void checkCoherency() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getNumberOfCells() const; - MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector& conn) const; MEDCOUPLING_EXPORT std::string simpleRepr() const; MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; - MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; + MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); - // + // overload of MEDCouplingPointSet + MEDCOUPLING_EXPORT void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const; MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(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=true) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const throw(INTERP_KERNEL::Exception); - 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; - MEDCOUPLING_EXPORT DataArrayInt *findBoundaryNodes() const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; - MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const; - MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps); - MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer(); + MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; + MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkFullyDefined() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector& tinyInfo) const; + MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N); + MEDCOUPLING_EXPORT void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; + public: + MEDCOUPLING_EXPORT int getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(std::vector& a) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *Merge1SGTUMeshesOnSameCoords(std::vector& a) throw(INTERP_KERNEL::Exception); + MEDCoupling1SGTUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); + public://specific + MEDCOUPLING_EXPORT void setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void allocateCells(int nbOfCells=0) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception); + private: + MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm); + MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy); + private: + void checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception); + static MEDCoupling1SGTUMesh *Merge1SGTUMeshesLL(std::vector& a) throw(INTERP_KERNEL::Exception); + DataArrayInt *simplexizePol0() throw(INTERP_KERNEL::Exception); + DataArrayInt *simplexizePol1() throw(INTERP_KERNEL::Exception); + DataArrayInt *simplexizePlanarFace5() throw(INTERP_KERNEL::Exception); + DataArrayInt *simplexizePlanarFace6() throw(INTERP_KERNEL::Exception); private: MEDCouplingAutoRefCountObjectPtr _conn; }; diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index b31721747..798b8f2bb 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -2175,7 +2175,7 @@ bool MEDCouplingFieldDouble::zipCoords(double epsOnVals) throw(INTERP_KERNEL::Ex * duplicates are removed.
* \param [in] compType - specifies a cell comparison technique. Meaning of its * valid values [0,1,2] is explained in the description of - * MEDCouplingUMesh::zipConnectivityTraducer() which is called by this method. + * MEDCouplingPointSet::zipConnectivityTraducer() which is called by this method. * \param [in] epsOnVals - a precision used to compare field * values at merged cells. If the values differ more than \a epsOnVals, an * exception is thrown. diff --git a/src/MEDCoupling/MEDCouplingMesh.cxx b/src/MEDCoupling/MEDCouplingMesh.cxx index 95d450a9c..3408e9e22 100644 --- a/src/MEDCoupling/MEDCouplingMesh.cxx +++ b/src/MEDCoupling/MEDCouplingMesh.cxx @@ -226,6 +226,8 @@ DataArrayInt *MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds(const int *partB */ void MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingMesh::checkFastEquivalWith : input mesh is null !"); if(getMeshDimension()!=other->getMeshDimension()) throw INTERP_KERNEL::Exception("checkFastEquivalWith : Mesh dimensions are not equal !"); if(getSpaceDimension()!=other->getSpaceDimension()) @@ -239,6 +241,8 @@ void MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double */ bool MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingMesh::areCompatibleForMerge : input mesh is null !"); if(getMeshDimension()!=other->getMeshDimension()) return false; if(getSpaceDimension()!=other->getSpaceDimension()) @@ -299,6 +303,8 @@ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbO */ void MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingMesh::copyTinyStringsFrom : input mesh is null !"); _name=other->_name; _description=other->_description; _time_unit=other->_time_unit; diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index 4cb2fd3c0..808ce986c 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -369,12 +369,20 @@ DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm->begin(),commIndex->begin(),commIndex->end(),newNbOfNodes); } -/* - * This method renumber 'this' using 'newNodeNumbers' array of size this->getNumberOfNodes. - * newNbOfNodes specifies the *std::max_element(newNodeNumbers,newNodeNumbers+this->getNumberOfNodes()) - * This value is asked because often known by the caller of this method. - * @param newNodeNumbers array specifying the new numbering in old2New convention.. - * @param newNbOfNodes the new number of nodes. +/*! + * Permutes and possibly removes nodes as specified by \a newNodeNumbers array. + * If \a newNodeNumbers[ i ] < 0 then the i-th node is removed, + * else \a newNodeNumbers[ i ] is a new id of the i-th node. The nodal connectivity + * array is modified accordingly. + * \param [in] newNodeNumbers - a permutation array, of length \a + * this->getNumberOfNodes(), in "Old to New" mode. + * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes. + * \param [in] newNbOfNodes - number of nodes remaining after renumbering. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * + * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".
+ * \ref py_mcumesh_renumberNodes "Here is a Python example". */ void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNodes) { @@ -382,16 +390,25 @@ void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNo throw INTERP_KERNEL::Exception("MEDCouplingPointSet::renumberNodes : no coords specified !"); MEDCouplingAutoRefCountObjectPtr newCoords=_coords->renumberAndReduce(newNodeNumbers,newNbOfNodes); setCoords(newCoords); + renumberNodesInConn(newNodeNumbers); } -/* - * This method renumber 'this' using 'newNodeNumbers' array of size this->getNumberOfNodes. - * newNbOfNodes specifies the *std::max_element(newNodeNumbers,newNodeNumbers+this->getNumberOfNodes()) - * This value is asked because often known by the caller of this method. - * Contrary to ParaMEDMEM::MEDCouplingPointSet::renumberNodes method for merged nodes the barycenter of them is computed here. +/*! + * Permutes and possibly removes nodes as specified by \a newNodeNumbers array. + * If \a newNodeNumbers[ i ] < 0 then the i-th node is removed, + * else \a newNodeNumbers[ i ] is a new id of the i-th node. The nodal connectivity + * array is modified accordingly. In contrast to renumberNodes(), location + * of merged nodes (whose new ids coincide) is changed to be at their barycenter. + * \param [in] newNodeNumbers - a permutation array, of length \a + * this->getNumberOfNodes(), in "Old to New" mode. + * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes. + * \param [in] newNbOfNodes - number of nodes remaining after renumbering, which is + * actually one more than the maximal id in \a newNodeNumbers. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. * - * @param newNodeNumbers array specifying the new numbering. - * @param newNbOfNodes the new number of nodes. + * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".
+ * \ref py_mcumesh_renumberNodes "Here is a Python example". */ void MEDCouplingPointSet::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes) { @@ -414,6 +431,7 @@ void MEDCouplingPointSet::renumberNodes2(const int *newNodeNumbers, int newNbOfN ptToFill=std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies(),1./(double)div[i])); setCoords(newCoords); newCoords->decrRef(); + renumberNodesInConn(newNodeNumbers); } /*! @@ -1171,3 +1189,279 @@ bool MEDCouplingPointSet::isButterfly2DCell(const std::vector& res, bool delete pol; return ret; } + +/*! + * This method compares 2 cells coming from two unstructured meshes : \a this and \a other. + * This method compares 2 cells having the same id 'cellId' in \a this and \a other. + */ +bool MEDCouplingPointSet::areCellsFrom2MeshEqual(const MEDCouplingPointSet *other, int cellId, double prec) const +{ + if(getTypeOfCell(cellId)!=other->getTypeOfCell(cellId)) + return false; + std::vector c1,c2; + getNodeIdsOfCell(cellId,c1); + other->getNodeIdsOfCell(cellId,c2); + std::size_t sz=c1.size(); + if(sz!=c2.size()) + return false; + for(std::size_t i=0;i n1,n2; + 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.begin(),std::ptr_fun(fabs)); + if(*std::max_element(n1.begin(),n1.end())>prec) + return false; + } + return true; +} + +/*! + * Substitutes node coordinates array of \a this mesh with that of \a other mesh + * (i.e. \a this->_coords with \a other._coords) provided that coordinates of the two + * meshes match with a specified precision, else an exception is thrown and \a this + * remains unchanged. In case of success the nodal connectivity of \a this mesh + * is permuted according to new order of nodes. + * Contrary to tryToShareSameCoords() this method makes a deeper analysis of + * coordinates (and so more expensive) than simple equality. + * \param [in] other - the other mesh whose node coordinates array will be used by + * \a this mesh in case of their equality. + * \param [in] epsilon - the precision used to compare coordinates (using infinite norm). + * \throw If the coordinates array of \a this is not set. + * \throw If the coordinates array of \a other is not set. + * \throw If the coordinates of \a this and \a other do not match. + */ +void MEDCouplingPointSet::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) +{ + const DataArrayDouble *coords=other.getCoords(); + if(!coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute : No coords specified in other !"); + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute : No coords specified in this whereas there is any in other !"); + int otherNbOfNodes=other.getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr newCoords=MergeNodesArray(&other,this); + _coords->incrRef(); + MEDCouplingAutoRefCountObjectPtr oldCoords=_coords; + setCoords(newCoords); + bool areNodesMerged; + int newNbOfNodes; + MEDCouplingAutoRefCountObjectPtr da=buildPermArrayForMergeNode(epsilon,otherNbOfNodes,areNodesMerged,newNbOfNodes); + if(!areNodesMerged) + { + setCoords(oldCoords); + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::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("MEDCouplingPointSet::tryToShareSameCoordsPermute fails : some nodes in this are not in other !"); + } + setCoords(oldCoords); + renumberNodesInConn(da->getConstPointer()+otherNbOfNodes); + setCoords(coords); +} + +MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const +{ + MEDCouplingAutoRefCountObjectPtr ret=buildPartOfMySelfKeepCoords(begin,end); + if(!keepCoords) + ret->zipCoords(); + return ret.retn(); +} + +MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=buildPartOfMySelfKeepCoords2(start,end,step); + if(!keepCoords) + ret->zipCoords(); + return ret.retn(); +} + +/*! + Creates a new MEDCouplingUMesh containing some cells of \a this mesh. The cells to + copy are selected basing on specified node ids and the value of \a fullyIn + parameter. If \a fullyIn ==\c true, a cell is copied if its all nodes are in the + array \a begin of node ids. If \a fullyIn ==\c false, a cell is copied if any its + node is in the array of node ids. The created mesh shares the node coordinates array + with \a this mesh. + * \param [in] begin - the array of node ids. + * \param [in] end - a pointer to the (last+1)-th element of \a begin. + * \param [in] fullyIn - if \c true, then cells whose all nodes are in the + * array \a begin are copied, else cells whose any node is in the + * array \a begin are copied. + * \return MEDCouplingPointSet * - new instance of MEDCouplingUMesh. The caller is + * to delete this mesh using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If any node id in \a begin is not valid. + * + * \ref cpp_mcumesh_buildPartOfMySelfNode "Here is a C++ example".
+ * \ref py_mcumesh_buildPartOfMySelfNode "Here is a Python example". + */ +MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const +{ + DataArrayInt *cellIdsKept=0; + fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept); + MEDCouplingAutoRefCountObjectPtr cellIdsKept2(cellIdsKept); + return buildPartOfMySelf(cellIdsKept->begin(),cellIdsKept->end(),true); +} + +/*! + * Removes duplicates of cells from \a this mesh and returns an array mapping between + * new and old cell ids in "Old to New" mode. Nothing is changed in \a this mesh if no + * equal cells found. + * \warning Cells of the result mesh are \b not sorted by geometric type, hence, + * to write this mesh to the MED file, its cells must be sorted using + * sortCellsInMEDFileFrmt(). + * \param [in] compType - specifies a cell comparison technique. Meaning of its + * valid values [0,1,2] is as follows. + * - 0 : "exact". Two cells are considered equal \c iff they have exactly same nodal + * connectivity and type. This is the strongest policy. + * - 1 : "permuted same orientation". Two cells are considered equal \c iff they + * are based on same nodes and have the same type and orientation. + * - 2 : "nodal". Two cells are considered equal \c iff they + * are based on same nodes and have the same type. This is the weakest + * policy, it can be used by users not sensitive to cell orientation. + * \param [in] startCellId - specifies the cell id at which search for equal cells + * starts. By default it is 0, which means that all cells in \a this will be + * scanned. + * \return DataArrayInt - a new instance of DataArrayInt, of length \a + * this->getNumberOfCells() before call of this method. The caller is to + * delete this array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If the nodal connectivity includes an invalid id. + * + * \ref cpp_mcumesh_zipConnectivityTraducer "Here is a C++ example".
+ * \ref py_mcumesh_zipConnectivityTraducer "Here is a Python example". + */ +DataArrayInt *MEDCouplingPointSet::zipConnectivityTraducer(int compType, int startCellId) throw(INTERP_KERNEL::Exception) +{ + DataArrayInt *commonCells=0,*commonCellsI=0; + findCommonCells(compType,startCellId,commonCells,commonCellsI); + MEDCouplingAutoRefCountObjectPtr commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); + int newNbOfCells=-1; + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfCells(),commonCells->begin(),commonCellsI->begin(), + commonCellsI->end(),newNbOfCells); + MEDCouplingAutoRefCountObjectPtr ret2=ret->invertArrayO2N2N2O(newNbOfCells); + MEDCouplingAutoRefCountObjectPtr self=buildPartOfMySelf(ret2->begin(),ret2->end(),true); + shallowCopyConnectivityFrom(self); + return ret.retn(); +} + +/*! + * Checks if \a this and \a other meshes are geometrically equivalent, else an + * exception is thrown. The meshes are + * considered equivalent if (1) \a this mesh contains the same nodes as the \a other + * mesh (with a specified precision) and (2) \a this mesh contains the same cells as + * the \a other mesh (with use of a specified cell comparison technique). The mapping + * from \a other to \a this for nodes and cells is returned via out parameters. + * \param [in] other - the mesh to compare with. + * \param [in] cellCompPol - id [0-2] of cell comparison method. See meaning of + * each method in description of MEDCouplingPointSet::zipConnectivityTraducer(). + * \param [in] prec - the precision used to compare nodes of the two meshes. + * \param [out] cellCor - a cell permutation array in "Old to New" mode. The caller is + * to delete this array using decrRef() as it is no more needed. + * \param [out] nodeCor - a node permutation array in "Old to New" mode. The caller is + * to delete this array using decrRef() as it is no more needed. + * \throw If the two meshes do not match. + * + * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
+ * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". + */ +void MEDCouplingPointSet::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalWith : input is null !"); + const MEDCouplingPointSet *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalWith : other is not a PointSet mesh !"); + MEDCouplingAutoRefCountObjectPtr m=dynamic_cast(mergeMyselfWith(otherC)); + bool areNodesMerged; + int newNbOfNodes; + int oldNbOfNodes=getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr da=m->buildPermArrayForMergeNode(prec,oldNbOfNodes,areNodesMerged,newNbOfNodes); + //mergeNodes + if(!areNodesMerged) + throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Nodes are incompatible ! "); + 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 !"); + m->renumberNodes(da->getConstPointer(),newNbOfNodes); + // + MEDCouplingAutoRefCountObjectPtr nodeCor2=da->substr(oldNbOfNodes); + da=m->mergeNodes(prec,areNodesMerged,newNbOfNodes); + // + da=m->zipConnectivityTraducer(cellCompPol); + int nbCells=getNumberOfCells(); + int maxId=-1; + if(nbCells!=0) + maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+nbCells); + pt=std::find_if(da->getConstPointer()+nbCells,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); + if(pt!=da->getConstPointer()+da->getNbOfElems()) + throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !"); + MEDCouplingAutoRefCountObjectPtr cellCor2=da->selectByTupleId2(nbCells,da->getNbOfElems(),1); + nodeCor=nodeCor2->isIdentity()?0:nodeCor2.retn(); + cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); +} + +/*! + * Checks if \a this and \a other meshes are geometrically equivalent, else an + * exception is thrown. The meshes are considered equivalent if (1) they share one + * node coordinates array and (2) they contain the same cells (with use of a specified + * cell comparison technique). The mapping from cells of the \a other to ones of \a this + * is returned via an out parameter. + * \param [in] other - the mesh to compare with. + * \param [in] cellCompPol - id [0-2] of cell comparison method. See the meaning of + * each method in description of MEDCouplingPointSet::zipConnectivityTraducer(). + * \param [in] prec - a not used parameter. + * \param [out] cellCor - the permutation array in "Old to New" mode. The caller is + * to delete this array using decrRef() as it is no more needed. + * \throw If the two meshes do not match. + * + * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
+ * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". + */ +void MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith : input is null !"); + const MEDCouplingPointSet *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith : other is not a PointSet mesh !"); + if(_coords!=otherC->_coords) + throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : meshes do not share the same coordinates ! Use tryToShareSameCoordinates or call checkDeepEquivalWith !"); + MEDCouplingAutoRefCountObjectPtr m=mergeMyselfWithOnSameCoords(otherC); + MEDCouplingAutoRefCountObjectPtr da=m->zipConnectivityTraducer(cellCompPol); + int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells()); + const int *pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); + if(pt!=da->getConstPointer()+da->getNbOfElems()) + { + throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : some cells in other are not in this !"); + } + MEDCouplingAutoRefCountObjectPtr cellCor2=da->selectByTupleId2(getNumberOfCells(),da->getNbOfElems(),1); + cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); +} + +void MEDCouplingPointSet::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingMesh::checkFastEquivalWith(other,prec); + //other not null checked by the line before + const MEDCouplingPointSet *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkFastEquivalWith : fails because other is not a pointset mesh !"); + int nbOfCells=getNumberOfCells(); + if(nbOfCells<1) + return ; + bool status=true; + status&=areCellsFrom2MeshEqual(otherC,0,prec); + status&=areCellsFrom2MeshEqual(otherC,nbOfCells/2,prec); + status&=areCellsFrom2MeshEqual(otherC,nbOfCells-1,prec); + if(!status) + throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not equal because on 3 test cells some difference have been detected !"); +} diff --git a/src/MEDCoupling/MEDCouplingPointSet.hxx b/src/MEDCoupling/MEDCouplingPointSet.hxx index e0ef76118..c7cec31ad 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.hxx +++ b/src/MEDCoupling/MEDCouplingPointSet.hxx @@ -62,16 +62,24 @@ namespace ParaMEDMEM void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); + void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception); + void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception); 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 void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception) = 0; virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0; virtual DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0; + virtual MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const = 0; void getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception); DataArrayInt *buildPermArrayForMergeNode(double precision, int limitNodeId, bool& areNodesMerged, int& newNbOfNodes) const; DataArrayInt *getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception); void getNodeIdsNearPoints(const double *pos, int nbOfPoints, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception); void findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const; + virtual void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception) = 0; DataArrayInt *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex, int& newNbOfNodes) const; void getBoundingBox(double *bbox) const throw(INTERP_KERNEL::Exception); @@ -84,7 +92,7 @@ namespace ParaMEDMEM void changeSpaceDimension(int newSpaceDim, double dftVal=0.) throw(INTERP_KERNEL::Exception); void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); void duplicateNodesInCoords(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd) throw(INTERP_KERNEL::Exception); - virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) = 0; + virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); void findNodesOnPlane(const double *pt, const double *vec, double eps, std::vector& nodes) const throw(INTERP_KERNEL::Exception); void findNodesOnLine(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) throw(INTERP_KERNEL::Exception); @@ -96,15 +104,21 @@ namespace ParaMEDMEM MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception); MEDCouplingMesh *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords=true) const = 0; - virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const throw(INTERP_KERNEL::Exception) = 0; - virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0; + virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords=true) const; + virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const = 0; + virtual MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const = 0; + virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; virtual MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0; virtual DataArrayInt *findBoundaryNodes() const = 0; virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const = 0; + virtual DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception) = 0; + virtual void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const = 0; + virtual void renumberNodesInConn(const int *newNodeNumbersO2N) = 0; virtual void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); virtual void renumberNodes2(const int *newNodeNumbers, int newNbOfNodes); virtual bool isEmptyMesh(const std::vector& tinyInfo) const = 0; + virtual void checkFullyDefined() const throw(INTERP_KERNEL::Exception) = 0; void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; @@ -112,10 +126,14 @@ namespace ParaMEDMEM const std::vector& littleStrings); virtual DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const = 0; virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) = 0; - virtual DataArrayInt *zipCoordsTraducer() = 0; + virtual DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception) = 0; + virtual DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception); + virtual void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception) = 0; + //tools + public: + MEDCOUPLING_EXPORT bool areCellsFrom2MeshEqual(const MEDCouplingPointSet *other, int cellId, double prec) const; protected: void checkCoherency() const throw(INTERP_KERNEL::Exception); - virtual void checkFullyDefined() const throw(INTERP_KERNEL::Exception) = 0; static bool intersectsBoundingBox(const double* bb1, const double* bb2, int dim, double eps); static bool intersectsBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bb1, const double* bb2, int dim, double eps); void rotate2D(const double *center, double angle); diff --git a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx index 407f956dc..efb9cddf3 100644 --- a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx +++ b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx @@ -161,46 +161,91 @@ std::vector MEDCouplingStructuredMesh::getDistributionOfTypes() const throw } /*! + * This method tries to minimize at most the number of deep copy. + * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return. + * * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information */ DataArrayInt *MEDCouplingStructuredMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) { - if(code.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code is empty, should not !"); - std::size_t sz=code.size(); - if(sz!=3) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code should be of size 3 exactly !"); - - int nbCells=getNumberOfCellsWithType((INTERP_KERNEL::NormalizedCellType)code[0]); + int nbOfCells=getNumberOfCells(); + if(code.size()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !"); + if(code[0]!=(int)getTypeOfCell(0)) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getTypeOfCell(0) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } if(code[2]==-1) { - if(code[1]==nbCells) + if(code[1]==nbOfCells) return 0; else - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : number of cells mismatch !"); - } - else - { - if(code[2]<-1) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code[2]<-1 mismatch !"); - if(code[2]>=(int)idsPerType.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code[2]>size idsPerType !"); - return idsPerType[code[2]]->deepCpy(); + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } } + if(code[2]!=0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !"); + if(idsPerType.size()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !"); + const DataArrayInt *pfl=idsPerType[0]; + if(!pfl) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !"); + if(pfl->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !"); + pfl->checkAllIdsInRange(0,nbOfCells); + pfl->incrRef(); + return const_cast(pfl); } /*! - * See MEDCouplingUMesh::splitProfilePerType for more information + * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type. + * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType. + * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType. + * + * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method. + * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i, + * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0] + * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type. + * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile. + * + * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType. + * + * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined + * + * \b Example1:
+ * - Before \a this has 3 cells \a profile contains [0,1,2] + * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty
+ * + * \b Example2:
+ * - Before \a this has 3 cells \a profile contains [1,2] + * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]]
+ */ void MEDCouplingStructuredMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) { - int nbCells=getNumberOfCells(); - code.resize(3); - code[0]=(int)getTypeOfCell(0); - code[1]=nbCells; + if(!profile) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::splitProfilePerType : input profile is NULL !"); + if(profile->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::splitProfilePerType : input profile should have exactly one component !"); + int nbTuples=profile->getNumberOfTuples(); + int nbOfCells=getNumberOfCells(); + code.resize(3); idsInPflPerType.resize(1); + code[0]=(int)getTypeOfCell(0); code[1]=nbOfCells; + idsInPflPerType.resize(1); + if(profile->isIdentity() && nbTuples==nbOfCells) + { + code[2]=-1; + idsInPflPerType[0]=const_cast(profile); idsInPflPerType[0]->incrRef(); + idsPerType.clear(); + } code[2]=0; - idsInPflPerType.push_back(profile->deepCpy()); - idsPerType.push_back(profile->deepCpy()); + profile->checkAllIdsInRange(0,nbOfCells); + idsPerType.resize(1); + idsPerType[0]=const_cast(profile); idsPerType[0]->incrRef(); + idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1); } /*! diff --git a/src/MEDCoupling/MEDCouplingTimeLabel.cxx b/src/MEDCoupling/MEDCouplingTimeLabel.cxx index 85c1d33f0..7026c3f11 100644 --- a/src/MEDCoupling/MEDCouplingTimeLabel.cxx +++ b/src/MEDCoupling/MEDCouplingTimeLabel.cxx @@ -22,7 +22,7 @@ using namespace ParaMEDMEM; -unsigned int TimeLabel::GLOBAL_TIME=0; +std::size_t TimeLabel::GLOBAL_TIME=0; TimeLabel::TimeLabel():_time(GLOBAL_TIME++) { diff --git a/src/MEDCoupling/MEDCouplingTimeLabel.hxx b/src/MEDCoupling/MEDCouplingTimeLabel.hxx index 2feefde9c..8dc2f693d 100644 --- a/src/MEDCoupling/MEDCouplingTimeLabel.hxx +++ b/src/MEDCoupling/MEDCouplingTimeLabel.hxx @@ -23,6 +23,8 @@ #include "MEDCoupling.hxx" +#include + namespace ParaMEDMEM { /*! @@ -37,15 +39,15 @@ namespace ParaMEDMEM void declareAsNew() const; //! This method should be called on high level classes as Field or Mesh to take into acount modifications done in aggregates objects. virtual void updateTime() const = 0; - unsigned int getTimeOfThis() const { return _time; } + std::size_t getTimeOfThis() const { return _time; } protected: TimeLabel(); virtual ~TimeLabel(); void updateTimeWith(const TimeLabel& other) const; void forceTimeOfThis(const TimeLabel& other) const; private: - static unsigned int GLOBAL_TIME; - mutable unsigned int _time; + static std::size_t GLOBAL_TIME; + mutable std::size_t _time; }; } diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 9a5f21200..ce9038fc8 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -19,6 +19,7 @@ // Author : Anthony Geay (CEA/DEN) #include "MEDCouplingUMesh.hxx" +#include "MEDCoupling1GTUMesh.hxx" #include "MEDCouplingMemArray.txx" #include "MEDCouplingFieldDouble.hxx" #include "CellModel.hxx" @@ -88,6 +89,17 @@ MEDCouplingUMesh *MEDCouplingUMesh::clone(bool recDeepCpy) const return new MEDCouplingUMesh(*this,recDeepCpy); } +void MEDCouplingUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::shallowCopyConnectivityFrom : input pointer is null !"); + const MEDCouplingUMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCouplingUMesh instance !"); + MEDCouplingUMesh *otherC2=const_cast(otherC);//sorry :( + setConnectivity(otherC2->getNodalConnectivity(),otherC2->getNodalConnectivityIndex(),true); +} + std::size_t MEDCouplingUMesh::getHeapMemorySize() const { std::size_t ret=0; @@ -150,6 +162,9 @@ void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) if(_nodal_connec->getInfoOnComponent(0)!="") throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !"); } + else + if(_mesh_dim!=-1) + throw INTERP_KERNEL::Exception("Nodal connectivity array is not defined !"); if(_nodal_connec_index) { if(_nodal_connec_index->getNumberOfComponents()!=1) @@ -157,6 +172,9 @@ void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) if(_nodal_connec_index->getInfoOnComponent(0)!="") throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !"); } + else + if(_mesh_dim!=-1) + throw INTERP_KERNEL::Exception("Nodal connectivity index array is not defined !"); } /*! @@ -268,14 +286,19 @@ void MEDCouplingUMesh::setMeshDimension(int meshDim) } /*! - * Allocates memory to store given number of cells. - * \param [in] nbOfCells - number of cell \a this mesh will contain. + * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted, + * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter. + * If a nodal connectivity previouly existed before the call of this method, it will be reset. + * + * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain. * * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
* \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". */ void MEDCouplingUMesh::allocateCells(int nbOfCells) { + if(nbOfCells<0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::allocateCells : the input number of cells should be >= 0 !"); if(_nodal_connec_index) { _nodal_connec_index->decrRef(); @@ -475,108 +498,6 @@ bool MEDCouplingUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other return true; } -/*! - * Checks if \a this and \a other meshes are geometrically equivalent, else an - * exception is thrown. The meshes are - * considered equivalent if (1) \a this mesh contains the same nodes as the \a other - * mesh (with a specified precision) and (2) \a this mesh contains the same cells as - * the \a other mesh (with use of a specified cell comparison technique). The mapping - * from \a other to \a this for nodes and cells is returned via out parameters. - * \param [in] other - the mesh to compare with. - * \param [in] cellCompPol - id [0-2] of cell comparison method. See meaning of - * each method in description of MEDCouplingUMesh::zipConnectivityTraducer(). - * \param [in] prec - the precision used to compare nodes of the two meshes. - * \param [out] cellCor - a cell permutation array in "Old to New" mode. The caller is - * to delete this array using decrRef() as it is no more needed. - * \param [out] nodeCor - a node permutation array in "Old to New" mode. The caller is - * to delete this array using decrRef() as it is no more needed. - * \throw If the two meshes do not match. - * - * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
- * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". - */ -void MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) -{ - const MEDCouplingUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Two meshes are not not unstructured !"); - MEDCouplingMesh::checkFastEquivalWith(other,prec); - if(_types!=otherC->_types) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Types are not equal !"); - MEDCouplingAutoRefCountObjectPtr m=MergeUMeshes(this,otherC); - bool areNodesMerged; - int newNbOfNodes; - int oldNbOfNodes=getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr da=m->buildPermArrayForMergeNode(prec,oldNbOfNodes,areNodesMerged,newNbOfNodes); - //mergeNodes - if(!areNodesMerged) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Nodes are incompatible ! "); - 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 !"); - m->renumberNodes(da->getConstPointer(),newNbOfNodes); - // - MEDCouplingAutoRefCountObjectPtr nodeCor2=da->substr(oldNbOfNodes); - da=m->mergeNodes(prec,areNodesMerged,newNbOfNodes); - - // - da=m->zipConnectivityTraducer(cellCompPol); - int nbCells=getNumberOfCells(); - int maxId=-1; - if(nbCells!=0) - maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+nbCells); - pt=std::find_if(da->getConstPointer()+nbCells,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); - if(pt!=da->getConstPointer()+da->getNbOfElems()) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !"); - MEDCouplingAutoRefCountObjectPtr cellCor2=da->selectByTupleId2(nbCells,da->getNbOfElems(),1); - nodeCor=nodeCor2->isIdentity()?0:nodeCor2.retn(); - cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); -} - -/*! - * Checks if \a this and \a other meshes are geometrically equivalent, else an - * exception is thrown. The meshes are considered equivalent if (1) they share one - * node coordinates array and (2) they contain the same cells (with use of a specified - * cell comparison technique). The mapping from cells of the \a other to ones of \a this - * is returned via an out parameter. - * \param [in] other - the mesh to compare with. - * \param [in] cellCompPol - id [0-2] of cell comparison method. See the meaning of - * each method in description of MEDCouplingUMesh::zipConnectivityTraducer(). - * \param [in] prec - a not used parameter. - * \param [out] cellCor - the permutation array in "Old to New" mode. The caller is - * to delete this array using decrRef() as it is no more needed. - * \throw If the two meshes do not match. - * - * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
- * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". - */ -void MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) -{ - const MEDCouplingUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : Two meshes are not not unstructured !"); - MEDCouplingMesh::checkFastEquivalWith(other,prec); - if(_types!=otherC->_types) - throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : Types are not equal !"); - if(_coords!=otherC->_coords) - throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : meshes do not share the same coordinates ! Use tryToShareSameCoordinates or call checkDeepEquivalWith !"); - std::vector ms(2); - ms[0]=this; - ms[1]=otherC; - MEDCouplingAutoRefCountObjectPtr m=MergeUMeshesOnSameCoords(ms); - MEDCouplingAutoRefCountObjectPtr da=m->zipConnectivityTraducer(cellCompPol); - int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells()); - const int *pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); - if(pt!=da->getConstPointer()+da->getNbOfElems()) - { - throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : some cells in other are not in this !"); - } - MEDCouplingAutoRefCountObjectPtr cellCor2=da->selectByTupleId2(getNumberOfCells(),da->getNbOfElems(),1); - cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); -} - /*! * Checks if \a this and \a other meshes are geometrically equivalent with high * probability, else an exception is thrown. The meshes are considered equivalent if @@ -589,19 +510,10 @@ void MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *ot */ void MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) { - const MEDCouplingUMesh *otherC=dynamic_cast(other); + MEDCouplingPointSet::checkFastEquivalWith(other,prec); + const MEDCouplingUMesh *otherC=dynamic_cast(other); if(!otherC) - throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not not unstructured !"); - MEDCouplingPointSet::checkFastEquivalWith(other,prec); - int nbOfCells=getNumberOfCells(); - if(nbOfCells<1) - return ; - bool status=true; - status&=areCellsFrom2MeshEqual(otherC,0,prec); - status&=areCellsFrom2MeshEqual(otherC,nbOfCells/2,prec); - status&=areCellsFrom2MeshEqual(otherC,nbOfCells-1,prec); - if(!status) - throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not equal because on 3 test cells some difference have been detected !"); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkFastEquivalWith : Two meshes are not not unstructured !"); } /*! @@ -1530,7 +1442,7 @@ DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer() throw(INTERP_KERNEL::Excepti /*! * This method stands if 'cell1' and 'cell2' are equals regarding 'compType' policy. - * The semantic of 'compType' is specified in MEDCouplingUMesh::zipConnectivityTraducer method. + * The semantic of 'compType' is specified in MEDCouplingPointSet::zipConnectivityTraducer method. */ int MEDCouplingUMesh::AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType) { @@ -1551,7 +1463,7 @@ int MEDCouplingUMesh::AreCellsEqual(const int *conn, const int *connI, int cell1 } /*! - * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 0. + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 0. */ int MEDCouplingUMesh::AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2) { @@ -1561,7 +1473,7 @@ int MEDCouplingUMesh::AreCellsEqual0(const int *conn, const int *connI, int cell } /*! - * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 1. + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 1. */ int MEDCouplingUMesh::AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2) { @@ -1594,7 +1506,7 @@ int MEDCouplingUMesh::AreCellsEqual1(const int *conn, const int *connI, int cell } /*! - * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 2. + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 2. */ int MEDCouplingUMesh::AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2) { @@ -1625,7 +1537,7 @@ int MEDCouplingUMesh::AreCellsEqual3(const int *conn, const int *connI, int cell } /*! - * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 7. + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 7. */ int MEDCouplingUMesh::AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2) { @@ -1686,39 +1598,11 @@ int MEDCouplingUMesh::AreCellsEqual7(const int *conn, const int *connI, int cell return 0; } - -/*! - * This method compares 2 cells coming from two unstructured meshes : \a this and \a other. - * This method compares 2 cells having the same id 'cellId' in \a this and \a other. - */ -bool MEDCouplingUMesh::areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int cellId, double prec) const -{ - if(getTypeOfCell(cellId)!=other->getTypeOfCell(cellId)) - return false; - std::vector c1,c2; - getNodeIdsOfCell(cellId,c1); - other->getNodeIdsOfCell(cellId,c2); - std::size_t sz=c1.size(); - if(sz!=c2.size()) - return false; - for(std::size_t i=0;i n1,n2; - 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.begin(),std::ptr_fun(fabs)); - if(*std::max_element(n1.begin(),n1.end())>prec) - return false; - } - return true; -} - /*! * This method find in candidate pool defined by 'candidates' the cells equal following the polycy 'compType'. * If any true is returned and the results will be put at the end of 'result' output parameter. If not false is returned * and result remains unchanged. - * The semantic of 'compType' is specified in MEDCouplingUMesh::zipConnectivityTraducer method. + * The semantic of 'compType' is specified in MEDCouplingPointSet::zipConnectivityTraducer method. * If in 'candidates' pool -1 value is considered as an empty value. * WARNING this method returns only ONE set of result ! */ @@ -1766,7 +1650,6 @@ bool MEDCouplingUMesh::AreCellsEqualInPool(const std::vector& candidates, i */ void MEDCouplingUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception) { - checkConnectivityFullyDefined(); MEDCouplingAutoRefCountObjectPtr revNodal=DataArrayInt::New(),revNodalI=DataArrayInt::New(); getReverseNodalConnectivity(revNodal,revNodalI); FindCommonCellsAlg(compType,startCellId,_nodal_connec,_nodal_connec_index,revNodal,revNodalI,commonCellsArr,commonCellsIArr); @@ -1853,49 +1736,6 @@ void MEDCouplingUMesh::FindCommonCellsAlg(int compType, int startCellId, const D commonCellsIArr=commonCellsI.retn(); } -/*! - * Removes duplicates of cells from \a this mesh and returns an array mapping between - * new and old cell ids in "Old to New" mode. Nothing is changed in \a this mesh if no - * equal cells found. - * \warning Cells of the result mesh are \b not sorted by geometric type, hence, - * to write this mesh to the MED file, its cells must be sorted using - * sortCellsInMEDFileFrmt(). - * \param [in] compType - specifies a cell comparison technique. Meaning of its - * valid values [0,1,2] is as follows. - * - 0 : "exact". Two cells are considered equal \c iff they have exactly same nodal - * connectivity and type. This is the strongest policy. - * - 1 : "permuted same orientation". Two cells are considered equal \c iff they - * are based on same nodes and have the same type and orientation. - * - 2 : "nodal". Two cells are considered equal \c iff they - * are based on same nodes and have the same type. This is the weakest - * policy, it can be used by users not sensitive to cell orientation. - * \param [in] startCellId - specifies the cell id at which search for equal cells - * starts. By default it is 0, which means that all cells in \a this will be - * scanned. - * \return DataArrayInt - a new instance of DataArrayInt, of length \a - * this->getNumberOfCells() before call of this method. The caller is to - * delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * - * \ref cpp_mcumesh_zipConnectivityTraducer "Here is a C++ example".
- * \ref py_mcumesh_zipConnectivityTraducer "Here is a Python example". - */ -DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType, int startCellId) throw(INTERP_KERNEL::Exception) -{ - DataArrayInt *commonCells=0,*commonCellsI=0; - findCommonCells(compType,startCellId,commonCells,commonCellsI); - MEDCouplingAutoRefCountObjectPtr commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); - int newNbOfCells=-1; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfCells(),commonCells->begin(),commonCellsI->begin(), - commonCellsI->end(),newNbOfCells); - MEDCouplingAutoRefCountObjectPtr ret2=ret->invertArrayO2N2N2O(newNbOfCells); - MEDCouplingAutoRefCountObjectPtr self=static_cast(buildPartOfMySelf(ret2->begin(),ret2->end(),true)); - setConnectivity(self->getNodalConnectivity(),self->getNodalConnectivityIndex(),true); - return ret.retn(); -} - /*! * Checks if \a this mesh includes all cells of an \a other mesh, and returns an array * giving for each cell of the \a other an id of a cell in \a this mesh. A value larger @@ -2001,10 +1841,10 @@ bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataAr */ DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) { - DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); + MEDCouplingAutoRefCountObjectPtr ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); if(areNodesMerged) - renumberNodes(ret->getConstPointer(),newNbOfNodes); - return ret; + renumberNodes(ret->begin(),newNbOfNodes); + return ret.retn(); } @@ -2033,51 +1873,17 @@ DataArrayInt *MEDCouplingUMesh::mergeNodes2(double precision, bool& areNodesMerg return ret; } -/*! - * Substitutes node coordinates array of \a this mesh with that of \a other mesh - * (i.e. \a this->_coords with \a other._coords) provided that coordinates of the two - * meshes match with a specified precision, else an exception is thrown and \a this - * remains unchanged. In case of success the nodal connectivity of \a this mesh - * is permuted according to new order of nodes. - * Contrary to tryToShareSameCoords() this method makes a deeper analysis of - * coordinates (and so more expensive) than simple equality. - * \param [in] other - the other mesh whose node coordinates array will be used by - * \a this mesh in case of their equality. - * \param [in] epsilon - the precision used to compare coordinates (using infinite norm). - * \throw If the coordinates array of \a this is not set. - * \throw If the coordinates array of \a other is not set. - * \throw If the coordinates of \a this and \a other do not match. - */ -void MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) +MEDCouplingPointSet *MEDCouplingUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const { - const 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 otherNbOfNodes=other.getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr newCoords=MergeNodesArray(&other,this); - _coords->incrRef(); - MEDCouplingAutoRefCountObjectPtr oldCoords=_coords; - setCoords(newCoords); - bool areNodesMerged; - int newNbOfNodes; - MEDCouplingAutoRefCountObjectPtr da=buildPermArrayForMergeNode(epsilon,otherNbOfNodes,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); + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeMyselfWithOnSameCoords : input other is null !"); + const MEDCouplingUMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type unstructured !"); + std::vector ms(2); + ms[0]=this; + ms[1]=otherC; + return MergeUMeshesOnSameCoords(ms); } /*! @@ -2094,12 +1900,7 @@ void MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& ot MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const throw(INTERP_KERNEL::Exception) { if(getMeshDimension()!=-1) - { - MEDCouplingUMesh *ret=buildPartOfMySelfKeepCoords2(start,end,step); - if(!keepCoords) - ret->zipCoords(); - return ret; - } + return MEDCouplingPointSet::buildPartOfMySelf2(start,end,step,keepCoords); else { int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelf2 for -1 dimension mesh "); @@ -2136,12 +1937,7 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, in MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const { if(getMeshDimension()!=-1) - { - MEDCouplingUMesh *ret=buildPartOfMySelfKeepCoords(begin,end); - if(!keepCoords) - ret->zipCoords(); - return ret; - } + return MEDCouplingPointSet::buildPartOfMySelf(begin,end,keepCoords); else { if(end-begin!=1) @@ -2156,13 +1952,13 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const /*! * This method operates only on nodal connectivity on \b this. Coordinates of \b this is completely ignored here. * - * This method allows to partially modify some cells in \b this (whose list is specified by [\b cellIdsBg, \b cellIdsEnd) ) with cells coming in \b otherOnSameCoordsThanThis. - * Size of [\b cellIdsBg, \b cellIdsEnd) ) must be equal to the number of cells of otherOnSameCoordsThanThis. + * This method allows to partially modify some cells in \b this (whose list is specified by [ \b cellIdsBg, \b cellIdsEnd ) ) with cells coming in \b otherOnSameCoordsThanThis. + * Size of [ \b cellIdsBg, \b cellIdsEnd ) ) must be equal to the number of cells of otherOnSameCoordsThanThis. * The number of cells of \b this will remain the same with this method. * * \param [in] begin begin of cell ids (included) of cells in this to assign * \param [in] end end of cell ids (excluded) of cells in this to assign - * \param [in] otherOnSameCoordsThanThis an another mesh with same meshdimension than \b this with exactly the same number of cells than cell ids list in [\b cellIdsBg, \b cellIdsEnd). + * \param [in] otherOnSameCoordsThanThis an another mesh with same meshdimension than \b this with exactly the same number of cells than cell ids list in [\b cellIdsBg, \b cellIdsEnd ). * Coordinate pointer of \b this and those of \b otherOnSameCoordsThanThis must be the same */ void MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception) @@ -2287,14 +2083,14 @@ DataArrayInt *MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *part } /*! - * Keeps from \a this only cells which constituing point id are in the ids specified by ['begin','end'). + * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ). * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter. - * Parameter 'fullyIn' specifies if a cell that has part of its nodes in ids array is kept or not. - * If 'fullyIn' is true only cells whose ids are \b fully contained in ['begin','end') tab will be kept. + * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not. + * If \a fullyIn is true only cells whose ids are \b fully contained in [ \a begin,\a end ) tab will be kept. * * \param [in] begin input start of array of node ids. * \param [in] end input end of array of node ids. - * \param [in] fullyIn input that specifies if all node ids must be in ['begin','end') array to consider cell to be in. + * \param [in] fullyIn input that specifies if all node ids must be in [ \a begin,\a end ) array to consider cell to be in. * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end. */ void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const @@ -2351,35 +2147,6 @@ DataArrayInt *MEDCouplingUMesh::getCellIdsLyingOnNodes(const int *begin, const i return cellIdsKept; } -/*! - Creates a new MEDCouplingUMesh containing some cells of \a this mesh. The cells to - copy are selected basing on specified node ids and the value of \a fullyIn - parameter. If \a fullyIn ==\c true, a cell is copied if its all nodes are in the - array \a begin of node ids. If \a fullyIn ==\c false, a cell is copied if any its - node is in the array of node ids. The created mesh shares the node coordinates array - with \a this mesh. - * \param [in] begin - the array of node ids. - * \param [in] end - a pointer to the (last+1)-th element of \a begin. - * \param [in] fullyIn - if \c true, then cells whose all nodes are in the - * array \a begin are copied, else cells whose any node is in the - * array \a begin are copied. - * \return MEDCouplingPointSet * - new instance of MEDCouplingUMesh. The caller is - * to delete this mesh using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If any node id in \a begin is not valid. - * - * \ref cpp_mcumesh_buildPartOfMySelfNode "Here is a C++ example".
- * \ref py_mcumesh_buildPartOfMySelfNode "Here is a Python example". - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const -{ - DataArrayInt *cellIdsKept=0; - fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept); - MEDCouplingAutoRefCountObjectPtr cellIdsKept2(cellIdsKept); - return buildPartOfMySelf(cellIdsKept->begin(),cellIdsKept->end(),true); -} - /*! * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a * this->getMeshDimension(), that bound some cells of \a this mesh. @@ -2589,50 +2356,6 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildUnstructured() const throw(INTERP_KERNE return const_cast(this); } -/*! - * Permutes and possibly removes nodes as specified by \a newNodeNumbers array. - * If \a newNodeNumbers[ i ] < 0 then the i-th node is removed, - * else \a newNodeNumbers[ i ] is a new id of the i-th node. The nodal connectivity - * array is modified accordingly. - * \param [in] newNodeNumbers - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes. - * \param [in] newNbOfNodes - number of nodes remaining after renumbering. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".
- * \ref py_mcumesh_renumberNodes "Here is a Python example". - */ -void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes) -{ - MEDCouplingPointSet::renumberNodes(newNodeNumbers,newNbOfNodes); - renumberNodesInConn(newNodeNumbers); -} - -/*! - * Permutes and possibly removes nodes as specified by \a newNodeNumbers array. - * If \a newNodeNumbers[ i ] < 0 then the i-th node is removed, - * else \a newNodeNumbers[ i ] is a new id of the i-th node. The nodal connectivity - * array is modified accordingly. In contrast to renumberNodes(), location - * of merged nodes (whose new ids coincide) is changed to be at their barycenter. - * \param [in] newNodeNumbers - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes. - * \param [in] newNbOfNodes - number of nodes remaining after renumbering, which is - * actually one more than the maximal id in \a newNodeNumbers. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".
- * \ref py_mcumesh_renumberNodes "Here is a Python example". - */ -void MEDCouplingUMesh::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes) -{ - MEDCouplingPointSet::renumberNodes2(newNodeNumbers,newNbOfNodes); - renumberNodesInConn(newNodeNumbers); -} - /*! * This method expects that \b this and \b otherDimM1OnSameCoords share the same coordinates array. * otherDimM1OnSameCoords->getMeshDimension() is expected to be equal to this->getMeshDimension()-1. @@ -2693,7 +2416,7 @@ void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1On /*! * This method operates a modification of the connectivity and coords in \b this. - * Every time that a node id in [\b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd) will append in nodal connectivity of \b this + * Every time that a node id in [ \b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd ) will append in nodal connectivity of \b this * its ids will be modified to id this->getNumberOfNodes()+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)). * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be * renumbered. The node id nodeIdsToDuplicateBg[0] will have id this->getNumberOfNodes()+0, node id nodeIdsToDuplicateBg[1] will have id this->getNumberOfNodes()+1, @@ -2772,7 +2495,7 @@ void MEDCouplingUMesh::shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Ex /*! * This method operates a modification of the connectivity in \b this. * Coordinates are \b NOT considered here and will remain unchanged by this method. this->_coords can ever been null for the needs of this method. - * Every time that a node id in [\b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd) will append in nodal connectivity of \b this + * Every time that a node id in [ \b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd ) will append in nodal connectivity of \b this * its ids will be modified to id offset+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)). * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be * renumbered. The node id nodeIdsToDuplicateBg[0] will have id offset+0, node id nodeIdsToDuplicateBg[1] will have id offset+1, @@ -2783,7 +2506,7 @@ void MEDCouplingUMesh::shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Ex * * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only - * \param [in] offset the offset applied to all node ids in connectivity that are in [nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd). + * \param [in] offset the offset applied to all node ids in connectivity that are in [ \a nodeIdsToDuplicateBg, \a nodeIdsToDuplicateEnd ). */ void MEDCouplingUMesh::duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset) throw(INTERP_KERNEL::Exception) { @@ -2815,12 +2538,12 @@ void MEDCouplingUMesh::duplicateNodesInConn(const int *nodeIdsToDuplicateBg, con * Contrary to MEDCouplingPointSet::renumberNodes, this method makes a permutation without any fuse of cell. * After the call of this method the number of cells remains the same as before. * - * If 'check' equals true the method will check that any elements in [old2NewBg;old2NewEnd) is unique ; if not - * an INTERP_KERNEL::Exception will be thrown. When 'check' equals true [old2NewBg;old2NewEnd) is not expected to + * If 'check' equals true the method will check that any elements in [ \a old2NewBg; \a old2NewEnd ) is unique ; if not + * an INTERP_KERNEL::Exception will be thrown. When 'check' equals true [ \a old2NewBg ; \a old2NewEnd ) is not expected to * be strictly in [0;this->getNumberOfCells()). * - * If 'check' equals false the method will not check the content of [old2NewBg;old2NewEnd). - * To avoid any throw of SIGSEGV when 'check' equals false, the elements in [old2NewBg;old2NewEnd) should be unique and + * If 'check' equals false the method will not check the content of [ \a old2NewBg ; \a old2NewEnd ). + * To avoid any throw of SIGSEGV when 'check' equals false, the elements in [ \a old2NewBg ; \a old2NewEnd ) should be unique and * should be contained in[0;this->getNumberOfCells()). * * \param [in] old2NewBg is expected to be a dynamically allocated pointer of size at least equal to this->getNumberOfCells() @@ -3443,7 +3166,7 @@ void MEDCouplingUMesh::unserialization(const std::vector& tinyInfoD, con * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf2. * CellIds are given using range specified by a start an end and step. */ -MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const { checkFullyDefined(); int ncell=getNumberOfCells(); @@ -3485,10 +3208,10 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int /*! * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf. - * Keeps from \a this only cells which constituing point id are in the ids specified by ['begin','end'). + * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ). * The return newly allocated mesh will share the same coordinates as \a this. */ -MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const { checkFullyDefined(); int ncell=getNumberOfCells(); @@ -6851,7 +6574,7 @@ bool MEDCouplingUMesh::checkConsecutiveCellTypesForMEDFileFrmt() const throw(INT /*! * This method performs the same job as checkConsecutiveCellTypes except that the order of types sequence is analyzed to check - * that the order is specified in array defined by [orderBg,orderEnd). + * that the order is specified in array defined by [ \a orderBg , \a orderEnd ). * If there is some geo types in \a this \b NOT in [ \a orderBg, \a orderEnd ) it is OK (return true) if contiguous. * If there is some geo types in [ \a orderBg, \a orderEnd ) \b NOT in \a this it is OK too (return true) if contiguous. */ @@ -6943,7 +6666,7 @@ DataArrayInt *MEDCouplingUMesh::getRenumArrForMEDFileFrmt() const throw(INTERP_K } /*! - * This method is similar to method MEDCouplingUMesh::rearrange2ConsecutiveCellTypes except that the type order is specfied by [orderBg,orderEnd) (as MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method) and that this method is \b const and performs \b NO permutation in \a this. + * This method is similar to method MEDCouplingUMesh::rearrange2ConsecutiveCellTypes except that the type order is specfied by [ \a orderBg , \a orderEnd ) (as MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method) and that this method is \b const and performs \b NO permutation in \a this. * This method returns an array of size getNumberOfCells() that gives a renumber array old2New that can be used as input of MEDCouplingMesh::renumberCells. * The mesh after this call to MEDCouplingMesh::renumberCells will pass the test of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder with the same inputs. * The returned array minimizes the permutations that is to say the order of cells inside same geometric type remains the same. @@ -7023,6 +6746,52 @@ std::vector MEDCouplingUMesh::splitByType() const return ret; } +/*! + * This method performs the opposite operation than those in MEDCoupling1SGTUMesh::buildUnstructured. + * If \a this is a single geometric type unstructured mesh, it will be converted into a more compact data structure, + * MEDCoupling1GTUMesh instance. The returned instance will aggregate the same DataArrayDouble instance of coordinates than \a this. + * + * \return a newly allocated instance, that the caller must manage. + * \throw If \a this contains more than one geometric type. + * \throw If the nodal connectivity of \a this is not fully defined. + * \throw If the internal data is not coherent. + */ +MEDCoupling1GTUMesh *MEDCouplingUMesh::convertIntoSingleGeoTypeMesh() const throw(INTERP_KERNEL::Exception) +{ + checkConnectivityFullyDefined(); + if(_types.size()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : current mesh does not contain exactly one geometric type !"); + INTERP_KERNEL::NormalizedCellType typ=*_types.begin(); + int typi=(int)typ; + MEDCouplingAutoRefCountObjectPtr ret=MEDCoupling1GTUMesh::New(getName(),typ); + ret->setCoords(ret->getCoords()); + MEDCoupling1SGTUMesh *retC=dynamic_cast((MEDCoupling1GTUMesh*)ret); + if(retC) + { + int nbCells=getNumberOfCells(); + int nbNodesPerCell=retC->getNumberOfNodesPerCell(); + MEDCouplingAutoRefCountObjectPtr connOut=DataArrayInt::New(); connOut->alloc(nbCells*nbNodesPerCell,1); + int *outPtr=connOut->getPointer(); + const int *conn=_nodal_connec->begin(); + const int *connI=_nodal_connec_index->begin(); + nbNodesPerCell++; + for(int i=0;isetNodalConnectivity(connOut); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : not implemented yet for non static geometric type !"); + return ret.retn(); +} + /*! * This method takes in input a vector of MEDCouplingUMesh instances lying on the same coordinates with same mesh dimensions. * Each mesh in \b ms must be sorted by type with the same order (typically using MEDCouplingUMesh::sortCellsInMEDFileFrmt). @@ -7092,7 +6861,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(cons /*! * This method returns a newly created DataArrayInt instance. - * This method retrieves cell ids in [begin,end) that have the type 'type'. + * This method retrieves cell ids in [ \a begin, \a end ) that have the type \a type. */ DataArrayInt *MEDCouplingUMesh::keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const throw(INTERP_KERNEL::Exception) { @@ -7749,7 +7518,7 @@ void MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector splitByType() const; + MEDCOUPLING_EXPORT MEDCoupling1GTUMesh *convertIntoSingleGeoTypeMesh() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static MEDCouplingUMesh *AggregateSortedByTypeMeshesOnSameCoords(const std::vector& ms, DataArrayInt *&szOfCellGrpOfSameType, DataArrayInt *&idInMsOfCellGrpOfSameType) throw(INTERP_KERNEL::Exception); @@ -275,8 +269,8 @@ namespace ParaMEDMEM DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception); DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception); static bool AreCellsEqualInPool(const std::vector& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result) ; - MEDCouplingUMesh *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; - MEDCouplingUMesh *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; + MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; + MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; DataArrayInt *convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const throw(INTERP_KERNEL::Exception); DataArrayInt *convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const throw(INTERP_KERNEL::Exception); DataArrayInt *convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx index df9d89271..755b433b1 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx @@ -79,6 +79,11 @@ MEDCouplingMesh *MEDCouplingUMeshDesc::deepCpy() const return 0; } +void MEDCouplingUMeshDesc::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + void MEDCouplingUMeshDesc::checkCoherency() const throw(INTERP_KERNEL::Exception) { for(std::set::const_iterator iter=_types.begin();iter!=_types.end();iter++) @@ -102,12 +107,6 @@ void MEDCouplingUMeshDesc::checkCoherency2(double eps) const throw(INTERP_KERNEL checkCoherency1(eps); } -void MEDCouplingUMeshDesc::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) -{ - throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::checkDeepEquivalWith : not implemented yet !"); -} - void MEDCouplingUMeshDesc::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) { @@ -401,33 +400,31 @@ DataArrayInt *MEDCouplingUMeshDesc::mergeNodes2(double precision, bool& areNodes return 0; } -void MEDCouplingUMeshDesc::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) +MEDCouplingPointSet *MEDCouplingUMeshDesc::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const { throw INTERP_KERNEL::Exception("Not implemented yet !"); } -MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const throw(INTERP_KERNEL::Exception) +MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const { throw INTERP_KERNEL::Exception("Not implemented yet !"); return 0; } -MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const +MEDCouplingPointSet *MEDCouplingUMeshDesc::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const { throw INTERP_KERNEL::Exception("Not implemented yet !"); return 0; } -MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const +MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const { throw INTERP_KERNEL::Exception("Not implemented yet !"); - return 0; } -MEDCouplingPointSet *MEDCouplingUMeshDesc::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const +MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelfKeepCoords2(int start, int end, int step) const { throw INTERP_KERNEL::Exception("Not implemented yet !"); - return 0; } DataArrayInt *MEDCouplingUMeshDesc::simplexize(int policy) throw(INTERP_KERNEL::Exception) @@ -456,9 +453,8 @@ void MEDCouplingUMeshDesc::renumberCells(const int *old2NewBg, bool check) throw throw INTERP_KERNEL::Exception("Available for UMesh desc but not implemented yet !"); } -void MEDCouplingUMeshDesc::renumberNodes(const int *newNodeNumbers, int newNbOfNodes) +void MEDCouplingUMeshDesc::renumberNodesInConn(const int *newNodeNumbersO2N) { - MEDCouplingPointSet::renumberNodes(newNodeNumbers,newNbOfNodes); throw INTERP_KERNEL::Exception("Not implemented yet !"); } @@ -482,12 +478,22 @@ MEDCouplingFieldDouble *MEDCouplingUMeshDesc::buildOrthogonalField() const return 0; } -DataArrayInt *MEDCouplingUMeshDesc::zipCoordsTraducer() +DataArrayInt *MEDCouplingUMeshDesc::zipCoordsTraducer() throw(INTERP_KERNEL::Exception) { throw INTERP_KERNEL::Exception("Not implemented yet !"); return 0; } +void MEDCouplingUMeshDesc::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingUMeshDesc::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + void MEDCouplingUMeshDesc::computeTypes() { if(_desc_connec && _desc_connec_index) @@ -513,6 +519,16 @@ MEDCouplingMesh *MEDCouplingUMeshDesc::mergeMyselfWith(const MEDCouplingMesh *ot return 0; } +DataArrayInt *MEDCouplingUMeshDesc::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingUMeshDesc::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + DataArrayDouble *MEDCouplingUMeshDesc::getBarycenterAndOwner() const { throw INTERP_KERNEL::Exception("Not implemented yet !"); diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx index e6a25b09b..c71e83366 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx @@ -36,11 +36,10 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static MEDCouplingUMeshDesc *New(const char *meshName, int meshDim); MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; + MEDCOUPLING_EXPORT void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkCoherency() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setMeshDimension(unsigned meshDim); @@ -73,9 +72,11 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps); MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes); - MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords=0) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const; + MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) 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; MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception); @@ -83,12 +84,14 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); + MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N); MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; - MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer(); + MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling/Makefile.am b/src/MEDCoupling/Makefile.am index 4c11df0cb..5076ac0ea 100644 --- a/src/MEDCoupling/Makefile.am +++ b/src/MEDCoupling/Makefile.am @@ -46,7 +46,7 @@ MEDCouplingFieldOverTime.hxx MEDCouplingCurveLinearMesh.hxx MEDCouplingStructure dist_libmedcoupling_la_SOURCES = \ MEDCouplingField.cxx MEDCouplingFieldDouble.cxx \ MEDCouplingUMesh.cxx MEDCouplingMemArray.cxx MEDCouplingTimeLabel.cxx \ - MEDCouplingCMesh.cxx MEDCouplingTimeDiscretization.cxx \ + MEDCouplingCMesh.cxx MEDCouplingTimeDiscretization.cxx MEDCoupling1GTUMesh.cxx \ MEDCouplingFieldDiscretization.cxx MEDCouplingRefCountObject.cxx \ MEDCouplingPointSet.cxx MEDCouplingUMeshDesc.cxx MEDCouplingFieldTemplate.cxx \ MEDCouplingExtrudedMesh.cxx MEDCouplingMesh.cxx MEDCouplingGaussLocalization.cxx \ diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx index 5d2b0c0f9..615c79a70 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx @@ -2471,7 +2471,7 @@ void MEDCouplingBasicsTest1::testCMesh2() dis[2]=0; DataArrayInt *ids=DataArrayInt::New(); ids->alloc(10,1); - ids->fillWithValue(111); + ids->fillWithValue(23); idsPerType.push_back(ids); DataArrayInt* check=mesh1->checkTypeConsistencyAndContig(dis, idsPerType); CPPUNIT_ASSERT(check); @@ -2487,7 +2487,9 @@ void MEDCouplingBasicsTest1::testCMesh2() CPPUNIT_ASSERT_EQUAL(0,code[2]); CPPUNIT_ASSERT_EQUAL(1,(int)idsInPflPerType.size()); CPPUNIT_ASSERT_EQUAL(1,(int)pfls.size()); - CPPUNIT_ASSERT(idsInPflPerType[0]->isEqual(*ids)); + DataArrayInt *exp=DataArrayInt::New(); exp->alloc(10,1); exp->iota(0); + CPPUNIT_ASSERT(idsInPflPerType[0]->isEqual(*exp)); + exp->decrRef(); CPPUNIT_ASSERT(pfls[0]->isEqual(*ids)); idsInPflPerType[0]->decrRef(); pfls[0]->decrRef(); diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 835e6e698..35a8eb09a 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -1845,7 +1845,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): dis[0][2]=0; ids=DataArrayInt.New(); ids.alloc(10, 1); - ids.fillWithValue(111); + ids.fillWithValue(23); idsPerType=[ids]; check=mesh1.checkTypeConsistencyAndContig(dis, idsPerType); self.assertTrue(check); @@ -1858,7 +1858,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(0, code[2]); self.assertEqual(1, len(idsInPflPerType)); self.assertEqual(1, len(pfls)); - self.assertTrue(idsInPflPerType[0].isEqual(ids)); + self.assertTrue(idsInPflPerType[0].isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9]))); self.assertTrue(pfls[0].isEqual(ids)); cells1=[0, 1, 25, 26] diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index 36b67bd07..632f32e5b 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -30,6 +30,7 @@ #include "MEDCouplingExtrudedMesh.hxx" #include "MEDCouplingCMesh.hxx" #include "MEDCouplingCurveLinearMesh.hxx" +#include "MEDCoupling1GTUMesh.hxx" #include "MEDCouplingField.hxx" #include "MEDCouplingFieldDouble.hxx" #include "MEDCouplingFieldTemplate.hxx" @@ -62,6 +63,11 @@ using namespace INTERP_KERNEL; $result=convertMesh($1,$owner); } +%typemap(out) ParaMEDMEM::MEDCoupling1GTUMesh* +{ + $result=convertMesh($1,$owner); +} + %typemap(out) ParaMEDMEM::MEDCouplingStructuredMesh* { $result=convertMesh($1,$owner); @@ -328,6 +334,9 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingPointSet::MergeNodesArray; %newobject ParaMEDMEM::MEDCouplingPointSet::buildPartOfMySelf2; %newobject ParaMEDMEM::MEDCouplingPointSet::BuildInstanceFromMeshType; +%newobject ParaMEDMEM::MEDCouplingPointSet::zipConnectivityTraducer; +%newobject ParaMEDMEM::MEDCouplingPointSet::mergeMyselfWithOnSameCoords; +%newobject ParaMEDMEM::MEDCouplingPointSet::fillCellIdsToKeepFromNodeIds; %newobject ParaMEDMEM::MEDCouplingUMesh::New; %newobject ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivity; %newobject ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex; @@ -335,7 +344,6 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingUMesh::__iter__; %newobject ParaMEDMEM::MEDCouplingUMesh::__getitem__; %newobject ParaMEDMEM::MEDCouplingUMesh::cellsByType; -%newobject ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer; %newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity; %newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity2; %newobject ParaMEDMEM::MEDCouplingUMesh::explode3DMeshTo1D; @@ -365,6 +373,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingUMesh::Build0DMeshFromCoords; %newobject ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells; %newobject ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DCells; +%newobject ParaMEDMEM::MEDCouplingUMesh::convertIntoSingleGeoTypeMesh; %newobject ParaMEDMEM::MEDCouplingUMesh::findCellIdsOnBoundary; %newobject ParaMEDMEM::MEDCouplingUMesh::computeSkin; %newobject ParaMEDMEM::MEDCouplingUMesh::getCellIdsLyingOnNodes; @@ -374,6 +383,12 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingUMesh::ComputeRangesFromTypeDistribution; %newobject ParaMEDMEM::MEDCouplingUMeshCellByTypeEntry::__iter__; %newobject ParaMEDMEM::MEDCouplingUMeshCellEntry::__iter__; +%newobject ParaMEDMEM::MEDCoupling1GTUMesh::New; +%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::New; +%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::getNodalConnectivity; +%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::buildSetInstanceFromThis; +%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::Merge1SGTUMeshes; +%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords; %newobject ParaMEDMEM::MEDCouplingExtrudedMesh::New; %newobject ParaMEDMEM::MEDCouplingExtrudedMesh::build3DUnstructuredMesh; %newobject ParaMEDMEM::MEDCouplingCMesh::New; @@ -391,6 +406,8 @@ using namespace INTERP_KERNEL; %feature("unref") MEDCouplingPointSet "$this->decrRef();" %feature("unref") MEDCouplingMesh "$this->decrRef();" %feature("unref") MEDCouplingUMesh "$this->decrRef();" +%feature("unref") MEDCoupling1GTUMesh "$this->decrRef();" +%feature("unref") MEDCoupling1SGTUMesh "$this->decrRef();" %feature("unref") MEDCouplingExtrudedMesh "$this->decrRef();" %feature("unref") MEDCouplingCMesh "$this->decrRef();" %feature("unref") DataArrayInt "$this->decrRef();" @@ -438,7 +455,18 @@ namespace INTERP_KERNEL }; } -%include "MEDCouplingTimeLabel.hxx" +namespace ParaMEDMEM +{ + class TimeLabel + { + public: + void declareAsNew() const; + virtual void updateTime() const; + unsigned int getTimeOfThis() const; + protected: + ~TimeLabel(); + }; +} namespace ParaMEDMEM { @@ -555,6 +583,8 @@ namespace ParaMEDMEM } } + //== MEDCouplingMesh + class MEDCouplingMesh : public RefCountObject, public TimeLabel { public: @@ -570,6 +600,7 @@ namespace ParaMEDMEM virtual MEDCouplingMesh *deepCpy() const; virtual bool isEqual(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); + virtual void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); virtual void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); virtual void copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); @@ -1001,6 +1032,8 @@ namespace ParaMEDMEM }; } +//== MEDCouplingMesh End + %include "NormalizedUnstructuredMesh.hxx" %include "MEDCouplingNatureOfField.hxx" %include "MEDCouplingTimeDiscretization.hxx" @@ -1011,12 +1044,13 @@ namespace ParaMEDMEM %ignore ParaMEDMEM::MEDCouplingFieldDiscretization::buildSubMeshDataRange; %ignore ParaMEDMEM::MEDCouplingFieldDiscretizationPerCell::getArrayOfDiscIds; +//== MEDCouplingPointSet + namespace ParaMEDMEM { class MEDCouplingPointSet : public ParaMEDMEM::MEDCouplingMesh { public: - void updateTime() const; void setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); DataArrayDouble *getCoordinatesAndOwner() const throw(INTERP_KERNEL::Exception); bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const throw(INTERP_KERNEL::Exception); @@ -1025,15 +1059,19 @@ namespace ParaMEDMEM void recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception); void changeSpaceDimension(int newSpaceDim, double dftVal=0.) throw(INTERP_KERNEL::Exception); void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); + virtual void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception); virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step) const throw(INTERP_KERNEL::Exception); virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); static DataArrayDouble *MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) throw(INTERP_KERNEL::Exception); static MEDCouplingPointSet *BuildInstanceFromMeshType(MEDCouplingMeshType type) throw(INTERP_KERNEL::Exception); virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const throw(INTERP_KERNEL::Exception); - virtual bool isEmptyMesh(const std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) throw(INTERP_KERNEL::Exception); virtual DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception); virtual DataArrayInt *findBoundaryNodes() const; + virtual DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception); + virtual MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const throw(INTERP_KERNEL::Exception); + virtual void checkFullyDefined() const throw(INTERP_KERNEL::Exception); + virtual bool isEmptyMesh(const std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); %extend { std::string __str__() const throw(INTERP_KERNEL::Exception) @@ -1103,6 +1141,29 @@ namespace ParaMEDMEM return convertMesh(ret, SWIG_POINTER_OWN | 0 ); } + virtual PyObject *buildPartOfMySelfKeepCoords(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + MEDCouplingPointSet *ret=self->buildPartOfMySelfKeepCoords(tmp,tmp+szArr); + if(sw==3)//DataArrayInt + { + void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + std::string name=argpt->getName(); + if(!name.empty()) + ret->setName(name.c_str()); + } + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + + virtual PyObject *buildPartOfMySelfKeepCoords2(int start, int end, int step) const throw(INTERP_KERNEL::Exception) + { + MEDCouplingPointSet *ret=self->buildPartOfMySelfKeepCoords2(start,end,step); + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + PyObject *buildFacePartOfMySelfNode(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception) { int szArr,sw,iTypppArr; @@ -1263,6 +1324,93 @@ namespace ParaMEDMEM } } + virtual PyObject *getReverseNodalConnectivity() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); + self->getReverseNodalConnectivity(d0,d1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + virtual PyObject *findCommonCells(int compType, int startCellId=0) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *v0=0,*v1=0; + self->findCommonCells(compType,startCellId,v0,v1); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(v0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(v1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return res; + } + + + virtual void renumberNodesInConn(PyObject *li) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); + self->renumberNodesInConn(tmp); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + self->renumberNodesInConn(da2->getConstPointer()); + } + } + + virtual PyObject *getNodeIdsInUse() const throw(INTERP_KERNEL::Exception) + { + int ret1=-1; + DataArrayInt *ret0=self->getNodeIdsInUse(ret1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); + return ret; + } + + virtual DataArrayInt *fillCellIdsToKeepFromNodeIds(PyObject *li, bool fullyIn) const + { + DataArrayInt *ret=0; + // + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->fillCellIdsToKeepFromNodeIds(tmp,tmp+szArr,fullyIn,ret); + return ret; + } + + virtual PyObject *mergeNodes(double precision) throw(INTERP_KERNEL::Exception) + { + bool ret1; + 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; + } + + virtual PyObject *mergeNodes2(double precision) throw(INTERP_KERNEL::Exception) + { + bool ret1; + int ret2; + DataArrayInt *ret0=self->mergeNodes2(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; + } + static void Rotate2DAlg(PyObject *center, double angle, int nbNodes, PyObject *coords) throw(INTERP_KERNEL::Exception) { int sz; @@ -1315,6 +1463,8 @@ namespace ParaMEDMEM } }; + //== MEDCouplingPointSet End + class MEDCouplingUMeshCell { public: @@ -1404,13 +1554,14 @@ namespace ParaMEDMEM } }; + //== MEDCouplingUMesh + class MEDCouplingUMesh : public ParaMEDMEM::MEDCouplingPointSet { public: static MEDCouplingUMesh *New() throw(INTERP_KERNEL::Exception); static MEDCouplingUMesh *New(const char *meshName, int meshDim) throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *clone(bool recDeepCpy) const; - void updateTime() const; void checkCoherency() const throw(INTERP_KERNEL::Exception); void setMeshDimension(int meshDim) throw(INTERP_KERNEL::Exception); void allocateCells(int nbOfCells=0) throw(INTERP_KERNEL::Exception); @@ -1436,7 +1587,6 @@ namespace ParaMEDMEM DataArrayInt *getRenumArrForMEDFileFrmt() const throw(INTERP_KERNEL::Exception); DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception); DataArrayInt *computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception); - DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); @@ -1458,6 +1608,7 @@ namespace ParaMEDMEM std::string cppRepr() const throw(INTERP_KERNEL::Exception); DataArrayInt *findAndCorrectBadOriented3DExtrudedCells() throw(INTERP_KERNEL::Exception); DataArrayInt *findAndCorrectBadOriented3DCells() throw(INTERP_KERNEL::Exception); + MEDCoupling1GTUMesh *convertIntoSingleGeoTypeMesh() const throw(INTERP_KERNEL::Exception); static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da) throw(INTERP_KERNEL::Exception); static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); @@ -1726,16 +1877,6 @@ namespace ParaMEDMEM return res; } - PyObject *findCommonCells(int compType, int startCellId=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *v0=0,*v1=0; - self->findCommonCells(compType,startCellId,v0,v1); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(v0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(v1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return res; - } - static PyObject *FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI) throw(INTERP_KERNEL::Exception) { DataArrayInt *v0=0,*v1=0; @@ -1773,29 +1914,7 @@ namespace ParaMEDMEM PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); return ret; } - - PyObject *mergeNodes(double precision) throw(INTERP_KERNEL::Exception) - { - bool ret1; - 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 *mergeNodes2(double precision) throw(INTERP_KERNEL::Exception) - { - bool ret1; - int ret2; - DataArrayInt *ret0=self->mergeNodes2(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(double eps=1e-12) throw(INTERP_KERNEL::Exception) { std::vector cells; @@ -1913,26 +2032,6 @@ namespace ParaMEDMEM } } - void renumberNodesInConn(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - self->renumberNodesInConn(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - self->renumberNodesInConn(da2->getConstPointer()); - } - } - PyObject *getLevArrPerCellTypes(PyObject *li) const throw(INTERP_KERNEL::Exception) { int sz; @@ -2298,17 +2397,6 @@ namespace ParaMEDMEM return ret; } - PyObject *getReverseNodalConnectivity() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - self->getReverseNodalConnectivity(d0,d1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - DataArrayDouble *getPartBarycenterAndOwner(DataArrayInt *da) const throw(INTERP_KERNEL::Exception) { if(!da) @@ -2376,16 +2464,6 @@ namespace ParaMEDMEM } } - PyObject *getNodeIdsInUse() const throw(INTERP_KERNEL::Exception) - { - int ret1=-1; - DataArrayInt *ret0=self->getNodeIdsInUse(ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); - return ret; - } - static PyObject *Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps) throw(INTERP_KERNEL::Exception) { DataArrayInt *cellNb1=0,*cellNb2=0; @@ -2500,12 +2578,15 @@ namespace ParaMEDMEM MEDCouplingUMesh *buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy) throw(INTERP_KERNEL::Exception); }; + //== MEDCouplingUMesh End + + //== MEDCouplingExtrudedMesh + class MEDCouplingExtrudedMesh : public ParaMEDMEM::MEDCouplingMesh { public: static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *build3DUnstructuredMesh() const throw(INTERP_KERNEL::Exception); - void updateTime() const throw(INTERP_KERNEL::Exception); %extend { MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception) { @@ -2548,14 +2629,87 @@ namespace ParaMEDMEM } }; + //== MEDCouplingExtrudedMesh End + + class MEDCoupling1GTUMesh : public ParaMEDMEM::MEDCouplingPointSet + { + public: + static MEDCoupling1GTUMesh *New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); + }; + + //== MEDCoupling1SGTUMesh + + class MEDCoupling1SGTUMesh : public ParaMEDMEM::MEDCoupling1GTUMesh + { + public: + static MEDCoupling1GTUMesh *New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); + void setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception); + void allocateCells(int nbOfCells=0) throw(INTERP_KERNEL::Exception); + int getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception); + int getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception); + static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception); + MEDCoupling1SGTUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); + %extend + { + MEDCoupling1SGTUMesh(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception) + { + return MEDCoupling1SGTUMesh::New(name,type); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + + DataArrayInt *getNodalConnectivity() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret=self->getNodalConnectivity(); + if(ret) ret->incrRef(); + return ret; + } + + void insertNextCell(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->insertNextCell(tmp,tmp+szArr); + } + + static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh,"MEDCoupling1SGTUMesh",tmp); + return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(tmp); + } + + static MEDCoupling1SGTUMesh *Merge1SGTUMeshesOnSameCoords(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh,"MEDCoupling1SGTUMesh",tmp); + return MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(tmp); + } + } + }; + + //== MEDCoupling1SGTUMesh End + class MEDCouplingStructuredMesh : public ParaMEDMEM::MEDCouplingMesh { public: - void updateTime() const throw(INTERP_KERNEL::Exception); int getCellIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception); int getNodeIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception); }; + //== MEDCouplingCMesh + class MEDCouplingCMesh : public ParaMEDMEM::MEDCouplingStructuredMesh { public: @@ -2595,6 +2749,10 @@ namespace ParaMEDMEM } }; + //== MEDCouplingCMesh End + + //== MEDCouplingCurveLinearMesh + class MEDCouplingCurveLinearMesh : public ParaMEDMEM::MEDCouplingStructuredMesh { public: @@ -2638,7 +2796,8 @@ namespace ParaMEDMEM } } }; - + + //== MEDCouplingCurveLinearMesh End } %extend ParaMEDMEM::MEDCouplingFieldDiscretization @@ -2926,7 +3085,6 @@ namespace ParaMEDMEM static MEDCouplingFieldTemplate *New(TypeOfField type); std::string simpleRepr() const throw(INTERP_KERNEL::Exception); std::string advancedRepr() const throw(INTERP_KERNEL::Exception); - void updateTime() const; %extend { MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception) @@ -2991,7 +3149,6 @@ namespace ParaMEDMEM void setEndOrder(int order) throw(INTERP_KERNEL::Exception); 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 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); @@ -4085,7 +4242,6 @@ namespace ParaMEDMEM virtual bool isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; virtual bool isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); - void updateTime() const throw(INTERP_KERNEL::Exception); %extend { std::string __str__() const throw(INTERP_KERNEL::Exception) diff --git a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i index 60c3c86af..27a6de03e 100644 --- a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i +++ b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i @@ -417,6 +417,8 @@ static PyObject *convertMesh(ParaMEDMEM::MEDCouplingMesh *mesh, int owner) throw } if(dynamic_cast(mesh)) ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,owner); + if(dynamic_cast(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh,owner); if(dynamic_cast(mesh)) ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingExtrudedMesh,owner); if(dynamic_cast(mesh))