Salome HOME
Attributes for AMR cartesian mesh developped. Ready to test.
[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 "MEDCouplingMemArray.hxx"
23
24 #include <sstream>
25
26 using namespace ParaMEDMEM;
27
28 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
29 {
30   return new DataArrayDoubleCollection(fieldNames);
31 }
32
33 void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
34 {
35   std::size_t sz(_arrs.size());
36   for(std::size_t i=0;i<sz;i++)
37     _arrs[i]->reAlloc(nbOfTuples);
38 }
39
40 void DataArrayDoubleCollection::dellocTuples()
41 {
42   std::size_t sz(_arrs.size());
43   for(std::size_t i=0;i<sz;i++)
44     _arrs[i]->reAlloc(0);
45 }
46
47 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
48 {
49   std::size_t sz(_arrs.size());
50   if(sz!=compNames.size())
51     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
52   for(std::size_t i=0;i<sz;i++)
53     {
54       const std::vector<std::string>& names(compNames[i]);
55       _arrs[i]->setInfoOnComponents(names);
56     }
57 }
58
59 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
60 {
61   std::size_t sz(_arrs.size());
62   std::vector<DataArrayDouble *> ret(sz);
63   for(std::size_t i=0;i<sz;i++)
64     {
65       const DataArrayDouble *tmp(_arrs[i]);
66       ret[i]=const_cast<DataArrayDouble *>(tmp);
67       if(ret[i])
68         ret[i]->incrRef();
69     }
70   return ret;
71 }
72
73 DataArrayDouble *DataArrayDoubleCollection::retrieveFieldWithName(const std::string& name) const
74 {
75   std::vector<std::string> vec;
76   for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
77     {
78       const DataArrayDouble *obj(*it);
79       if(obj)
80         {
81           if(obj->getName()==name)
82             {
83               DataArrayDouble *ret(const_cast<DataArrayDouble *>(obj));
84               if(ret)
85                 ret->incrRef();
86               return ret;
87             }
88           else
89             {
90               vec.push_back(obj->getName());
91             }
92         }
93     }
94   std::ostringstream oss; oss << "DataArrayDoubleCollection::retrieveFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
95   std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
96   throw INTERP_KERNEL::Exception(oss.str().c_str());
97 }
98
99 void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
100 {
101   if(!fine || !coarse)
102     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
103   std::size_t sz(coarse->_arrs.size());
104   if(fine->_arrs.size()!=sz)
105     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
106   for(std::size_t i=0;i<sz;i++)
107     fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i],coarse->_arrs[i],ghostLev);
108 }
109
110 void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
111 {
112   if(!fine || !coarse)
113     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
114   std::size_t sz(coarse->_arrs.size());
115   if(fine->_arrs.size()!=sz)
116     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
117   for(std::size_t i=0;i<sz;i++)
118     fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i],fine->_arrs[i],ghostLev);
119 }
120
121 void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
122 {
123   if(!fatherOfFineMesh)
124     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
125   std::size_t sz(children.size());
126   if(fieldsOnFine.size()!=sz)
127     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
128   if(sz<=1)
129     return ;
130   std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
131   for(std::size_t i=0;i<sz;i++)
132     if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
133       throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
134   for(std::size_t i=1;i<sz;i++)
135     if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
136       throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
137   for(std::size_t i=0;i<nbOfCall;i++)
138     {
139       std::vector<const DataArrayDouble *> arrs(sz);
140       for(std::size_t j=0;j<sz;j++)
141         arrs[j]=fieldsOnFine[j]->_arrs[i];
142       fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
143     }
144 }
145
146 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
147 {
148   if(!fine || !coarse)
149     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
150   std::size_t sz(coarse->_arrs.size());
151   if(fine->_arrs.size()!=sz)
152     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
153   for(std::size_t i=0;i<sz;i++)
154     fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i],fine->_arrs[i],ghostLev);
155 }
156
157 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
158 {
159   std::size_t sz(fieldNames.size());
160   std::vector<std::string> names(sz);
161   for(std::size_t i=0;i<sz;i++)
162     {
163       const std::pair<std::string,int>& info(fieldNames[i]);
164       _arrs[i]=DataArrayDouble::New();
165       _arrs[i]->alloc(0,info.second);
166       _arrs[i]->setName(info.first);
167       names[i]=info.second;
168     }
169   CheckDiscriminantNames(names);
170 }
171
172 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
173 {
174   std::size_t ret(sizeof(DataArrayDoubleCollection));
175   ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
176   return ret;
177 }
178
179 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
180 {
181   std::vector<const BigMemoryObject *> ret;
182   for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
183     {
184       const DataArrayDouble *pt(*it);
185       if(pt)
186         ret.push_back(pt);
187     }
188   return ret;
189 }
190
191 void DataArrayDoubleCollection::updateTime() const
192 {
193   for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
194     {
195       const DataArrayDouble *pt(*it);
196       if(pt)
197         updateTimeWith(*pt);
198     }
199 }
200
201 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
202 {
203   std::set<std::string> s(names.begin(),names.end());
204   if(s.size()!=names.size())
205     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
206 }
207
208 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
209 {
210   return new MEDCouplingGridCollection(ms,fieldNames);
211 }
212
213 void MEDCouplingGridCollection::alloc(int ghostLev)
214 {
215   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
216     {
217       int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
218       DataArrayDoubleCollection *dadc((*it).second);
219       if(dadc)
220         dadc->allocTuples(nbTuples);
221       else
222         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
223     }
224 }
225
226 void MEDCouplingGridCollection::dealloc()
227 {
228   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
229     {
230       DataArrayDoubleCollection *dadc((*it).second);
231       if(dadc)
232         dadc->dellocTuples();
233       else
234         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
235     }
236 }
237
238 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
239 {
240   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
241     (*it).second->spillInfoOnComponents(compNames);
242 }
243
244 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
245 {
246   int ret(0);
247   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
248     {
249       if((*it).first==m)
250         {
251           pos=ret;
252           return true;
253         }
254     }
255   return false;
256 }
257
258 const DataArrayDoubleCollection& MEDCouplingGridCollection::retrieveFieldsAt(int pos) const
259 {
260   if(pos<0 || pos>(int)_map_of_dadc.size())
261     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::retrieveFieldsAt : invalid pos given in input ! Must be in [0,size) !");
262   return *_map_of_dadc[pos].second;
263 }
264
265 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
266 {
267   if(!fine || !coarse)
268     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
269   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
270   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
271   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
272     {
273       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
274       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
275       bool found(false);
276       for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
277         {
278           if((*it0).first==fatherOfFineMesh)
279             {
280               found=true;
281               int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
282               const DataArrayDoubleCollection *coarseDaCol((*it0).second);
283               DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
284               DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
285             }
286         }
287       if(!found)
288         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
289     }
290 }
291
292 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
293 {
294   if(!fine || !coarse)
295     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
296   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
297   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
298   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
299     {
300       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
301       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
302       bool found(false);
303       for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
304         {
305           if((*it0).first==fatherOfFineMesh)
306             {
307               found=true;
308               int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
309               const DataArrayDoubleCollection *fineDaCol((*it).second);
310               DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
311               DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
312             }
313         }
314       if(!found)
315         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
316     }
317 }
318
319 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev) const
320 {
321   std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> > > m;
322   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
323     {
324       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
325       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
326       m[fatherOfFineMesh].push_back(std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *>(fineMesh,(*it).second));
327     }
328   for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector<std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> > >::const_iterator it0=m.begin();it0!=m.end();it0++)
329     {
330       std::size_t sz((*it0).second.size());
331       std::vector<const MEDCouplingCartesianAMRMeshGen *> v0(sz);
332       std::vector<DataArrayDoubleCollection *> v1(sz);
333       for(std::size_t i=0;i<sz;i++)
334         {
335           v0[i]=(*it0).second[i].first;
336           const DataArrayDoubleCollection *tmp((*it0).second[i].second);
337           v1[i]=const_cast<DataArrayDoubleCollection *>(tmp);
338         }
339       for(std::vector<std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> >::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
340         {
341           int patchId((*it0).first->getPatchIdFromChildMesh((*it1).first));
342           DataArrayDoubleCollection::SynchronizeFineEachOther(patchId,ghostLev,(*it0).first,v0,v1);
343         }
344     }
345 }
346
347 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
348 {
349   if(!fine || !coarse)
350     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
351   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
352   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
353   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
354     {
355       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
356       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
357       bool found(false);
358       for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
359         {
360           if((*it0).first==fatherOfFineMesh)
361             {
362               found=true;
363               int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
364               const DataArrayDoubleCollection *fineDaCol((*it).second);
365               DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
366               DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
367             }
368         }
369       if(!found)
370         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
371     }
372 }
373
374 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
375 {
376   std::size_t sz(ms.size());
377   for(std::size_t i=0;i<sz;i++)
378     {
379       if(!ms[i])
380         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
381       _map_of_dadc[i].first=ms[i];
382       _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
383     }
384 }
385
386 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
387 {
388   std::size_t ret(sizeof(MEDCouplingGridCollection));
389   ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
390   return ret;
391 }
392
393 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
394 {
395   std::vector<const BigMemoryObject *> ret;
396   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
397     {
398       const DataArrayDoubleCollection *col((*it).second);
399       if(col)
400         ret.push_back(col);
401     }
402   return ret;
403 }
404
405 void MEDCouplingGridCollection::updateTime() const
406 {
407   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
408     {
409       const MEDCouplingCartesianAMRMeshGen *a((*it).first);
410       if(a)
411         updateTimeWith(*a);
412       const DataArrayDoubleCollection *b((*it).second);
413       if(b)
414         updateTimeWith(*b);
415     }
416 }
417
418 /*!
419  * 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.
420  */
421 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames)
422 {
423   return new MEDCouplingAMRAttribute(gf,fieldNames);
424 }
425
426 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames)
427 {
428   std::size_t sz(fieldNames.size());
429   std::vector< std::pair<std::string,int> > fieldNames2(sz);
430   std::vector< std::vector<std::string> > compNames(sz);
431   for(std::size_t i=0;i<sz;i++)
432     {
433       fieldNames2[i].first=fieldNames[i].first;
434       fieldNames2[i].second=(int)fieldNames[i].second.size();
435       compNames[i]=fieldNames[i].second;
436     }
437   MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2));
438   ret->spillInfoOnComponents(compNames);
439   return ret.retn();
440 }
441
442 /*!
443  * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
444  * 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.
445  * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
446  * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
447  */
448 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
449 {
450   _tlc.checkConst();
451   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
452     (*it)->spillInfoOnComponents(compNames);
453 }
454
455 /*!
456  * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
457  * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
458  *
459  * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
460  * \sa retrieveFieldOn
461  */
462 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
463 {
464   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
465     {
466       int tmp(-1);
467       if((*it)->presenceOf(mesh,tmp))
468         {
469           const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
470           return ddc.retrieveFields();
471         }
472     }
473   throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
474 }
475
476 /*!
477  * \sa retrieveFieldsOn
478  */
479 DataArrayDouble *MEDCouplingAMRAttribute::retrieveFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
480 {
481   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
482       {
483         int tmp(-1);
484         if((*it)->presenceOf(mesh,tmp))
485           {
486             const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
487             return ddc.retrieveFieldWithName(fieldName);
488           }
489       }
490     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldOn : the mesh specified is not in the progeny of this !");
491 }
492
493 /*!
494  * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
495  * MEDCouplingAMRAttribute::alloc method.
496  */
497 void MEDCouplingAMRAttribute::synchronizeFineToCoarse(int ghostLev)
498 {
499   if(_levs.empty())
500     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
501   std::size_t sz(_levs.size());
502   //
503   while(sz>1)
504     {
505       sz--;
506       const MEDCouplingGridCollection *fine(_levs[sz]),*coarse(_levs[sz-1]);
507       MEDCouplingGridCollection::SynchronizeFineToCoarse(ghostLev,fine,coarse);
508     }
509 }
510
511 /*!
512  * This method synchronizes from coarse to fine arrays and fine to fine each other (if ghostLev is >0). This method makes the hypothesis that \a this has been allocated before using
513  * MEDCouplingAMRAttribute::alloc method.
514  */
515 void MEDCouplingAMRAttribute::synchronizeCoarseToFine(int ghostLev)
516 {
517   if(_levs.empty())
518     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
519   std::size_t sz(_levs.size());
520   //
521   for(std::size_t i=1;i<sz;i++)
522     {
523       const MEDCouplingGridCollection *fine(_levs[sz]),*coarse(_levs[sz-1]);
524       MEDCouplingGridCollection::SynchronizeCoarseToFine(ghostLev,coarse,fine);
525     }
526 }
527
528 /*!
529  * This method performs coarse to fine spread only in the ghost zone.
530  * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
531  * So if \a ghostLev == 0 this method has no effect.
532  */
533 void MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone(int ghostLev)
534 {
535   if(_levs.empty())
536     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone : not any levels in this !");
537   std::size_t sz(_levs.size());
538   //
539   for(std::size_t i=1;i<sz;i++)
540     {
541       const MEDCouplingGridCollection *fine(_levs[sz]),*coarse(_levs[sz-1]);
542       MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,coarse,fine);
543     }
544 }
545
546 /*!
547  * This method synchronizes fine each other only in the ghost zone.
548  */
549 void MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone(int ghostLev)
550 {
551   if(_levs.empty())
552     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
553   std::size_t sz(_levs.size());
554   //
555   for(std::size_t i=1;i<sz;i++)
556     {
557       const MEDCouplingGridCollection *fine(_levs[sz]);
558       if(!fine)
559         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
560       fine->synchronizeFineEachOther(ghostLev);
561     }
562 }
563
564 /*!
565  * This method allocates all DataArrayDouble instances stored recursively in \a this.
566  *
567  * \param [in] ghostLev - The size of ghost zone.
568  *
569  * \sa dealloc
570  */
571 void MEDCouplingAMRAttribute::alloc(int ghostLev)
572 {
573   _tlc.resetState();
574   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
575     {
576       MEDCouplingGridCollection *elt(*it);
577       if(elt)
578         elt->alloc(ghostLev);
579       else
580         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
581     }
582 }
583
584 /*!
585  * This method deallocates all DataArrayDouble instances stored recursively in \a this.
586  * \sa alloc
587  */
588 void MEDCouplingAMRAttribute::dealloc()
589 {
590   _tlc.checkConst();
591   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
592     {
593       MEDCouplingGridCollection *elt(*it);
594       if(elt)
595         elt->dealloc();
596       else
597         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
598     }
599 }
600
601 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
602 {
603   bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
604   return ret;
605 }
606
607 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
608 {
609   std::size_t ret(sizeof(MEDCouplingAMRAttribute));
610   ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
611   return ret;
612 }
613
614 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
615 {
616   std::vector<const BigMemoryObject *> ret;
617   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
618     {
619       const MEDCouplingGridCollection *elt(*it);
620       if(elt)
621         ret.push_back(elt);
622     }
623   return ret;
624 }
625
626 void MEDCouplingAMRAttribute::updateTime() const
627 {//tony
628 }
629
630 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames):MEDCouplingDataForGodFather(gf)
631 {
632   //gf non empty, checked by constructor
633   int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()+1);
634   _levs.resize(maxLev+1);
635   for(int i=0;i<maxLev;i++)
636     {
637       std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
638       std::size_t sz(patches.size());
639       std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
640       for(std::size_t j=0;j<sz;j++)
641         patchesSafe[j]=patches[j];
642       std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
643       for(std::size_t j=0;j<sz;j++)
644         {
645           ms[j]=patches[j]->getMesh();
646         }
647       _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
648     }
649 }