From 8074f62b7d5b54a5e0ce41393404f8bdb11c0a12 Mon Sep 17 00:00:00 2001 From: ageay Date: Tue, 3 Jul 2012 11:01:44 +0000 Subject: [PATCH] BuildPart on range of cell ids. --- src/MEDCoupling/MEDCouplingMemArray.cxx | 33 +++ src/MEDCoupling/MEDCouplingMemArray.hxx | 1 + src/MEDCoupling/MEDCouplingPointSet.hxx | 1 + src/MEDCoupling/MEDCouplingUMesh.cxx | 265 +++++++++++++++++- src/MEDCoupling/MEDCouplingUMesh.hxx | 10 +- src/MEDCoupling/MEDCouplingUMeshDesc.cxx | 6 + src/MEDCoupling/MEDCouplingUMeshDesc.hxx | 1 + .../Test/MEDCouplingBasicsTest5.cxx | 46 +++ .../Test/MEDCouplingBasicsTest5.hxx | 2 + src/MEDCoupling_Swig/MEDCouplingBasicsTest.py | 26 +- src/MEDCoupling_Swig/MEDCouplingCommon.i | 69 ++++- 11 files changed, 446 insertions(+), 14 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 5f0967631..0e7fac3d4 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -369,6 +369,39 @@ int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, con return 0; } +int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception) +{ + if(step!=0) + { + if(step>0) + { + if(begin<=value && end=value && end>value) + { + if((begin-value)%(-step)==0) + return (begin-value)/(-step); + else + return -1; + } + else + return -1; + } + } + else + return -1; +} + DataArrayDouble *DataArrayDouble::New() { return new DataArrayDouble; diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index 13a93f9bb..a7c1b4e04 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -114,6 +114,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void checkNbOfElems(int nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static int GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static int GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static int GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static std::string GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static std::string GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception); protected: diff --git a/src/MEDCoupling/MEDCouplingPointSet.hxx b/src/MEDCoupling/MEDCouplingPointSet.hxx index df09cacb7..18b200ec6 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.hxx +++ b/src/MEDCoupling/MEDCouplingPointSet.hxx @@ -94,6 +94,7 @@ namespace ParaMEDMEM MEDCouplingMesh *buildPart(const int *start, const int *end) const; MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords=true) const = 0; + virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const throw(INTERP_KERNEL::Exception) = 0; virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0; virtual MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0; virtual DataArrayInt *findBoundaryNodes() const = 0; diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index a8b16f9ec..8f8de1c6f 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -1634,7 +1634,36 @@ void MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& ot } /*! - * build a sub part of 'this'. This sub part is defined by the cell ids contained in the array in [begin,end). + * Build a sub part of \b this lying or not on the same coordinates than \b this (regarding value of \b keepCoords). + * By default coordinates are kept. This method is close to MEDCouplingUMesh::buildPartOfMySelf except that here input + * cellIds is not given explicitely but by a range python like. + * + * \param keepCoords that specifies if you want or not to keep coords as this or zip it (see ParaMEDMEM::MEDCouplingUMesh::zipCoords). If true zipCoords is \b NOT called, if false, zipCoords is called. + * \return a newly allocated + */ +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const throw(INTERP_KERNEL::Exception) +{ + if(getMeshDimension()!=-1) + { + MEDCouplingUMesh *ret=buildPartOfMySelfKeepCoords2(start,end,step); + if(!keepCoords) + ret->zipCoords(); + return ret; + } + else + { + int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelf2 for -1 dimension mesh "); + if(newNbOfCells!=1) + throw INTERP_KERNEL::Exception("-1D mesh has only one cell !"); + if(start!=0) + throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !"); + incrRef(); + return const_cast(this); + } +} + +/*! + * build a sub part of \b this. This sub part is defined by the cell ids contained in the array in [begin,end). * @param begin begin of array containing the cell ids to keep. * @param end end of array of cell ids to keep. \b WARNING end param is \b not included ! Idem STL standard definitions. * @param keepCoords that specifies if you want or not to keep coords as this or zip it (see ParaMEDMEM::MEDCouplingUMesh::zipCoords). If true zipCoords is \b NOT called, if false, zipCoords is called. @@ -1708,7 +1737,10 @@ void MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsE } } if(easyAssign) - MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(cellIdsBg,cellIdsEnd,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index); + { + MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(cellIdsBg,cellIdsEnd,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index); + computeTypes(); + } else { DataArrayInt *arrOut=0,*arrIOut=0; @@ -1718,6 +1750,57 @@ void MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsE } } +void MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception) +{ + checkConnectivityFullyDefined(); + otherOnSameCoordsThanThis.checkConnectivityFullyDefined(); + if(getCoords()!=otherOnSameCoordsThanThis.getCoords()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf2 : coordinates pointer are not the same ! Invoke setCoords or call tryToShareSameCoords method !"); + if(getMeshDimension()!=otherOnSameCoordsThanThis.getMeshDimension()) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : Mismatch of meshdimensions ! this is equal to " << getMeshDimension(); + oss << ", whereas other mesh dimension is set equal to " << otherOnSameCoordsThanThis.getMeshDimension() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfCellsToModify=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::setPartOfMySelf2 : "); + if(nbOfCellsToModify!=otherOnSameCoordsThanThis.getNumberOfCells()) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : cells ids length (" << nbOfCellsToModify << ") do not match the number of cells of other mesh (" << otherOnSameCoordsThanThis.getNumberOfCells() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfCells=getNumberOfCells(); + bool easyAssign=true; + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const int *connOther=otherOnSameCoordsThanThis._nodal_connec->getConstPointer(); + const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer(); + int it=start; + for(int i=0;i=0 && it cellIdsKept; @@ -2724,7 +2807,63 @@ void MEDCouplingUMesh::unserialization(const std::vector& tinyInfoD, con } /*! - * This is the low algorithm of buildPartOfMySelf. + * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf2. + * CellIds are given using range specified by a start an end and step. + */ +MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const +{ + checkFullyDefined(); + int ncell=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(); + ret->_mesh_dim=_mesh_dim; + ret->setCoords(_coords); + int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelfKeepCoords2 : "); + MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(newNbOfCells+1,1); + int *newConnIPtr=newConnI->getPointer(); *newConnIPtr=0; + int work=start; + const int *conn=_nodal_connec->getConstPointer(); + const int *connIndex=_nodal_connec_index->getConstPointer(); + for(int i=0;i=0 && work newConn=DataArrayInt::New(); newConn->alloc(newConnIPtr[0],1); + int *newConnPtr=newConn->getPointer(); + std::set types; + work=start; + for(int i=0;isetConnectivity(newConn,newConnI,false); + ret->_types=types; + ret->copyTinyInfoFrom(this); + std::string name(getName()); + std::size_t sz=strlen(PART_OF_NAME); + if(name.length()>=sz) + name=name.substr(0,sz); + if(name!=PART_OF_NAME) + { + std::ostringstream stream; stream << PART_OF_NAME << getName(); + ret->setName(stream.str().c_str()); + } + else + ret->setName(getName()); + ret->incrRef(); + return ret; +} + +/*! + * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf. * Keeps from 'this' only cells which constituing point id are in the ids specified by ['begin','end'). * The return newly allocated mesh will share the same coordinates as 'this'. */ @@ -5702,7 +5841,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const std::vectorgetCoords(); @@ -7016,7 +7155,7 @@ void MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const in } else { - std::size_t pos=(int)std::distance(idsOfSelectBg,std::find(idsOfSelectBg,idsOfSelectEnd,ii)); + std::size_t pos=std::distance(idsOfSelectBg,std::find(idsOfSelectBg,idsOfSelectEnd,ii)); arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr); *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]); } @@ -7056,13 +7195,13 @@ void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, c std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[*it]); else { - std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArrays : On pos #" << std::distance(idsOfSelectBg,it) << " id (idsOfSelectBg[" << std::distance(idsOfSelectBg,it)<< "]) is " << *it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !"; + std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " id (idsOfSelectBg[" << std::distance(idsOfSelectBg,it)<< "]) is " << *it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } } else { - std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArrays : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !"; + std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } } @@ -7116,6 +7255,118 @@ DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *a return arro->getIdsEqual(1); } +/*! + * 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 + * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex). + * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays. + * + * \param [in] start begin of set of ids of the input extraction (included) + * \param [in] end end of set of ids of the input extraction (excluded) + * \param [in] step step of the set of ids in range mode. + * \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 [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd) + * \param [in] srcArrIndex index array of \b srcArr + * \param [out] arrOut the resulting array + * \param [out] arrIndexOut the index array of the resulting array \b arrOut + * + * \sa MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx MEDCouplingUMesh::SetPartOfIndexedArrays + */ +void MEDCouplingUMesh::SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception) +{ + if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays2 : presence of null pointer in input parameter !"); + MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); + int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; + int offset=0; + const int *arrIndxInPtr=arrIndxIn->getConstPointer(); + const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); + int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArrays2 : "); + int it=start; + for(int i=0;i=0 && italloc(nbOfTuples+1,1); + arro->alloc(arrIn->getNumberOfTuples()+offset,1); + const int *arrInPtr=arrIn->getConstPointer(); + const int *srcArrPtr=srcArr->getConstPointer(); + int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0; + int *arroPtr=arro->getPointer(); + for(int ii=0;iiincrRef(); + arrIndexOut=arrIo; arrIo->incrRef(); +} + +/*! + * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. + * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignement do not modify the index in \b arrIndxIn. + * + * \param [in] start begin of set of ids of the input extraction (included) + * \param [in] end end of set of ids of the input extraction (excluded) + * \param [in] step step of the set of ids in range mode. + * \param [in,out] arrInOut 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 [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd) + * \param [in] srcArrIndex index array of \b srcArr + * + * \sa MEDCouplingUMesh::SetPartOfIndexedArrays2 MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx + */ +void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception) +{ + if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : presence of null pointer in input parameter !"); + int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; + const int *arrIndxInPtr=arrIndxIn->getConstPointer(); + const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); + int *arrInOutPtr=arrInOut->getPointer(); + const int *srcArrPtr=srcArr->getConstPointer(); + int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : "); + int it=start; + for(int i=0;i=0 && it& res, std::vector& resI) const; bool areCellsEqualInPool(const std::vector& candidates, int compType, std::vector& result) const; MEDCouplingUMesh *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; + MEDCouplingUMesh *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; template void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints, double eps, std::vector& elts, std::vector& eltsIndex) const; diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx index e71ddee8d..4807d075b 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx @@ -374,6 +374,12 @@ void MEDCouplingUMeshDesc::tryToShareSameCoordsPermute(const MEDCouplingPointSet throw INTERP_KERNEL::Exception("Not implemented yet !"); } +MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); + return 0; +} + MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const { throw INTERP_KERNEL::Exception("Not implemented yet !"); diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx index b8ca0c7a6..27216c8f3 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx @@ -69,6 +69,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes); MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords=0) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx index f5cb3df6b..53378fe93 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx @@ -1326,3 +1326,49 @@ void MEDCouplingBasicsTest5::testComputeTupleIdsToSelectFromCellIds1() sel->decrRef(); res->decrRef(); } + +void MEDCouplingBasicsTest5::testComputeSkin1() +{ + const double input1[5]={2.,3.4,5.6,7.7,8.0}; + const double input2[6]={2.,3.4,5.6,7.7,9.0,14.2}; + DataArrayDouble *arrX=DataArrayDouble::New(); arrX->alloc(5,1); std::copy(input1,input1+5,arrX->getPointer()); + DataArrayDouble *arrY=DataArrayDouble::New(); arrY->alloc(6,1); std::copy(input2,input2+6,arrY->getPointer()); + MEDCouplingCMesh *cmesh=MEDCouplingCMesh::New() ; cmesh->setCoordsAt(0,arrX) ; cmesh->setCoordsAt(1,arrY); + MEDCouplingUMesh *umesh=cmesh->buildUnstructured(); + cmesh->decrRef(); arrX->decrRef(); arrY->decrRef(); + // + MEDCouplingUMesh *skin=umesh->computeSkin(); + CPPUNIT_ASSERT_EQUAL(18,skin->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(1,skin->getMeshDimension()); + CPPUNIT_ASSERT(skin->getCoords()==umesh->getCoords()); + const int expected1[19]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54}; + const int expected2[54]={1,1,0,1,0,5,1,2,1,1,3,2,1,4,3,1,9,4,1,5,10,1,14,9,1,10,15,1,19,14,1,15,20,1,24,19,1,20,25,1,25,26,1,26,27,1,27,28,1,28,29,1,29,24}; + CPPUNIT_ASSERT_EQUAL(19,skin->getNodalConnectivityIndex()->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+19,skin->getNodalConnectivityIndex()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL(54,skin->getNodalConnectivity()->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+54,skin->getNodalConnectivity()->getConstPointer())); + DataArrayInt *ids=skin->computeFetchedNodeIds(); + const int expected3[18]={0,1,2,3,4,5,9,10,14,15,19,20,24,25,26,27,28,29}; + CPPUNIT_ASSERT_EQUAL(18,ids->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(expected3,expected3+18,ids->getConstPointer())); + MEDCouplingUMesh *part=dynamic_cast(umesh->buildFacePartOfMySelfNode(ids->begin(),ids->end(),true)); + part->setName(skin->getName()); + CPPUNIT_ASSERT(part->isEqual(skin,1e-12)); + MEDCouplingUMesh *part2=dynamic_cast(part->buildPartOfMySelf2(1,18,2,true)); + DataArrayInt *ids2=DataArrayInt::Range(0,18,2); + part->setPartOfMySelf(ids2->begin(),ids2->end(),*part2); + ids2->decrRef(); + CPPUNIT_ASSERT(!part->isEqual(skin,1e-12)); + DataArrayInt *trad=part->zipConnectivityTraducer(0); + CPPUNIT_ASSERT_EQUAL(9,part->getNumberOfCells()); + const int expected4[18]={0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8}; + CPPUNIT_ASSERT(std::equal(expected4,expected4+18,trad->getConstPointer())); + CPPUNIT_ASSERT_EQUAL(18,trad->getNbOfElems()); + trad->decrRef(); + part->decrRef(); + part2->decrRef(); + // + ids->decrRef(); + umesh->decrRef(); + skin->decrRef(); +} diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx index 67b7b7c93..d8798baa3 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx @@ -60,6 +60,7 @@ namespace ParaMEDMEM CPPUNIT_TEST( testGiveCellsWithType1 ); CPPUNIT_TEST( testBuildSlice3D2 ); CPPUNIT_TEST( testComputeTupleIdsToSelectFromCellIds1 ); + CPPUNIT_TEST( testComputeSkin1 ); CPPUNIT_TEST_SUITE_END(); public: void testUMeshTessellate2D1(); @@ -87,6 +88,7 @@ namespace ParaMEDMEM void testGiveCellsWithType1(); void testBuildSlice3D2(); void testComputeTupleIdsToSelectFromCellIds1(); + void testComputeSkin1(); }; } diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 1ee7ed1b1..5c33f0701 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -9832,7 +9832,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): def testPartitionBySpreadZone1(self): m=MEDCouplingDataForTest.build2DTargetMesh_1(); - m4=MEDCouplingUMesh.MergeUMeshes([m,m[2:],m[0:2]]); + m4=MEDCouplingUMesh.MergeUMeshes([m,m[-3:],m[0:2]]); m4.renumberCells([5,2,9,6,4,7,0,1,3,8]); # v2=m4.partitionBySpreadZone(); @@ -10020,6 +10020,30 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertTrue(arr2.isEqual(f2.getArray(),1e-12)) pass + def testComputeSkin1(self): + arrX=DataArrayDouble([2.,3.4,5.6,7.7,8.0]) ; arrY=DataArrayDouble([2.,3.4,5.6,7.7,9.0,14.2]) + cmesh=MEDCouplingCMesh() ; cmesh.setCoordsAt(0,arrX) ; cmesh.setCoordsAt(1,arrY) + umesh=cmesh.buildUnstructured() + # + skin=umesh.computeSkin() + self.assertEqual(18,skin.getNumberOfCells()) + self.assertEqual(1,skin.getMeshDimension()) + self.assertTrue(skin.getCoords().getHiddenCppPointer()==umesh.getCoords().getHiddenCppPointer()) + self.assertEqual([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54],skin.getNodalConnectivityIndex().getValues()) + self.assertEqual([1,1,0,1,0,5,1,2,1,1,3,2,1,4,3,1,9,4,1,5,10,1,14,9,1,10,15,1,19,14,1,15,20,1,24,19,1,20,25,1,25,26,1,26,27,1,27,28,1,28,29,1,29,24],skin.getNodalConnectivity().getValues()) + ids=skin.computeFetchedNodeIds() + self.assertEqual([0,1,2,3,4,5,9,10,14,15,19,20,24,25,26,27,28,29],ids.getValues()) + part=umesh.buildFacePartOfMySelfNode(ids,True) + part.setName(skin.getName()); + self.assertTrue(part.isEqual(skin,1e-12)) + part2=part[1::2] + part[::2]=part2 + self.assertTrue(not part.isEqual(skin,1e-12)) + trad=part.zipConnectivityTraducer(0) + self.assertEqual(9,part.getNumberOfCells()) + self.assertEqual([0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8],trad.getValues()) + pass + def setUp(self): pass pass diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index 857e7ad88..8d57723cc 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -244,6 +244,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingPointSet::findBoundaryNodes; %newobject ParaMEDMEM::MEDCouplingPointSet::buildBoundaryMesh; %newobject ParaMEDMEM::MEDCouplingPointSet::MergeNodesArray; +%newobject ParaMEDMEM::MEDCouplingPointSet::buildPartOfMySelf2; %newobject ParaMEDMEM::MEDCouplingPointSet::BuildInstanceFromMeshType; %newobject ParaMEDMEM::MEDCouplingUMesh::New; %newobject ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivity; @@ -791,6 +792,7 @@ namespace ParaMEDMEM void recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception); void changeSpaceDimension(int newSpaceDim, double dftVal=0.) throw(INTERP_KERNEL::Exception); void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); + virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step) const throw(INTERP_KERNEL::Exception); virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); static DataArrayDouble *MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) throw(INTERP_KERNEL::Exception); static MEDCouplingPointSet *BuildInstanceFromMeshType(MEDCouplingMeshType type) throw(INTERP_KERNEL::Exception); @@ -1237,6 +1239,7 @@ namespace ParaMEDMEM MEDCouplingUMeshCellByTypeEntry *cellsByType() throw(INTERP_KERNEL::Exception); void setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true) throw(INTERP_KERNEL::Exception); INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const throw(INTERP_KERNEL::Exception); + void setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception); int getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception); int getMeshLength() const throw(INTERP_KERNEL::Exception); void computeTypes() throw(INTERP_KERNEL::Exception); @@ -1338,8 +1341,7 @@ namespace ParaMEDMEM } case 3: { - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::Range(slic.first,slic.second.first,slic.second.second); - return self->buildPartOfMySelf(d0->begin(),d0->end(),true); + return self->buildPartOfMySelf2(slic.first,slic.second.first,slic.second.second,true); } case 4: { @@ -1352,6 +1354,64 @@ namespace ParaMEDMEM throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__getitem__ : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); } } + + void setPartOfMySelf(PyObject *li, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception) + { + int sw; + int singleVal; + std::vector multiVal; + std::pair > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + int nbc=self->getNumberOfCells(); + convertObjToPossibleCpp2(li,nbc,sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + { + if(singleVal>=nbc) + { + std::ostringstream oss; + oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(singleVal>=0) + { + self->setPartOfMySelf(&singleVal,&singleVal+1,otherOnSameCoordsThanThis); + break; + } + else + { + if(nbc+singleVal>0) + { + int tmp=nbc+singleVal; + self->setPartOfMySelf(&tmp,&tmp+1,otherOnSameCoordsThanThis); + break; + } + else + { + std::ostringstream oss; + oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + case 2: + { + self->setPartOfMySelf(&multiVal[0],&multiVal[0]+multiVal.size(),otherOnSameCoordsThanThis); + break; + } + case 4: + { + if(!daIntTyypp) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : null instance has been given in input !"); + daIntTyypp->checkAllocated(); + self->setPartOfMySelf(daIntTyypp->begin(),daIntTyypp->end(),otherOnSameCoordsThanThis); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); + } + } void __setitem__(PyObject *li, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception) { @@ -1400,8 +1460,7 @@ namespace ParaMEDMEM } case 3: { - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::Range(slic.first,slic.second.first,slic.second.second); - self->setPartOfMySelf(d0->begin(),d0->end(),otherOnSameCoordsThanThis); + self->setPartOfMySelf2(slic.first,slic.second.first,slic.second.second,otherOnSameCoordsThanThis); break; } case 4: @@ -1413,7 +1472,7 @@ namespace ParaMEDMEM break; } default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__setitem__ : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__setitem__ : unrecognized type in input ! Possibilities are : int, list or tuple of int, slice, DataArrayInt instance !"); } } -- 2.39.2