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 MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
303 return new MEDCouplingGridCollection(*this,newGf,oldGf);
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, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf):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 std::vector<int> pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf));
548 _map_of_dadc[i].first=newGf->getMeshAtPosition(pos);
549 const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
551 _map_of_dadc[i].second=dac->deepCpy();
555 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
557 std::size_t ret(sizeof(MEDCouplingGridCollection));
558 ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
562 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
564 std::vector<const BigMemoryObject *> ret;
565 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
567 const DataArrayDoubleCollection *col((*it).second);
574 void MEDCouplingGridCollection::updateTime() const
576 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
578 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
581 const DataArrayDoubleCollection *b((*it).second);
587 MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather()
592 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
595 throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
599 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
604 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
606 bool ret(_tlc.keepTrackOfNewTL(gf));
616 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
618 other._tlc.checkConst();
621 const MEDCouplingCartesianAMRMesh *gf(other._gf);
624 _tlc.keepTrackOfNewTL(_gf);
629 * 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.
631 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
633 return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
636 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
638 std::size_t sz(fieldNames.size());
639 std::vector< std::pair<std::string,int> > fieldNames2(sz);
640 std::vector< std::vector<std::string> > compNames(sz);
641 for(std::size_t i=0;i<sz;i++)
643 fieldNames2[i].first=fieldNames[i].first;
644 fieldNames2[i].second=(int)fieldNames[i].second.size();
645 compNames[i]=fieldNames[i].second;
647 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
648 ret->spillInfoOnComponents(compNames);
653 * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
654 * 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.
655 * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
656 * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
658 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
661 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
662 (*it)->spillInfoOnComponents(compNames);
666 * Assign nature for each fields in \a this.
669 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
672 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
673 (*it)->spillNatures(nfs);
676 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const
678 return new MEDCouplingAMRAttribute(*this,true);
681 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const
683 return new MEDCouplingAMRAttribute(*this,false);
687 * 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).
690 int MEDCouplingAMRAttribute::getNumberOfLevels() const
692 checkGodFatherFrozen();
693 return (int)_levs.size();
697 * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
698 * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
700 * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
701 * \sa retrieveFieldOn
703 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
705 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
708 if((*it)->presenceOf(mesh,tmp))
710 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
711 return ddc.retrieveFields();
714 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
718 * \sa retrieveFieldsOn
720 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
722 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
725 if((*it)->presenceOf(mesh,tmp))
727 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
728 return ddc.getFieldWithName(fieldName);
731 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldOn : the mesh specified is not in the progeny of this !");
735 * This method returns a field on an unstructured mesh the most refined as possible without overlap.
736 * Ghost part are not visible here.
738 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
740 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
742 std::vector<const DataArrayDouble *> recurseArrs;
744 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
747 if((*it)->presenceOf(mesh,tmp))
749 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
750 recurseArrs.push_back(ddc.getFieldWithName(fieldName));
755 for(std::size_t i=lev;i<_levs.size();i++)
757 const MEDCouplingGridCollection *gc(_levs[i]);
758 gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
760 return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
764 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
765 * The output field also displays ghost cells.
767 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
769 * \sa buildCellFieldOnWithoutGhost
771 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
773 const DataArrayDouble *arr(0);
774 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
777 if((*it)->presenceOf(mesh,tmp))
779 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
780 arr=ddc.getFieldWithName(fieldName);
784 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
785 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
786 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
788 ret->setArray(const_cast<DataArrayDouble *>(arr));
789 ret->setName(arr->getName());
794 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
795 * The output field does not display ghost cells.
797 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
799 * \sa buildCellFieldOnWithGhost
801 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
804 const DataArrayDouble *arr(0);
805 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
808 if((*it)->presenceOf(mesh,tmp))
810 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
811 arr=ddc.getFieldWithName(fieldName);
815 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
817 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
818 std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
819 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New());
820 arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
821 std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
822 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
823 std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
824 MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
825 arr2->copyStringInfoFrom(*arr);
827 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
828 ret->setMesh(mesh->getImageMesh());
830 ret->setName(arr->getName());
835 * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
836 * MEDCouplingAMRAttribute::alloc method.
837 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse)
839 * \sa synchronizeFineToCoarseBetween
841 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
844 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
845 std::size_t sz(_levs.size());
850 synchronizeFineToCoarseByOneLevel((int)sz);
855 * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
856 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
857 * until reaching \a toLev level.
858 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse).
860 * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
861 * \param [in] toLev - an existing level considered as the target level to reach.
864 void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev)
866 int nbl(getNumberOfLevels());
867 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
868 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
870 return ;//nothing to do
872 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
873 for(int i=fromLev;i>toLev;i--)
874 synchronizeFineToCoarseByOneLevel(i);
878 * 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
879 * MEDCouplingAMRAttribute::alloc method.
880 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method)
882 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
885 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
886 std::size_t sz(_levs.size());
888 for(std::size_t i=0;i<sz-1;i++)
889 synchronizeCoarseToFineByOneLevel((int)i);
893 * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
894 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
895 * until reaching \a toLev level.
896 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarseBetween method)
898 * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
899 * \param [in] toLev - an existing level considered as the target level to reach.
901 void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev)
903 int nbl(getNumberOfLevels());
904 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
905 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
907 return ;//nothing to do
909 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
910 for(int i=fromLev;i<toLev;i++)
911 synchronizeCoarseToFineByOneLevel(i);
915 * This method synchronizes the ghost zone of all patches (excepted the god father one).
916 * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
918 * - firstly coarse to fine with no interactions between brother patches.
919 * - secondly connected brother patches in a same master patch are updated.
920 * - thirdly connected nephew patches are updated each other.
921 * - forthly nth generation cousin patches are updated each other.
923 * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
924 * So if \a _ghost_lev == 0 this method has no effect.
926 void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
928 int sz(getNumberOfLevels());
930 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
931 // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
932 for(int i=1;i<sz;i++)
934 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
935 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
937 // 2nd - classical direct sublevel inside common patch
938 for(int i=1;i<sz;i++)
940 const MEDCouplingGridCollection *curLev(_levs[i]);
942 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
943 curLev->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
946 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
948 const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
949 DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
951 // 4th - same level but with far ancestor.
952 for(int i=1;i<sz;i++)
954 const MEDCouplingGridCollection *fine(_levs[i]);
955 fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
960 * This method synchronizes all direct children of \a mesh each other.
962 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh)
965 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !");
966 int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels());
967 if(level<0 || level>=sz-1)
968 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !");
969 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& itemsToFilter(_neighbors[level+1]);
970 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > itemsToSync; itemsToSync.reserve(itemsToFilter.size());
971 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++)
973 if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh)
974 itemsToSync.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>((*it).first,(*it).second));
976 const MEDCouplingGridCollection *curLev(_levs[level+1]);
978 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !");
979 curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync);
983 * This method allocates all DataArrayDouble instances stored recursively in \a this.
987 void MEDCouplingAMRAttribute::alloc()
990 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
992 MEDCouplingGridCollection *elt(*it);
994 elt->alloc(_ghost_lev);
996 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
1001 * This method deallocates all DataArrayDouble instances stored recursively in \a this.
1004 void MEDCouplingAMRAttribute::dealloc()
1007 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1009 MEDCouplingGridCollection *elt(*it);
1013 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
1017 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
1019 bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
1023 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
1025 std::size_t ret(sizeof(MEDCouplingAMRAttribute));
1026 ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
1030 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
1032 std::vector<const BigMemoryObject *> ret;
1033 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1035 const MEDCouplingGridCollection *elt(*it);
1042 void MEDCouplingAMRAttribute::updateTime() const
1046 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
1048 //gf non empty, checked by constructor
1049 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
1050 _levs.resize(maxLev);
1051 for(int i=0;i<maxLev;i++)
1053 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1054 std::size_t sz(patches.size());
1055 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
1056 for(std::size_t j=0;j<sz;j++)
1057 patchesSafe[j]=patches[j];
1058 std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
1059 for(std::size_t j=0;j<sz;j++)
1061 ms[j]=patches[j]->getMesh();
1063 _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
1065 // updates cross levels neighbors
1066 _neighbors.resize(_levs.size());
1067 _cross_lev_neighbors.resize(_levs.size());
1069 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
1070 std::size_t sz(_levs.size());
1071 for(std::size_t i=1;i<sz;i++)
1073 const MEDCouplingGridCollection *fine(_levs[i]);
1075 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
1076 _neighbors[i]=fine->findNeighbors(_ghost_lev);
1079 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
1081 MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
1082 std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
1083 std::size_t fullLev(i+neighs2.size());
1085 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
1086 std::size_t ii(i+1);
1087 for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
1088 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
1094 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)
1096 std::size_t sz(other._levs.size());
1097 for(std::size_t i=0;i<sz;i++)
1099 const MEDCouplingGridCollection *elt(other._levs[i]);
1102 _levs[i]=other._levs[i]->deepCpy(_gf,other._gf);
1105 //_cross_lev_neighbors(other._cross_lev_neighbors)
1106 sz=other._neighbors.size();
1107 for(std::size_t i=0;i<sz;i++)
1109 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._neighbors[i]);
1110 std::size_t sz2(neigh2.size());
1111 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_neighbors[i]);
1112 for(std::size_t j=0;j<sz2;j++)
1114 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1115 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1116 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1117 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1121 sz=other._mixed_lev_neighbors.size();
1122 for(std::size_t i=0;i<sz;i++)
1124 const MEDCouplingCartesianAMRPatch *p1(other._mixed_lev_neighbors[i].first),*p2(other._mixed_lev_neighbors[i].second);
1125 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1126 _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1);
1127 _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2);
1130 sz=other._cross_lev_neighbors.size();
1131 for(std::size_t i=0;i<sz;i++)
1133 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._cross_lev_neighbors[i]);
1134 std::size_t sz2(neigh2.size());
1135 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_cross_lev_neighbors[i]);
1136 for(std::size_t j=0;j<sz2;j++)
1138 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1139 std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1140 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1141 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1146 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
1148 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1150 const MEDCouplingGridCollection *elt(*it);
1154 if(elt->presenceOf(m,tmp))
1156 return elt->getFieldsAt(tmp);
1160 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
1163 void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level)
1165 int nbl(getNumberOfLevels());
1166 if(level<=0 || level>=nbl)
1167 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
1168 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1169 MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
1172 void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level)
1174 int nbl(getNumberOfLevels());
1175 if(level<0 || level>=nbl-1)
1176 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
1177 const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
1178 MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);