1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay
21 #include "MEDCouplingAMRAttribute.hxx"
22 #include "MEDCouplingFieldDouble.hxx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingIMesh.hxx"
29 using namespace ParaMEDMEM;
31 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
33 return new DataArrayDoubleCollection(fieldNames);
36 DataArrayDoubleCollection *DataArrayDoubleCollection::deepCpy() const
38 return new DataArrayDoubleCollection(*this);
41 void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
43 std::size_t sz(_arrs.size());
44 for(std::size_t i=0;i<sz;i++)
45 _arrs[i].first->reAlloc(nbOfTuples);
48 void DataArrayDoubleCollection::dellocTuples()
50 std::size_t sz(_arrs.size());
51 for(std::size_t i=0;i<sz;i++)
52 _arrs[i].first->reAlloc(0);
55 void DataArrayDoubleCollection::copyFrom(const DataArrayDoubleCollection& other)
57 std::size_t sz(_arrs.size());
58 if(sz!=other._arrs.size())
59 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : size are not the same !");
60 for(std::size_t i=0;i<sz;i++)
62 DataArrayDouble *thisArr(_arrs[i].first);
63 const DataArrayDouble *otherArr(other._arrs[i].first);
64 if(!thisArr || !otherArr)
65 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : empty DataArray !");
66 thisArr->cpyFrom(*otherArr);
70 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
72 std::size_t sz(_arrs.size());
73 if(sz!=compNames.size())
74 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
75 for(std::size_t i=0;i<sz;i++)
77 const std::vector<std::string>& names(compNames[i]);
78 _arrs[i].first->setInfoOnComponents(names);
82 void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& nfs)
84 std::size_t sz(_arrs.size());
86 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !");
87 for(std::size_t i=0;i<sz;i++)
89 CheckValidNature(nfs[i]);
90 _arrs[i].second=nfs[i];
94 std::vector< std::pair < std::string, std::vector<std::string> > > DataArrayDoubleCollection::getInfoOnComponents() const
96 std::size_t sz(_arrs.size());
97 std::vector< std::pair < std::string, std::vector<std::string> > > ret(sz);
98 for(std::size_t i=0;i<sz;i++)
100 const DataArrayDouble *elt(_arrs[i].first);
102 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::getInfoOnComponents : empty array !");
103 ret[i]=std::pair < std::string, std::vector<std::string> >(elt->getName(),elt->getInfoOnComponents());
108 std::vector<NatureOfField> DataArrayDoubleCollection::getNatures() const
110 std::size_t sz(_arrs.size());
111 std::vector<NatureOfField> ret(sz);
112 for(std::size_t i=0;i<sz;i++)
113 ret[i]=_arrs[i].second;
117 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
119 std::size_t sz(_arrs.size());
120 std::vector<DataArrayDouble *> ret(sz);
121 for(std::size_t i=0;i<sz;i++)
123 const DataArrayDouble *tmp(_arrs[i].first);
124 ret[i]=const_cast<DataArrayDouble *>(tmp);
131 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
133 std::vector<std::string> vec;
134 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
136 const DataArrayDouble *obj((*it).first);
139 if(obj->getName()==name)
142 vec.push_back(obj->getName());
145 std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
146 std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
147 throw INTERP_KERNEL::Exception(oss.str().c_str());
150 DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name)
152 std::vector<std::string> vec;
153 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::iterator it=_arrs.begin();it!=_arrs.end();it++)
155 DataArrayDouble *obj((*it).first);
158 if(obj->getName()==name)
161 vec.push_back(obj->getName());
164 std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName non const : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
165 std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
166 throw INTERP_KERNEL::Exception(oss.str().c_str());
169 DataArrayDouble *DataArrayDoubleCollection::at(int pos)
171 if(pos<0 || pos>=(int)_arrs.size())
172 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at (non const) : pos must be in [0,nbOfFields) !");
173 return _arrs[pos].first;
176 const DataArrayDouble *DataArrayDoubleCollection::at(int pos) const
178 if(pos<0 || pos>=(int)_arrs.size())
179 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at : pos must be in [0,nbOfFields) !");
180 return _arrs[pos].first;
183 int DataArrayDoubleCollection::size() const
185 return (int)_arrs.size();
188 void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
191 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
192 std::size_t sz(coarse->_arrs.size());
193 if(fine->_arrs.size()!=sz)
194 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
195 for(std::size_t i=0;i<sz;i++)
197 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
198 fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
202 void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
205 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
206 std::size_t sz(coarse->_arrs.size());
207 if(fine->_arrs.size()!=sz)
208 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
209 for(std::size_t i=0;i<sz;i++)
211 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
212 fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
216 void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
218 if(!fatherOfFineMesh)
219 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
220 std::size_t sz(children.size());
221 if(fieldsOnFine.size()!=sz)
222 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
225 std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
226 for(std::size_t i=0;i<sz;i++)
227 if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
228 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
229 for(std::size_t i=1;i<sz;i++)
230 if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
231 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
232 for(std::size_t i=0;i<nbOfCall;i++)
234 std::vector<const DataArrayDouble *> arrs(sz);
235 for(std::size_t j=0;j<sz;j++)
236 arrs[j]=fieldsOnFine[j]->_arrs[i].first;
237 fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
242 * 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).
244 void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac)
246 if(!p1 || !p1dac || !p2 || !p2dac)
247 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !");
248 std::size_t sz(p1dac->_arrs.size());
249 if(p2dac->_arrs.size()!=sz)
250 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !");
251 for(std::size_t i=0;i<sz;i++)
253 const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first);
254 DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second);
255 bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second));
256 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative);
260 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
263 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
264 std::size_t sz(coarse->_arrs.size());
265 if(fine->_arrs.size()!=sz)
266 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
267 for(std::size_t i=0;i<sz;i++)
268 fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev);
271 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
273 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
274 std::size_t sz(_arrs.size());
275 if(other._arrs.size()!=sz)
276 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
277 for(std::size_t i=0;i<sz;i++)
278 father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
281 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
283 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
284 std::size_t sz(_arrs.size());
285 if(other._arrs.size()!=sz)
286 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
287 for(std::size_t i=0;i<sz;i++)
288 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
291 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
293 std::size_t sz(fieldNames.size());
294 std::vector<std::string> names(sz);
295 for(std::size_t i=0;i<sz;i++)
297 const std::pair<std::string,int>& info(fieldNames[i]);
300 std::ostringstream oss; oss << "DataArrayDoubleCollection constructor : At pos #" << i << " the array with name \"" << info.first << "\" as a number of components equal to " << info.second;
301 oss << " It has to be >=1 !";
302 throw INTERP_KERNEL::Exception(oss.str().c_str());
304 _arrs[i].first=DataArrayDouble::New();
305 _arrs[i].first->alloc(0,info.second);
306 _arrs[i].first->setName(info.first);
307 names[i]=info.second;
308 _arrs[i].second=ConservativeVolumic;
310 CheckDiscriminantNames(names);
313 DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size())
315 std::size_t sz(other._arrs.size());
316 for(std::size_t i=0;i<sz;i++)
318 _arrs[i].second=other._arrs[i].second;
319 const DataArrayDouble *da(other._arrs[i].first);
321 _arrs[i].first=da->deepCpy();
325 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
327 std::size_t ret(sizeof(DataArrayDoubleCollection));
328 ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
332 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildrenWithNull() const
334 std::vector<const BigMemoryObject *> ret;
335 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
336 ret.push_back((const DataArrayDouble *)(*it).first);
340 void DataArrayDoubleCollection::updateTime() const
342 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
344 const DataArrayDouble *pt((*it).first);
350 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
352 std::set<std::string> s(names.begin(),names.end());
353 if(s.size()!=names.size())
354 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
357 bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
360 return n==RevIntegral || n==IntegralGlobConstraint;
363 void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
365 CheckValidNature(n1);
366 CheckValidNature(n2);
368 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
371 void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
373 if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral)
374 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
377 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
379 return new MEDCouplingGridCollection(ms,fieldNames);
382 MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
384 return new MEDCouplingGridCollection(*this,newGf,oldGf);
387 void MEDCouplingGridCollection::alloc(int ghostLev)
389 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
391 int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
392 DataArrayDoubleCollection *dadc((*it).second);
394 dadc->allocTuples(nbTuples);
396 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
400 void MEDCouplingGridCollection::dealloc()
402 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
404 DataArrayDoubleCollection *dadc((*it).second);
406 dadc->dellocTuples();
408 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
412 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
414 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
415 (*it).second->spillInfoOnComponents(compNames);
418 void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
420 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
421 (*it).second->spillNatures(nfs);
424 std::vector< std::pair<std::string, std::vector<std::string> > > MEDCouplingGridCollection::getInfoOnComponents() const
426 if(_map_of_dadc.empty())
427 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !");
428 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
430 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !");
431 return elt->getInfoOnComponents();
434 std::vector<NatureOfField> MEDCouplingGridCollection::getNatures() const
436 if(_map_of_dadc.empty())
437 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !");
438 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
440 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !");
441 return elt->getNatures();
444 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
447 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
458 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
460 if(pos<0 || pos>(int)_map_of_dadc.size())
461 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
462 return *_map_of_dadc[pos].second;
465 DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos)
467 if(pos<0 || pos>(int)_map_of_dadc.size())
468 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !");
469 return *_map_of_dadc[pos].second;
473 * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting
474 * part of fields of \a this. The fields are expected to be the same between \a other and \a this.
475 * 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.
477 void MEDCouplingGridCollection::copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other)
479 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
481 std::vector<int> deltaThis,deltaOther;
482 std::vector< std::pair<int,int> > rgThis((*it).first->positionRelativeToGodFather(deltaThis));
483 std::vector<int> thisSt((*it).first->getImageMesh()->getCellGridStructure());
484 std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
485 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++)
487 std::vector< std::pair<int,int> > rgOther((*it2).first->positionRelativeToGodFather(deltaOther));
488 if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther))
490 std::vector< std::pair<int,int> > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther));
491 std::vector< std::pair<int,int> > pThis,pOther;
492 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true);
493 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true);
494 std::vector<int> otherSt((*it2).first->getImageMesh()->getCellGridStructure());
495 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev);
496 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev);
497 std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
498 int sz((*it2).second->size());
499 for(int i=0;i<sz;i++)
501 const DataArrayDouble *otherArr((*it2).second->at(i));
502 DataArrayDouble *thisArr((*it).second->at(i));
503 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther));
504 MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther);
511 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
514 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
515 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
516 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
517 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
519 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
520 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
522 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
524 if((*it0).first==fatherOfFineMesh)
527 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
528 const DataArrayDoubleCollection *coarseDaCol((*it0).second);
529 DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
530 DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
534 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
538 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
541 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
542 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
543 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
544 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
546 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
547 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
549 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
551 if((*it0).first==fatherOfFineMesh)
554 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
555 const DataArrayDoubleCollection *fineDaCol((*it).second);
556 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
557 DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
561 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
566 * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
568 * \sa synchronizeFineEachOtherExt
570 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
572 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
575 if(!presenceOf((*it).first->getMesh(),p1))
576 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
577 if(!presenceOf((*it).second->getMesh(),p2))
578 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
579 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
580 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
581 col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
586 * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
588 * \sa synchronizeFineEachOther
590 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
592 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
595 if(!presenceOf((*it).first->getMesh(),p1))
596 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
597 if(!presenceOf((*it).second->getMesh(),p2))
598 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
599 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
600 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
601 col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
606 * The pairs returned share the same direct father. The number of returned elements must be even.
608 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
610 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
611 std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
612 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
614 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
615 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
616 m[fatherOfFineMesh].push_back(fineMesh);
618 for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
620 for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
622 int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
623 std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
624 const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
625 for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
627 const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
628 ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
633 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
637 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
640 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
641 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
642 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
643 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
645 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
646 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
648 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
650 if((*it0).first==fatherOfFineMesh)
653 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
654 const DataArrayDoubleCollection *fineDaCol((*it).second);
655 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
656 DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
660 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
664 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
666 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
668 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
669 if(head==a || head->isObjectInTheProgeny(a))
671 const DataArrayDoubleCollection *gc((*it).second);
672 recurseArrs.push_back(gc->getFieldWithName(fieldName));
677 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
679 std::size_t sz(ms.size());
680 for(std::size_t i=0;i<sz;i++)
683 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
684 _map_of_dadc[i].first=ms[i];
685 _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
689 MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
691 std::size_t sz(other._map_of_dadc.size());
692 for(std::size_t i=0;i<sz;i++)
694 std::vector<int> pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf));
695 _map_of_dadc[i].first=newGf->getMeshAtPosition(pos);
696 const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
698 _map_of_dadc[i].second=dac->deepCpy();
702 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
704 std::size_t ret(sizeof(MEDCouplingGridCollection));
705 ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
709 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildrenWithNull() const
711 std::vector<const BigMemoryObject *> ret;
712 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
713 ret.push_back((const DataArrayDoubleCollection *)(*it).second);
717 void MEDCouplingGridCollection::updateTime() const
719 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
721 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
724 const DataArrayDoubleCollection *b((*it).second);
730 MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather()
735 const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const
740 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
743 throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
747 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
752 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
754 bool ret(_tlc.keepTrackOfNewTL(gf));
764 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
766 other._tlc.checkConst();
769 const MEDCouplingCartesianAMRMesh *gf(other._gf);
772 _tlc.keepTrackOfNewTL(_gf);
777 * 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.
779 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
781 return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
784 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
786 std::size_t sz(fieldNames.size());
787 std::vector< std::pair<std::string,int> > fieldNames2(sz);
788 std::vector< std::vector<std::string> > compNames(sz);
789 for(std::size_t i=0;i<sz;i++)
791 fieldNames2[i].first=fieldNames[i].first;
792 fieldNames2[i].second=(int)fieldNames[i].second.size();
793 compNames[i]=fieldNames[i].second;
795 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
796 ret->spillInfoOnComponents(compNames);
801 * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
802 * 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.
803 * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
804 * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
806 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
809 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
810 (*it)->spillInfoOnComponents(compNames);
814 * Assign nature for each fields in \a this.
817 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
820 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
821 (*it)->spillNatures(nfs);
824 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const
826 return new MEDCouplingAMRAttribute(*this,true);
829 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const
831 return new MEDCouplingAMRAttribute(*this,false);
835 * 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).
838 int MEDCouplingAMRAttribute::getNumberOfLevels() const
840 checkGodFatherFrozen();
841 return (int)_levs.size();
845 * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
846 * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
848 * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
849 * \sa retrieveFieldOn
851 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
853 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
856 if((*it)->presenceOf(mesh,tmp))
858 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
859 return ddc.retrieveFields();
862 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
866 * \sa retrieveFieldsOn
868 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
870 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
873 if((*it)->presenceOf(mesh,tmp))
875 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
876 return ddc.getFieldWithName(fieldName);
879 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn : the mesh specified is not in the progeny of this !");
882 DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName)
884 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
887 if((*it)->presenceOf(mesh,tmp))
889 DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
890 return ddc.getFieldWithName(fieldName);
893 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn non const : the mesh specified is not in the progeny of this !");
897 * This method returns a field on an unstructured mesh the most refined as possible without overlap.
898 * Ghost part are not visible here.
900 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
902 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
904 std::vector<const DataArrayDouble *> recurseArrs;
906 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
909 if((*it)->presenceOf(mesh,tmp))
911 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
912 recurseArrs.push_back(ddc.getFieldWithName(fieldName));
917 for(std::size_t i=lev;i<_levs.size();i++)
919 const MEDCouplingGridCollection *gc(_levs[i]);
920 gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
922 return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
926 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
927 * The output field also displays ghost cells.
929 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
931 * \sa buildCellFieldOnWithoutGhost
933 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
935 const DataArrayDouble *arr(0);
936 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
939 if((*it)->presenceOf(mesh,tmp))
941 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
942 arr=ddc.getFieldWithName(fieldName);
946 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
947 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
948 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
950 ret->setArray(const_cast<DataArrayDouble *>(arr));
951 ret->setName(arr->getName());
956 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
957 * The output field does not display ghost cells.
959 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
961 * \sa buildCellFieldOnWithGhost
963 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
965 const DataArrayDouble *arr(0);
966 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
969 if((*it)->presenceOf(mesh,tmp))
971 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
972 arr=ddc.getFieldWithName(fieldName);
976 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
978 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
979 std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
980 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New());
981 arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
982 std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
983 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
984 std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
985 MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
986 arr2->copyStringInfoFrom(*arr);
988 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
989 ret->setMesh(mesh->getImageMesh());
991 ret->setName(arr->getName());
996 std::string MEDCouplingAMRAttribute::writeVTHB(const std::string& fileName) const
998 static const char EXT[]=".vthb";
999 std::string baseName,extName,zeFileName;
1000 MEDCouplingMesh::SplitExtension(fileName,baseName,extName);
1002 zeFileName=fileName;
1004 { zeFileName=baseName; zeFileName+=EXT; }
1006 std::ofstream ofs(fileName.c_str());
1007 ofs << "<VTKFile type=\"vtkOverlappingAMR\" version=\"1.1\" byte_order=\"" << MEDCouplingByteOrderStr() << "\">\n";
1008 const MEDCouplingCartesianAMRMesh *gf(getMyGodFather());
1009 ofs << " <vtkOverlappingAMR origin=\"";
1010 const MEDCouplingIMesh *gfm(gf->getImageMesh());
1011 std::vector<double> orig(gfm->getOrigin());
1012 std::vector<double> spacing(gfm->getDXYZ());
1013 int dim((int)orig.size());
1014 std::copy(orig.begin(),orig.end(),std::ostream_iterator<double>(ofs," ")); ofs << "\" grid_description=\"";
1015 for(int i=0;i<dim;i++)
1017 char tmp[2]; tmp[0]='X'+i; tmp[1]='\0';
1022 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()),kk(0);
1023 for(int i=0;i<maxLev;i++)
1025 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1026 std::size_t sz(patches.size());
1027 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(sz);
1028 for(std::size_t j=0;j<sz;j++)
1029 patchesSafe[j]=patches[j];
1032 ofs << " <Block level=\"" << i << "\" spacing=\"";
1033 std::copy(spacing.begin(),spacing.end(),std::ostream_iterator<double>(ofs," "));
1037 std::vector<int> factors(patches[0]->getMesh()->getFactors());
1038 for(int k=0;k<dim;k++)
1039 spacing[k]*=1./((double) factors[k]);
1042 for(std::vector<MEDCouplingCartesianAMRPatchGen *>::const_iterator it=patches.begin();it!=patches.end();it++,jj++,kk++)
1044 ofs << " <DataSet index=\"" << jj << "\" amr_box=\"";
1045 const MEDCouplingCartesianAMRPatch *patchCast(dynamic_cast<const MEDCouplingCartesianAMRPatch *>(*it));
1046 const MEDCouplingCartesianAMRMeshGen *mesh((*it)->getMesh());
1049 const std::vector< std::pair<int,int> >& bltr(patchCast->getBLTRRangeRelativeToGF());
1050 for(int pp=0;pp<dim;pp++)
1051 ofs << bltr[pp].first << " " << bltr[pp].second-1 << " ";
1055 const MEDCouplingIMesh *im((*it)->getMesh()->getImageMesh());
1056 std::vector<int> cgs(im->getCellGridStructure());
1057 for(int pp=0;pp<dim;pp++)
1058 ofs << "0 " << cgs[pp]-1 << " ";
1060 ofs << "\" file=\"";
1063 if(_levs[i]->presenceOf((*it)->getMesh(),tmp))
1065 const DataArrayDoubleCollection& ddc(_levs[i]->getFieldsAt(tmp));
1066 std::vector<DataArrayDouble *> arrs(ddc.retrieveFields());
1067 std::size_t nbFields(arrs.size());
1068 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrsSafe(nbFields),arrs2Safe(nbFields);
1069 std::vector< const MEDCouplingFieldDouble *> fields(nbFields);
1070 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> > fieldsSafe(nbFields);
1071 for(std::size_t pp=0;pp<nbFields;pp++)
1072 arrsSafe[pp]=arrs[pp];
1073 for(std::size_t pp=0;pp<nbFields;pp++)
1075 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
1076 std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
1077 arrs2Safe[pp]=DataArrayDouble::New();
1078 arrs2Safe[pp]->alloc(mesh->getImageMesh()->getNumberOfCells(),arrs[pp]->getNumberOfComponents());
1079 std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
1080 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
1081 std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
1082 MEDCouplingIMesh::SpreadCoarseToFine(arrs[pp],cgsWG,arrs2Safe[pp],cgs2,fakeFactors);
1083 arrs2Safe[pp]->copyStringInfoFrom(*arrs[pp]);
1085 fieldsSafe[pp]=MEDCouplingFieldDouble::New(ON_CELLS); fields[pp]=fieldsSafe[pp];
1086 fieldsSafe[pp]->setMesh(mesh->getImageMesh());
1087 fieldsSafe[pp]->setArray(arrs2Safe[pp]);
1088 fieldsSafe[pp]->setName(arrs[pp]->getName());
1090 std::ostringstream vtiFileName; vtiFileName << baseName << "_" << kk << ".vti";
1091 MEDCouplingFieldDouble::WriteVTK(vtiFileName.str(),fields,true);
1093 ofs << vtiFileName.str() << "\">\n";
1094 ofs << " \n </DataSet>\n";
1097 ofs << " </Block>\n";
1100 ofs << " </vtkOverlappingAMR>\n";
1101 ofs << "</VTKFile>\n";
1106 * This method is useful just after a remesh after a time step computation to project values in \a this to the new
1109 * This method performs a projection from \a this to a target AMR mesh \a targetGF.
1110 * This method performs the projection by trying to transfer the finest information to \a targetGF.
1111 * \b WARNING this method does not update the ghost zone, if any.
1112 * The level0 of \a this god father must have the same structure than those of \a targetGF.
1114 * This method makes checks that ghost size of \a this and \a targetGF are the same, and that
1115 * the number of levels in \a this and in \a targetGF are also the same.
1117 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const
1120 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !");
1122 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !");
1123 const MEDCouplingGridCollection *lev0(_levs[0]);
1125 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !");
1126 std::vector< std::pair < std::string, std::vector<std::string> > > fieldNames(lev0->getInfoOnComponents());
1127 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev));
1128 ret->spillNatures(lev0->getNatures());
1130 int nbLevs(getNumberOfLevels());
1131 if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs)
1132 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !");
1133 // first step copy level0
1134 if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure())
1135 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !");
1136 const DataArrayDoubleCollection& col(lev0->getFieldsAt(0));
1137 DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0));
1138 colTarget.copyFrom(col);
1139 // then go deeper and deeper
1140 for(int i=1;i<nbLevs;i++)
1142 ret->synchronizeCoarseToFineByOneLevel(i-1);
1143 MEDCouplingGridCollection *targetCol(ret->_levs[i]);
1145 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !");
1146 const MEDCouplingGridCollection *thisCol(_levs[i]);
1148 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !");
1149 targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol);
1155 * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
1156 * MEDCouplingAMRAttribute::alloc method.
1157 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse)
1159 * \sa synchronizeFineToCoarseBetween
1161 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
1164 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
1165 std::size_t sz(_levs.size());
1170 synchronizeFineToCoarseByOneLevel((int)sz);
1175 * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
1176 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
1177 * until reaching \a toLev level.
1178 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse).
1180 * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
1181 * \param [in] toLev - an existing level considered as the target level to reach.
1184 void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
1186 int nbl(getNumberOfLevels());
1187 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1188 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1190 return ;//nothing to do
1192 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
1193 for(int i=fromLev;i>toLev;i--)
1194 synchronizeFineToCoarseByOneLevel(i);
1198 * 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
1199 * MEDCouplingAMRAttribute::alloc method.
1200 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method)
1202 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
1205 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
1206 std::size_t sz(_levs.size());
1208 for(std::size_t i=0;i<sz-1;i++)
1209 synchronizeCoarseToFineByOneLevel((int)i);
1213 * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
1214 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
1215 * until reaching \a toLev level.
1216 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarseBetween method)
1218 * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
1219 * \param [in] toLev - an existing level considered as the target level to reach.
1221 void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
1223 int nbl(getNumberOfLevels());
1224 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1225 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1227 return ;//nothing to do
1229 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
1230 for(int i=fromLev;i<toLev;i++)
1231 synchronizeCoarseToFineByOneLevel(i);
1235 * This method synchronizes the ghost zone of all patches (excepted the god father one).
1236 * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
1238 * - firstly coarse to fine with no interactions between brother patches.
1239 * - secondly connected brother patches in a same master patch are updated.
1240 * - thirdly connected nephew patches are updated each other.
1241 * - forthly nth generation cousin patches are updated each other.
1243 * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
1244 * So if \a _ghost_lev == 0 this method has no effect.
1246 void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
1248 int sz(getNumberOfLevels());
1250 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
1251 // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
1252 for(int i=1;i<sz;i++)
1254 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
1255 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1257 // 2nd - classical direct sublevel inside common patch
1258 for(int i=1;i<sz;i++)
1260 const MEDCouplingGridCollection *curLev(_levs[i]);
1262 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
1263 curLev->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
1265 // 3rd - mixed level
1266 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
1268 const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
1269 DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
1271 // 4th - same level but with far ancestor.
1272 for(int i=1;i<sz;i++)
1274 const MEDCouplingGridCollection *fine(_levs[i]);
1275 fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
1280 * 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.
1281 * 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).
1282 * 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.
1283 * 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.
1285 * \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.
1288 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh)
1291 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !");
1292 int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels());
1293 if(level<0 || level>=sz-1)
1294 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !");
1295 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& itemsToFilter(_neighbors[level+1]);
1296 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > itemsToSync; itemsToSync.reserve(itemsToFilter.size());
1297 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++)
1299 if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh)
1300 itemsToSync.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>((*it).first,(*it).second));
1302 const MEDCouplingGridCollection *curLev(_levs[level+1]);
1304 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !");
1305 curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync);
1309 * This method updates \b all the patches at level \a level each other without consideration of their father.
1310 * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf.
1312 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level)
1314 int maxLev(getNumberOfLevels());
1315 if(level<0 || level>=maxLev)
1316 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !");
1318 return ;//at level 0 only one patch -> no need to update
1319 // 1st step - updates all patches pairs at level \a level sharing the same father
1320 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items(_neighbors[level]);
1321 const MEDCouplingGridCollection *curLev(_levs[level]);
1323 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !");
1324 curLev->synchronizeFineEachOther(_ghost_lev,items);
1325 //2nd step - updates all patches pairs at level \a level not sharing the same father
1326 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items2(_cross_lev_neighbors[level]);
1327 curLev->synchronizeFineEachOtherExt(_ghost_lev,items2);
1331 * 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).
1332 * This method is useful to propagate to the ghost zone of childhood the modification.
1334 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level)
1336 int maxLev(getNumberOfLevels());
1337 if(level<=0 || level>=maxLev)
1338 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !");
1339 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1340 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1341 //_cross_lev_neighbors is not needed.
1345 * This method allocates all DataArrayDouble instances stored recursively in \a this.
1349 void MEDCouplingAMRAttribute::alloc()
1352 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1354 MEDCouplingGridCollection *elt(*it);
1356 elt->alloc(_ghost_lev);
1358 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
1363 * This method deallocates all DataArrayDouble instances stored recursively in \a this.
1366 void MEDCouplingAMRAttribute::dealloc()
1369 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1371 MEDCouplingGridCollection *elt(*it);
1375 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
1379 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
1381 bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
1385 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
1387 std::size_t ret(sizeof(MEDCouplingAMRAttribute));
1388 ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
1392 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildrenWithNull() const
1394 std::vector<const BigMemoryObject *> ret;
1395 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1396 ret.push_back((const MEDCouplingGridCollection *)*it);
1400 void MEDCouplingAMRAttribute::updateTime() const
1404 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
1406 //gf non empty, checked by constructor
1407 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
1408 _levs.resize(maxLev);
1409 for(int i=0;i<maxLev;i++)
1411 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1412 std::size_t sz(patches.size());
1413 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
1414 for(std::size_t j=0;j<sz;j++)
1415 patchesSafe[j]=patches[j];
1416 std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
1417 for(std::size_t j=0;j<sz;j++)
1419 ms[j]=patches[j]->getMesh();
1421 _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
1423 // updates cross levels neighbors
1424 _neighbors.resize(_levs.size());
1425 _cross_lev_neighbors.resize(_levs.size());
1427 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
1428 std::size_t sz(_levs.size());
1429 for(std::size_t i=1;i<sz;i++)
1431 const MEDCouplingGridCollection *fine(_levs[i]);
1433 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
1434 _neighbors[i]=fine->findNeighbors(_ghost_lev);
1437 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
1439 MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
1440 std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
1441 std::size_t fullLev(i+neighs2.size());
1443 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
1444 std::size_t ii(i+1);
1445 for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
1446 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
1452 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)
1454 std::size_t sz(other._levs.size());
1455 for(std::size_t i=0;i<sz;i++)
1457 const MEDCouplingGridCollection *elt(other._levs[i]);
1460 _levs[i]=other._levs[i]->deepCpy(_gf,other._gf);
1463 //_cross_lev_neighbors(other._cross_lev_neighbors)
1464 sz=other._neighbors.size();
1465 for(std::size_t i=0;i<sz;i++)
1467 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._neighbors[i]);
1468 std::size_t sz2(neigh2.size());
1469 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_neighbors[i]);
1470 for(std::size_t j=0;j<sz2;j++)
1472 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1473 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1474 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1475 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1479 sz=other._mixed_lev_neighbors.size();
1480 for(std::size_t i=0;i<sz;i++)
1482 const MEDCouplingCartesianAMRPatch *p1(other._mixed_lev_neighbors[i].first),*p2(other._mixed_lev_neighbors[i].second);
1483 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1484 _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1);
1485 _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2);
1488 sz=other._cross_lev_neighbors.size();
1489 for(std::size_t i=0;i<sz;i++)
1491 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._cross_lev_neighbors[i]);
1492 std::size_t sz2(neigh2.size());
1493 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_cross_lev_neighbors[i]);
1494 for(std::size_t j=0;j<sz2;j++)
1496 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1497 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1498 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1499 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1504 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
1506 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1508 const MEDCouplingGridCollection *elt(*it);
1512 if(elt->presenceOf(m,tmp))
1514 return elt->getFieldsAt(tmp);
1518 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
1521 void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
1523 int nbl(getNumberOfLevels());
1524 if(level<=0 || level>=nbl)
1525 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
1526 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1527 MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
1530 void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
1532 int nbl(getNumberOfLevels());
1533 if(level<0 || level>=nbl-1)
1534 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
1535 const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
1536 MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);