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<DataArrayDoubleCollection *>(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;i<sz;i++)
+ father->fillCellFieldOnPatchOnlyOnGhostZoneWith(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<DataArrayDoubleCollection *>(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<sz;i++)
+ MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i],other._arrs[i]);
+}
+
DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
{
std::size_t sz(fieldNames.size());
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;
}
}
}
-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<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
{
- std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> > > m;
+ for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::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<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
+{
+ for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::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<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
+{
+ std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
+ std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::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<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *>(fineMesh,(*it).second));
+ m[fatherOfFineMesh].push_back(fineMesh);
}
- for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector<std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> > >::const_iterator it0=m.begin();it0!=m.end();it0++)
+ for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
{
- std::size_t sz((*it0).second.size());
- std::vector<const MEDCouplingCartesianAMRMeshGen *> v0(sz);
- std::vector<DataArrayDoubleCollection *> v1(sz);
- for(std::size_t i=0;i<sz;i++)
+ for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::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<DataArrayDoubleCollection *>(tmp);
- }
- for(std::vector<std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> >::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<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
+ const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
+ for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
+ {
+ const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
+ ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(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)
/*!
* 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<std::string,int> >& fieldNames)
+MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
{
- return new MEDCouplingAMRAttribute(gf,fieldNames);
+ return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
}
-MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames)
+MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
{
std::size_t sz(fieldNames.size());
std::vector< std::pair<std::string,int> > fieldNames2(sz);
fieldNames2[i].second=(int)fieldNames[i].second.size();
compNames[i]=fieldNames[i].second;
}
- MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2));
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
ret->spillInfoOnComponents(compNames);
return ret.retn();
}
int tmp(-1);
if((*it)->presenceOf(mesh,tmp))
{
- const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
+ const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
return ddc.retrieveFields();
}
}
int tmp(-1);
if((*it)->presenceOf(mesh,tmp))
{
- const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
+ const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
return ddc.getFieldWithName(fieldName);
}
}
*
* \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<const DataArrayDouble *> recurseArrs;
std::size_t lev(0);
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;
}
const MEDCouplingGridCollection *gc(_levs[i]);
gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
}
- return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(ghostLev,recurseArrs);
+ return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
}
/*!
* \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<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
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<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(ghostLev));
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
ret->setMesh(im);
ret->setArray(const_cast<DataArrayDouble *>(arr));
* 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 !");
{
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 !");
for(std::size_t i=1;i<sz;i++)
{
const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
- MEDCouplingGridCollection::SynchronizeCoarseToFine(ghostLev,coarse,fine);
+ MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);
}
}
/*!
* This method performs coarse to fine spread only in the ghost zone.
* This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
- * So if \a ghostLev == 0 this method has no effect.
+ * So if \a _ghost_lev == 0 this method has no effect.
*/
-void MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone(int ghostLev)
+void MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone()
{
if(_levs.empty())
throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone : not any levels in this !");
for(std::size_t i=1;i<sz;i++)
{
const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
- MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,coarse,fine);
+ MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
}
}
/*!
* This method synchronizes fine each other only in the ghost zone.
*/
-void MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone(int ghostLev)
+void MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone()
{
if(_levs.empty())
throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
const MEDCouplingGridCollection *fine(_levs[i]);
if(!fine)
throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
- fine->synchronizeFineEachOther(ghostLev);
+ fine->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
+ }
+ // cross lev
+ for(std::size_t i=1;i<sz;i++)
+ {
+ const MEDCouplingGridCollection *fine(_levs[i]);
+ fine->synchronizeFineEachOtherExt(_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<MEDCouplingGridCollection> >::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 !");
}
{//tony
}
-MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames):MEDCouplingDataForGodFather(gf)
+MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
{
//gf non empty, checked by constructor
int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
}
_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;i<sz;i++)
+ {
+ const MEDCouplingGridCollection *fine(_levs[i]);
+ if(!fine)
+ throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
+ _neighbors[i]=fine->findNeighbors(_ghost_lev);
+ if(i!=sz-1)
+ {
+ for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
+ {
+ std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > 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 MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
+ _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
+ }
+ }
+ }
}
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<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& 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<std::string,int> >& fieldNames);
std::size_t getHeapMemorySizeWithoutChildren() const;
void dealloc();
void spillInfoOnComponents(const std::vector< std::vector<std::string> >& 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<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const;
+ void synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const;
+ std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > 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<const DataArrayDouble *>& recurseArrs) const;
private:
class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel
{
public:
- MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames);
- MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames);
+ MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev);
+ MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev);
MEDCOUPLING_EXPORT void spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames);
MEDCOUPLING_EXPORT std::vector<DataArrayDouble *> 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);
//
MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildren() const;
MEDCOUPLING_EXPORT void updateTime() const;
private:
- MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames);
+ MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev);
private:
+ int _ghost_lev;
std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> > _levs;
+ std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > _neighbors;
+ std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > _cross_lev_neighbors;
};
}
return true;
}
+std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > 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<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > ret;
+ std::vector< const MEDCouplingCartesianAMRPatch *> p1Work(p1->getMesh()->getPatches()),p2Work(p2->getMesh()->getPatches());
+ while(!p1Work.empty())
+ {
+ std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > retTmp;
+ std::vector<const MEDCouplingCartesianAMRPatch *> p1Work2,p2Work2;
+ for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it1=p1Work.begin();it1!=p1Work.end();it1++)
+ {
+ for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++)
+ {
+ if((*it1)->isInMyNeighborhoodExt(*it2,ghostLev))
+ retTmp.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(*it1,*it2));
+ }
+ std::vector<const MEDCouplingCartesianAMRPatch *> tmp1((*it1)->getMesh()->getPatches());
+ p1Work2.insert(p1Work2.end(),tmp1.begin(),tmp1.end());
+ }
+ for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++)
+ {
+ std::vector<const MEDCouplingCartesianAMRPatch *> 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<int>& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2)
+{
+ const std::vector< std::pair<int,int> >& p1BLTR(p1->getBLTRRange());
+ const std::vector< std::pair<int,int> >& p2BLTR(p2->getBLTRRange());
+ UpdateNeighborsOfOneWithTwoInternal(ghostLev,factors,p1BLTR,p2BLTR,dataOnP1,dataOnP2);
+}
+
+void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector<int>& factors, const std::vector< std::pair<int,int> >&p1 ,const std::vector< std::pair<int,int> >&p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2)
+{//p1=[(1,4),(2,4)] p2=[(4,5),(3,4)]
+ int dim((int)factors.size());
+ std::vector<int> dimsCoarse(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(p1));//[3,2]
+ std::transform(dimsCoarse.begin(),dimsCoarse.end(),factors.begin(),dimsCoarse.begin(),std::multiplies<int>());//[12,8]
+ std::transform(dimsCoarse.begin(),dimsCoarse.end(),dimsCoarse.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));//[14,10]
+ std::vector< std::pair<int,int> > rangeCoarse(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsCoarse));//[(0,14),(0,10)]
+ std::vector<int> fakeFactors(dim,1);
+ //
+ std::vector< std::pair<int,int> > 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<int,int> > 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<int,int> > dimsFine(p2);
+ ApplyFactorsOnCompactFrmt(dimsFine,factors);
+ ApplyAllGhostOnCompactFrmt(dimsFine,ghostLev);
+ //
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> 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<int,int> >& p1BLTR(p1->getBLTRRange());//p1BLTR=[(10,12),(5,8)]
+ std::vector< std::pair<int,int> > p2BLTR(p2->getBLTRRange());//p2BLTR=[(0,1),(0,5)]
+ int lev(0);
+ const MEDCouplingCartesianAMRMeshGen *ca(FindCommonAncestor(p1,p2,lev));
+ std::vector<int> 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));
{
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<lev;i++)
+ for(int i=0;i<zeLev;i++)
{
const MEDCouplingCartesianAMRMeshGen *f1(p1->_mesh),*f2(p2->_mesh);
const MEDCouplingCartesianAMRPatch *p1h(0),*p2h(0);
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<int,int> >& partBeforeFact, const std::vector<int>& 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<sz;i++)
+ {
+ partBeforeFact[i].first*=factors[i];
+ partBeforeFact[i].second*=factors[i];
+ }
+}
+
+/*!
+ * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
+ * \param [in] ghostSize - the ghost size of zone for all axis.
+ */
+void MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& 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<sz;i++)
+ {
+ partBeforeFact[i].first+=ghostSize;
+ partBeforeFact[i].second+=ghostSize;
+ }
+}
+
+/*!
+ * This method is different than ApplyGhostOnCompactFrmt. The \a partBeforeFact parameter is enlarger contrary to ApplyGhostOnCompactFrmt.
+ *
+ * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
+ * \param [in] ghostSize - the ghost size of zone for all axis.
+ */
+void MEDCouplingCartesianAMRPatch::ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& 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<sz;i++)
+ {
+ partBeforeFact[i].first-=ghostSize;
+ partBeforeFact[i].second+=ghostSize;
+ }
+}
+
MEDCouplingCartesianAMRPatchGF::MEDCouplingCartesianAMRPatchGF(MEDCouplingCartesianAMRMesh *mesh):MEDCouplingCartesianAMRPatchGen(mesh)
{
}
*/
void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector<const DataArrayDouble *>& 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<DataArrayDouble *>(arrsOnPatches[patchId]));
const MEDCouplingCartesianAMRPatch *refP(getPatch(patchId));
- const std::vector< std::pair<int,int> >& refBLTR(refP->getBLTRRange());//[(1,4),(2,4)]
- std::vector<int> dimsCoarse(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(refBLTR));//[3,2]
- std::transform(dimsCoarse.begin(),dimsCoarse.end(),_factors.begin(),dimsCoarse.begin(),std::multiplies<int>());//[12,8]
- std::transform(dimsCoarse.begin(),dimsCoarse.end(),dimsCoarse.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));//[14,10]
- std::vector< std::pair<int,int> > rangeCoarse(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsCoarse));//[(0,14),(0,10)]
- std::vector<int> fakeFactors(dim,1),ids(getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
- //
+ DataArrayDouble *theFieldToFill(const_cast<DataArrayDouble *>(arrsOnPatches[patchId]));
+ std::vector<int> ids(getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
for(std::vector<int>::const_iterator it=ids.begin();it!=ids.end();it++)
{
const MEDCouplingCartesianAMRPatch *otherP(getPatch(*it));
- const std::vector< std::pair<int,int> >& otherBLTR(otherP->getBLTRRange());//[(4,5),(3,4)]
- std::vector< std::pair<int,int> > 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<int,int> > 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<int,int> > dimsFine(otherBLTR);
- ApplyFactorsOnCompactFrmt(dimsFine,_factors);
- ApplyAllGhostOnCompactFrmt(dimsFine,ghostLev);
- //
- MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> 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.
*
std::vector<int> st(_mesh->getCellGridStructure());
std::vector< std::pair<int,int> > p(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(st));
std::transform(st.begin(),st.end(),st.begin(),std::bind2nd(std::plus<int>(),2*ghostSz));
- ApplyGhostOnCompactFrmt(p,ghostSz);
+ MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt(p,ghostSz);
MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(st,arr,p));
return ret.retn();
}
}
}
-/*!
- * \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<int,int> >& partBeforeFact, const std::vector<int>& 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<sz;i++)
- {
- partBeforeFact[i].first*=factors[i];
- partBeforeFact[i].second*=factors[i];
- }
-}
-
-/*!
- * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
- * \param [in] ghostSize - the ghost size of zone for all axis.
- */
-void MEDCouplingCartesianAMRMeshGen::ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& 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<sz;i++)
- {
- partBeforeFact[i].first+=ghostSize;
- partBeforeFact[i].second+=ghostSize;
- }
-}
-
-/*!
- * This method is different than ApplyGhostOnCompactFrmt. The \a partBeforeFact parameter is enlarger contrary to ApplyGhostOnCompactFrmt.
- *
- * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
- * \param [in] ghostSize - the ghost size of zone for all axis.
- */
-void MEDCouplingCartesianAMRMeshGen::ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& 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<sz;i++)
- {
- partBeforeFact[i].first-=ghostSize;
- partBeforeFact[i].second+=ghostSize;
- }
-}
-
int MEDCouplingCartesianAMRMeshGen::GetGhostLevelInFineRef(int ghostLev, const std::vector<int>& factors)
{
if(ghostLev<0)
data->incrRef();
}
-void MEDCouplingCartesianAMRMesh::allocData(int ghostLev) const
+void MEDCouplingCartesianAMRMesh::allocData() const
{
checkData();
- _data->alloc(ghostLev);
+ _data->alloc();
}
void MEDCouplingCartesianAMRMesh::deallocData() const
// basic set/get
MEDCOUPLING_EXPORT const std::vector< std::pair<int,int> >& getBLTRRange() const { return _bl_tr; }
MEDCOUPLING_EXPORT static bool IsInMyNeighborhood(int ghostLev, const std::vector< std::pair<int,int> >& p1, const std::vector< std::pair<int,int> >& p2);
+ //
+ static std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > FindNeighborsOfSubPatchesOf(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2);
+ static void UpdateNeighborsOfOneWithTwo(int ghostLev, const std::vector<int>& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2);
+ static void UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector<int>& factors, const std::vector< std::pair<int,int> >&p1 ,const std::vector< std::pair<int,int> >&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<int> ComputeOffsetFromTwoToOne(const MEDCouplingCartesianAMRMeshGen *comAncestor, int lev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2);
+ public:
+ static void ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors);
+ static void ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize);
+ static void ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize);
private:
//! bottom left/top right cell range relative to \a _father
std::vector< std::pair<int,int> > _bl_tr;
{
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);
MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const;
// fine to fine
MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector<const DataArrayDouble *>& 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;
void checkPatchId(int patchId) const;
void checkFactorsAndIfNotSetAssign(const std::vector<int>& factors);
void retrieveGridsAtInternal(int lev, std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> >& grids) const;
- static void ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors);
- static void ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize);
- static void ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize);
static int GetGhostLevelInFineRef(int ghostLev, const std::vector<int>& factors);
std::vector<const DataArrayDouble *> extractSubTreeFromGlobalFlatten(const MEDCouplingCartesianAMRMeshGen *head, const std::vector<const DataArrayDouble *>& all) const;
protected:
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,
}
}
+/*!
+ * This method performs a translation (defined by \a translation) of \a part and returns the result of translated part.
+ */
+std::vector< std::pair<int,int> > MEDCouplingStructuredMesh::TranslateCompactFrmt(const std::vector< std::pair<int,int> >& part, const std::vector<int>& 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<int,int> > ret(sz);
+ for(std::size_t i=0;i<sz;i++)
+ {
+ ret[i].first=part[i].first+translation[i];
+ ret[i].second=part[i].second+translation[i];
+ }
+ return ret;
+}
+
/*!
* This method builds the explicit entity array from the structure in \a st and the range in \a partCompactFormat.
* If the range contains invalid values regarding sructure an exception will be thrown.
MEDCOUPLING_EXPORT static DataArrayDouble *ExtractFieldOfDoubleFrom(const std::vector<int>& st, const DataArrayDouble *fieldOfDbl, const std::vector< std::pair<int,int> >& partCompactFormat);
MEDCOUPLING_EXPORT static void ChangeReferenceFromGlobalOfCompactFrmt(const std::vector< std::pair<int,int> >& bigInAbs, const std::vector< std::pair<int,int> >& partOfBigInAbs, std::vector< std::pair<int,int> >& partOfBigRelativeToBig, bool check=true);
MEDCOUPLING_EXPORT static void ChangeReferenceToGlobalOfCompactFrmt(const std::vector< std::pair<int,int> >& bigInAbs, const std::vector< std::pair<int,int> >& partOfBigRelativeToBig, std::vector< std::pair<int,int> >& partOfBigInAbs, bool check=true);
+ MEDCOUPLING_EXPORT static std::vector< std::pair<int,int> > TranslateCompactFrmt(const std::vector< std::pair<int,int> >& part, const std::vector<int>& translation);
MEDCOUPLING_EXPORT static DataArrayInt *BuildExplicitIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat);
MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivity(const int *nodeStBg, const int *nodeStEnd);
MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh(const int *nodeStBg, const int *nodeStEnd);
return retPy;
}
+ static PyObject *TranslateCompactFrmt(PyObject *part, const std::vector<int>& translation) throw(INTERP_KERNEL::Exception)
+ {
+ std::vector< std::pair<int,int> > param0;
+ convertPyToVectorPairInt(part,param0);
+ std::vector< std::pair<int,int> > ret(MEDCouplingStructuredMesh::TranslateCompactFrmt(param0,translation));
+ PyObject *retPy(PyList_New(ret.size()));
+ for(std::size_t i=0;i<ret.size();i++)
+ {
+ PyObject *tmp(PyTuple_New(2));
+ PyTuple_SetItem(tmp,0,PyInt_FromLong(ret[i].first));
+ PyTuple_SetItem(tmp,1,PyInt_FromLong(ret[i].second));
+ PyList_SetItem(retPy,i,tmp);
+ }
+ return retPy;
+ }
+
static PyObject *ChangeReferenceToGlobalOfCompactFrmt(PyObject *bigInAbs, PyObject *partOfBigRelativeToBig, bool check=true) throw(INTERP_KERNEL::Exception)
{
std::vector< std::pair<int,int> > param0,param1,ret;
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);
};
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);
{
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
{
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<std::string,int> > fieldNamesCpp0;
std::vector< std::pair<std::string, std::vector<std::string> > > fieldNamesCpp1;
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)