X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingMemArray.txx;h=0a0128161c97e2d1b14e8a8a604250f58dd9fe5f;hb=9abc40a840f69fd7f07b356cd31876b64dc81e14;hp=750620d9a065bc28ee63268b70ae52c3d484ddad;hpb=33bef9c33b06748118a99ec0b81a5f627b5db8aa;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingMemArray.txx b/src/MEDCoupling/MEDCouplingMemArray.txx index 750620d9a..0a0128161 100755 --- a/src/MEDCoupling/MEDCouplingMemArray.txx +++ b/src/MEDCoupling/MEDCouplingMemArray.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -4920,6 +4920,56 @@ struct NotInRange nc[nbOfCompo*i+compoIds[j]]=*ac; } + /*! + * This method searches each value in \a valToSearchIntoTuples among values in \a this given the corresponding tuple to find into. + * If the value at the corresponding tuple is not found in the tuple an exception will be thrown. + * If the value is found the corresponding component id is returned. + * + * \param [in] valToSearchIntoTuples - a one component array containing the values to find in \a this + * \param [in] tupleIdHint - a one component array having same size than \a valToSearchIntoTuples giving for each value the tuple to find into + * \return DataArrayInt * - A newly allocated array having same size than \a valToSearchIntoTuples with one component + * + * \b Example:
+ * - \a this: [(0, 1, 2), (3, 4, 5), (6, 2, 3), (7, 8, 9), (9, 0, 10), (11, 12, 13), (14, 5, 11), (15, 16, 17)] + * - \a valToSearchIntoTuples: [1, 4, 6, 8, 10, 12, 14, 16, 17] + * - \a tupleIdHint: [0, 1, 2, 3, 4, 5, 6, 7, 7] + * - result array: [1, 1, 0, 1, 2, 1, 0, 1, 2] ==
+ */ + template + DataArrayIdType *DataArrayDiscrete::locateComponentId(const DataArrayType *valToSearchIntoTuples, const DataArrayIdType *tupleIdHint) const + { + if(!valToSearchIntoTuples || !tupleIdHint) + THROW_IK_EXCEPTION("DataArrayInt::locateComponentId : valToSearchIntoTuples and tupleIdHint must be not nullptr !"); + valToSearchIntoTuples->checkAllocated(); tupleIdHint->checkAllocated(); + this->checkAllocated(); + constexpr char MSG1[] = "DataArrayInt::locateComponentId : single component array expected"; + valToSearchIntoTuples->checkNbOfComps(1,MSG1); tupleIdHint->checkNbOfComps(1,MSG1); + std::size_t nbOfCompo( this->getNumberOfComponents() ); + mcIdType thisNbTuples( this->getNumberOfTuples() ); + mcIdType nbOfTuples( valToSearchIntoTuples->getNumberOfTuples() ); + tupleIdHint->checkNbOfTuples(nbOfTuples,"Number of tuples of input arrays must be the same."); + const T *cPtr(this->begin()),*valSearchPt(valToSearchIntoTuples->begin()); + const mcIdType *tHintPtr(tupleIdHint->begin()); + MCAuto ret = DataArrayIdType::New(); + ret->alloc(nbOfTuples,1); + mcIdType *retPtr(ret->getPointer()); + for(auto i = 0 ; i < nbOfTuples ; ++i) + { + if( tHintPtr[i] >=0 && tHintPtr[i] < thisNbTuples ) + { + auto strtSearch(cPtr+nbOfCompo*tHintPtr[i]),endSearch(cPtr+nbOfCompo*(tHintPtr[i]+1)); + auto pos = std::find(strtSearch,endSearch,valSearchPt[i]); + if(pos != endSearch) + *retPtr++ = ToIdType( std::distance(strtSearch,pos) ); + else + THROW_IK_EXCEPTION("At pos " << i << " value " << valSearchPt[i] << " is not present at tuple " << tHintPtr[i]); + } + else + THROW_IK_EXCEPTION("At pos " << i << " hint tuple is " << tHintPtr[i] << " not in [0," << thisNbTuples << ")"); + } + return ret.retn(); + } + /*! * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not * equal to a given one. @@ -5866,7 +5916,7 @@ struct NotInRange throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !"); std::size_t nbOfElements=this->getNumberOfTuples(); if(nbOfElements<2) - throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !"); + throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 2 tuples at least must be present in 'this' !"); const T *ptr=this->getConstPointer(); DataArrayType *ret=DataArrayType::New(); ret->alloc(nbOfElements-1,1); @@ -6248,7 +6298,7 @@ struct NotInRange * * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectivity without any coordinates consideration. * - * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList + * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::sortToHaveConsecutivePairs(), DataArrayInt::fromLinkedListOfPairToList */ template void DataArrayDiscrete::sortEachPairToMakeALinkedList() @@ -6269,6 +6319,11 @@ struct NotInRange std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + if(conn[2]!=conn[1] && conn[3]!=conn[1]) + { + std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : There is no common noeud between the tuple #" << i << " and the tuple #" << i + 1 << ". Need call DataArrayInt::sortToHaveConsecutivePairs() "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0]) std::swap(conn[2],conn[3]); //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0]) @@ -6307,6 +6362,57 @@ struct NotInRange } } + /*! + * This method is the improvement from the method sortEachPairToMakeALinkedList(). + * + * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::sortEachPairToMakeALinkedList(), DataArrayInt::fromLinkedListOfPairToList + */ + template + void DataArrayDiscrete::sortToHaveConsecutivePairs() + { + this->checkAllocated(); + if(this->getNumberOfComponents()!=2) + throw INTERP_KERNEL::Exception("DataArrayInt::sortToHaveConsecutivePairs : Only works on DataArrayInt instance with nb of components equal to 2 !"); + mcIdType nbOfTuples(this->getNumberOfTuples()); + T *thisPtr(this->getPointer()); + mcIdType idOfLastTuple = 0; + std::pair tmp; + if(thisPtr[0]==thisPtr[1]) + { + THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : In the first tuple presence of a pair filled with same ids !"); + } + while(idOfLastTuple < nbOfTuples-1) + { + mcIdType i = idOfLastTuple+1; + tmp.first = &thisPtr[2*i]; + tmp.second = &thisPtr[2*i+1]; + if(std::get<0>(tmp)[0] == std::get<1>(tmp)[0]) + { + THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : In the tuple #" << i << " presence of a pair filled with same ids !"); + } + while((this->getIJ(idOfLastTuple,1) != std::get<0>(tmp)[0] && + this->getIJ(idOfLastTuple,1) != std::get<1>(tmp)[0]) && + i < nbOfTuples-1) + { + std::swap(std::get<0>(tmp)[0],thisPtr[2*(i+1)]); + std::swap(std::get<1>(tmp)[0],thisPtr[2*(i+1)+1]); + i++; + } + if(i < nbOfTuples-1 || + this->getIJ(idOfLastTuple,1) == std::get<0>(tmp)[0] || + this->getIJ(idOfLastTuple,1) == std::get<1>(tmp)[0]) + { + if(this->getIJ(idOfLastTuple,1) != std::get<0>(tmp)[0]) + std::swap(std::get<0>(tmp)[0],std::get<1>(tmp)[0]); + idOfLastTuple++; + } + else + { + THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : not found the tuple which have the common noeud = " << this->getIJ(idOfLastTuple,1)); + } + } + } + /*! * \a this is expected to be a correctly linked list of pairs. *