From a868721191966b1de6ba2c089b79579ed5b62595 Mon Sep 17 00:00:00 2001 From: ageay Date: Mon, 7 Jan 2013 16:12:26 +0000 Subject: [PATCH] MEDFileUMesh::addNodeGroup --- src/MEDCoupling/MEDCouplingMemArray.cxx | 102 ++++++++++++++--- src/MEDCoupling/MEDCouplingMemArray.hxx | 3 + src/MEDLoader/MEDFileMesh.cxx | 141 ++++++++++++++++++++++-- src/MEDLoader/MEDFileMesh.hxx | 10 +- src/MEDLoader/Swig/MEDLoaderCommon.i | 6 +- 5 files changed, 235 insertions(+), 27 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index a276c9691..c4d29ef95 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -3894,23 +3894,75 @@ bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Excep { for(int i=1;i=ref) + ref=ptr[i]; + else return false; - ref=ptr[i]; } } else + { + for(int i=1;iref) + ref=ptr[i]; + else + return false; + } + } + else + { + for(int i=1;i res; + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); int nbOfTuples=getNumberOfTuples(); for(int i=0;ialloc((int)res.size(),1); - std::copy(res.begin(),res.end(),ret->getPointer()); - return ret; + ret->pushBackSilent(i); + return ret.retn(); } DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception) @@ -4939,15 +4988,12 @@ DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::E if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !"); const int *cptr=getConstPointer(); - std::vector res; + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); int nbOfTuples=getNumberOfTuples(); for(int i=0;ialloc((int)res.size(),1); - std::copy(res.begin(),res.end(),ret->getPointer()); - return ret; + ret->pushBackSilent(i); + return ret.retn(); } /*! @@ -5554,6 +5600,32 @@ DataArrayInt *DataArrayInt::BuildIntersection(const std::vectorcheckAllocated(); + if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG); + if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG); + const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work2(pt2Bg); + MEDCouplingAutoRefCountObjectPtr ret0(DataArrayInt::New()),ret1(DataArrayInt::New()); ret0->alloc(0,1); ret1->alloc(0,1); + for(const int *work1=pt1Bg;work1!=pt1End;work1++) + { + if(work2!=pt2End && *work1==*work2) + { ret1->pushBackSilent(*work1); work2++; } + else + { ret0->pushBackSilent(*work1); } + } + idsInThisNotInOther=ret0.retn(); idsInThisAndInOther=ret1.retn(); +} + DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception) { checkAllocated(); diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index 32bbac43e..dc3778b26 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -383,6 +383,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void reverse() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void fillWithZero() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void fillWithValue(int val) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void iota(int init=0) throw(INTERP_KERNEL::Exception); @@ -481,6 +483,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static DataArrayInt *MakePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *BuildUnion(const std::vector& arr) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *BuildIntersection(const std::vector& arr) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void splitInTwoPartsWith(const DataArrayInt *other, DataArrayInt *&idsInThisNotInOther, DataArrayInt *&idsInThisAndInOther) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index 71306745f..22d0ce52a 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -843,6 +843,20 @@ int MEDFileMesh::getMinFamilyId() const throw(INTERP_KERNEL::Exception) return ret; } +int MEDFileMesh::getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception) +{ + int m1=getMaxFamilyId(); + int m2=getMaxFamilyIdInArrays(); + return std::max(m1,m2); +} + +int MEDFileMesh::getTheMinFamilyId() const throw(INTERP_KERNEL::Exception) +{ + int m1=getMinFamilyId(); + int m2=getMinFamilyIdInArrays(); + return std::min(m1,m2); +} + DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception) { MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); @@ -1687,6 +1701,52 @@ std::vector MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToM return ret; } +int MEDFileUMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) +{ + int ret=-std::numeric_limits::max(),tmp=-1; + if((const DataArrayInt *)_fam_coords) + { + int val=_fam_coords->getMaxValue(tmp); + ret=std::max(ret,val); + } + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + { + if((const MEDFileUMeshSplitL1 *)(*it)) + { + const DataArrayInt *da=(*it)->getFamilyField(); + if(da) + { + int val=_fam_coords->getMaxValue(tmp); + ret=std::max(ret,val); + } + } + } + return ret; +} + +int MEDFileUMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) +{ + int ret=std::numeric_limits::max(),tmp=-1; + if((const DataArrayInt *)_fam_coords) + { + int val=_fam_coords->getMinValue(tmp); + ret=std::min(ret,val); + } + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + { + if((const MEDFileUMeshSplitL1 *)(*it)) + { + const DataArrayInt *da=(*it)->getFamilyField(); + if(da) + { + int val=_fam_coords->getMinValue(tmp); + ret=std::min(ret,val); + } + } + } + return ret; +} + int MEDFileUMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception) { int lev=0; @@ -2239,14 +2299,14 @@ DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception) MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1); std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1()); MEDCouplingAutoRefCountObjectPtr ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse); - MEDCouplingAutoRefCountObjectPtr newCoords=coo->selectByTupleId(ret2->begin(),ret2->end()); + MEDCouplingAutoRefCountObjectPtr newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end()); MEDCouplingAutoRefCountObjectPtr newFamCoords; if((const DataArrayInt *)_fam_coords) - newFamCoords=_fam_coords->selectByTupleId(ret2->begin(),ret2->end()); + newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); MEDCouplingAutoRefCountObjectPtr newNumCoords; if((const DataArrayInt *)_num_coords) - newNumCoords=_num_coords->selectByTupleId(ret2->begin(),ret2->end()); - _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; + newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); + _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _rev_num_coords=0; for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) { if((MEDFileUMeshSplitL1*)*it) @@ -2255,14 +2315,65 @@ DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception) return ret.retn(); } -void MEDFileUMesh::addNodeGroup(const std::string& name, const std::vector& ids) throw(INTERP_KERNEL::Exception) -{ +/*! + * This method is here only to add a group on node. + * MEDFileUMesh::setGroupsAtLevel with 1 in the first parameter. + * + * \param [in] ids node ids of and group name of the new group to add. The ids should be sorted and different each other (MED file norm). + */ +void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception) +{ +if(!ids) + throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : NULL pointer in input !"); + std::string grpName(ids->getName()); + if(grpName.empty()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : empty group name ! MED file format do not accept empty group name !"); + ids->checkStrictlyMonotonic(true); + std::vector grpsNames=getGroupsNames(); + if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end()) + { + std::ostringstream oss; oss << "MEDFileUMesh::addNodeGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } const DataArrayDouble *coords=_coords; if(!coords) - throw INTERP_KERNEL::Exception("addNodeGroup : no coords set !"); - DataArrayInt *sub=_fam_coords->selectByTupleIdSafe(&ids[0],&ids[0]+ids.size()); - std::set ssub(sub->getConstPointer(),sub->getConstPointer()+sub->getNumberOfTuples()); - + throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !"); + int nbOfNodes=coords->getNumberOfTuples(); + if(!((DataArrayInt *)_fam_coords)) + { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); } + MEDCouplingAutoRefCountObjectPtr famIds=_fam_coords->selectByTupleIdSafe(ids->begin(),ids->end()); + std::set diffFamIds=famIds->getDifferentValues(); + std::size_t sz=0; + std::vector familyIds; + std::vector< MEDCouplingAutoRefCountObjectPtr > idsPerfamiliyIds; + int maxVal=getTheMaxFamilyId()+1; + for(std::set::const_iterator famId=diffFamIds.begin();famId!=diffFamIds.end();famId++) + { + MEDCouplingAutoRefCountObjectPtr ids2Tmp=famIds->getIdsEqual(*famId); + MEDCouplingAutoRefCountObjectPtr ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end()); + MEDCouplingAutoRefCountObjectPtr ids1=_fam_coords->getIdsEqual(*famId); + DataArrayInt *ret0=0,*ret1=0; + ids1->splitInTwoPartsWith(ids2,ret0,ret1); + MEDCouplingAutoRefCountObjectPtr ret00(ret0),ret11(ret1); + if(ret0->empty()) + { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret00); sz++; } + else + { + familyIds.push_back(maxVal); idsPerfamiliyIds.push_back(ret00); + familyIds.push_back(maxVal+1); idsPerfamiliyIds.push_back(ret11); + maxVal+=2; sz+=2; + } + } + std::vector fams; + for(std::size_t i=0;iempty()) + _fam_coords->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1); + fams.push_back(findOrCreateAndGiveFamilyWithId(familyIds[i],created)); + } + setFamiliesOnGroup(grpName.c_str(),fams); } void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception) @@ -2507,6 +2618,16 @@ MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, return new MEDFileCMesh(fid,mName,dt,it); } +int MEDFileCMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Tony"); +} + +int MEDFileCMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Tony"); +} + int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception) { if(!((const MEDCouplingCMesh*)_cmesh)) diff --git a/src/MEDLoader/MEDFileMesh.hxx b/src/MEDLoader/MEDFileMesh.hxx index 88d4c5e8c..528f0a568 100644 --- a/src/MEDLoader/MEDFileMesh.hxx +++ b/src/MEDLoader/MEDFileMesh.hxx @@ -98,6 +98,10 @@ namespace ParaMEDMEM int getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception); int getMaxFamilyId() const throw(INTERP_KERNEL::Exception); int getMinFamilyId() const throw(INTERP_KERNEL::Exception); + int getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception); + int getTheMinFamilyId() const throw(INTERP_KERNEL::Exception); + virtual int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) = 0; + virtual int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) = 0; DataArrayInt *getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception); std::vector getFamiliesIds(const std::vector& famNames) const throw(INTERP_KERNEL::Exception); std::string getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception); @@ -164,6 +168,8 @@ namespace ParaMEDMEM void clearNonDiscrAttributes() const; ~MEDFileUMesh(); // + int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); + int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); int getMeshDimension() const throw(INTERP_KERNEL::Exception); int getSpaceDimension() const throw(INTERP_KERNEL::Exception); std::string simpleRepr() const; @@ -202,7 +208,7 @@ namespace ParaMEDMEM void eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception); void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception); void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception); - void addNodeGroup(const std::string& name, const std::vector& ids) throw(INTERP_KERNEL::Exception); + void addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); void removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception); void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false) throw(INTERP_KERNEL::Exception); void setMeshAtLevelGen(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception); @@ -243,6 +249,8 @@ namespace ParaMEDMEM MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception); MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception); bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; + int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); + int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); int getMeshDimension() const throw(INTERP_KERNEL::Exception); std::string simpleRepr() const; std::string advancedRepr() const; diff --git a/src/MEDLoader/Swig/MEDLoaderCommon.i b/src/MEDLoader/Swig/MEDLoaderCommon.i index a7a8da4f6..78e707acb 100644 --- a/src/MEDLoader/Swig/MEDLoaderCommon.i +++ b/src/MEDLoader/Swig/MEDLoaderCommon.i @@ -391,6 +391,10 @@ namespace ParaMEDMEM int getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception); int getMaxFamilyId() const throw(INTERP_KERNEL::Exception); int getMinFamilyId() const throw(INTERP_KERNEL::Exception); + int getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception); + int getTheMinFamilyId() const throw(INTERP_KERNEL::Exception); + virtual int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); + virtual int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); DataArrayInt *getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception); std::vector getFamiliesIds(const std::vector& famNames) const throw(INTERP_KERNEL::Exception); std::string getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception); @@ -577,7 +581,7 @@ namespace ParaMEDMEM void setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception); void setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); void eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception); - void addNodeGroup(const std::string& name, const std::vector& ids) throw(INTERP_KERNEL::Exception); + void addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); void removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception); void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false) throw(INTERP_KERNEL::Exception); void setMeshAtLevelGen(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception); -- 2.39.2