1 // Copyright (C) 2007-2014 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"
28 using namespace ParaMEDMEM;
30 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
32 return new DataArrayDoubleCollection(fieldNames);
35 DataArrayDoubleCollection *DataArrayDoubleCollection::deepCpy() const
37 return new DataArrayDoubleCollection(*this);
40 void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
42 std::size_t sz(_arrs.size());
43 for(std::size_t i=0;i<sz;i++)
44 _arrs[i].first->reAlloc(nbOfTuples);
47 void DataArrayDoubleCollection::dellocTuples()
49 std::size_t sz(_arrs.size());
50 for(std::size_t i=0;i<sz;i++)
51 _arrs[i].first->reAlloc(0);
54 void DataArrayDoubleCollection::copyFrom(const DataArrayDoubleCollection& other)
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++)
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);
69 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
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++)
76 const std::vector<std::string>& names(compNames[i]);
77 _arrs[i].first->setInfoOnComponents(names);
81 void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& nfs)
83 std::size_t sz(_arrs.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++)
88 CheckValidNature(nfs[i]);
89 _arrs[i].second=nfs[i];
93 std::vector< std::pair < std::string, std::vector<std::string> > > DataArrayDoubleCollection::getInfoOnComponents() const
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++)
99 const DataArrayDouble *elt(_arrs[i].first);
101 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::getInfoOnComponents : empty array !");
102 ret[i]=std::pair < std::string, std::vector<std::string> >(elt->getName(),elt->getInfoOnComponents());
107 std::vector<NatureOfField> DataArrayDoubleCollection::getNatures() const
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;
116 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
118 std::size_t sz(_arrs.size());
119 std::vector<DataArrayDouble *> ret(sz);
120 for(std::size_t i=0;i<sz;i++)
122 const DataArrayDouble *tmp(_arrs[i].first);
123 ret[i]=const_cast<DataArrayDouble *>(tmp);
130 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
132 std::vector<std::string> vec;
133 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
135 const DataArrayDouble *obj((*it).first);
138 if(obj->getName()==name)
141 vec.push_back(obj->getName());
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());
149 DataArrayDouble *DataArrayDoubleCollection::at(int pos)
151 if(pos<0 || pos>=(int)_arrs.size())
152 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at (non const) : pos must be in [0,nbOfFields) !");
153 return _arrs[pos].first;
156 const DataArrayDouble *DataArrayDoubleCollection::at(int pos) const
158 if(pos<0 || pos>=(int)_arrs.size())
159 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at : pos must be in [0,nbOfFields) !");
160 return _arrs[pos].first;
163 int DataArrayDoubleCollection::size() const
165 return (int)_arrs.size();
168 void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
171 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
172 std::size_t sz(coarse->_arrs.size());
173 if(fine->_arrs.size()!=sz)
174 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
175 for(std::size_t i=0;i<sz;i++)
177 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
178 fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
182 void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
185 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
186 std::size_t sz(coarse->_arrs.size());
187 if(fine->_arrs.size()!=sz)
188 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
189 for(std::size_t i=0;i<sz;i++)
191 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
192 fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
196 void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
198 if(!fatherOfFineMesh)
199 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
200 std::size_t sz(children.size());
201 if(fieldsOnFine.size()!=sz)
202 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
205 std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
206 for(std::size_t i=0;i<sz;i++)
207 if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
208 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
209 for(std::size_t i=1;i<sz;i++)
210 if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
211 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
212 for(std::size_t i=0;i<nbOfCall;i++)
214 std::vector<const DataArrayDouble *> arrs(sz);
215 for(std::size_t j=0;j<sz;j++)
216 arrs[j]=fieldsOnFine[j]->_arrs[i].first;
217 fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
222 * 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).
224 void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac)
226 if(!p1 || !p1dac || !p2 || !p2dac)
227 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !");
228 std::size_t sz(p1dac->_arrs.size());
229 if(p2dac->_arrs.size()!=sz)
230 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !");
231 for(std::size_t i=0;i<sz;i++)
233 const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first);
234 DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second);
235 bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second));
236 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative);
240 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
243 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
244 std::size_t sz(coarse->_arrs.size());
245 if(fine->_arrs.size()!=sz)
246 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
247 for(std::size_t i=0;i<sz;i++)
248 fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev);
251 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
253 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
254 std::size_t sz(_arrs.size());
255 if(other._arrs.size()!=sz)
256 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
257 for(std::size_t i=0;i<sz;i++)
258 father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
261 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
263 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
264 std::size_t sz(_arrs.size());
265 if(other._arrs.size()!=sz)
266 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
267 for(std::size_t i=0;i<sz;i++)
268 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
271 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
273 std::size_t sz(fieldNames.size());
274 std::vector<std::string> names(sz);
275 for(std::size_t i=0;i<sz;i++)
277 const std::pair<std::string,int>& info(fieldNames[i]);
278 _arrs[i].first=DataArrayDouble::New();
279 _arrs[i].first->alloc(0,info.second);
280 _arrs[i].first->setName(info.first);
281 names[i]=info.second;
282 _arrs[i].second=ConservativeVolumic;
284 CheckDiscriminantNames(names);
287 DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size())
289 std::size_t sz(other._arrs.size());
290 for(std::size_t i=0;i<sz;i++)
292 _arrs[i].second=other._arrs[i].second;
293 const DataArrayDouble *da(other._arrs[i].first);
295 _arrs[i].first=da->deepCpy();
299 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
301 std::size_t ret(sizeof(DataArrayDoubleCollection));
302 ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
306 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
308 std::vector<const BigMemoryObject *> ret;
309 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
311 const DataArrayDouble *pt((*it).first);
318 void DataArrayDoubleCollection::updateTime() const
320 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
322 const DataArrayDouble *pt((*it).first);
328 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
330 std::set<std::string> s(names.begin(),names.end());
331 if(s.size()!=names.size())
332 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
335 bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
338 return n==RevIntegral || n==IntegralGlobConstraint;
341 void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
343 CheckValidNature(n1);
344 CheckValidNature(n2);
346 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
349 void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
351 if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral)
352 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
355 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
357 return new MEDCouplingGridCollection(ms,fieldNames);
360 MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
362 return new MEDCouplingGridCollection(*this,newGf,oldGf);
365 void MEDCouplingGridCollection::alloc(int ghostLev)
367 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
369 int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
370 DataArrayDoubleCollection *dadc((*it).second);
372 dadc->allocTuples(nbTuples);
374 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
378 void MEDCouplingGridCollection::dealloc()
380 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
382 DataArrayDoubleCollection *dadc((*it).second);
384 dadc->dellocTuples();
386 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
390 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
392 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
393 (*it).second->spillInfoOnComponents(compNames);
396 void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
398 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
399 (*it).second->spillNatures(nfs);
402 std::vector< std::pair<std::string, std::vector<std::string> > > MEDCouplingGridCollection::getInfoOnComponents() const
404 if(_map_of_dadc.empty())
405 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !");
406 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
408 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !");
409 return elt->getInfoOnComponents();
412 std::vector<NatureOfField> MEDCouplingGridCollection::getNatures() const
414 if(_map_of_dadc.empty())
415 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !");
416 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
418 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !");
419 return elt->getNatures();
422 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
425 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
436 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
438 if(pos<0 || pos>(int)_map_of_dadc.size())
439 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
440 return *_map_of_dadc[pos].second;
443 DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos)
445 if(pos<0 || pos>(int)_map_of_dadc.size())
446 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !");
447 return *_map_of_dadc[pos].second;
451 * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting
452 * part of fields of \a this. The fields are expected to be the same between \a other and \a this.
453 * 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.
455 void MEDCouplingGridCollection::copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other)
457 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
459 std::vector<int> deltaThis,deltaOther;
460 std::vector< std::pair<int,int> > rgThis((*it).first->positionRelativeToGodFather(deltaThis));
461 std::vector<int> thisSt((*it).first->getImageMesh()->getCellGridStructure());
462 std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
463 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++)
465 std::vector< std::pair<int,int> > rgOther((*it2).first->positionRelativeToGodFather(deltaOther));
466 if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther))
468 std::vector< std::pair<int,int> > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther));
469 std::vector< std::pair<int,int> > pThis,pOther;
470 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true);
471 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true);
472 std::vector<int> otherSt((*it2).first->getImageMesh()->getCellGridStructure());
473 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev);
474 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev);
475 std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
476 int sz((*it2).second->size());
477 for(int i=0;i<sz;i++)
479 const DataArrayDouble *otherArr((*it2).second->at(i));
480 DataArrayDouble *thisArr((*it).second->at(i));
481 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther));
482 MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther);
489 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
492 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
493 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
494 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
495 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
497 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
498 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
500 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
502 if((*it0).first==fatherOfFineMesh)
505 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
506 const DataArrayDoubleCollection *coarseDaCol((*it0).second);
507 DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
508 DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
512 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
516 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
519 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
520 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
521 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
522 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
524 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
525 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
527 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
529 if((*it0).first==fatherOfFineMesh)
532 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
533 const DataArrayDoubleCollection *fineDaCol((*it).second);
534 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
535 DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
539 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
544 * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
546 * \sa synchronizeFineEachOtherExt
548 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
550 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
553 if(!presenceOf((*it).first->getMesh(),p1))
554 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
555 if(!presenceOf((*it).second->getMesh(),p2))
556 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
557 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
558 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
559 col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
564 * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
566 * \sa synchronizeFineEachOther
568 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
570 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
573 if(!presenceOf((*it).first->getMesh(),p1))
574 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
575 if(!presenceOf((*it).second->getMesh(),p2))
576 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
577 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
578 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
579 col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
584 * The pairs returned share the same direct father. The number of returned elements must be even.
586 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
588 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
589 std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
590 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
592 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
593 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
594 m[fatherOfFineMesh].push_back(fineMesh);
596 for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
598 for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
600 int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
601 std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
602 const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
603 for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
605 const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
606 ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
611 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
615 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
618 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
619 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
620 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
621 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
623 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
624 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
626 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
628 if((*it0).first==fatherOfFineMesh)
631 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
632 const DataArrayDoubleCollection *fineDaCol((*it).second);
633 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
634 DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
638 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
642 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
644 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
646 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
647 if(head==a || head->isObjectInTheProgeny(a))
649 const DataArrayDoubleCollection *gc((*it).second);
650 recurseArrs.push_back(gc->getFieldWithName(fieldName));
655 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
657 std::size_t sz(ms.size());
658 for(std::size_t i=0;i<sz;i++)
661 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
662 _map_of_dadc[i].first=ms[i];
663 _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
667 MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
669 std::size_t sz(other._map_of_dadc.size());
670 for(std::size_t i=0;i<sz;i++)
672 std::vector<int> pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf));
673 _map_of_dadc[i].first=newGf->getMeshAtPosition(pos);
674 const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
676 _map_of_dadc[i].second=dac->deepCpy();
680 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
682 std::size_t ret(sizeof(MEDCouplingGridCollection));
683 ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
687 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
689 std::vector<const BigMemoryObject *> ret;
690 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
692 const DataArrayDoubleCollection *col((*it).second);
699 void MEDCouplingGridCollection::updateTime() const
701 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
703 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
706 const DataArrayDoubleCollection *b((*it).second);
712 MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather()
717 const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const
722 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
725 throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
729 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
734 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
736 bool ret(_tlc.keepTrackOfNewTL(gf));
746 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
748 other._tlc.checkConst();
751 const MEDCouplingCartesianAMRMesh *gf(other._gf);
754 _tlc.keepTrackOfNewTL(_gf);
759 * 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.
761 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
763 return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
766 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
768 std::size_t sz(fieldNames.size());
769 std::vector< std::pair<std::string,int> > fieldNames2(sz);
770 std::vector< std::vector<std::string> > compNames(sz);
771 for(std::size_t i=0;i<sz;i++)
773 fieldNames2[i].first=fieldNames[i].first;
774 fieldNames2[i].second=(int)fieldNames[i].second.size();
775 compNames[i]=fieldNames[i].second;
777 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
778 ret->spillInfoOnComponents(compNames);
783 * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
784 * 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.
785 * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
786 * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
788 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
791 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
792 (*it)->spillInfoOnComponents(compNames);
796 * Assign nature for each fields in \a this.
799 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
802 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
803 (*it)->spillNatures(nfs);
806 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const
808 return new MEDCouplingAMRAttribute(*this,true);
811 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const
813 return new MEDCouplingAMRAttribute(*this,false);
817 * 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).
820 int MEDCouplingAMRAttribute::getNumberOfLevels() const
822 checkGodFatherFrozen();
823 return (int)_levs.size();
827 * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
828 * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
830 * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
831 * \sa retrieveFieldOn
833 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
835 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
838 if((*it)->presenceOf(mesh,tmp))
840 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
841 return ddc.retrieveFields();
844 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
848 * \sa retrieveFieldsOn
850 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
852 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
855 if((*it)->presenceOf(mesh,tmp))
857 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
858 return ddc.getFieldWithName(fieldName);
861 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldOn : the mesh specified is not in the progeny of this !");
865 * This method returns a field on an unstructured mesh the most refined as possible without overlap.
866 * Ghost part are not visible here.
868 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
870 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
872 std::vector<const DataArrayDouble *> recurseArrs;
874 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
877 if((*it)->presenceOf(mesh,tmp))
879 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
880 recurseArrs.push_back(ddc.getFieldWithName(fieldName));
885 for(std::size_t i=lev;i<_levs.size();i++)
887 const MEDCouplingGridCollection *gc(_levs[i]);
888 gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
890 return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
894 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
895 * The output field also displays ghost cells.
897 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
899 * \sa buildCellFieldOnWithoutGhost
901 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
903 const DataArrayDouble *arr(0);
904 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
907 if((*it)->presenceOf(mesh,tmp))
909 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
910 arr=ddc.getFieldWithName(fieldName);
914 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
915 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
916 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
918 ret->setArray(const_cast<DataArrayDouble *>(arr));
919 ret->setName(arr->getName());
924 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
925 * The output field does not display ghost cells.
927 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
929 * \sa buildCellFieldOnWithGhost
931 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
934 const DataArrayDouble *arr(0);
935 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
938 if((*it)->presenceOf(mesh,tmp))
940 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
941 arr=ddc.getFieldWithName(fieldName);
945 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
947 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
948 std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
949 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New());
950 arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
951 std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
952 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
953 std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
954 MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
955 arr2->copyStringInfoFrom(*arr);
957 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
958 ret->setMesh(mesh->getImageMesh());
960 ret->setName(arr->getName());
965 * This method is useful just after a remesh after a time step computation to project values in \a this to the new
968 * This method performs a projection from \a this to a target AMR mesh \a targetGF.
969 * This method performs the projection by trying to transfer the finest information to \a targetGF.
970 * \b WARNING this method does not update the ghost zone, if any.
971 * The level0 of \a this god father must have the same structure than those of \a targetGF.
973 * This method makes checks that ghost size of \a this and \a targetGF are the same, and that
974 * the number of levels in \a this and in \a targetGF are also the same.
976 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const
979 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !");
981 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !");
982 const MEDCouplingGridCollection *lev0(_levs[0]);
984 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !");
985 std::vector< std::pair < std::string, std::vector<std::string> > > fieldNames(lev0->getInfoOnComponents());
986 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev));
987 ret->spillNatures(lev0->getNatures());
989 int nbLevs(getNumberOfLevels());
990 if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs)
991 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !");
992 // first step copy level0
993 if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure())
994 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !");
995 const DataArrayDoubleCollection& col(lev0->getFieldsAt(0));
996 DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0));
997 colTarget.copyFrom(col);
998 // then go deeper and deeper
999 for(int i=1;i<nbLevs;i++)
1001 ret->synchronizeCoarseToFineByOneLevel(i-1);
1002 MEDCouplingGridCollection *targetCol(ret->_levs[i]);
1004 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !");
1005 const MEDCouplingGridCollection *thisCol(_levs[i]);
1007 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !");
1008 targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol);
1014 * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
1015 * MEDCouplingAMRAttribute::alloc method.
1016 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse)
1018 * \sa synchronizeFineToCoarseBetween
1020 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
1023 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
1024 std::size_t sz(_levs.size());
1029 synchronizeFineToCoarseByOneLevel((int)sz);
1034 * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
1035 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
1036 * until reaching \a toLev level.
1037 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse).
1039 * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
1040 * \param [in] toLev - an existing level considered as the target level to reach.
1043 void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
1045 int nbl(getNumberOfLevels());
1046 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1047 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1049 return ;//nothing to do
1051 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
1052 for(int i=fromLev;i>toLev;i--)
1053 synchronizeFineToCoarseByOneLevel(i);
1057 * 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
1058 * MEDCouplingAMRAttribute::alloc method.
1059 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method)
1061 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
1064 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
1065 std::size_t sz(_levs.size());
1067 for(std::size_t i=0;i<sz-1;i++)
1068 synchronizeCoarseToFineByOneLevel((int)i);
1072 * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
1073 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
1074 * until reaching \a toLev level.
1075 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarseBetween method)
1077 * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
1078 * \param [in] toLev - an existing level considered as the target level to reach.
1080 void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
1082 int nbl(getNumberOfLevels());
1083 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1084 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1086 return ;//nothing to do
1088 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
1089 for(int i=fromLev;i<toLev;i++)
1090 synchronizeCoarseToFineByOneLevel(i);
1094 * This method synchronizes the ghost zone of all patches (excepted the god father one).
1095 * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
1097 * - firstly coarse to fine with no interactions between brother patches.
1098 * - secondly connected brother patches in a same master patch are updated.
1099 * - thirdly connected nephew patches are updated each other.
1100 * - forthly nth generation cousin patches are updated each other.
1102 * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
1103 * So if \a _ghost_lev == 0 this method has no effect.
1105 void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
1107 int sz(getNumberOfLevels());
1109 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
1110 // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
1111 for(int i=1;i<sz;i++)
1113 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
1114 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1116 // 2nd - classical direct sublevel inside common patch
1117 for(int i=1;i<sz;i++)
1119 const MEDCouplingGridCollection *curLev(_levs[i]);
1121 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
1122 curLev->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
1124 // 3rd - mixed level
1125 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
1127 const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
1128 DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
1130 // 4th - same level but with far ancestor.
1131 for(int i=1;i<sz;i++)
1133 const MEDCouplingGridCollection *fine(_levs[i]);
1134 fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
1139 * 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.
1140 * 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).
1141 * 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.
1142 * 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.
1144 * \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.
1147 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh)
1150 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !");
1151 int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels());
1152 if(level<0 || level>=sz-1)
1153 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !");
1154 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& itemsToFilter(_neighbors[level+1]);
1155 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > itemsToSync; itemsToSync.reserve(itemsToFilter.size());
1156 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++)
1158 if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh)
1159 itemsToSync.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>((*it).first,(*it).second));
1161 const MEDCouplingGridCollection *curLev(_levs[level+1]);
1163 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !");
1164 curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync);
1168 * This method updates \b all the patches at level \a level each other without consideration of their father.
1169 * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf.
1171 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level)
1173 int maxLev(getNumberOfLevels());
1174 if(level<0 || level>=maxLev)
1175 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !");
1177 return ;//at level 0 only one patch -> no need to update
1178 // 1st step - updates all patches pairs at level \a level sharing the same father
1179 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items(_neighbors[level]);
1180 const MEDCouplingGridCollection *curLev(_levs[level]);
1182 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !");
1183 curLev->synchronizeFineEachOther(_ghost_lev,items);
1184 //2nd step - updates all patches pairs at level \a level not sharing the same father
1185 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items2(_cross_lev_neighbors[level]);
1186 curLev->synchronizeFineEachOtherExt(_ghost_lev,items2);
1190 * 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).
1191 * This method is useful to propagate to the ghost zone of childhood the modification.
1193 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level)
1195 int maxLev(getNumberOfLevels());
1196 if(level<=0 || level>=maxLev)
1197 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !");
1198 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1199 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1200 //_cross_lev_neighbors is not needed.
1204 * This method allocates all DataArrayDouble instances stored recursively in \a this.
1208 void MEDCouplingAMRAttribute::alloc()
1211 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1213 MEDCouplingGridCollection *elt(*it);
1215 elt->alloc(_ghost_lev);
1217 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
1222 * This method deallocates all DataArrayDouble instances stored recursively in \a this.
1225 void MEDCouplingAMRAttribute::dealloc()
1228 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1230 MEDCouplingGridCollection *elt(*it);
1234 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
1238 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
1240 bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
1244 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
1246 std::size_t ret(sizeof(MEDCouplingAMRAttribute));
1247 ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
1251 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
1253 std::vector<const BigMemoryObject *> ret;
1254 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1256 const MEDCouplingGridCollection *elt(*it);
1263 void MEDCouplingAMRAttribute::updateTime() const
1267 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
1269 //gf non empty, checked by constructor
1270 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
1271 _levs.resize(maxLev);
1272 for(int i=0;i<maxLev;i++)
1274 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1275 std::size_t sz(patches.size());
1276 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
1277 for(std::size_t j=0;j<sz;j++)
1278 patchesSafe[j]=patches[j];
1279 std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
1280 for(std::size_t j=0;j<sz;j++)
1282 ms[j]=patches[j]->getMesh();
1284 _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
1286 // updates cross levels neighbors
1287 _neighbors.resize(_levs.size());
1288 _cross_lev_neighbors.resize(_levs.size());
1290 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
1291 std::size_t sz(_levs.size());
1292 for(std::size_t i=1;i<sz;i++)
1294 const MEDCouplingGridCollection *fine(_levs[i]);
1296 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
1297 _neighbors[i]=fine->findNeighbors(_ghost_lev);
1300 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
1302 MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
1303 std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
1304 std::size_t fullLev(i+neighs2.size());
1306 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
1307 std::size_t ii(i+1);
1308 for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
1309 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
1315 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)
1317 std::size_t sz(other._levs.size());
1318 for(std::size_t i=0;i<sz;i++)
1320 const MEDCouplingGridCollection *elt(other._levs[i]);
1323 _levs[i]=other._levs[i]->deepCpy(_gf,other._gf);
1326 //_cross_lev_neighbors(other._cross_lev_neighbors)
1327 sz=other._neighbors.size();
1328 for(std::size_t i=0;i<sz;i++)
1330 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._neighbors[i]);
1331 std::size_t sz2(neigh2.size());
1332 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_neighbors[i]);
1333 for(std::size_t j=0;j<sz2;j++)
1335 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1336 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1337 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1338 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1342 sz=other._mixed_lev_neighbors.size();
1343 for(std::size_t i=0;i<sz;i++)
1345 const MEDCouplingCartesianAMRPatch *p1(other._mixed_lev_neighbors[i].first),*p2(other._mixed_lev_neighbors[i].second);
1346 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1347 _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1);
1348 _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2);
1351 sz=other._cross_lev_neighbors.size();
1352 for(std::size_t i=0;i<sz;i++)
1354 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._cross_lev_neighbors[i]);
1355 std::size_t sz2(neigh2.size());
1356 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_cross_lev_neighbors[i]);
1357 for(std::size_t j=0;j<sz2;j++)
1359 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1360 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1361 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1362 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1367 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
1369 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1371 const MEDCouplingGridCollection *elt(*it);
1375 if(elt->presenceOf(m,tmp))
1377 return elt->getFieldsAt(tmp);
1381 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
1384 void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
1386 int nbl(getNumberOfLevels());
1387 if(level<=0 || level>=nbl)
1388 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
1389 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1390 MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
1393 void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
1395 int nbl(getNumberOfLevels());
1396 if(level<0 || level>=nbl-1)
1397 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
1398 const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
1399 MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);