]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/MEDCoupling/MEDCouplingAMRAttribute.cxx
Salome HOME
Stash 5.
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingAMRAttribute.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay
20
21 #include "MEDCouplingAMRAttribute.hxx"
22 #include "MEDCouplingFieldDouble.hxx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingIMesh.hxx"
25
26 #include <sstream>
27
28 using namespace ParaMEDMEM;
29
30 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
31 {
32   return new DataArrayDoubleCollection(fieldNames);
33 }
34
35 void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
36 {
37   std::size_t sz(_arrs.size());
38   for(std::size_t i=0;i<sz;i++)
39     _arrs[i]->reAlloc(nbOfTuples);
40 }
41
42 void DataArrayDoubleCollection::dellocTuples()
43 {
44   std::size_t sz(_arrs.size());
45   for(std::size_t i=0;i<sz;i++)
46     _arrs[i]->reAlloc(0);
47 }
48
49 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
50 {
51   std::size_t sz(_arrs.size());
52   if(sz!=compNames.size())
53     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
54   for(std::size_t i=0;i<sz;i++)
55     {
56       const std::vector<std::string>& names(compNames[i]);
57       _arrs[i]->setInfoOnComponents(names);
58     }
59 }
60
61 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
62 {
63   std::size_t sz(_arrs.size());
64   std::vector<DataArrayDouble *> ret(sz);
65   for(std::size_t i=0;i<sz;i++)
66     {
67       const DataArrayDouble *tmp(_arrs[i]);
68       ret[i]=const_cast<DataArrayDouble *>(tmp);
69       if(ret[i])
70         ret[i]->incrRef();
71     }
72   return ret;
73 }
74
75 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
76 {
77   std::vector<std::string> vec;
78   for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
79     {
80       const DataArrayDouble *obj(*it);
81       if(obj)
82         {
83           if(obj->getName()==name)
84             return obj;
85           else
86             vec.push_back(obj->getName());
87         }
88     }
89   std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
90   std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
91   throw INTERP_KERNEL::Exception(oss.str().c_str());
92 }
93
94 void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
95 {
96   if(!fine || !coarse)
97     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
98   std::size_t sz(coarse->_arrs.size());
99   if(fine->_arrs.size()!=sz)
100     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
101   for(std::size_t i=0;i<sz;i++)
102     fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i],coarse->_arrs[i],ghostLev);
103 }
104
105 void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
106 {
107   if(!fine || !coarse)
108     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
109   std::size_t sz(coarse->_arrs.size());
110   if(fine->_arrs.size()!=sz)
111     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
112   for(std::size_t i=0;i<sz;i++)
113     fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i],fine->_arrs[i],ghostLev);
114 }
115
116 void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
117 {
118   if(!fatherOfFineMesh)
119     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
120   std::size_t sz(children.size());
121   if(fieldsOnFine.size()!=sz)
122     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
123   if(sz<=1)
124     return ;
125   std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
126   for(std::size_t i=0;i<sz;i++)
127     if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
128       throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
129   for(std::size_t i=1;i<sz;i++)
130     if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
131       throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
132   for(std::size_t i=0;i<nbOfCall;i++)
133     {
134       std::vector<const DataArrayDouble *> arrs(sz);
135       for(std::size_t j=0;j<sz;j++)
136         arrs[j]=fieldsOnFine[j]->_arrs[i];
137       fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
138     }
139 }
140
141 /*!
142  * 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).
143  */
144 void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac)
145 {
146   if(!p1 || !p1dac || !p2 || !p2dac)
147     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !");
148   std::size_t sz(p1dac->_arrs.size());
149   if(p2dac->_arrs.size()!=sz)
150     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !");
151   for(std::size_t i=0;i<sz;i++)
152     {
153       const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i]);
154       MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i]);
155     }
156 }
157
158 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
159 {
160   if(!fine || !coarse)
161     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
162   std::size_t sz(coarse->_arrs.size());
163   if(fine->_arrs.size()!=sz)
164     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
165   for(std::size_t i=0;i<sz;i++)
166     fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i],fine->_arrs[i],ghostLev);
167 }
168
169 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
170 {
171   DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
172   std::size_t sz(_arrs.size());
173   if(other._arrs.size()!=sz)
174     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
175   for(std::size_t i=0;i<sz;i++)
176     father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i],other._arrs[i]);
177 }
178
179 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
180 {
181   DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
182   std::size_t sz(_arrs.size());
183   if(other._arrs.size()!=sz)
184     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
185   for(std::size_t i=0;i<sz;i++)
186     MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i],other._arrs[i]);
187 }
188
189 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
190 {
191   std::size_t sz(fieldNames.size());
192   std::vector<std::string> names(sz);
193   for(std::size_t i=0;i<sz;i++)
194     {
195       const std::pair<std::string,int>& info(fieldNames[i]);
196       _arrs[i]=DataArrayDouble::New();
197       _arrs[i]->alloc(0,info.second);
198       _arrs[i]->setName(info.first);
199       names[i]=info.second;
200     }
201   CheckDiscriminantNames(names);
202 }
203
204 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
205 {
206   std::size_t ret(sizeof(DataArrayDoubleCollection));
207   ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
208   return ret;
209 }
210
211 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
212 {
213   std::vector<const BigMemoryObject *> ret;
214   for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
215     {
216       const DataArrayDouble *pt(*it);
217       if(pt)
218         ret.push_back(pt);
219     }
220   return ret;
221 }
222
223 void DataArrayDoubleCollection::updateTime() const
224 {
225   for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
226     {
227       const DataArrayDouble *pt(*it);
228       if(pt)
229         updateTimeWith(*pt);
230     }
231 }
232
233 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
234 {
235   std::set<std::string> s(names.begin(),names.end());
236   if(s.size()!=names.size())
237     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
238 }
239
240 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
241 {
242   return new MEDCouplingGridCollection(ms,fieldNames);
243 }
244
245 void MEDCouplingGridCollection::alloc(int ghostLev)
246 {
247   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
248     {
249       int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
250       DataArrayDoubleCollection *dadc((*it).second);
251       if(dadc)
252         dadc->allocTuples(nbTuples);
253       else
254         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
255     }
256 }
257
258 void MEDCouplingGridCollection::dealloc()
259 {
260   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
261     {
262       DataArrayDoubleCollection *dadc((*it).second);
263       if(dadc)
264         dadc->dellocTuples();
265       else
266         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
267     }
268 }
269
270 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
271 {
272   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
273     (*it).second->spillInfoOnComponents(compNames);
274 }
275
276 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
277 {
278   int ret(0);
279   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
280     {
281       if((*it).first==m)
282         {
283           pos=ret;
284           return true;
285         }
286     }
287   return false;
288 }
289
290 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
291 {
292   if(pos<0 || pos>(int)_map_of_dadc.size())
293     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
294   return *_map_of_dadc[pos].second;
295 }
296
297 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
298 {
299   if(!fine || !coarse)
300     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
301   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
302   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
303   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
304     {
305       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
306       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
307       bool found(false);
308       for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
309         {
310           if((*it0).first==fatherOfFineMesh)
311             {
312               found=true;
313               int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
314               const DataArrayDoubleCollection *coarseDaCol((*it0).second);
315               DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
316               DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
317             }
318         }
319       if(!found)
320         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
321     }
322 }
323
324 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
325 {
326   if(!fine || !coarse)
327     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
328   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
329   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
330   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
331     {
332       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
333       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
334       bool found(false);
335       for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
336         {
337           if((*it0).first==fatherOfFineMesh)
338             {
339               found=true;
340               int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
341               const DataArrayDoubleCollection *fineDaCol((*it).second);
342               DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
343               DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
344             }
345         }
346       if(!found)
347         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
348     }
349 }
350
351 /*!
352  * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
353  *
354  * \sa synchronizeFineEachOtherExt
355  */
356 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
357 {
358   for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
359     {
360       int p1,p2;
361       if(!presenceOf((*it).first->getMesh(),p1))
362         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
363       if(!presenceOf((*it).second->getMesh(),p2))
364         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
365       const DataArrayDoubleCollection& col1(getFieldsAt(p1));
366       const DataArrayDoubleCollection& col2(getFieldsAt(p2));
367       col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
368     }
369 }
370
371 /*!
372  * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
373  *
374  * \sa synchronizeFineEachOther
375  */
376 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
377 {
378   for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
379     {
380       int p1,p2;
381       if(!presenceOf((*it).first->getMesh(),p1))
382         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
383       if(!presenceOf((*it).second->getMesh(),p2))
384         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
385       const DataArrayDoubleCollection& col1(getFieldsAt(p1));
386       const DataArrayDoubleCollection& col2(getFieldsAt(p2));
387       col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
388     }
389 }
390
391 /*!
392  * The pairs returned share the same direct father. The number of returned elements must be even.
393  */
394 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
395 {
396   std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
397   std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
398   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
399     {
400       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
401       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
402       m[fatherOfFineMesh].push_back(fineMesh);
403     }
404   for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
405     {
406       for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
407         {
408           int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
409           std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
410           const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
411           for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
412             {
413               const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
414               ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
415             }
416         }
417     }
418   if(ret.size()%2!=0)
419     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
420   return ret;
421 }
422
423 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
424 {
425   if(!fine || !coarse)
426     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
427   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
428   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
429   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
430     {
431       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
432       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
433       bool found(false);
434       for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
435         {
436           if((*it0).first==fatherOfFineMesh)
437             {
438               found=true;
439               int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
440               const DataArrayDoubleCollection *fineDaCol((*it).second);
441               DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
442               DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
443             }
444         }
445       if(!found)
446         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
447     }
448 }
449
450 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
451 {
452   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
453     {
454       const MEDCouplingCartesianAMRMeshGen *a((*it).first);
455       if(head==a || head->isObjectInTheProgeny(a))
456         {
457           const DataArrayDoubleCollection *gc((*it).second);
458           recurseArrs.push_back(gc->getFieldWithName(fieldName));
459         }
460     }
461 }
462
463 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
464 {
465   std::size_t sz(ms.size());
466   for(std::size_t i=0;i<sz;i++)
467     {
468       if(!ms[i])
469         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
470       _map_of_dadc[i].first=ms[i];
471       _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
472     }
473 }
474
475 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
476 {
477   std::size_t ret(sizeof(MEDCouplingGridCollection));
478   ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
479   return ret;
480 }
481
482 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
483 {
484   std::vector<const BigMemoryObject *> ret;
485   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
486     {
487       const DataArrayDoubleCollection *col((*it).second);
488       if(col)
489         ret.push_back(col);
490     }
491   return ret;
492 }
493
494 void MEDCouplingGridCollection::updateTime() const
495 {
496   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
497     {
498       const MEDCouplingCartesianAMRMeshGen *a((*it).first);
499       if(a)
500         updateTimeWith(*a);
501       const DataArrayDoubleCollection *b((*it).second);
502       if(b)
503         updateTimeWith(*b);
504     }
505 }
506
507 /*!
508  * 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.
509  */
510 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
511 {
512   return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
513 }
514
515 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
516 {
517   std::size_t sz(fieldNames.size());
518   std::vector< std::pair<std::string,int> > fieldNames2(sz);
519   std::vector< std::vector<std::string> > compNames(sz);
520   for(std::size_t i=0;i<sz;i++)
521     {
522       fieldNames2[i].first=fieldNames[i].first;
523       fieldNames2[i].second=(int)fieldNames[i].second.size();
524       compNames[i]=fieldNames[i].second;
525     }
526   MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
527   ret->spillInfoOnComponents(compNames);
528   return ret.retn();
529 }
530
531 /*!
532  * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
533  * 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.
534  * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
535  * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
536  */
537 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
538 {
539   _tlc.checkConst();
540   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
541     (*it)->spillInfoOnComponents(compNames);
542 }
543
544 /*!
545  * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
546  * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
547  *
548  * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
549  * \sa retrieveFieldOn
550  */
551 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
552 {
553   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
554     {
555       int tmp(-1);
556       if((*it)->presenceOf(mesh,tmp))
557         {
558           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
559           return ddc.retrieveFields();
560         }
561     }
562   throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
563 }
564
565 /*!
566  * \sa retrieveFieldsOn
567  */
568 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
569 {
570   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
571     {
572       int tmp(-1);
573       if((*it)->presenceOf(mesh,tmp))
574         {
575           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
576           return ddc.getFieldWithName(fieldName);
577         }
578     }
579   throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldOn : the mesh specified is not in the progeny of this !");
580 }
581
582 /*!
583  * This method returns a field on an unstructured mesh the most refined as possible without overlap.
584  * Ghost part are not visible here.
585  *
586  * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
587  */
588 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
589 {
590   std::vector<const DataArrayDouble *> recurseArrs;
591   std::size_t lev(0);
592   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
593     {
594       int tmp(-1);
595       if((*it)->presenceOf(mesh,tmp))
596         {
597           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
598           recurseArrs.push_back(ddc.getFieldWithName(fieldName));
599           break;
600         }
601     }
602   lev++;
603   for(std::size_t i=lev;i<_levs.size();i++)
604     {
605       const MEDCouplingGridCollection *gc(_levs[i]);
606       gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
607     }
608   return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
609 }
610
611 /*!
612  * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
613  * The output field also displays ghost cells.
614  *
615  * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
616  *
617  */
618 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
619 {
620   const DataArrayDouble *arr(0);
621   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
622     {
623       int tmp(-1);
624       if((*it)->presenceOf(mesh,tmp))
625         {
626           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
627           arr=ddc.getFieldWithName(fieldName);
628         }
629     }
630   if(!arr)
631     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
632   MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
633   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
634   ret->setMesh(im);
635   ret->setArray(const_cast<DataArrayDouble *>(arr));
636   ret->setName(arr->getName());
637   return ret.retn();
638 }
639
640 /*!
641  * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
642  * MEDCouplingAMRAttribute::alloc method.
643  */
644 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
645 {
646   if(_levs.empty())
647     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
648   std::size_t sz(_levs.size());
649   //
650   while(sz>1)
651     {
652       sz--;
653       const MEDCouplingGridCollection *fine(_levs[sz]),*coarse(_levs[sz-1]);
654       MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
655     }
656 }
657
658 /*!
659  * 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
660  * MEDCouplingAMRAttribute::alloc method.
661  */
662 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
663 {
664   if(_levs.empty())
665     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
666   std::size_t sz(_levs.size());
667   //
668   for(std::size_t i=1;i<sz;i++)
669     {
670       const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
671       MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);
672     }
673 }
674
675 /*!
676  * This method performs coarse to fine spread only in the ghost zone.
677  * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
678  * So if \a _ghost_lev == 0 this method has no effect.
679  */
680 void MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone()
681 {
682   if(_levs.empty())
683     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone : not any levels in this !");
684   std::size_t sz(_levs.size());
685   //
686   for(std::size_t i=1;i<sz;i++)
687     {
688       const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
689       MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
690     }
691 }
692
693 /*!
694  * This method synchronizes fine each other only in the ghost zone.
695  */
696 void MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone()
697 {
698   if(_levs.empty())
699     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
700   std::size_t sz(_levs.size());
701   // 1st - classical direct sublevel inside common patch
702   for(std::size_t i=1;i<sz;i++)
703     {
704       const MEDCouplingGridCollection *fine(_levs[i]);
705       if(!fine)
706         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
707       fine->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
708     }
709   // 2nd - mixed level
710   for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
711     {
712       const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
713       DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
714     }
715   // 3td - same level but with far ancestor.
716   for(std::size_t i=1;i<sz;i++)
717     {
718       const MEDCouplingGridCollection *fine(_levs[i]);
719       fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
720     }
721 }
722
723 /*!
724  * This method allocates all DataArrayDouble instances stored recursively in \a this.
725  *
726  * \sa dealloc
727  */
728 void MEDCouplingAMRAttribute::alloc()
729 {
730   _tlc.resetState();
731   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
732     {
733       MEDCouplingGridCollection *elt(*it);
734       if(elt)
735         elt->alloc(_ghost_lev);
736       else
737         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
738     }
739 }
740
741 /*!
742  * This method deallocates all DataArrayDouble instances stored recursively in \a this.
743  * \sa alloc
744  */
745 void MEDCouplingAMRAttribute::dealloc()
746 {
747   _tlc.checkConst();
748   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
749     {
750       MEDCouplingGridCollection *elt(*it);
751       if(elt)
752         elt->dealloc();
753       else
754         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
755     }
756 }
757
758 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
759 {
760   bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
761   return ret;
762 }
763
764 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
765 {
766   std::size_t ret(sizeof(MEDCouplingAMRAttribute));
767   ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
768   return ret;
769 }
770
771 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
772 {
773   std::vector<const BigMemoryObject *> ret;
774   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
775     {
776       const MEDCouplingGridCollection *elt(*it);
777       if(elt)
778         ret.push_back(elt);
779     }
780   return ret;
781 }
782
783 void MEDCouplingAMRAttribute::updateTime() const
784 {//tony
785 }
786
787 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
788 {
789   //gf non empty, checked by constructor
790   int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
791   _levs.resize(maxLev);
792   for(int i=0;i<maxLev;i++)
793     {
794       std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
795       std::size_t sz(patches.size());
796       std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
797       for(std::size_t j=0;j<sz;j++)
798         patchesSafe[j]=patches[j];
799       std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
800       for(std::size_t j=0;j<sz;j++)
801         {
802           ms[j]=patches[j]->getMesh();
803         }
804       _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
805     }
806   // updates cross levels neighbors
807   _neighbors.resize(_levs.size());
808   _cross_lev_neighbors.resize(_levs.size());
809   if(_levs.empty())
810     throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
811   std::size_t sz(_levs.size());
812   for(std::size_t i=1;i<sz;i++)
813     {
814       const MEDCouplingGridCollection *fine(_levs[i]);
815       if(!fine)
816         throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
817       _neighbors[i]=fine->findNeighbors(_ghost_lev);
818       if(i!=sz-1)
819         {
820           for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
821             {
822               MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
823               std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
824               std::size_t fullLev(i+neighs2.size());
825               if(fullLev>=sz)
826                 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
827               std::size_t ii(i+1);
828               for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
829                 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
830             }
831         }
832     }
833 }
834
835 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
836 {
837   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
838     {
839       const MEDCouplingGridCollection *elt(*it);
840       if(elt)
841         {
842           int tmp(-1);
843           if(elt->presenceOf(m,tmp))
844             {
845               return elt->getFieldsAt(tmp);
846             }
847         }
848     }
849   throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
850 }