From fbf03cb9eeb48da1502916875ee0640aa4255f5d Mon Sep 17 00:00:00 2001 From: ageay Date: Thu, 20 Jun 2013 16:48:57 +0000 Subject: [PATCH] nearly ready for the single geo type in MEDLoader --- src/MEDCoupling/MEDCoupling1GTUMesh.cxx | 1165 ++++++++++++++++++- src/MEDCoupling/MEDCoupling1GTUMesh.hxx | 84 +- src/MEDCoupling/MEDCouplingMemArray.cxx | 96 +- src/MEDCoupling/MEDCouplingMemArray.hxx | 4 + src/MEDCoupling/MEDCouplingMemArrayChar.cxx | 20 +- src/MEDCoupling/MEDCouplingPointSet.cxx | 49 + src/MEDCoupling/MEDCouplingPointSet.hxx | 4 +- src/MEDCoupling/MEDCouplingUMesh.cxx | 128 +- src/MEDCoupling/MEDCouplingUMesh.hxx | 4 +- src/MEDCoupling/MEDCouplingUMeshDesc.cxx | 14 - src/MEDCoupling/MEDCouplingUMeshDesc.hxx | 2 - src/MEDCoupling_Swig/MEDCouplingCommon.i | 144 ++- src/MEDCoupling_Swig/MEDCouplingMemArray.i | 10 + src/MEDCoupling_Swig/MEDCouplingTypemaps.i | 2 + 14 files changed, 1585 insertions(+), 141 deletions(-) diff --git a/src/MEDCoupling/MEDCoupling1GTUMesh.cxx b/src/MEDCoupling/MEDCoupling1GTUMesh.cxx index 20960db90..87f1ebe29 100644 --- a/src/MEDCoupling/MEDCoupling1GTUMesh.cxx +++ b/src/MEDCoupling/MEDCoupling1GTUMesh.cxx @@ -42,7 +42,8 @@ MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *name, INTERP_KERNEL::N const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); if(!cm.isDynamic()) return MEDCoupling1SGTUMesh::New(name,type); - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : not implemented yet !"); + else + return MEDCoupling1DGTUMesh::New(name,type); } const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const throw(INTERP_KERNEL::Exception) @@ -229,6 +230,11 @@ std::string MEDCoupling1GTUMesh::getVTKDataSetType() const throw(INTERP_KERNEL:: return std::string("UnstructuredGrid"); } +std::size_t MEDCoupling1GTUMesh::getHeapMemorySize() const +{ + return MEDCouplingPointSet::getHeapMemorySize(); +} + bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason)) @@ -367,7 +373,7 @@ MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL: 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 !"; + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } return new MEDCoupling1SGTUMesh(name,cm); @@ -402,7 +408,7 @@ std::size_t MEDCoupling1SGTUMesh::getHeapMemorySize() const const DataArrayInt *c(_conn); if(c) ret+=c->getHeapMemorySize(); - return MEDCouplingPointSet::getHeapMemorySize()+ret; + return MEDCoupling1GTUMesh::getHeapMemorySize()+ret; } MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const @@ -575,7 +581,7 @@ 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 << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n"; ret << "Description of mesh : \"" << getDescription() << "\"\n"; int tmpp1,tmpp2; double tt=getTime(tmpp1,tmpp2); @@ -658,7 +664,7 @@ DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() cons { MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); int spaceDim=getSpaceDimension(); - int nbOfCells=getNumberOfCells(); + int nbOfCells=getNumberOfCells();//checkCoherency() int nbOfNodes=getNumberOfNodes(); ret->alloc(nbOfCells,spaceDim); double *ptToFill=ret->getPointer(); @@ -791,32 +797,6 @@ DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL:: } } -/*! - * \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; -} - /// @cond INTERNAL struct MEDCouplingAccVisit @@ -1149,7 +1129,7 @@ DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL: void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) { - stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Name : \"" << getName() << "\"."; + stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\"."; stream << " Mesh dimension : " << getMeshDimension() << "."; if(!_coords) { stream << " No coordinates set !"; return ; } @@ -1196,6 +1176,17 @@ void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, do 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 !"); + const DataArrayInt *c1(_conn),*c2(otherC->_conn); + if(c1==c2) + return; + if(!c1 || !c2) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !"); + if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated())) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !"); + if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !"); + if(c1->getHashCode()!=c2->getHashCode()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs"); } MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const @@ -1254,26 +1245,11 @@ void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, D /*! * 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(); + if(nodalConn) + nodalConn->incrRef(); _conn=nodalConn; declareAsNew(); } @@ -1331,3 +1307,1094 @@ void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const in throw INTERP_KERNEL::Exception(oss.str().c_str()); } } + +//== find static tony + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception) +{ + if(type==INTERP_KERNEL::NORM_ERROR) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::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 << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return new MEDCoupling1DGTUMesh(name,cm); +} + +MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm) +{ +} + +MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn) +{ + if(recDeepCpy) + { + const DataArrayInt *c(other._conn); + if(c) + _conn=c->deepCpy(); + c=other._conn_indx; + if(c) + _conn_indx=c->deepCpy(); + } +} + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const +{ + return new MEDCoupling1DGTUMesh(*this,recDeepCpy); +} + +void MEDCoupling1DGTUMesh::updateTime() const +{ + MEDCoupling1GTUMesh::updateTime(); + const DataArrayInt *c(_conn); + if(c) + updateTimeWith(*c); + c=_conn_indx; + if(c) + updateTimeWith(*c); +} + +std::size_t MEDCoupling1DGTUMesh::getHeapMemorySize() const +{ + std::size_t ret=0; + const DataArrayInt *c(_conn); + if(c) + ret+=c->getHeapMemorySize(); + c=_conn_indx; + if(c) + ret+=c->getHeapMemorySize(); + return MEDCoupling1GTUMesh::getHeapMemorySize()+ret; +} + +MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const +{ + return clone(true); +} + +bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !"); + std::ostringstream oss; oss.precision(15); + const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); + if(!otherC) + { + reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !"; + 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 dynamic geometric type exactly one among this and other is null !"; + return false; + } + if(!c1->isEqualIfNotWhy(*c2,reason)) + { + reason.insert(0,"Nodal connectivity DataArrayInt differs : "); + return false; + } + c1=_conn_indx; c2=otherC->_conn_indx; + if(c1==c2) + return true; + if(!c1 || !c2) + { + reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !"; + return false; + } + if(!c1->isEqualIfNotWhy(*c2,reason)) + { + reason.insert(0,"Nodal connectivity index DataArrayInt differs : "); + return false; + } + return true; +} + +bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !"); + const MEDCoupling1DGTUMesh *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; + c1=_conn_indx; c2=otherC->_conn_indx; + if(c1==c2) + return true; + if(!c1 || !c2) + return false; + if(!c1->isEqualWithoutConsideringStr(*c2)) + return false; + return true; +} + +/*! + * 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 MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingPointSet::checkFastEquivalWith(other,prec); + const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not not unstructured with single static geometric type !"); + const DataArrayInt *c1(_conn),*c2(otherC->_conn); + if(c1!=c2) + { + if(!c1 || !c2) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !"); + if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated())) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !"); + if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !"); + if(c1->getHashCode()!=c2->getHashCode()) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs"); + } + c1=_conn_indx; c2=otherC->_conn_indx; + if(c1!=c2) + { + if(!c1 || !c2) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !"); + if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated())) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !"); + if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !"); + if(c1->getHashCode()!=c2->getHashCode()) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs"); + } +} + +/*! + * If \a this pass this method, you are sure that connectivity arrays are not null, with exactly one component, no name, no component name, allocated. + * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one. + * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array. + */ +void MEDCoupling1DGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingPointSet::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 !"); + // + int sz2=_conn->getNumberOfTuples(); + c1=_conn_indx; + if(c1) + { + if(c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !"); + c1->checkAllocated(); + if(c1->getNumberOfTuples()<1) + throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !"); + if(c1->getInfoOnComponent(0)!="") + throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !"); + int f=c1->front(),ll=c1->back(); + if(f<0 || f>=sz2) + { + std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(ll<0 || ll>sz2) + { + std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(f>ll) + { + std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !"); + int szOfC1Exp=_conn_indx->back(); + if(sz2getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); + const DataArrayInt *c1(_conn),*c2(_conn_indx); + if(!c2->isMonotonic(true)) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !"); + // + int nbOfTuples=c1->getNumberOfTuples(); + int nbOfNodes=getNumberOfNodes(); + const int *w(c1->begin()); + for(int i=0;i=nbOfNodes) + { + std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency1(eps); +} + +int MEDCoupling1DGTUMesh::getNumberOfCells() const +{ + checkCoherency();//do not remove + return _conn_indx->getNumberOfTuples()-1; +} + +/*! + * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component. + * For each cell in \b this the number of nodes constituting cell is computed. + * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned. + * So for pohyhedrons some nodes can be counted several times in the returned result. + * + * \return a newly allocated array + */ +DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); + _conn_indx->checkMonotonic(true); + if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) + return _conn_indx->deltaShiftIndex(); + // for polyhedrons + int nbOfCells=_conn_indx->getNumberOfTuples()-1; + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *retPtr=ret->getPointer(); + const int *ci=_conn_indx->begin(),*c=_conn->begin(); + for(int i=0;igetNumberOfCells() tuples and 1 component. + * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed. + * + * \return a newly allocated array + */ +DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); + _conn_indx->checkMonotonic(true); + if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG) + return _conn_indx->deltaShiftIndex(); + if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG) + { + MEDCouplingAutoRefCountObjectPtr ret=_conn_indx->deltaShiftIndex(); + ret->applyDivideBy(2); + return ret.retn(); + } + // for polyhedrons + int nbOfCells=_conn_indx->getNumberOfTuples()-1; + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *retPtr=ret->getPointer(); + const int *ci=_conn_indx->begin(),*c=_conn->begin(); + for(int i=0;i& conn) const +{ + int nbOfCells=getNumberOfCells();//performs checks + if(cellId>=0 && cellIdgetIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0); + int nbOfNodes=stp-strt; + if(nbOfNodes<0) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !"); + conn.resize(nbOfNodes); + std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin()); + } + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +std::string MEDCoupling1DGTUMesh::simpleRepr() const +{ + static const char msg0[]="No coordinates specified !"; + std::ostringstream ret; + ret << "Single dynamic geometic type (" << _cm->getRepr() << ") 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 : "; + bool isOK=true; + try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e) + { + ret << "Nodal connectivity arrays are not set or badly set !\n"; + isOK=false; + } + if(isOK) + ret << getNumberOfCells() << "\n"; + ret << "Cell type : " << _cm->getRepr() << "\n"; + return ret.str(); +} + +std::string MEDCoupling1DGTUMesh::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\nNodal Connectivity : \n____________________\n\n"; + // + bool isOK=true; + try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& e) + { + ret << "Nodal connectivity arrays are not set or badly set !\n"; + isOK=false; + } + if(!isOK) + return ret.str(); + int nbOfCells=getNumberOfCells(); + const int *ci=_conn_indx->begin(),*c=_conn->begin(); + for(int i=0;i(ret," ")); + ret << "\n"; + } + return ret.str(); +} + +DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + int spaceDim=getSpaceDimension(); + int nbOfCells=getNumberOfCells();//checkCoherency() + int nbOfNodes=getNumberOfNodes(); + ret->alloc(nbOfCells,spaceDim); + double *ptToFill=ret->getPointer(); + const double *coor=_coords->begin(); + const int *nodal=_conn->begin(),*nodali=_conn_indx->begin(); + nodal+=nodali[0]; + if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) + { + for(int i=0;i=nodali[1])// >= to avoid division by 0. + { + for(int j=nodali[0];j=0 && *nodal()); + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::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(),1./(nodali[1]-nodali[0]))); + } + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + else + { + for(int i=0;i=nodali[1])// >= to avoid division by 0. + { + int nbOfNod=0; + for(int j=nodali[0];j=0 && *nodal()); + nbOfNod++; + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(nbOfNod!=0) + std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies(),1./nbOfNod)); + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + return ret.retn(); +} + +void MEDCoupling1DGTUMesh::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(),*conni=_conn_indx->begin(); + MEDCouplingAutoRefCountObjectPtr n2o=o2n->invertArrayO2N2N2O(nbCells); + const int *n2oPtr=n2o->begin(); + MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); + newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1); + newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx); + // + int *newC=newConn->getPointer(),*newCI=newConnI->getPointer(); + for(int i=0;i=0) + newCI[n2oPtr[i]]=sz; + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + newConnI->computeOffsets2(); newCI=newConnI->getPointer(); + // + for(int i=0;igetType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED) + throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !"); + const MEDCoupling1DGTUMesh *otherC=static_cast(other); + return Merge1DGTUMeshes(this,otherC); +} + +MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName(),getMeshDimension()); + ret->setCoords(getCoords()); + const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin(); + int nbCells=getNumberOfCells();//checkCoherency + int geoType=(int)getCellModelEnum(); + MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1); + MEDCouplingAutoRefCountObjectPtr cI=DataArrayInt::New(); cI->alloc(nbCells+1); + int *cPtr=c->getPointer(),*ciPtr=cI->getPointer(); + ciPtr[0]=0; + for(int i=0;i=0) + { + *cPtr++=geoType; + cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr); + ciPtr[1]=ciPtr[0]+sz+1; + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setConnectivity(c,cI,true); + return ret.retn(); +} + +/*! + * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes + */ +DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception) +{ + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + ret->iota(0); + return ret.retn(); +} + +void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\"."; + stream << " Mesh dimension : " << getMeshDimension() << "."; + if(!_coords) + { stream << " No coordinates set !"; return ; } + if(!_coords->isAllocated()) + { stream << " Coordinates set but not allocated !"; return ; } + stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl; + stream << "Number of nodes : " << _coords->getNumberOfTuples() << "."; + bool isOK=true; + try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e) + { + stream << std::endl << "Nodal connectivity NOT set properly !\n"; + isOK=false; + } + if(isOK) + stream << std::endl << "Number of cells : " << getNumberOfCells() << "."; +} + +void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !"); + const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !"); + setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex()); +} + +MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !"); + const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::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 Merge1DGTUMeshesOnSameCoords(ms); +} + +MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const +{ + checkCoherency(); + MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); + ret->setCoords(_coords); + DataArrayInt *c=0,*ci=0; + MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci); + MEDCouplingAutoRefCountObjectPtr cSafe(c),ciSafe(ci); + ret->setNodalConnectivity(c,ci); + return ret.retn(); +} + +MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const +{ + checkCoherency(); + MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); + ret->setCoords(_coords); + DataArrayInt *c=0,*ci=0; + MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci); + MEDCouplingAutoRefCountObjectPtr cSafe(c),ciSafe(ci); + ret->setNodalConnectivity(c,ci); + return ret.retn(); +} + +void MEDCoupling1DGTUMesh::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(),*conni=_conn_indx->begin(); + int nbOfCells=getNumberOfCells(); + int nbOfEltsInRevNodal=0; + for(int eltId=0;eltId=0) + { + for(int j=0;j=0 && nodeId()); + 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; + } + } +} + +void MEDCoupling1DGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception) +{ + if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined."); +} + +bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector& tinyInfo) const +{ + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !"); +} + +/*! + * 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 *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception) +{ + nbrOfNodesInUse=-1; + int nbOfNodes=getNumberOfNodes(); + int nbOfCells=getNumberOfCells();//checkCoherency + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(nbOfNodes,1); + int *traducer=ret->getPointer(); + std::fill(traducer,traducer+nbOfNodes,-1); + const int *conn=_conn->begin(),*conni(_conn_indx->begin()); + for(int i=0;i=0 && nodeIdgetNumberOfNodes(), 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 MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N) +{ + getNumberOfCells();//only to check that all is well defined. + // + int nbElemsIn=getNumberOfNodes(); + int nbOfTuples=_conn->getNumberOfTuples(); + int *pt=_conn->getPointer(); + for(int i=0;i=0 && *ptdeclareAsNew(); + // + updateTime(); +} + +/*! + * 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 \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 [\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 MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const +{ + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr 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(),*conni=_conn_indx->begin(); + for(int i=0;i=0) + { + for(int j=0;j=0) + { + ref++; + if(fastFinder[nodeId]) + nbOfHit++; + } + } + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn)) + cellIdsKept->pushBackSilent(i); + } + cellIdsKeptArr=cellIdsKept.retn(); +} + +void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception) +{ + if(nbOfCells<0) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !"); + _conn=DataArrayInt::New(); + _conn->reserve(nbOfCells*3); + _conn_indx=DataArrayInt::New(); + _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0); + 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 MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception) +{ + int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd); + DataArrayInt *c(_conn),*c2(_conn_indx); + if(c && c2) + { + int pos=c2->back(); + if(pos==c->getNumberOfTuples()) + { + c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd); + c2->pushBackSilent(pos+sz); + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !"); +} + +void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception) +{ + if(nodalConn) + nodalConn->incrRef(); + _conn=nodalConn; + if(nodalConnIndex) + nodalConnIndex->incrRef(); + _conn_indx=nodalConnIndex; + declareAsNew(); +} + +/*! + * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it. + */ +DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception) +{ + const DataArrayInt *ret(_conn); + return const_cast(ret); +} + +/*! + * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it. + */ +DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception) +{ + const DataArrayInt *ret(_conn_indx); + return const_cast(ret); +} + +/*! + * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here". + * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity). + * Geometrically the returned mesh is equal to \a this. So if \a this is already packed, the return value is a shallow copy of \a this. + * + * Whatever the status of pack of \a this, the coordinates array of the returned newly created instance is the same than those in \a this. + * + * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal + * connectivity arrays are different (false) + * \return a new object to be managed by the caller. + * + * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked + */ +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); + DataArrayInt *nc=0,*nci=0; + isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci); + MEDCouplingAutoRefCountObjectPtr ncs(nc),ncis(nci); + ret->_conn=ncs; ret->_conn_indx=ncis; + ret->setCoords(getCoords()); + return ret.retn(); +} + +/*! + * This method allows to compute, if needed, the packed nodal connectivity pair. + * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array. + * It is typically the case when nodalConnIndx starts with an id greater than 0, and finishes with id less than number of tuples in \c this->_conn. + * + * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array) + * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case. + * + * If nodal connectivity index points to a subpart of nodal connectivity index the packed pair of arrays will be computed (new objects) and returned and false + * will be returned. + * + * This method return 3 elements. + * \param [out] nodalConn - a pointer that can be equal to \a this->_conn if true is returned (general case). Whatever the value of return parameter + * this pointer can be seen as a new object, that is to managed by the caller. + * \param [out] nodalConnIndx - a pointer that can be equal to \a this->_conn_indx if true is returned (general case). Whatever the value of return parameter + * this pointer can be seen as a new object, that is to managed by the caller. + * \return bool - an indication of the content of the 2 output parameters. If true, \a this looks packed (general case), if true, \a this is not packed then + * output parameters are newly created objects. + * + * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test + */ +bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const throw(INTERP_KERNEL::Exception) +{ + if(isPacked())//performs the checkCoherency + { + const DataArrayInt *c0(_conn),*c1(_conn_indx); + nodalConn=const_cast(c0); nodalConnIndx=const_cast(c1); + nodalConn->incrRef(); nodalConnIndx->incrRef(); + return true; + } + int bg=_conn_indx->front(),end=_conn_indx->back(); + MEDCouplingAutoRefCountObjectPtr nc(_conn->selectByTupleId2(bg,end,1)); + MEDCouplingAutoRefCountObjectPtr nci(_conn_indx->deepCpy()); + nci->applyLin(1,-bg); + nodalConn=nc.retn(); nodalConnIndx=nci.retn(); + return false; +} + +/* + * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array) + * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case. + * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned. + * \return bool - true if \a this looks packed, false is not. + * + * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test + */ +bool MEDCoupling1DGTUMesh::isPacked() const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); + return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples(); +} + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) throw(INTERP_KERNEL::Exception) +{ + std::vector tmp(2); + tmp[0]=const_cast(mesh1); tmp[1]=const_cast(mesh2); + return Merge1DGTUMeshes(tmp); +} + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector& a) throw(INTERP_KERNEL::Exception) +{ + std::size_t sz=a.size(); + if(sz==0) + return Merge1DGTUMeshesLL(a); + for(std::size_t ii=0;iigetCellModel()); + for(std::size_t ii=0;iigetCellModel())!=cm) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > bb(sz); + std::vector< const MEDCoupling1DGTUMesh * > aa(sz); + int spaceDim=-3; + for(std::size_t i=0;igetCoords(); + if(coo) + spaceDim=coo->getNumberOfComponents(); + } + if(spaceDim==-3) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !"); + for(std::size_t i=0;ibuildSetInstanceFromThis(spaceDim); + aa[i]=bb[i]; + } + return Merge1DGTUMeshesLL(aa); +} + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector& a) throw(INTERP_KERNEL::Exception) +{ + if(a.empty()) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !"); + std::vector::const_iterator it=a.begin(); + if(!(*it)) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > objs(a.size()); + std::vector ncs(a.size()),ncis(a.size()); + int nbOfCells=(*it)->getNumberOfCells(); + const DataArrayDouble *coords=(*it)->getCoords(); + const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); + bool tmp; + objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp); + ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex(); + it++; + for(int i=1;it!=a.end();i++,it++) + { + if(cm!=&((*it)->getCellModel())) + throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !"); + (*it)->getNumberOfCells();//to check that all is OK + objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp); + ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex(); + if(coords!=(*it)->getCoords()) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !"); + } + MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh("merge",*cm)); + ret->setCoords(coords); + ret->_conn=DataArrayInt::Aggregate(ncs); + ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis); + return ret.retn(); +} + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector& a) throw(INTERP_KERNEL::Exception) +{ + //tony +} + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); + MEDCouplingAutoRefCountObjectPtr tmp1,tmp2; + const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx); + if(!nodalConn) + { + tmp1=DataArrayInt::New(); tmp1->alloc(0,1); + } + else + tmp1=_conn; + ret->_conn=tmp1; + // + if(!nodalConnI) + { + tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0); + } + else + tmp2=_conn_indx; + ret->_conn_indx=tmp2; + // + if(!_coords) + { + MEDCouplingAutoRefCountObjectPtr coords=DataArrayDouble::New(); coords->alloc(0,spaceDim); + ret->setCoords(coords); + } + else + ret->setCoords(_coords); + return ret.retn(); +} diff --git a/src/MEDCoupling/MEDCoupling1GTUMesh.hxx b/src/MEDCoupling/MEDCoupling1GTUMesh.hxx index 5b4eba07e..867071333 100644 --- a/src/MEDCoupling/MEDCoupling1GTUMesh.hxx +++ b/src/MEDCoupling/MEDCoupling1GTUMesh.hxx @@ -49,6 +49,7 @@ namespace ParaMEDMEM 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 std::size_t getHeapMemorySize() 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 checkCoherency() const throw(INTERP_KERNEL::Exception); @@ -63,6 +64,9 @@ namespace ParaMEDMEM 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); + public: + MEDCOUPLING_EXPORT virtual void allocateCells(int nbOfCells=0) throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual void insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception) = 0; protected: MEDCOUPLING_EXPORT MEDCoupling1GTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm); MEDCOUPLING_EXPORT MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy); @@ -102,8 +106,6 @@ namespace ParaMEDMEM // 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 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); @@ -112,22 +114,21 @@ namespace ParaMEDMEM 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: + // overload of MEDCoupling1GTUMesh + 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); + public://specific + MEDCOUPLING_EXPORT void setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() const throw(INTERP_KERNEL::Exception); 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); - virtual ~MEDCoupling1SGTUMesh() { } private: void checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception); static MEDCoupling1SGTUMesh *Merge1SGTUMeshesLL(std::vector& a) throw(INTERP_KERNEL::Exception); @@ -138,6 +139,71 @@ namespace ParaMEDMEM private: MEDCouplingAutoRefCountObjectPtr _conn; }; + + class MEDCoupling1DGTUMesh : public MEDCoupling1GTUMesh + { + public: + MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT MEDCoupling1DGTUMesh *clone(bool recDeepCpy) const; + // 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_DYNAMIC_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 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 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 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 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; + // overload of MEDCoupling1GTUMesh + 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); + public://specific + MEDCOUPLING_EXPORT void setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT MEDCoupling1DGTUMesh *copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isPacked() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *Merge1DGTUMeshes(std::vector& a) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *Merge1DGTUMeshesOnSameCoords(std::vector& a) throw(INTERP_KERNEL::Exception); + MEDCoupling1DGTUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); + private: + MEDCOUPLING_EXPORT MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm); + MEDCOUPLING_EXPORT MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy); + private: + void checkDynamicGeoType() const throw(INTERP_KERNEL::Exception); + static MEDCoupling1DGTUMesh *Merge1DGTUMeshesLL(std::vector& a) throw(INTERP_KERNEL::Exception); + private: + MEDCouplingAutoRefCountObjectPtr _conn_indx; + MEDCouplingAutoRefCountObjectPtr _conn; + }; } #endif diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index f6f5243bd..aa04149d7 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -2683,6 +2683,24 @@ double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_K return _mem[tupleId*_info_on_compo.size()+compoId]; } +/*! + * Returns the first value of \a this. + * \return double - the last value of \a this array. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() < 1. + */ +double DataArrayDouble::front() const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<1) + throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !"); + return *(getConstPointer()); +} + /*! * Returns the last value of \a this. * \return double - the last value of \a this array. @@ -5816,7 +5834,7 @@ void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd *pt=indArrBg[*pt]; else { - std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn; + std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } } @@ -7811,9 +7829,27 @@ int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL: return _mem[tupleId*_info_on_compo.size()+compoId]; } +/*! + * Returns the first value of \a this. + * \return int - the last value of \a this array. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() < 1. + */ +int DataArrayInt::front() const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<1) + throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !"); + return *(getConstPointer()); +} + /*! * Returns the last value of \a this. - * \return double - the last value of \a this array. + * \return int - the last value of \a this array. * \throw If \a this is not allocated. * \throw If \a this->getNumberOfComponents() != 1. * \throw If \a this->getNumberOfTuples() < 1. @@ -8300,6 +8336,57 @@ DataArrayInt *DataArrayInt::Aggregate(const std::vector& a return ret.retn(); } +/*! + * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays. + * A packed index array is an allocated array with one component, and at least one tuple. The first element + * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic. + * This method is useful for users that want to aggregate a pair of DataArrayInt representing an indexed data (typically nodal connectivity index in unstructured meshes. + * + * \return DataArrayInt * - a new object to be managed by the caller. + */ +DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector& arrs) throw(INTERP_KERNEL::Exception) +{ + int retSz=1; + for(std::vector::const_iterator it4=arrs.begin();it4!=arrs.end();it4++) + { + if(*it4) + { + (*it4)->checkAllocated(); + if((*it4)->getNumberOfComponents()!=1) + { + std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbTupl=(*it4)->getNumberOfTuples(); + if(nbTupl<1) + { + std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if((*it4)->front()!=0) + { + std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + retSz+=nbTupl-1; + } + else + { + std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(arrs.empty()) + throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !"); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(retSz,1); + int *pt=ret->getPointer(); *pt++=0; + for(std::vector::const_iterator it=arrs.begin();it!=arrs.end();it++) + pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus(),pt[-1])); + ret->copyStringInfoFrom(*(arrs[0])); + return ret.retn(); +} + /*! * Returns the maximal value and its location within \a this one-dimensional array. * \param [out] tupleId - index of the tuple holding the maximal value. @@ -9057,6 +9144,7 @@ DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception) * "MEDCouplingUMesh::buildDescendingConnectivity" and * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex * "MEDCouplingUMesh::getNodalConnectivityIndex" etc. + * This method preforms the reverse operation of DataArrayInt::computeOffsets2. * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples * equals to \a this->getNumberOfComponents() - 1, and number of components is 1. * The caller is to delete this array using decrRef() as it is no more needed. @@ -9068,6 +9156,8 @@ DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception) * - this contains [1,3,6,7,7,9,15] * - result array contains [2,3,1,0,2,6], * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc. + * + * \sa DataArrayInt::computeOffsets2 */ DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception) { @@ -9130,12 +9220,14 @@ void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception) * components remains the same and number of tuples is inceamented by one.
* This method is useful for allToAllV in MPI with contiguous policy. This method * differs from computeOffsets() in that the number of tuples is changed by this one. + * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex. * \throw If \a this is not allocated. * \throw If \a this->getNumberOfComponents() != 1. * * \b Example:
* - Before \a this contains [3,5,1,2,0,8] * - After \a this contains [0,3,8,9,11,11,19]
+ * \sa DataArrayInt::deltaShiftIndex */ void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception) { diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index 713df678d..ec19ea017 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -264,6 +264,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getTuple(int tupleId, double *res) const throw(INTERP_KERNEL::Exception) { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } MEDCOUPLING_EXPORT double getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } + MEDCOUPLING_EXPORT double front() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double back() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, double newVal) throw(INTERP_KERNEL::Exception) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } @@ -497,6 +498,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void getTuple(int tupleId, int *res) const throw(INTERP_KERNEL::Exception) { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } MEDCOUPLING_EXPORT int getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) { return _mem[tupleId*_info_on_compo.size()+compoId]; } MEDCOUPLING_EXPORT int getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int front() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int back() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, int newVal) throw(INTERP_KERNEL::Exception) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, int newVal) throw(INTERP_KERNEL::Exception) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } @@ -540,6 +542,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT bool checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2); MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const std::vector& arr) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayInt *AggregateIndexes(const std::vector& arrs) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *Meld(const std::vector& arr) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *MakePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups) throw(INTERP_KERNEL::Exception); @@ -686,6 +689,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void getTuple(int tupleId, char *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } MEDCOUPLING_EXPORT char getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } MEDCOUPLING_EXPORT char getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT char front() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT char back() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, char newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, char newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } diff --git a/src/MEDCoupling/MEDCouplingMemArrayChar.cxx b/src/MEDCoupling/MEDCouplingMemArrayChar.cxx index dccae5d95..37f69d28f 100644 --- a/src/MEDCoupling/MEDCouplingMemArrayChar.cxx +++ b/src/MEDCoupling/MEDCouplingMemArrayChar.cxx @@ -1456,9 +1456,27 @@ char DataArrayChar::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNE return _mem[tupleId*_info_on_compo.size()+compoId]; } +/*! + * Returns the first value of \a this. + * \return char - the last value of \a this array. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() < 1. + */ +char DataArrayChar::front() const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayChar::front : number of components not equal to one !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<1) + throw INTERP_KERNEL::Exception("DataArrayChar::front : number of tuples must be >= 1 !"); + return *(getConstPointer()); +} + /*! * Returns the last value of \a this. - * \return double - the last value of \a this array. + * \return char - the last value of \a this array. * \throw If \a this is not allocated. * \throw If \a this->getNumberOfComponents() != 1. * \throw If \a this->getNumberOfTuples() < 1. diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index 204111cb6..1f9f0189b 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -1537,3 +1537,52 @@ DataArrayInt *MEDCouplingPointSet::zipCoordsTraducer() throw(INTERP_KERNEL::Exce renumberNodes(traducer->getConstPointer(),newNbOfNodes); return traducer.retn(); } + +/*! + * Merges nodes equal within \a precision and returns an array describing the + * permutation used to remove duplicate nodes. + * \param [in] precision - minimal absolute distance between two nodes at which they are + * considered not coincident. + * \param [out] areNodesMerged - is set to \c true if any coincident nodes removed. + * \param [out] newNbOfNodes - number of nodes remaining after the removal. + * \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. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * + * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".
+ * \ref py_mcumesh_mergeNodes "Here is a Python example". + */ +DataArrayInt *MEDCouplingPointSet::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) +{ + MEDCouplingAutoRefCountObjectPtr ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); + if(areNodesMerged) + renumberNodes(ret->begin(),newNbOfNodes); + return ret.retn(); +} + +/*! + * Merges nodes equal within \a precision and returns an array describing the + * permutation used to remove duplicate nodes. In contrast to mergeNodes(), location + * of merged nodes is changed to be at their barycenter. + * \param [in] precision - minimal absolute distance between two nodes at which they are + * considered not coincident. + * \param [out] areNodesMerged - is set to \c true if any coincident nodes removed. + * \param [out] newNbOfNodes - number of nodes remaining after the removal. + * \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. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * + * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".
+ * \ref py_mcumesh_mergeNodes "Here is a Python example". + */ +DataArrayInt *MEDCouplingPointSet::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) +{ + DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); + if(areNodesMerged) + renumberNodes2(ret->getConstPointer(),newNbOfNodes); + return ret; +} diff --git a/src/MEDCoupling/MEDCouplingPointSet.hxx b/src/MEDCoupling/MEDCouplingPointSet.hxx index a815d8508..e9e265881 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.hxx +++ b/src/MEDCoupling/MEDCouplingPointSet.hxx @@ -71,8 +71,8 @@ namespace ParaMEDMEM 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 DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); + virtual DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes); 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; diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 754a7d797..26fd3a45b 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -1820,56 +1820,6 @@ bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataAr return true; } -/*! - * Merges nodes equal within \a precision and returns an array describing the - * permutation used to remove duplicate nodes. - * \param [in] precision - minimal absolute distance between two nodes at which they are - * considered not coincident. - * \param [out] areNodesMerged - is set to \c true if any coincident nodes removed. - * \param [out] newNbOfNodes - number of nodes remaining after the removal. - * \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. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".
- * \ref py_mcumesh_mergeNodes "Here is a Python example". - */ -DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) -{ - MEDCouplingAutoRefCountObjectPtr ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); - if(areNodesMerged) - renumberNodes(ret->begin(),newNbOfNodes); - return ret.retn(); -} - - -/*! - * Merges nodes equal within \a precision and returns an array describing the - * permutation used to remove duplicate nodes. In contrast to mergeNodes(), location - * of merged nodes is changed to be at their barycenter. - * \param [in] precision - minimal absolute distance between two nodes at which they are - * considered not coincident. - * \param [out] areNodesMerged - is set to \c true if any coincident nodes removed. - * \param [out] newNbOfNodes - number of nodes remaining after the removal. - * \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. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".
- * \ref py_mcumesh_mergeNodes "Here is a Python example". - */ -DataArrayInt *MEDCouplingUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) -{ - DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); - if(areNodesMerged) - renumberNodes2(ret->getConstPointer(),newNbOfNodes); - return ret; -} - MEDCouplingPointSet *MEDCouplingUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const { if(!other) @@ -8684,16 +8634,22 @@ bool MEDCouplingUMesh::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, cons * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn * \param [out] arrOut the resulting array * \param [out] arrIndexOut the index array of the resulting array \b arrOut + * \sa MEDCouplingUMesh::ExtractFromIndexedArrays2 */ void MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception) { if(!arrIn || !arrIndxIn) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input pointer is NULL !"); + arrIn->checkAllocated(); arrIndxIn->checkAllocated(); + if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input arrays must have exactly one component !"); std::size_t sz=std::distance(idsOfSelectBg,idsOfSelectEnd); const int *arrInPtr=arrIn->getConstPointer(); const int *arrIndxPtr=arrIndxIn->getConstPointer(); int nbOfGrps=arrIndxIn->getNumberOfTuples()-1; + if(nbOfGrps<0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !"); int maxSizeOfArr=arrIn->getNumberOfTuples(); MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); @@ -8738,6 +8694,78 @@ void MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const arrIndexOut=arrIo.retn(); } +/*! + * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. + * This method returns the result of the extraction ( specified by a set of ids with a slice given by \a idsOfSelectStart, \a idsOfSelectStop and \a idsOfSelectStep ). + * The selection of extraction is done standardly in new2old format. + * This method returns indexed arrays using 2 arrays (arrOut,arrIndexOut). + * + * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included) + * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded) + * \param [in] arrIn arr origin array from which the extraction will be done. + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn + * \param [out] arrOut the resulting array + * \param [out] arrIndexOut the index array of the resulting array \b arrOut + * \sa MEDCouplingUMesh::ExtractFromIndexedArrays + */ +void MEDCouplingUMesh::ExtractFromIndexedArrays2(int idsOfSelectStart, int idsOfSelectStop, int idsOfSelectStep, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception) +{ + if(!arrIn || !arrIndxIn) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : input pointer is NULL !"); + arrIn->checkAllocated(); arrIndxIn->checkAllocated(); + if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : input arrays must have exactly one component !"); + int sz=DataArrayInt::GetNumberOfItemGivenBESRelative(idsOfSelectStart,idsOfSelectStop,idsOfSelectStep,"MEDCouplingUMesh::ExtractFromIndexedArrays2 : Input slice "); + const int *arrInPtr=arrIn->getConstPointer(); + const int *arrIndxPtr=arrIndxIn->getConstPointer(); + int nbOfGrps=arrIndxIn->getNumberOfTuples()-1; + if(nbOfGrps<0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !"); + int maxSizeOfArr=arrIn->getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); + arrIo->alloc((int)(sz+1),1); + int idsIt=idsOfSelectStart; + int *work=arrIo->getPointer(); + *work++=0; + int lgth=0; + for(std::size_t i=0;i=0 && idsIt=work[-1]) + *work=lgth; + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " and at this pos arrIndxIn[" << idsIt; + oss << "+1]-arrIndxIn[" << idsIt << "] < 0 ! The input index array is bugged !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + arro->alloc(lgth,1); + work=arro->getPointer(); + idsIt=idsOfSelectStart; + for(std::size_t i=0;i=0 && arrIndxPtr[idsIt+1]<=maxSizeOfArr) + work=std::copy(arrInPtr+arrIndxPtr[idsIt],arrInPtr+arrIndxPtr[idsIt+1],work); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " arrIndx[" << idsIt << "] must be >= 0 and arrIndx["; + oss << idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + arrOut=arro.retn(); + arrIndexOut=arrIo.retn(); +} + /*! * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index ce2d83637..f16d212d6 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -119,8 +119,6 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static void ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI, DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); - MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes); MEDCOUPLING_EXPORT MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *begin, 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); @@ -232,6 +230,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static bool RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval=0) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static void ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static void ExtractFromIndexedArrays2(int idsOfSelectStart, int idsOfSelectStop, int idsOfSelectStep, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static void SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx index 755b433b1..e712dd004 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx @@ -386,20 +386,6 @@ DataArrayInt *MEDCouplingUMeshDesc::getCellsInBoundingBox(const INTERP_KERNEL::D return elems.retn(); } -DataArrayInt *MEDCouplingUMeshDesc::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); - areNodesMerged=false; - return 0; -} - -DataArrayInt *MEDCouplingUMeshDesc::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); - areNodesMerged=false; - return 0; -} - MEDCouplingPointSet *MEDCouplingUMeshDesc::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const { throw INTERP_KERNEL::Exception("Not implemented yet !"); diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx index c71e83366..62bdbcf11 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx @@ -70,8 +70,6 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const; 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 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; diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index 1b9d202ea..60883c988 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -389,6 +389,12 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCoupling1SGTUMesh::buildSetInstanceFromThis; %newobject ParaMEDMEM::MEDCoupling1SGTUMesh::Merge1SGTUMeshes; %newobject ParaMEDMEM::MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords; +%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::New; +%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::getNodalConnectivity; +%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::getNodalConnectivityIndex; +%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::buildSetInstanceFromThis; +%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::Merge1DGTUMeshes; +%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords; %newobject ParaMEDMEM::MEDCouplingExtrudedMesh::New; %newobject ParaMEDMEM::MEDCouplingExtrudedMesh::build3DUnstructuredMesh; %newobject ParaMEDMEM::MEDCouplingCMesh::New; @@ -408,6 +414,7 @@ using namespace INTERP_KERNEL; %feature("unref") MEDCouplingUMesh "$this->decrRef();" %feature("unref") MEDCoupling1GTUMesh "$this->decrRef();" %feature("unref") MEDCoupling1SGTUMesh "$this->decrRef();" +%feature("unref") MEDCoupling1DGTUMesh "$this->decrRef();" %feature("unref") MEDCouplingExtrudedMesh "$this->decrRef();" %feature("unref") MEDCouplingCMesh "$this->decrRef();" %feature("unref") DataArrayInt "$this->decrRef();" @@ -2192,6 +2199,37 @@ namespace ParaMEDMEM return ret; } + static PyObject *ExtractFromIndexedArrays2(int strt, int stp, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception) + { + DataArrayInt *arrOut=0,*arrIndexOut=0; + MEDCouplingUMesh::ExtractFromIndexedArrays2(strt,stp,step,arrIn,arrIndxIn,arrOut,arrIndexOut); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + static PyObject *ExtractFromIndexedArrays2(PyObject *slic, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception) + { + if(!PySlice_Check(slic)) + throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : the first param is not a pyslice !"); + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *sliC=reinterpret_cast(slic); + if(!arrIndxIn) + throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : last array is null !"); + arrIndxIn->checkAllocated(); + if(arrIndxIn->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : number of components of last argument must be equal to one !"); + if(PySlice_GetIndices(sliC,arrIndxIn->getNumberOfTuples(),&strt,&stp,&step)!=0) + throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : Invalid slice regarding nb of elements !"); + DataArrayInt *arrOut=0,*arrIndexOut=0; + MEDCouplingUMesh::ExtractFromIndexedArrays2(strt,stp,step,arrIn,arrIndxIn,arrOut,arrIndexOut); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + static PyObject *SetPartOfIndexedArrays(PyObject *li, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception) @@ -2652,6 +2690,17 @@ namespace ParaMEDMEM public: static MEDCoupling1GTUMesh *New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); INTERP_KERNEL::NormalizedCellType getCellModelEnum() const throw(INTERP_KERNEL::Exception); + virtual void allocateCells(int nbOfCells=0) throw(INTERP_KERNEL::Exception); + %extend + { + virtual 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); + } + } }; //== MEDCoupling1SGTUMesh @@ -2661,7 +2710,6 @@ namespace ParaMEDMEM 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); @@ -2692,14 +2740,6 @@ namespace ParaMEDMEM 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; @@ -2715,9 +2755,93 @@ namespace ParaMEDMEM } } }; - + //== MEDCoupling1SGTUMesh End + //== MEDCoupling1DGTUMesh + + class MEDCoupling1DGTUMesh : public ParaMEDMEM::MEDCoupling1GTUMesh + { + public: + static MEDCoupling1DGTUMesh *New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); + void setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception); + MEDCoupling1DGTUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); + bool isPacked() const throw(INTERP_KERNEL::Exception); + %extend + { + MEDCoupling1DGTUMesh(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception) + { + return MEDCoupling1DGTUMesh::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; + } + + DataArrayInt *getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret=self->getNodalConnectivityIndex(); + if(ret) ret->incrRef(); + return ret; + } + + PyObject *retrievePackedNodalConnectivity() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0,*ret2=0; + bool ret0=self->retrievePackedNodalConnectivity(ret1,ret2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyObject *ret=PyTuple_New(3); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(ret2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *copyWithNodalConnectivityPacked() const throw(INTERP_KERNEL::Exception) + { + bool ret1; + MEDCoupling1DGTUMesh *ret0=self->copyWithNodalConnectivityPacked(ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret1Py=ret1?Py_True:Py_False; Py_XINCREF(ret1Py); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,ret1Py); + return ret; + } + + static MEDCoupling1DGTUMesh *Merge1DGTUMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh,"MEDCoupling1DGTUMesh",tmp); + return MEDCoupling1DGTUMesh::Merge1DGTUMeshes(tmp); + } + + static MEDCoupling1DGTUMesh *Merge1DGTUMeshesOnSameCoords(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh,"MEDCoupling1DGTUMesh",tmp); + return MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(tmp); + } + } + }; + + //== MEDCoupling1DGTUMeshEnd + class MEDCouplingStructuredMesh : public ParaMEDMEM::MEDCouplingMesh { public: diff --git a/src/MEDCoupling_Swig/MEDCouplingMemArray.i b/src/MEDCoupling_Swig/MEDCouplingMemArray.i index 569240dff..53fbb05e5 100644 --- a/src/MEDCoupling_Swig/MEDCouplingMemArray.i +++ b/src/MEDCoupling_Swig/MEDCouplingMemArray.i @@ -302,6 +302,7 @@ namespace ParaMEDMEM void setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception); void setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); double getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); + double front() const throw(INTERP_KERNEL::Exception); double back() const throw(INTERP_KERNEL::Exception); double getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); void setIJ(int tupleId, int compoId, double newVal) throw(INTERP_KERNEL::Exception); @@ -2321,6 +2322,7 @@ namespace ParaMEDMEM void getTuple(int tupleId, int *res) const throw(INTERP_KERNEL::Exception); int getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); int getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); + int front() const throw(INTERP_KERNEL::Exception); int back() const throw(INTERP_KERNEL::Exception); void setIJ(int tupleId, int compoId, int newVal) throw(INTERP_KERNEL::Exception); void setIJSilent(int tupleId, int compoId, int newVal) throw(INTERP_KERNEL::Exception); @@ -2918,6 +2920,13 @@ namespace ParaMEDMEM return DataArrayInt::Aggregate(tmp); } + static DataArrayInt *AggregateIndexes(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); + return DataArrayInt::AggregateIndexes(tmp); + } + static DataArrayInt *BuildUnion(PyObject *li) throw(INTERP_KERNEL::Exception) { std::vector tmp; @@ -4564,6 +4573,7 @@ namespace ParaMEDMEM DataArrayChar *changeNbOfComponents(int newNbOfComp, char dftValue) const throw(INTERP_KERNEL::Exception); void meldWith(const DataArrayChar *other) throw(INTERP_KERNEL::Exception); void setPartOfValuesAdv(const DataArrayChar *a, const DataArrayChar *tuplesSelec) throw(INTERP_KERNEL::Exception); + char front() const throw(INTERP_KERNEL::Exception); char back() const throw(INTERP_KERNEL::Exception); void setIJ(int tupleId, int compoId, char newVal) throw(INTERP_KERNEL::Exception); void setIJSilent(int tupleId, int compoId, char newVal) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i index 27a6de03e..ace73d104 100644 --- a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i +++ b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i @@ -419,6 +419,8 @@ static PyObject *convertMesh(ParaMEDMEM::MEDCouplingMesh *mesh, int owner) throw 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__MEDCoupling1DGTUMesh,owner); if(dynamic_cast(mesh)) ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingExtrudedMesh,owner); if(dynamic_cast(mesh)) -- 2.39.2