1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay
21 #include "MEDCouplingAMRAttribute.hxx"
22 #include "MEDCouplingFieldDouble.hxx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingIMesh.hxx"
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::getDirectChildren() 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++)
337 const DataArrayDouble *pt((*it).first);
344 void DataArrayDoubleCollection::updateTime() const
346 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
348 const DataArrayDouble *pt((*it).first);
354 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
356 std::set<std::string> s(names.begin(),names.end());
357 if(s.size()!=names.size())
358 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
361 bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
364 return n==RevIntegral || n==IntegralGlobConstraint;
367 void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
369 CheckValidNature(n1);
370 CheckValidNature(n2);
372 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
375 void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
377 if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral)
378 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
381 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
383 return new MEDCouplingGridCollection(ms,fieldNames);
386 MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
388 return new MEDCouplingGridCollection(*this,newGf,oldGf);
391 void MEDCouplingGridCollection::alloc(int ghostLev)
393 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
395 int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
396 DataArrayDoubleCollection *dadc((*it).second);
398 dadc->allocTuples(nbTuples);
400 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
404 void MEDCouplingGridCollection::dealloc()
406 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
408 DataArrayDoubleCollection *dadc((*it).second);
410 dadc->dellocTuples();
412 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
416 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
418 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
419 (*it).second->spillInfoOnComponents(compNames);
422 void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
424 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
425 (*it).second->spillNatures(nfs);
428 std::vector< std::pair<std::string, std::vector<std::string> > > MEDCouplingGridCollection::getInfoOnComponents() const
430 if(_map_of_dadc.empty())
431 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !");
432 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
434 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !");
435 return elt->getInfoOnComponents();
438 std::vector<NatureOfField> MEDCouplingGridCollection::getNatures() const
440 if(_map_of_dadc.empty())
441 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !");
442 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
444 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !");
445 return elt->getNatures();
448 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
451 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
462 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
464 if(pos<0 || pos>(int)_map_of_dadc.size())
465 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
466 return *_map_of_dadc[pos].second;
469 DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos)
471 if(pos<0 || pos>(int)_map_of_dadc.size())
472 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !");
473 return *_map_of_dadc[pos].second;
477 * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting
478 * part of fields of \a this. The fields are expected to be the same between \a other and \a this.
479 * 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.
481 void MEDCouplingGridCollection::copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other)
483 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
485 std::vector<int> deltaThis,deltaOther;
486 std::vector< std::pair<int,int> > rgThis((*it).first->positionRelativeToGodFather(deltaThis));
487 std::vector<int> thisSt((*it).first->getImageMesh()->getCellGridStructure());
488 std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
489 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++)
491 std::vector< std::pair<int,int> > rgOther((*it2).first->positionRelativeToGodFather(deltaOther));
492 if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther))
494 std::vector< std::pair<int,int> > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther));
495 std::vector< std::pair<int,int> > pThis,pOther;
496 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true);
497 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true);
498 std::vector<int> otherSt((*it2).first->getImageMesh()->getCellGridStructure());
499 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev);
500 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev);
501 std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
502 int sz((*it2).second->size());
503 for(int i=0;i<sz;i++)
505 const DataArrayDouble *otherArr((*it2).second->at(i));
506 DataArrayDouble *thisArr((*it).second->at(i));
507 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther));
508 MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther);
515 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
518 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
519 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
520 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
521 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
523 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
524 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
526 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
528 if((*it0).first==fatherOfFineMesh)
531 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
532 const DataArrayDoubleCollection *coarseDaCol((*it0).second);
533 DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
534 DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
538 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
542 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
545 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
546 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
547 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
548 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
550 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
551 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
553 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
555 if((*it0).first==fatherOfFineMesh)
558 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
559 const DataArrayDoubleCollection *fineDaCol((*it).second);
560 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
561 DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
565 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
570 * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
572 * \sa synchronizeFineEachOtherExt
574 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
576 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
579 if(!presenceOf((*it).first->getMesh(),p1))
580 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
581 if(!presenceOf((*it).second->getMesh(),p2))
582 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
583 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
584 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
585 col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
590 * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
592 * \sa synchronizeFineEachOther
594 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
596 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
599 if(!presenceOf((*it).first->getMesh(),p1))
600 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
601 if(!presenceOf((*it).second->getMesh(),p2))
602 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
603 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
604 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
605 col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
610 * The pairs returned share the same direct father. The number of returned elements must be even.
612 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
614 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
615 std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
616 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
618 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
619 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
620 m[fatherOfFineMesh].push_back(fineMesh);
622 for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
624 for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
626 int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
627 std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
628 const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
629 for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
631 const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
632 ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
637 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
641 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
644 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
645 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
646 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
647 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
649 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
650 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
652 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
654 if((*it0).first==fatherOfFineMesh)
657 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
658 const DataArrayDoubleCollection *fineDaCol((*it).second);
659 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
660 DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
664 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
668 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
670 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
672 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
673 if(head==a || head->isObjectInTheProgeny(a))
675 const DataArrayDoubleCollection *gc((*it).second);
676 recurseArrs.push_back(gc->getFieldWithName(fieldName));
681 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
683 std::size_t sz(ms.size());
684 for(std::size_t i=0;i<sz;i++)
687 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
688 _map_of_dadc[i].first=ms[i];
689 _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
693 MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
695 std::size_t sz(other._map_of_dadc.size());
696 for(std::size_t i=0;i<sz;i++)
698 std::vector<int> pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf));
699 _map_of_dadc[i].first=newGf->getMeshAtPosition(pos);
700 const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
702 _map_of_dadc[i].second=dac->deepCpy();
706 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
708 std::size_t ret(sizeof(MEDCouplingGridCollection));
709 ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
713 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
715 std::vector<const BigMemoryObject *> ret;
716 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
718 const DataArrayDoubleCollection *col((*it).second);
725 void MEDCouplingGridCollection::updateTime() const
727 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
729 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
732 const DataArrayDoubleCollection *b((*it).second);
738 MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather()
743 const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const
748 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
751 throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
755 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
760 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
762 bool ret(_tlc.keepTrackOfNewTL(gf));
772 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
774 other._tlc.checkConst();
777 const MEDCouplingCartesianAMRMesh *gf(other._gf);
780 _tlc.keepTrackOfNewTL(_gf);
785 * 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.
787 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
789 return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
792 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
794 std::size_t sz(fieldNames.size());
795 std::vector< std::pair<std::string,int> > fieldNames2(sz);
796 std::vector< std::vector<std::string> > compNames(sz);
797 for(std::size_t i=0;i<sz;i++)
799 fieldNames2[i].first=fieldNames[i].first;
800 fieldNames2[i].second=(int)fieldNames[i].second.size();
801 compNames[i]=fieldNames[i].second;
803 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
804 ret->spillInfoOnComponents(compNames);
809 * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
810 * 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.
811 * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
812 * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
814 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
817 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
818 (*it)->spillInfoOnComponents(compNames);
822 * Assign nature for each fields in \a this.
825 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
828 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
829 (*it)->spillNatures(nfs);
832 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const
834 return new MEDCouplingAMRAttribute(*this,true);
837 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const
839 return new MEDCouplingAMRAttribute(*this,false);
843 * 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).
846 int MEDCouplingAMRAttribute::getNumberOfLevels() const
848 checkGodFatherFrozen();
849 return (int)_levs.size();
853 * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
854 * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
856 * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
857 * \sa retrieveFieldOn
859 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
861 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
864 if((*it)->presenceOf(mesh,tmp))
866 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
867 return ddc.retrieveFields();
870 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
874 * \sa retrieveFieldsOn
876 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
878 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
881 if((*it)->presenceOf(mesh,tmp))
883 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
884 return ddc.getFieldWithName(fieldName);
887 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn : the mesh specified is not in the progeny of this !");
890 DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName)
892 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
895 if((*it)->presenceOf(mesh,tmp))
897 DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
898 return ddc.getFieldWithName(fieldName);
901 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn non const : the mesh specified is not in the progeny of this !");
905 * This method returns a field on an unstructured mesh the most refined as possible without overlap.
906 * Ghost part are not visible here.
908 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
910 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
912 std::vector<const DataArrayDouble *> recurseArrs;
914 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
917 if((*it)->presenceOf(mesh,tmp))
919 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
920 recurseArrs.push_back(ddc.getFieldWithName(fieldName));
925 for(std::size_t i=lev;i<_levs.size();i++)
927 const MEDCouplingGridCollection *gc(_levs[i]);
928 gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
930 return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
934 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
935 * The output field also displays ghost cells.
937 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
939 * \sa buildCellFieldOnWithoutGhost
941 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
943 const DataArrayDouble *arr(0);
944 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
947 if((*it)->presenceOf(mesh,tmp))
949 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
950 arr=ddc.getFieldWithName(fieldName);
954 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
955 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
956 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
958 ret->setArray(const_cast<DataArrayDouble *>(arr));
959 ret->setName(arr->getName());
964 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
965 * The output field does not display ghost cells.
967 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
969 * \sa buildCellFieldOnWithGhost
971 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
973 const DataArrayDouble *arr(0);
974 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
977 if((*it)->presenceOf(mesh,tmp))
979 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
980 arr=ddc.getFieldWithName(fieldName);
984 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
986 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
987 std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
988 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New());
989 arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
990 std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
991 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
992 std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
993 MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
994 arr2->copyStringInfoFrom(*arr);
996 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
997 ret->setMesh(mesh->getImageMesh());
999 ret->setName(arr->getName());
1004 std::string MEDCouplingAMRAttribute::writeVTHB(const std::string& fileName) const
1006 static const char EXT[]=".vthb";
1007 std::string baseName,extName,zeFileName;
1008 MEDCouplingMesh::SplitExtension(fileName,baseName,extName);
1010 zeFileName=fileName;
1012 { zeFileName=baseName; zeFileName+=EXT; }
1014 std::ofstream ofs(fileName.c_str());
1015 ofs << "<VTKFile type=\"vtkOverlappingAMR\" version=\"1.1\" byte_order=\"" << MEDCouplingByteOrderStr() << "\">\n";
1016 const MEDCouplingCartesianAMRMesh *gf(getMyGodFather());
1017 ofs << " <vtkOverlappingAMR origin=\"";
1018 const MEDCouplingIMesh *gfm(gf->getImageMesh());
1019 std::vector<double> orig(gfm->getOrigin());
1020 std::vector<double> spacing(gfm->getDXYZ());
1021 int dim((int)orig.size());
1022 std::copy(orig.begin(),orig.end(),std::ostream_iterator<double>(ofs," ")); ofs << "\" grid_description=\"";
1023 for(int i=0;i<dim;i++)
1025 char tmp[2]; tmp[0]='X'+i; tmp[1]='\0';
1030 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()),kk(0);
1031 for(int i=0;i<maxLev;i++)
1033 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1034 std::size_t sz(patches.size());
1035 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(sz);
1036 for(std::size_t j=0;j<sz;j++)
1037 patchesSafe[j]=patches[j];
1040 ofs << " <Block level=\"" << i << "\" spacing=\"";
1041 std::copy(spacing.begin(),spacing.end(),std::ostream_iterator<double>(ofs," "));
1045 std::vector<int> factors(patches[0]->getMesh()->getFactors());
1046 for(int k=0;k<dim;k++)
1047 spacing[k]*=1./((double) factors[k]);
1050 for(std::vector<MEDCouplingCartesianAMRPatchGen *>::const_iterator it=patches.begin();it!=patches.end();it++,jj++,kk++)
1052 ofs << " <DataSet index=\"" << jj << "\" amr_box=\"";
1053 const MEDCouplingCartesianAMRPatch *patchCast(dynamic_cast<const MEDCouplingCartesianAMRPatch *>(*it));
1054 const MEDCouplingCartesianAMRMeshGen *mesh((*it)->getMesh());
1057 const std::vector< std::pair<int,int> >& bltr(patchCast->getBLTRRangeRelativeToGF());
1058 for(int pp=0;pp<dim;pp++)
1059 ofs << bltr[pp].first << " " << bltr[pp].second-1 << " ";
1063 const MEDCouplingIMesh *im((*it)->getMesh()->getImageMesh());
1064 std::vector<int> cgs(im->getCellGridStructure());
1065 for(int pp=0;pp<dim;pp++)
1066 ofs << "0 " << cgs[pp]-1 << " ";
1068 ofs << "\" file=\"";
1071 if(_levs[i]->presenceOf((*it)->getMesh(),tmp))
1073 const DataArrayDoubleCollection& ddc(_levs[i]->getFieldsAt(tmp));
1074 std::vector<DataArrayDouble *> arrs(ddc.retrieveFields());
1075 std::size_t nbFields(arrs.size());
1076 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrsSafe(nbFields),arrs2Safe(nbFields);
1077 std::vector< const MEDCouplingFieldDouble *> fields(nbFields);
1078 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> > fieldsSafe(nbFields);
1079 for(std::size_t pp=0;pp<nbFields;pp++)
1080 arrsSafe[pp]=arrs[pp];
1081 for(std::size_t pp=0;pp<nbFields;pp++)
1083 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
1084 std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
1085 arrs2Safe[pp]=DataArrayDouble::New();
1086 arrs2Safe[pp]->alloc(mesh->getImageMesh()->getNumberOfCells(),arrs[pp]->getNumberOfComponents());
1087 std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
1088 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
1089 std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
1090 MEDCouplingIMesh::SpreadCoarseToFine(arrs[pp],cgsWG,arrs2Safe[pp],cgs2,fakeFactors);
1091 arrs2Safe[pp]->copyStringInfoFrom(*arrs[pp]);
1093 fieldsSafe[pp]=MEDCouplingFieldDouble::New(ON_CELLS); fields[pp]=fieldsSafe[pp];
1094 fieldsSafe[pp]->setMesh(mesh->getImageMesh());
1095 fieldsSafe[pp]->setArray(arrs2Safe[pp]);
1096 fieldsSafe[pp]->setName(arrs[pp]->getName());
1098 std::ostringstream vtiFileName; vtiFileName << baseName << "_" << kk << ".vti";
1099 MEDCouplingFieldDouble::WriteVTK(vtiFileName.str(),fields,true);
1101 ofs << vtiFileName.str() << "\">\n";
1102 ofs << " \n </DataSet>\n";
1105 ofs << " </Block>\n";
1108 ofs << " </vtkOverlappingAMR>\n";
1109 ofs << "</VTKFile>\n";
1114 * This method is useful just after a remesh after a time step computation to project values in \a this to the new
1117 * This method performs a projection from \a this to a target AMR mesh \a targetGF.
1118 * This method performs the projection by trying to transfer the finest information to \a targetGF.
1119 * \b WARNING this method does not update the ghost zone, if any.
1120 * The level0 of \a this god father must have the same structure than those of \a targetGF.
1122 * This method makes checks that ghost size of \a this and \a targetGF are the same, and that
1123 * the number of levels in \a this and in \a targetGF are also the same.
1125 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const
1128 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !");
1130 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !");
1131 const MEDCouplingGridCollection *lev0(_levs[0]);
1133 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !");
1134 std::vector< std::pair < std::string, std::vector<std::string> > > fieldNames(lev0->getInfoOnComponents());
1135 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev));
1136 ret->spillNatures(lev0->getNatures());
1138 int nbLevs(getNumberOfLevels());
1139 if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs)
1140 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !");
1141 // first step copy level0
1142 if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure())
1143 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !");
1144 const DataArrayDoubleCollection& col(lev0->getFieldsAt(0));
1145 DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0));
1146 colTarget.copyFrom(col);
1147 // then go deeper and deeper
1148 for(int i=1;i<nbLevs;i++)
1150 ret->synchronizeCoarseToFineByOneLevel(i-1);
1151 MEDCouplingGridCollection *targetCol(ret->_levs[i]);
1153 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !");
1154 const MEDCouplingGridCollection *thisCol(_levs[i]);
1156 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !");
1157 targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol);
1163 * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
1164 * MEDCouplingAMRAttribute::alloc method.
1165 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse)
1167 * \sa synchronizeFineToCoarseBetween
1169 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
1172 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
1173 std::size_t sz(_levs.size());
1178 synchronizeFineToCoarseByOneLevel((int)sz);
1183 * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
1184 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
1185 * until reaching \a toLev level.
1186 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse).
1188 * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
1189 * \param [in] toLev - an existing level considered as the target level to reach.
1192 void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
1194 int nbl(getNumberOfLevels());
1195 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1196 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1198 return ;//nothing to do
1200 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
1201 for(int i=fromLev;i>toLev;i--)
1202 synchronizeFineToCoarseByOneLevel(i);
1206 * 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
1207 * MEDCouplingAMRAttribute::alloc method.
1208 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method)
1210 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
1213 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
1214 std::size_t sz(_levs.size());
1216 for(std::size_t i=0;i<sz-1;i++)
1217 synchronizeCoarseToFineByOneLevel((int)i);
1221 * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
1222 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
1223 * until reaching \a toLev level.
1224 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarseBetween method)
1226 * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
1227 * \param [in] toLev - an existing level considered as the target level to reach.
1229 void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
1231 int nbl(getNumberOfLevels());
1232 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1233 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1235 return ;//nothing to do
1237 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
1238 for(int i=fromLev;i<toLev;i++)
1239 synchronizeCoarseToFineByOneLevel(i);
1243 * This method synchronizes the ghost zone of all patches (excepted the god father one).
1244 * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
1246 * - firstly coarse to fine with no interactions between brother patches.
1247 * - secondly connected brother patches in a same master patch are updated.
1248 * - thirdly connected nephew patches are updated each other.
1249 * - forthly nth generation cousin patches are updated each other.
1251 * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
1252 * So if \a _ghost_lev == 0 this method has no effect.
1254 void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
1256 int sz(getNumberOfLevels());
1258 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
1259 // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
1260 for(int i=1;i<sz;i++)
1262 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
1263 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1265 // 2nd - classical direct sublevel inside common patch
1266 for(int i=1;i<sz;i++)
1268 const MEDCouplingGridCollection *curLev(_levs[i]);
1270 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
1271 curLev->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
1273 // 3rd - mixed level
1274 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
1276 const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
1277 DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
1279 // 4th - same level but with far ancestor.
1280 for(int i=1;i<sz;i++)
1282 const MEDCouplingGridCollection *fine(_levs[i]);
1283 fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
1288 * 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.
1289 * 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).
1290 * 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.
1291 * 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.
1293 * \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.
1296 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh)
1299 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !");
1300 int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels());
1301 if(level<0 || level>=sz-1)
1302 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !");
1303 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& itemsToFilter(_neighbors[level+1]);
1304 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > itemsToSync; itemsToSync.reserve(itemsToFilter.size());
1305 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++)
1307 if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh)
1308 itemsToSync.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>((*it).first,(*it).second));
1310 const MEDCouplingGridCollection *curLev(_levs[level+1]);
1312 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !");
1313 curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync);
1317 * This method updates \b all the patches at level \a level each other without consideration of their father.
1318 * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf.
1320 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level)
1322 int maxLev(getNumberOfLevels());
1323 if(level<0 || level>=maxLev)
1324 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !");
1326 return ;//at level 0 only one patch -> no need to update
1327 // 1st step - updates all patches pairs at level \a level sharing the same father
1328 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items(_neighbors[level]);
1329 const MEDCouplingGridCollection *curLev(_levs[level]);
1331 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !");
1332 curLev->synchronizeFineEachOther(_ghost_lev,items);
1333 //2nd step - updates all patches pairs at level \a level not sharing the same father
1334 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items2(_cross_lev_neighbors[level]);
1335 curLev->synchronizeFineEachOtherExt(_ghost_lev,items2);
1339 * 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).
1340 * This method is useful to propagate to the ghost zone of childhood the modification.
1342 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level)
1344 int maxLev(getNumberOfLevels());
1345 if(level<=0 || level>=maxLev)
1346 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !");
1347 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1348 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1349 //_cross_lev_neighbors is not needed.
1353 * This method allocates all DataArrayDouble instances stored recursively in \a this.
1357 void MEDCouplingAMRAttribute::alloc()
1360 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1362 MEDCouplingGridCollection *elt(*it);
1364 elt->alloc(_ghost_lev);
1366 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
1371 * This method deallocates all DataArrayDouble instances stored recursively in \a this.
1374 void MEDCouplingAMRAttribute::dealloc()
1377 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1379 MEDCouplingGridCollection *elt(*it);
1383 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
1387 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
1389 bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
1393 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
1395 std::size_t ret(sizeof(MEDCouplingAMRAttribute));
1396 ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
1400 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
1402 std::vector<const BigMemoryObject *> ret;
1403 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1405 const MEDCouplingGridCollection *elt(*it);
1412 void MEDCouplingAMRAttribute::updateTime() const
1416 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
1418 //gf non empty, checked by constructor
1419 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
1420 _levs.resize(maxLev);
1421 for(int i=0;i<maxLev;i++)
1423 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1424 std::size_t sz(patches.size());
1425 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
1426 for(std::size_t j=0;j<sz;j++)
1427 patchesSafe[j]=patches[j];
1428 std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
1429 for(std::size_t j=0;j<sz;j++)
1431 ms[j]=patches[j]->getMesh();
1433 _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
1435 // updates cross levels neighbors
1436 _neighbors.resize(_levs.size());
1437 _cross_lev_neighbors.resize(_levs.size());
1439 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
1440 std::size_t sz(_levs.size());
1441 for(std::size_t i=1;i<sz;i++)
1443 const MEDCouplingGridCollection *fine(_levs[i]);
1445 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
1446 _neighbors[i]=fine->findNeighbors(_ghost_lev);
1449 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
1451 MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
1452 std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
1453 std::size_t fullLev(i+neighs2.size());
1455 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
1456 std::size_t ii(i+1);
1457 for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
1458 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
1464 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)
1466 std::size_t sz(other._levs.size());
1467 for(std::size_t i=0;i<sz;i++)
1469 const MEDCouplingGridCollection *elt(other._levs[i]);
1472 _levs[i]=other._levs[i]->deepCpy(_gf,other._gf);
1475 //_cross_lev_neighbors(other._cross_lev_neighbors)
1476 sz=other._neighbors.size();
1477 for(std::size_t i=0;i<sz;i++)
1479 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._neighbors[i]);
1480 std::size_t sz2(neigh2.size());
1481 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_neighbors[i]);
1482 for(std::size_t j=0;j<sz2;j++)
1484 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1485 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1486 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1487 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1491 sz=other._mixed_lev_neighbors.size();
1492 for(std::size_t i=0;i<sz;i++)
1494 const MEDCouplingCartesianAMRPatch *p1(other._mixed_lev_neighbors[i].first),*p2(other._mixed_lev_neighbors[i].second);
1495 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1496 _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1);
1497 _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2);
1500 sz=other._cross_lev_neighbors.size();
1501 for(std::size_t i=0;i<sz;i++)
1503 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._cross_lev_neighbors[i]);
1504 std::size_t sz2(neigh2.size());
1505 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_cross_lev_neighbors[i]);
1506 for(std::size_t j=0;j<sz2;j++)
1508 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1509 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1510 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1511 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1516 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
1518 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1520 const MEDCouplingGridCollection *elt(*it);
1524 if(elt->presenceOf(m,tmp))
1526 return elt->getFieldsAt(tmp);
1530 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
1533 void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
1535 int nbl(getNumberOfLevels());
1536 if(level<=0 || level>=nbl)
1537 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
1538 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1539 MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
1542 void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
1544 int nbl(getNumberOfLevels());
1545 if(level<0 || level>=nbl-1)
1546 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
1547 const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
1548 MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);