1 // Copyright (C) 2007-2019 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"
33 using namespace MEDCoupling;
36 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
38 return new DataArrayDoubleCollection(fieldNames);
41 DataArrayDoubleCollection *DataArrayDoubleCollection::deepCopy() const
43 return new DataArrayDoubleCollection(*this);
46 void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
48 std::size_t sz(_arrs.size());
49 for(std::size_t i=0;i<sz;i++)
50 _arrs[i].first->reAlloc(nbOfTuples);
53 void DataArrayDoubleCollection::dellocTuples()
55 std::size_t sz(_arrs.size());
56 for(std::size_t i=0;i<sz;i++)
57 _arrs[i].first->reAlloc(0);
60 void DataArrayDoubleCollection::copyFrom(const DataArrayDoubleCollection& other)
62 std::size_t sz(_arrs.size());
63 if(sz!=other._arrs.size())
64 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : size are not the same !");
65 for(std::size_t i=0;i<sz;i++)
67 DataArrayDouble *thisArr(_arrs[i].first);
68 const DataArrayDouble *otherArr(other._arrs[i].first);
69 if(!thisArr || !otherArr)
70 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : empty DataArray !");
71 thisArr->deepCopyFrom(*otherArr);
75 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
77 std::size_t sz(_arrs.size());
78 if(sz!=compNames.size())
79 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
80 for(std::size_t i=0;i<sz;i++)
82 const std::vector<std::string>& names(compNames[i]);
83 _arrs[i].first->setInfoOnComponents(names);
87 void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& nfs)
89 std::size_t sz(_arrs.size());
91 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !");
92 for(std::size_t i=0;i<sz;i++)
94 CheckValidNature(nfs[i]);
95 _arrs[i].second=nfs[i];
99 std::vector< std::pair < std::string, std::vector<std::string> > > DataArrayDoubleCollection::getInfoOnComponents() const
101 std::size_t sz(_arrs.size());
102 std::vector< std::pair < std::string, std::vector<std::string> > > ret(sz);
103 for(std::size_t i=0;i<sz;i++)
105 const DataArrayDouble *elt(_arrs[i].first);
107 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::getInfoOnComponents : empty array !");
108 ret[i]=std::pair < std::string, std::vector<std::string> >(elt->getName(),elt->getInfoOnComponents());
113 std::vector<NatureOfField> DataArrayDoubleCollection::getNatures() const
115 std::size_t sz(_arrs.size());
116 std::vector<NatureOfField> ret(sz);
117 for(std::size_t i=0;i<sz;i++)
118 ret[i]=_arrs[i].second;
122 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
124 std::size_t sz(_arrs.size());
125 std::vector<DataArrayDouble *> ret(sz);
126 for(std::size_t i=0;i<sz;i++)
128 const DataArrayDouble *tmp(_arrs[i].first);
129 ret[i]=const_cast<DataArrayDouble *>(tmp);
136 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
138 std::vector<std::string> vec;
139 for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
141 const DataArrayDouble *obj((*it).first);
144 if(obj->getName()==name)
147 vec.push_back(obj->getName());
150 std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
151 std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
152 throw INTERP_KERNEL::Exception(oss.str().c_str());
155 DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name)
157 std::vector<std::string> vec;
158 for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::iterator it=_arrs.begin();it!=_arrs.end();it++)
160 DataArrayDouble *obj((*it).first);
163 if(obj->getName()==name)
166 vec.push_back(obj->getName());
169 std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName non const : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
170 std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
171 throw INTERP_KERNEL::Exception(oss.str().c_str());
174 DataArrayDouble *DataArrayDoubleCollection::at(int pos)
176 if(pos<0 || pos>=(int)_arrs.size())
177 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at (non const) : pos must be in [0,nbOfFields) !");
178 return _arrs[pos].first;
181 const DataArrayDouble *DataArrayDoubleCollection::at(int pos) const
183 if(pos<0 || pos>=(int)_arrs.size())
184 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at : pos must be in [0,nbOfFields) !");
185 return _arrs[pos].first;
188 int DataArrayDoubleCollection::size() const
190 return (int)_arrs.size();
193 void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
196 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
197 std::size_t sz(coarse->_arrs.size());
198 if(fine->_arrs.size()!=sz)
199 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
200 for(std::size_t i=0;i<sz;i++)
202 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
203 fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
207 void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
210 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
211 std::size_t sz(coarse->_arrs.size());
212 if(fine->_arrs.size()!=sz)
213 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
214 for(std::size_t i=0;i<sz;i++)
216 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
217 fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
221 void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
223 if(!fatherOfFineMesh)
224 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
225 std::size_t sz(children.size());
226 if(fieldsOnFine.size()!=sz)
227 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
230 std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
231 for(std::size_t i=0;i<sz;i++)
232 if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
233 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
234 for(std::size_t i=1;i<sz;i++)
235 if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
236 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
237 for(std::size_t i=0;i<nbOfCall;i++)
239 std::vector<const DataArrayDouble *> arrs(sz);
240 for(std::size_t j=0;j<sz;j++)
241 arrs[j]=fieldsOnFine[j]->_arrs[i].first;
242 fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
247 * 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).
249 void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac)
251 if(!p1 || !p1dac || !p2 || !p2dac)
252 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !");
253 std::size_t sz(p1dac->_arrs.size());
254 if(p2dac->_arrs.size()!=sz)
255 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !");
256 for(std::size_t i=0;i<sz;i++)
258 const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first);
259 DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second);
260 bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second));
261 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative);
265 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
268 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
269 std::size_t sz(coarse->_arrs.size());
270 if(fine->_arrs.size()!=sz)
271 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
272 for(std::size_t i=0;i<sz;i++)
273 fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev);
276 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
278 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
279 std::size_t sz(_arrs.size());
280 if(other._arrs.size()!=sz)
281 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
282 for(std::size_t i=0;i<sz;i++)
283 father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
286 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
288 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
289 std::size_t sz(_arrs.size());
290 if(other._arrs.size()!=sz)
291 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
292 for(std::size_t i=0;i<sz;i++)
293 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
296 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
298 std::size_t sz(fieldNames.size());
299 std::vector<std::string> names(sz);
300 for(std::size_t i=0;i<sz;i++)
302 const std::pair<std::string,int>& info(fieldNames[i]);
305 std::ostringstream oss; oss << "DataArrayDoubleCollection constructor : At pos #" << i << " the array with name \"" << info.first << "\" as a number of components equal to " << info.second;
306 oss << " It has to be >=1 !";
307 throw INTERP_KERNEL::Exception(oss.str().c_str());
309 _arrs[i].first=DataArrayDouble::New();
310 _arrs[i].first->alloc(0,info.second);
311 _arrs[i].first->setName(info.first);
312 names[i]=info.second;
313 _arrs[i].second=IntensiveMaximum;
315 CheckDiscriminantNames(names);
318 DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size())
320 std::size_t sz(other._arrs.size());
321 for(std::size_t i=0;i<sz;i++)
323 _arrs[i].second=other._arrs[i].second;
324 const DataArrayDouble *da(other._arrs[i].first);
326 _arrs[i].first=da->deepCopy();
330 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
332 std::size_t ret(sizeof(DataArrayDoubleCollection));
333 ret+=_arrs.capacity()*sizeof(MCAuto<DataArrayDouble>);
337 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildrenWithNull() const
339 std::vector<const BigMemoryObject *> ret;
340 for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
341 ret.push_back((const DataArrayDouble *)(*it).first);
345 void DataArrayDoubleCollection::updateTime() const
347 for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
349 const DataArrayDouble *pt((*it).first);
355 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
357 std::set<std::string> s(names.begin(),names.end());
358 if(s.size()!=names.size())
359 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
362 bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
365 return n==IntensiveConservation || n==ExtensiveConservation;
368 void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
370 CheckValidNature(n1);
371 CheckValidNature(n2);
373 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
376 void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
378 if(n!=IntensiveMaximum && n!=ExtensiveMaximum && n!=ExtensiveConservation && n!=IntensiveConservation)
379 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
382 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
384 return new MEDCouplingGridCollection(ms,fieldNames);
387 MEDCouplingGridCollection *MEDCouplingGridCollection::deepCopy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
389 return new MEDCouplingGridCollection(*this,newGf,oldGf);
392 void MEDCouplingGridCollection::alloc(int ghostLev)
394 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
396 int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
397 DataArrayDoubleCollection *dadc((*it).second);
399 dadc->allocTuples(nbTuples);
401 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
405 void MEDCouplingGridCollection::dealloc()
407 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
409 DataArrayDoubleCollection *dadc((*it).second);
411 dadc->dellocTuples();
413 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
417 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
419 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
420 (*it).second->spillInfoOnComponents(compNames);
423 void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
425 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
426 (*it).second->spillNatures(nfs);
429 std::vector< std::pair<std::string, std::vector<std::string> > > MEDCouplingGridCollection::getInfoOnComponents() const
431 if(_map_of_dadc.empty())
432 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !");
433 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
435 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !");
436 return elt->getInfoOnComponents();
439 std::vector<NatureOfField> MEDCouplingGridCollection::getNatures() const
441 if(_map_of_dadc.empty())
442 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !");
443 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
445 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !");
446 return elt->getNatures();
449 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
452 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
463 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
465 if(pos<0 || pos>(int)_map_of_dadc.size())
466 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
467 return *_map_of_dadc[pos].second;
470 DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos)
472 if(pos<0 || pos>(int)_map_of_dadc.size())
473 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !");
474 return *_map_of_dadc[pos].second;
478 * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting
479 * part of fields of \a this. The fields are expected to be the same between \a other and \a this.
480 * 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.
482 void MEDCouplingGridCollection::copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other)
484 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
486 std::vector<int> deltaThis,deltaOther;
487 std::vector< std::pair<int,int> > rgThis((*it).first->positionRelativeToGodFather(deltaThis));
488 std::vector<int> thisSt((*it).first->getImageMesh()->getCellGridStructure());
489 std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
490 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++)
492 std::vector< std::pair<int,int> > rgOther((*it2).first->positionRelativeToGodFather(deltaOther));
493 if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther))
495 std::vector< std::pair<int,int> > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther));
496 std::vector< std::pair<int,int> > pThis,pOther;
497 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true);
498 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true);
499 std::vector<int> otherSt((*it2).first->getImageMesh()->getCellGridStructure());
500 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev);
501 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev);
502 std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
503 int sz((*it2).second->size());
504 for(int i=0;i<sz;i++)
506 const DataArrayDouble *otherArr((*it2).second->at(i));
507 DataArrayDouble *thisArr((*it).second->at(i));
508 MCAuto<DataArrayDouble> partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther));
509 MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther);
516 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
519 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
520 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
521 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
522 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<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 *,MCAuto<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 *coarseDaCol((*it0).second);
534 DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
535 DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
539 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
543 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
546 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
547 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
548 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
549 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
551 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
552 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
554 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
556 if((*it0).first==fatherOfFineMesh)
559 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
560 const DataArrayDoubleCollection *fineDaCol((*it).second);
561 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
562 DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
566 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
571 * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
573 * \sa synchronizeFineEachOtherExt
575 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
577 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
580 if(!presenceOf((*it).first->getMesh(),p1))
581 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
582 if(!presenceOf((*it).second->getMesh(),p2))
583 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
584 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
585 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
586 col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
591 * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
593 * \sa synchronizeFineEachOther
595 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
597 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
600 if(!presenceOf((*it).first->getMesh(),p1))
601 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
602 if(!presenceOf((*it).second->getMesh(),p2))
603 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
604 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
605 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
606 col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
611 * The pairs returned share the same direct father. The number of returned elements must be even.
613 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
615 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
616 std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
617 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
619 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
620 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
621 m[fatherOfFineMesh].push_back(fineMesh);
623 for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
625 for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
627 int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
628 std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
629 const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
630 for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
632 const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
633 ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
638 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
642 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
645 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
646 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
647 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
648 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
650 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
651 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
653 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
655 if((*it0).first==fatherOfFineMesh)
658 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
659 const DataArrayDoubleCollection *fineDaCol((*it).second);
660 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
661 DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
665 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
669 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
671 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
673 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
674 if(head==a || head->isObjectInTheProgeny(a))
676 const DataArrayDoubleCollection *gc((*it).second);
677 recurseArrs.push_back(gc->getFieldWithName(fieldName));
682 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
684 std::size_t sz(ms.size());
685 for(std::size_t i=0;i<sz;i++)
688 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
689 _map_of_dadc[i].first=ms[i];
690 _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
694 MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
696 std::size_t sz(other._map_of_dadc.size());
697 for(std::size_t i=0;i<sz;i++)
699 std::vector<int> pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf));
700 _map_of_dadc[i].first=newGf->getMeshAtPosition(pos);
701 const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
703 _map_of_dadc[i].second=dac->deepCopy();
707 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
709 std::size_t ret(sizeof(MEDCouplingGridCollection));
710 ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> >);
714 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildrenWithNull() const
716 std::vector<const BigMemoryObject *> ret;
717 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
718 ret.push_back((const DataArrayDoubleCollection *)(*it).second);
722 void MEDCouplingGridCollection::updateTime() const
724 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
726 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
729 const DataArrayDoubleCollection *b((*it).second);
737 MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather()
742 const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const
747 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
750 throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
754 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
759 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
761 bool ret(_tlc.keepTrackOfNewTL(gf));
771 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
773 other._tlc.checkConst();
776 const MEDCouplingCartesianAMRMesh *gf(other._gf);
779 _tlc.keepTrackOfNewTL(_gf);
784 * This method creates, attach to a main AMR mesh \a gf ( called god father :-) ) and returns a data linked to \a gf ready for the computation.
786 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
788 return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
791 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
793 std::size_t sz(fieldNames.size());
794 std::vector< std::pair<std::string,int> > fieldNames2(sz);
795 std::vector< std::vector<std::string> > compNames(sz);
796 for(std::size_t i=0;i<sz;i++)
798 fieldNames2[i].first=fieldNames[i].first;
799 fieldNames2[i].second=(int)fieldNames[i].second.size();
800 compNames[i]=fieldNames[i].second;
802 MCAuto<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
803 ret->spillInfoOnComponents(compNames);
808 * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
809 * The first dim of input \a compNames is the field id in the same order than those implicitly specified in \a fieldNames parameter of MEDCouplingAMRAttribute::New.
810 * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
811 * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
813 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
816 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
817 (*it)->spillInfoOnComponents(compNames);
821 * Assign nature for each fields in \a this.
824 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
827 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
828 (*it)->spillNatures(nfs);
831 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCopy() const
833 return new MEDCouplingAMRAttribute(*this,true);
836 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const
838 return new MEDCouplingAMRAttribute(*this,false);
842 * Returns the number of levels by \b only \b considering \a this (god father instance is considered only to see if it has not changed still last update of \a this).
845 int MEDCouplingAMRAttribute::getNumberOfLevels() const
847 checkGodFatherFrozen();
848 return (int)_levs.size();
852 * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
853 * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
855 * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
856 * \sa retrieveFieldOn
858 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
860 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
863 if((*it)->presenceOf(mesh,tmp))
865 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
866 return ddc.retrieveFields();
869 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
873 * \sa retrieveFieldsOn
875 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
877 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
880 if((*it)->presenceOf(mesh,tmp))
882 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
883 return ddc.getFieldWithName(fieldName);
886 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn : the mesh specified is not in the progeny of this !");
889 DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName)
891 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
894 if((*it)->presenceOf(mesh,tmp))
896 DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
897 return ddc.getFieldWithName(fieldName);
900 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn non const : the mesh specified is not in the progeny of this !");
904 * This method returns a field on an unstructured mesh the most refined as possible without overlap.
905 * Ghost part are not visible here.
907 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
909 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
911 std::vector<const DataArrayDouble *> recurseArrs;
913 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
916 if((*it)->presenceOf(mesh,tmp))
918 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
919 recurseArrs.push_back(ddc.getFieldWithName(fieldName));
924 for(std::size_t i=lev;i<_levs.size();i++)
926 const MEDCouplingGridCollection *gc(_levs[i]);
927 gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
929 return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
933 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
934 * The output field also displays ghost cells.
936 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
938 * \sa buildCellFieldOnWithoutGhost
940 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
942 const DataArrayDouble *arr(0);
943 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
946 if((*it)->presenceOf(mesh,tmp))
948 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
949 arr=ddc.getFieldWithName(fieldName);
953 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
954 MCAuto<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
955 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
957 ret->setArray(const_cast<DataArrayDouble *>(arr));
958 ret->setName(arr->getName());
963 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
964 * The output field does not display ghost cells.
966 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
968 * \sa buildCellFieldOnWithGhost
970 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
972 const DataArrayDouble *arr(0);
973 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
976 if((*it)->presenceOf(mesh,tmp))
978 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
979 arr=ddc.getFieldWithName(fieldName);
983 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
985 MCAuto<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
986 std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
987 MCAuto<DataArrayDouble> arr2(DataArrayDouble::New());
988 arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
989 std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
990 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
991 std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
992 MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
993 arr2->copyStringInfoFrom(*arr);
995 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
996 ret->setMesh(mesh->getImageMesh());
998 ret->setName(arr->getName());
1003 std::string MEDCouplingAMRAttribute::writeVTHB(const std::string& fileName) const
1005 static const char EXT[]=".vthb";
1006 std::string baseName,extName,zeFileName;
1007 MEDCouplingMesh::SplitExtension(fileName,baseName,extName);
1009 zeFileName=fileName;
1011 { zeFileName=baseName; zeFileName+=EXT; }
1013 std::ofstream ofs(fileName.c_str());
1014 ofs << "<VTKFile type=\"vtkOverlappingAMR\" version=\"1.1\" byte_order=\"" << MEDCouplingByteOrderStr() << "\">\n";
1015 const MEDCouplingCartesianAMRMesh *gf(getMyGodFather());
1016 ofs << " <vtkOverlappingAMR origin=\"";
1017 const MEDCouplingIMesh *gfm(gf->getImageMesh());
1018 std::vector<double> orig(gfm->getOrigin());
1019 std::vector<double> spacing(gfm->getDXYZ());
1020 int dim((int)orig.size());
1021 std::copy(orig.begin(),orig.end(),std::ostream_iterator<double>(ofs," ")); ofs << "\" grid_description=\"";
1022 for(int i=0;i<dim;i++)
1024 char tmp[2]; tmp[0]='X'+i; tmp[1]='\0';
1029 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()),kk(0);
1030 for(int i=0;i<maxLev;i++)
1032 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1033 std::size_t sz(patches.size());
1034 std::vector< MCAuto<MEDCouplingCartesianAMRPatchGen> > patchesSafe(sz);
1035 for(std::size_t j=0;j<sz;j++)
1036 patchesSafe[j]=patches[j];
1039 ofs << " <Block level=\"" << i << "\" spacing=\"";
1040 std::copy(spacing.begin(),spacing.end(),std::ostream_iterator<double>(ofs," "));
1044 std::vector<int> factors(patches[0]->getMesh()->getFactors());
1045 for(int k=0;k<dim;k++)
1046 spacing[k]*=1./((double) factors[k]);
1049 for(std::vector<MEDCouplingCartesianAMRPatchGen *>::const_iterator it=patches.begin();it!=patches.end();it++,jj++,kk++)
1051 ofs << " <DataSet index=\"" << jj << "\" amr_box=\"";
1052 const MEDCouplingCartesianAMRPatch *patchCast(dynamic_cast<const MEDCouplingCartesianAMRPatch *>(*it));
1053 const MEDCouplingCartesianAMRMeshGen *mesh((*it)->getMesh());
1056 const std::vector< std::pair<int,int> >& bltr(patchCast->getBLTRRangeRelativeToGF());
1057 for(int pp=0;pp<dim;pp++)
1058 ofs << bltr[pp].first << " " << bltr[pp].second-1 << " ";
1062 const MEDCouplingIMesh *im((*it)->getMesh()->getImageMesh());
1063 std::vector<int> cgs(im->getCellGridStructure());
1064 for(int pp=0;pp<dim;pp++)
1065 ofs << "0 " << cgs[pp]-1 << " ";
1067 ofs << "\" file=\"";
1070 if(_levs[i]->presenceOf((*it)->getMesh(),tmp))
1072 const DataArrayDoubleCollection& ddc(_levs[i]->getFieldsAt(tmp));
1073 std::vector<DataArrayDouble *> arrs(ddc.retrieveFields());
1074 std::size_t nbFields(arrs.size());
1075 std::vector< MCAuto<DataArrayDouble> > arrsSafe(nbFields),arrs2Safe(nbFields);
1076 std::vector< const MEDCouplingFieldDouble *> fields(nbFields);
1077 std::vector< MCAuto<MEDCouplingFieldDouble> > fieldsSafe(nbFields);
1078 for(std::size_t pp=0;pp<nbFields;pp++)
1079 arrsSafe[pp]=arrs[pp];
1080 for(std::size_t pp=0;pp<nbFields;pp++)
1082 MCAuto<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
1083 std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
1084 arrs2Safe[pp]=DataArrayDouble::New();
1085 arrs2Safe[pp]->alloc(mesh->getImageMesh()->getNumberOfCells(),arrs[pp]->getNumberOfComponents());
1086 std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
1087 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
1088 std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
1089 MEDCouplingIMesh::SpreadCoarseToFine(arrs[pp],cgsWG,arrs2Safe[pp],cgs2,fakeFactors);
1090 arrs2Safe[pp]->copyStringInfoFrom(*arrs[pp]);
1092 fieldsSafe[pp]=MEDCouplingFieldDouble::New(ON_CELLS); fields[pp]=fieldsSafe[pp];
1093 fieldsSafe[pp]->setMesh(mesh->getImageMesh());
1094 fieldsSafe[pp]->setArray(arrs2Safe[pp]);
1095 fieldsSafe[pp]->setName(arrs[pp]->getName());
1097 std::ostringstream vtiFileName; vtiFileName << baseName << "_" << kk << ".vti";
1098 MEDCouplingFieldDouble::WriteVTK(vtiFileName.str(),fields,true);
1100 ofs << vtiFileName.str() << "\">\n";
1101 ofs << " \n </DataSet>\n";
1104 ofs << " </Block>\n";
1107 ofs << " </vtkOverlappingAMR>\n";
1108 ofs << "</VTKFile>\n";
1113 * This method is useful just after a remesh after a time step computation to project values in \a this to the new
1116 * This method performs a projection from \a this to a target AMR mesh \a targetGF.
1117 * This method performs the projection by trying to transfer the finest information to \a targetGF.
1118 * \b WARNING this method does not update the ghost zone, if any.
1119 * The level0 of \a this god father must have the same structure than those of \a targetGF.
1121 * This method makes checks that ghost size of \a this and \a targetGF are the same, and that
1122 * the number of levels in \a this and in \a targetGF are also the same.
1124 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const
1127 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !");
1129 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !");
1130 const MEDCouplingGridCollection *lev0(_levs[0]);
1132 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !");
1133 std::vector< std::pair < std::string, std::vector<std::string> > > fieldNames(lev0->getInfoOnComponents());
1134 MCAuto<MEDCouplingAMRAttribute> ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev));
1135 ret->spillNatures(lev0->getNatures());
1137 int nbLevs(getNumberOfLevels());
1138 if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs)
1139 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !");
1140 // first step copy level0
1141 if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure())
1142 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !");
1143 const DataArrayDoubleCollection& col(lev0->getFieldsAt(0));
1144 DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0));
1145 colTarget.copyFrom(col);
1146 // then go deeper and deeper
1147 for(int i=1;i<nbLevs;i++)
1149 ret->synchronizeCoarseToFineByOneLevel(i-1);
1150 MEDCouplingGridCollection *targetCol(ret->_levs[i]);
1152 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !");
1153 const MEDCouplingGridCollection *thisCol(_levs[i]);
1155 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !");
1156 targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol);
1162 * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
1163 * MEDCouplingAMRAttribute::alloc method.
1164 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse)
1166 * \sa synchronizeFineToCoarseBetween
1168 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
1171 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
1172 std::size_t sz(_levs.size());
1177 synchronizeFineToCoarseByOneLevel((int)sz);
1182 * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
1183 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
1184 * until reaching \a toLev level.
1185 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse).
1187 * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
1188 * \param [in] toLev - an existing level considered as the target level to reach.
1191 void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
1193 int nbl(getNumberOfLevels());
1194 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1195 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1197 return ;//nothing to do
1199 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
1200 for(int i=fromLev;i>toLev;i--)
1201 synchronizeFineToCoarseByOneLevel(i);
1205 * 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
1206 * MEDCouplingAMRAttribute::alloc method.
1207 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method)
1209 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
1212 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
1213 std::size_t sz(_levs.size());
1215 for(std::size_t i=0;i<sz-1;i++)
1216 synchronizeCoarseToFineByOneLevel((int)i);
1220 * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
1221 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
1222 * until reaching \a toLev level.
1223 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarseBetween method)
1225 * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
1226 * \param [in] toLev - an existing level considered as the target level to reach.
1228 void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
1230 int nbl(getNumberOfLevels());
1231 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1232 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1234 return ;//nothing to do
1236 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
1237 for(int i=fromLev;i<toLev;i++)
1238 synchronizeCoarseToFineByOneLevel(i);
1242 * This method synchronizes the ghost zone of all patches (excepted the god father one).
1243 * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
1245 * - firstly coarse to fine with no interactions between brother patches.
1246 * - secondly connected brother patches in a same master patch are updated.
1247 * - thirdly connected nephew patches are updated each other.
1248 * - forthly nth generation cousin patches are updated each other.
1250 * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
1251 * So if \a _ghost_lev == 0 this method has no effect.
1253 void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
1255 int sz(getNumberOfLevels());
1257 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
1258 // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
1259 for(int i=1;i<sz;i++)
1261 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
1262 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1264 // 2nd - classical direct sublevel inside common patch
1265 for(int i=1;i<sz;i++)
1267 const MEDCouplingGridCollection *curLev(_levs[i]);
1269 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
1270 curLev->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
1272 // 3rd - mixed level
1273 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
1275 const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
1276 DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
1278 // 4th - same level but with far ancestor.
1279 for(int i=1;i<sz;i++)
1281 const MEDCouplingGridCollection *fine(_levs[i]);
1282 fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
1287 * 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.
1288 * 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).
1289 * 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.
1290 * 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.
1292 * \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.
1295 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh)
1298 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !");
1299 int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels());
1300 if(level<0 || level>=sz-1)
1301 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !");
1302 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& itemsToFilter(_neighbors[level+1]);
1303 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > itemsToSync; itemsToSync.reserve(itemsToFilter.size());
1304 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++)
1306 if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh)
1307 itemsToSync.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>((*it).first,(*it).second));
1309 const MEDCouplingGridCollection *curLev(_levs[level+1]);
1311 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !");
1312 curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync);
1316 * This method updates \b all the patches at level \a level each other without consideration of their father.
1317 * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf.
1319 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level)
1321 int maxLev(getNumberOfLevels());
1322 if(level<0 || level>=maxLev)
1323 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !");
1325 return ;//at level 0 only one patch -> no need to update
1326 // 1st step - updates all patches pairs at level \a level sharing the same father
1327 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items(_neighbors[level]);
1328 const MEDCouplingGridCollection *curLev(_levs[level]);
1330 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !");
1331 curLev->synchronizeFineEachOther(_ghost_lev,items);
1332 //2nd step - updates all patches pairs at level \a level not sharing the same father
1333 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items2(_cross_lev_neighbors[level]);
1334 curLev->synchronizeFineEachOtherExt(_ghost_lev,items2);
1338 * 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).
1339 * This method is useful to propagate to the ghost zone of childhood the modification.
1341 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level)
1343 int maxLev(getNumberOfLevels());
1344 if(level<=0 || level>=maxLev)
1345 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !");
1346 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1347 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1348 //_cross_lev_neighbors is not needed.
1352 * This method allocates all DataArrayDouble instances stored recursively in \a this.
1356 void MEDCouplingAMRAttribute::alloc()
1359 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1361 MEDCouplingGridCollection *elt(*it);
1363 elt->alloc(_ghost_lev);
1365 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
1370 * This method deallocates all DataArrayDouble instances stored recursively in \a this.
1373 void MEDCouplingAMRAttribute::dealloc()
1376 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1378 MEDCouplingGridCollection *elt(*it);
1382 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
1386 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
1388 bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
1392 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
1394 std::size_t ret(sizeof(MEDCouplingAMRAttribute));
1395 ret+=_levs.capacity()*sizeof(MCAuto<MEDCouplingGridCollection>);
1399 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildrenWithNull() const
1401 std::vector<const BigMemoryObject *> ret;
1402 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1403 ret.push_back((const MEDCouplingGridCollection *)*it);
1407 void MEDCouplingAMRAttribute::updateTime() const
1411 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
1413 //gf non empty, checked by constructor
1414 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
1415 _levs.resize(maxLev);
1416 for(int i=0;i<maxLev;i++)
1418 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1419 std::size_t sz(patches.size());
1420 std::vector< MCAuto<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
1421 for(std::size_t j=0;j<sz;j++)
1422 patchesSafe[j]=patches[j];
1423 std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
1424 for(std::size_t j=0;j<sz;j++)
1426 ms[j]=patches[j]->getMesh();
1428 _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
1430 // updates cross levels neighbors
1431 _neighbors.resize(_levs.size());
1432 _cross_lev_neighbors.resize(_levs.size());
1434 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
1435 std::size_t sz(_levs.size());
1436 for(std::size_t i=1;i<sz;i++)
1438 const MEDCouplingGridCollection *fine(_levs[i]);
1440 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
1441 _neighbors[i]=fine->findNeighbors(_ghost_lev);
1444 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
1446 MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
1447 std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
1448 std::size_t fullLev(i+neighs2.size());
1450 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
1451 std::size_t ii(i+1);
1452 for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
1453 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
1459 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)
1461 std::size_t sz(other._levs.size());
1462 for(std::size_t i=0;i<sz;i++)
1464 const MEDCouplingGridCollection *elt(other._levs[i]);
1467 _levs[i]=other._levs[i]->deepCopy(_gf,other._gf);
1470 //_cross_lev_neighbors(other._cross_lev_neighbors)
1471 sz=other._neighbors.size();
1472 for(std::size_t i=0;i<sz;i++)
1474 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._neighbors[i]);
1475 std::size_t sz2(neigh2.size());
1476 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_neighbors[i]);
1477 for(std::size_t j=0;j<sz2;j++)
1479 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1480 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1481 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1482 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1486 sz=other._mixed_lev_neighbors.size();
1487 for(std::size_t i=0;i<sz;i++)
1489 const MEDCouplingCartesianAMRPatch *p1(other._mixed_lev_neighbors[i].first),*p2(other._mixed_lev_neighbors[i].second);
1490 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1491 _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1);
1492 _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2);
1495 sz=other._cross_lev_neighbors.size();
1496 for(std::size_t i=0;i<sz;i++)
1498 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._cross_lev_neighbors[i]);
1499 std::size_t sz2(neigh2.size());
1500 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_cross_lev_neighbors[i]);
1501 for(std::size_t j=0;j<sz2;j++)
1503 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1504 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1505 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1506 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1511 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
1513 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1515 const MEDCouplingGridCollection *elt(*it);
1519 if(elt->presenceOf(m,tmp))
1521 return elt->getFieldsAt(tmp);
1525 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
1528 void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
1530 int nbl(getNumberOfLevels());
1531 if(level<=0 || level>=nbl)
1532 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
1533 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1534 MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
1537 void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
1539 int nbl(getNumberOfLevels());
1540 if(level<0 || level>=nbl-1)
1541 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
1542 const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
1543 MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);