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 void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
37 std::size_t sz(_arrs.size());
38 for(std::size_t i=0;i<sz;i++)
39 _arrs[i]->reAlloc(nbOfTuples);
42 void DataArrayDoubleCollection::dellocTuples()
44 std::size_t sz(_arrs.size());
45 for(std::size_t i=0;i<sz;i++)
49 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
51 std::size_t sz(_arrs.size());
52 if(sz!=compNames.size())
53 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
54 for(std::size_t i=0;i<sz;i++)
56 const std::vector<std::string>& names(compNames[i]);
57 _arrs[i]->setInfoOnComponents(names);
61 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
63 std::size_t sz(_arrs.size());
64 std::vector<DataArrayDouble *> ret(sz);
65 for(std::size_t i=0;i<sz;i++)
67 const DataArrayDouble *tmp(_arrs[i]);
68 ret[i]=const_cast<DataArrayDouble *>(tmp);
75 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
77 std::vector<std::string> vec;
78 for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
80 const DataArrayDouble *obj(*it);
83 if(obj->getName()==name)
86 vec.push_back(obj->getName());
89 std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
90 std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
91 throw INTERP_KERNEL::Exception(oss.str().c_str());
94 void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
97 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
98 std::size_t sz(coarse->_arrs.size());
99 if(fine->_arrs.size()!=sz)
100 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
101 for(std::size_t i=0;i<sz;i++)
102 fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i],coarse->_arrs[i],ghostLev);
105 void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
108 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
109 std::size_t sz(coarse->_arrs.size());
110 if(fine->_arrs.size()!=sz)
111 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
112 for(std::size_t i=0;i<sz;i++)
113 fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i],fine->_arrs[i],ghostLev);
116 void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
118 if(!fatherOfFineMesh)
119 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
120 std::size_t sz(children.size());
121 if(fieldsOnFine.size()!=sz)
122 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
125 std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
126 for(std::size_t i=0;i<sz;i++)
127 if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i)
128 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
129 for(std::size_t i=1;i<sz;i++)
130 if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
131 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
132 for(std::size_t i=0;i<nbOfCall;i++)
134 std::vector<const DataArrayDouble *> arrs(sz);
135 for(std::size_t j=0;j<sz;j++)
136 arrs[j]=fieldsOnFine[j]->_arrs[i];
137 fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
141 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
144 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
145 std::size_t sz(coarse->_arrs.size());
146 if(fine->_arrs.size()!=sz)
147 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
148 for(std::size_t i=0;i<sz;i++)
149 fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i],fine->_arrs[i],ghostLev);
152 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
154 std::size_t sz(fieldNames.size());
155 std::vector<std::string> names(sz);
156 for(std::size_t i=0;i<sz;i++)
158 const std::pair<std::string,int>& info(fieldNames[i]);
159 _arrs[i]=DataArrayDouble::New();
160 _arrs[i]->alloc(0,info.second);
161 _arrs[i]->setName(info.first);
162 names[i]=info.second;
164 CheckDiscriminantNames(names);
167 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
169 std::size_t ret(sizeof(DataArrayDoubleCollection));
170 ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
174 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
176 std::vector<const BigMemoryObject *> ret;
177 for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
179 const DataArrayDouble *pt(*it);
186 void DataArrayDoubleCollection::updateTime() const
188 for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
190 const DataArrayDouble *pt(*it);
196 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
198 std::set<std::string> s(names.begin(),names.end());
199 if(s.size()!=names.size())
200 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
203 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
205 return new MEDCouplingGridCollection(ms,fieldNames);
208 void MEDCouplingGridCollection::alloc(int ghostLev)
210 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
212 int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
213 DataArrayDoubleCollection *dadc((*it).second);
215 dadc->allocTuples(nbTuples);
217 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
221 void MEDCouplingGridCollection::dealloc()
223 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
225 DataArrayDoubleCollection *dadc((*it).second);
227 dadc->dellocTuples();
229 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
233 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
235 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
236 (*it).second->spillInfoOnComponents(compNames);
239 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
242 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
253 const DataArrayDoubleCollection& MEDCouplingGridCollection::retrieveFieldsAt(int pos) const
255 if(pos<0 || pos>(int)_map_of_dadc.size())
256 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::retrieveFieldsAt : invalid pos given in input ! Must be in [0,size) !");
257 return *_map_of_dadc[pos].second;
260 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
263 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
264 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
265 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
266 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
268 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
269 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
271 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
273 if((*it0).first==fatherOfFineMesh)
276 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
277 const DataArrayDoubleCollection *coarseDaCol((*it0).second);
278 DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
279 DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
283 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
287 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
290 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
291 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
292 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
293 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
295 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
296 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
298 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
300 if((*it0).first==fatherOfFineMesh)
303 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
304 const DataArrayDoubleCollection *fineDaCol((*it).second);
305 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
306 DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
310 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
314 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev) const
316 std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> > > m;
317 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
319 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
320 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
321 m[fatherOfFineMesh].push_back(std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *>(fineMesh,(*it).second));
323 for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector<std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> > >::const_iterator it0=m.begin();it0!=m.end();it0++)
325 std::size_t sz((*it0).second.size());
326 std::vector<const MEDCouplingCartesianAMRMeshGen *> v0(sz);
327 std::vector<DataArrayDoubleCollection *> v1(sz);
328 for(std::size_t i=0;i<sz;i++)
330 v0[i]=(*it0).second[i].first;
331 const DataArrayDoubleCollection *tmp((*it0).second[i].second);
332 v1[i]=const_cast<DataArrayDoubleCollection *>(tmp);
334 for(std::vector<std::pair<const MEDCouplingCartesianAMRMeshGen *, const DataArrayDoubleCollection *> >::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
336 int patchId((*it0).first->getPatchIdFromChildMesh((*it1).first));
337 DataArrayDoubleCollection::SynchronizeFineEachOther(patchId,ghostLev,(*it0).first,v0,v1);
342 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
345 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
346 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
347 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
348 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
350 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
351 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
353 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
355 if((*it0).first==fatherOfFineMesh)
358 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
359 const DataArrayDoubleCollection *fineDaCol((*it).second);
360 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
361 DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
365 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
369 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
371 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
373 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
374 if(head==a || head->isObjectInTheProgeny(a))
376 const DataArrayDoubleCollection *gc((*it).second);
377 recurseArrs.push_back(gc->getFieldWithName(fieldName));
382 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
384 std::size_t sz(ms.size());
385 for(std::size_t i=0;i<sz;i++)
388 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
389 _map_of_dadc[i].first=ms[i];
390 _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
394 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
396 std::size_t ret(sizeof(MEDCouplingGridCollection));
397 ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
401 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
403 std::vector<const BigMemoryObject *> ret;
404 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
406 const DataArrayDoubleCollection *col((*it).second);
413 void MEDCouplingGridCollection::updateTime() const
415 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
417 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
420 const DataArrayDoubleCollection *b((*it).second);
427 * 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.
429 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames)
431 return new MEDCouplingAMRAttribute(gf,fieldNames);
434 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames)
436 std::size_t sz(fieldNames.size());
437 std::vector< std::pair<std::string,int> > fieldNames2(sz);
438 std::vector< std::vector<std::string> > compNames(sz);
439 for(std::size_t i=0;i<sz;i++)
441 fieldNames2[i].first=fieldNames[i].first;
442 fieldNames2[i].second=(int)fieldNames[i].second.size();
443 compNames[i]=fieldNames[i].second;
445 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2));
446 ret->spillInfoOnComponents(compNames);
451 * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
452 * 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.
453 * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
454 * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
456 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
459 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
460 (*it)->spillInfoOnComponents(compNames);
464 * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
465 * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
467 * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
468 * \sa retrieveFieldOn
470 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
472 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
475 if((*it)->presenceOf(mesh,tmp))
477 const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
478 return ddc.retrieveFields();
481 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
485 * \sa retrieveFieldsOn
487 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
489 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
492 if((*it)->presenceOf(mesh,tmp))
494 const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
495 return ddc.getFieldWithName(fieldName);
498 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldOn : the mesh specified is not in the progeny of this !");
502 * This method returns a field on an unstructured mesh the most refined as possible without overlap.
503 * Ghost part are not visible here.
505 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
507 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
509 std::vector<const DataArrayDouble *> recurseArrs;
511 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
514 if((*it)->presenceOf(mesh,tmp))
516 const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
517 recurseArrs.push_back(ddc.getFieldWithName(fieldName));
522 for(std::size_t i=lev;i<_levs.size();i++)
524 const MEDCouplingGridCollection *gc(_levs[i]);
525 gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
527 return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(ghostLev,recurseArrs);
531 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
532 * The output field also displays ghost cells.
534 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
537 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(int ghostLev, MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
539 const DataArrayDouble *arr(0);
540 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
543 if((*it)->presenceOf(mesh,tmp))
545 const DataArrayDoubleCollection& ddc((*it)->retrieveFieldsAt(tmp));
546 arr=ddc.getFieldWithName(fieldName);
550 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
551 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(ghostLev));
552 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
554 ret->setArray(const_cast<DataArrayDouble *>(arr));
555 ret->setName(arr->getName());
560 * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
561 * MEDCouplingAMRAttribute::alloc method.
563 void MEDCouplingAMRAttribute::synchronizeFineToCoarse(int ghostLev)
566 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
567 std::size_t sz(_levs.size());
572 const MEDCouplingGridCollection *fine(_levs[sz]),*coarse(_levs[sz-1]);
573 MEDCouplingGridCollection::SynchronizeFineToCoarse(ghostLev,fine,coarse);
578 * This method synchronizes from coarse to fine arrays and fine to fine each other (if ghostLev is >0). This method makes the hypothesis that \a this has been allocated before using
579 * MEDCouplingAMRAttribute::alloc method.
581 void MEDCouplingAMRAttribute::synchronizeCoarseToFine(int ghostLev)
584 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
585 std::size_t sz(_levs.size());
587 for(std::size_t i=1;i<sz;i++)
589 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
590 MEDCouplingGridCollection::SynchronizeCoarseToFine(ghostLev,coarse,fine);
595 * This method performs coarse to fine spread only in the ghost zone.
596 * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
597 * So if \a ghostLev == 0 this method has no effect.
599 void MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone(int ghostLev)
602 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone : not any levels in this !");
603 std::size_t sz(_levs.size());
605 for(std::size_t i=1;i<sz;i++)
607 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
608 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,coarse,fine);
613 * This method synchronizes fine each other only in the ghost zone.
615 void MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone(int ghostLev)
618 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
619 std::size_t sz(_levs.size());
621 for(std::size_t i=1;i<sz;i++)
623 const MEDCouplingGridCollection *fine(_levs[i]);
625 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
626 fine->synchronizeFineEachOther(ghostLev);
631 * This method allocates all DataArrayDouble instances stored recursively in \a this.
633 * \param [in] ghostLev - The size of ghost zone.
637 void MEDCouplingAMRAttribute::alloc(int ghostLev)
640 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
642 MEDCouplingGridCollection *elt(*it);
644 elt->alloc(ghostLev);
646 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
651 * This method deallocates all DataArrayDouble instances stored recursively in \a this.
654 void MEDCouplingAMRAttribute::dealloc()
657 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
659 MEDCouplingGridCollection *elt(*it);
663 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
667 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
669 bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
673 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
675 std::size_t ret(sizeof(MEDCouplingAMRAttribute));
676 ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
680 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
682 std::vector<const BigMemoryObject *> ret;
683 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
685 const MEDCouplingGridCollection *elt(*it);
692 void MEDCouplingAMRAttribute::updateTime() const
696 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames):MEDCouplingDataForGodFather(gf)
698 //gf non empty, checked by constructor
699 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
700 _levs.resize(maxLev);
701 for(int i=0;i<maxLev;i++)
703 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
704 std::size_t sz(patches.size());
705 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
706 for(std::size_t j=0;j<sz;j++)
707 patchesSafe[j]=patches[j];
708 std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
709 for(std::size_t j=0;j<sz;j++)
711 ms[j]=patches[j]->getMesh();
713 _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);