1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay
21 #include "MEDCouplingAMRAttribute.hxx"
22 #include "MEDCouplingFieldDouble.hxx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingIMesh.hxx"
28 using namespace ParaMEDMEM;
30 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
32 return new DataArrayDoubleCollection(fieldNames);
35 DataArrayDoubleCollection *DataArrayDoubleCollection::deepCpy() const
37 return new DataArrayDoubleCollection(*this);
40 void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
42 std::size_t sz(_arrs.size());
43 for(std::size_t i=0;i<sz;i++)
44 _arrs[i].first->reAlloc(nbOfTuples);
47 void DataArrayDoubleCollection::dellocTuples()
49 std::size_t sz(_arrs.size());
50 for(std::size_t i=0;i<sz;i++)
51 _arrs[i].first->reAlloc(0);
54 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
56 std::size_t sz(_arrs.size());
57 if(sz!=compNames.size())
58 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
59 for(std::size_t i=0;i<sz;i++)
61 const std::vector<std::string>& names(compNames[i]);
62 _arrs[i].first->setInfoOnComponents(names);
66 void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& nfs)
68 std::size_t sz(_arrs.size());
70 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !");
71 for(std::size_t i=0;i<sz;i++)
73 CheckValidNature(nfs[i]);
74 _arrs[i].second=nfs[i];
78 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
80 std::size_t sz(_arrs.size());
81 std::vector<DataArrayDouble *> ret(sz);
82 for(std::size_t i=0;i<sz;i++)
84 const DataArrayDouble *tmp(_arrs[i].first);
85 ret[i]=const_cast<DataArrayDouble *>(tmp);
92 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
94 std::vector<std::string> vec;
95 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
97 const DataArrayDouble *obj((*it).first);
100 if(obj->getName()==name)
103 vec.push_back(obj->getName());
106 std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
107 std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
108 throw INTERP_KERNEL::Exception(oss.str().c_str());
111 void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
114 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
115 std::size_t sz(coarse->_arrs.size());
116 if(fine->_arrs.size()!=sz)
117 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
118 for(std::size_t i=0;i<sz;i++)
120 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
121 fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
125 void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
128 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
129 std::size_t sz(coarse->_arrs.size());
130 if(fine->_arrs.size()!=sz)
131 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
132 for(std::size_t i=0;i<sz;i++)
134 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
135 fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
139 void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
141 if(!fatherOfFineMesh)
142 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
143 std::size_t sz(children.size());
144 if(fieldsOnFine.size()!=sz)
145 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
148 std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
149 for(std::size_t i=0;i<sz;i++)
150 if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
151 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
152 for(std::size_t i=1;i<sz;i++)
153 if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
154 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
155 for(std::size_t i=0;i<nbOfCall;i++)
157 std::vector<const DataArrayDouble *> arrs(sz);
158 for(std::size_t j=0;j<sz;j++)
159 arrs[j]=fieldsOnFine[j]->_arrs[i].first;
160 fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
165 * This method updates \a p1dac ghost zone parts using \a p2dac (which is really const). \a p2 is in the neighborhood of \a p1 (which size is defined by \a ghostLev).
167 void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac)
169 if(!p1 || !p1dac || !p2 || !p2dac)
170 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !");
171 std::size_t sz(p1dac->_arrs.size());
172 if(p2dac->_arrs.size()!=sz)
173 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !");
174 for(std::size_t i=0;i<sz;i++)
176 const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first);
177 DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second);
178 bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second));
179 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative);
183 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
186 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
187 std::size_t sz(coarse->_arrs.size());
188 if(fine->_arrs.size()!=sz)
189 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
190 for(std::size_t i=0;i<sz;i++)
191 fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev);
194 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
196 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
197 std::size_t sz(_arrs.size());
198 if(other._arrs.size()!=sz)
199 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
200 for(std::size_t i=0;i<sz;i++)
201 father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
204 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
206 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
207 std::size_t sz(_arrs.size());
208 if(other._arrs.size()!=sz)
209 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
210 for(std::size_t i=0;i<sz;i++)
211 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
214 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
216 std::size_t sz(fieldNames.size());
217 std::vector<std::string> names(sz);
218 for(std::size_t i=0;i<sz;i++)
220 const std::pair<std::string,int>& info(fieldNames[i]);
221 _arrs[i].first=DataArrayDouble::New();
222 _arrs[i].first->alloc(0,info.second);
223 _arrs[i].first->setName(info.first);
224 names[i]=info.second;
225 _arrs[i].second=ConservativeVolumic;
227 CheckDiscriminantNames(names);
230 DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size())
232 std::size_t sz(other._arrs.size());
233 for(std::size_t i=0;i<sz;i++)
235 _arrs[i].second=other._arrs[i].second;
236 const DataArrayDouble *da(other._arrs[i].first);
238 _arrs[i].first=da->deepCpy();
242 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
244 std::size_t ret(sizeof(DataArrayDoubleCollection));
245 ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
249 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
251 std::vector<const BigMemoryObject *> ret;
252 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
254 const DataArrayDouble *pt((*it).first);
261 void DataArrayDoubleCollection::updateTime() const
263 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
265 const DataArrayDouble *pt((*it).first);
271 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
273 std::set<std::string> s(names.begin(),names.end());
274 if(s.size()!=names.size())
275 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
278 bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
281 return n==RevIntegral || n==IntegralGlobConstraint;
284 void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
286 CheckValidNature(n1);
287 CheckValidNature(n2);
289 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
292 void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
294 if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral)
295 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
298 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
300 return new MEDCouplingGridCollection(ms,fieldNames);
303 MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
305 return new MEDCouplingGridCollection(*this,newGf,oldGf);
308 void MEDCouplingGridCollection::alloc(int ghostLev)
310 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
312 int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
313 DataArrayDoubleCollection *dadc((*it).second);
315 dadc->allocTuples(nbTuples);
317 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
321 void MEDCouplingGridCollection::dealloc()
323 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
325 DataArrayDoubleCollection *dadc((*it).second);
327 dadc->dellocTuples();
329 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
333 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
335 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
336 (*it).second->spillInfoOnComponents(compNames);
339 void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
341 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
342 (*it).second->spillNatures(nfs);
345 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
348 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
359 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
361 if(pos<0 || pos>(int)_map_of_dadc.size())
362 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
363 return *_map_of_dadc[pos].second;
366 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
369 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
370 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
371 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
372 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
374 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
375 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
377 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
379 if((*it0).first==fatherOfFineMesh)
382 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
383 const DataArrayDoubleCollection *coarseDaCol((*it0).second);
384 DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
385 DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
389 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
393 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
396 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
397 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
398 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
399 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
401 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
402 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
404 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
406 if((*it0).first==fatherOfFineMesh)
409 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
410 const DataArrayDoubleCollection *fineDaCol((*it).second);
411 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
412 DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
416 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
421 * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
423 * \sa synchronizeFineEachOtherExt
425 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
427 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
430 if(!presenceOf((*it).first->getMesh(),p1))
431 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
432 if(!presenceOf((*it).second->getMesh(),p2))
433 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
434 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
435 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
436 col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
441 * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
443 * \sa synchronizeFineEachOther
445 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
447 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
450 if(!presenceOf((*it).first->getMesh(),p1))
451 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
452 if(!presenceOf((*it).second->getMesh(),p2))
453 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
454 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
455 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
456 col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
461 * The pairs returned share the same direct father. The number of returned elements must be even.
463 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
465 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
466 std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
467 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
469 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
470 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
471 m[fatherOfFineMesh].push_back(fineMesh);
473 for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
475 for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
477 int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
478 std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
479 const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
480 for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
482 const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
483 ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
488 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
492 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
495 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
496 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
497 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
498 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
500 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
501 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
503 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
505 if((*it0).first==fatherOfFineMesh)
508 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
509 const DataArrayDoubleCollection *fineDaCol((*it).second);
510 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
511 DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
515 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
519 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
521 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
523 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
524 if(head==a || head->isObjectInTheProgeny(a))
526 const DataArrayDoubleCollection *gc((*it).second);
527 recurseArrs.push_back(gc->getFieldWithName(fieldName));
532 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
534 std::size_t sz(ms.size());
535 for(std::size_t i=0;i<sz;i++)
538 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
539 _map_of_dadc[i].first=ms[i];
540 _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
544 MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
546 std::size_t sz(other._map_of_dadc.size());
547 for(std::size_t i=0;i<sz;i++)
549 std::vector<int> pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf));
550 _map_of_dadc[i].first=newGf->getMeshAtPosition(pos);
551 const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
553 _map_of_dadc[i].second=dac->deepCpy();
557 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
559 std::size_t ret(sizeof(MEDCouplingGridCollection));
560 ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
564 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
566 std::vector<const BigMemoryObject *> ret;
567 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
569 const DataArrayDoubleCollection *col((*it).second);
576 void MEDCouplingGridCollection::updateTime() const
578 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
580 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
583 const DataArrayDoubleCollection *b((*it).second);
589 MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather()
594 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
597 throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
601 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
606 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
608 bool ret(_tlc.keepTrackOfNewTL(gf));
618 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
620 other._tlc.checkConst();
623 const MEDCouplingCartesianAMRMesh *gf(other._gf);
626 _tlc.keepTrackOfNewTL(_gf);
631 * 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.
633 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
635 return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
638 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
640 std::size_t sz(fieldNames.size());
641 std::vector< std::pair<std::string,int> > fieldNames2(sz);
642 std::vector< std::vector<std::string> > compNames(sz);
643 for(std::size_t i=0;i<sz;i++)
645 fieldNames2[i].first=fieldNames[i].first;
646 fieldNames2[i].second=(int)fieldNames[i].second.size();
647 compNames[i]=fieldNames[i].second;
649 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
650 ret->spillInfoOnComponents(compNames);
655 * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
656 * The first dim of input \a compNames is the field id in the same order than those implicitely specified in \a fieldNames parameter of MEDCouplingAMRAttribute::New.
657 * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
658 * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
660 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
663 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
664 (*it)->spillInfoOnComponents(compNames);
668 * Assign nature for each fields in \a this.
671 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
674 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
675 (*it)->spillNatures(nfs);
678 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const
680 return new MEDCouplingAMRAttribute(*this,true);
683 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const
685 return new MEDCouplingAMRAttribute(*this,false);
689 * Returns the number of levels by \b only \b considering \a this (god father instance is considered only to see if it has not changed still last update of \a this).
692 int MEDCouplingAMRAttribute::getNumberOfLevels() const
694 checkGodFatherFrozen();
695 return (int)_levs.size();
699 * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
700 * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
702 * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
703 * \sa retrieveFieldOn
705 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
707 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
710 if((*it)->presenceOf(mesh,tmp))
712 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
713 return ddc.retrieveFields();
716 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
720 * \sa retrieveFieldsOn
722 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
724 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
727 if((*it)->presenceOf(mesh,tmp))
729 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
730 return ddc.getFieldWithName(fieldName);
733 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldOn : the mesh specified is not in the progeny of this !");
737 * This method returns a field on an unstructured mesh the most refined as possible without overlap.
738 * Ghost part are not visible here.
740 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
742 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
744 std::vector<const DataArrayDouble *> recurseArrs;
746 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
749 if((*it)->presenceOf(mesh,tmp))
751 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
752 recurseArrs.push_back(ddc.getFieldWithName(fieldName));
757 for(std::size_t i=lev;i<_levs.size();i++)
759 const MEDCouplingGridCollection *gc(_levs[i]);
760 gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
762 return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
766 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
767 * The output field also displays ghost cells.
769 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
771 * \sa buildCellFieldOnWithoutGhost
773 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
775 const DataArrayDouble *arr(0);
776 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
779 if((*it)->presenceOf(mesh,tmp))
781 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
782 arr=ddc.getFieldWithName(fieldName);
786 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
787 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
788 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
790 ret->setArray(const_cast<DataArrayDouble *>(arr));
791 ret->setName(arr->getName());
796 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
797 * The output field does not display ghost cells.
799 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
801 * \sa buildCellFieldOnWithGhost
803 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
806 const DataArrayDouble *arr(0);
807 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
810 if((*it)->presenceOf(mesh,tmp))
812 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
813 arr=ddc.getFieldWithName(fieldName);
817 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
819 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
820 std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
821 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New());
822 arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
823 std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
824 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
825 std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
826 MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
827 arr2->copyStringInfoFrom(*arr);
829 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
830 ret->setMesh(mesh->getImageMesh());
832 ret->setName(arr->getName());
837 * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
838 * MEDCouplingAMRAttribute::alloc method.
839 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse)
841 * \sa synchronizeFineToCoarseBetween
843 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
846 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
847 std::size_t sz(_levs.size());
852 synchronizeFineToCoarseByOneLevel((int)sz);
857 * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
858 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
859 * until reaching \a toLev level.
860 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse).
862 * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
863 * \param [in] toLev - an existing level considered as the target level to reach.
866 void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
868 int nbl(getNumberOfLevels());
869 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
870 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
872 return ;//nothing to do
874 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
875 for(int i=fromLev;i>toLev;i--)
876 synchronizeFineToCoarseByOneLevel(i);
880 * 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
881 * MEDCouplingAMRAttribute::alloc method.
882 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method)
884 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
887 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
888 std::size_t sz(_levs.size());
890 for(std::size_t i=0;i<sz-1;i++)
891 synchronizeCoarseToFineByOneLevel((int)i);
895 * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
896 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
897 * until reaching \a toLev level.
898 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarseBetween method)
900 * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
901 * \param [in] toLev - an existing level considered as the target level to reach.
903 void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
905 int nbl(getNumberOfLevels());
906 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
907 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
909 return ;//nothing to do
911 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
912 for(int i=fromLev;i<toLev;i++)
913 synchronizeCoarseToFineByOneLevel(i);
917 * This method synchronizes the ghost zone of all patches (excepted the god father one).
918 * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
920 * - firstly coarse to fine with no interactions between brother patches.
921 * - secondly connected brother patches in a same master patch are updated.
922 * - thirdly connected nephew patches are updated each other.
923 * - forthly nth generation cousin patches are updated each other.
925 * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
926 * So if \a _ghost_lev == 0 this method has no effect.
928 void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
930 int sz(getNumberOfLevels());
932 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
933 // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
934 for(int i=1;i<sz;i++)
936 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
937 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
939 // 2nd - classical direct sublevel inside common patch
940 for(int i=1;i<sz;i++)
942 const MEDCouplingGridCollection *curLev(_levs[i]);
944 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
945 curLev->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
948 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
950 const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
951 DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
953 // 4th - same level but with far ancestor.
954 for(int i=1;i<sz;i++)
956 const MEDCouplingGridCollection *fine(_levs[i]);
957 fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
962 * This method works \b ONLY \b ON \b DIRECT \b SONS \b OF \a mesh. So only a part of patches at a given level is updated here.
963 * The ghost zone of all of these sons of \a mesh are updated using the brother patches (the patches sharing the \b SAME \a mesh).
964 * It is sometimes possible that a ghost zone of some sons of \a mesh are covered by a patch of same level but different father.
965 * For such cases, the ghost zones are \b NOT updated. If you need a more thorough (but more costly) ghost zone update use synchronizeAllGhostZonesAtASpecifiedLevel method instead.
967 * \param [in] mesh - an element in the progeny of god father in \a this, which the ghost zone of its sons will be updated each other.
970 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh)
973 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !");
974 int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels());
975 if(level<0 || level>=sz-1)
976 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !");
977 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& itemsToFilter(_neighbors[level+1]);
978 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > itemsToSync; itemsToSync.reserve(itemsToFilter.size());
979 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++)
981 if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh)
982 itemsToSync.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>((*it).first,(*it).second));
984 const MEDCouplingGridCollection *curLev(_levs[level+1]);
986 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !");
987 curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync);
991 * This method updates \b all the patches at level \a level each other without consideration of their father.
992 * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf.
994 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level)
996 int maxLev(getNumberOfLevels());
997 if(level<0 || level>=maxLev)
998 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !");
1000 return ;//at level 0 only one patch -> no need to update
1001 // 1st step - updates all patches pairs at level \a level sharing the same father
1002 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items(_neighbors[level]);
1003 const MEDCouplingGridCollection *curLev(_levs[level]);
1005 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !");
1006 curLev->synchronizeFineEachOther(_ghost_lev,items);
1007 //2nd step - updates all patches pairs at level \a level not sharing the same father
1008 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items2(_cross_lev_neighbors[level]);
1009 curLev->synchronizeFineEachOtherExt(_ghost_lev,items2);
1013 * This method updates ghost zones of patches at level \a level whatever their father \b using \b father \b patches \b ONLY (at level \b level - 1).
1014 * This method is useful to propagate to the ghost zone of childhood the modification.
1016 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level)
1018 int maxLev(getNumberOfLevels());
1019 if(level<=0 || level>=maxLev)
1020 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !");
1021 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1022 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1023 //_cross_lev_neighbors is not needed.
1027 * This method allocates all DataArrayDouble instances stored recursively in \a this.
1031 void MEDCouplingAMRAttribute::alloc()
1034 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1036 MEDCouplingGridCollection *elt(*it);
1038 elt->alloc(_ghost_lev);
1040 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
1045 * This method deallocates all DataArrayDouble instances stored recursively in \a this.
1048 void MEDCouplingAMRAttribute::dealloc()
1051 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1053 MEDCouplingGridCollection *elt(*it);
1057 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
1061 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
1063 bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
1067 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
1069 std::size_t ret(sizeof(MEDCouplingAMRAttribute));
1070 ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
1074 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
1076 std::vector<const BigMemoryObject *> ret;
1077 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1079 const MEDCouplingGridCollection *elt(*it);
1086 void MEDCouplingAMRAttribute::updateTime() const
1090 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
1092 //gf non empty, checked by constructor
1093 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
1094 _levs.resize(maxLev);
1095 for(int i=0;i<maxLev;i++)
1097 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1098 std::size_t sz(patches.size());
1099 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
1100 for(std::size_t j=0;j<sz;j++)
1101 patchesSafe[j]=patches[j];
1102 std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
1103 for(std::size_t j=0;j<sz;j++)
1105 ms[j]=patches[j]->getMesh();
1107 _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
1109 // updates cross levels neighbors
1110 _neighbors.resize(_levs.size());
1111 _cross_lev_neighbors.resize(_levs.size());
1113 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
1114 std::size_t sz(_levs.size());
1115 for(std::size_t i=1;i<sz;i++)
1117 const MEDCouplingGridCollection *fine(_levs[i]);
1119 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
1120 _neighbors[i]=fine->findNeighbors(_ghost_lev);
1123 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
1125 MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
1126 std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
1127 std::size_t fullLev(i+neighs2.size());
1129 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
1130 std::size_t ii(i+1);
1131 for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
1132 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
1138 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& other, bool deepCpyGF):MEDCouplingDataForGodFather(other,deepCpyGF),_ghost_lev(other._ghost_lev),_levs(other._levs.size()),_neighbors(other._neighbors),_mixed_lev_neighbors(other._mixed_lev_neighbors),_cross_lev_neighbors(other._cross_lev_neighbors)
1140 std::size_t sz(other._levs.size());
1141 for(std::size_t i=0;i<sz;i++)
1143 const MEDCouplingGridCollection *elt(other._levs[i]);
1146 _levs[i]=other._levs[i]->deepCpy(_gf,other._gf);
1149 //_cross_lev_neighbors(other._cross_lev_neighbors)
1150 sz=other._neighbors.size();
1151 for(std::size_t i=0;i<sz;i++)
1153 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._neighbors[i]);
1154 std::size_t sz2(neigh2.size());
1155 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_neighbors[i]);
1156 for(std::size_t j=0;j<sz2;j++)
1158 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1159 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1160 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1161 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1165 sz=other._mixed_lev_neighbors.size();
1166 for(std::size_t i=0;i<sz;i++)
1168 const MEDCouplingCartesianAMRPatch *p1(other._mixed_lev_neighbors[i].first),*p2(other._mixed_lev_neighbors[i].second);
1169 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1170 _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1);
1171 _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2);
1174 sz=other._cross_lev_neighbors.size();
1175 for(std::size_t i=0;i<sz;i++)
1177 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._cross_lev_neighbors[i]);
1178 std::size_t sz2(neigh2.size());
1179 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_cross_lev_neighbors[i]);
1180 for(std::size_t j=0;j<sz2;j++)
1182 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1183 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1184 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1185 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1190 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
1192 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1194 const MEDCouplingGridCollection *elt(*it);
1198 if(elt->presenceOf(m,tmp))
1200 return elt->getFieldsAt(tmp);
1204 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
1207 void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
1209 int nbl(getNumberOfLevels());
1210 if(level<=0 || level>=nbl)
1211 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
1212 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1213 MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
1216 void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
1218 int nbl(getNumberOfLevels());
1219 if(level<0 || level>=nbl-1)
1220 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
1221 const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
1222 MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);