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::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
56 std::size_t sz(_arrs.size());
57 if(sz!=compNames.size())
58 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
59 for(std::size_t i=0;i<sz;i++)
61 const std::vector<std::string>& names(compNames[i]);
62 _arrs[i].first->setInfoOnComponents(names);
66 void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& nfs)
68 std::size_t sz(_arrs.size());
70 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !");
71 for(std::size_t i=0;i<sz;i++)
73 CheckValidNature(nfs[i]);
74 _arrs[i].second=nfs[i];
78 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
80 std::size_t sz(_arrs.size());
81 std::vector<DataArrayDouble *> ret(sz);
82 for(std::size_t i=0;i<sz;i++)
84 const DataArrayDouble *tmp(_arrs[i].first);
85 ret[i]=const_cast<DataArrayDouble *>(tmp);
92 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
94 std::vector<std::string> vec;
95 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
97 const DataArrayDouble *obj((*it).first);
100 if(obj->getName()==name)
103 vec.push_back(obj->getName());
106 std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
107 std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
108 throw INTERP_KERNEL::Exception(oss.str().c_str());
111 void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
114 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
115 std::size_t sz(coarse->_arrs.size());
116 if(fine->_arrs.size()!=sz)
117 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
118 for(std::size_t i=0;i<sz;i++)
120 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
121 fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
125 void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
128 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
129 std::size_t sz(coarse->_arrs.size());
130 if(fine->_arrs.size()!=sz)
131 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
132 for(std::size_t i=0;i<sz;i++)
134 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
135 fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
139 void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
141 if(!fatherOfFineMesh)
142 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
143 std::size_t sz(children.size());
144 if(fieldsOnFine.size()!=sz)
145 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
148 std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
149 for(std::size_t i=0;i<sz;i++)
150 if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
151 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
152 for(std::size_t i=1;i<sz;i++)
153 if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
154 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
155 for(std::size_t i=0;i<nbOfCall;i++)
157 std::vector<const DataArrayDouble *> arrs(sz);
158 for(std::size_t j=0;j<sz;j++)
159 arrs[j]=fieldsOnFine[j]->_arrs[i].first;
160 fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
165 * 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).
167 void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac)
169 if(!p1 || !p1dac || !p2 || !p2dac)
170 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !");
171 std::size_t sz(p1dac->_arrs.size());
172 if(p2dac->_arrs.size()!=sz)
173 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !");
174 for(std::size_t i=0;i<sz;i++)
176 const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first);
177 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first);
181 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
184 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
185 std::size_t sz(coarse->_arrs.size());
186 if(fine->_arrs.size()!=sz)
187 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
188 for(std::size_t i=0;i<sz;i++)
189 fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev);
192 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
194 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
195 std::size_t sz(_arrs.size());
196 if(other._arrs.size()!=sz)
197 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
198 for(std::size_t i=0;i<sz;i++)
199 father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
202 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
204 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
205 std::size_t sz(_arrs.size());
206 if(other._arrs.size()!=sz)
207 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
208 for(std::size_t i=0;i<sz;i++)
209 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
212 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
214 std::size_t sz(fieldNames.size());
215 std::vector<std::string> names(sz);
216 for(std::size_t i=0;i<sz;i++)
218 const std::pair<std::string,int>& info(fieldNames[i]);
219 _arrs[i].first=DataArrayDouble::New();
220 _arrs[i].first->alloc(0,info.second);
221 _arrs[i].first->setName(info.first);
222 names[i]=info.second;
223 _arrs[i].second=ConservativeVolumic;
225 CheckDiscriminantNames(names);
228 DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size())
230 std::size_t sz(other._arrs.size());
231 for(std::size_t i=0;i<sz;i++)
233 _arrs[i].second=other._arrs[i].second;
234 const DataArrayDouble *da(other._arrs[i].first);
236 _arrs[i].first=da->deepCpy();
240 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
242 std::size_t ret(sizeof(DataArrayDoubleCollection));
243 ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
247 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
249 std::vector<const BigMemoryObject *> ret;
250 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
252 const DataArrayDouble *pt((*it).first);
259 void DataArrayDoubleCollection::updateTime() const
261 for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
263 const DataArrayDouble *pt((*it).first);
269 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
271 std::set<std::string> s(names.begin(),names.end());
272 if(s.size()!=names.size())
273 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
276 bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
279 return n==RevIntegral || n==IntegralGlobConstraint;
282 void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
284 CheckValidNature(n1);
285 CheckValidNature(n2);
287 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
290 void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
292 if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral)
293 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
296 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
298 return new MEDCouplingGridCollection(ms,fieldNames);
301 MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy() const
303 return new MEDCouplingGridCollection(*this);
306 void MEDCouplingGridCollection::alloc(int ghostLev)
308 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
310 int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
311 DataArrayDoubleCollection *dadc((*it).second);
313 dadc->allocTuples(nbTuples);
315 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
319 void MEDCouplingGridCollection::dealloc()
321 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
323 DataArrayDoubleCollection *dadc((*it).second);
325 dadc->dellocTuples();
327 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
331 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
333 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
334 (*it).second->spillInfoOnComponents(compNames);
337 void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
339 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
340 (*it).second->spillNatures(nfs);
343 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
346 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
357 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
359 if(pos<0 || pos>(int)_map_of_dadc.size())
360 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
361 return *_map_of_dadc[pos].second;
364 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
367 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
368 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
369 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
370 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
372 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
373 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
375 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
377 if((*it0).first==fatherOfFineMesh)
380 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
381 const DataArrayDoubleCollection *coarseDaCol((*it0).second);
382 DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
383 DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
387 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
391 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
394 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
395 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
396 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
397 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
399 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
400 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
402 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
404 if((*it0).first==fatherOfFineMesh)
407 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
408 const DataArrayDoubleCollection *fineDaCol((*it).second);
409 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
410 DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
414 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
419 * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
421 * \sa synchronizeFineEachOtherExt
423 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
425 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
428 if(!presenceOf((*it).first->getMesh(),p1))
429 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
430 if(!presenceOf((*it).second->getMesh(),p2))
431 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
432 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
433 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
434 col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
439 * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
441 * \sa synchronizeFineEachOther
443 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
445 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
448 if(!presenceOf((*it).first->getMesh(),p1))
449 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
450 if(!presenceOf((*it).second->getMesh(),p2))
451 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
452 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
453 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
454 col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
459 * The pairs returned share the same direct father. The number of returned elements must be even.
461 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
463 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
464 std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
465 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
467 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
468 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
469 m[fatherOfFineMesh].push_back(fineMesh);
471 for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
473 for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
475 int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
476 std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
477 const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
478 for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
480 const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
481 ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
486 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
490 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
493 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
494 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
495 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
496 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
498 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
499 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
501 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
503 if((*it0).first==fatherOfFineMesh)
506 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
507 const DataArrayDoubleCollection *fineDaCol((*it).second);
508 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
509 DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
513 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
517 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
519 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
521 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
522 if(head==a || head->isObjectInTheProgeny(a))
524 const DataArrayDoubleCollection *gc((*it).second);
525 recurseArrs.push_back(gc->getFieldWithName(fieldName));
530 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
532 std::size_t sz(ms.size());
533 for(std::size_t i=0;i<sz;i++)
536 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
537 _map_of_dadc[i].first=ms[i];
538 _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
542 MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
544 std::size_t sz(other._map_of_dadc.size());
545 for(std::size_t i=0;i<sz;i++)
547 _map_of_dadc[i].first=other._map_of_dadc[i].first;
548 const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
550 _map_of_dadc[i].second=dac->deepCpy();
554 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
556 std::size_t ret(sizeof(MEDCouplingGridCollection));
557 ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
561 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
563 std::vector<const BigMemoryObject *> ret;
564 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
566 const DataArrayDoubleCollection *col((*it).second);
573 void MEDCouplingGridCollection::updateTime() const
575 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
577 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
580 const DataArrayDoubleCollection *b((*it).second);
586 MEDCouplingCartesianAMRPatchGF::MEDCouplingCartesianAMRPatchGF(MEDCouplingCartesianAMRMesh *mesh):MEDCouplingCartesianAMRPatchGen(mesh)
590 std::size_t MEDCouplingCartesianAMRPatchGF::getHeapMemorySizeWithoutChildren() const
592 return sizeof(MEDCouplingCartesianAMRPatchGF);
595 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMeshGen *gf):_gf(gf),_tlc(gf)
598 throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
602 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
607 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMeshGen *gf)
609 bool ret(_tlc.keepTrackOfNewTL(gf));
619 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
621 other._tlc.checkConst();
625 * 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.
627 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
629 return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
632 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
634 std::size_t sz(fieldNames.size());
635 std::vector< std::pair<std::string,int> > fieldNames2(sz);
636 std::vector< std::vector<std::string> > compNames(sz);
637 for(std::size_t i=0;i<sz;i++)
639 fieldNames2[i].first=fieldNames[i].first;
640 fieldNames2[i].second=(int)fieldNames[i].second.size();
641 compNames[i]=fieldNames[i].second;
643 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
644 ret->spillInfoOnComponents(compNames);
649 * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
650 * 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.
651 * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
652 * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
654 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
657 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
658 (*it)->spillInfoOnComponents(compNames);
662 * Assign nature for each fields in \a this.
665 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
668 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
669 (*it)->spillNatures(nfs);
672 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const
674 return new MEDCouplingAMRAttribute(*this);
678 * 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).
681 int MEDCouplingAMRAttribute::getNumberOfLevels() const
683 checkGodFatherFrozen();
684 return (int)_levs.size();
688 * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
689 * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
691 * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
692 * \sa retrieveFieldOn
694 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
696 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
699 if((*it)->presenceOf(mesh,tmp))
701 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
702 return ddc.retrieveFields();
705 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
709 * \sa retrieveFieldsOn
711 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
713 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
716 if((*it)->presenceOf(mesh,tmp))
718 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
719 return ddc.getFieldWithName(fieldName);
722 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldOn : the mesh specified is not in the progeny of this !");
726 * This method returns a field on an unstructured mesh the most refined as possible without overlap.
727 * Ghost part are not visible here.
729 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
731 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
733 std::vector<const DataArrayDouble *> recurseArrs;
735 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
738 if((*it)->presenceOf(mesh,tmp))
740 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
741 recurseArrs.push_back(ddc.getFieldWithName(fieldName));
746 for(std::size_t i=lev;i<_levs.size();i++)
748 const MEDCouplingGridCollection *gc(_levs[i]);
749 gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
751 return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
755 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
756 * The output field also displays ghost cells.
758 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
760 * \sa buildCellFieldOnWithoutGhost
762 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
764 const DataArrayDouble *arr(0);
765 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
768 if((*it)->presenceOf(mesh,tmp))
770 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
771 arr=ddc.getFieldWithName(fieldName);
775 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
776 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
777 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
779 ret->setArray(const_cast<DataArrayDouble *>(arr));
780 ret->setName(arr->getName());
785 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
786 * The output field does not display ghost cells.
788 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
790 * \sa buildCellFieldOnWithGhost
792 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
795 const DataArrayDouble *arr(0);
796 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
799 if((*it)->presenceOf(mesh,tmp))
801 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
802 arr=ddc.getFieldWithName(fieldName);
806 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
808 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
809 std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
810 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New());
811 arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
812 std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
813 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
814 std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
815 MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
816 arr2->copyStringInfoFrom(*arr);
818 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
819 ret->setMesh(mesh->getImageMesh());
821 ret->setName(arr->getName());
826 * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
827 * MEDCouplingAMRAttribute::alloc method.
829 * \sa synchronizeFineToCoarseBetween
831 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
834 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
835 std::size_t sz(_levs.size());
840 synchronizeFineToCoarseByOneLevel((int)sz);
845 * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
846 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
847 * until reaching \a toLev level.
849 * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
850 * \param [in] toLev - an existing level considered as the target level to reach.
853 void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
855 int nbl(getNumberOfLevels());
856 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
857 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
859 return ;//nothing to do
861 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
862 for(int i=fromLev;i>toLev;i--)
863 synchronizeFineToCoarseByOneLevel(i);
867 * 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
868 * MEDCouplingAMRAttribute::alloc method.
870 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
873 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
874 std::size_t sz(_levs.size());
876 for(std::size_t i=0;i<sz-1;i++)
877 synchronizeCoarseToFineByOneLevel((int)i);
881 * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
882 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
883 * until reaching \a toLev level.
885 * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
886 * \param [in] toLev - an existing level considered as the target level to reach.
888 void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
890 int nbl(getNumberOfLevels());
891 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
892 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
894 return ;//nothing to do
896 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
897 for(int i=fromLev;i<toLev;i++)
898 synchronizeCoarseToFineByOneLevel(i);
902 * This method synchronizes the ghost zone of all patches (excepted the god father one).
903 * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
905 * - firstly coarse to fine with no interactions between brother patches.
906 * - secondly connected brother patches in a same master patch are updated.
907 * - thirdly connected nephew patches are updated each other.
908 * - forthly nth generation cousin patches are updated each other.
910 * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
911 * So if \a _ghost_lev == 0 this method has no effect.
913 void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
916 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
917 // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
918 std::size_t sz(_levs.size());
919 for(std::size_t i=1;i<sz;i++)
921 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
922 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
924 // 2nd - classical direct sublevel inside common patch
925 for(std::size_t i=1;i<sz;i++)
927 const MEDCouplingGridCollection *fine(_levs[i]);
929 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
930 fine->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
933 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
935 const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
936 DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
938 // 4th - same level but with far ancestor.
939 for(std::size_t i=1;i<sz;i++)
941 const MEDCouplingGridCollection *fine(_levs[i]);
942 fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
947 * This method allocates all DataArrayDouble instances stored recursively in \a this.
951 void MEDCouplingAMRAttribute::alloc()
954 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
956 MEDCouplingGridCollection *elt(*it);
958 elt->alloc(_ghost_lev);
960 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
965 * This method deallocates all DataArrayDouble instances stored recursively in \a this.
968 void MEDCouplingAMRAttribute::dealloc()
971 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
973 MEDCouplingGridCollection *elt(*it);
977 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
981 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMeshGen *gf)
983 bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
987 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
989 std::size_t ret(sizeof(MEDCouplingAMRAttribute));
990 ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
994 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
996 std::vector<const BigMemoryObject *> ret;
997 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
999 const MEDCouplingGridCollection *elt(*it);
1006 void MEDCouplingAMRAttribute::updateTime() const
1010 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
1012 //gf non empty, checked by constructor
1013 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
1014 _levs.resize(maxLev);
1015 for(int i=0;i<maxLev;i++)
1017 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1018 std::size_t sz(patches.size());
1019 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
1020 for(std::size_t j=0;j<sz;j++)
1021 patchesSafe[j]=patches[j];
1022 std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
1023 for(std::size_t j=0;j<sz;j++)
1025 ms[j]=patches[j]->getMesh();
1027 _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
1029 // updates cross levels neighbors
1030 _neighbors.resize(_levs.size());
1031 _cross_lev_neighbors.resize(_levs.size());
1033 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
1034 std::size_t sz(_levs.size());
1035 for(std::size_t i=1;i<sz;i++)
1037 const MEDCouplingGridCollection *fine(_levs[i]);
1039 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
1040 _neighbors[i]=fine->findNeighbors(_ghost_lev);
1043 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
1045 MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
1046 std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
1047 std::size_t fullLev(i+neighs2.size());
1049 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
1050 std::size_t ii(i+1);
1051 for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
1052 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
1058 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& other):MEDCouplingDataForGodFather(other),_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)
1060 std::size_t sz(other._levs.size());
1061 for(std::size_t i=0;i<sz;i++)
1063 const MEDCouplingGridCollection *elt(other._levs[i]);
1066 _levs[i]=other._levs[i]->deepCpy();
1071 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
1073 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1075 const MEDCouplingGridCollection *elt(*it);
1079 if(elt->presenceOf(m,tmp))
1081 return elt->getFieldsAt(tmp);
1085 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
1088 void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
1090 int nbl(getNumberOfLevels());
1091 if(level<=0 || level>=nbl)
1092 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
1093 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1094 MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
1097 void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
1099 int nbl(getNumberOfLevels());
1100 if(level<0 || level>=nbl-1)
1101 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
1102 const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
1103 MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);