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