1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay
21 #include "MEDCouplingAMRAttribute.hxx"
22 #include "MEDCouplingFieldDouble.hxx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingIMesh.hxx"
29 using namespace MEDCoupling;
32 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
34 return new DataArrayDoubleCollection(fieldNames);
37 DataArrayDoubleCollection *DataArrayDoubleCollection::deepCopy() const
39 return new DataArrayDoubleCollection(*this);
42 void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
44 std::size_t sz(_arrs.size());
45 for(std::size_t i=0;i<sz;i++)
46 _arrs[i].first->reAlloc(nbOfTuples);
49 void DataArrayDoubleCollection::dellocTuples()
51 std::size_t sz(_arrs.size());
52 for(std::size_t i=0;i<sz;i++)
53 _arrs[i].first->reAlloc(0);
56 void DataArrayDoubleCollection::copyFrom(const DataArrayDoubleCollection& other)
58 std::size_t sz(_arrs.size());
59 if(sz!=other._arrs.size())
60 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : size are not the same !");
61 for(std::size_t i=0;i<sz;i++)
63 DataArrayDouble *thisArr(_arrs[i].first);
64 const DataArrayDouble *otherArr(other._arrs[i].first);
65 if(!thisArr || !otherArr)
66 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : empty DataArray !");
67 thisArr->deepCopyFrom(*otherArr);
71 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
73 std::size_t sz(_arrs.size());
74 if(sz!=compNames.size())
75 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
76 for(std::size_t i=0;i<sz;i++)
78 const std::vector<std::string>& names(compNames[i]);
79 _arrs[i].first->setInfoOnComponents(names);
83 void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& nfs)
85 std::size_t sz(_arrs.size());
87 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !");
88 for(std::size_t i=0;i<sz;i++)
90 CheckValidNature(nfs[i]);
91 _arrs[i].second=nfs[i];
95 std::vector< std::pair < std::string, std::vector<std::string> > > DataArrayDoubleCollection::getInfoOnComponents() const
97 std::size_t sz(_arrs.size());
98 std::vector< std::pair < std::string, std::vector<std::string> > > ret(sz);
99 for(std::size_t i=0;i<sz;i++)
101 const DataArrayDouble *elt(_arrs[i].first);
103 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::getInfoOnComponents : empty array !");
104 ret[i]=std::pair < std::string, std::vector<std::string> >(elt->getName(),elt->getInfoOnComponents());
109 std::vector<NatureOfField> DataArrayDoubleCollection::getNatures() const
111 std::size_t sz(_arrs.size());
112 std::vector<NatureOfField> ret(sz);
113 for(std::size_t i=0;i<sz;i++)
114 ret[i]=_arrs[i].second;
118 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
120 std::size_t sz(_arrs.size());
121 std::vector<DataArrayDouble *> ret(sz);
122 for(std::size_t i=0;i<sz;i++)
124 const DataArrayDouble *tmp(_arrs[i].first);
125 ret[i]=const_cast<DataArrayDouble *>(tmp);
132 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
134 std::vector<std::string> vec;
135 for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
137 const DataArrayDouble *obj((*it).first);
140 if(obj->getName()==name)
143 vec.push_back(obj->getName());
146 std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
147 std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
148 throw INTERP_KERNEL::Exception(oss.str().c_str());
151 DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name)
153 std::vector<std::string> vec;
154 for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::iterator it=_arrs.begin();it!=_arrs.end();it++)
156 DataArrayDouble *obj((*it).first);
159 if(obj->getName()==name)
162 vec.push_back(obj->getName());
165 std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName non const : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
166 std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
167 throw INTERP_KERNEL::Exception(oss.str().c_str());
170 DataArrayDouble *DataArrayDoubleCollection::at(int pos)
172 if(pos<0 || pos>=(int)_arrs.size())
173 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at (non const) : pos must be in [0,nbOfFields) !");
174 return _arrs[pos].first;
177 const DataArrayDouble *DataArrayDoubleCollection::at(int pos) const
179 if(pos<0 || pos>=(int)_arrs.size())
180 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at : pos must be in [0,nbOfFields) !");
181 return _arrs[pos].first;
184 int DataArrayDoubleCollection::size() const
186 return (int)_arrs.size();
189 void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
192 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
193 std::size_t sz(coarse->_arrs.size());
194 if(fine->_arrs.size()!=sz)
195 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
196 for(std::size_t i=0;i<sz;i++)
198 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
199 fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
203 void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
206 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
207 std::size_t sz(coarse->_arrs.size());
208 if(fine->_arrs.size()!=sz)
209 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
210 for(std::size_t i=0;i<sz;i++)
212 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
213 fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
217 void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
219 if(!fatherOfFineMesh)
220 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
221 std::size_t sz(children.size());
222 if(fieldsOnFine.size()!=sz)
223 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
226 std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
227 for(std::size_t i=0;i<sz;i++)
228 if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
229 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
230 for(std::size_t i=1;i<sz;i++)
231 if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
232 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
233 for(std::size_t i=0;i<nbOfCall;i++)
235 std::vector<const DataArrayDouble *> arrs(sz);
236 for(std::size_t j=0;j<sz;j++)
237 arrs[j]=fieldsOnFine[j]->_arrs[i].first;
238 fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
243 * 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).
245 void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac)
247 if(!p1 || !p1dac || !p2 || !p2dac)
248 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !");
249 std::size_t sz(p1dac->_arrs.size());
250 if(p2dac->_arrs.size()!=sz)
251 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !");
252 for(std::size_t i=0;i<sz;i++)
254 const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first);
255 DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second);
256 bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second));
257 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative);
261 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
264 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
265 std::size_t sz(coarse->_arrs.size());
266 if(fine->_arrs.size()!=sz)
267 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
268 for(std::size_t i=0;i<sz;i++)
269 fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev);
272 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
274 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
275 std::size_t sz(_arrs.size());
276 if(other._arrs.size()!=sz)
277 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
278 for(std::size_t i=0;i<sz;i++)
279 father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
282 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
284 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
285 std::size_t sz(_arrs.size());
286 if(other._arrs.size()!=sz)
287 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
288 for(std::size_t i=0;i<sz;i++)
289 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
292 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
294 std::size_t sz(fieldNames.size());
295 std::vector<std::string> names(sz);
296 for(std::size_t i=0;i<sz;i++)
298 const std::pair<std::string,int>& info(fieldNames[i]);
301 std::ostringstream oss; oss << "DataArrayDoubleCollection constructor : At pos #" << i << " the array with name \"" << info.first << "\" as a number of components equal to " << info.second;
302 oss << " It has to be >=1 !";
303 throw INTERP_KERNEL::Exception(oss.str().c_str());
305 _arrs[i].first=DataArrayDouble::New();
306 _arrs[i].first->alloc(0,info.second);
307 _arrs[i].first->setName(info.first);
308 names[i]=info.second;
309 _arrs[i].second=IntensiveMaximum;
311 CheckDiscriminantNames(names);
314 DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size())
316 std::size_t sz(other._arrs.size());
317 for(std::size_t i=0;i<sz;i++)
319 _arrs[i].second=other._arrs[i].second;
320 const DataArrayDouble *da(other._arrs[i].first);
322 _arrs[i].first=da->deepCopy();
326 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
328 std::size_t ret(sizeof(DataArrayDoubleCollection));
329 ret+=_arrs.capacity()*sizeof(MCAuto<DataArrayDouble>);
333 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildrenWithNull() const
335 std::vector<const BigMemoryObject *> ret;
336 for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
337 ret.push_back((const DataArrayDouble *)(*it).first);
341 void DataArrayDoubleCollection::updateTime() const
343 for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
345 const DataArrayDouble *pt((*it).first);
351 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
353 std::set<std::string> s(names.begin(),names.end());
354 if(s.size()!=names.size())
355 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
358 bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
361 return n==IntensiveConservation || n==ExtensiveConservation;
364 void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
366 CheckValidNature(n1);
367 CheckValidNature(n2);
369 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
372 void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
374 if(n!=IntensiveMaximum && n!=ExtensiveMaximum && n!=ExtensiveConservation && n!=IntensiveConservation)
375 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
378 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
380 return new MEDCouplingGridCollection(ms,fieldNames);
383 MEDCouplingGridCollection *MEDCouplingGridCollection::deepCopy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
385 return new MEDCouplingGridCollection(*this,newGf,oldGf);
388 void MEDCouplingGridCollection::alloc(int ghostLev)
390 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
392 int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
393 DataArrayDoubleCollection *dadc((*it).second);
395 dadc->allocTuples(nbTuples);
397 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
401 void MEDCouplingGridCollection::dealloc()
403 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
405 DataArrayDoubleCollection *dadc((*it).second);
407 dadc->dellocTuples();
409 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
413 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
415 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
416 (*it).second->spillInfoOnComponents(compNames);
419 void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
421 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
422 (*it).second->spillNatures(nfs);
425 std::vector< std::pair<std::string, std::vector<std::string> > > MEDCouplingGridCollection::getInfoOnComponents() const
427 if(_map_of_dadc.empty())
428 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !");
429 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
431 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !");
432 return elt->getInfoOnComponents();
435 std::vector<NatureOfField> MEDCouplingGridCollection::getNatures() const
437 if(_map_of_dadc.empty())
438 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !");
439 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
441 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !");
442 return elt->getNatures();
445 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
448 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
459 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
461 if(pos<0 || pos>(int)_map_of_dadc.size())
462 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
463 return *_map_of_dadc[pos].second;
466 DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos)
468 if(pos<0 || pos>(int)_map_of_dadc.size())
469 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !");
470 return *_map_of_dadc[pos].second;
474 * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting
475 * part of fields of \a this. The fields are expected to be the same between \a other and \a this.
476 * 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.
478 void MEDCouplingGridCollection::copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other)
480 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
482 std::vector<int> deltaThis,deltaOther;
483 std::vector< std::pair<int,int> > rgThis((*it).first->positionRelativeToGodFather(deltaThis));
484 std::vector<int> thisSt((*it).first->getImageMesh()->getCellGridStructure());
485 std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
486 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++)
488 std::vector< std::pair<int,int> > rgOther((*it2).first->positionRelativeToGodFather(deltaOther));
489 if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther))
491 std::vector< std::pair<int,int> > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther));
492 std::vector< std::pair<int,int> > pThis,pOther;
493 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true);
494 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true);
495 std::vector<int> otherSt((*it2).first->getImageMesh()->getCellGridStructure());
496 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev);
497 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev);
498 std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
499 int sz((*it2).second->size());
500 for(int i=0;i<sz;i++)
502 const DataArrayDouble *otherArr((*it2).second->at(i));
503 DataArrayDouble *thisArr((*it).second->at(i));
504 MCAuto<DataArrayDouble> partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther));
505 MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther);
512 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
515 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
516 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
517 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
518 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
520 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
521 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
523 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
525 if((*it0).first==fatherOfFineMesh)
528 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
529 const DataArrayDoubleCollection *coarseDaCol((*it0).second);
530 DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
531 DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
535 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
539 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
542 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
543 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
544 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
545 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
547 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
548 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
550 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
552 if((*it0).first==fatherOfFineMesh)
555 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
556 const DataArrayDoubleCollection *fineDaCol((*it).second);
557 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
558 DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
562 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
567 * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
569 * \sa synchronizeFineEachOtherExt
571 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
573 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
576 if(!presenceOf((*it).first->getMesh(),p1))
577 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
578 if(!presenceOf((*it).second->getMesh(),p2))
579 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
580 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
581 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
582 col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
587 * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
589 * \sa synchronizeFineEachOther
591 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
593 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
596 if(!presenceOf((*it).first->getMesh(),p1))
597 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
598 if(!presenceOf((*it).second->getMesh(),p2))
599 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
600 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
601 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
602 col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
607 * The pairs returned share the same direct father. The number of returned elements must be even.
609 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
611 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
612 std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
613 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
615 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
616 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
617 m[fatherOfFineMesh].push_back(fineMesh);
619 for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
621 for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
623 int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
624 std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
625 const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
626 for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
628 const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
629 ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
634 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
638 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
641 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
642 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
643 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
644 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
646 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
647 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
649 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
651 if((*it0).first==fatherOfFineMesh)
654 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
655 const DataArrayDoubleCollection *fineDaCol((*it).second);
656 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
657 DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
661 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
665 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
667 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
669 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
670 if(head==a || head->isObjectInTheProgeny(a))
672 const DataArrayDoubleCollection *gc((*it).second);
673 recurseArrs.push_back(gc->getFieldWithName(fieldName));
678 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
680 std::size_t sz(ms.size());
681 for(std::size_t i=0;i<sz;i++)
684 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
685 _map_of_dadc[i].first=ms[i];
686 _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
690 MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
692 std::size_t sz(other._map_of_dadc.size());
693 for(std::size_t i=0;i<sz;i++)
695 std::vector<int> pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf));
696 _map_of_dadc[i].first=newGf->getMeshAtPosition(pos);
697 const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
699 _map_of_dadc[i].second=dac->deepCopy();
703 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
705 std::size_t ret(sizeof(MEDCouplingGridCollection));
706 ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> >);
710 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildrenWithNull() const
712 std::vector<const BigMemoryObject *> ret;
713 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
714 ret.push_back((const DataArrayDoubleCollection *)(*it).second);
718 void MEDCouplingGridCollection::updateTime() const
720 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
722 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
725 const DataArrayDoubleCollection *b((*it).second);
733 MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather()
738 const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const
743 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
746 throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
750 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
755 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
757 bool ret(_tlc.keepTrackOfNewTL(gf));
767 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
769 other._tlc.checkConst();
772 const MEDCouplingCartesianAMRMesh *gf(other._gf);
775 _tlc.keepTrackOfNewTL(_gf);
780 * 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.
782 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
784 return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
787 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
789 std::size_t sz(fieldNames.size());
790 std::vector< std::pair<std::string,int> > fieldNames2(sz);
791 std::vector< std::vector<std::string> > compNames(sz);
792 for(std::size_t i=0;i<sz;i++)
794 fieldNames2[i].first=fieldNames[i].first;
795 fieldNames2[i].second=(int)fieldNames[i].second.size();
796 compNames[i]=fieldNames[i].second;
798 MCAuto<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
799 ret->spillInfoOnComponents(compNames);
804 * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
805 * 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.
806 * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
807 * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
809 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
812 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
813 (*it)->spillInfoOnComponents(compNames);
817 * Assign nature for each fields in \a this.
820 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
823 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
824 (*it)->spillNatures(nfs);
827 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCopy() const
829 return new MEDCouplingAMRAttribute(*this,true);
832 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const
834 return new MEDCouplingAMRAttribute(*this,false);
838 * 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).
841 int MEDCouplingAMRAttribute::getNumberOfLevels() const
843 checkGodFatherFrozen();
844 return (int)_levs.size();
848 * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
849 * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
851 * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
852 * \sa retrieveFieldOn
854 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
856 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
859 if((*it)->presenceOf(mesh,tmp))
861 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
862 return ddc.retrieveFields();
865 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
869 * \sa retrieveFieldsOn
871 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
873 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
876 if((*it)->presenceOf(mesh,tmp))
878 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
879 return ddc.getFieldWithName(fieldName);
882 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn : the mesh specified is not in the progeny of this !");
885 DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName)
887 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
890 if((*it)->presenceOf(mesh,tmp))
892 DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
893 return ddc.getFieldWithName(fieldName);
896 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn non const : the mesh specified is not in the progeny of this !");
900 * This method returns a field on an unstructured mesh the most refined as possible without overlap.
901 * Ghost part are not visible here.
903 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
905 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
907 std::vector<const DataArrayDouble *> recurseArrs;
909 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
912 if((*it)->presenceOf(mesh,tmp))
914 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
915 recurseArrs.push_back(ddc.getFieldWithName(fieldName));
920 for(std::size_t i=lev;i<_levs.size();i++)
922 const MEDCouplingGridCollection *gc(_levs[i]);
923 gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
925 return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
929 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
930 * The output field also displays ghost cells.
932 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
934 * \sa buildCellFieldOnWithoutGhost
936 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
938 const DataArrayDouble *arr(0);
939 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
942 if((*it)->presenceOf(mesh,tmp))
944 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
945 arr=ddc.getFieldWithName(fieldName);
949 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
950 MCAuto<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
951 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
953 ret->setArray(const_cast<DataArrayDouble *>(arr));
954 ret->setName(arr->getName());
959 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
960 * The output field does not display ghost cells.
962 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
964 * \sa buildCellFieldOnWithGhost
966 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
968 const DataArrayDouble *arr(0);
969 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
972 if((*it)->presenceOf(mesh,tmp))
974 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
975 arr=ddc.getFieldWithName(fieldName);
979 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
981 MCAuto<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
982 std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
983 MCAuto<DataArrayDouble> arr2(DataArrayDouble::New());
984 arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
985 std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
986 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
987 std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
988 MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
989 arr2->copyStringInfoFrom(*arr);
991 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
992 ret->setMesh(mesh->getImageMesh());
994 ret->setName(arr->getName());
999 std::string MEDCouplingAMRAttribute::writeVTHB(const std::string& fileName) const
1001 static const char EXT[]=".vthb";
1002 std::string baseName,extName,zeFileName;
1003 MEDCouplingMesh::SplitExtension(fileName,baseName,extName);
1005 zeFileName=fileName;
1007 { zeFileName=baseName; zeFileName+=EXT; }
1009 std::ofstream ofs(fileName.c_str());
1010 ofs << "<VTKFile type=\"vtkOverlappingAMR\" version=\"1.1\" byte_order=\"" << MEDCouplingByteOrderStr() << "\">\n";
1011 const MEDCouplingCartesianAMRMesh *gf(getMyGodFather());
1012 ofs << " <vtkOverlappingAMR origin=\"";
1013 const MEDCouplingIMesh *gfm(gf->getImageMesh());
1014 std::vector<double> orig(gfm->getOrigin());
1015 std::vector<double> spacing(gfm->getDXYZ());
1016 int dim((int)orig.size());
1017 std::copy(orig.begin(),orig.end(),std::ostream_iterator<double>(ofs," ")); ofs << "\" grid_description=\"";
1018 for(int i=0;i<dim;i++)
1020 char tmp[2]; tmp[0]='X'+i; tmp[1]='\0';
1025 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()),kk(0);
1026 for(int i=0;i<maxLev;i++)
1028 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1029 std::size_t sz(patches.size());
1030 std::vector< MCAuto<MEDCouplingCartesianAMRPatchGen> > patchesSafe(sz);
1031 for(std::size_t j=0;j<sz;j++)
1032 patchesSafe[j]=patches[j];
1035 ofs << " <Block level=\"" << i << "\" spacing=\"";
1036 std::copy(spacing.begin(),spacing.end(),std::ostream_iterator<double>(ofs," "));
1040 std::vector<int> factors(patches[0]->getMesh()->getFactors());
1041 for(int k=0;k<dim;k++)
1042 spacing[k]*=1./((double) factors[k]);
1045 for(std::vector<MEDCouplingCartesianAMRPatchGen *>::const_iterator it=patches.begin();it!=patches.end();it++,jj++,kk++)
1047 ofs << " <DataSet index=\"" << jj << "\" amr_box=\"";
1048 const MEDCouplingCartesianAMRPatch *patchCast(dynamic_cast<const MEDCouplingCartesianAMRPatch *>(*it));
1049 const MEDCouplingCartesianAMRMeshGen *mesh((*it)->getMesh());
1052 const std::vector< std::pair<int,int> >& bltr(patchCast->getBLTRRangeRelativeToGF());
1053 for(int pp=0;pp<dim;pp++)
1054 ofs << bltr[pp].first << " " << bltr[pp].second-1 << " ";
1058 const MEDCouplingIMesh *im((*it)->getMesh()->getImageMesh());
1059 std::vector<int> cgs(im->getCellGridStructure());
1060 for(int pp=0;pp<dim;pp++)
1061 ofs << "0 " << cgs[pp]-1 << " ";
1063 ofs << "\" file=\"";
1066 if(_levs[i]->presenceOf((*it)->getMesh(),tmp))
1068 const DataArrayDoubleCollection& ddc(_levs[i]->getFieldsAt(tmp));
1069 std::vector<DataArrayDouble *> arrs(ddc.retrieveFields());
1070 std::size_t nbFields(arrs.size());
1071 std::vector< MCAuto<DataArrayDouble> > arrsSafe(nbFields),arrs2Safe(nbFields);
1072 std::vector< const MEDCouplingFieldDouble *> fields(nbFields);
1073 std::vector< MCAuto<MEDCouplingFieldDouble> > fieldsSafe(nbFields);
1074 for(std::size_t pp=0;pp<nbFields;pp++)
1075 arrsSafe[pp]=arrs[pp];
1076 for(std::size_t pp=0;pp<nbFields;pp++)
1078 MCAuto<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
1079 std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
1080 arrs2Safe[pp]=DataArrayDouble::New();
1081 arrs2Safe[pp]->alloc(mesh->getImageMesh()->getNumberOfCells(),arrs[pp]->getNumberOfComponents());
1082 std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
1083 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
1084 std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
1085 MEDCouplingIMesh::SpreadCoarseToFine(arrs[pp],cgsWG,arrs2Safe[pp],cgs2,fakeFactors);
1086 arrs2Safe[pp]->copyStringInfoFrom(*arrs[pp]);
1088 fieldsSafe[pp]=MEDCouplingFieldDouble::New(ON_CELLS); fields[pp]=fieldsSafe[pp];
1089 fieldsSafe[pp]->setMesh(mesh->getImageMesh());
1090 fieldsSafe[pp]->setArray(arrs2Safe[pp]);
1091 fieldsSafe[pp]->setName(arrs[pp]->getName());
1093 std::ostringstream vtiFileName; vtiFileName << baseName << "_" << kk << ".vti";
1094 MEDCouplingFieldDouble::WriteVTK(vtiFileName.str(),fields,true);
1096 ofs << vtiFileName.str() << "\">\n";
1097 ofs << " \n </DataSet>\n";
1100 ofs << " </Block>\n";
1103 ofs << " </vtkOverlappingAMR>\n";
1104 ofs << "</VTKFile>\n";
1109 * This method is useful just after a remesh after a time step computation to project values in \a this to the new
1112 * This method performs a projection from \a this to a target AMR mesh \a targetGF.
1113 * This method performs the projection by trying to transfer the finest information to \a targetGF.
1114 * \b WARNING this method does not update the ghost zone, if any.
1115 * The level0 of \a this god father must have the same structure than those of \a targetGF.
1117 * This method makes checks that ghost size of \a this and \a targetGF are the same, and that
1118 * the number of levels in \a this and in \a targetGF are also the same.
1120 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const
1123 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !");
1125 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !");
1126 const MEDCouplingGridCollection *lev0(_levs[0]);
1128 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !");
1129 std::vector< std::pair < std::string, std::vector<std::string> > > fieldNames(lev0->getInfoOnComponents());
1130 MCAuto<MEDCouplingAMRAttribute> ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev));
1131 ret->spillNatures(lev0->getNatures());
1133 int nbLevs(getNumberOfLevels());
1134 if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs)
1135 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !");
1136 // first step copy level0
1137 if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure())
1138 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !");
1139 const DataArrayDoubleCollection& col(lev0->getFieldsAt(0));
1140 DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0));
1141 colTarget.copyFrom(col);
1142 // then go deeper and deeper
1143 for(int i=1;i<nbLevs;i++)
1145 ret->synchronizeCoarseToFineByOneLevel(i-1);
1146 MEDCouplingGridCollection *targetCol(ret->_levs[i]);
1148 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !");
1149 const MEDCouplingGridCollection *thisCol(_levs[i]);
1151 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !");
1152 targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol);
1158 * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
1159 * MEDCouplingAMRAttribute::alloc method.
1160 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse)
1162 * \sa synchronizeFineToCoarseBetween
1164 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
1167 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
1168 std::size_t sz(_levs.size());
1173 synchronizeFineToCoarseByOneLevel((int)sz);
1178 * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
1179 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
1180 * until reaching \a toLev level.
1181 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse).
1183 * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
1184 * \param [in] toLev - an existing level considered as the target level to reach.
1187 void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
1189 int nbl(getNumberOfLevels());
1190 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1191 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1193 return ;//nothing to do
1195 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
1196 for(int i=fromLev;i>toLev;i--)
1197 synchronizeFineToCoarseByOneLevel(i);
1201 * 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
1202 * MEDCouplingAMRAttribute::alloc method.
1203 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method)
1205 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
1208 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
1209 std::size_t sz(_levs.size());
1211 for(std::size_t i=0;i<sz-1;i++)
1212 synchronizeCoarseToFineByOneLevel((int)i);
1216 * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
1217 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
1218 * until reaching \a toLev level.
1219 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarseBetween method)
1221 * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
1222 * \param [in] toLev - an existing level considered as the target level to reach.
1224 void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
1226 int nbl(getNumberOfLevels());
1227 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1228 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1230 return ;//nothing to do
1232 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
1233 for(int i=fromLev;i<toLev;i++)
1234 synchronizeCoarseToFineByOneLevel(i);
1238 * This method synchronizes the ghost zone of all patches (excepted the god father one).
1239 * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
1241 * - firstly coarse to fine with no interactions between brother patches.
1242 * - secondly connected brother patches in a same master patch are updated.
1243 * - thirdly connected nephew patches are updated each other.
1244 * - forthly nth generation cousin patches are updated each other.
1246 * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
1247 * So if \a _ghost_lev == 0 this method has no effect.
1249 void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
1251 int sz(getNumberOfLevels());
1253 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
1254 // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
1255 for(int i=1;i<sz;i++)
1257 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
1258 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1260 // 2nd - classical direct sublevel inside common patch
1261 for(int i=1;i<sz;i++)
1263 const MEDCouplingGridCollection *curLev(_levs[i]);
1265 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
1266 curLev->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
1268 // 3rd - mixed level
1269 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
1271 const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
1272 DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
1274 // 4th - same level but with far ancestor.
1275 for(int i=1;i<sz;i++)
1277 const MEDCouplingGridCollection *fine(_levs[i]);
1278 fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
1283 * 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.
1284 * 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).
1285 * 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.
1286 * 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.
1288 * \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.
1291 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh)
1294 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !");
1295 int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels());
1296 if(level<0 || level>=sz-1)
1297 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !");
1298 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& itemsToFilter(_neighbors[level+1]);
1299 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > itemsToSync; itemsToSync.reserve(itemsToFilter.size());
1300 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++)
1302 if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh)
1303 itemsToSync.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>((*it).first,(*it).second));
1305 const MEDCouplingGridCollection *curLev(_levs[level+1]);
1307 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !");
1308 curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync);
1312 * This method updates \b all the patches at level \a level each other without consideration of their father.
1313 * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf.
1315 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level)
1317 int maxLev(getNumberOfLevels());
1318 if(level<0 || level>=maxLev)
1319 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !");
1321 return ;//at level 0 only one patch -> no need to update
1322 // 1st step - updates all patches pairs at level \a level sharing the same father
1323 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items(_neighbors[level]);
1324 const MEDCouplingGridCollection *curLev(_levs[level]);
1326 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !");
1327 curLev->synchronizeFineEachOther(_ghost_lev,items);
1328 //2nd step - updates all patches pairs at level \a level not sharing the same father
1329 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items2(_cross_lev_neighbors[level]);
1330 curLev->synchronizeFineEachOtherExt(_ghost_lev,items2);
1334 * 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).
1335 * This method is useful to propagate to the ghost zone of childhood the modification.
1337 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level)
1339 int maxLev(getNumberOfLevels());
1340 if(level<=0 || level>=maxLev)
1341 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !");
1342 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1343 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1344 //_cross_lev_neighbors is not needed.
1348 * This method allocates all DataArrayDouble instances stored recursively in \a this.
1352 void MEDCouplingAMRAttribute::alloc()
1355 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1357 MEDCouplingGridCollection *elt(*it);
1359 elt->alloc(_ghost_lev);
1361 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
1366 * This method deallocates all DataArrayDouble instances stored recursively in \a this.
1369 void MEDCouplingAMRAttribute::dealloc()
1372 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1374 MEDCouplingGridCollection *elt(*it);
1378 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
1382 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
1384 bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
1388 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
1390 std::size_t ret(sizeof(MEDCouplingAMRAttribute));
1391 ret+=_levs.capacity()*sizeof(MCAuto<MEDCouplingGridCollection>);
1395 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildrenWithNull() const
1397 std::vector<const BigMemoryObject *> ret;
1398 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1399 ret.push_back((const MEDCouplingGridCollection *)*it);
1403 void MEDCouplingAMRAttribute::updateTime() const
1407 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
1409 //gf non empty, checked by constructor
1410 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
1411 _levs.resize(maxLev);
1412 for(int i=0;i<maxLev;i++)
1414 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1415 std::size_t sz(patches.size());
1416 std::vector< MCAuto<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
1417 for(std::size_t j=0;j<sz;j++)
1418 patchesSafe[j]=patches[j];
1419 std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
1420 for(std::size_t j=0;j<sz;j++)
1422 ms[j]=patches[j]->getMesh();
1424 _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
1426 // updates cross levels neighbors
1427 _neighbors.resize(_levs.size());
1428 _cross_lev_neighbors.resize(_levs.size());
1430 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
1431 std::size_t sz(_levs.size());
1432 for(std::size_t i=1;i<sz;i++)
1434 const MEDCouplingGridCollection *fine(_levs[i]);
1436 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
1437 _neighbors[i]=fine->findNeighbors(_ghost_lev);
1440 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
1442 MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
1443 std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
1444 std::size_t fullLev(i+neighs2.size());
1446 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
1447 std::size_t ii(i+1);
1448 for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
1449 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
1455 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)
1457 std::size_t sz(other._levs.size());
1458 for(std::size_t i=0;i<sz;i++)
1460 const MEDCouplingGridCollection *elt(other._levs[i]);
1463 _levs[i]=other._levs[i]->deepCopy(_gf,other._gf);
1466 //_cross_lev_neighbors(other._cross_lev_neighbors)
1467 sz=other._neighbors.size();
1468 for(std::size_t i=0;i<sz;i++)
1470 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._neighbors[i]);
1471 std::size_t sz2(neigh2.size());
1472 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_neighbors[i]);
1473 for(std::size_t j=0;j<sz2;j++)
1475 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1476 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1477 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1478 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1482 sz=other._mixed_lev_neighbors.size();
1483 for(std::size_t i=0;i<sz;i++)
1485 const MEDCouplingCartesianAMRPatch *p1(other._mixed_lev_neighbors[i].first),*p2(other._mixed_lev_neighbors[i].second);
1486 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1487 _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1);
1488 _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2);
1491 sz=other._cross_lev_neighbors.size();
1492 for(std::size_t i=0;i<sz;i++)
1494 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._cross_lev_neighbors[i]);
1495 std::size_t sz2(neigh2.size());
1496 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_cross_lev_neighbors[i]);
1497 for(std::size_t j=0;j<sz2;j++)
1499 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1500 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1501 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1502 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1507 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
1509 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1511 const MEDCouplingGridCollection *elt(*it);
1515 if(elt->presenceOf(m,tmp))
1517 return elt->getFieldsAt(tmp);
1521 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
1524 void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
1526 int nbl(getNumberOfLevels());
1527 if(level<=0 || level>=nbl)
1528 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
1529 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1530 MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
1533 void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
1535 int nbl(getNumberOfLevels());
1536 if(level<0 || level>=nbl-1)
1537 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
1538 const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
1539 MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);