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 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first);
181 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
184 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
185 std::size_t sz(coarse->_arrs.size());
186 if(fine->_arrs.size()!=sz)
187 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
188 for(std::size_t i=0;i<sz;i++)
189 fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev);
192 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
194 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
195 std::size_t sz(_arrs.size());
196 if(other._arrs.size()!=sz)
197 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
198 for(std::size_t i=0;i<sz;i++)
199 father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
202 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
204 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
205 std::size_t sz(_arrs.size());
206 if(other._arrs.size()!=sz)
207 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
208 for(std::size_t i=0;i<sz;i++)
209 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
212 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
214 std::size_t sz(fieldNames.size());
215 std::vector<std::string> names(sz);
216 for(std::size_t i=0;i<sz;i++)
218 const std::pair<std::string,int>& info(fieldNames[i]);
219 _arrs[i].first=DataArrayDouble::New();
220 _arrs[i].first->alloc(0,info.second);
221 _arrs[i].first->setName(info.first);
222 names[i]=info.second;
223 _arrs[i].second=ConservativeVolumic;
225 CheckDiscriminantNames(names);
228 DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size())
230 std::size_t sz(other._arrs.size());
231 for(std::size_t i=0;i<sz;i++)
233 _arrs[i].second=other._arrs[i].second;
234 const DataArrayDouble *da(other._arrs[i].first);
236 _arrs[i].first=da->deepCpy();
240 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
242 std::size_t ret(sizeof(DataArrayDoubleCollection));
243 ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
247 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
249 std::vector<const BigMemoryObject *> ret;
250 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
252 const DataArrayDouble *pt((*it).first);
259 void DataArrayDoubleCollection::updateTime() const
261 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
263 const DataArrayDouble *pt((*it).first);
269 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
271 std::set<std::string> s(names.begin(),names.end());
272 if(s.size()!=names.size())
273 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
276 bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
279 return n==RevIntegral || n==IntegralGlobConstraint;
282 void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
284 CheckValidNature(n1);
285 CheckValidNature(n2);
287 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
290 void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
292 if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral)
293 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
296 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
298 return new MEDCouplingGridCollection(ms,fieldNames);
301 MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
303 return new MEDCouplingGridCollection(*this,newGf,oldGf);
306 void MEDCouplingGridCollection::alloc(int ghostLev)
308 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
310 int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
311 DataArrayDoubleCollection *dadc((*it).second);
313 dadc->allocTuples(nbTuples);
315 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
319 void MEDCouplingGridCollection::dealloc()
321 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
323 DataArrayDoubleCollection *dadc((*it).second);
325 dadc->dellocTuples();
327 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
331 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
333 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
334 (*it).second->spillInfoOnComponents(compNames);
337 void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
339 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
340 (*it).second->spillNatures(nfs);
343 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
346 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
357 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
359 if(pos<0 || pos>(int)_map_of_dadc.size())
360 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
361 return *_map_of_dadc[pos].second;
364 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
367 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
368 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
369 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
370 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
372 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
373 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
375 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
377 if((*it0).first==fatherOfFineMesh)
380 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
381 const DataArrayDoubleCollection *coarseDaCol((*it0).second);
382 DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
383 DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
387 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
391 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
394 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
395 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
396 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
397 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
399 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
400 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
402 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
404 if((*it0).first==fatherOfFineMesh)
407 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
408 const DataArrayDoubleCollection *fineDaCol((*it).second);
409 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
410 DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
414 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
419 * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
421 * \sa synchronizeFineEachOtherExt
423 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
425 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
428 if(!presenceOf((*it).first->getMesh(),p1))
429 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
430 if(!presenceOf((*it).second->getMesh(),p2))
431 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
432 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
433 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
434 col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
439 * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
441 * \sa synchronizeFineEachOther
443 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
445 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
448 if(!presenceOf((*it).first->getMesh(),p1))
449 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
450 if(!presenceOf((*it).second->getMesh(),p2))
451 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
452 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
453 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
454 col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
459 * The pairs returned share the same direct father. The number of returned elements must be even.
461 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
463 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
464 std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
465 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
467 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
468 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
469 m[fatherOfFineMesh].push_back(fineMesh);
471 for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
473 for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
475 int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
476 std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
477 const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
478 for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
480 const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
481 ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
486 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
490 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
493 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
494 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
495 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
496 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
498 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
499 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
501 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
503 if((*it0).first==fatherOfFineMesh)
506 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
507 const DataArrayDoubleCollection *fineDaCol((*it).second);
508 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
509 DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
513 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
517 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
519 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
521 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
522 if(head==a || head->isObjectInTheProgeny(a))
524 const DataArrayDoubleCollection *gc((*it).second);
525 recurseArrs.push_back(gc->getFieldWithName(fieldName));
530 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
532 std::size_t sz(ms.size());
533 for(std::size_t i=0;i<sz;i++)
536 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
537 _map_of_dadc[i].first=ms[i];
538 _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
542 MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
544 std::size_t sz(other._map_of_dadc.size());
545 for(std::size_t i=0;i<sz;i++)
547 std::vector<int> pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf));
548 _map_of_dadc[i].first=newGf->getMeshAtPosition(pos);
549 const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
551 _map_of_dadc[i].second=dac->deepCpy();
555 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
557 std::size_t ret(sizeof(MEDCouplingGridCollection));
558 ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
562 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
564 std::vector<const BigMemoryObject *> ret;
565 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
567 const DataArrayDoubleCollection *col((*it).second);
574 void MEDCouplingGridCollection::updateTime() const
576 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
578 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
581 const DataArrayDoubleCollection *b((*it).second);
587 MEDCouplingCartesianAMRMeshGen *MEDCouplingDataForGodFather::getMyGodFather()
592 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMeshGen *gf):_gf(gf),_tlc(gf)
595 throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
599 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
604 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMeshGen *gf)
606 bool ret(_tlc.keepTrackOfNewTL(gf));
616 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
618 other._tlc.checkConst();
621 const MEDCouplingCartesianAMRMeshGen *gf(other._gf);
624 _tlc.keepTrackOfNewTL(_gf);
629 * 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.
631 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
633 return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
636 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
638 std::size_t sz(fieldNames.size());
639 std::vector< std::pair<std::string,int> > fieldNames2(sz);
640 std::vector< std::vector<std::string> > compNames(sz);
641 for(std::size_t i=0;i<sz;i++)
643 fieldNames2[i].first=fieldNames[i].first;
644 fieldNames2[i].second=(int)fieldNames[i].second.size();
645 compNames[i]=fieldNames[i].second;
647 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
648 ret->spillInfoOnComponents(compNames);
653 * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
654 * 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.
655 * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
656 * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
658 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
661 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
662 (*it)->spillInfoOnComponents(compNames);
666 * Assign nature for each fields in \a this.
669 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
672 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
673 (*it)->spillNatures(nfs);
676 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const
678 return new MEDCouplingAMRAttribute(*this,true);
681 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const
683 return new MEDCouplingAMRAttribute(*this,false);
687 * 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).
690 int MEDCouplingAMRAttribute::getNumberOfLevels() const
692 checkGodFatherFrozen();
693 return (int)_levs.size();
697 * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
698 * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
700 * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
701 * \sa retrieveFieldOn
703 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
705 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
708 if((*it)->presenceOf(mesh,tmp))
710 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
711 return ddc.retrieveFields();
714 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
718 * \sa retrieveFieldsOn
720 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
722 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
725 if((*it)->presenceOf(mesh,tmp))
727 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
728 return ddc.getFieldWithName(fieldName);
731 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldOn : the mesh specified is not in the progeny of this !");
735 * This method returns a field on an unstructured mesh the most refined as possible without overlap.
736 * Ghost part are not visible here.
738 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
740 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
742 std::vector<const DataArrayDouble *> recurseArrs;
744 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
747 if((*it)->presenceOf(mesh,tmp))
749 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
750 recurseArrs.push_back(ddc.getFieldWithName(fieldName));
755 for(std::size_t i=lev;i<_levs.size();i++)
757 const MEDCouplingGridCollection *gc(_levs[i]);
758 gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
760 return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
764 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
765 * The output field also displays ghost cells.
767 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
769 * \sa buildCellFieldOnWithoutGhost
771 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
773 const DataArrayDouble *arr(0);
774 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
777 if((*it)->presenceOf(mesh,tmp))
779 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
780 arr=ddc.getFieldWithName(fieldName);
784 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
785 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
786 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
788 ret->setArray(const_cast<DataArrayDouble *>(arr));
789 ret->setName(arr->getName());
794 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
795 * The output field does not display ghost cells.
797 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
799 * \sa buildCellFieldOnWithGhost
801 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
804 const DataArrayDouble *arr(0);
805 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
808 if((*it)->presenceOf(mesh,tmp))
810 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
811 arr=ddc.getFieldWithName(fieldName);
815 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
817 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
818 std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
819 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New());
820 arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
821 std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
822 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
823 std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
824 MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
825 arr2->copyStringInfoFrom(*arr);
827 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
828 ret->setMesh(mesh->getImageMesh());
830 ret->setName(arr->getName());
835 * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
836 * MEDCouplingAMRAttribute::alloc method.
838 * \sa synchronizeFineToCoarseBetween
840 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
843 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
844 std::size_t sz(_levs.size());
849 synchronizeFineToCoarseByOneLevel((int)sz);
854 * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
855 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
856 * until reaching \a toLev level.
858 * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
859 * \param [in] toLev - an existing level considered as the target level to reach.
862 void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
864 int nbl(getNumberOfLevels());
865 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
866 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
868 return ;//nothing to do
870 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
871 for(int i=fromLev;i>toLev;i--)
872 synchronizeFineToCoarseByOneLevel(i);
876 * 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
877 * MEDCouplingAMRAttribute::alloc method.
879 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
882 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
883 std::size_t sz(_levs.size());
885 for(std::size_t i=0;i<sz-1;i++)
886 synchronizeCoarseToFineByOneLevel((int)i);
890 * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
891 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
892 * until reaching \a toLev level.
894 * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
895 * \param [in] toLev - an existing level considered as the target level to reach.
897 void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
899 int nbl(getNumberOfLevels());
900 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
901 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
903 return ;//nothing to do
905 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
906 for(int i=fromLev;i<toLev;i++)
907 synchronizeCoarseToFineByOneLevel(i);
911 * This method synchronizes the ghost zone of all patches (excepted the god father one).
912 * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
914 * - firstly coarse to fine with no interactions between brother patches.
915 * - secondly connected brother patches in a same master patch are updated.
916 * - thirdly connected nephew patches are updated each other.
917 * - forthly nth generation cousin patches are updated each other.
919 * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
920 * So if \a _ghost_lev == 0 this method has no effect.
922 void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
924 int sz(getNumberOfLevels());
926 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
927 // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
928 for(int i=1;i<sz;i++)
930 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
931 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
933 // 2nd - classical direct sublevel inside common patch
934 for(int i=1;i<sz;i++)
936 const MEDCouplingGridCollection *fine(_levs[i]);
938 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
939 fine->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
942 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
944 const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
945 DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
947 // 4th - same level but with far ancestor.
948 for(int i=1;i<sz;i++)
950 const MEDCouplingGridCollection *fine(_levs[i]);
951 fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
958 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh)
961 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !");
962 int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels());
963 if(level<0 || level>=sz-1)
964 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !");
965 const DataArrayDoubleCollection& colCoarse(findCollectionAttachedTo(mesh));
966 std::vector< const MEDCouplingCartesianAMRPatch *> directChildren(mesh->getPatches());
967 std::size_t nbOfDirChildren(directChildren.size());
968 for(std::size_t patchId=0;patchId<nbOfDirChildren;patchId++)
970 const DataArrayDoubleCollection& colFine(findCollectionAttachedTo(directChildren[patchId]->getMesh()));
971 DataArrayDoubleCollection *colFine2(const_cast<DataArrayDoubleCollection *>(&colFine));
972 DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,mesh,(int)patchId,&colCoarse,colFine2);
977 * This method allocates all DataArrayDouble instances stored recursively in \a this.
981 void MEDCouplingAMRAttribute::alloc()
984 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
986 MEDCouplingGridCollection *elt(*it);
988 elt->alloc(_ghost_lev);
990 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
995 * This method deallocates all DataArrayDouble instances stored recursively in \a this.
998 void MEDCouplingAMRAttribute::dealloc()
1001 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1003 MEDCouplingGridCollection *elt(*it);
1007 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
1011 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMeshGen *gf)
1013 bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
1017 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
1019 std::size_t ret(sizeof(MEDCouplingAMRAttribute));
1020 ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
1024 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
1026 std::vector<const BigMemoryObject *> ret;
1027 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1029 const MEDCouplingGridCollection *elt(*it);
1036 void MEDCouplingAMRAttribute::updateTime() const
1040 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
1042 //gf non empty, checked by constructor
1043 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
1044 _levs.resize(maxLev);
1045 for(int i=0;i<maxLev;i++)
1047 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1048 std::size_t sz(patches.size());
1049 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
1050 for(std::size_t j=0;j<sz;j++)
1051 patchesSafe[j]=patches[j];
1052 std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
1053 for(std::size_t j=0;j<sz;j++)
1055 ms[j]=patches[j]->getMesh();
1057 _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
1059 // updates cross levels neighbors
1060 _neighbors.resize(_levs.size());
1061 _cross_lev_neighbors.resize(_levs.size());
1063 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
1064 std::size_t sz(_levs.size());
1065 for(std::size_t i=1;i<sz;i++)
1067 const MEDCouplingGridCollection *fine(_levs[i]);
1069 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
1070 _neighbors[i]=fine->findNeighbors(_ghost_lev);
1073 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
1075 MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
1076 std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
1077 std::size_t fullLev(i+neighs2.size());
1079 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
1080 std::size_t ii(i+1);
1081 for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
1082 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
1088 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)
1090 std::size_t sz(other._levs.size());
1091 for(std::size_t i=0;i<sz;i++)
1093 const MEDCouplingGridCollection *elt(other._levs[i]);
1096 _levs[i]=other._levs[i]->deepCpy(_gf,other._gf);
1101 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
1103 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1105 const MEDCouplingGridCollection *elt(*it);
1109 if(elt->presenceOf(m,tmp))
1111 return elt->getFieldsAt(tmp);
1115 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
1118 void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
1120 int nbl(getNumberOfLevels());
1121 if(level<=0 || level>=nbl)
1122 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
1123 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1124 MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
1127 void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
1129 int nbl(getNumberOfLevels());
1130 if(level<0 || level>=nbl-1)
1131 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
1132 const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
1133 MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);