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 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
154 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
155 std::size_t sz(_arrs.size());
156 if(other._arrs.size()!=sz)
157 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
158 for(std::size_t i=0;i<sz;i++)
159 father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i],other._arrs[i]);
162 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
164 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
165 std::size_t sz(_arrs.size());
166 if(other._arrs.size()!=sz)
167 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
168 for(std::size_t i=0;i<sz;i++)
169 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i],other._arrs[i]);
172 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
174 std::size_t sz(fieldNames.size());
175 std::vector<std::string> names(sz);
176 for(std::size_t i=0;i<sz;i++)
178 const std::pair<std::string,int>& info(fieldNames[i]);
179 _arrs[i]=DataArrayDouble::New();
180 _arrs[i]->alloc(0,info.second);
181 _arrs[i]->setName(info.first);
182 names[i]=info.second;
184 CheckDiscriminantNames(names);
187 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
189 std::size_t ret(sizeof(DataArrayDoubleCollection));
190 ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
194 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
196 std::vector<const BigMemoryObject *> ret;
197 for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
199 const DataArrayDouble *pt(*it);
206 void DataArrayDoubleCollection::updateTime() const
208 for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
210 const DataArrayDouble *pt(*it);
216 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
218 std::set<std::string> s(names.begin(),names.end());
219 if(s.size()!=names.size())
220 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
223 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
225 return new MEDCouplingGridCollection(ms,fieldNames);
228 void MEDCouplingGridCollection::alloc(int ghostLev)
230 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
232 int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
233 DataArrayDoubleCollection *dadc((*it).second);
235 dadc->allocTuples(nbTuples);
237 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
241 void MEDCouplingGridCollection::dealloc()
243 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
245 DataArrayDoubleCollection *dadc((*it).second);
247 dadc->dellocTuples();
249 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
253 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
255 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
256 (*it).second->spillInfoOnComponents(compNames);
259 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
262 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
273 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const
275 if(pos<0 || pos>(int)_map_of_dadc.size())
276 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
277 return *_map_of_dadc[pos].second;
280 void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
283 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
284 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
285 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
286 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
288 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
289 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
291 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
293 if((*it0).first==fatherOfFineMesh)
296 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
297 const DataArrayDoubleCollection *coarseDaCol((*it0).second);
298 DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
299 DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
303 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
307 void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
310 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
311 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
312 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
313 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
315 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
316 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
318 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
320 if((*it0).first==fatherOfFineMesh)
323 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
324 const DataArrayDoubleCollection *fineDaCol((*it).second);
325 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
326 DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
330 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
335 * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
337 * \sa synchronizeFineEachOtherExt
339 void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
341 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
344 if(!presenceOf((*it).first->getMesh(),p1))
345 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
346 if(!presenceOf((*it).second->getMesh(),p2))
347 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
348 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
349 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
350 col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
355 * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
357 * \sa synchronizeFineEachOther
359 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
361 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
364 if(!presenceOf((*it).first->getMesh(),p1))
365 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
366 if(!presenceOf((*it).second->getMesh(),p2))
367 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
368 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
369 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
370 col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
375 * The pairs returned share the same direct father. The number of returned elements must be even.
377 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const
379 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
380 std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
381 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
383 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
384 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
385 m[fatherOfFineMesh].push_back(fineMesh);
387 for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
389 for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
391 int patchId((*it0).first->getPatchIdFromChildMesh(*it1));
392 std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
393 const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
394 for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
396 const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
397 ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
402 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
406 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
409 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
410 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
411 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
412 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
414 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
415 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
417 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
419 if((*it0).first==fatherOfFineMesh)
422 int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
423 const DataArrayDoubleCollection *fineDaCol((*it).second);
424 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
425 DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
429 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
433 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
435 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
437 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
438 if(head==a || head->isObjectInTheProgeny(a))
440 const DataArrayDoubleCollection *gc((*it).second);
441 recurseArrs.push_back(gc->getFieldWithName(fieldName));
446 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
448 std::size_t sz(ms.size());
449 for(std::size_t i=0;i<sz;i++)
452 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
453 _map_of_dadc[i].first=ms[i];
454 _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
458 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
460 std::size_t ret(sizeof(MEDCouplingGridCollection));
461 ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
465 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
467 std::vector<const BigMemoryObject *> ret;
468 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
470 const DataArrayDoubleCollection *col((*it).second);
477 void MEDCouplingGridCollection::updateTime() const
479 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
481 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
484 const DataArrayDoubleCollection *b((*it).second);
491 * 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.
493 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev)
495 return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
498 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev)
500 std::size_t sz(fieldNames.size());
501 std::vector< std::pair<std::string,int> > fieldNames2(sz);
502 std::vector< std::vector<std::string> > compNames(sz);
503 for(std::size_t i=0;i<sz;i++)
505 fieldNames2[i].first=fieldNames[i].first;
506 fieldNames2[i].second=(int)fieldNames[i].second.size();
507 compNames[i]=fieldNames[i].second;
509 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
510 ret->spillInfoOnComponents(compNames);
515 * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
516 * 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.
517 * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
518 * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
520 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
523 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
524 (*it)->spillInfoOnComponents(compNames);
528 * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
529 * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
531 * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
532 * \sa retrieveFieldOn
534 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
536 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
539 if((*it)->presenceOf(mesh,tmp))
541 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
542 return ddc.retrieveFields();
545 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
549 * \sa retrieveFieldsOn
551 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
553 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
556 if((*it)->presenceOf(mesh,tmp))
558 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
559 return ddc.getFieldWithName(fieldName);
562 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldOn : the mesh specified is not in the progeny of this !");
566 * This method returns a field on an unstructured mesh the most refined as possible without overlap.
567 * Ghost part are not visible here.
569 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
571 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
573 std::vector<const DataArrayDouble *> recurseArrs;
575 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
578 if((*it)->presenceOf(mesh,tmp))
580 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
581 recurseArrs.push_back(ddc.getFieldWithName(fieldName));
586 for(std::size_t i=lev;i<_levs.size();i++)
588 const MEDCouplingGridCollection *gc(_levs[i]);
589 gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
591 return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
595 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
596 * The output field also displays ghost cells.
598 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
601 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
603 const DataArrayDouble *arr(0);
604 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
607 if((*it)->presenceOf(mesh,tmp))
609 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
610 arr=ddc.getFieldWithName(fieldName);
614 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
615 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
616 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
618 ret->setArray(const_cast<DataArrayDouble *>(arr));
619 ret->setName(arr->getName());
624 * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
625 * MEDCouplingAMRAttribute::alloc method.
627 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
630 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
631 std::size_t sz(_levs.size());
636 const MEDCouplingGridCollection *fine(_levs[sz]),*coarse(_levs[sz-1]);
637 MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
642 * 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
643 * MEDCouplingAMRAttribute::alloc method.
645 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
648 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
649 std::size_t sz(_levs.size());
651 for(std::size_t i=1;i<sz;i++)
653 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
654 MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);
659 * This method performs coarse to fine spread only in the ghost zone.
660 * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
661 * So if \a _ghost_lev == 0 this method has no effect.
663 void MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone()
666 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineOnlyInGhostZone : not any levels in this !");
667 std::size_t sz(_levs.size());
669 for(std::size_t i=1;i<sz;i++)
671 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
672 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
677 * This method synchronizes fine each other only in the ghost zone.
679 void MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone()
682 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
683 std::size_t sz(_levs.size());
685 for(std::size_t i=1;i<sz;i++)
687 const MEDCouplingGridCollection *fine(_levs[i]);
689 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
690 fine->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
693 for(std::size_t i=1;i<sz;i++)
695 const MEDCouplingGridCollection *fine(_levs[i]);
696 fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
701 * This method allocates all DataArrayDouble instances stored recursively in \a this.
705 void MEDCouplingAMRAttribute::alloc()
708 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
710 MEDCouplingGridCollection *elt(*it);
712 elt->alloc(_ghost_lev);
714 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
719 * This method deallocates all DataArrayDouble instances stored recursively in \a this.
722 void MEDCouplingAMRAttribute::dealloc()
725 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
727 MEDCouplingGridCollection *elt(*it);
731 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
735 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
737 bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
741 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
743 std::size_t ret(sizeof(MEDCouplingAMRAttribute));
744 ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
748 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
750 std::vector<const BigMemoryObject *> ret;
751 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
753 const MEDCouplingGridCollection *elt(*it);
760 void MEDCouplingAMRAttribute::updateTime() const
764 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
766 //gf non empty, checked by constructor
767 int maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
768 _levs.resize(maxLev);
769 for(int i=0;i<maxLev;i++)
771 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
772 std::size_t sz(patches.size());
773 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
774 for(std::size_t j=0;j<sz;j++)
775 patchesSafe[j]=patches[j];
776 std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
777 for(std::size_t j=0;j<sz;j++)
779 ms[j]=patches[j]->getMesh();
781 _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
783 // updates cross levels neighbors
784 _neighbors.resize(_levs.size());
785 _cross_lev_neighbors.resize(_levs.size());
787 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
788 std::size_t sz(_levs.size());
789 for(std::size_t i=1;i<sz;i++)
791 const MEDCouplingGridCollection *fine(_levs[i]);
793 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
794 _neighbors[i]=fine->findNeighbors(_ghost_lev);
797 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
799 std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second));
800 std::size_t fullLev(i+neighs2.size());
802 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
804 for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
805 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());