Salome HOME
d78f2a58d2dabf60374e72256e420ac661986b07
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingAMRAttribute.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay
20
21 #include "MEDCouplingAMRAttribute.hxx"
22 #include "MEDCouplingFieldDouble.hxx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingIMesh.hxx"
25
26 #include <sstream>
27
28 using namespace ParaMEDMEM;
29
30 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
31 {
32   return new DataArrayDoubleCollection(fieldNames);
33 }
34
35 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::copyFrom(const DataArrayDoubleCollection& other)
55 {
56   std::size_t sz(_arrs.size());
57   if(sz!=other._arrs.size())
58     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : size are not the same !");
59   for(std::size_t i=0;i<sz;i++)
60     {
61       DataArrayDouble *thisArr(_arrs[i].first);
62       const DataArrayDouble *otherArr(other._arrs[i].first);
63       if(!thisArr || !otherArr)
64         throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : empty DataArray !");
65       thisArr->cpyFrom(*otherArr);
66     }
67 }
68
69 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
70 {
71   std::size_t sz(_arrs.size());
72   if(sz!=compNames.size())
73     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
74   for(std::size_t i=0;i<sz;i++)
75     {
76       const std::vector<std::string>& names(compNames[i]);
77       _arrs[i].first->setInfoOnComponents(names);
78     }
79 }
80
81 void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& nfs)
82 {
83   std::size_t sz(_arrs.size());
84   if(sz!=nfs.size())
85     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !");
86   for(std::size_t i=0;i<sz;i++)
87     {
88       CheckValidNature(nfs[i]);
89       _arrs[i].second=nfs[i];
90     }
91 }
92
93 std::vector< std::pair < std::string, std::vector<std::string> > > DataArrayDoubleCollection::getInfoOnComponents() const
94 {
95   std::size_t sz(_arrs.size());
96   std::vector< std::pair < std::string, std::vector<std::string> > > ret(sz);
97   for(std::size_t i=0;i<sz;i++)
98     {
99       const DataArrayDouble *elt(_arrs[i].first);
100       if(!elt)
101         throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::getInfoOnComponents : empty array !");
102       ret[i]=std::pair < std::string, std::vector<std::string> >(elt->getName(),elt->getInfoOnComponents());
103     }
104   return ret;
105 }
106
107 std::vector<NatureOfField> DataArrayDoubleCollection::getNatures() const
108 {
109   std::size_t sz(_arrs.size());
110   std::vector<NatureOfField> ret(sz);
111   for(std::size_t i=0;i<sz;i++)
112     ret[i]=_arrs[i].second;
113   return ret;
114 }
115
116 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
117 {
118   std::size_t sz(_arrs.size());
119   std::vector<DataArrayDouble *> ret(sz);
120   for(std::size_t i=0;i<sz;i++)
121     {
122       const DataArrayDouble *tmp(_arrs[i].first);
123       ret[i]=const_cast<DataArrayDouble *>(tmp);
124       if(ret[i])
125         ret[i]->incrRef();
126     }
127   return ret;
128 }
129
130 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
131 {
132   std::vector<std::string> vec;
133   for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
134     {
135       const DataArrayDouble *obj((*it).first);
136       if(obj)
137         {
138           if(obj->getName()==name)
139             return obj;
140           else
141             vec.push_back(obj->getName());
142         }
143     }
144   std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
145   std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
146   throw INTERP_KERNEL::Exception(oss.str().c_str());
147 }
148
149 DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name)
150 {
151   std::vector<std::string> vec;
152   for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::iterator it=_arrs.begin();it!=_arrs.end();it++)
153     {
154       DataArrayDouble *obj((*it).first);
155       if(obj)
156         {
157           if(obj->getName()==name)
158             return obj;
159           else
160             vec.push_back(obj->getName());
161         }
162     }
163   std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName non const : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
164   std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
165   throw INTERP_KERNEL::Exception(oss.str().c_str());
166 }
167
168 DataArrayDouble *DataArrayDoubleCollection::at(int pos)
169 {
170   if(pos<0 || pos>=(int)_arrs.size())
171     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at (non const) : pos must be in [0,nbOfFields) !");
172   return _arrs[pos].first;
173 }
174
175 const DataArrayDouble *DataArrayDoubleCollection::at(int pos) const
176 {
177   if(pos<0 || pos>=(int)_arrs.size())
178     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at : pos must be in [0,nbOfFields) !");
179   return _arrs[pos].first;
180 }
181
182 int DataArrayDoubleCollection::size() const
183 {
184   return (int)_arrs.size();
185 }
186
187 void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
188 {
189   if(!fine || !coarse)
190     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
191   std::size_t sz(coarse->_arrs.size());
192   if(fine->_arrs.size()!=sz)
193     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
194   for(std::size_t i=0;i<sz;i++)
195     {
196       CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
197       fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
198     }
199 }
200
201 void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
202 {
203   if(!fine || !coarse)
204     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
205   std::size_t sz(coarse->_arrs.size());
206   if(fine->_arrs.size()!=sz)
207     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
208   for(std::size_t i=0;i<sz;i++)
209     {
210       CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
211       fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
212     }
213 }
214
215 void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
216 {
217   if(!fatherOfFineMesh)
218     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
219   std::size_t sz(children.size());
220   if(fieldsOnFine.size()!=sz)
221     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
222   if(sz<=1)
223     return ;
224   std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
225   for(std::size_t i=0;i<sz;i++)
226     if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
227       throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
228   for(std::size_t i=1;i<sz;i++)
229     if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
230       throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
231   for(std::size_t i=0;i<nbOfCall;i++)
232     {
233       std::vector<const DataArrayDouble *> arrs(sz);
234       for(std::size_t j=0;j<sz;j++)
235         arrs[j]=fieldsOnFine[j]->_arrs[i].first;
236       fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
237     }
238 }
239
240 /*!
241  * 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).
242  */
243 void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac)
244 {
245   if(!p1 || !p1dac || !p2 || !p2dac)
246     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !");
247   std::size_t sz(p1dac->_arrs.size());
248   if(p2dac->_arrs.size()!=sz)
249     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !");
250   for(std::size_t i=0;i<sz;i++)
251     {
252       const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first);
253       DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second);
254       bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second));
255       MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative);
256     }
257 }
258
259 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
260 {
261   if(!fine || !coarse)
262     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
263   std::size_t sz(coarse->_arrs.size());
264   if(fine->_arrs.size()!=sz)
265     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
266   for(std::size_t i=0;i<sz;i++)
267     fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev);
268 }
269
270 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
271 {
272   DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
273   std::size_t sz(_arrs.size());
274   if(other._arrs.size()!=sz)
275     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
276   for(std::size_t i=0;i<sz;i++)
277     father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
278 }
279
280 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
281 {
282   DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
283   std::size_t sz(_arrs.size());
284   if(other._arrs.size()!=sz)
285     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
286   for(std::size_t i=0;i<sz;i++)
287     MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
288 }
289
290 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
291 {
292   std::size_t sz(fieldNames.size());
293   std::vector<std::string> names(sz);
294   for(std::size_t i=0;i<sz;i++)
295     {
296       const std::pair<std::string,int>& info(fieldNames[i]);
297       if(info.second<=0)
298         {
299           std::ostringstream oss; oss << "DataArrayDoubleCollection constructor : At pos #" << i << " the array with name \"" << info.first << "\" as a number of components equal to " << info.second;
300           oss << " It has to be >=1 !";
301           throw INTERP_KERNEL::Exception(oss.str().c_str());
302         }
303       _arrs[i].first=DataArrayDouble::New();
304       _arrs[i].first->alloc(0,info.second);
305       _arrs[i].first->setName(info.first);
306       names[i]=info.second;
307       _arrs[i].second=ConservativeVolumic;
308     }
309   CheckDiscriminantNames(names);
310 }
311
312 DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size())
313 {
314   std::size_t sz(other._arrs.size());
315   for(std::size_t i=0;i<sz;i++)
316     {
317       _arrs[i].second=other._arrs[i].second;
318       const DataArrayDouble *da(other._arrs[i].first);
319       if(da)
320         _arrs[i].first=da->deepCpy();
321     }
322 }
323
324 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
325 {
326   std::size_t ret(sizeof(DataArrayDoubleCollection));
327   ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
328   return ret;
329 }
330
331 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
332 {
333   std::vector<const BigMemoryObject *> ret;
334   for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
335     {
336       const DataArrayDouble *pt((*it).first);
337       if(pt)
338         ret.push_back(pt);
339     }
340   return ret;
341 }
342
343 void DataArrayDoubleCollection::updateTime() const
344 {
345   for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
346     {
347       const DataArrayDouble *pt((*it).first);
348       if(pt)
349         updateTimeWith(*pt);
350     }
351 }
352
353 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
354 {
355   std::set<std::string> s(names.begin(),names.end());
356   if(s.size()!=names.size())
357     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
358 }
359
360 bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
361 {
362   CheckValidNature(n);
363   return n==RevIntegral || n==IntegralGlobConstraint;
364 }
365
366 void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
367 {
368   CheckValidNature(n1);
369   CheckValidNature(n2);
370   if(n1!=n2)
371     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
372 }
373
374 void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
375 {
376   if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral)
377     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
378 }
379
380 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
381 {
382   return new MEDCouplingGridCollection(ms,fieldNames);
383 }
384
385 MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
386 {
387   return new MEDCouplingGridCollection(*this,newGf,oldGf);
388 }
389
390 void MEDCouplingGridCollection::alloc(int ghostLev)
391 {
392   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
393     {
394       int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
395       DataArrayDoubleCollection *dadc((*it).second);
396       if(dadc)
397         dadc->allocTuples(nbTuples);
398       else
399         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
400     }
401 }
402
403 void MEDCouplingGridCollection::dealloc()
404 {
405   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
406     {
407       DataArrayDoubleCollection *dadc((*it).second);
408       if(dadc)
409         dadc->dellocTuples();
410       else
411         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
412     }
413 }
414
415 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
416 {
417   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
418     (*it).second->spillInfoOnComponents(compNames);
419 }
420
421 void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
422 {
423   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
424     (*it).second->spillNatures(nfs);
425 }
426
427 std::vector< std::pair<std::string, std::vector<std::string> > > MEDCouplingGridCollection::getInfoOnComponents() const
428 {
429   if(_map_of_dadc.empty())
430     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !");
431   const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
432   if(!elt)
433     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !");
434   return elt->getInfoOnComponents();
435 }
436
437 std::vector<NatureOfField> MEDCouplingGridCollection::getNatures() const
438 {
439   if(_map_of_dadc.empty())
440     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !");
441   const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
442   if(!elt)
443     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !");
444   return elt->getNatures();
445 }
446
447 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
448 {
449   int ret(0);
450   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
451     {
452       if((*it).first==m)
453         {
454           pos=ret;
455           return true;
456         }
457     }
458   return false;
459 }
460
461 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
462 {
463   if(pos<0 || pos>(int)_map_of_dadc.size())
464     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
465   return *_map_of_dadc[pos].second;
466 }
467
468 DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos)
469 {
470   if(pos<0 || pos>(int)_map_of_dadc.size())
471     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !");
472   return *_map_of_dadc[pos].second;
473 }
474
475 /*!
476  * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting
477  * part of fields of \a this. The fields are expected to be the same between \a other and \a this.
478  * This methods makes the hypothesis that \a this and \a other share two god father that are compatible each other that is to say with the same cell grid structure.
479  */
480 void MEDCouplingGridCollection::copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other)
481 {
482   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
483     {
484       std::vector<int> deltaThis,deltaOther;
485       std::vector< std::pair<int,int> > rgThis((*it).first->positionRelativeToGodFather(deltaThis));
486       std::vector<int> thisSt((*it).first->getImageMesh()->getCellGridStructure());
487       std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
488       for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++)
489         {
490           std::vector< std::pair<int,int> > rgOther((*it2).first->positionRelativeToGodFather(deltaOther));
491           if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther))
492             {
493               std::vector< std::pair<int,int> > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther));
494               std::vector< std::pair<int,int> > pThis,pOther;
495               MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true);
496               MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true);
497               std::vector<int> otherSt((*it2).first->getImageMesh()->getCellGridStructure());
498               MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev);
499               MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev);
500               std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
501               int sz((*it2).second->size());
502               for(int i=0;i<sz;i++)
503                 {
504                   const DataArrayDouble *otherArr((*it2).second->at(i));
505                   DataArrayDouble *thisArr((*it).second->at(i));
506                   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther));
507                   MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther);
508                 }
509             }
510         }
511     }
512 }
513
514 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
515 {
516   if(!fine || !coarse)
517     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
518   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
519   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
520   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
521     {
522       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
523       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
524       bool found(false);
525       for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
526         {
527           if((*it0).first==fatherOfFineMesh)
528             {
529               found=true;
530               int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
531               const DataArrayDoubleCollection *coarseDaCol((*it0).second);
532               DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
533               DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
534             }
535         }
536       if(!found)
537         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
538     }
539 }
540
541 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
542 {
543   if(!fine || !coarse)
544     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
545   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
546   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
547   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
548     {
549       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
550       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
551       bool found(false);
552       for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
553         {
554           if((*it0).first==fatherOfFineMesh)
555             {
556               found=true;
557               int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
558               const DataArrayDoubleCollection *fineDaCol((*it).second);
559               DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
560               DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
561             }
562         }
563       if(!found)
564         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
565     }
566 }
567
568 /*!
569  * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
570  *
571  * \sa synchronizeFineEachOtherExt
572  */
573 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
574 {
575   for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
576     {
577       int p1,p2;
578       if(!presenceOf((*it).first->getMesh(),p1))
579         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
580       if(!presenceOf((*it).second->getMesh(),p2))
581         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
582       const DataArrayDoubleCollection& col1(getFieldsAt(p1));
583       const DataArrayDoubleCollection& col2(getFieldsAt(p2));
584       col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
585     }
586 }
587
588 /*!
589  * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
590  *
591  * \sa synchronizeFineEachOther
592  */
593 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
594 {
595   for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
596     {
597       int p1,p2;
598       if(!presenceOf((*it).first->getMesh(),p1))
599         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
600       if(!presenceOf((*it).second->getMesh(),p2))
601         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
602       const DataArrayDoubleCollection& col1(getFieldsAt(p1));
603       const DataArrayDoubleCollection& col2(getFieldsAt(p2));
604       col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
605     }
606 }
607
608 /*!
609  * The pairs returned share the same direct father. The number of returned elements must be even.
610  */
611 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
612 {
613   std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
614   std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
615   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
616     {
617       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
618       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
619       m[fatherOfFineMesh].push_back(fineMesh);
620     }
621   for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
622     {
623       for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
624         {
625           int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
626           std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
627           const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
628           for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
629             {
630               const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
631               ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
632             }
633         }
634     }
635   if(ret.size()%2!=0)
636     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
637   return ret;
638 }
639
640 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
641 {
642   if(!fine || !coarse)
643     throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
644   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
645   const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
646   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
647     {
648       const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
649       const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
650       bool found(false);
651       for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
652         {
653           if((*it0).first==fatherOfFineMesh)
654             {
655               found=true;
656               int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
657               const DataArrayDoubleCollection *fineDaCol((*it).second);
658               DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
659               DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
660             }
661         }
662       if(!found)
663         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
664     }
665 }
666
667 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
668 {
669   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
670     {
671       const MEDCouplingCartesianAMRMeshGen *a((*it).first);
672       if(head==a || head->isObjectInTheProgeny(a))
673         {
674           const DataArrayDoubleCollection *gc((*it).second);
675           recurseArrs.push_back(gc->getFieldWithName(fieldName));
676         }
677     }
678 }
679
680 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
681 {
682   std::size_t sz(ms.size());
683   for(std::size_t i=0;i<sz;i++)
684     {
685       if(!ms[i])
686         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
687       _map_of_dadc[i].first=ms[i];
688       _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
689     }
690 }
691
692 MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
693 {
694   std::size_t sz(other._map_of_dadc.size());
695   for(std::size_t i=0;i<sz;i++)
696     {
697       std::vector<int> pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf));
698       _map_of_dadc[i].first=newGf->getMeshAtPosition(pos);
699       const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
700       if(dac)
701         _map_of_dadc[i].second=dac->deepCpy();
702     }
703 }
704
705 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
706 {
707   std::size_t ret(sizeof(MEDCouplingGridCollection));
708   ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
709   return ret;
710 }
711
712 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
713 {
714   std::vector<const BigMemoryObject *> ret;
715   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
716     {
717       const DataArrayDoubleCollection *col((*it).second);
718       if(col)
719         ret.push_back(col);
720     }
721   return ret;
722 }
723
724 void MEDCouplingGridCollection::updateTime() const
725 {
726   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
727     {
728       const MEDCouplingCartesianAMRMeshGen *a((*it).first);
729       if(a)
730         updateTimeWith(*a);
731       const DataArrayDoubleCollection *b((*it).second);
732       if(b)
733         updateTimeWith(*b);
734     }
735 }
736
737 MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather()
738 {
739   return _gf;
740 }
741
742 const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const
743 {
744   return _gf;
745 }
746
747 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
748 {
749   if(!gf)
750     throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
751   gf->incrRef();
752 }
753
754 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
755 {
756   _tlc.checkConst();
757 }
758
759 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
760 {
761   bool ret(_tlc.keepTrackOfNewTL(gf));
762   if(ret)
763     {
764       _gf=gf;
765       if(gf)
766         gf->incrRef();
767     }
768   return ret;
769 }
770
771 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
772 {
773   other._tlc.checkConst();
774   if(deepCpyGF)
775     {
776       const MEDCouplingCartesianAMRMesh *gf(other._gf);
777       if(gf)
778         _gf=gf->deepCpy(0);
779       _tlc.keepTrackOfNewTL(_gf);
780     }
781 }
782
783 /*!
784  * 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.
785  */
786 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
787 {
788   return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
789 }
790
791 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
792 {
793   std::size_t sz(fieldNames.size());
794   std::vector< std::pair<std::string,int> > fieldNames2(sz);
795   std::vector< std::vector<std::string> > compNames(sz);
796   for(std::size_t i=0;i<sz;i++)
797     {
798       fieldNames2[i].first=fieldNames[i].first;
799       fieldNames2[i].second=(int)fieldNames[i].second.size();
800       compNames[i]=fieldNames[i].second;
801     }
802   MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
803   ret->spillInfoOnComponents(compNames);
804   return ret.retn();
805 }
806
807 /*!
808  * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
809  * 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.
810  * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
811  * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
812  */
813 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
814 {
815   _tlc.checkConst();
816   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
817     (*it)->spillInfoOnComponents(compNames);
818 }
819
820 /*!
821  * Assign nature for each fields in \a this.
822  * \param [in] nfs
823  */
824 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
825 {
826   _tlc.checkConst();
827   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
828     (*it)->spillNatures(nfs);
829 }
830
831 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const
832 {
833   return new MEDCouplingAMRAttribute(*this,true);
834 }
835
836 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const
837 {
838   return new MEDCouplingAMRAttribute(*this,false);
839 }
840
841 /*!
842  * 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).
843  *
844  */
845 int MEDCouplingAMRAttribute::getNumberOfLevels() const
846 {
847   checkGodFatherFrozen();
848   return (int)_levs.size();
849 }
850
851 /*!
852  * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
853  * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
854  *
855  * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
856  * \sa retrieveFieldOn
857  */
858 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
859 {
860   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
861     {
862       int tmp(-1);
863       if((*it)->presenceOf(mesh,tmp))
864         {
865           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
866           return ddc.retrieveFields();
867         }
868     }
869   throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
870 }
871
872 /*!
873  * \sa retrieveFieldsOn
874  */
875 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
876 {
877   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
878     {
879       int tmp(-1);
880       if((*it)->presenceOf(mesh,tmp))
881         {
882           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
883           return ddc.getFieldWithName(fieldName);
884         }
885     }
886   throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn : the mesh specified is not in the progeny of this !");
887 }
888
889 DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName)
890 {
891   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
892     {
893       int tmp(-1);
894       if((*it)->presenceOf(mesh,tmp))
895         {
896           DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
897           return ddc.getFieldWithName(fieldName);
898         }
899     }
900   throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn non const : the mesh specified is not in the progeny of this !");
901 }
902
903 /*!
904  * This method returns a field on an unstructured mesh the most refined as possible without overlap.
905  * Ghost part are not visible here.
906  *
907  * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
908  */
909 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
910 {
911   std::vector<const DataArrayDouble *> recurseArrs;
912   std::size_t lev(0);
913   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
914     {
915       int tmp(-1);
916       if((*it)->presenceOf(mesh,tmp))
917         {
918           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
919           recurseArrs.push_back(ddc.getFieldWithName(fieldName));
920           break;
921         }
922     }
923   lev++;
924   for(std::size_t i=lev;i<_levs.size();i++)
925     {
926       const MEDCouplingGridCollection *gc(_levs[i]);
927       gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
928     }
929   return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
930 }
931
932 /*!
933  * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
934  * The output field also displays ghost cells.
935  *
936  * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
937  *
938  * \sa buildCellFieldOnWithoutGhost
939  */
940 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
941 {
942   const DataArrayDouble *arr(0);
943   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
944     {
945       int tmp(-1);
946       if((*it)->presenceOf(mesh,tmp))
947         {
948           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
949           arr=ddc.getFieldWithName(fieldName);
950         }
951     }
952   if(!arr)
953     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
954   MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
955   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
956   ret->setMesh(im);
957   ret->setArray(const_cast<DataArrayDouble *>(arr));
958   ret->setName(arr->getName());
959   return ret.retn();
960 }
961
962 /*!
963  * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
964  * The output field does not display ghost cells.
965  *
966  * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
967  *
968  * \sa buildCellFieldOnWithGhost
969  */
970 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
971 {
972   //tony
973   const DataArrayDouble *arr(0);
974   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
975     {
976       int tmp(-1);
977       if((*it)->presenceOf(mesh,tmp))
978         {
979           const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
980           arr=ddc.getFieldWithName(fieldName);
981         }
982     }
983   if(!arr)
984     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
985   //
986   MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
987   std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
988   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New());
989   arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
990   std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
991   MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
992   std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
993   MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
994   arr2->copyStringInfoFrom(*arr);
995   //
996   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
997   ret->setMesh(mesh->getImageMesh());
998   ret->setArray(arr2);
999   ret->setName(arr->getName());
1000   return ret.retn();
1001 }
1002
1003 /*!
1004  * This method is useful just after a remesh after a time step computation to project values in \a this to the new
1005  * mesh \a targetGF.
1006  *
1007  * This method performs a projection from \a this to a target AMR mesh \a targetGF.
1008  * This method performs the projection by trying to transfer the finest information to \a targetGF.
1009  * \b WARNING this method does not update the ghost zone, if any.
1010  * The level0 of \a this god father must have the same structure than those of \a targetGF.
1011  *
1012  * This method makes checks that ghost size of \a this and \a targetGF are the same, and that
1013  * the number of levels in \a this and in \a targetGF are also the same.
1014  */
1015 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const
1016 {
1017   if(!targetGF)
1018     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !");
1019   if(_levs.empty())
1020     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !");
1021   const MEDCouplingGridCollection *lev0(_levs[0]);
1022   if(!lev0)
1023     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !");
1024   std::vector< std::pair < std::string, std::vector<std::string> > > fieldNames(lev0->getInfoOnComponents());
1025   MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev));
1026   ret->spillNatures(lev0->getNatures());
1027   ret->alloc();
1028   int nbLevs(getNumberOfLevels());
1029   if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs)
1030     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !");
1031   // first step copy level0
1032   if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure())
1033     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !");
1034   const DataArrayDoubleCollection& col(lev0->getFieldsAt(0));
1035   DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0));
1036   colTarget.copyFrom(col);
1037   // then go deeper and deeper
1038   for(int i=1;i<nbLevs;i++)
1039     {
1040       ret->synchronizeCoarseToFineByOneLevel(i-1);
1041       MEDCouplingGridCollection *targetCol(ret->_levs[i]);
1042       if(!targetCol)
1043         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !");
1044       const MEDCouplingGridCollection *thisCol(_levs[i]);
1045       if(!thisCol)
1046         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !");
1047       targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol);
1048     }
1049   return ret.retn();
1050 }
1051
1052 /*!
1053  * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
1054  * MEDCouplingAMRAttribute::alloc method.
1055  * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse)
1056  *
1057  * \sa synchronizeFineToCoarseBetween
1058  */
1059 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
1060 {
1061   if(_levs.empty())
1062     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
1063   std::size_t sz(_levs.size());
1064   //
1065   while(sz>1)
1066     {
1067       sz--;
1068       synchronizeFineToCoarseByOneLevel((int)sz);
1069     }
1070 }
1071
1072 /*!
1073  * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
1074  * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
1075  * until reaching \a toLev level.
1076  * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse).
1077  *
1078  * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
1079  * \param [in] toLev - an existing level considered as the target level to reach.
1080  *
1081  */
1082 void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
1083 {
1084   int nbl(getNumberOfLevels());
1085   if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1086     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1087   if(fromLev==toLev)
1088     return ;//nothing to do
1089   if(fromLev<toLev)
1090     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
1091   for(int i=fromLev;i>toLev;i--)
1092     synchronizeFineToCoarseByOneLevel(i);
1093 }
1094
1095 /*!
1096  * 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
1097  * MEDCouplingAMRAttribute::alloc method.
1098  * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method)
1099  */
1100 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
1101 {
1102   if(_levs.empty())
1103     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
1104   std::size_t sz(_levs.size());
1105   //
1106   for(std::size_t i=0;i<sz-1;i++)
1107     synchronizeCoarseToFineByOneLevel((int)i);
1108 }
1109
1110 /*!
1111  * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
1112  * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
1113  * until reaching \a toLev level.
1114  * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarseBetween method)
1115  *
1116  * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
1117  * \param [in] toLev - an existing level considered as the target level to reach.
1118  */
1119 void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
1120 {
1121   int nbl(getNumberOfLevels());
1122   if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1123     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1124   if(fromLev==toLev)
1125     return ;//nothing to do
1126   if(fromLev>toLev)
1127     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
1128   for(int i=fromLev;i<toLev;i++)
1129     synchronizeCoarseToFineByOneLevel(i);
1130 }
1131
1132 /*!
1133  * This method synchronizes the ghost zone of all patches (excepted the god father one).
1134  * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
1135  *
1136  * - firstly coarse to fine with no interactions between brother patches.
1137  * - secondly connected brother patches in a same master patch are updated.
1138  * - thirdly connected nephew patches are updated each other.
1139  * - forthly nth generation cousin patches are updated each other.
1140  *
1141  * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
1142  * So if \a _ghost_lev == 0 this method has no effect.
1143  */
1144 void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
1145 {
1146   int sz(getNumberOfLevels());
1147   if(sz==0)
1148     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
1149   // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
1150   for(int i=1;i<sz;i++)
1151     {
1152       const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
1153       MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1154     }
1155   // 2nd - classical direct sublevel inside common patch
1156   for(int i=1;i<sz;i++)
1157     {
1158       const MEDCouplingGridCollection *curLev(_levs[i]);
1159       if(!curLev)
1160         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
1161       curLev->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
1162     }
1163   // 3rd - mixed level
1164   for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
1165     {
1166       const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
1167       DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
1168     }
1169   // 4th - same level but with far ancestor.
1170   for(int i=1;i<sz;i++)
1171     {
1172       const MEDCouplingGridCollection *fine(_levs[i]);
1173       fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
1174     }
1175 }
1176
1177 /*!
1178  * This method works \b ONLY \b ON \b DIRECT \b SONS \b OF \a mesh. So only a part of patches at a given level is updated here.
1179  * The ghost zone of all of these sons of \a mesh are updated using the brother patches (the patches sharing the \b SAME \a mesh).
1180  * It is sometimes possible that a ghost zone of some sons of \a mesh are covered by a patch of same level but different father.
1181  * For such cases, the ghost zones are \b NOT updated. If you need a more thorough (but more costly) ghost zone update use synchronizeAllGhostZonesAtASpecifiedLevel method instead.
1182  *
1183  * \param [in] mesh - an element in the progeny of god father in \a this, which the ghost zone of its sons will be updated each other.
1184  *
1185  */
1186 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh)
1187 {
1188   if(!mesh)
1189     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !");
1190   int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels());
1191   if(level<0 || level>=sz-1)
1192     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !");
1193   const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& itemsToFilter(_neighbors[level+1]);
1194   std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > itemsToSync; itemsToSync.reserve(itemsToFilter.size());
1195   for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++)
1196     {
1197       if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh)
1198         itemsToSync.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>((*it).first,(*it).second));
1199     }
1200   const MEDCouplingGridCollection *curLev(_levs[level+1]);
1201   if(!curLev)
1202     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !");
1203   curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync);
1204 }
1205
1206 /*!
1207  * This method updates \b all the patches at level \a level each other without consideration of their father.
1208  * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf.
1209  */
1210 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level)
1211 {
1212   int maxLev(getNumberOfLevels());
1213   if(level<0 || level>=maxLev)
1214     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !");
1215   if(level==0)
1216     return ;//at level 0 only one patch -> no need to update
1217   // 1st step - updates all patches pairs at level \a level sharing the same father
1218   const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items(_neighbors[level]);
1219   const MEDCouplingGridCollection *curLev(_levs[level]);
1220   if(!curLev)
1221     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !");
1222   curLev->synchronizeFineEachOther(_ghost_lev,items);
1223   //2nd step - updates all patches pairs at level \a level not sharing the same father
1224   const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items2(_cross_lev_neighbors[level]);
1225   curLev->synchronizeFineEachOtherExt(_ghost_lev,items2);
1226 }
1227
1228 /*!
1229  * This method updates ghost zones of patches at level \a level whatever their father \b using \b father \b patches \b ONLY (at level \b level - 1).
1230  * This method is useful to propagate to the ghost zone of childhood the modification.
1231  */
1232 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level)
1233 {
1234   int maxLev(getNumberOfLevels());
1235   if(level<=0 || level>=maxLev)
1236     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !");
1237   const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1238   MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1239   //_cross_lev_neighbors is not needed.
1240 }
1241
1242 /*!
1243  * This method allocates all DataArrayDouble instances stored recursively in \a this.
1244  *
1245  * \sa dealloc
1246  */
1247 void MEDCouplingAMRAttribute::alloc()
1248 {
1249   _tlc.resetState();
1250   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1251     {
1252       MEDCouplingGridCollection *elt(*it);
1253       if(elt)
1254         elt->alloc(_ghost_lev);
1255       else
1256         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
1257     }
1258 }
1259
1260 /*!
1261  * This method deallocates all DataArrayDouble instances stored recursively in \a this.
1262  * \sa alloc
1263  */
1264 void MEDCouplingAMRAttribute::dealloc()
1265 {
1266   _tlc.checkConst();
1267   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1268     {
1269       MEDCouplingGridCollection *elt(*it);
1270       if(elt)
1271         elt->dealloc();
1272       else
1273         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
1274     }
1275 }
1276
1277 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
1278 {
1279   bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
1280   return ret;
1281 }
1282
1283 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
1284 {
1285   std::size_t ret(sizeof(MEDCouplingAMRAttribute));
1286   ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
1287   return ret;
1288 }
1289
1290 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
1291 {
1292   std::vector<const BigMemoryObject *> ret;
1293   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1294     {
1295       const MEDCouplingGridCollection *elt(*it);
1296       if(elt)
1297         ret.push_back(elt);
1298     }
1299   return ret;
1300 }
1301
1302 void MEDCouplingAMRAttribute::updateTime() const
1303 {//tony
1304 }
1305
1306 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
1307 {
1308   //gf non empty, checked by constructor
1309   int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
1310   _levs.resize(maxLev);
1311   for(int i=0;i<maxLev;i++)
1312     {
1313       std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1314       std::size_t sz(patches.size());
1315       std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
1316       for(std::size_t j=0;j<sz;j++)
1317         patchesSafe[j]=patches[j];
1318       std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
1319       for(std::size_t j=0;j<sz;j++)
1320         {
1321           ms[j]=patches[j]->getMesh();
1322         }
1323       _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
1324     }
1325   // updates cross levels neighbors
1326   _neighbors.resize(_levs.size());
1327   _cross_lev_neighbors.resize(_levs.size());
1328   if(_levs.empty())
1329     throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
1330   std::size_t sz(_levs.size());
1331   for(std::size_t i=1;i<sz;i++)
1332     {
1333       const MEDCouplingGridCollection *fine(_levs[i]);
1334       if(!fine)
1335         throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
1336       _neighbors[i]=fine->findNeighbors(_ghost_lev);
1337       if(i!=sz-1)
1338         {
1339           for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
1340             {
1341               MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
1342               std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
1343               std::size_t fullLev(i+neighs2.size());
1344               if(fullLev>=sz)
1345                 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
1346               std::size_t ii(i+1);
1347               for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
1348                 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
1349             }
1350         }
1351     }
1352 }
1353
1354 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& other, bool deepCpyGF):MEDCouplingDataForGodFather(other,deepCpyGF),_ghost_lev(other._ghost_lev),_levs(other._levs.size()),_neighbors(other._neighbors),_mixed_lev_neighbors(other._mixed_lev_neighbors),_cross_lev_neighbors(other._cross_lev_neighbors)
1355 {
1356   std::size_t sz(other._levs.size());
1357   for(std::size_t i=0;i<sz;i++)
1358     {
1359       const MEDCouplingGridCollection *elt(other._levs[i]);
1360       if(elt)
1361         {
1362           _levs[i]=other._levs[i]->deepCpy(_gf,other._gf);
1363         }
1364     }
1365   //_cross_lev_neighbors(other._cross_lev_neighbors)
1366   sz=other._neighbors.size();
1367   for(std::size_t i=0;i<sz;i++)
1368     {
1369       const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._neighbors[i]);
1370       std::size_t sz2(neigh2.size());
1371       std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_neighbors[i]);
1372       for(std::size_t j=0;j<sz2;j++)
1373         {
1374           const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1375           std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1376           neigh3[j].first=_gf->getPatchAtPosition(pp1);
1377           neigh3[j].second=_gf->getPatchAtPosition(pp2);
1378         }
1379     }
1380   //
1381   sz=other._mixed_lev_neighbors.size();
1382   for(std::size_t i=0;i<sz;i++)
1383     {
1384       const MEDCouplingCartesianAMRPatch *p1(other._mixed_lev_neighbors[i].first),*p2(other._mixed_lev_neighbors[i].second);
1385       std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1386       _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1);
1387       _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2);
1388     }
1389   //
1390   sz=other._cross_lev_neighbors.size();
1391   for(std::size_t i=0;i<sz;i++)
1392     {
1393       const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._cross_lev_neighbors[i]);
1394       std::size_t sz2(neigh2.size());
1395       std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_cross_lev_neighbors[i]);
1396       for(std::size_t j=0;j<sz2;j++)
1397         {
1398           const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1399           std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1400           neigh3[j].first=_gf->getPatchAtPosition(pp1);
1401           neigh3[j].second=_gf->getPatchAtPosition(pp2);
1402         }
1403     }
1404 }
1405
1406 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
1407 {
1408   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1409     {
1410       const MEDCouplingGridCollection *elt(*it);
1411       if(elt)
1412         {
1413           int tmp(-1);
1414           if(elt->presenceOf(m,tmp))
1415             {
1416               return elt->getFieldsAt(tmp);
1417             }
1418         }
1419     }
1420   throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
1421 }
1422
1423 void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
1424 {
1425   int nbl(getNumberOfLevels());
1426   if(level<=0 || level>=nbl)
1427     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
1428   const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1429   MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
1430 }
1431
1432 void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
1433 {
1434   int nbl(getNumberOfLevels());
1435   if(level<0 || level>=nbl-1)
1436     throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
1437   const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
1438   MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);
1439 }