1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay
21 #include "MEDCouplingAMRAttribute.hxx"
22 #include "MEDCouplingFieldDouble.hxx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingIMesh.hxx"
28 using namespace ParaMEDMEM;
30 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
32 return new DataArrayDoubleCollection(fieldNames);
35 DataArrayDoubleCollection *DataArrayDoubleCollection::deepCpy() const
37 return new DataArrayDoubleCollection(*this);
40 void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
42 std::size_t sz(_arrs.size());
43 for(std::size_t i=0;i<sz;i++)
44 _arrs[i].first->reAlloc(nbOfTuples);
47 void DataArrayDoubleCollection::dellocTuples()
49 std::size_t sz(_arrs.size());
50 for(std::size_t i=0;i<sz;i++)
51 _arrs[i].first->reAlloc(0);
54 void DataArrayDoubleCollection::copyFrom(const DataArrayDoubleCollection& other)
56 std::size_t sz(_arrs.size());
57 if(sz!=other._arrs.size())
58 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : size are not the same !");
59 for(std::size_t i=0;i<sz;i++)
61 DataArrayDouble *thisArr(_arrs[i].first);
62 const DataArrayDouble *otherArr(other._arrs[i].first);
63 if(!thisArr || !otherArr)
64 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : empty DataArray !");
65 thisArr->cpyFrom(*otherArr);
69 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
71 std::size_t sz(_arrs.size());
72 if(sz!=compNames.size())
73 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
74 for(std::size_t i=0;i<sz;i++)
76 const std::vector<std::string>& names(compNames[i]);
77 _arrs[i].first->setInfoOnComponents(names);
81 void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& nfs)
83 std::size_t sz(_arrs.size());
85 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !");
86 for(std::size_t i=0;i<sz;i++)
88 CheckValidNature(nfs[i]);
89 _arrs[i].second=nfs[i];
93 std::vector< std::pair < std::string, std::vector<std::string> > > DataArrayDoubleCollection::getInfoOnComponents() const
95 std::size_t sz(_arrs.size());
96 std::vector< std::pair < std::string, std::vector<std::string> > > ret(sz);
97 for(std::size_t i=0;i<sz;i++)
99 const DataArrayDouble *elt(_arrs[i].first);
101 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::getInfoOnComponents : empty array !");
102 ret[i]=std::pair < std::string, std::vector<std::string> >(elt->getName(),elt->getInfoOnComponents());
107 std::vector<NatureOfField> DataArrayDoubleCollection::getNatures() const
109 std::size_t sz(_arrs.size());
110 std::vector<NatureOfField> ret(sz);
111 for(std::size_t i=0;i<sz;i++)
112 ret[i]=_arrs[i].second;
116 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
118 std::size_t sz(_arrs.size());
119 std::vector<DataArrayDouble *> ret(sz);
120 for(std::size_t i=0;i<sz;i++)
122 const DataArrayDouble *tmp(_arrs[i].first);
123 ret[i]=const_cast<DataArrayDouble *>(tmp);
130 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
132 std::vector<std::string> vec;
133 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
135 const DataArrayDouble *obj((*it).first);
138 if(obj->getName()==name)
141 vec.push_back(obj->getName());
144 std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
145 std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
146 throw INTERP_KERNEL::Exception(oss.str().c_str());
149 DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name)
151 std::vector<std::string> vec;
152 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::iterator it=_arrs.begin();it!=_arrs.end();it++)
154 DataArrayDouble *obj((*it).first);
157 if(obj->getName()==name)
160 vec.push_back(obj->getName());
163 std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName non const : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
164 std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
165 throw INTERP_KERNEL::Exception(oss.str().c_str());
168 DataArrayDouble *DataArrayDoubleCollection::at(int pos)
170 if(pos<0 || pos>=(int)_arrs.size())
171 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at (non const) : pos must be in [0,nbOfFields) !");
172 return _arrs[pos].first;
175 const DataArrayDouble *DataArrayDoubleCollection::at(int pos) const
177 if(pos<0 || pos>=(int)_arrs.size())
178 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at : pos must be in [0,nbOfFields) !");
179 return _arrs[pos].first;
182 int DataArrayDoubleCollection::size() const
184 return (int)_arrs.size();
187 void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
190 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
191 std::size_t sz(coarse->_arrs.size());
192 if(fine->_arrs.size()!=sz)
193 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
194 for(std::size_t i=0;i<sz;i++)
196 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
197 fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
201 void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
204 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
205 std::size_t sz(coarse->_arrs.size());
206 if(fine->_arrs.size()!=sz)
207 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
208 for(std::size_t i=0;i<sz;i++)
210 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
211 fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
215 void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
217 if(!fatherOfFineMesh)
218 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
219 std::size_t sz(children.size());
220 if(fieldsOnFine.size()!=sz)
221 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
224 std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
225 for(std::size_t i=0;i<sz;i++)
226 if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
227 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
228 for(std::size_t i=1;i<sz;i++)
229 if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
230 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
231 for(std::size_t i=0;i<nbOfCall;i++)
233 std::vector<const DataArrayDouble *> arrs(sz);
234 for(std::size_t j=0;j<sz;j++)
235 arrs[j]=fieldsOnFine[j]->_arrs[i].first;
236 fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
241 * 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).
243 void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac)
245 if(!p1 || !p1dac || !p2 || !p2dac)
246 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !");
247 std::size_t sz(p1dac->_arrs.size());
248 if(p2dac->_arrs.size()!=sz)
249 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !");
250 for(std::size_t i=0;i<sz;i++)
252 const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first);
253 DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second);
254 bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second));
255 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative);
259 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
262 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
263 std::size_t sz(coarse->_arrs.size());
264 if(fine->_arrs.size()!=sz)
265 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
266 for(std::size_t i=0;i<sz;i++)
267 fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev);
270 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
272 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
273 std::size_t sz(_arrs.size());
274 if(other._arrs.size()!=sz)
275 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
276 for(std::size_t i=0;i<sz;i++)
277 father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
280 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
282 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
283 std::size_t sz(_arrs.size());
284 if(other._arrs.size()!=sz)
285 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
286 for(std::size_t i=0;i<sz;i++)
287 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
290 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
292 std::size_t sz(fieldNames.size());
293 std::vector<std::string> names(sz);
294 for(std::size_t i=0;i<sz;i++)
296 const std::pair<std::string,int>& info(fieldNames[i]);
299 std::ostringstream oss; oss << "DataArrayDoubleCollection constructor : At pos #" << i << " the array with name \"" << info.first << "\" as a number of components equal to " << info.second;
300 oss << " It has to be >=1 !";
301 throw INTERP_KERNEL::Exception(oss.str().c_str());
303 _arrs[i].first=DataArrayDouble::New();
304 _arrs[i].first->alloc(0,info.second);
305 _arrs[i].first->setName(info.first);
306 names[i]=info.second;
307 _arrs[i].second=ConservativeVolumic;
309 CheckDiscriminantNames(names);
312 DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size())
314 std::size_t sz(other._arrs.size());
315 for(std::size_t i=0;i<sz;i++)
317 _arrs[i].second=other._arrs[i].second;
318 const DataArrayDouble *da(other._arrs[i].first);
320 _arrs[i].first=da->deepCpy();
324 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
326 std::size_t ret(sizeof(DataArrayDoubleCollection));
327 ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
331 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
333 std::vector<const BigMemoryObject *> ret;
334 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
336 const DataArrayDouble *pt((*it).first);
343 void DataArrayDoubleCollection::updateTime() const
345 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
347 const DataArrayDouble *pt((*it).first);
353 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
355 std::set<std::string> s(names.begin(),names.end());
356 if(s.size()!=names.size())
357 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
360 bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
363 return n==RevIntegral || n==IntegralGlobConstraint;
366 void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
368 CheckValidNature(n1);
369 CheckValidNature(n2);
371 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
374 void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
376 if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral)
377 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
380 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
382 return new MEDCouplingGridCollection(ms,fieldNames);
385 MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
387 return new MEDCouplingGridCollection(*this,newGf,oldGf);
390 void MEDCouplingGridCollection::alloc(int ghostLev)
392 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
394 int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
395 DataArrayDoubleCollection *dadc((*it).second);
397 dadc->allocTuples(nbTuples);
399 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
403 void MEDCouplingGridCollection::dealloc()
405 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
407 DataArrayDoubleCollection *dadc((*it).second);
409 dadc->dellocTuples();
411 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
415 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
417 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
418 (*it).second->spillInfoOnComponents(compNames);
421 void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
423 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
424 (*it).second->spillNatures(nfs);
427 std::vector< std::pair<std::string, std::vector<std::string> > > MEDCouplingGridCollection::getInfoOnComponents() const
429 if(_map_of_dadc.empty())
430 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !");
431 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
433 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !");
434 return elt->getInfoOnComponents();
437 std::vector<NatureOfField> MEDCouplingGridCollection::getNatures() const
439 if(_map_of_dadc.empty())
440 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !");
441 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
443 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !");
444 return elt->getNatures();
447 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
450 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
461 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
463 if(pos<0 || pos>(int)_map_of_dadc.size())
464 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
465 return *_map_of_dadc[pos].second;
468 DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos)
470 if(pos<0 || pos>(int)_map_of_dadc.size())
471 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !");
472 return *_map_of_dadc[pos].second;
476 * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting
477 * part of fields of \a this. The fields are expected to be the same between \a other and \a this.
478 * 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.
480 void MEDCouplingGridCollection::copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other)
482 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
484 std::vector<int> deltaThis,deltaOther;
485 std::vector< std::pair<int,int> > rgThis((*it).first->positionRelativeToGodFather(deltaThis));
486 std::vector<int> thisSt((*it).first->getImageMesh()->getCellGridStructure());
487 std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
488 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++)
490 std::vector< std::pair<int,int> > rgOther((*it2).first->positionRelativeToGodFather(deltaOther));
491 if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther))
493 std::vector< std::pair<int,int> > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther));
494 std::vector< std::pair<int,int> > pThis,pOther;
495 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true);
496 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true);
497 std::vector<int> otherSt((*it2).first->getImageMesh()->getCellGridStructure());
498 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev);
499 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev);
500 std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
501 int sz((*it2).second->size());
502 for(int i=0;i<sz;i++)
504 const DataArrayDouble *otherArr((*it2).second->at(i));
505 DataArrayDouble *thisArr((*it).second->at(i));
506 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther));
507 MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther);
514 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
517 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
518 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
519 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
520 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
522 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
523 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
525 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
527 if((*it0).first==fatherOfFineMesh)
530 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
531 const DataArrayDoubleCollection *coarseDaCol((*it0).second);
532 DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
533 DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
537 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
541 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
544 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
545 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
546 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
547 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
549 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
550 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
552 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
554 if((*it0).first==fatherOfFineMesh)
557 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
558 const DataArrayDoubleCollection *fineDaCol((*it).second);
559 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
560 DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
564 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
569 * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
571 * \sa synchronizeFineEachOtherExt
573 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
575 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
578 if(!presenceOf((*it).first->getMesh(),p1))
579 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
580 if(!presenceOf((*it).second->getMesh(),p2))
581 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
582 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
583 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
584 col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
589 * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
591 * \sa synchronizeFineEachOther
593 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
595 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
598 if(!presenceOf((*it).first->getMesh(),p1))
599 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
600 if(!presenceOf((*it).second->getMesh(),p2))
601 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
602 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
603 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
604 col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
609 * The pairs returned share the same direct father. The number of returned elements must be even.
611 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
613 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
614 std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
615 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
617 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
618 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
619 m[fatherOfFineMesh].push_back(fineMesh);
621 for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
623 for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
625 int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
626 std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
627 const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
628 for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
630 const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
631 ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
636 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
640 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
643 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
644 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
645 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
646 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
648 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
649 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
651 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
653 if((*it0).first==fatherOfFineMesh)
656 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
657 const DataArrayDoubleCollection *fineDaCol((*it).second);
658 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
659 DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
663 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
667 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
669 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
671 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
672 if(head==a || head->isObjectInTheProgeny(a))
674 const DataArrayDoubleCollection *gc((*it).second);
675 recurseArrs.push_back(gc->getFieldWithName(fieldName));
680 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
682 std::size_t sz(ms.size());
683 for(std::size_t i=0;i<sz;i++)
686 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
687 _map_of_dadc[i].first=ms[i];
688 _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
692 MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
694 std::size_t sz(other._map_of_dadc.size());
695 for(std::size_t i=0;i<sz;i++)
697 std::vector<int> pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf));
698 _map_of_dadc[i].first=newGf->getMeshAtPosition(pos);
699 const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
701 _map_of_dadc[i].second=dac->deepCpy();
705 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
707 std::size_t ret(sizeof(MEDCouplingGridCollection));
708 ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
712 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
714 std::vector<const BigMemoryObject *> ret;
715 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
717 const DataArrayDoubleCollection *col((*it).second);
724 void MEDCouplingGridCollection::updateTime() const
726 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
728 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
731 const DataArrayDoubleCollection *b((*it).second);
737 MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather()
742 const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const
747 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
750 throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
754 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
759 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
761 bool ret(_tlc.keepTrackOfNewTL(gf));
771 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
773 other._tlc.checkConst();
776 const MEDCouplingCartesianAMRMesh *gf(other._gf);
779 _tlc.keepTrackOfNewTL(_gf);
784 * This method creates, attach to a main AMR mesh \a gf ( called god father :-) ) and returns a data linked to \a gf ready for the computation.
786 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
788 return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
791 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
793 std::size_t sz(fieldNames.size());
794 std::vector< std::pair<std::string,int> > fieldNames2(sz);
795 std::vector< std::vector<std::string> > compNames(sz);
796 for(std::size_t i=0;i<sz;i++)
798 fieldNames2[i].first=fieldNames[i].first;
799 fieldNames2[i].second=(int)fieldNames[i].second.size();
800 compNames[i]=fieldNames[i].second;
802 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
803 ret->spillInfoOnComponents(compNames);
808 * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
809 * The first dim of input \a compNames is the field id in the same order than those implicitely specified in \a fieldNames parameter of MEDCouplingAMRAttribute::New.
810 * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
811 * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
813 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
816 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
817 (*it)->spillInfoOnComponents(compNames);
821 * Assign nature for each fields in \a this.
824 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
827 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
828 (*it)->spillNatures(nfs);
831 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const
833 return new MEDCouplingAMRAttribute(*this,true);
836 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const
838 return new MEDCouplingAMRAttribute(*this,false);
842 * Returns the number of levels by \b only \b considering \a this (god father instance is considered only to see if it has not changed still last update of \a this).
845 int MEDCouplingAMRAttribute::getNumberOfLevels() const
847 checkGodFatherFrozen();
848 return (int)_levs.size();
852 * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
853 * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
855 * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
856 * \sa retrieveFieldOn
858 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
860 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
863 if((*it)->presenceOf(mesh,tmp))
865 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
866 return ddc.retrieveFields();
869 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
873 * \sa retrieveFieldsOn
875 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
877 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
880 if((*it)->presenceOf(mesh,tmp))
882 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
883 return ddc.getFieldWithName(fieldName);
886 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn : the mesh specified is not in the progeny of this !");
889 DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName)
891 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
894 if((*it)->presenceOf(mesh,tmp))
896 DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
897 return ddc.getFieldWithName(fieldName);
900 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn non const : the mesh specified is not in the progeny of this !");
904 * This method returns a field on an unstructured mesh the most refined as possible without overlap.
905 * Ghost part are not visible here.
907 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
909 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
911 std::vector<const DataArrayDouble *> recurseArrs;
913 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
916 if((*it)->presenceOf(mesh,tmp))
918 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
919 recurseArrs.push_back(ddc.getFieldWithName(fieldName));
924 for(std::size_t i=lev;i<_levs.size();i++)
926 const MEDCouplingGridCollection *gc(_levs[i]);
927 gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
929 return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
933 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
934 * The output field also displays ghost cells.
936 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
938 * \sa buildCellFieldOnWithoutGhost
940 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
942 const DataArrayDouble *arr(0);
943 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
946 if((*it)->presenceOf(mesh,tmp))
948 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
949 arr=ddc.getFieldWithName(fieldName);
953 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
954 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
955 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
957 ret->setArray(const_cast<DataArrayDouble *>(arr));
958 ret->setName(arr->getName());
963 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
964 * The output field does not display ghost cells.
966 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
968 * \sa buildCellFieldOnWithGhost
970 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
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 * This method is useful just after a remesh after a time step computation to project values in \a this to the new
1007 * This method performs a projection from \a this to a target AMR mesh \a targetGF.
1008 * This method performs the projection by trying to transfer the finest information to \a targetGF.
1009 * \b WARNING this method does not update the ghost zone, if any.
1010 * The level0 of \a this god father must have the same structure than those of \a targetGF.
1012 * This method makes checks that ghost size of \a this and \a targetGF are the same, and that
1013 * the number of levels in \a this and in \a targetGF are also the same.
1015 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const
1018 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !");
1020 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !");
1021 const MEDCouplingGridCollection *lev0(_levs[0]);
1023 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !");
1024 std::vector< std::pair < std::string, std::vector<std::string> > > fieldNames(lev0->getInfoOnComponents());
1025 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev));
1026 ret->spillNatures(lev0->getNatures());
1028 int nbLevs(getNumberOfLevels());
1029 if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs)
1030 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !");
1031 // first step copy level0
1032 if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure())
1033 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !");
1034 const DataArrayDoubleCollection& col(lev0->getFieldsAt(0));
1035 DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0));
1036 colTarget.copyFrom(col);
1037 // then go deeper and deeper
1038 for(int i=1;i<nbLevs;i++)
1040 ret->synchronizeCoarseToFineByOneLevel(i-1);
1041 MEDCouplingGridCollection *targetCol(ret->_levs[i]);
1043 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !");
1044 const MEDCouplingGridCollection *thisCol(_levs[i]);
1046 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !");
1047 targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol);
1053 * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
1054 * MEDCouplingAMRAttribute::alloc method.
1055 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse)
1057 * \sa synchronizeFineToCoarseBetween
1059 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
1062 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
1063 std::size_t sz(_levs.size());
1068 synchronizeFineToCoarseByOneLevel((int)sz);
1073 * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
1074 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
1075 * until reaching \a toLev level.
1076 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse).
1078 * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
1079 * \param [in] toLev - an existing level considered as the target level to reach.
1082 void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
1084 int nbl(getNumberOfLevels());
1085 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1086 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1088 return ;//nothing to do
1090 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
1091 for(int i=fromLev;i>toLev;i--)
1092 synchronizeFineToCoarseByOneLevel(i);
1096 * 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
1097 * MEDCouplingAMRAttribute::alloc method.
1098 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method)
1100 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
1103 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
1104 std::size_t sz(_levs.size());
1106 for(std::size_t i=0;i<sz-1;i++)
1107 synchronizeCoarseToFineByOneLevel((int)i);
1111 * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
1112 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
1113 * until reaching \a toLev level.
1114 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarseBetween method)
1116 * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
1117 * \param [in] toLev - an existing level considered as the target level to reach.
1119 void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
1121 int nbl(getNumberOfLevels());
1122 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1123 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1125 return ;//nothing to do
1127 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
1128 for(int i=fromLev;i<toLev;i++)
1129 synchronizeCoarseToFineByOneLevel(i);
1133 * This method synchronizes the ghost zone of all patches (excepted the god father one).
1134 * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
1136 * - firstly coarse to fine with no interactions between brother patches.
1137 * - secondly connected brother patches in a same master patch are updated.
1138 * - thirdly connected nephew patches are updated each other.
1139 * - forthly nth generation cousin patches are updated each other.
1141 * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
1142 * So if \a _ghost_lev == 0 this method has no effect.
1144 void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
1146 int sz(getNumberOfLevels());
1148 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
1149 // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
1150 for(int i=1;i<sz;i++)
1152 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
1153 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1155 // 2nd - classical direct sublevel inside common patch
1156 for(int i=1;i<sz;i++)
1158 const MEDCouplingGridCollection *curLev(_levs[i]);
1160 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
1161 curLev->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
1163 // 3rd - mixed level
1164 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
1166 const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
1167 DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
1169 // 4th - same level but with far ancestor.
1170 for(int i=1;i<sz;i++)
1172 const MEDCouplingGridCollection *fine(_levs[i]);
1173 fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
1178 * 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.
1179 * 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).
1180 * 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.
1181 * 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.
1183 * \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.
1186 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh)
1189 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !");
1190 int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels());
1191 if(level<0 || level>=sz-1)
1192 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !");
1193 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& itemsToFilter(_neighbors[level+1]);
1194 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > itemsToSync; itemsToSync.reserve(itemsToFilter.size());
1195 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++)
1197 if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh)
1198 itemsToSync.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>((*it).first,(*it).second));
1200 const MEDCouplingGridCollection *curLev(_levs[level+1]);
1202 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !");
1203 curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync);
1207 * This method updates \b all the patches at level \a level each other without consideration of their father.
1208 * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf.
1210 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level)
1212 int maxLev(getNumberOfLevels());
1213 if(level<0 || level>=maxLev)
1214 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !");
1216 return ;//at level 0 only one patch -> no need to update
1217 // 1st step - updates all patches pairs at level \a level sharing the same father
1218 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items(_neighbors[level]);
1219 const MEDCouplingGridCollection *curLev(_levs[level]);
1221 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !");
1222 curLev->synchronizeFineEachOther(_ghost_lev,items);
1223 //2nd step - updates all patches pairs at level \a level not sharing the same father
1224 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items2(_cross_lev_neighbors[level]);
1225 curLev->synchronizeFineEachOtherExt(_ghost_lev,items2);
1229 * 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).
1230 * This method is useful to propagate to the ghost zone of childhood the modification.
1232 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level)
1234 int maxLev(getNumberOfLevels());
1235 if(level<=0 || level>=maxLev)
1236 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !");
1237 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1238 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1239 //_cross_lev_neighbors is not needed.
1243 * This method allocates all DataArrayDouble instances stored recursively in \a this.
1247 void MEDCouplingAMRAttribute::alloc()
1250 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1252 MEDCouplingGridCollection *elt(*it);
1254 elt->alloc(_ghost_lev);
1256 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
1261 * This method deallocates all DataArrayDouble instances stored recursively in \a this.
1264 void MEDCouplingAMRAttribute::dealloc()
1267 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1269 MEDCouplingGridCollection *elt(*it);
1273 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
1277 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
1279 bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
1283 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
1285 std::size_t ret(sizeof(MEDCouplingAMRAttribute));
1286 ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
1290 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
1292 std::vector<const BigMemoryObject *> ret;
1293 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1295 const MEDCouplingGridCollection *elt(*it);
1302 void MEDCouplingAMRAttribute::updateTime() const
1306 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
1308 //gf non empty, checked by constructor
1309 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
1310 _levs.resize(maxLev);
1311 for(int i=0;i<maxLev;i++)
1313 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1314 std::size_t sz(patches.size());
1315 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
1316 for(std::size_t j=0;j<sz;j++)
1317 patchesSafe[j]=patches[j];
1318 std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
1319 for(std::size_t j=0;j<sz;j++)
1321 ms[j]=patches[j]->getMesh();
1323 _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
1325 // updates cross levels neighbors
1326 _neighbors.resize(_levs.size());
1327 _cross_lev_neighbors.resize(_levs.size());
1329 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
1330 std::size_t sz(_levs.size());
1331 for(std::size_t i=1;i<sz;i++)
1333 const MEDCouplingGridCollection *fine(_levs[i]);
1335 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
1336 _neighbors[i]=fine->findNeighbors(_ghost_lev);
1339 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
1341 MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
1342 std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
1343 std::size_t fullLev(i+neighs2.size());
1345 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
1346 std::size_t ii(i+1);
1347 for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
1348 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
1354 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)
1356 std::size_t sz(other._levs.size());
1357 for(std::size_t i=0;i<sz;i++)
1359 const MEDCouplingGridCollection *elt(other._levs[i]);
1362 _levs[i]=other._levs[i]->deepCpy(_gf,other._gf);
1365 //_cross_lev_neighbors(other._cross_lev_neighbors)
1366 sz=other._neighbors.size();
1367 for(std::size_t i=0;i<sz;i++)
1369 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._neighbors[i]);
1370 std::size_t sz2(neigh2.size());
1371 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_neighbors[i]);
1372 for(std::size_t j=0;j<sz2;j++)
1374 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1375 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1376 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1377 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1381 sz=other._mixed_lev_neighbors.size();
1382 for(std::size_t i=0;i<sz;i++)
1384 const MEDCouplingCartesianAMRPatch *p1(other._mixed_lev_neighbors[i].first),*p2(other._mixed_lev_neighbors[i].second);
1385 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1386 _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1);
1387 _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2);
1390 sz=other._cross_lev_neighbors.size();
1391 for(std::size_t i=0;i<sz;i++)
1393 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._cross_lev_neighbors[i]);
1394 std::size_t sz2(neigh2.size());
1395 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_cross_lev_neighbors[i]);
1396 for(std::size_t j=0;j<sz2;j++)
1398 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1399 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1400 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1401 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1406 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
1408 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1410 const MEDCouplingGridCollection *elt(*it);
1414 if(elt->presenceOf(m,tmp))
1416 return elt->getFieldsAt(tmp);
1420 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
1423 void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
1425 int nbl(getNumberOfLevels());
1426 if(level<=0 || level>=nbl)
1427 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
1428 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1429 MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
1432 void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
1434 int nbl(getNumberOfLevels());
1435 if(level<0 || level>=nbl-1)
1436 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
1437 const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
1438 MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);