From e747134dcef9dd54e26973c2e90a5635c3e1de11 Mon Sep 17 00:00:00 2001 From: geay Date: Wed, 4 Jun 2014 13:11:43 +0200 Subject: [PATCH] Full synchronisation of patches across levels. --- src/MEDCoupling/MEDCouplingAMRAttribute.cxx | 184 ++++++++++---- src/MEDCoupling/MEDCouplingAMRAttribute.hxx | 32 ++- .../MEDCouplingCartesianAMRMesh.cxx | 229 ++++++++++++------ .../MEDCouplingCartesianAMRMesh.hxx | 25 +- src/MEDCoupling/MEDCouplingStructuredMesh.cxx | 17 ++ src/MEDCoupling/MEDCouplingStructuredMesh.hxx | 1 + src/MEDCoupling_Swig/MEDCouplingCommon.i | 43 +++- 7 files changed, 373 insertions(+), 158 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingAMRAttribute.cxx b/src/MEDCoupling/MEDCouplingAMRAttribute.cxx index a3c652165..8af2cf6fe 100644 --- a/src/MEDCoupling/MEDCouplingAMRAttribute.cxx +++ b/src/MEDCoupling/MEDCouplingAMRAttribute.cxx @@ -149,6 +149,26 @@ void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghost fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i],fine->_arrs[i],ghostLev); } +void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const +{ + DataArrayDoubleCollection *thisNC(const_cast(this)); + std::size_t sz(_arrs.size()); + if(other._arrs.size()!=sz) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !"); + for(std::size_t i=0;ifillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i],other._arrs[i]); +} + +void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const +{ + DataArrayDoubleCollection *thisNC(const_cast(this)); + std::size_t sz(_arrs.size()); + if(other._arrs.size()!=sz) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !"); + for(std::size_t i=0;i_arrs[i],other._arrs[i]); +} + DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair >& fieldNames):_arrs(fieldNames.size()) { std::size_t sz(fieldNames.size()); @@ -250,10 +270,10 @@ bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen return false; } -const DataArrayDoubleCollection& MEDCouplingGridCollection::retrieveFieldsAt(int pos) const +const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const { if(pos<0 || pos>(int)_map_of_dadc.size()) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::retrieveFieldsAt : invalid pos given in input ! Must be in [0,size) !"); + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !"); return *_map_of_dadc[pos].second; } @@ -311,32 +331,76 @@ void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDC } } -void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev) const +/*! + * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead. + * + * \sa synchronizeFineEachOtherExt + */ +void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair >& ps) const { - std::map > > m; + for(std::vector< std::pair >::const_iterator it=ps.begin();it!=ps.end();it++) + { + int p1,p2; + if(!presenceOf((*it).first->getMesh(),p1)) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !"); + if(!presenceOf((*it).second->getMesh(),p2)) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !"); + const DataArrayDoubleCollection& col1(getFieldsAt(p1)); + const DataArrayDoubleCollection& col2(getFieldsAt(p2)); + col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather()); + } +} + +/*! + * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless. + * + * \sa synchronizeFineEachOther + */ +void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair >& ps) const +{ + for(std::vector< std::pair >::const_iterator it=ps.begin();it!=ps.end();it++) + { + int p1,p2; + if(!presenceOf((*it).first->getMesh(),p1)) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !"); + if(!presenceOf((*it).second->getMesh(),p2)) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !"); + const DataArrayDoubleCollection& col1(getFieldsAt(p1)); + const DataArrayDoubleCollection& col2(getFieldsAt(p2)); + col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second); + } +} + +/*! + * The pairs returned share the same direct father. The number of returned elements must be even. + */ +std::vector< std::pair > MEDCouplingGridCollection::findNeighbors(int ghostLev) const +{ + std::vector< std::pair > ret; + std::map > m; for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) { const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); - m[fatherOfFineMesh].push_back(std::pair(fineMesh,(*it).second)); + m[fatherOfFineMesh].push_back(fineMesh); } - for(std::map > >::const_iterator it0=m.begin();it0!=m.end();it0++) + for(std::map >::const_iterator it0=m.begin();it0!=m.end();it0++) { - std::size_t sz((*it0).second.size()); - std::vector v0(sz); - std::vector v1(sz); - for(std::size_t i=0;i::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++) { - v0[i]=(*it0).second[i].first; - const DataArrayDoubleCollection *tmp((*it0).second[i].second); - v1[i]=const_cast(tmp); - } - for(std::vector >::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++) - { - int patchId((*it0).first->getPatchIdFromChildMesh((*it1).first)); - DataArrayDoubleCollection::SynchronizeFineEachOther(patchId,ghostLev,(*it0).first,v0,v1); + int patchId((*it0).first->getPatchIdFromChildMesh(*it1)); + std::vector neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev)); + const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId)); + for(std::vector::const_iterator it2=neighs.begin();it2!=neighs.end();it2++) + { + const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2)); + ret.push_back(std::pair(pRef,pLoc)); + } } } + if(ret.size()%2!=0) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !"); + return ret; } void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine) @@ -426,12 +490,12 @@ void MEDCouplingGridCollection::updateTime() const /*! * This method creates, attach to a main AMR mesh \a gf ( called god father :-) ) and returns a data linked to \a gf ready for the computation. */ -MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames) +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames, int ghostLev) { - return new MEDCouplingAMRAttribute(gf,fieldNames); + return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev); } -MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair > >& fieldNames) +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair > >& fieldNames, int ghostLev) { std::size_t sz(fieldNames.size()); std::vector< std::pair > fieldNames2(sz); @@ -442,7 +506,7 @@ MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMes fieldNames2[i].second=(int)fieldNames[i].second.size(); compNames[i]=fieldNames[i].second; } - MEDCouplingAutoRefCountObjectPtr ret(New(gf,fieldNames2)); + MEDCouplingAutoRefCountObjectPtr ret(New(gf,fieldNames2,ghostLev)); ret->spillInfoOnComponents(compNames); return ret.retn(); } @@ -474,7 +538,7 @@ std::vector MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCoup int tmp(-1); if((*it)->presenceOf(mesh,tmp)) { - const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp)); + const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); return ddc.retrieveFields(); } } @@ -491,7 +555,7 @@ const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianA int tmp(-1); if((*it)->presenceOf(mesh,tmp)) { - const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp)); + const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); return ddc.getFieldWithName(fieldName); } } @@ -504,7 +568,7 @@ const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianA * * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it). */ -MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const +MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const { std::vector recurseArrs; std::size_t lev(0); @@ -513,7 +577,7 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutO int tmp(-1); if((*it)->presenceOf(mesh,tmp)) { - const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp)); + const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); recurseArrs.push_back(ddc.getFieldWithName(fieldName)); break; } @@ -524,7 +588,7 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutO const MEDCouplingGridCollection *gc(_levs[i]); gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs); } - return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(ghostLev,recurseArrs); + return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs); } /*! @@ -534,7 +598,7 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutO * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it). * */ -MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const +MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const { const DataArrayDouble *arr(0); for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) @@ -542,13 +606,13 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(int g int tmp(-1); if((*it)->presenceOf(mesh,tmp)) { - const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp)); + const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); arr=ddc.getFieldWithName(fieldName); } } if(!arr) throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !"); - MEDCouplingAutoRefCountObjectPtr im(mesh->getImageMesh()->buildWithGhost(ghostLev)); + MEDCouplingAutoRefCountObjectPtr im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingFieldDouble::New(ON_CELLS)); ret->setMesh(im); ret->setArray(const_cast(arr)); @@ -560,7 +624,7 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(int g * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using * MEDCouplingAMRAttribute::alloc method. */ -void MEDCouplingAMRAttribute::synchronizeFineToCoarse(int ghostLev) +void MEDCouplingAMRAttribute::synchronizeFineToCoarse() { if(_levs.empty()) throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !"); @@ -570,15 +634,15 @@ void MEDCouplingAMRAttribute::synchronizeFineToCoarse(int ghostLev) { sz--; const MEDCouplingGridCollection *fine(_levs[sz]),*coarse(_levs[sz-1]); - MEDCouplingGridCollection::SynchronizeFineToCoarse(ghostLev,fine,coarse); + MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse); } } /*! - * This method synchronizes from coarse to fine arrays and fine to fine each other (if ghostLev is >0). This method makes the hypothesis that \a this has been allocated before using + * This method synchronizes from coarse to fine arrays and fine to fine each other (if _ghost_lev is >0). This method makes the hypothesis that \a this has been allocated before using * MEDCouplingAMRAttribute::alloc method. */ -void MEDCouplingAMRAttribute::synchronizeCoarseToFine(int ghostLev) +void MEDCouplingAMRAttribute::synchronizeCoarseToFine() { if(_levs.empty()) throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !"); @@ -587,16 +651,16 @@ void MEDCouplingAMRAttribute::synchronizeCoarseToFine(int ghostLev) for(std::size_t i=1;isynchronizeFineEachOther(ghostLev); + fine->synchronizeFineEachOther(_ghost_lev,_neighbors[i]); + } + // cross lev + for(std::size_t i=1;isynchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]); } } /*! * This method allocates all DataArrayDouble instances stored recursively in \a this. * - * \param [in] ghostLev - The size of ghost zone. - * * \sa dealloc */ -void MEDCouplingAMRAttribute::alloc(int ghostLev) +void MEDCouplingAMRAttribute::alloc() { _tlc.resetState(); for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) { MEDCouplingGridCollection *elt(*it); if(elt) - elt->alloc(ghostLev); + elt->alloc(_ghost_lev); else throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !"); } @@ -693,7 +761,7 @@ void MEDCouplingAMRAttribute::updateTime() const {//tony } -MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames):MEDCouplingDataForGodFather(gf) +MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev) { //gf non empty, checked by constructor int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()); @@ -712,4 +780,30 @@ MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf } _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames); } + // updates cross levels neighbors + _neighbors.resize(_levs.size()); + _cross_lev_neighbors.resize(_levs.size()); + if(_levs.empty()) + throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !"); + std::size_t sz(_levs.size()); + for(std::size_t i=1;ifindNeighbors(_ghost_lev); + if(i!=sz-1) + { + for(std::vector< std::pair >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++) + { + std::vector< std::vector < std::pair > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second)); + std::size_t fullLev(i+neighs2.size()); + if(fullLev>=sz) + throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !"); + std::size_t ii(i+1); + for(std::vector< std::vector< std::pair > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++) + _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end()); + } + } + } } diff --git a/src/MEDCoupling/MEDCouplingAMRAttribute.hxx b/src/MEDCoupling/MEDCouplingAMRAttribute.hxx index 726aac1e9..c8cc1ab55 100644 --- a/src/MEDCoupling/MEDCouplingAMRAttribute.hxx +++ b/src/MEDCoupling/MEDCouplingAMRAttribute.hxx @@ -40,6 +40,8 @@ namespace ParaMEDMEM static void SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine); static void SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector& children, const std::vector& fieldsOnFine); static void SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine); + void synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const; + void synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const; private: DataArrayDoubleCollection(const std::vector< std::pair >& fieldNames); std::size_t getHeapMemorySizeWithoutChildren() const; @@ -58,10 +60,13 @@ namespace ParaMEDMEM void dealloc(); void spillInfoOnComponents(const std::vector< std::vector >& compNames); bool presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const; - const DataArrayDoubleCollection& retrieveFieldsAt(int pos) const; + const DataArrayDoubleCollection& getFieldsAt(int pos) const; static void SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse); static void SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine); - void synchronizeFineEachOther(int ghostLev) const; + //void synchronizeFineEachOtherOld(int ghostLev) const; + void synchronizeFineEachOther(int ghostLev, const std::vector< std::pair >& ps) const; + void synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair >& ps) const; + std::vector< std::pair > findNeighbors(int ghostLev) const; static void SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine); void fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector& recurseArrs) const; private: @@ -78,19 +83,19 @@ namespace ParaMEDMEM class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel { public: - MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames); - MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair > >& fieldNames); + MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames, int ghostLev); + MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair > >& fieldNames, int ghostLev); MEDCOUPLING_EXPORT void spillInfoOnComponents(const std::vector< std::vector >& compNames); MEDCOUPLING_EXPORT std::vector retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const; MEDCOUPLING_EXPORT const DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnWithGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; // - MEDCOUPLING_EXPORT void synchronizeFineToCoarse(int ghostLev); - MEDCOUPLING_EXPORT void synchronizeCoarseToFine(int ghostLev); - MEDCOUPLING_EXPORT void synchronizeCoarseToFineOnlyInGhostZone(int ghostLev); - MEDCOUPLING_EXPORT void synchronizeFineEachOtherInGhostZone(int ghostLev); - MEDCOUPLING_EXPORT void alloc(int ghostLev); + MEDCOUPLING_EXPORT void synchronizeFineToCoarse(); + MEDCOUPLING_EXPORT void synchronizeCoarseToFine(); + MEDCOUPLING_EXPORT void synchronizeCoarseToFineOnlyInGhostZone(); + MEDCOUPLING_EXPORT void synchronizeFineEachOtherInGhostZone(); + MEDCOUPLING_EXPORT void alloc(); MEDCOUPLING_EXPORT void dealloc(); MEDCOUPLING_EXPORT bool changeGodFather(MEDCouplingCartesianAMRMesh *gf); // @@ -98,9 +103,12 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT std::vector getDirectChildren() const; MEDCOUPLING_EXPORT void updateTime() const; private: - MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames); + MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames, int ghostLev); private: + int _ghost_lev; std::vector< MEDCouplingAutoRefCountObjectPtr > _levs; + std::vector< std::vector< std::pair > > _neighbors; + std::vector< std::vector< std::pair > > _cross_lev_neighbors; }; } diff --git a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx index 9a71e5a92..ced42519c 100644 --- a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx @@ -185,6 +185,92 @@ bool MEDCouplingCartesianAMRPatch::IsInMyNeighborhood(int ghostLev, const std::v return true; } +std::vector< std::vector< std::pair > > MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2) +{ + if(!p1 || !p2) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf : the input pointers must be not NULL !"); + std::vector< std::vector< std::pair > > ret; + std::vector< const MEDCouplingCartesianAMRPatch *> p1Work(p1->getMesh()->getPatches()),p2Work(p2->getMesh()->getPatches()); + while(!p1Work.empty()) + { + std::vector< std::pair > retTmp; + std::vector p1Work2,p2Work2; + for(std::vector::const_iterator it1=p1Work.begin();it1!=p1Work.end();it1++) + { + for(std::vector::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++) + { + if((*it1)->isInMyNeighborhoodExt(*it2,ghostLev)) + retTmp.push_back(std::pair(*it1,*it2)); + } + std::vector tmp1((*it1)->getMesh()->getPatches()); + p1Work2.insert(p1Work2.end(),tmp1.begin(),tmp1.end()); + } + for(std::vector::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++) + { + std::vector tmp2((*it2)->getMesh()->getPatches()); + p2Work2.insert(p2Work2.end(),tmp2.begin(),tmp2.end()); + } + ret.push_back(retTmp); + p1Work=p1Work2; + p2Work=p2Work2; + } + return ret; +} + +/*! + * \a p1 and \a p2 are expected to be neighbors (inside the \a ghostLev zone). This method updates \a dataOnP1 only in the ghost part using a part of \a dataOnP2. + * + * \saUpdateNeighborsOfOneWithTwoExt + */ +void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(int ghostLev, const std::vector& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2) +{ + const std::vector< std::pair >& p1BLTR(p1->getBLTRRange()); + const std::vector< std::pair >& p2BLTR(p2->getBLTRRange()); + UpdateNeighborsOfOneWithTwoInternal(ghostLev,factors,p1BLTR,p2BLTR,dataOnP1,dataOnP2); +} + +void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector& factors, const std::vector< std::pair >&p1 ,const std::vector< std::pair >&p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2) +{//p1=[(1,4),(2,4)] p2=[(4,5),(3,4)] + int dim((int)factors.size()); + std::vector dimsCoarse(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(p1));//[3,2] + std::transform(dimsCoarse.begin(),dimsCoarse.end(),factors.begin(),dimsCoarse.begin(),std::multiplies());//[12,8] + std::transform(dimsCoarse.begin(),dimsCoarse.end(),dimsCoarse.begin(),std::bind2nd(std::plus(),2*ghostLev));//[14,10] + std::vector< std::pair > rangeCoarse(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsCoarse));//[(0,14),(0,10)] + std::vector fakeFactors(dim,1); + // + std::vector< std::pair > tmp0,tmp1,tmp2; + MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p1,p2,tmp0,false);//tmp0=[(3,4),(1,2)] + ApplyFactorsOnCompactFrmt(tmp0,factors);//tmp0=[(12,16),(4,8)] + ApplyGhostOnCompactFrmt(tmp0,ghostLev);//tmp0=[(13,17),(5,9)] + std::vector< std::pair > interstRange(MEDCouplingStructuredMesh::IntersectRanges(tmp0,rangeCoarse));//interstRange=[(13,14),(5,9)] + MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p2,p1,tmp1,false);//tmp1=[(-3,0),(-1,1)] + ApplyFactorsOnCompactFrmt(tmp1,factors);//tmp1=[(-12,-4),(-4,0)] + MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(tmp1,interstRange,tmp2,false);//tmp2=[(1,2),(1,5)] + // + std::vector< std::pair > dimsFine(p2); + ApplyFactorsOnCompactFrmt(dimsFine,factors); + ApplyAllGhostOnCompactFrmt(dimsFine,ghostLev); + // + MEDCouplingAutoRefCountObjectPtr ghostVals(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(dimsFine),dataOnP2,tmp2)); + MEDCouplingIMesh::CondenseFineToCoarse(dimsCoarse,ghostVals,interstRange,fakeFactors,dataOnP1); +} + +/*! + * Idem than UpdateNeighborsOfOneWithTwo, except that here \a p1 and \a p2 are not sharing the same direct father. + * + * \sa UpdateNeighborsOfOneWithTwo + */ +void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2) +{ + const std::vector< std::pair >& p1BLTR(p1->getBLTRRange());//p1BLTR=[(10,12),(5,8)] + std::vector< std::pair > p2BLTR(p2->getBLTRRange());//p2BLTR=[(0,1),(0,5)] + int lev(0); + const MEDCouplingCartesianAMRMeshGen *ca(FindCommonAncestor(p1,p2,lev)); + std::vector offset(ComputeOffsetFromTwoToOne(ca,lev,p1,p2));//[12,4] + p2BLTR=MEDCouplingStructuredMesh::TranslateCompactFrmt(p2BLTR,offset);//p2BLTR=[(12,13),(4,9)] + UpdateNeighborsOfOneWithTwoInternal(ghostLev,p1->getMesh()->getFather()->getFactors(),p1BLTR,p2BLTR,dataOnP1,dataOnP2); +} + std::size_t MEDCouplingCartesianAMRPatch::getHeapMemorySizeWithoutChildren() const { std::size_t ret(sizeof(MEDCouplingCartesianAMRPatch)); @@ -212,12 +298,13 @@ std::vector MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne(const M { if(lev<=0) throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : this method is useful only for lev > 0 !"); + int zeLev(lev-1); int dim(p1->getMesh()->getSpaceDimension()); if(p2->getMesh()->getSpaceDimension()!=dim) throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : dimension must be the same !"); std::vector< int > ret(dim,0); - for(int i=0;i_mesh),*f2(p2->_mesh); const MEDCouplingCartesianAMRPatch *p1h(0),*p2h(0); @@ -243,6 +330,56 @@ std::vector MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne(const M return ret; } +/*! + * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in refined reference. + * \param [in] factors - the factors per axis. + */ +void MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt(std::vector< std::pair >& partBeforeFact, const std::vector& factors) +{ + std::size_t sz(factors.size()); + if(sz!=partBeforeFact.size()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt : size of input vectors must be the same !"); + for(std::size_t i=0;i >& partBeforeFact, int ghostSize) +{ + if(ghostSize<0) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt : ghost size must be >= 0 !"); + std::size_t sz(partBeforeFact.size()); + for(std::size_t i=0;i >& partBeforeFact, int ghostSize) +{ + if(ghostSize<0) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyAllGhostOnCompactFrmt : ghost size must be >= 0 !"); + std::size_t sz(partBeforeFact.size()); + for(std::size_t i=0;i& arrsOnPatches) const { - int nbp(getNumberOfPatches()),dim(getSpaceDimension()); + int nbp(getNumberOfPatches()); if(nbp!=(int)arrsOnPatches.size()) { std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - DataArrayDouble *theFieldToFill(const_cast(arrsOnPatches[patchId])); const MEDCouplingCartesianAMRPatch *refP(getPatch(patchId)); - const std::vector< std::pair >& refBLTR(refP->getBLTRRange());//[(1,4),(2,4)] - std::vector dimsCoarse(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(refBLTR));//[3,2] - std::transform(dimsCoarse.begin(),dimsCoarse.end(),_factors.begin(),dimsCoarse.begin(),std::multiplies());//[12,8] - std::transform(dimsCoarse.begin(),dimsCoarse.end(),dimsCoarse.begin(),std::bind2nd(std::plus(),2*ghostLev));//[14,10] - std::vector< std::pair > rangeCoarse(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsCoarse));//[(0,14),(0,10)] - std::vector fakeFactors(dim,1),ids(getPatchIdsInTheNeighborhoodOf(patchId,ghostLev)); - // + DataArrayDouble *theFieldToFill(const_cast(arrsOnPatches[patchId])); + std::vector ids(getPatchIdsInTheNeighborhoodOf(patchId,ghostLev)); for(std::vector::const_iterator it=ids.begin();it!=ids.end();it++) { const MEDCouplingCartesianAMRPatch *otherP(getPatch(*it)); - const std::vector< std::pair >& otherBLTR(otherP->getBLTRRange());//[(4,5),(3,4)] - std::vector< std::pair > tmp0,tmp1,tmp2; - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(refBLTR,otherBLTR,tmp0,false);//tmp0=[(3,4),(1,2)] - ApplyFactorsOnCompactFrmt(tmp0,_factors);//tmp0=[(12,16),(4,8)] - ApplyGhostOnCompactFrmt(tmp0,ghostLev);//tmp0=[(13,17),(5,9)] - std::vector< std::pair > interstRange(MEDCouplingStructuredMesh::IntersectRanges(tmp0,rangeCoarse));//interstRange=[(13,14),(5,9)] - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(otherBLTR,refBLTR,tmp1,false);//tmp1=[(-3,0),(-1,1)] - ApplyFactorsOnCompactFrmt(tmp1,_factors);//tmp1=[(-12,-4),(-4,0)] - MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(tmp1,interstRange,tmp2,false);//tmp2=[(1,2),(1,5)] - // - std::vector< std::pair > dimsFine(otherBLTR); - ApplyFactorsOnCompactFrmt(dimsFine,_factors); - ApplyAllGhostOnCompactFrmt(dimsFine,ghostLev); - // - MEDCouplingAutoRefCountObjectPtr ghostVals(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(dimsFine),arrsOnPatches[*it],tmp2)); - MEDCouplingIMesh::CondenseFineToCoarse(dimsCoarse,ghostVals,interstRange,fakeFactors,theFieldToFill); + MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,refP,otherP,theFieldToFill,arrsOnPatches[*it]); } } +void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const +{ + MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,patchToBeModified,neighborPatch,cellFieldOnPatch,cellFieldNeighbor); +} + /*! * This method updates \a cellFieldOnThis part of values coming from the cell field \a cellFieldOnPatch lying on patch having id \a patchId. * @@ -1134,7 +1255,7 @@ DataArrayDouble *MEDCouplingCartesianAMRMeshGen::extractGhostFrom(int ghostSz, c std::vector st(_mesh->getCellGridStructure()); std::vector< std::pair > p(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(st)); std::transform(st.begin(),st.end(),st.begin(),std::bind2nd(std::plus(),2*ghostSz)); - ApplyGhostOnCompactFrmt(p,ghostSz); + MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt(p,ghostSz); MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(st,arr,p)); return ret.retn(); } @@ -1230,56 +1351,6 @@ void MEDCouplingCartesianAMRMeshGen::retrieveGridsAtInternal(int lev, std::vecto } } -/*! - * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in refined reference. - * \param [in] factors - the factors per axis. - */ -void MEDCouplingCartesianAMRMeshGen::ApplyFactorsOnCompactFrmt(std::vector< std::pair >& partBeforeFact, const std::vector& factors) -{ - std::size_t sz(factors.size()); - if(sz!=partBeforeFact.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::ApplyFactorsOnCompactFrmt : size of input vectors must be the same !"); - for(std::size_t i=0;i >& partBeforeFact, int ghostSize) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::ApplyGhostOnCompactFrmt : ghost size must be >= 0 !"); - std::size_t sz(partBeforeFact.size()); - for(std::size_t i=0;i >& partBeforeFact, int ghostSize) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::ApplyAllGhostOnCompactFrmt : ghost size must be >= 0 !"); - std::size_t sz(partBeforeFact.size()); - for(std::size_t i=0;i& factors) { if(ghostLev<0) @@ -1385,10 +1456,10 @@ void MEDCouplingCartesianAMRMesh::setData(MEDCouplingDataForGodFather *data) data->incrRef(); } -void MEDCouplingCartesianAMRMesh::allocData(int ghostLev) const +void MEDCouplingCartesianAMRMesh::allocData() const { checkData(); - _data->alloc(ghostLev); + _data->alloc(); } void MEDCouplingCartesianAMRMesh::deallocData() const diff --git a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx index f5e246bdb..4a6399e06 100644 --- a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx +++ b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx @@ -79,10 +79,19 @@ namespace ParaMEDMEM // basic set/get MEDCOUPLING_EXPORT const std::vector< std::pair >& getBLTRRange() const { return _bl_tr; } MEDCOUPLING_EXPORT static bool IsInMyNeighborhood(int ghostLev, const std::vector< std::pair >& p1, const std::vector< std::pair >& p2); + // + static std::vector< std::vector< std::pair > > FindNeighborsOfSubPatchesOf(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2); + static void UpdateNeighborsOfOneWithTwo(int ghostLev, const std::vector& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2); + static void UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector& factors, const std::vector< std::pair >&p1 ,const std::vector< std::pair >&p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2); + static void UpdateNeighborsOfOneWithTwoExt(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2); private: std::size_t getHeapMemorySizeWithoutChildren() const; static const MEDCouplingCartesianAMRMeshGen *FindCommonAncestor(const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, int& lev); static std::vector ComputeOffsetFromTwoToOne(const MEDCouplingCartesianAMRMeshGen *comAncestor, int lev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2); + public: + static void ApplyFactorsOnCompactFrmt(std::vector< std::pair >& partBeforeFact, const std::vector& factors); + static void ApplyGhostOnCompactFrmt(std::vector< std::pair >& partBeforeFact, int ghostSize); + static void ApplyAllGhostOnCompactFrmt(std::vector< std::pair >& partBeforeFact, int ghostSize); private: //! bottom left/top right cell range relative to \a _father std::vector< std::pair > _bl_tr; @@ -103,11 +112,11 @@ namespace ParaMEDMEM { friend class MEDCouplingCartesianAMRMesh; public: - MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarse(int ghostLev) = 0; - MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFine(int ghostLev) = 0; - MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFineOnlyInGhostZone(int ghostLev) = 0; - MEDCOUPLING_EXPORT virtual void synchronizeFineEachOtherInGhostZone(int ghostLev) = 0; - MEDCOUPLING_EXPORT virtual void alloc(int ghostLev) = 0; + MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarse() = 0; + MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFine() = 0; + MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFineOnlyInGhostZone() = 0; + MEDCOUPLING_EXPORT virtual void synchronizeFineEachOtherInGhostZone() = 0; + MEDCOUPLING_EXPORT virtual void alloc() = 0; MEDCOUPLING_EXPORT virtual void dealloc() = 0; protected: MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf); @@ -162,6 +171,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector& arrsOnPatches) const; // fine to fine MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector& arrsOnPatches) const; + MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const; // fine to coarse MEDCOUPLING_EXPORT void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const; MEDCOUPLING_EXPORT void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev) const; @@ -181,9 +191,6 @@ namespace ParaMEDMEM void checkPatchId(int patchId) const; void checkFactorsAndIfNotSetAssign(const std::vector& factors); void retrieveGridsAtInternal(int lev, std::vector< MEDCouplingAutoRefCountObjectPtr >& grids) const; - static void ApplyFactorsOnCompactFrmt(std::vector< std::pair >& partBeforeFact, const std::vector& factors); - static void ApplyGhostOnCompactFrmt(std::vector< std::pair >& partBeforeFact, int ghostSize); - static void ApplyAllGhostOnCompactFrmt(std::vector< std::pair >& partBeforeFact, int ghostSize); static int GetGhostLevelInFineRef(int ghostLev, const std::vector& factors); std::vector extractSubTreeFromGlobalFlatten(const MEDCouplingCartesianAMRMeshGen *head, const std::vector& all) const; protected: @@ -211,7 +218,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT const MEDCouplingDataForGodFather *getDataConst() const { return _data; } MEDCOUPLING_EXPORT MEDCouplingDataForGodFather *getData() { return _data; } MEDCOUPLING_EXPORT void setData(MEDCouplingDataForGodFather *data); - MEDCOUPLING_EXPORT void allocData(int ghostLev) const; + MEDCOUPLING_EXPORT void allocData() const; MEDCOUPLING_EXPORT void deallocData() const; private: MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, diff --git a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx index d079e8288..23a236f47 100644 --- a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx +++ b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx @@ -1606,6 +1606,23 @@ void MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(const std:: } } +/*! + * This method performs a translation (defined by \a translation) of \a part and returns the result of translated part. + */ +std::vector< std::pair > MEDCouplingStructuredMesh::TranslateCompactFrmt(const std::vector< std::pair >& part, const std::vector& translation) +{ + std::size_t sz(part.size()); + if(translation.size()!=sz) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::TranslateCompactFrmt : the size are not equal !"); + std::vector< std::pair > ret(sz); + for(std::size_t i=0;i& st, const DataArrayDouble *fieldOfDbl, const std::vector< std::pair >& partCompactFormat); MEDCOUPLING_EXPORT static void ChangeReferenceFromGlobalOfCompactFrmt(const std::vector< std::pair >& bigInAbs, const std::vector< std::pair >& partOfBigInAbs, std::vector< std::pair >& partOfBigRelativeToBig, bool check=true); MEDCOUPLING_EXPORT static void ChangeReferenceToGlobalOfCompactFrmt(const std::vector< std::pair >& bigInAbs, const std::vector< std::pair >& partOfBigRelativeToBig, std::vector< std::pair >& partOfBigInAbs, bool check=true); + MEDCOUPLING_EXPORT static std::vector< std::pair > TranslateCompactFrmt(const std::vector< std::pair >& part, const std::vector& translation); MEDCOUPLING_EXPORT static DataArrayInt *BuildExplicitIdsFrom(const std::vector& st, const std::vector< std::pair >& partCompactFormat); MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivity(const int *nodeStBg, const int *nodeStEnd); MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh(const int *nodeStBg, const int *nodeStEnd); diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index b2e9d6e6c..f4798c174 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -3016,6 +3016,22 @@ namespace ParaMEDMEM return retPy; } + static PyObject *TranslateCompactFrmt(PyObject *part, const std::vector& translation) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair > param0; + convertPyToVectorPairInt(part,param0); + std::vector< std::pair > ret(MEDCouplingStructuredMesh::TranslateCompactFrmt(param0,translation)); + PyObject *retPy(PyList_New(ret.size())); + for(std::size_t i=0;i > param0,param1,ret; @@ -4859,11 +4875,11 @@ namespace ParaMEDMEM class MEDCouplingDataForGodFather : public RefCountObject { public: - virtual void synchronizeFineToCoarse(int ghostLev) throw(INTERP_KERNEL::Exception); - virtual void synchronizeCoarseToFine(int ghostLev) throw(INTERP_KERNEL::Exception); - virtual void synchronizeCoarseToFineOnlyInGhostZone(int ghostLev) throw(INTERP_KERNEL::Exception); - virtual void synchronizeFineEachOtherInGhostZone(int ghostLev) throw(INTERP_KERNEL::Exception); - virtual void alloc(int ghostLev) throw(INTERP_KERNEL::Exception); + virtual void synchronizeFineToCoarse() throw(INTERP_KERNEL::Exception); + virtual void synchronizeCoarseToFine() throw(INTERP_KERNEL::Exception); + virtual void synchronizeCoarseToFineOnlyInGhostZone() throw(INTERP_KERNEL::Exception); + virtual void synchronizeFineEachOtherInGhostZone() throw(INTERP_KERNEL::Exception); + virtual void alloc() throw(INTERP_KERNEL::Exception); virtual void dealloc() throw(INTERP_KERNEL::Exception); }; @@ -4896,6 +4912,7 @@ namespace ParaMEDMEM void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch) const throw(INTERP_KERNEL::Exception); void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const throw(INTERP_KERNEL::Exception); void fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const throw(INTERP_KERNEL::Exception); + void fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const; void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const throw(INTERP_KERNEL::Exception); void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev) const throw(INTERP_KERNEL::Exception); DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const throw(INTERP_KERNEL::Exception); @@ -5021,7 +5038,7 @@ namespace ParaMEDMEM { public: void setData(MEDCouplingDataForGodFather *data) throw(INTERP_KERNEL::Exception); - void allocData(int ghostLev) const throw(INTERP_KERNEL::Exception); + void allocData() const throw(INTERP_KERNEL::Exception); void deallocData() const throw(INTERP_KERNEL::Exception); %extend { @@ -5070,12 +5087,12 @@ namespace ParaMEDMEM class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel { public: - MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *buildCellFieldOnWithGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception); bool changeGodFather(MEDCouplingCartesianAMRMesh *gf) throw(INTERP_KERNEL::Exception); %extend { - static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames) throw(INTERP_KERNEL::Exception) + static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames, int ghostLev) throw(INTERP_KERNEL::Exception) { std::vector< std::pair > fieldNamesCpp0; std::vector< std::pair > > fieldNamesCpp1; @@ -5083,19 +5100,19 @@ namespace ParaMEDMEM try { convertPyToVectorPairStringInt(fieldNames,fieldNamesCpp0); - ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp0); + ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp0,ghostLev); } catch(INTERP_KERNEL::Exception&) { convertPyToVectorPairStringVecString(fieldNames,fieldNamesCpp1); - ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp1); + ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp1,ghostLev); } return ret; } - MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames) throw(INTERP_KERNEL::Exception) + MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames, int ghostLev) throw(INTERP_KERNEL::Exception) { - return ParaMEDMEM_MEDCouplingAMRAttribute_New(gf,fieldNames); + return ParaMEDMEM_MEDCouplingAMRAttribute_New(gf,fieldNames,ghostLev); } DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception) -- 2.39.2