1 // Copyright (C) 2007-2022 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"
30 using namespace MEDCoupling;
33 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
35 return new DataArrayDoubleCollection(fieldNames);
38 DataArrayDoubleCollection *DataArrayDoubleCollection::deepCopy() const
40 return new DataArrayDoubleCollection(*this);
43 void DataArrayDoubleCollection::allocTuples(mcIdType nbOfTuples)
45 std::size_t sz(_arrs.size());
46 for(std::size_t i=0;i<sz;i++)
47 _arrs[i].first->reAlloc(nbOfTuples);
50 void DataArrayDoubleCollection::dellocTuples()
52 std::size_t sz(_arrs.size());
53 for(std::size_t i=0;i<sz;i++)
54 _arrs[i].first->reAlloc(0);
57 void DataArrayDoubleCollection::copyFrom(const DataArrayDoubleCollection& other)
59 std::size_t sz(_arrs.size());
60 if(sz!=other._arrs.size())
61 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : size are not the same !");
62 for(std::size_t i=0;i<sz;i++)
64 DataArrayDouble *thisArr(_arrs[i].first);
65 const DataArrayDouble *otherArr(other._arrs[i].first);
66 if(!thisArr || !otherArr)
67 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : empty DataArray !");
68 thisArr->deepCopyFrom(*otherArr);
72 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
74 std::size_t sz(_arrs.size());
75 if(sz!=compNames.size())
76 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
77 for(std::size_t i=0;i<sz;i++)
79 const std::vector<std::string>& names(compNames[i]);
80 _arrs[i].first->setInfoOnComponents(names);
84 void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& nfs)
86 std::size_t sz(_arrs.size());
88 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !");
89 for(std::size_t i=0;i<sz;i++)
91 CheckValidNature(nfs[i]);
92 _arrs[i].second=nfs[i];
96 std::vector< std::pair < std::string, std::vector<std::string> > > DataArrayDoubleCollection::getInfoOnComponents() const
98 std::size_t sz(_arrs.size());
99 std::vector< std::pair < std::string, std::vector<std::string> > > ret(sz);
100 for(std::size_t i=0;i<sz;i++)
102 const DataArrayDouble *elt(_arrs[i].first);
104 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::getInfoOnComponents : empty array !");
105 ret[i]=std::pair < std::string, std::vector<std::string> >(elt->getName(),elt->getInfoOnComponents());
110 std::vector<NatureOfField> DataArrayDoubleCollection::getNatures() const
112 std::size_t sz(_arrs.size());
113 std::vector<NatureOfField> ret(sz);
114 for(std::size_t i=0;i<sz;i++)
115 ret[i]=_arrs[i].second;
119 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
121 std::size_t sz(_arrs.size());
122 std::vector<DataArrayDouble *> ret(sz);
123 for(std::size_t i=0;i<sz;i++)
125 const DataArrayDouble *tmp(_arrs[i].first);
126 ret[i]=const_cast<DataArrayDouble *>(tmp);
133 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
135 std::vector<std::string> vec;
136 for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
138 const DataArrayDouble *obj((*it).first);
141 if(obj->getName()==name)
144 vec.push_back(obj->getName());
147 std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
148 std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
149 throw INTERP_KERNEL::Exception(oss.str().c_str());
152 DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name)
154 std::vector<std::string> vec;
155 for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::iterator it=_arrs.begin();it!=_arrs.end();it++)
157 DataArrayDouble *obj((*it).first);
160 if(obj->getName()==name)
163 vec.push_back(obj->getName());
166 std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName non const : fieldName \"" << name << "\" does not exist in this ! Possibilities are :";
167 std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," "));
168 throw INTERP_KERNEL::Exception(oss.str().c_str());
171 DataArrayDouble *DataArrayDoubleCollection::at(mcIdType pos)
173 if(pos<0 || pos>=ToIdType(_arrs.size()))
174 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at (non const) : pos must be in [0,nbOfFields) !");
175 return _arrs[pos].first;
178 const DataArrayDouble *DataArrayDoubleCollection::at(mcIdType pos) const
180 if(pos<0 || pos>=ToIdType(_arrs.size()))
181 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at : pos must be in [0,nbOfFields) !");
182 return _arrs[pos].first;
185 mcIdType DataArrayDoubleCollection::size() const
187 return ToIdType(_arrs.size());
190 void DataArrayDoubleCollection::SynchronizeFineToCoarse(mcIdType ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, mcIdType patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse)
193 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !");
194 std::size_t sz(coarse->_arrs.size());
195 if(fine->_arrs.size()!=sz)
196 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
197 for(std::size_t i=0;i<sz;i++)
199 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
200 fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
204 void DataArrayDoubleCollection::SynchronizeCoarseToFine(mcIdType ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, mcIdType patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
207 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !");
208 std::size_t sz(coarse->_arrs.size());
209 if(fine->_arrs.size()!=sz)
210 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
211 for(std::size_t i=0;i<sz;i++)
213 CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
214 fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
218 void DataArrayDoubleCollection::SynchronizeFineEachOther(mcIdType patchId, mcIdType ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
220 if(!fatherOfFineMesh)
221 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !");
222 std::size_t sz(children.size());
223 if(fieldsOnFine.size()!=sz)
224 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !");
227 std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size());
228 for(std::size_t i=0;i<sz;i++)
229 if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=ToIdType(i))
230 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !");
231 for(std::size_t i=1;i<sz;i++)
232 if(nbOfCall!=fieldsOnFine[i]->_arrs.size())
233 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !");
234 for(std::size_t i=0;i<nbOfCall;i++)
236 std::vector<const DataArrayDouble *> arrs(sz);
237 for(std::size_t j=0;j<sz;j++)
238 arrs[j]=fieldsOnFine[j]->_arrs[i].first;
239 fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
244 * 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).
246 void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(mcIdType ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac)
248 if(!p1 || !p1dac || !p2 || !p2dac)
249 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !");
250 std::size_t sz(p1dac->_arrs.size());
251 if(p2dac->_arrs.size()!=sz)
252 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !");
253 for(std::size_t i=0;i<sz;i++)
255 const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first);
256 DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second);
257 bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second));
258 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative);
262 void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(mcIdType ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, mcIdType patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
265 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !");
266 std::size_t sz(coarse->_arrs.size());
267 if(fine->_arrs.size()!=sz)
268 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
269 for(std::size_t i=0;i<sz;i++)
270 fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev);
273 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(mcIdType ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
275 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
276 std::size_t sz(_arrs.size());
277 if(other._arrs.size()!=sz)
278 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
279 for(std::size_t i=0;i<sz;i++)
280 father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
283 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(mcIdType ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
285 DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this));
286 std::size_t sz(_arrs.size());
287 if(other._arrs.size()!=sz)
288 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
289 for(std::size_t i=0;i<sz;i++)
290 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
293 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
295 std::size_t sz(fieldNames.size());
296 std::vector<std::string> names(sz);
297 for(std::size_t i=0;i<sz;i++)
299 const std::pair<std::string,int>& info(fieldNames[i]);
302 std::ostringstream oss; oss << "DataArrayDoubleCollection constructor : At pos #" << i << " the array with name \"" << info.first << "\" as a number of components equal to " << info.second;
303 oss << " It has to be >=1 !";
304 throw INTERP_KERNEL::Exception(oss.str().c_str());
306 _arrs[i].first=DataArrayDouble::New();
307 _arrs[i].first->alloc(0,info.second);
308 _arrs[i].first->setName(info.first);
310 _arrs[i].second=IntensiveMaximum;
312 CheckDiscriminantNames(names);
315 DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size())
317 std::size_t sz(other._arrs.size());
318 for(std::size_t i=0;i<sz;i++)
320 _arrs[i].second=other._arrs[i].second;
321 const DataArrayDouble *da(other._arrs[i].first);
323 _arrs[i].first=da->deepCopy();
327 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
329 std::size_t ret(sizeof(DataArrayDoubleCollection));
330 ret+=_arrs.capacity()*sizeof(MCAuto<DataArrayDouble>);
334 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildrenWithNull() const
336 std::vector<const BigMemoryObject *> ret;
337 for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
338 ret.push_back((const DataArrayDouble *)(*it).first);
342 void DataArrayDoubleCollection::updateTime() const
344 for(std::vector< std::pair< MCAuto<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
346 const DataArrayDouble *pt((*it).first);
352 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
354 std::set<std::string> s(names.begin(),names.end());
355 if(s.size()!=names.size())
356 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
359 bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
362 return n==IntensiveConservation || n==ExtensiveConservation;
365 void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
367 CheckValidNature(n1);
368 CheckValidNature(n2);
370 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
373 void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
375 if(n!=IntensiveMaximum && n!=ExtensiveMaximum && n!=ExtensiveConservation && n!=IntensiveConservation)
376 throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
379 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
381 return new MEDCouplingGridCollection(ms,fieldNames);
384 MEDCouplingGridCollection *MEDCouplingGridCollection::deepCopy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const
386 return new MEDCouplingGridCollection(*this,newGf,oldGf);
389 void MEDCouplingGridCollection::alloc(mcIdType ghostLev)
391 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
393 mcIdType nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
394 DataArrayDoubleCollection *dadc((*it).second);
396 dadc->allocTuples(nbTuples);
398 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
402 void MEDCouplingGridCollection::dealloc()
404 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
406 DataArrayDoubleCollection *dadc((*it).second);
408 dadc->dellocTuples();
410 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
414 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
416 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
417 (*it).second->spillInfoOnComponents(compNames);
420 void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
422 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
423 (*it).second->spillNatures(nfs);
426 std::vector< std::pair<std::string, std::vector<std::string> > > MEDCouplingGridCollection::getInfoOnComponents() const
428 if(_map_of_dadc.empty())
429 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !");
430 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
432 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !");
433 return elt->getInfoOnComponents();
436 std::vector<NatureOfField> MEDCouplingGridCollection::getNatures() const
438 if(_map_of_dadc.empty())
439 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !");
440 const DataArrayDoubleCollection *elt(_map_of_dadc[0].second);
442 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !");
443 return elt->getNatures();
446 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, mcIdType& pos) const
449 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++)
460 const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(mcIdType pos) const
462 if(pos<0 || pos>ToIdType(_map_of_dadc.size()))
463 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !");
464 return *_map_of_dadc[pos].second;
467 DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(mcIdType pos)
469 if(pos<0 || pos>ToIdType(_map_of_dadc.size()))
470 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !");
471 return *_map_of_dadc[pos].second;
475 * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting
476 * part of fields of \a this. The fields are expected to be the same between \a other and \a this.
477 * This methods makes the hypothesis that \a this and \a other share two god father that are compatible each other that is to say with the same cell grid structure.
479 void MEDCouplingGridCollection::copyOverlappedZoneFrom(mcIdType ghostLev, const MEDCouplingGridCollection& other)
481 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
483 std::vector<mcIdType> deltaThis,deltaOther;
484 std::vector< std::pair<mcIdType,mcIdType> > rgThis((*it).first->positionRelativeToGodFather(deltaThis));
485 std::vector<mcIdType> thisSt((*it).first->getImageMesh()->getCellGridStructure());
486 std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind(std::plus<mcIdType>(),std::placeholders::_1,2*ghostLev));
487 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++)
489 std::vector< std::pair<mcIdType,mcIdType> > rgOther((*it2).first->positionRelativeToGodFather(deltaOther));
490 if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther))
492 std::vector< std::pair<mcIdType,mcIdType> > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther));
493 std::vector< std::pair<mcIdType,mcIdType> > pThis,pOther;
494 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true);
495 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true);
496 std::vector<mcIdType> otherSt((*it2).first->getImageMesh()->getCellGridStructure());
497 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev);
498 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev);
499 std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind(std::plus<mcIdType>(),std::placeholders::_1,2*ghostLev));
500 mcIdType sz((*it2).second->size());
501 for(mcIdType i=0;i<sz;i++)
503 const DataArrayDouble *otherArr((*it2).second->at(i));
504 DataArrayDouble *thisArr((*it).second->at(i));
505 MCAuto<DataArrayDouble> partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther));
506 MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther);
513 void MEDCouplingGridCollection::SynchronizeFineToCoarse(mcIdType ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse)
516 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !");
517 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
518 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
519 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
521 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
522 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
524 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
526 if((*it0).first==fatherOfFineMesh)
529 mcIdType patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
530 const DataArrayDoubleCollection *coarseDaCol((*it0).second);
531 DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered
532 DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified);
536 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !");
540 void MEDCouplingGridCollection::SynchronizeCoarseToFine(mcIdType ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
543 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !");
544 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
545 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
546 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
548 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
549 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
551 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
553 if((*it0).first==fatherOfFineMesh)
556 mcIdType patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
557 const DataArrayDoubleCollection *fineDaCol((*it).second);
558 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
559 DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
563 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !");
568 * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead.
570 * \sa synchronizeFineEachOtherExt
572 void MEDCouplingGridCollection::synchronizeFineEachOther(mcIdType ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
574 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
577 if(!presenceOf((*it).first->getMesh(),p1))
578 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !");
579 if(!presenceOf((*it).second->getMesh(),p2))
580 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !");
581 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
582 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
583 col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather());
588 * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless.
590 * \sa synchronizeFineEachOther
592 void MEDCouplingGridCollection::synchronizeFineEachOtherExt(mcIdType ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const
594 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++)
597 if(!presenceOf((*it).first->getMesh(),p1))
598 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !");
599 if(!presenceOf((*it).second->getMesh(),p2))
600 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !");
601 const DataArrayDoubleCollection& col1(getFieldsAt(p1));
602 const DataArrayDoubleCollection& col2(getFieldsAt(p2));
603 col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second);
608 * The pairs returned share the same direct father. The number of returned elements must be even.
610 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(mcIdType ghostLev) const
612 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret;
613 std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m;
614 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
616 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
617 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
618 m[fatherOfFineMesh].push_back(fineMesh);
620 for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++)
622 for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
624 mcIdType patchId((*it0).first->getPatchIdFromChildMesh(*it1));
625 std::vector<mcIdType> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
626 const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId));
627 for(std::vector<mcIdType>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++)
629 const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2));
630 ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc));
635 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !");
639 void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(mcIdType ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine)
642 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !");
643 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc);
644 const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc);
645 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++)
647 const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first);
648 const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather());
650 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++)
652 if((*it0).first==fatherOfFineMesh)
655 mcIdType patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh));
656 const DataArrayDoubleCollection *fineDaCol((*it).second);
657 DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered
658 DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified);
662 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !");
666 void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const
668 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
670 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
671 if(head==a || head->isObjectInTheProgeny(a))
673 const DataArrayDoubleCollection *gc((*it).second);
674 recurseArrs.push_back(gc->getFieldWithName(fieldName));
679 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
681 std::size_t sz(ms.size());
682 for(std::size_t i=0;i<sz;i++)
685 throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
686 _map_of_dadc[i].first=ms[i];
687 _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
691 MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size())
693 std::size_t sz(other._map_of_dadc.size());
694 for(std::size_t i=0;i<sz;i++)
696 std::vector<mcIdType> pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf));
697 _map_of_dadc[i].first=newGf->getMeshAtPosition(pos);
698 const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second);
700 _map_of_dadc[i].second=dac->deepCopy();
704 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
706 std::size_t ret(sizeof(MEDCouplingGridCollection));
707 ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> >);
711 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildrenWithNull() const
713 std::vector<const BigMemoryObject *> ret;
714 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
715 ret.push_back((const DataArrayDoubleCollection *)(*it).second);
719 void MEDCouplingGridCollection::updateTime() const
721 for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MCAuto<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
723 const MEDCouplingCartesianAMRMeshGen *a((*it).first);
726 const DataArrayDoubleCollection *b((*it).second);
734 MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather()
739 const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const
744 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
747 throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
751 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
756 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
758 bool ret(_tlc.keepTrackOfNewTL(gf));
768 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf)
770 other._tlc.checkConst();
773 const MEDCouplingCartesianAMRMesh *gf(other._gf);
776 _tlc.keepTrackOfNewTL(_gf);
781 * 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.
783 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, mcIdType ghostLev)
785 return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev);
788 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, mcIdType ghostLev)
790 std::size_t sz(fieldNames.size());
791 std::vector< std::pair<std::string,int> > fieldNames2(sz);
792 std::vector< std::vector<std::string> > compNames(sz);
793 for(std::size_t i=0;i<sz;i++)
795 fieldNames2[i].first=fieldNames[i].first;
796 fieldNames2[i].second=(int)fieldNames[i].second.size();
797 compNames[i]=fieldNames[i].second;
799 MCAuto<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev));
800 ret->spillInfoOnComponents(compNames);
805 * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
806 * The first dim of input \a compNames is the field id in the same order than those implicitly specified in \a fieldNames parameter of MEDCouplingAMRAttribute::New.
807 * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
808 * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
810 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
813 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
814 (*it)->spillInfoOnComponents(compNames);
818 * Assign nature for each fields in \a this.
819 * \param [in] nfs vector of field natures.
821 void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
824 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
825 (*it)->spillNatures(nfs);
828 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCopy() const
830 return new MEDCouplingAMRAttribute(*this,true);
833 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const
835 return new MEDCouplingAMRAttribute(*this,false);
839 * 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).
842 mcIdType MEDCouplingAMRAttribute::getNumberOfLevels() const
844 checkGodFatherFrozen();
845 return ToIdType(_levs.size());
849 * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
850 * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
852 * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef).
853 * \sa retrieveFieldOn
855 std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const
857 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
860 if((*it)->presenceOf(mesh,tmp))
862 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
863 return ddc.retrieveFields();
866 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !");
870 * \sa retrieveFieldsOn
872 const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
874 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
877 if((*it)->presenceOf(mesh,tmp))
879 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
880 return ddc.getFieldWithName(fieldName);
883 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn : the mesh specified is not in the progeny of this !");
886 DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName)
888 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
891 if((*it)->presenceOf(mesh,tmp))
893 DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
894 return ddc.getFieldWithName(fieldName);
897 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn non const : the mesh specified is not in the progeny of this !");
901 * This method returns a field on an unstructured mesh the most refined as possible without overlap.
902 * Ghost part are not visible here.
904 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
906 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
908 std::vector<const DataArrayDouble *> recurseArrs;
910 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++)
913 if((*it)->presenceOf(mesh,tmp))
915 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
916 recurseArrs.push_back(ddc.getFieldWithName(fieldName));
921 for(std::size_t i=lev;i<_levs.size();i++)
923 const MEDCouplingGridCollection *gc(_levs[i]);
924 gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs);
926 return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs);
930 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
931 * The output field also displays ghost cells.
933 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
935 * \sa buildCellFieldOnWithoutGhost
937 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
939 const DataArrayDouble *arr(0);
940 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
943 if((*it)->presenceOf(mesh,tmp))
945 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
946 arr=ddc.getFieldWithName(fieldName);
950 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !");
951 MCAuto<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
952 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
954 ret->setArray(const_cast<DataArrayDouble *>(arr));
955 ret->setName(arr->getName());
960 * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement.
961 * The output field does not display ghost cells.
963 * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it).
965 * \sa buildCellFieldOnWithGhost
967 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
969 const DataArrayDouble *arr(0);
970 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
973 if((*it)->presenceOf(mesh,tmp))
975 const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp));
976 arr=ddc.getFieldWithName(fieldName);
980 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !");
982 MCAuto<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
983 std::vector<mcIdType> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
984 MCAuto<DataArrayDouble> arr2(DataArrayDouble::New());
985 arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
986 std::vector< std::pair<mcIdType,mcIdType> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
987 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
988 std::vector<mcIdType> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
989 MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
990 arr2->copyStringInfoFrom(*arr);
992 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
993 ret->setMesh(mesh->getImageMesh());
995 ret->setName(arr->getName());
1000 std::string MEDCouplingAMRAttribute::writeVTHB(const std::string& fileName) const
1002 static const char EXT[]=".vthb";
1003 std::string baseName,extName,zeFileName;
1004 MEDCouplingMesh::SplitExtension(fileName,baseName,extName);
1006 zeFileName=fileName;
1008 { zeFileName=baseName; zeFileName+=EXT; }
1010 std::ofstream ofs(fileName.c_str());
1011 ofs << "<VTKFile type=\"vtkOverlappingAMR\" version=\"1.1\" byte_order=\"" << MEDCouplingByteOrderStr() << "\">\n";
1012 const MEDCouplingCartesianAMRMesh *gf(getMyGodFather());
1013 ofs << " <vtkOverlappingAMR origin=\"";
1014 const MEDCouplingIMesh *gfm(gf->getImageMesh());
1015 std::vector<double> orig(gfm->getOrigin());
1016 std::vector<double> spacing(gfm->getDXYZ());
1017 mcIdType dim(ToIdType(orig.size()));
1018 std::copy(orig.begin(),orig.end(),std::ostream_iterator<double>(ofs," ")); ofs << "\" grid_description=\"";
1019 for(mcIdType i=0;i<dim;i++)
1021 char tmp[2]; tmp[0]=(char)(int('X')+i); tmp[1]='\0';
1026 mcIdType maxLev(gf->getMaxNumberOfLevelsRelativeToThis()),kk(0);
1027 for(mcIdType i=0;i<maxLev;i++)
1029 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1030 std::size_t sz(patches.size());
1031 std::vector< MCAuto<MEDCouplingCartesianAMRPatchGen> > patchesSafe(sz);
1032 for(std::size_t j=0;j<sz;j++)
1033 patchesSafe[j]=patches[j];
1036 ofs << " <Block level=\"" << i << "\" spacing=\"";
1037 std::copy(spacing.begin(),spacing.end(),std::ostream_iterator<double>(ofs," "));
1041 std::vector<mcIdType> factors(patches[0]->getMesh()->getFactors());
1042 for(mcIdType k=0;k<dim;k++)
1043 spacing[k]*=1./((double) factors[k]);
1046 for(std::vector<MEDCouplingCartesianAMRPatchGen *>::const_iterator it=patches.begin();it!=patches.end();it++,jj++,kk++)
1048 ofs << " <DataSet index=\"" << jj << "\" amr_box=\"";
1049 const MEDCouplingCartesianAMRPatch *patchCast(dynamic_cast<const MEDCouplingCartesianAMRPatch *>(*it));
1050 const MEDCouplingCartesianAMRMeshGen *mesh((*it)->getMesh());
1053 const std::vector< std::pair<mcIdType,mcIdType> >& bltr(patchCast->getBLTRRangeRelativeToGF());
1054 for(mcIdType pp=0;pp<dim;pp++)
1055 ofs << bltr[pp].first << " " << bltr[pp].second-1 << " ";
1059 const MEDCouplingIMesh *im((*it)->getMesh()->getImageMesh());
1060 std::vector<mcIdType> cgs(im->getCellGridStructure());
1061 for(mcIdType pp=0;pp<dim;pp++)
1062 ofs << "0 " << cgs[pp]-1 << " ";
1064 ofs << "\" file=\"";
1067 if(_levs[i]->presenceOf((*it)->getMesh(),tmp))
1069 const DataArrayDoubleCollection& ddc(_levs[i]->getFieldsAt(tmp));
1070 std::vector<DataArrayDouble *> arrs(ddc.retrieveFields());
1071 std::size_t nbFields(arrs.size());
1072 std::vector< MCAuto<DataArrayDouble> > arrsSafe(nbFields),arrs2Safe(nbFields);
1073 std::vector< const MEDCouplingFieldDouble *> fields(nbFields);
1074 std::vector< MCAuto<MEDCouplingFieldDouble> > fieldsSafe(nbFields);
1075 for(std::size_t pp=0;pp<nbFields;pp++)
1076 arrsSafe[pp]=arrs[pp];
1077 for(std::size_t pp=0;pp<nbFields;pp++)
1079 MCAuto<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
1080 std::vector<mcIdType> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
1081 arrs2Safe[pp]=DataArrayDouble::New();
1082 arrs2Safe[pp]->alloc(mesh->getImageMesh()->getNumberOfCells(),arrs[pp]->getNumberOfComponents());
1083 std::vector< std::pair<mcIdType,mcIdType> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
1084 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
1085 std::vector<mcIdType> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
1086 MEDCouplingIMesh::SpreadCoarseToFine(arrs[pp],cgsWG,arrs2Safe[pp],cgs2,fakeFactors);
1087 arrs2Safe[pp]->copyStringInfoFrom(*arrs[pp]);
1089 fieldsSafe[pp]=MEDCouplingFieldDouble::New(ON_CELLS); fields[pp]=fieldsSafe[pp];
1090 fieldsSafe[pp]->setMesh(mesh->getImageMesh());
1091 fieldsSafe[pp]->setArray(arrs2Safe[pp]);
1092 fieldsSafe[pp]->setName(arrs[pp]->getName());
1094 std::ostringstream vtiFileName; vtiFileName << baseName << "_" << kk << ".vti";
1095 MEDCouplingFieldDouble::WriteVTK(vtiFileName.str(),fields,true);
1097 ofs << vtiFileName.str() << "\">\n";
1098 ofs << " \n </DataSet>\n";
1101 ofs << " </Block>\n";
1104 ofs << " </vtkOverlappingAMR>\n";
1105 ofs << "</VTKFile>\n";
1110 * This method is useful just after a remesh after a time step computation to project values in \a this to the new
1113 * This method performs a projection from \a this to a target AMR mesh \a targetGF.
1114 * This method performs the projection by trying to transfer the finest information to \a targetGF.
1115 * \b WARNING this method does not update the ghost zone, if any.
1116 * The level0 of \a this god father must have the same structure than those of \a targetGF.
1118 * This method makes checks that ghost size of \a this and \a targetGF are the same, and that
1119 * the number of levels in \a this and in \a targetGF are also the same.
1121 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const
1124 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !");
1126 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !");
1127 const MEDCouplingGridCollection *lev0(_levs[0]);
1129 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !");
1130 std::vector< std::pair < std::string, std::vector<std::string> > > fieldNames(lev0->getInfoOnComponents());
1131 MCAuto<MEDCouplingAMRAttribute> ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev));
1132 ret->spillNatures(lev0->getNatures());
1134 mcIdType nbLevs(getNumberOfLevels());
1135 if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs)
1136 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !");
1137 // first step copy level0
1138 if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure())
1139 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !");
1140 const DataArrayDoubleCollection& col(lev0->getFieldsAt(0));
1141 DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0));
1142 colTarget.copyFrom(col);
1143 // then go deeper and deeper
1144 for(mcIdType i=1;i<nbLevs;i++)
1146 ret->synchronizeCoarseToFineByOneLevel(i-1);
1147 MEDCouplingGridCollection *targetCol(ret->_levs[i]);
1149 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !");
1150 const MEDCouplingGridCollection *thisCol(_levs[i]);
1152 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !");
1153 targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol);
1159 * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using
1160 * MEDCouplingAMRAttribute::alloc method.
1161 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse)
1163 * \sa synchronizeFineToCoarseBetween
1165 void MEDCouplingAMRAttribute::synchronizeFineToCoarse()
1168 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !");
1169 std::size_t sz(_levs.size());
1174 synchronizeFineToCoarseByOneLevel(ToIdType(sz));
1179 * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level.
1180 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ...
1181 * until reaching \a toLev level.
1182 * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse).
1184 * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev
1185 * \param [in] toLev - an existing level considered as the target level to reach.
1188 void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(mcIdType fromLev, mcIdType toLev)
1190 mcIdType nbl(getNumberOfLevels());
1191 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1192 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1194 return ;//nothing to do
1196 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween ");
1197 for(mcIdType i=fromLev;i>toLev;i--)
1198 synchronizeFineToCoarseByOneLevel(i);
1202 * 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
1203 * MEDCouplingAMRAttribute::alloc method.
1204 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method)
1206 void MEDCouplingAMRAttribute::synchronizeCoarseToFine()
1209 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !");
1210 std::size_t sz(_levs.size());
1212 for(std::size_t i=0;i<sz-1;i++)
1213 synchronizeCoarseToFineByOneLevel(ToIdType(i));
1217 * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level.
1218 * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ...
1219 * until reaching \a toLev level.
1220 * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarseBetween method)
1222 * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev
1223 * \param [in] toLev - an existing level considered as the target level to reach.
1225 void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(mcIdType fromLev, mcIdType toLev)
1227 mcIdType nbl(getNumberOfLevels());
1228 if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl)
1229 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !");
1231 return ;//nothing to do
1233 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !");
1234 for(mcIdType i=fromLev;i<toLev;i++)
1235 synchronizeCoarseToFineByOneLevel(i);
1239 * This method synchronizes the ghost zone of all patches (excepted the god father one).
1240 * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone.
1242 * - firstly coarse to fine with no interactions between brother patches.
1243 * - secondly connected brother patches in a same master patch are updated.
1244 * - thirdly connected nephew patches are updated each other.
1245 * - forthly nth generation cousin patches are updated each other.
1247 * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method.
1248 * So if \a _ghost_lev == 0 this method has no effect.
1250 void MEDCouplingAMRAttribute::synchronizeAllGhostZones()
1252 mcIdType sz(getNumberOfLevels());
1254 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !");
1255 // 1st - synchronize from coarse to the finest all the patches (excepted the god father one)
1256 for(mcIdType i=1;i<sz;i++)
1258 const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]);
1259 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1261 // 2nd - classical direct sublevel inside common patch
1262 for(mcIdType i=1;i<sz;i++)
1264 const MEDCouplingGridCollection *curLev(_levs[i]);
1266 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !");
1267 curLev->synchronizeFineEachOther(_ghost_lev,_neighbors[i]);
1269 // 3rd - mixed level
1270 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++)
1272 const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh()));
1273 DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC);
1275 // 4th - same level but with far ancestor.
1276 for(mcIdType i=1;i<sz;i++)
1278 const MEDCouplingGridCollection *fine(_levs[i]);
1279 fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]);
1284 * This method works \b ONLY \b ON \b DIRECT \b SONS \b OF \a mesh. So only a part of patches at a given level is updated here.
1285 * The ghost zone of all of these sons of \a mesh are updated using the brother patches (the patches sharing the \b SAME \a mesh).
1286 * It is sometimes possible that a ghost zone of some sons of \a mesh are covered by a patch of same level but different father.
1287 * For such cases, the ghost zones are \b NOT updated. If you need a more thorough (but more costly) ghost zone update use synchronizeAllGhostZonesAtASpecifiedLevel method instead.
1289 * \param [in] mesh - an element in the progeny of god father in \a this, which the ghost zone of its sons will be updated each other.
1292 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh)
1295 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !");
1296 mcIdType level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels());
1297 if(level<0 || level>=sz-1)
1298 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !");
1299 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& itemsToFilter(_neighbors[level+1]);
1300 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > itemsToSync; itemsToSync.reserve(itemsToFilter.size());
1301 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++)
1303 if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh)
1304 itemsToSync.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>((*it).first,(*it).second));
1306 const MEDCouplingGridCollection *curLev(_levs[level+1]);
1308 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !");
1309 curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync);
1313 * This method updates \b all the patches at level \a level each other without consideration of their father.
1314 * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf.
1316 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(mcIdType level)
1318 mcIdType maxLev(getNumberOfLevels());
1319 if(level<0 || level>=maxLev)
1320 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !");
1322 return ;//at level 0 only one patch -> no need to update
1323 // 1st step - updates all patches pairs at level \a level sharing the same father
1324 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items(_neighbors[level]);
1325 const MEDCouplingGridCollection *curLev(_levs[level]);
1327 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !");
1328 curLev->synchronizeFineEachOther(_ghost_lev,items);
1329 //2nd step - updates all patches pairs at level \a level not sharing the same father
1330 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items2(_cross_lev_neighbors[level]);
1331 curLev->synchronizeFineEachOtherExt(_ghost_lev,items2);
1335 * This method updates ghost zones of patches at level \a level whatever their father \b using \b father \b patches \b ONLY (at level \b level - 1).
1336 * This method is useful to propagate to the ghost zone of childhood the modification.
1338 void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(mcIdType level)
1340 mcIdType maxLev(getNumberOfLevels());
1341 if(level<=0 || level>=maxLev)
1342 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !");
1343 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1344 MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine);
1345 //_cross_lev_neighbors is not needed.
1349 * This method allocates all DataArrayDouble instances stored recursively in \a this.
1353 void MEDCouplingAMRAttribute::alloc()
1356 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1358 MEDCouplingGridCollection *elt(*it);
1360 elt->alloc(_ghost_lev);
1362 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
1367 * This method deallocates all DataArrayDouble instances stored recursively in \a this.
1370 void MEDCouplingAMRAttribute::dealloc()
1373 for(std::vector< MCAuto<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
1375 MEDCouplingGridCollection *elt(*it);
1379 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
1383 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
1385 bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
1389 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
1391 std::size_t ret(sizeof(MEDCouplingAMRAttribute));
1392 ret+=_levs.capacity()*sizeof(MCAuto<MEDCouplingGridCollection>);
1396 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildrenWithNull() const
1398 std::vector<const BigMemoryObject *> ret;
1399 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1400 ret.push_back((const MEDCouplingGridCollection *)*it);
1404 void MEDCouplingAMRAttribute::updateTime() const
1408 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, mcIdType ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev)
1410 //gf non empty, checked by constructor
1411 mcIdType maxLev(gf->getMaxNumberOfLevelsRelativeToThis());
1412 _levs.resize(maxLev);
1413 for(mcIdType i=0;i<maxLev;i++)
1415 std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
1416 std::size_t sz(patches.size());
1417 std::vector< MCAuto<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
1418 for(std::size_t j=0;j<sz;j++)
1419 patchesSafe[j]=patches[j];
1420 std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
1421 for(std::size_t j=0;j<sz;j++)
1423 ms[j]=patches[j]->getMesh();
1425 _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
1427 // updates cross levels neighbors
1428 _neighbors.resize(_levs.size());
1429 _cross_lev_neighbors.resize(_levs.size());
1431 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !");
1432 std::size_t sz(_levs.size());
1433 for(std::size_t i=1;i<sz;i++)
1435 const MEDCouplingGridCollection *fine(_levs[i]);
1437 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !");
1438 _neighbors[i]=fine->findNeighbors(_ghost_lev);
1441 for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++)
1443 MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors);
1444 std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second));
1445 std::size_t fullLev(i+neighs2.size());
1447 throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !");
1448 std::size_t ii(i+1);
1449 for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++)
1450 _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end());
1456 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)
1458 std::size_t sz(other._levs.size());
1459 for(std::size_t i=0;i<sz;i++)
1461 const MEDCouplingGridCollection *elt(other._levs[i]);
1464 _levs[i]=other._levs[i]->deepCopy(_gf,other._gf);
1467 //_cross_lev_neighbors(other._cross_lev_neighbors)
1468 sz=other._neighbors.size();
1469 for(std::size_t i=0;i<sz;i++)
1471 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._neighbors[i]);
1472 std::size_t sz2(neigh2.size());
1473 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_neighbors[i]);
1474 for(std::size_t j=0;j<sz2;j++)
1476 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1477 std::vector<mcIdType> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1478 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1479 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1483 sz=other._mixed_lev_neighbors.size();
1484 for(std::size_t i=0;i<sz;i++)
1486 const MEDCouplingCartesianAMRPatch *p1(other._mixed_lev_neighbors[i].first),*p2(other._mixed_lev_neighbors[i].second);
1487 std::vector<mcIdType> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1488 _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1);
1489 _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2);
1492 sz=other._cross_lev_neighbors.size();
1493 for(std::size_t i=0;i<sz;i++)
1495 const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._cross_lev_neighbors[i]);
1496 std::size_t sz2(neigh2.size());
1497 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_cross_lev_neighbors[i]);
1498 for(std::size_t j=0;j<sz2;j++)
1500 const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second);
1501 std::vector<mcIdType> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf));
1502 neigh3[j].first=_gf->getPatchAtPosition(pp1);
1503 neigh3[j].second=_gf->getPatchAtPosition(pp2);
1508 const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const
1510 for(std::vector< MCAuto<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
1512 const MEDCouplingGridCollection *elt(*it);
1516 if(elt->presenceOf(m,tmp))
1518 return elt->getFieldsAt(tmp);
1522 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !");
1525 void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(mcIdType level)
1527 mcIdType nbl(getNumberOfLevels());
1528 if(level<=0 || level>=nbl)
1529 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !");
1530 const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]);
1531 MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse);
1534 void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(mcIdType level)
1536 mcIdType nbl(getNumberOfLevels());
1537 if(level<0 || level>=nbl-1)
1538 throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !");
1539 const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]);
1540 MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine);