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 "MEDCouplingCartesianAMRMesh.hxx"
22 #include "MEDCouplingFieldDouble.hxx"
23 #include "MEDCoupling1GTUMesh.hxx"
24 #include "MEDCouplingIMesh.hxx"
25 #include "MEDCouplingUMesh.hxx"
31 using namespace ParaMEDMEM;
35 int MEDCouplingCartesianAMRPatchGen::getNumberOfCellsRecursiveWithOverlap() const
37 return _mesh->getNumberOfCellsRecursiveWithOverlap();
40 int MEDCouplingCartesianAMRPatchGen::getNumberOfCellsRecursiveWithoutOverlap() const
42 return _mesh->getNumberOfCellsRecursiveWithoutOverlap();
45 int MEDCouplingCartesianAMRPatchGen::getMaxNumberOfLevelsRelativeToThis() const
47 return _mesh->getMaxNumberOfLevelsRelativeToThis();
50 MEDCouplingCartesianAMRPatchGen::MEDCouplingCartesianAMRPatchGen(MEDCouplingCartesianAMRMeshGen *mesh)
53 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen constructor : input mesh is NULL !");
54 _mesh=mesh; _mesh->incrRef();
57 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatchGen::getMeshSafe() const
59 const MEDCouplingCartesianAMRMeshGen *mesh(_mesh);
61 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen::getMeshSafe const : the mesh is NULL !");
65 MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatchGen::getMeshSafe()
67 MEDCouplingCartesianAMRMeshGen *mesh(_mesh);
69 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen::getMeshSafe : the mesh is NULL !");
73 std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRPatchGen::getDirectChildren() const
75 std::vector<const BigMemoryObject *> ret;
76 if((const MEDCouplingCartesianAMRMeshGen *)_mesh)
77 ret.push_back((const MEDCouplingCartesianAMRMeshGen *)_mesh);
82 * \param [in] mesh not null pointer of refined mesh replacing the cell range of \a father defined by the bottom left and top right just after.
83 * \param [in] bottomLeftTopRight a vector equal to the space dimension of \a mesh that specifies for each dimension, the included cell start of the range for the first element of the pair,
84 * a the end cell (\b excluded) of the range for the second element of the pair.
86 MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMeshGen *mesh, const std::vector< std::pair<int,int> >& bottomLeftTopRight):MEDCouplingCartesianAMRPatchGen(mesh),_bl_tr(bottomLeftTopRight)
88 int dim((int)bottomLeftTopRight.size()),dimExp(_mesh->getSpaceDimension());
90 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch constructor : space dimension of father and input bottomLeft/topRight size mismatches !");
93 void MEDCouplingCartesianAMRPatch::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors)
95 return getMeshSafe()->addPatch(bottomLeftTopRight,factors);
98 int MEDCouplingCartesianAMRPatch::getNumberOfOverlapedCellsForFather() const
100 return MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(_bl_tr);
104 * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter
105 * the must be >= 0. \b WARNING this method only works if \a this and \a other share the same father (no check of this will be done !).
106 * Call isInMyNeighborhoodExt to deal with 2 patches not sharing directly the same father.
108 * \param [in] other - The other patch
109 * \param [in] ghostLev - The size of the neighborhood zone.
111 * \throw if \a this or \a other are invalid (end before start).
112 * \throw if \a ghostLev is \b not >= 0 .
113 * \throw if \a this and \a other have not the same space dimension.
115 * \sa isInMyNeighborhoodExt
117 bool MEDCouplingCartesianAMRPatch::isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const
120 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the size of the neighborhood must be >= 0 !");
122 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the input patch is NULL !");
123 const std::vector< std::pair<int,int> >& thisp(getBLTRRange());
124 const std::vector< std::pair<int,int> >& otherp(other->getBLTRRange());
125 return IsInMyNeighborhood(ghostLev,thisp,otherp);
129 * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter
130 * the must be >= 0. This method works even if \a this and \a other does not share the same father.
132 * \param [in] other - The other patch
133 * \param [in] ghostLev - The size of the neighborhood zone.
135 * \throw if \a this or \a other are invalid (end before start).
136 * \throw if \a ghostLev is \b not >= 0 .
137 * \throw if \a this and \a other have not the same space dimension.
138 * \throw if there is not common ancestor of \a this and \a other.
140 * \sa isInMyNeighborhood
142 bool MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const
145 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt : the size of the neighborhood must be >= 0 !");
147 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt : the input patch is NULL !");
149 const MEDCouplingCartesianAMRMeshGen *com(FindCommonAncestor(this,other,lev));//check that factors are OK
151 return isInMyNeighborhood(other,ghostLev);
152 std::vector<int> offset(ComputeOffsetFromTwoToOne(com,lev,this,other));
153 const std::vector< std::pair<int,int> >& thisp(getBLTRRange());
154 std::vector< std::pair<int,int> > otherp(other->getBLTRRange());
155 std::size_t sz(offset.size());
156 for(std::size_t i=0;i<sz;i++)
158 otherp[i].first+=offset[i];
159 otherp[i].second+=offset[i];
161 return IsInMyNeighborhood(ghostLev,thisp,otherp);
164 bool MEDCouplingCartesianAMRPatch::IsInMyNeighborhood(int ghostLev, const std::vector< std::pair<int,int> >& p1, const std::vector< std::pair<int,int> >& p2)
166 std::size_t thispsize(p1.size());
167 if(thispsize!=p2.size())
168 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the dimensions must be the same !");
169 for(std::size_t i=0;i<thispsize;i++)
171 const std::pair<int,int>& thispp(p1[i]);
172 const std::pair<int,int>& otherpp(p2[i]);
173 if(thispp.second<thispp.first)
174 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : this patch is invalid !");
175 if(otherpp.second<otherpp.first)
176 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : this patch is invalid !");
177 if(otherpp.first==thispp.second+ghostLev-1)
179 if(otherpp.second+ghostLev-1==thispp.first)
181 int start(std::max(thispp.first,otherpp.first)),end(std::min(thispp.second,otherpp.second));
188 std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2)
191 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf : the input pointers must be not NULL !");
192 std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > ret;
193 std::vector< const MEDCouplingCartesianAMRPatch *> p1Work(p1->getMesh()->getPatches()),p2Work(p2->getMesh()->getPatches());
194 while(!p1Work.empty())
196 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > retTmp;
197 std::vector<const MEDCouplingCartesianAMRPatch *> p1Work2,p2Work2;
198 for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it1=p1Work.begin();it1!=p1Work.end();it1++)
200 for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++)
202 if((*it1)->isInMyNeighborhoodExt(*it2,ghostLev))
203 retTmp.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(*it1,*it2));
205 std::vector<const MEDCouplingCartesianAMRPatch *> tmp1((*it1)->getMesh()->getPatches());
206 p1Work2.insert(p1Work2.end(),tmp1.begin(),tmp1.end());
208 for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++)
210 std::vector<const MEDCouplingCartesianAMRPatch *> tmp2((*it2)->getMesh()->getPatches());
211 p2Work2.insert(p2Work2.end(),tmp2.begin(),tmp2.end());
213 ret.push_back(retTmp);
221 * \a p1 and \a p2 are expected to be neighbors (inside the \a ghostLev zone). This method updates \a dataOnP1 only in the ghost part using a part of \a dataOnP2.
223 * \saUpdateNeighborsOfOneWithTwoExt
225 void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(int ghostLev, const std::vector<int>& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2)
227 const std::vector< std::pair<int,int> >& p1BLTR(p1->getBLTRRange());
228 const std::vector< std::pair<int,int> >& p2BLTR(p2->getBLTRRange());
229 UpdateNeighborsOfOneWithTwoInternal(ghostLev,factors,p1BLTR,p2BLTR,dataOnP1,dataOnP2);
232 void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector<int>& factors, const std::vector< std::pair<int,int> >&p1 ,const std::vector< std::pair<int,int> >&p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2)
233 {//p1=[(1,4),(2,4)] p2=[(4,5),(3,4)]
234 int dim((int)factors.size());
235 std::vector<int> dimsCoarse(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(p1));//[3,2]
236 std::transform(dimsCoarse.begin(),dimsCoarse.end(),factors.begin(),dimsCoarse.begin(),std::multiplies<int>());//[12,8]
237 std::transform(dimsCoarse.begin(),dimsCoarse.end(),dimsCoarse.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));//[14,10]
238 std::vector< std::pair<int,int> > rangeCoarse(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsCoarse));//[(0,14),(0,10)]
239 std::vector<int> fakeFactors(dim,1);
241 std::vector< std::pair<int,int> > tmp0,tmp1,tmp2;
242 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p1,p2,tmp0,false);//tmp0=[(3,4),(1,2)]
243 ApplyFactorsOnCompactFrmt(tmp0,factors);//tmp0=[(12,16),(4,8)]
244 ApplyGhostOnCompactFrmt(tmp0,ghostLev);//tmp0=[(13,17),(5,9)]
245 std::vector< std::pair<int,int> > interstRange(MEDCouplingStructuredMesh::IntersectRanges(tmp0,rangeCoarse));//interstRange=[(13,14),(5,9)]
246 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p2,p1,tmp1,false);//tmp1=[(-3,0),(-1,1)]
247 ApplyFactorsOnCompactFrmt(tmp1,factors);//tmp1=[(-12,-4),(-4,0)]
248 MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(tmp1,interstRange,tmp2,false);//tmp2=[(1,2),(1,5)]
250 std::vector< std::pair<int,int> > dimsFine(p2);
251 ApplyFactorsOnCompactFrmt(dimsFine,factors);
252 ApplyAllGhostOnCompactFrmt(dimsFine,ghostLev);
254 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ghostVals(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(dimsFine),dataOnP2,tmp2));
255 MEDCouplingIMesh::CondenseFineToCoarse(dimsCoarse,ghostVals,interstRange,fakeFactors,dataOnP1);
259 * Idem than UpdateNeighborsOfOneWithTwo, except that here \a p1 and \a p2 are not sharing the same direct father.
261 * \sa UpdateNeighborsOfOneWithTwo
263 void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2)
265 const std::vector< std::pair<int,int> >& p1BLTR(p1->getBLTRRange());//p1BLTR=[(10,12),(5,8)]
266 std::vector< std::pair<int,int> > p2BLTR(p2->getBLTRRange());//p2BLTR=[(0,1),(0,5)]
268 const MEDCouplingCartesianAMRMeshGen *ca(FindCommonAncestor(p1,p2,lev));
269 std::vector<int> offset(ComputeOffsetFromTwoToOne(ca,lev,p1,p2));//[12,4]
270 p2BLTR=MEDCouplingStructuredMesh::TranslateCompactFrmt(p2BLTR,offset);//p2BLTR=[(12,13),(4,9)]
271 UpdateNeighborsOfOneWithTwoInternal(ghostLev,p1->getMesh()->getFather()->getFactors(),p1BLTR,p2BLTR,dataOnP1,dataOnP2);
274 std::size_t MEDCouplingCartesianAMRPatch::getHeapMemorySizeWithoutChildren() const
276 std::size_t ret(sizeof(MEDCouplingCartesianAMRPatch));
277 ret+=_bl_tr.capacity()*sizeof(std::pair<int,int>);
281 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatch::FindCommonAncestor(const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, int& lev)
283 const MEDCouplingCartesianAMRMeshGen *f1(p1->_mesh),*f2(p2->_mesh);
285 while(f1!=f2 || f1==0 || f2==0)
287 f1=f1->getFather(); f2=f2->getFather();
288 if(f1->getFactors()!=f2->getFactors())
289 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindCommonAncestor : factors differ !");
293 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindCommonAncestor : no common ancestor between p1 and p2 !");
297 std::vector<int> MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne(const MEDCouplingCartesianAMRMeshGen *comAncestor, int lev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2)
300 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : this method is useful only for lev > 0 !");
302 int dim(p1->getMesh()->getSpaceDimension());
303 if(p2->getMesh()->getSpaceDimension()!=dim)
304 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : dimension must be the same !");
305 std::vector< int > ret(dim,0);
307 for(int i=0;i<zeLev;i++)
309 const MEDCouplingCartesianAMRMeshGen *f1(p1->_mesh),*f2(p2->_mesh);
310 const MEDCouplingCartesianAMRPatch *p1h(0),*p2h(0);
311 for(int j=0;j<lev-i;j++)
313 const MEDCouplingCartesianAMRMeshGen *f1tmp(f1->getFather()),*f2tmp(f2->getFather());
314 int pid1(f1tmp->getPatchIdFromChildMesh(f1)),pid2(f2tmp->getPatchIdFromChildMesh(f2));
315 p1h=f1tmp->getPatch(pid1); p2h=f2tmp->getPatch(pid2);
318 std::vector< std::pair<int,int> > p2c(p2h->getBLTRRange());
319 for(int k=0;k<dim;k++)
321 p2c[k].first+=ret[k];
322 p2c[k].second+=ret[k];
324 for(int k=0;k<dim;k++)
326 ret[k]=p2c[k].first-p1h->getBLTRRange()[k].first;
327 ret[k]*=f1->getFactors()[k];
334 * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in refined reference.
335 * \param [in] factors - the factors per axis.
337 void MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors)
339 std::size_t sz(factors.size());
340 if(sz!=partBeforeFact.size())
341 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt : size of input vectors must be the same !");
342 for(std::size_t i=0;i<sz;i++)
344 partBeforeFact[i].first*=factors[i];
345 partBeforeFact[i].second*=factors[i];
350 * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
351 * \param [in] ghostSize - the ghost size of zone for all axis.
353 void MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize)
356 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt : ghost size must be >= 0 !");
357 std::size_t sz(partBeforeFact.size());
358 for(std::size_t i=0;i<sz;i++)
360 partBeforeFact[i].first+=ghostSize;
361 partBeforeFact[i].second+=ghostSize;
366 * This method is different than ApplyGhostOnCompactFrmt. The \a partBeforeFact parameter is enlarger contrary to ApplyGhostOnCompactFrmt.
368 * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
369 * \param [in] ghostSize - the ghost size of zone for all axis.
371 void MEDCouplingCartesianAMRPatch::ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize)
374 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyAllGhostOnCompactFrmt : ghost size must be >= 0 !");
375 std::size_t sz(partBeforeFact.size());
376 for(std::size_t i=0;i<sz;i++)
378 partBeforeFact[i].first-=ghostSize;
379 partBeforeFact[i].second+=ghostSize;
383 MEDCouplingCartesianAMRPatchGF::MEDCouplingCartesianAMRPatchGF(MEDCouplingCartesianAMRMesh *mesh):MEDCouplingCartesianAMRPatchGen(mesh)
387 std::size_t MEDCouplingCartesianAMRPatchGF::getHeapMemorySizeWithoutChildren() const
389 return sizeof(MEDCouplingCartesianAMRPatchGF);
392 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
395 throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
399 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
404 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
406 bool ret(_tlc.keepTrackOfNewTL(gf));
416 int MEDCouplingCartesianAMRMeshGen::getSpaceDimension() const
418 return _mesh->getSpaceDimension();
421 void MEDCouplingCartesianAMRMeshGen::setFactors(const std::vector<int>& newFactors)
423 if(getSpaceDimension()!=(int)newFactors.size())
424 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::setFactors : size of input factors is not equal to the space dimension !");
430 if(_factors==newFactors)
432 if(!_patches.empty())
433 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::setFactors : modification of factors is not allowed when presence of patches !");
438 int MEDCouplingCartesianAMRMeshGen::getMaxNumberOfLevelsRelativeToThis() const
441 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
442 ret=std::max(ret,(*it)->getMaxNumberOfLevelsRelativeToThis()+1);
447 * This method returns the number of cells of \a this with the help of the MEDCouplingIMesh instance representing \a this.
448 * The patches in \a this are ignored here.
449 * \sa getNumberOfCellsAtCurrentLevelGhost, getNumberOfCellsRecursiveWithOverlap
451 int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsAtCurrentLevel() const
453 return _mesh->getNumberOfCells();
457 * This method returns the number of cells of \a this with the help of the MEDCouplingIMesh instance representing \a this enlarged by \a ghostLev size
458 * to take into account of the ghost cells for future computation.
459 * The patches in \a this are ignored here.
461 * \sa getNumberOfCellsAtCurrentLevel
463 int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsAtCurrentLevelGhost(int ghostLev) const
465 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> tmp(_mesh->buildWithGhost(ghostLev));
466 return tmp->getNumberOfCells();
470 * This method returns the number of cells including the current level but \b also \b including recursively all cells of other levels
471 * starting from this. The set of cells which size is returned here are generally overlapping each other.
473 int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithOverlap() const
475 int ret(_mesh->getNumberOfCells());
476 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
478 ret+=(*it)->getNumberOfCellsRecursiveWithOverlap();
484 * This method returns the max number of cells covering all the space without overlapping.
485 * It returns the number of cells of the mesh with the highest resolution.
486 * The returned value is equal to the number of cells of mesh returned by buildUnstructured.
488 * \sa buildUnstructured
490 int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithoutOverlap() const
492 int ret(_mesh->getNumberOfCells());
493 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
495 ret-=(*it)->getNumberOfOverlapedCellsForFather();
496 ret+=(*it)->getNumberOfCellsRecursiveWithoutOverlap();
501 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshGen::getFather() const
506 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshGen::getGodFather() const
511 return _father->getGodFather();
515 * This method returns the level of \a this. 0 for god father. -1 for children of god father ...
517 int MEDCouplingCartesianAMRMeshGen::getAbsoluteLevel() const
522 return _father->getAbsoluteLevel()-1;
526 * This method returns grids relative to god father to specified level \a absoluteLev.
528 * \return std::vector<MEDCouplingCartesianAMRPatchGen *> - objects in vector are to be managed (decrRef) by the caller.
530 std::vector<MEDCouplingCartesianAMRPatchGen *> MEDCouplingCartesianAMRMeshGen::retrieveGridsAt(int absoluteLev) const
533 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::retrieveGridsAt : absolute level must be >=0 !");
535 return getGodFather()->retrieveGridsAt(absoluteLev);
537 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > rets;
538 retrieveGridsAtInternal(absoluteLev,rets);
539 std::vector< MEDCouplingCartesianAMRPatchGen * > ret(rets.size());
540 for(std::size_t i=0;i<rets.size();i++)
542 ret[i]=rets[i].retn();
547 void MEDCouplingCartesianAMRMeshGen::detachFromFather()
554 * \param [in] bottomLeftTopRight a vector equal to the space dimension of \a mesh that specifies for each dimension, the included cell start of the range for the first element of the pair,
555 * a the end cell (\b excluded) of the range for the second element of the pair.
556 * \param [in] factors The factor of refinement per axis (different from 0).
558 void MEDCouplingCartesianAMRMeshGen::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors)
560 checkFactorsAndIfNotSetAssign(factors);
561 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> mesh(static_cast<MEDCouplingIMesh *>(_mesh->buildStructuredSubPart(bottomLeftTopRight)));
562 mesh->refineWithFactor(factors);
563 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRMeshSub> zeMesh(new MEDCouplingCartesianAMRMeshSub(this,mesh));
564 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> elt(new MEDCouplingCartesianAMRPatch(zeMesh,bottomLeftTopRight));
565 _patches.push_back(elt);
571 class InternalPatch : public RefCountObjectOnly
574 InternalPatch():_nb_of_true(0) { }
575 int getDimension() const { return (int)_part.size(); }
576 double getEfficiency() const { return (double)_nb_of_true/(double)_crit.size(); }
577 int getNumberOfCells() const { return (int)_crit.size(); }
578 void setNumberOfTrue(int nboft) { _nb_of_true=nboft; }
579 std::vector<bool>& getCriterion() { return _crit; }
580 const std::vector<bool>& getConstCriterion() const { return _crit; }
581 void setPart(const std::vector< std::pair<int,int> >& part) { _part=part; }
582 std::vector< std::pair<int,int> >& getPart() { return _part; }
583 const std::vector< std::pair<int,int> >& getConstPart() const { return _part; }
584 bool presenceOfTrue() const { return _nb_of_true>0; }
585 std::vector<int> computeCGS() const { return MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(_part); }
586 std::vector< std::vector<int> > computeSignature() const { return MEDCouplingStructuredMesh::ComputeSignaturePerAxisOf(computeCGS(),getConstCriterion()); }
587 double getEfficiencyPerAxis(int axisId) const { return (double)_nb_of_true/((double)(_part[axisId].second-_part[axisId].first)); }
588 void zipToFitOnCriterion();
589 void updateNumberOfTrue() const;
590 MEDCouplingAutoRefCountObjectPtr<InternalPatch> extractPart(const std::vector< std::pair<int,int> >&partInGlobal) const;
591 MEDCouplingAutoRefCountObjectPtr<InternalPatch> deepCpy() const;
595 mutable int _nb_of_true;
596 std::vector<bool> _crit;
598 std::vector< std::pair<int,int> > _part;
601 void InternalPatch::zipToFitOnCriterion()
603 std::vector<int> cgs(computeCGS());
604 std::vector<bool> newCrit;
605 std::vector< std::pair<int,int> > newPart,newPart2;
606 int newNbOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(cgs,_crit,newCrit,newPart));
607 MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(_part,newPart,newPart2);
608 if(newNbOfTrue!=_nb_of_true)
609 throw INTERP_KERNEL::Exception("InternalPatch::zipToFitOnCrit : internal error !");
610 _crit=newCrit; _part=newPart2;
613 void InternalPatch::updateNumberOfTrue() const
615 _nb_of_true=(int)std::count(_crit.begin(),_crit.end(),true);
618 MEDCouplingAutoRefCountObjectPtr<InternalPatch> InternalPatch::extractPart(const std::vector< std::pair<int,int> >&partInGlobal) const
620 MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(new InternalPatch);
621 std::vector<int> cgs(computeCGS());
622 std::vector< std::pair<int,int> > newPart;
623 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(_part,partInGlobal,newPart);
624 MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom(cgs,_crit,newPart,ret->getCriterion());
625 ret->setPart(partInGlobal);
626 ret->updateNumberOfTrue();
630 MEDCouplingAutoRefCountObjectPtr<InternalPatch> InternalPatch::deepCpy() const
632 MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(new InternalPatch);
637 void DissectBigPatch(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int rangeOfAxisId, bool& cutFound, int& cutPlace)
639 cutFound=false; cutPlace=-1;
640 std::vector<double> ratio(rangeOfAxisId-1);
641 for(int id=0;id<rangeOfAxisId-1;id++)
643 double efficiency[2];
646 std::vector< std::pair<int,int> > rectH(patchToBeSplit->getConstPart());
648 rectH[axisId].second=patchToBeSplit->getConstPart()[axisId].first+id;
650 rectH[axisId].first=patchToBeSplit->getConstPart()[axisId].first+id;
651 MEDCouplingAutoRefCountObjectPtr<InternalPatch> p(patchToBeSplit->deepCpy());
652 p->zipToFitOnCriterion();
654 efficiency[h]=p->getEfficiencyPerAxis(axisId);
656 ratio[id]=std::max(efficiency[0],efficiency[1])/std::min(efficiency[0],efficiency[1]);
658 int minCellDirection(bso.getMinCellDirection()),indexMin(-1);
659 int dimRatioInner(rangeOfAxisId-1-2*(minCellDirection-1));
660 std::vector<double> ratio_inner(dimRatioInner);
661 double minRatio(1.e10);
662 for(int i=0; i<dimRatioInner; i++)
664 if(ratio[minCellDirection-1+i]<minRatio)
666 minRatio=ratio[minCellDirection-1+i];
667 indexMin=i+minCellDirection;
670 cutFound=true; cutPlace=indexMin+patchToBeSplit->getConstPart()[axisId].first-1;
673 void FindHole(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int& axisId, bool& cutFound, int& cutPlace)
675 cutPlace=-1; cutFound=false;
676 int minCellDirection(bso.getMinCellDirection());
677 const int dim(patchToBeSplit->getDimension());
678 std::vector< std::vector<int> > signatures(patchToBeSplit->computeSignature());
679 for(int id=0;id<dim;id++)
681 const std::vector<int>& signature(signatures[id]);
682 std::vector<int> hole;
683 std::vector<double> distance;
684 int len((int)signature.size());
685 for(int i=0;i<len;i++)
687 if(len>= 2*minCellDirection && i >= minCellDirection-1 && i <= len-minCellDirection-1)
691 double center(((double)len/2.));
692 for(std::size_t i=0;i<hole.size();i++)
693 distance.push_back(fabs(hole[i]+1.-center));
695 std::size_t posDistanceMin(std::distance(distance.begin(),std::min_element(distance.begin(),distance.end())));
698 cutPlace=hole[posDistanceMin]+patchToBeSplit->getConstPart()[axisId].first+1;
704 void FindInflection(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, bool& cutFound, int& cutPlace, int& axisId)
706 cutFound=false; cutPlace=-1;// do not set axisId before to be sure that cutFound was set to true
708 const std::vector< std::pair<int,int> >& part(patchToBeSplit->getConstPart());
709 int sign,minCellDirection(bso.getMinCellDirection());
710 const int dim(patchToBeSplit->getDimension());
712 std::vector<int> zeroCrossDims(dim,-1);
713 std::vector<int> zeroCrossVals(dim,-1);
714 std::vector< std::vector<int> > signatures(patchToBeSplit->computeSignature());
715 for (int id=0;id<dim;id++)
717 const std::vector<int>& signature(signatures[id]);
719 std::vector<int> derivate_second_order,gradient_absolute,signe_change,zero_cross,edge,max_cross_list ;
720 std::vector<double> distance ;
722 for (unsigned int i=1;i<signature.size()-1;i++)
723 derivate_second_order.push_back(signature[i-1]-2*signature[i]+signature[i+1]) ;
725 // Gradient absolute value
726 for ( unsigned int i=1;i<derivate_second_order.size();i++)
727 gradient_absolute.push_back(fabs(derivate_second_order[i]-derivate_second_order[i-1])) ;
728 if(derivate_second_order.empty())
730 for (unsigned int i=0;i<derivate_second_order.size()-1;i++)
732 if (derivate_second_order[i]*derivate_second_order[i+1] < 0 )
734 if (derivate_second_order[i]*derivate_second_order[i+1] > 0 )
736 if (derivate_second_order[i]*derivate_second_order[i+1] == 0 )
738 if ( sign==0 || sign==-1 )
739 if ( i >= (unsigned int)minCellDirection-2 && i <= signature.size()-minCellDirection-2 )
741 zero_cross.push_back(i) ;
742 edge.push_back(gradient_absolute[i]) ;
744 signe_change.push_back(sign) ;
746 if ( zero_cross.size() > 0 )
748 int max_cross=*max_element(edge.begin(),edge.end()) ;
749 for (unsigned int i=0;i<edge.size();i++)
750 if (edge[i]==max_cross)
751 max_cross_list.push_back(zero_cross[i]+1) ;
753 double center((signature.size()/2.0));
754 for (unsigned int i=0;i<max_cross_list.size();i++)
755 distance.push_back(fabs(max_cross_list[i]+1-center));
757 float distance_min=*min_element(distance.begin(),distance.end()) ;
758 int pos_distance_min=find(distance.begin(),distance.end(),distance_min)-distance.begin();
759 int best_place = max_cross_list[pos_distance_min] + part[id].first ;
762 zeroCrossDims[id] = best_place ;
763 zeroCrossVals[id] = max_cross ;
766 derivate_second_order.clear() ;
767 gradient_absolute.clear() ;
768 signe_change.clear() ;
771 max_cross_list.clear() ;
775 if ( zeroCrossDims[0]!=-1 || zeroCrossDims[1]!=-1 )
777 int max_cross_dims = *max_element(zeroCrossVals.begin(),zeroCrossVals.end()) ;
779 if (zeroCrossVals[0]==max_cross_dims && zeroCrossVals[1]==max_cross_dims )
781 int nl_left(part[0].second-part[0].first);
782 int nc_left(part[1].second-part[1].first);
783 if ( nl_left >= nc_left )
789 max_cross_dims=std::find(zeroCrossVals.begin(),zeroCrossVals.end(),max_cross_dims)-zeroCrossVals.begin();
791 cutPlace=zeroCrossDims[max_cross_dims];
792 axisId=max_cross_dims ;
796 void TryAction4(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int rangeOfAxisId, bool& cutFound, int& cutPlace)
799 if(patchToBeSplit->getEfficiency()<=bso.getEffeciencySnd())
801 if(rangeOfAxisId>=2*bso.getMinCellDirection())
804 cutPlace=rangeOfAxisId/2+patchToBeSplit->getConstPart()[axisId].first-1;
809 if(patchToBeSplit->getNumberOfCells()>bso.getMaxCells())
811 DissectBigPatch(bso,patchToBeSplit,axisId,rangeOfAxisId,cutFound,cutPlace);
816 MEDCouplingAutoRefCountObjectPtr<InternalPatch> DealWithNoCut(const InternalPatch *patch)
818 MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(const_cast<InternalPatch *>(patch));
823 void DealWithCut(const InternalPatch *patchToBeSplit, int axisId, int cutPlace, std::vector<MEDCouplingAutoRefCountObjectPtr<InternalPatch> >& listOfPatches)
825 MEDCouplingAutoRefCountObjectPtr<InternalPatch> leftPart,rightPart;
826 std::vector< std::pair<int,int> > rect(patchToBeSplit->getConstPart());
827 std::vector< std::pair<int,int> > leftRect(rect),rightRect(rect);
828 leftRect[axisId].second=cutPlace+1;
829 rightRect[axisId].first=cutPlace+1;
830 leftPart=patchToBeSplit->extractPart(leftRect);
831 rightPart=patchToBeSplit->extractPart(rightRect);
832 leftPart->zipToFitOnCriterion(); rightPart->zipToFitOnCriterion();
833 listOfPatches.push_back(leftPart);
834 listOfPatches.push_back(rightPart);
840 * This method creates patches in \a this (by destroying the patches if any). This method uses \a criterion array as a field on cells on this level.
842 void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const std::vector<bool>& criterion, const std::vector<int>& factors)
844 int nbCells(getNumberOfCellsAtCurrentLevel());
845 if(nbCells!=(int)criterion.size())
846 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterion : the number of tuples of criterion array must be equal to the number of cells at the current level !");
848 std::vector<int> cgs(_mesh->getCellGridStructure());
849 std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> > listOfPatches,listOfPatchesOK;
851 MEDCouplingAutoRefCountObjectPtr<InternalPatch> p(new InternalPatch);
852 p->setNumberOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(cgs,criterion,p->getCriterion(),p->getPart()));
853 if(p->presenceOfTrue())
854 listOfPatches.push_back(p);
855 while(!listOfPatches.empty())
857 std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> > listOfPatchesTmp;
858 for(std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> >::iterator it=listOfPatches.begin();it!=listOfPatches.end();it++)
861 int axisId,rangeOfAxisId,cutPlace;
863 MEDCouplingStructuredMesh::FindTheWidestAxisOfGivenRangeInCompactFrmt((*it)->getConstPart(),axisId,rangeOfAxisId);
864 if((*it)->getEfficiency()>=bso.getEffeciency() && (*it)->getNumberOfCells()<bso.getMaxCells())
865 { listOfPatchesOK.push_back(DealWithNoCut(*it)); continue; }//action 1
866 FindHole(bso,*it,axisId,cutFound,cutPlace);//axisId overwritten here if FindHole equal to true !
868 { DealWithCut(*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 2
869 FindInflection(bso,*it,cutFound,cutPlace,axisId);//axisId overwritten here if cutFound equal to true !
871 { DealWithCut(*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 3
872 TryAction4(bso,*it,axisId,rangeOfAxisId,cutFound,cutPlace);
874 { DealWithCut(*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 4
875 listOfPatchesOK.push_back(DealWithNoCut(*it));
877 listOfPatches=listOfPatchesTmp;
879 for(std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> >::const_iterator it=listOfPatchesOK.begin();it!=listOfPatchesOK.end();it++)
880 addPatch((*it)->getConstPart(),factors);
885 * This method creates patches in \a this (by destroying the patches if any). This method uses \a criterion array as a field on cells on this level.
887 void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector<int>& factors)
889 if(!criterion || !criterion->isAllocated())
890 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterion : the criterion DataArrayByte instance must be allocated and not NULL !");
891 std::vector<bool> crit(criterion->toVectorOfBool());//check that criterion has one component.
892 createPatchesFromCriterion(bso,crit,factors);
896 void MEDCouplingCartesianAMRMeshGen::removeAllPatches()
902 void MEDCouplingCartesianAMRMeshGen::removePatch(int patchId)
904 checkPatchId(patchId);
905 int sz((int)_patches.size()),j(0);
906 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> > patches(sz-1);
907 for(int i=0;i<sz;i++)
909 patches[j++]=_patches[i];
910 (const_cast<MEDCouplingCartesianAMRMeshGen *>(_patches[patchId]->getMesh()))->detachFromFather();
915 int MEDCouplingCartesianAMRMeshGen::getNumberOfPatches() const
917 return (int)_patches.size();
920 int MEDCouplingCartesianAMRMeshGen::getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const
923 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++,ret++)
925 if((*it)->getMesh()==mesh)
928 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchIdFromChildMesh : no such a mesh in my direct progeny !");
931 std::vector< const MEDCouplingCartesianAMRPatch *> MEDCouplingCartesianAMRMeshGen::getPatches() const
933 std::size_t sz(_patches.size());
934 std::vector< const MEDCouplingCartesianAMRPatch *> ret(sz);
935 for(std::size_t i=0;i<sz;i++)
940 const MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRMeshGen::getPatch(int patchId) const
942 checkPatchId(patchId);
943 return _patches[patchId];
947 * This method states if patch2 (with id \a patchId2) is in the neighborhood of patch1 (with id \a patchId1).
948 * The neighborhood size is defined by \a ghostLev in the reference of \a this ( \b not in the reference of patches !).
950 bool MEDCouplingCartesianAMRMeshGen::isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const
952 const MEDCouplingCartesianAMRPatch *p1(getPatch(patchId1)),*p2(getPatch(patchId2));
953 return p1->isInMyNeighborhood(p2,GetGhostLevelInFineRef(ghostLev,_factors));
957 * This method creates a new cell field array on given \a patchId patch in \a this starting from a coarse cell field on \a this \a cellFieldOnThis.
958 * This method can be seen as a fast projection from the cell field \a cellFieldOnThis on \c this->getImageMesh() to a refined part of \a this
959 * defined by the patch with id \a patchId.
961 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
962 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
963 * \return DataArrayDouble * - The array of the cell field on the requested patch
965 * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() )
966 * \throw if \a cellFieldOnThis is NULL or not allocated
967 * \sa fillCellFieldOnPatch, MEDCouplingIMesh::SpreadCoarseToFine
969 DataArrayDouble *MEDCouplingCartesianAMRMeshGen::createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const
971 if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
972 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !");
973 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
974 const MEDCouplingIMesh *fine(patch->getMesh()->getImageMesh());
975 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(fine->getNumberOfCells(),cellFieldOnThis->getNumberOfComponents());
976 ret->copyStringInfoFrom(*cellFieldOnThis);
977 MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),ret,patch->getBLTRRange(),getFactors());
982 * This method is equivalent to MEDCouplingCartesianAMRMesh::createCellFieldOnPatch except that here instead of creating a new instance
983 * it fills the value into the \a cellFieldOnPatch data.
985 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
986 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
987 * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled.
989 * \sa createCellFieldOnPatch, fillCellFieldComingFromPatch
991 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch) const
993 if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
994 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !");
995 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
996 MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors());
1000 * This method is the generalization of fillCellFieldOnPatch method. This method only projects coarse to fine without considering the
1001 * potential neighbor patches covered by the ghost cells of patch with id \a patchId.
1003 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
1004 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
1005 * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled.
1006 * \param [in] ghostLev - The size of the ghost zone (must be >=0 !)
1008 * \sa fillCellFieldOnPatch, fillCellFieldOnPatchGhostAdv
1010 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const
1012 if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
1013 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatchGhost : the input cell field array is NULL or not allocated !");
1014 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
1015 MEDCouplingIMesh::SpreadCoarseToFineGhost(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev);
1019 * This method is equivalent to fillCellFieldOnPatchGhost except that here \b ONLY \b the \b ghost \b zone will be updated
1020 * in \a cellFieldOnPatch.
1022 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
1023 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
1024 * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled \b only \b in \b the \b ghost \b zone.
1025 * \param [in] ghostLev - The size of the ghost zone (must be >=0 !)
1027 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const
1029 if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
1030 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyOnGhostZone : the input cell field array is NULL or not allocated !");
1031 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
1032 MEDCouplingIMesh::SpreadCoarseToFineGhostZone(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev);
1036 * This method is a refinement of fillCellFieldOnPatchGhost. fillCellFieldOnPatchGhost is first called.
1037 * Then for all other patches than those pointed by \a patchId that overlap the ghost zone of the patch impact the ghost zone adequately.
1039 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
1040 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
1041 * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled.
1042 * \param [in] ghostLev - The size of the ghost zone (must be >=0 !)
1043 * \param [in] arrsOnPatches - \b WARNING arrsOnPatches[patchId] is \b NOT \b const. All others are const.
1045 * \sa fillCellFieldOnPatchOnlyGhostAdv
1047 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const
1049 int nbp(getNumberOfPatches());
1050 if(nbp!=(int)arrsOnPatches.size())
1052 std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !";
1053 throw INTERP_KERNEL::Exception(oss.str().c_str());
1055 DataArrayDouble *theFieldToFill(const_cast<DataArrayDouble *>(arrsOnPatches[patchId]));
1056 // first, do as usual
1057 fillCellFieldOnPatchGhost(patchId,cellFieldOnThis,theFieldToFill,ghostLev);
1058 fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrsOnPatches);
1062 * This method updates the patch with id \a patchId considering the only the all the patches in \a this to fill ghost zone.
1063 * So \b warning, the DataArrayDouble instance \a arrsOnPatches[patchId] is non const.
1065 * \sa getPatchIdsInTheNeighborhoodOf
1067 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const
1069 int nbp(getNumberOfPatches());
1070 if(nbp!=(int)arrsOnPatches.size())
1072 std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !";
1073 throw INTERP_KERNEL::Exception(oss.str().c_str());
1075 const MEDCouplingCartesianAMRPatch *refP(getPatch(patchId));
1076 DataArrayDouble *theFieldToFill(const_cast<DataArrayDouble *>(arrsOnPatches[patchId]));
1077 std::vector<int> ids(getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
1078 for(std::vector<int>::const_iterator it=ids.begin();it!=ids.end();it++)
1080 const MEDCouplingCartesianAMRPatch *otherP(getPatch(*it));
1081 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,refP,otherP,theFieldToFill,arrsOnPatches[*it]);
1085 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const
1087 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,patchToBeModified,neighborPatch,cellFieldOnPatch,cellFieldNeighbor);
1091 * This method updates \a cellFieldOnThis part of values coming from the cell field \a cellFieldOnPatch lying on patch having id \a patchId.
1093 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
1094 * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId.
1095 * \param [in,out] cellFieldOnThis The array of the cell field on \a this to be updated only on the part concerning the patch with id \a patchId.
1097 * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() )
1098 * \throw if \a cellFieldOnPatch is NULL or not allocated
1099 * \sa createCellFieldOnPatch, MEDCouplingIMesh::CondenseFineToCoarse,fillCellFieldComingFromPatchGhost
1101 void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const
1103 if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated())
1104 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch : the input cell field array is NULL or not allocated !");
1105 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
1106 MEDCouplingIMesh::CondenseFineToCoarse(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis);
1110 * This method is the extension of MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch managing the ghost cells. If this
1111 * method is called with \a ghostLev equal to 0 it behaves exactly as MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch.
1113 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
1114 * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId.
1115 * \param [in,out] cellFieldOnThis The array of the cell field on \a this to be updated only on the part concerning the patch with id \a patchId.
1116 * \param [in] ghostLev The size of ghost zone (must be >= 0 !)
1118 * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() )
1119 * \throw if \a cellFieldOnPatch is NULL or not allocated
1120 * \sa fillCellFieldComingFromPatch
1122 void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev) const
1124 if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated())
1125 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatchGhost : the input cell field array is NULL or not allocated !");
1126 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
1127 MEDCouplingIMesh::CondenseFineToCoarseGhost(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis,ghostLev);
1131 * This method finds all patches (located by their ids) that are in the neighborhood of patch with id \a patchId. The neighborhood size is
1132 * defined by ghostLev.
1134 * \param [in] patchId - the id of the considered patch.
1135 * \param [in] ghostLev - the size of the neighborhood.
1136 * \return DataArrayInt * - the newly allocated array containing the list of patches in the neighborhood of the considered patch. This array is to be deallocated by the caller.
1138 DataArrayInt *MEDCouplingCartesianAMRMeshGen::findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const
1140 int nbp(getNumberOfPatches());
1141 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1142 for(int i=0;i<nbp;i++)
1145 if(isPatchInNeighborhoodOf(i,patchId,ghostLev))
1146 ret->pushBackSilent(i);
1151 MEDCouplingUMesh *MEDCouplingCartesianAMRMeshGen::buildUnstructured() const
1153 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> part(_mesh->buildUnstructured());
1154 std::vector<bool> bs(_mesh->getNumberOfCells(),false);
1155 std::vector<int> cgs(_mesh->getCellGridStructure());
1156 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > msSafe(_patches.size()+1);
1158 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++,ii++)
1160 MEDCouplingStructuredMesh::SwitchOnIdsFrom(cgs,(*it)->getBLTRRange(),bs);
1161 msSafe[ii+1]=(*it)->getMesh()->buildUnstructured();
1163 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsOff(DataArrayInt::BuildListOfSwitchedOff(bs));
1164 msSafe[0]=static_cast<MEDCouplingUMesh *>(part->buildPartOfMySelf(eltsOff->begin(),eltsOff->end(),false));
1165 std::vector< const MEDCouplingUMesh * > ms(msSafe.size());
1166 for(std::size_t i=0;i<msSafe.size();i++)
1168 return MEDCouplingUMesh::MergeUMeshes(ms);
1172 * This method returns a mesh containing as cells that there is patches at the current level.
1173 * The patches are seen like 'boxes' that is too say the refinement will not appear here.
1175 * \return MEDCoupling1SGTUMesh * - A new object to be managed by the caller containing as cells as there are patches in \a this.
1177 MEDCoupling1SGTUMesh *MEDCouplingCartesianAMRMeshGen::buildMeshFromPatchEnvelop() const
1179 std::vector<const MEDCoupling1SGTUMesh *> cells;
1180 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > cellsSafe;
1181 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1183 const MEDCouplingCartesianAMRPatch *patch(*it);
1186 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> cell(patch->getMesh()->getImageMesh()->asSingleCell());
1187 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> cell1SGT(cell->build1SGTUnstructured());
1188 cellsSafe.push_back(cell1SGT); cells.push_back(cell1SGT);
1191 return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(cells);
1194 MEDCoupling1SGTUMesh *MEDCouplingCartesianAMRMeshGen::buildMeshOfDirectChildrenOnly() const
1196 std::vector<const MEDCoupling1SGTUMesh *> patches;
1197 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > patchesSafe;
1198 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1200 const MEDCouplingCartesianAMRPatch *patch(*it);
1203 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> patchMesh(patch->getMesh()->getImageMesh()->build1SGTUnstructured());
1204 patchesSafe.push_back(patchMesh); patches.push_back(patchMesh);
1207 return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(patches);
1211 * This method works same as buildUnstructured except that arrays are given in input to build a field on cell in output.
1212 * \return MEDCouplingFieldDouble * - a newly created instance the caller has reponsability to deal with.
1213 * \sa buildUnstructured
1215 MEDCouplingFieldDouble *MEDCouplingCartesianAMRMeshGen::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostSz, const std::vector<const DataArrayDouble *>& recurseArrs) const
1217 if(recurseArrs.empty())
1218 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::buildCellFieldOnRecurseWithoutOverlapWithoutGhost : array is empty ! Should never happen !");
1220 std::vector<bool> bs(_mesh->getNumberOfCells(),false);
1221 std::vector<int> cgs(_mesh->getCellGridStructure());
1222 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> > msSafe(_patches.size()+1);
1224 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++,ii++)
1226 MEDCouplingStructuredMesh::SwitchOnIdsFrom(cgs,(*it)->getBLTRRange(),bs);
1227 std::vector<const DataArrayDouble *> tmpArrs(extractSubTreeFromGlobalFlatten((*it)->getMesh(),recurseArrs));
1228 msSafe[ii+1]=(*it)->getMesh()->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(ghostSz,tmpArrs);
1230 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsOff(DataArrayInt::BuildListOfSwitchedOff(bs));
1232 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
1233 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(extractGhostFrom(ghostSz,recurseArrs[0]));
1234 arr2=arr2->selectByTupleIdSafe(eltsOff->begin(),eltsOff->end());
1235 ret->setArray(arr2);
1236 ret->setName(arr2->getName());
1237 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> part(_mesh->buildUnstructured());
1238 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mesh(part->buildPartOfMySelf(eltsOff->begin(),eltsOff->end(),false));
1242 std::vector< const MEDCouplingFieldDouble * > ms(msSafe.size());
1243 for(std::size_t i=0;i<msSafe.size();i++)
1246 return MEDCouplingFieldDouble::MergeFields(ms);
1250 * This method extracts from \arr arr the part inside \a arr by cutting the \a ghostSz external part.
1251 * \arr is expected to be an array having a number of tuples equal to \c getImageMesh()->buildWithGhost(ghostSz).
1253 DataArrayDouble *MEDCouplingCartesianAMRMeshGen::extractGhostFrom(int ghostSz, const DataArrayDouble *arr) const
1255 std::vector<int> st(_mesh->getCellGridStructure());
1256 std::vector< std::pair<int,int> > p(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(st));
1257 std::transform(st.begin(),st.end(),st.begin(),std::bind2nd(std::plus<int>(),2*ghostSz));
1258 MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt(p,ghostSz);
1259 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(st,arr,p));
1264 * This method returns all the patches in \a this not equal to \a patchId that are in neighborhood of patch with id \a patchId.
1266 * \sa fillCellFieldOnPatchOnlyGhostAdv
1268 std::vector<int> MEDCouplingCartesianAMRMeshGen::getPatchIdsInTheNeighborhoodOf(int patchId, int ghostLev) const
1270 std::vector<int> ret;
1271 int nbp(getNumberOfPatches());
1273 for(int i=0;i<nbp;i++)
1276 if(isPatchInNeighborhoodOf(i,patchId,ghostLev))
1282 MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
1283 const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop):_father(0)
1285 _mesh=MEDCouplingIMesh::New(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop);
1288 MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh):_father(father)
1291 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh) constructor : empty father !");
1293 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh) constructor : The input mesh is null !");
1294 mesh->checkCoherency();
1295 _mesh=mesh; _mesh->incrRef();
1298 void MEDCouplingCartesianAMRMeshGen::checkPatchId(int patchId) const
1300 int sz(getNumberOfPatches());
1301 if(patchId<0 || patchId>=sz)
1303 std::ostringstream oss; oss << "MEDCouplingCartesianAMRMeshGen::checkPatchId : invalid patchId (" << patchId << ") ! Must be in [0," << sz << ") !";
1304 throw INTERP_KERNEL::Exception(oss.str().c_str());
1308 void MEDCouplingCartesianAMRMeshGen::checkFactorsAndIfNotSetAssign(const std::vector<int>& factors)
1310 if(getSpaceDimension()!=(int)factors.size())
1311 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::checkFactorsAndIfNotSetAssign : invalid size of factors ! size must be equal to the spaceDimension !");
1312 if(_factors.empty())
1318 if(_factors!=factors)
1319 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::checkFactorsAndIfNotSetAssign : the factors ");
1323 void MEDCouplingCartesianAMRMeshGen::retrieveGridsAtInternal(int lev, std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> >& grids) const
1327 const MEDCouplingCartesianAMRMesh *thisc(dynamic_cast<const MEDCouplingCartesianAMRMesh *>(this));//tony
1328 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGF> elt(new MEDCouplingCartesianAMRPatchGF(const_cast<MEDCouplingCartesianAMRMesh *>(thisc)));
1329 grids.push_back(DynamicCastSafe<MEDCouplingCartesianAMRPatchGF,MEDCouplingCartesianAMRPatchGen>(elt));
1333 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1335 const MEDCouplingCartesianAMRPatch *pt(*it);
1338 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> tmp1(*it);
1339 grids.push_back(DynamicCastSafe<MEDCouplingCartesianAMRPatch,MEDCouplingCartesianAMRPatchGen>(tmp1));
1345 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1347 const MEDCouplingCartesianAMRPatch *pt(*it);
1349 pt->getMesh()->retrieveGridsAtInternal(lev-1,grids);
1354 int MEDCouplingCartesianAMRMeshGen::GetGhostLevelInFineRef(int ghostLev, const std::vector<int>& factors)
1357 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::GetGhostLevelInFineRef : the ghost size must be >=0 !");
1359 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::GetGhostLevelInFineRef : no factors defined !");
1360 int ghostLevInPatchRef;
1362 ghostLevInPatchRef=0;
1365 ghostLevInPatchRef=(ghostLev-1)/factors[0]+1;
1366 for(std::size_t i=0;i<factors.size();i++)
1367 ghostLevInPatchRef=std::max(ghostLevInPatchRef,(ghostLev-1)/factors[i]+1);
1369 return ghostLevInPatchRef;
1373 * This method returns a sub set of \a all. The subset is defined by the \a head in the tree defined by \a this.
1374 * Elements in \a all are expected to be sorted from god father to most refined structure.
1376 std::vector<const DataArrayDouble *> MEDCouplingCartesianAMRMeshGen::extractSubTreeFromGlobalFlatten(const MEDCouplingCartesianAMRMeshGen *head, const std::vector<const DataArrayDouble *>& all) const
1378 int maxLev(getMaxNumberOfLevelsRelativeToThis());
1379 std::vector<const DataArrayDouble *> ret;
1380 std::vector<const MEDCouplingCartesianAMRMeshGen *> meshes(1,this);
1382 for(int i=0;i<maxLev;i++)
1384 std::vector<const MEDCouplingCartesianAMRMeshGen *> meshesTmp;
1385 for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it=meshes.begin();it!=meshes.end();it++)
1387 if((*it)==head || head->isObjectInTheProgeny(*it))
1388 ret.push_back(all[kk]);
1390 std::vector< const MEDCouplingCartesianAMRPatch *> ps((*it)->getPatches());
1391 for(std::vector< const MEDCouplingCartesianAMRPatch *>::const_iterator it0=ps.begin();it0!=ps.end();it0++)
1393 const MEDCouplingCartesianAMRMeshGen *mesh((*it0)->getMesh());
1394 meshesTmp.push_back(mesh);
1400 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::extractSubTreeFromGlobalFlatten : the size of input vector is not compatible with number of leaves in this !");
1404 std::size_t MEDCouplingCartesianAMRMeshGen::getHeapMemorySizeWithoutChildren() const
1406 return sizeof(MEDCouplingCartesianAMRMeshGen);
1409 std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRMeshGen::getDirectChildren() const
1411 std::vector<const BigMemoryObject *> ret;
1412 if((const MEDCouplingIMesh *)_mesh)
1413 ret.push_back((const MEDCouplingIMesh *)_mesh);
1414 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1416 if((const MEDCouplingCartesianAMRPatch*)*it)
1417 ret.push_back((const MEDCouplingCartesianAMRPatch*)*it);
1422 void MEDCouplingCartesianAMRMeshGen::updateTime() const
1424 if((const MEDCouplingIMesh *)_mesh)
1425 updateTimeWith(*_mesh);
1426 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1428 const MEDCouplingCartesianAMRPatch *elt(*it);
1431 const MEDCouplingCartesianAMRMeshGen *mesh(elt->getMesh());
1433 updateTimeWith(*mesh);
1437 MEDCouplingCartesianAMRMeshSub::MEDCouplingCartesianAMRMeshSub(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh):MEDCouplingCartesianAMRMeshGen(father,mesh)
1441 MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
1442 const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop)
1444 return new MEDCouplingCartesianAMRMesh(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop);
1447 void MEDCouplingCartesianAMRMesh::setData(MEDCouplingDataForGodFather *data)
1449 MEDCouplingDataForGodFather *myData(_data);
1453 myData->changeGodFather(0);
1459 void MEDCouplingCartesianAMRMesh::allocData() const
1465 void MEDCouplingCartesianAMRMesh::deallocData() const
1471 MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
1472 const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop):MEDCouplingCartesianAMRMeshGen(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop)
1476 std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRMesh::getDirectChildren() const
1478 std::vector<const BigMemoryObject *> ret(MEDCouplingCartesianAMRMeshGen::getDirectChildren());
1479 const MEDCouplingDataForGodFather *pt(_data);
1485 void MEDCouplingCartesianAMRMesh::checkData() const
1487 const MEDCouplingDataForGodFather *data(_data);
1489 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::checkData : no data set !");
1492 MEDCouplingCartesianAMRMesh::~MEDCouplingCartesianAMRMesh()
1494 MEDCouplingDataForGodFather *data(_data);
1496 data->changeGodFather(0);