Salome HOME
interlevels methods.
[modules/med.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 DataArrayDoubleCollection *DataArrayDoubleCollection::deepCpy() const
36 {
37   return new DataArrayDoubleCollection(*this);
38 }
39
40 void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
41 {
42   std::size_t sz(_arrs.size());
43   for(std::size_t i=0;i<sz;i++)
44     _arrs[i].first->reAlloc(nbOfTuples);
45 }
46
47 void DataArrayDoubleCollection::dellocTuples()
48 {
49   std::size_t sz(_arrs.size());
50   for(std::size_t i=0;i<sz;i++)
51     _arrs[i].first->reAlloc(0);
52 }
53
54 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
55 {
56   std::size_t sz(_arrs.size());
57   if(sz!=compNames.size())
58     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
59   for(std::size_t i=0;i<sz;i++)
60     {
61       const std::vector<std::string>& names(compNames[i]);
62       _arrs[i].first->setInfoOnComponents(names);
63     }
64 }
65
66 void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& nfs)
67 {
68   std::size_t sz(_arrs.size());
69   if(sz!=nfs.size())
70     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !");
71   for(std::size_t i=0;i<sz;i++)
72     {
73       CheckValidNature(nfs[i]);
74       _arrs[i].second=nfs[i];
75     }
76 }
77
78 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
79 {
80   std::size_t sz(_arrs.size());
81   std::vector<DataArrayDouble *> ret(sz);
82   for(std::size_t i=0;i<sz;i++)
83     {
84       const DataArrayDouble *tmp(_arrs[i].first);
85       ret[i]=const_cast<DataArrayDouble *>(tmp);
86       if(ret[i])
87         ret[i]->incrRef();
88     }
89   return ret;
90 }
91
92 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
93 {
94   std::vector<std::string> vec;
95   for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
96     {
97       const DataArrayDouble *obj((*it).first);
98       if(obj)
99         {
100           if(obj->getName()==name)
101             return obj;
102           else
103             vec.push_back(obj->getName());
104         }
105     }
106   std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
107   std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
108   throw INTERP_KERNEL::Exception(oss.str().c_str());
109 }
110
111 void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
112 {
113   if(!fine || !coarse)
114     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
115   std::size_t sz(coarse->_arrs.size());
116   if(fine->_arrs.size()!=sz)
117     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
118   for(std::size_t i=0;i<sz;i++)
119     {
120       CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
121       fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
122     }
123 }
124
125 void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
126 {
127   if(!fine || !coarse)
128     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
129   std::size_t sz(coarse->_arrs.size());
130   if(fine->_arrs.size()!=sz)
131     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
132   for(std::size_t i=0;i<sz;i++)
133     {
134       CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
135       fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
136     }
137 }
138
139 void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
140 {
141   if(!fatherOfFineMesh)
142     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
143   std::size_t sz(children.size());
144   if(fieldsOnFine.size()!=sz)
145     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
146   if(sz<=1)
147     return ;
148   std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
149   for(std::size_t i=0;i<sz;i++)
150     if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
151       throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
152   for(std::size_t i=1;i<sz;i++)
153     if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
154       throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
155   for(std::size_t i=0;i<nbOfCall;i++)
156     {
157       std::vector<const DataArrayDouble *> arrs(sz);
158       for(std::size_t j=0;j<sz;j++)
159         arrs[j]=fieldsOnFine[j]->_arrs[i].first;
160       fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
161     }
162 }
163
164 /*!
165  * This method updates \a p1dac ghost zone parts using \a p2dac (which is really const). \a p2 is in the neighborhood of \a p1 (which size is defined by \a ghostLev).
166  */
167 void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac)
168 {
169   if(!p1 || !p1dac || !p2 || !p2dac)
170     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !");
171   std::size_t sz(p1dac->_arrs.size());
172   if(p2dac->_arrs.size()!=sz)
173     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !");
174   for(std::size_t i=0;i<sz;i++)
175     {
176       const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first);
177       MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first);
178     }
179 }
180
181 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
182 {
183   if(!fine || !coarse)
184     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
185   std::size_t sz(coarse->_arrs.size());
186   if(fine->_arrs.size()!=sz)
187     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
188   for(std::size_t i=0;i<sz;i++)
189     fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev);
190 }
191
192 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
193 {
194   DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
195   std::size_t sz(_arrs.size());
196   if(other._arrs.size()!=sz)
197     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
198   for(std::size_t i=0;i<sz;i++)
199     father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
200 }
201
202 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
203 {
204   DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
205   std::size_t sz(_arrs.size());
206   if(other._arrs.size()!=sz)
207     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
208   for(std::size_t i=0;i<sz;i++)
209     MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
210 }
211
212 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
213 {
214   std::size_t sz(fieldNames.size());
215   std::vector<std::string> names(sz);
216   for(std::size_t i=0;i<sz;i++)
217     {
218       const std::pair<std::string,int>& info(fieldNames[i]);
219       _arrs[i].first=DataArrayDouble::New();
220       _arrs[i].first->alloc(0,info.second);
221       _arrs[i].first->setName(info.first);
222       names[i]=info.second;
223       _arrs[i].second=ConservativeVolumic;
224     }
225   CheckDiscriminantNames(names);
226 }
227
228 DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size())
229 {
230   std::size_t sz(other._arrs.size());
231   for(std::size_t i=0;i<sz;i++)
232     {
233       _arrs[i].second=other._arrs[i].second;
234       const DataArrayDouble *da(other._arrs[i].first);
235       if(da)
236         _arrs[i].first=da->deepCpy();
237     }
238 }
239
240 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
241 {
242   std::size_t ret(sizeof(DataArrayDoubleCollection));
243   ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
244   return ret;
245 }
246
247 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
248 {
249   std::vector<const BigMemoryObject *> ret;
250   for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
251     {
252       const DataArrayDouble *pt((*it).first);
253       if(pt)
254         ret.push_back(pt);
255     }
256   return ret;
257 }
258
259 void DataArrayDoubleCollection::updateTime() const
260 {
261   for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
262     {
263       const DataArrayDouble *pt((*it).first);
264       if(pt)
265         updateTimeWith(*pt);
266     }
267 }
268
269 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
270 {
271   std::set<std::string> s(names.begin(),names.end());
272   if(s.size()!=names.size())
273     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
274 }
275
276 bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
277 {
278   CheckValidNature(n);
279   return n==RevIntegral || n==IntegralGlobConstraint;
280 }
281
282 void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
283 {
284   CheckValidNature(n1);
285   CheckValidNature(n2);
286   if(n1!=n2)
287     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
288 }
289
290 void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
291 {
292   if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral)
293     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
294 }
295
296 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
297 {
298   return new MEDCouplingGridCollection(ms,fieldNames);
299 }
300
301 MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy() const
302 {
303   return new MEDCouplingGridCollection(*this);
304 }
305
306 void MEDCouplingGridCollection::alloc(int ghostLev)
307 {
308   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
309     {
310       int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
311       DataArrayDoubleCollection *dadc((*it).second);
312       if(dadc)
313         dadc->allocTuples(nbTuples);
314       else
315         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
316     }
317 }
318
319 void MEDCouplingGridCollection::dealloc()
320 {
321   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
322     {
323       DataArrayDoubleCollection *dadc((*it).second);
324       if(dadc)
325         dadc->dellocTuples();
326       else
327         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
328     }
329 }
330
331 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
332 {
333   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
334     (*it).second->spillInfoOnComponents(compNames);
335 }
336
337 void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
338 {
339   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
340     (*it).second->spillNatures(nfs);
341 }
342
343 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
344 {
345   int ret(0);
346   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
347     {
348       if((*it).first==m)
349         {
350           pos=ret;
351           return true;
352         }
353     }
354   return false;
355 }
356
357 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
358 {
359   if(pos<0 || pos>(int)_map_of_dadc.size())
360     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
361   return *_map_of_dadc[pos].second;
362 }
363
364 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
365 {
366   if(!fine || !coarse)
367     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
368   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
369   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
370   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
371     {
372       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
373       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
374       bool found(false);
375       for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
376         {
377           if((*it0).first==fatherOfFineMesh)
378             {
379               found=true;
380               int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
381               const DataArrayDoubleCollection *coarseDaCol((*it0).second);
382               DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
383               DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
384             }
385         }
386       if(!found)
387         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
388     }
389 }
390
391 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
392 {
393   if(!fine || !coarse)
394     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
395   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
396   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
397   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
398     {
399       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
400       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
401       bool found(false);
402       for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
403         {
404           if((*it0).first==fatherOfFineMesh)
405             {
406               found=true;
407               int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
408               const DataArrayDoubleCollection *fineDaCol((*it).second);
409               DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
410               DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
411             }
412         }
413       if(!found)
414         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
415     }
416 }
417
418 /*!
419  * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
420  *
421  * \sa synchronizeFineEachOtherExt
422  */
423 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
424 {
425   for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
426     {
427       int p1,p2;
428       if(!presenceOf((*it).first->getMesh(),p1))
429         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
430       if(!presenceOf((*it).second->getMesh(),p2))
431         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
432       const DataArrayDoubleCollection& col1(getFieldsAt(p1));
433       const DataArrayDoubleCollection& col2(getFieldsAt(p2));
434       col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
435     }
436 }
437
438 /*!
439  * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
440  *
441  * \sa synchronizeFineEachOther
442  */
443 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
444 {
445   for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
446     {
447       int p1,p2;
448       if(!presenceOf((*it).first->getMesh(),p1))
449         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
450       if(!presenceOf((*it).second->getMesh(),p2))
451         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
452       const DataArrayDoubleCollection& col1(getFieldsAt(p1));
453       const DataArrayDoubleCollection& col2(getFieldsAt(p2));
454       col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
455     }
456 }
457
458 /*!
459  * The pairs returned share the same direct father. The number of returned elements must be even.
460  */
461 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
462 {
463   std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
464   std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
465   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
466     {
467       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
468       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
469       m[fatherOfFineMesh].push_back(fineMesh);
470     }
471   for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
472     {
473       for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
474         {
475           int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
476           std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
477           const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
478           for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
479             {
480               const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
481               ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
482             }
483         }
484     }
485   if(ret.size()%2!=0)
486     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
487   return ret;
488 }
489
490 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
491 {
492   if(!fine || !coarse)
493     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
494   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
495   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
496   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
497     {
498       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
499       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
500       bool found(false);
501       for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
502         {
503           if((*it0).first==fatherOfFineMesh)
504             {
505               found=true;
506               int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
507               const DataArrayDoubleCollection *fineDaCol((*it).second);
508               DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
509               DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
510             }
511         }
512       if(!found)
513         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
514     }
515 }
516
517 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
518 {
519   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
520     {
521       const MEDCouplingCartesianAMRMeshGen *a((*it).first);
522       if(head==a || head->isObjectInTheProgeny(a))
523         {
524           const DataArrayDoubleCollection *gc((*it).second);
525           recurseArrs.push_back(gc->getFieldWithName(fieldName));
526         }
527     }
528 }
529
530 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
531 {
532   std::size_t sz(ms.size());
533   for(std::size_t i=0;i<sz;i++)
534     {
535       if(!ms[i])
536         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
537       _map_of_dadc[i].first=ms[i];
538       _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
539     }
540 }
541
542 MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
543 {
544   std::size_t sz(other._map_of_dadc.size());
545   for(std::size_t i=0;i<sz;i++)
546     {
547       _map_of_dadc[i].first=other._map_of_dadc[i].first;
548       const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
549       if(dac)
550         _map_of_dadc[i].second=dac->deepCpy();
551     }
552 }
553
554 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
555 {
556   std::size_t ret(sizeof(MEDCouplingGridCollection));
557   ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
558   return ret;
559 }
560
561 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
562 {
563   std::vector<const BigMemoryObject *> ret;
564   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
565     {
566       const DataArrayDoubleCollection *col((*it).second);
567       if(col)
568         ret.push_back(col);
569     }
570   return ret;
571 }
572
573 void MEDCouplingGridCollection::updateTime() const
574 {
575   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
576     {
577       const MEDCouplingCartesianAMRMeshGen *a((*it).first);
578       if(a)
579         updateTimeWith(*a);
580       const DataArrayDoubleCollection *b((*it).second);
581       if(b)
582         updateTimeWith(*b);
583     }
584 }
585
586 MEDCouplingCartesianAMRPatchGF::MEDCouplingCartesianAMRPatchGF(MEDCouplingCartesianAMRMesh *mesh):MEDCouplingCartesianAMRPatchGen(mesh)
587 {
588 }
589
590 std::size_t MEDCouplingCartesianAMRPatchGF::getHeapMemorySizeWithoutChildren() const
591 {
592   return sizeof(MEDCouplingCartesianAMRPatchGF);
593 }
594
595 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMeshGen *gf):_gf(gf),_tlc(gf)
596 {
597   if(!gf)
598     throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
599   gf->incrRef();
600 }
601
602 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
603 {
604   _tlc.checkConst();
605 }
606
607 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMeshGen *gf)
608 {
609   bool ret(_tlc.keepTrackOfNewTL(gf));
610   if(ret)
611     {
612       _gf=gf;
613       if(gf)
614         gf->incrRef();
615     }
616   return ret;
617 }
618
619 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
620 {
621   other._tlc.checkConst();
622 }
623
624 /*!
625  * 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.
626  */
627 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
628 {
629   return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
630 }
631
632 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
633 {
634   std::size_t sz(fieldNames.size());
635   std::vector< std::pair<std::string,int> > fieldNames2(sz);
636   std::vector< std::vector<std::string> > compNames(sz);
637   for(std::size_t i=0;i<sz;i++)
638     {
639       fieldNames2[i].first=fieldNames[i].first;
640       fieldNames2[i].second=(int)fieldNames[i].second.size();
641       compNames[i]=fieldNames[i].second;
642     }
643   MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
644   ret->spillInfoOnComponents(compNames);
645   return ret.retn();
646 }
647
648 /*!
649  * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
650  * 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.
651  * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
652  * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
653  */
654 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
655 {
656   _tlc.checkConst();
657   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
658     (*it)->spillInfoOnComponents(compNames);
659 }
660
661 /*!
662  * Assign nature for each fields in \a this.
663  * \param [in] nfs
664  */
665 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
666 {
667   _tlc.checkConst();
668   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
669     (*it)->spillNatures(nfs);
670 }
671
672 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const
673 {
674   return new MEDCouplingAMRAttribute(*this);
675 }
676
677 /*!
678  * Returns the number of levels by \b only \b considering \a this (god father instance is considered only to see if it has not changed still last update of \a this).
679  *
680  */
681 int MEDCouplingAMRAttribute::getNumberOfLevels() const
682 {
683   checkGodFatherFrozen();
684   return (int)_levs.size();
685 }
686
687 /*!
688  * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
689  * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
690  *
691  * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
692  * \sa retrieveFieldOn
693  */
694 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
695 {
696   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
697     {
698       int tmp(-1);
699       if((*it)->presenceOf(mesh,tmp))
700         {
701           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
702           return ddc.retrieveFields();
703         }
704     }
705   throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
706 }
707
708 /*!
709  * \sa retrieveFieldsOn
710  */
711 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
712 {
713   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
714     {
715       int tmp(-1);
716       if((*it)->presenceOf(mesh,tmp))
717         {
718           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
719           return ddc.getFieldWithName(fieldName);
720         }
721     }
722   throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldOn : the mesh specified is not in the progeny of this !");
723 }
724
725 /*!
726  * This method returns a field on an unstructured mesh the most refined as possible without overlap.
727  * Ghost part are not visible here.
728  *
729  * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
730  */
731 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
732 {
733   std::vector<const DataArrayDouble *> recurseArrs;
734   std::size_t lev(0);
735   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
736     {
737       int tmp(-1);
738       if((*it)->presenceOf(mesh,tmp))
739         {
740           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
741           recurseArrs.push_back(ddc.getFieldWithName(fieldName));
742           break;
743         }
744     }
745   lev++;
746   for(std::size_t i=lev;i<_levs.size();i++)
747     {
748       const MEDCouplingGridCollection *gc(_levs[i]);
749       gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
750     }
751   return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
752 }
753
754 /*!
755  * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
756  * The output field also displays ghost cells.
757  *
758  * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
759  *
760  * \sa buildCellFieldOnWithoutGhost
761  */
762 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
763 {
764   const DataArrayDouble *arr(0);
765   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
766     {
767       int tmp(-1);
768       if((*it)->presenceOf(mesh,tmp))
769         {
770           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
771           arr=ddc.getFieldWithName(fieldName);
772         }
773     }
774   if(!arr)
775     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
776   MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
777   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
778   ret->setMesh(im);
779   ret->setArray(const_cast<DataArrayDouble *>(arr));
780   ret->setName(arr->getName());
781   return ret.retn();
782 }
783
784 /*!
785  * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
786  * The output field does not display ghost cells.
787  *
788  * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
789  *
790  * \sa buildCellFieldOnWithGhost
791  */
792 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
793 {
794   //tony
795   const DataArrayDouble *arr(0);
796   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
797     {
798       int tmp(-1);
799       if((*it)->presenceOf(mesh,tmp))
800         {
801           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
802           arr=ddc.getFieldWithName(fieldName);
803         }
804     }
805   if(!arr)
806     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
807   //
808   MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
809   std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
810   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New());
811   arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
812   std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
813   MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
814   std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
815   MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
816   arr2->copyStringInfoFrom(*arr);
817   //
818   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
819   ret->setMesh(mesh->getImageMesh());
820   ret->setArray(arr2);
821   ret->setName(arr->getName());
822   return ret.retn();
823 }
824
825 /*!
826  * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
827  * MEDCouplingAMRAttribute::alloc method.
828  *
829  * \sa synchronizeFineToCoarseBetween
830  */
831 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
832 {
833   if(_levs.empty())
834     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
835   std::size_t sz(_levs.size());
836   //
837   while(sz>1)
838     {
839       sz--;
840       synchronizeFineToCoarseByOneLevel((int)sz);
841     }
842 }
843
844 /*!
845  * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
846  * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
847  * until reaching \a toLev level.
848  *
849  * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
850  * \param [in] toLev - an existing level considered as the target level to reach.
851  *
852  */
853 void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
854 {
855   int nbl(getNumberOfLevels());
856   if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
857     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
858   if(fromLev==toLev)
859     return ;//nothing to do
860   if(fromLev<toLev)
861     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
862   for(int i=fromLev;i>toLev;i--)
863     synchronizeFineToCoarseByOneLevel(i);
864 }
865
866 /*!
867  * 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
868  * MEDCouplingAMRAttribute::alloc method.
869  */
870 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
871 {
872   if(_levs.empty())
873     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
874   std::size_t sz(_levs.size());
875   //
876   for(std::size_t i=0;i<sz-1;i++)
877     synchronizeCoarseToFineByOneLevel((int)i);
878 }
879
880 /*!
881  * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
882  * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
883  * until reaching \a toLev level.
884  *
885  * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
886  * \param [in] toLev - an existing level considered as the target level to reach.
887  */
888 void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
889 {
890   int nbl(getNumberOfLevels());
891   if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
892     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
893   if(fromLev==toLev)
894     return ;//nothing to do
895   if(fromLev>toLev)
896     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
897   for(int i=fromLev;i<toLev;i++)
898     synchronizeCoarseToFineByOneLevel(i);
899 }
900
901 /*!
902  * This method synchronizes the ghost zone of all patches (excepted the god father one).
903  * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
904  *
905  * - firstly coarse to fine with no interactions between brother patches.
906  * - secondly connected brother patches in a same master patch are updated.
907  * - thirdly connected nephew patches are updated each other.
908  * - forthly nth generation cousin patches are updated each other.
909  *
910  * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
911  * So if \a _ghost_lev == 0 this method has no effect.
912  */
913 void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
914 {
915   if(_levs.empty())
916     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
917   // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
918   std::size_t sz(_levs.size());
919   for(std::size_t i=1;i<sz;i++)
920     {
921       const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
922       MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
923     }
924   // 2nd - classical direct sublevel inside common patch
925   for(std::size_t i=1;i<sz;i++)
926     {
927       const MEDCouplingGridCollection *fine(_levs[i]);
928       if(!fine)
929         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
930       fine->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
931     }
932   // 3rd - mixed level
933   for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
934     {
935       const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
936       DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
937     }
938   // 4th - same level but with far ancestor.
939   for(std::size_t i=1;i<sz;i++)
940     {
941       const MEDCouplingGridCollection *fine(_levs[i]);
942       fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
943     }
944 }
945
946 /*!
947  * This method allocates all DataArrayDouble instances stored recursively in \a this.
948  *
949  * \sa dealloc
950  */
951 void MEDCouplingAMRAttribute::alloc()
952 {
953   _tlc.resetState();
954   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
955     {
956       MEDCouplingGridCollection *elt(*it);
957       if(elt)
958         elt->alloc(_ghost_lev);
959       else
960         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
961     }
962 }
963
964 /*!
965  * This method deallocates all DataArrayDouble instances stored recursively in \a this.
966  * \sa alloc
967  */
968 void MEDCouplingAMRAttribute::dealloc()
969 {
970   _tlc.checkConst();
971   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
972     {
973       MEDCouplingGridCollection *elt(*it);
974       if(elt)
975         elt->dealloc();
976       else
977         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
978     }
979 }
980
981 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMeshGen *gf)
982 {
983   bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
984   return ret;
985 }
986
987 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
988 {
989   std::size_t ret(sizeof(MEDCouplingAMRAttribute));
990   ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
991   return ret;
992 }
993
994 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
995 {
996   std::vector<const BigMemoryObject *> ret;
997   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
998     {
999       const MEDCouplingGridCollection *elt(*it);
1000       if(elt)
1001         ret.push_back(elt);
1002     }
1003   return ret;
1004 }
1005
1006 void MEDCouplingAMRAttribute::updateTime() const
1007 {//tony
1008 }
1009
1010 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
1011 {
1012   //gf non empty, checked by constructor
1013   int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
1014   _levs.resize(maxLev);
1015   for(int i=0;i<maxLev;i++)
1016     {
1017       std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1018       std::size_t sz(patches.size());
1019       std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
1020       for(std::size_t j=0;j<sz;j++)
1021         patchesSafe[j]=patches[j];
1022       std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
1023       for(std::size_t j=0;j<sz;j++)
1024         {
1025           ms[j]=patches[j]->getMesh();
1026         }
1027       _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
1028     }
1029   // updates cross levels neighbors
1030   _neighbors.resize(_levs.size());
1031   _cross_lev_neighbors.resize(_levs.size());
1032   if(_levs.empty())
1033     throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
1034   std::size_t sz(_levs.size());
1035   for(std::size_t i=1;i<sz;i++)
1036     {
1037       const MEDCouplingGridCollection *fine(_levs[i]);
1038       if(!fine)
1039         throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
1040       _neighbors[i]=fine->findNeighbors(_ghost_lev);
1041       if(i!=sz-1)
1042         {
1043           for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
1044             {
1045               MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
1046               std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
1047               std::size_t fullLev(i+neighs2.size());
1048               if(fullLev>=sz)
1049                 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
1050               std::size_t ii(i+1);
1051               for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
1052                 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
1053             }
1054         }
1055     }
1056 }
1057
1058 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& other):MEDCouplingDataForGodFather(other),_ghost_lev(other._ghost_lev),_levs(other._levs.size()),_neighbors(other._neighbors),_mixed_lev_neighbors(other._mixed_lev_neighbors),_cross_lev_neighbors(other._cross_lev_neighbors)
1059 {
1060   std::size_t sz(other._levs.size());
1061   for(std::size_t i=0;i<sz;i++)
1062     {
1063       const MEDCouplingGridCollection *elt(other._levs[i]);
1064       if(elt)
1065         {
1066           _levs[i]=other._levs[i]->deepCpy();
1067         }
1068     }
1069 }
1070
1071 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
1072 {
1073   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1074     {
1075       const MEDCouplingGridCollection *elt(*it);
1076       if(elt)
1077         {
1078           int tmp(-1);
1079           if(elt->presenceOf(m,tmp))
1080             {
1081               return elt->getFieldsAt(tmp);
1082             }
1083         }
1084     }
1085   throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
1086 }
1087
1088 void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
1089 {
1090   int nbl(getNumberOfLevels());
1091   if(level<=0 || level>=nbl)
1092     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
1093   const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1094   MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
1095 }
1096
1097 void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
1098 {
1099   int nbl(getNumberOfLevels());
1100   if(level<0 || level>=nbl-1)
1101     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
1102   const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
1103   MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);
1104 }