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 "MEDCouplingAMRAttribute.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
24 #include "MEDCoupling1GTUMesh.hxx"
25 #include "MEDCouplingIMesh.hxx"
26 #include "MEDCouplingUMesh.hxx"
32 using namespace ParaMEDMEM;
36 int MEDCouplingCartesianAMRPatchGen::getNumberOfCellsRecursiveWithOverlap() const
38 return _mesh->getNumberOfCellsRecursiveWithOverlap();
41 int MEDCouplingCartesianAMRPatchGen::getNumberOfCellsRecursiveWithoutOverlap() const
43 return _mesh->getNumberOfCellsRecursiveWithoutOverlap();
46 int MEDCouplingCartesianAMRPatchGen::getMaxNumberOfLevelsRelativeToThis() const
48 return _mesh->getMaxNumberOfLevelsRelativeToThis();
51 MEDCouplingCartesianAMRPatchGen::MEDCouplingCartesianAMRPatchGen(MEDCouplingCartesianAMRMeshGen *mesh)
54 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen constructor : input mesh is NULL !");
55 _mesh=mesh; _mesh->incrRef();
58 MEDCouplingCartesianAMRPatchGen::MEDCouplingCartesianAMRPatchGen(const MEDCouplingCartesianAMRPatchGen& other, MEDCouplingCartesianAMRMeshGen *father):RefCountObject(other),_mesh(other._mesh)
60 const MEDCouplingCartesianAMRMeshGen *mesh(other._mesh);
62 _mesh=mesh->deepCpy(father);
65 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatchGen::getMeshSafe() const
67 const MEDCouplingCartesianAMRMeshGen *mesh(_mesh);
69 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen::getMeshSafe const : the mesh is NULL !");
73 MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatchGen::getMeshSafe()
75 MEDCouplingCartesianAMRMeshGen *mesh(_mesh);
77 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen::getMeshSafe : the mesh is NULL !");
81 std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRPatchGen::getDirectChildren() const
83 std::vector<const BigMemoryObject *> ret;
84 if((const MEDCouplingCartesianAMRMeshGen *)_mesh)
85 ret.push_back((const MEDCouplingCartesianAMRMeshGen *)_mesh);
90 * \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.
91 * \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,
92 * a the end cell (\b excluded) of the range for the second element of the pair.
94 MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMeshGen *mesh, const std::vector< std::pair<int,int> >& bottomLeftTopRight):MEDCouplingCartesianAMRPatchGen(mesh),_bl_tr(bottomLeftTopRight)
96 int dim((int)bottomLeftTopRight.size()),dimExp(_mesh->getSpaceDimension());
98 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch constructor : space dimension of father and input bottomLeft/topRight size mismatches !");
101 MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRPatch::deepCpy(MEDCouplingCartesianAMRMeshGen *father) const
103 return new MEDCouplingCartesianAMRPatch(*this,father);
106 void MEDCouplingCartesianAMRPatch::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors)
108 return getMeshSafe()->addPatch(bottomLeftTopRight,factors);
111 int MEDCouplingCartesianAMRPatch::getNumberOfOverlapedCellsForFather() const
113 return MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(_bl_tr);
117 * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter
118 * 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 !).
119 * Call isInMyNeighborhoodExt to deal with 2 patches not sharing directly the same father.
121 * \param [in] other - The other patch
122 * \param [in] ghostLev - The size of the neighborhood zone.
124 * \throw if \a this or \a other are invalid (end before start).
125 * \throw if \a ghostLev is \b not >= 0 .
126 * \throw if \a this and \a other have not the same space dimension.
128 * \sa isInMyNeighborhoodExt
130 bool MEDCouplingCartesianAMRPatch::isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const
133 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the size of the neighborhood must be >= 0 !");
135 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the input patch is NULL !");
136 const std::vector< std::pair<int,int> >& thisp(getBLTRRange());
137 const std::vector< std::pair<int,int> >& otherp(other->getBLTRRange());
138 return IsInMyNeighborhood(ghostLev,thisp,otherp);
142 * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter
143 * the must be >= 0. This method works even if \a this and \a other does not share the same father. But the level between their common
144 * ancestor must be the same. If they don't have the same ancestor an exception will be thrown.
146 * \param [in] other - The other patch
147 * \param [in] ghostLev - The size of the neighborhood zone.
149 * \throw if \a this or \a other are invalid (end before start).
150 * \throw if \a ghostLev is \b not >= 0 .
151 * \throw if \a this and \a other have not the same space dimension.
152 * \throw if there is not common ancestor of \a this and \a other.
154 * \sa isInMyNeighborhood, isInMyNeighborhoodDiffLev
156 bool MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const
159 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt : the size of the neighborhood must be >= 0 !");
161 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt : the input patch is NULL !");
163 const MEDCouplingCartesianAMRMeshGen *com(FindCommonAncestor(this,other,lev));//check that factors are OK
165 return isInMyNeighborhood(other,ghostLev);
166 std::vector<int> offset(ComputeOffsetFromTwoToOne(com,lev,this,other));
167 const std::vector< std::pair<int,int> >& thisp(getBLTRRange());
168 std::vector< std::pair<int,int> > otherp(other->getBLTRRange());
169 otherp=MEDCouplingStructuredMesh::TranslateCompactFrmt(otherp,offset);
170 return IsInMyNeighborhood(ghostLev,thisp,otherp);
174 * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter
175 * the must be >= 0. This method works even if \a this and \a other does not share the same father.
176 * \a this is expected to be more refined than \a other. That is to say lev of \a this is greater than level of \a other.
178 * \param [in] other - The other patch
179 * \param [in] ghostLev - The size of the neighborhood zone.
181 * \throw if \a this or \a other are invalid (end before start).
182 * \throw if \a ghostLev is \b not >= 0 .
183 * \throw if \a this and \a other have not the same space dimension.
184 * \throw if there is not common ancestor of \a this and \a other.
186 * \sa isInMyNeighborhoodExt
188 bool MEDCouplingCartesianAMRPatch::isInMyNeighborhoodDiffLev(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const
190 std::vector< std::pair<int,int> > thispp,otherpp;
191 std::vector<int> factors;
192 ComputeZonesOfTwoRelativeToOneDiffLev(ghostLev,this,other,thispp,otherpp,factors);
193 return IsInMyNeighborhood(ghostLev>0?1:0,thispp,otherpp);//1 not ghostLev ! It is not a bug ( I hope :) ) ! Because as \a this is a refinement of \a other ghostLev is supposed to be <= factors
196 std::vector<int> MEDCouplingCartesianAMRPatch::computeCellGridSt() const
198 const MEDCouplingCartesianAMRMeshGen *m(getMesh());
200 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::computeCellGridSt : no mesh held by this !");
201 const MEDCouplingCartesianAMRMeshGen *father(m->getFather());
203 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::computeCellGridSt : no father help by underlying mesh !");
204 const std::vector< std::pair<int,int> >& bltr(getBLTRRange());
205 const std::vector<int>& factors(father->getFactors());
206 std::vector<int> ret(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(bltr));
207 std::transform(ret.begin(),ret.end(),factors.begin(),ret.begin(),std::multiplies<int>());
211 bool MEDCouplingCartesianAMRPatch::IsInMyNeighborhood(int ghostLev, const std::vector< std::pair<int,int> >& p1, const std::vector< std::pair<int,int> >& p2)
213 std::size_t thispsize(p1.size());
214 if(thispsize!=p2.size())
215 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the dimensions must be the same !");
216 for(std::size_t i=0;i<thispsize;i++)
218 const std::pair<int,int>& thispp(p1[i]);
219 const std::pair<int,int>& otherpp(p2[i]);
220 if(thispp.second<thispp.first)
221 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : this patch is invalid !");
222 if(otherpp.second<otherpp.first)
223 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : this patch is invalid !");
224 if(otherpp.first==thispp.second+ghostLev-1)
226 if(otherpp.second+ghostLev-1==thispp.first)
228 int start(std::max(thispp.first,otherpp.first)),end(std::min(thispp.second,otherpp.second));
236 * \sa FindNeighborsOfSubPatchesOf
238 std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2)
241 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev : the input pointers must be not NULL !");
242 std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > ret;
243 std::vector< const MEDCouplingCartesianAMRPatch *> p1Work(p1->getMesh()->getPatches()),p2Work(p2->getMesh()->getPatches());
244 while(!p1Work.empty())
246 std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > retTmp;
247 std::vector<const MEDCouplingCartesianAMRPatch *> p1Work2,p2Work2;
248 for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it1=p1Work.begin();it1!=p1Work.end();it1++)
250 for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++)
252 if((*it1)->isInMyNeighborhoodExt(*it2,ghostLev>0?1:0))//1 not ghostLev ! It is not a bug ( I hope :) ) ! Because as \a this is a refinement of \a other ghostLev is supposed to be <= factors
253 retTmp.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(*it1,*it2));
255 std::vector<const MEDCouplingCartesianAMRPatch *> tmp1((*it1)->getMesh()->getPatches());
256 p1Work2.insert(p1Work2.end(),tmp1.begin(),tmp1.end());
258 for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++)
260 std::vector<const MEDCouplingCartesianAMRPatch *> tmp2((*it2)->getMesh()->getPatches());
261 p2Work2.insert(p2Work2.end(),tmp2.begin(),tmp2.end());
263 ret.push_back(retTmp);
271 * This method returns all pair of patches (pa,pb) so that pb is in the neighborhood of pa (size of neighborhood is \a ghostLev).
272 * pa is a refinement (a child) of \b p1 and pb is equal to \a p2. So the returned pair do not have the same level as it is the case for
273 * FindNeighborsOfSubPatchesOfSameLev.
275 * \sa FindNeighborsOfSubPatchesOfSameLev
277 void MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair<const MEDCouplingCartesianAMRPatch *, const MEDCouplingCartesianAMRPatch *> >& ret)
280 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf : the input pointers must be not NULL !");
281 std::vector< const MEDCouplingCartesianAMRPatch *> p1Work(p1->getMesh()->getPatches());
282 while(!p1Work.empty())
284 std::vector<const MEDCouplingCartesianAMRPatch *> p1Work2;
285 for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it0=p1Work.begin();it0!=p1Work.end();it0++)
287 if((*it0)->isInMyNeighborhoodDiffLev(p2,ghostLev))
288 ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(*it0,p2));
289 std::vector<const MEDCouplingCartesianAMRPatch *> tmp2((*it0)->getMesh()->getPatches());
290 p1Work2.insert(p1Work2.end(),tmp2.begin(),tmp2.end());
297 * \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.
299 * \saUpdateNeighborsOfOneWithTwoExt
301 void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(int ghostLev, const std::vector<int>& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2)
303 const std::vector< std::pair<int,int> >& p1BLTR(p1->getBLTRRange());
304 const std::vector< std::pair<int,int> >& p2BLTR(p2->getBLTRRange());
305 UpdateNeighborsOfOneWithTwoInternal(ghostLev,factors,p1BLTR,p2BLTR,dataOnP1,dataOnP2);
309 * Idem than UpdateNeighborsOfOneWithTwo, except that here \a p1 and \a p2 are not sharing the same direct father.
311 * \sa UpdateNeighborsOfOneWithTwo
313 void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2)
315 const std::vector< std::pair<int,int> >& p1BLTR(p1->getBLTRRange());//p1BLTR=[(10,12),(5,8)]
316 std::vector< std::pair<int,int> > p2BLTR(p2->getBLTRRange());//p2BLTR=[(0,1),(0,5)]
318 const MEDCouplingCartesianAMRMeshGen *ca(FindCommonAncestor(p1,p2,lev));
319 std::vector<int> offset(ComputeOffsetFromTwoToOne(ca,lev,p1,p2));//[12,4]
320 p2BLTR=MEDCouplingStructuredMesh::TranslateCompactFrmt(p2BLTR,offset);//p2BLTR=[(12,13),(4,9)]
321 UpdateNeighborsOfOneWithTwoInternal(ghostLev,p1->getMesh()->getFather()->getFactors(),p1BLTR,p2BLTR,dataOnP1,dataOnP2);
325 * \a p1 is expected to be more refined than \a p2. \a p1 and \a p2 have to share a common ancestor. Compared to UpdateNeighborsOfOneWithTwoExt here \a p1 and \a p2 are \b not at the same level !
327 void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2)
329 std::vector< std::pair<int,int> > p1pp,p2pp;
330 std::vector<int> factors;
331 ComputeZonesOfTwoRelativeToOneDiffLev(ghostLev,p1,p2,p1pp,p2pp,factors);
333 std::vector<int> dimsP2NotRefined(p2->computeCellGridSt());
334 std::vector<int> dimsP2Refined(dimsP2NotRefined);
335 std::transform(dimsP2NotRefined.begin(),dimsP2NotRefined.end(),factors.begin(),dimsP2Refined.begin(),std::multiplies<int>());
336 std::vector< std::pair<int,int> > p2RefinedAbs(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsP2NotRefined));
337 std::vector<int> dimsP2RefinedGhost(dimsP2Refined.size());
338 std::transform(dimsP2Refined.begin(),dimsP2Refined.end(),dimsP2RefinedGhost.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));
339 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> fineP2(DataArrayDouble::New()); fineP2->alloc(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(dimsP2RefinedGhost),dataOnP2->getNumberOfComponents());
340 MEDCouplingIMesh::SpreadCoarseToFineGhost(dataOnP2,dimsP2NotRefined,fineP2,p2RefinedAbs,factors,ghostLev);
342 UpdateNeighborsOfOneWithTwoInternal(ghostLev,p1->getMesh()->getFather()->getFactors(),p1pp,p2pp,dataOnP1,fineP2);
346 * \a p1 is expected to be more refined than \a p2. \a p1 and \a p2 have to share a common ancestor. Compared to UpdateNeighborsOfOneWithTwoExt here \a p1 and \a p2 are \b not at the same level !
347 * This method has 3 outputs. 2 two first are the resp the position of \a p1 and \a p2 relative to \a p1. And \a factToApplyOn2 is the coeff of refinement to be applied on \a p2 to be virtualy
348 * on the same level as \a p1.
350 void MEDCouplingCartesianAMRPatch::ComputeZonesOfTwoRelativeToOneDiffLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair<int,int> >& p1Zone, std::vector< std::pair<int,int> >& p2Zone, std::vector<int>& factToApplyOn2)
352 std::vector<const MEDCouplingCartesianAMRMeshGen *> ancestorsOfThis;
353 const MEDCouplingCartesianAMRMeshGen *work(p1->getMesh()),*work2(0);
354 ancestorsOfThis.push_back(work);
357 work=work->getFather();
359 ancestorsOfThis.push_back(work);
364 std::size_t levThis(0),levOther(0);
365 while(work && !found)
368 work=work->getFather();
372 std::vector<const MEDCouplingCartesianAMRMeshGen *>::iterator it(std::find(ancestorsOfThis.begin(),ancestorsOfThis.end(),work));
373 if(it!=ancestorsOfThis.end())
375 levThis=std::distance(ancestorsOfThis.begin(),it);
381 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeZonesOfTwoRelativeToOneDiffLev : no common ancestor found !");
382 if(levThis<=levOther)
383 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeZonesOfTwoRelativeToOneDiffLev : this method is not called correctly !");
385 const MEDCouplingCartesianAMRMeshGen *comAncestor(ancestorsOfThis[levThis]);
386 int idThis(comAncestor->getPatchIdFromChildMesh(ancestorsOfThis[levThis-1])),idOther(comAncestor->getPatchIdFromChildMesh(work2));
387 const MEDCouplingCartesianAMRPatch *thisp(comAncestor->getPatch(idThis)),*otherp(comAncestor->getPatch(idOther));
388 std::vector<int> offset(ComputeOffsetFromTwoToOne(comAncestor,levOther,thisp,otherp));
389 p1Zone=thisp->getBLTRRange(); p2Zone=MEDCouplingStructuredMesh::TranslateCompactFrmt(otherp->getBLTRRange(),offset);
390 factToApplyOn2.resize(p1Zone.size()); std::fill(factToApplyOn2.begin(),factToApplyOn2.end(),1);
392 std::size_t nbOfTurn(levThis-levOther);
393 for(std::size_t i=0;i<nbOfTurn;i++)
395 std::vector< std::pair<int,int> > tmp0;
396 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p1Zone,p2Zone,tmp0,false);
398 const MEDCouplingCartesianAMRMeshGen *curAncestor(ancestorsOfThis[levThis-i]);
399 ApplyFactorsOnCompactFrmt(p2Zone,curAncestor->getFactors());
400 curAncestor=ancestorsOfThis[levThis-1-i];
401 const std::vector<int>& factors(curAncestor->getFactors());
402 std::transform(factToApplyOn2.begin(),factToApplyOn2.end(),factors.begin(),factToApplyOn2.begin(),std::multiplies<int>());
403 int tmpId(curAncestor->getPatchIdFromChildMesh(ancestorsOfThis[levThis-2-i]));
404 p1Zone=curAncestor->getPatch(tmpId)->getBLTRRange();
408 std::size_t MEDCouplingCartesianAMRPatch::getHeapMemorySizeWithoutChildren() const
410 std::size_t ret(sizeof(MEDCouplingCartesianAMRPatch));
411 ret+=_bl_tr.capacity()*sizeof(std::pair<int,int>);
415 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatch::FindCommonAncestor(const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, int& lev)
417 const MEDCouplingCartesianAMRMeshGen *f1(p1->_mesh),*f2(p2->_mesh);
419 while(f1!=f2 || f1==0 || f2==0)
421 f1=f1->getFather(); f2=f2->getFather();
422 if(f1->getFactors()!=f2->getFactors())
423 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindCommonAncestor : factors differ !");
427 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindCommonAncestor : no common ancestor between p1 and p2 !");
431 std::vector<int> MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne(const MEDCouplingCartesianAMRMeshGen *comAncestor, int lev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2)
434 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : this method is useful only for lev > 0 !");
436 int dim(p1->getMesh()->getSpaceDimension());
437 if(p2->getMesh()->getSpaceDimension()!=dim)
438 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : dimension must be the same !");
439 std::vector< int > ret(dim,0);
440 for(int i=0;i<zeLev;i++)
442 const MEDCouplingCartesianAMRMeshGen *f1(p1->_mesh),*f2(p2->_mesh);
443 const MEDCouplingCartesianAMRPatch *p1h(0),*p2h(0);
444 for(int j=0;j<lev-i;j++)
446 const MEDCouplingCartesianAMRMeshGen *f1tmp(f1->getFather()),*f2tmp(f2->getFather());
447 int pid1(f1tmp->getPatchIdFromChildMesh(f1)),pid2(f2tmp->getPatchIdFromChildMesh(f2));
448 p1h=f1tmp->getPatch(pid1); p2h=f2tmp->getPatch(pid2);
451 std::vector< std::pair<int,int> > p2c(p2h->getBLTRRange());
452 for(int k=0;k<dim;k++)
454 p2c[k].first+=ret[k];
455 p2c[k].second+=ret[k];
457 for(int k=0;k<dim;k++)
459 ret[k]=p2c[k].first-p1h->getBLTRRange()[k].first;
460 ret[k]*=f1->getFactors()[k];
466 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)
467 {//p1=[(1,4),(2,4)] p2=[(4,5),(3,4)]
468 int dim((int)factors.size());
469 std::vector<int> dimsCoarse(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(p1));//[3,2]
470 std::transform(dimsCoarse.begin(),dimsCoarse.end(),factors.begin(),dimsCoarse.begin(),std::multiplies<int>());//[12,8]
471 std::transform(dimsCoarse.begin(),dimsCoarse.end(),dimsCoarse.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));//[14,10]
472 std::vector< std::pair<int,int> > rangeCoarse(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsCoarse));//[(0,14),(0,10)]
473 std::vector<int> fakeFactors(dim,1);
475 std::vector< std::pair<int,int> > tmp0,tmp1,tmp2;
476 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p1,p2,tmp0,false);//tmp0=[(3,4),(1,2)]
477 ApplyFactorsOnCompactFrmt(tmp0,factors);//tmp0=[(12,16),(4,8)]
478 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(tmp0,ghostLev);//tmp0=[(13,17),(5,9)]
479 std::vector< std::pair<int,int> > interstRange(MEDCouplingStructuredMesh::IntersectRanges(tmp0,rangeCoarse));//interstRange=[(13,14),(5,9)]
480 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p2,p1,tmp1,false);//tmp1=[(-3,0),(-1,1)]
481 ApplyFactorsOnCompactFrmt(tmp1,factors);//tmp1=[(-12,-4),(-4,0)]
482 MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(tmp1,interstRange,tmp2,false);//tmp2=[(1,2),(1,5)]
484 std::vector< std::pair<int,int> > dimsFine(p2);
485 ApplyFactorsOnCompactFrmt(dimsFine,factors);
486 ApplyAllGhostOnCompactFrmt(dimsFine,ghostLev);
488 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ghostVals(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(dimsFine),dataOnP2,tmp2));
489 MEDCouplingIMesh::CondenseFineToCoarse(dimsCoarse,ghostVals,interstRange,fakeFactors,dataOnP1);
492 MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(const MEDCouplingCartesianAMRPatch& other, MEDCouplingCartesianAMRMeshGen *father):MEDCouplingCartesianAMRPatchGen(other,father),_bl_tr(other._bl_tr)
497 * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in refined reference.
498 * \param [in] factors - the factors per axis.
500 void MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors)
502 std::size_t sz(factors.size());
503 if(sz!=partBeforeFact.size())
504 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt : size of input vectors must be the same !");
505 for(std::size_t i=0;i<sz;i++)
507 partBeforeFact[i].first*=factors[i];
508 partBeforeFact[i].second*=factors[i];
513 * This method is different than ApplyGhostOnCompactFrmt. The \a partBeforeFact parameter is enlarger contrary to ApplyGhostOnCompactFrmt.
515 * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
516 * \param [in] ghostSize - the ghost size of zone for all axis.
518 void MEDCouplingCartesianAMRPatch::ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize)
521 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyAllGhostOnCompactFrmt : ghost size must be >= 0 !");
522 std::size_t sz(partBeforeFact.size());
523 for(std::size_t i=0;i<sz;i++)
525 partBeforeFact[i].first-=ghostSize;
526 partBeforeFact[i].second+=ghostSize;
530 MEDCouplingCartesianAMRPatchGF::MEDCouplingCartesianAMRPatchGF(MEDCouplingCartesianAMRMesh *mesh):MEDCouplingCartesianAMRPatchGen(mesh)
534 MEDCouplingCartesianAMRPatchGF *MEDCouplingCartesianAMRPatchGF::deepCpy(MEDCouplingCartesianAMRMeshGen *father) const
536 return new MEDCouplingCartesianAMRPatchGF(*this,father);
539 std::size_t MEDCouplingCartesianAMRPatchGF::getHeapMemorySizeWithoutChildren() const
541 return sizeof(MEDCouplingCartesianAMRPatchGF);
544 MEDCouplingCartesianAMRPatchGF::MEDCouplingCartesianAMRPatchGF(const MEDCouplingCartesianAMRPatchGF& other, MEDCouplingCartesianAMRMeshGen *father):MEDCouplingCartesianAMRPatchGen(other,father)
550 int MEDCouplingCartesianAMRMeshGen::getSpaceDimension() const
552 return _mesh->getSpaceDimension();
555 void MEDCouplingCartesianAMRMeshGen::setFactors(const std::vector<int>& newFactors)
557 if(getSpaceDimension()!=(int)newFactors.size())
558 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::setFactors : size of input factors is not equal to the space dimension !");
564 if(_factors==newFactors)
566 if(!_patches.empty())
567 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::setFactors : modification of factors is not allowed when presence of patches !");
572 int MEDCouplingCartesianAMRMeshGen::getMaxNumberOfLevelsRelativeToThis() const
575 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
576 ret=std::max(ret,(*it)->getMaxNumberOfLevelsRelativeToThis()+1);
581 * This method returns the number of cells of \a this with the help of the MEDCouplingIMesh instance representing \a this.
582 * The patches in \a this are ignored here.
583 * \sa getNumberOfCellsAtCurrentLevelGhost, getNumberOfCellsRecursiveWithOverlap
585 int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsAtCurrentLevel() const
587 return _mesh->getNumberOfCells();
591 * 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
592 * to take into account of the ghost cells for future computation.
593 * The patches in \a this are ignored here.
595 * \sa getNumberOfCellsAtCurrentLevel
597 int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsAtCurrentLevelGhost(int ghostLev) const
599 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> tmp(_mesh->buildWithGhost(ghostLev));
600 return tmp->getNumberOfCells();
604 * This method returns the number of cells including the current level but \b also \b including recursively all cells of other levels
605 * starting from this. The set of cells which size is returned here are generally overlapping each other.
607 int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithOverlap() const
609 int ret(_mesh->getNumberOfCells());
610 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
612 ret+=(*it)->getNumberOfCellsRecursiveWithOverlap();
618 * This method returns the max number of cells covering all the space without overlapping.
619 * It returns the number of cells of the mesh with the highest resolution.
620 * The returned value is equal to the number of cells of mesh returned by buildUnstructured.
622 * \sa buildUnstructured
624 int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithoutOverlap() const
626 int ret(_mesh->getNumberOfCells());
627 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
629 ret-=(*it)->getNumberOfOverlapedCellsForFather();
630 ret+=(*it)->getNumberOfCellsRecursiveWithoutOverlap();
636 * This method returns a vector of size equal to getAbsoluteLevelRelativeTo. It allows to find position an absolute position of \a this
637 * relative to \a ref (that is typically the god father).
639 * \sa getPatchAtPosition
641 std::vector<int> MEDCouplingCartesianAMRMeshGen::getPositionRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const
644 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPositionRelativeTo : input pointer is NULL !");
645 std::vector<int> ret;
646 getPositionRelativeToInternal(ref,ret);
647 std::reverse(ret.begin(),ret.end());
652 * \sa getPositionRelativeTo, getMeshAtPosition
654 const MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRMeshGen::getPatchAtPosition(const std::vector<int>& pos) const
656 std::size_t sz(pos.size());
658 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchAtPosition : empty input -> no patch by definition !");
660 const MEDCouplingCartesianAMRPatch *elt(getPatch(patchId));
663 if(!elt || !elt->getMesh())
664 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchAtPosition : NULL element found during walk !");
665 std::vector<int> pos2(pos.begin()+1,pos.end());
666 return elt->getMesh()->getPatchAtPosition(pos2);
669 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshGen::getMeshAtPosition(const std::vector<int>& pos) const
671 std::size_t sz(pos.size());
675 const MEDCouplingCartesianAMRPatch *elt(getPatch(patchId));
679 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getMeshAtPosition : NULL patch !");
680 return elt->getMesh();
682 if(!elt || !elt->getMesh())
683 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchAtPosition : NULL element found during walk !");
684 std::vector<int> pos2(pos.begin()+1,pos.end());
685 return elt->getMesh()->getMeshAtPosition(pos2);
689 * This method returns grids relative to god father to specified level \a absoluteLev.
691 * \return std::vector<MEDCouplingCartesianAMRPatchGen *> - objects in vector are to be managed (decrRef) by the caller.
693 std::vector<MEDCouplingCartesianAMRPatchGen *> MEDCouplingCartesianAMRMeshGen::retrieveGridsAt(int absoluteLev) const
696 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::retrieveGridsAt : absolute level must be >=0 !");
697 return getGodFather()->retrieveGridsAt(absoluteLev);
701 * \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,
702 * a the end cell (\b excluded) of the range for the second element of the pair.
703 * \param [in] factors The factor of refinement per axis (different from 0).
705 void MEDCouplingCartesianAMRMeshGen::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors)
707 checkFactorsAndIfNotSetAssign(factors);
708 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> mesh(static_cast<MEDCouplingIMesh *>(_mesh->buildStructuredSubPart(bottomLeftTopRight)));
709 mesh->refineWithFactor(factors);
710 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRMeshSub> zeMesh(new MEDCouplingCartesianAMRMeshSub(this,mesh));
711 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> elt(new MEDCouplingCartesianAMRPatch(zeMesh,bottomLeftTopRight));
712 _patches.push_back(elt);
718 class InternalPatch : public RefCountObjectOnly
721 InternalPatch():_nb_of_true(0) { }
722 int getDimension() const { return (int)_part.size(); }
723 double getEfficiency() const { return (double)_nb_of_true/(double)_crit.size(); }
724 int getNumberOfCells() const { return (int)_crit.size(); }
725 void setNumberOfTrue(int nboft) { _nb_of_true=nboft; }
726 std::vector<bool>& getCriterion() { return _crit; }
727 const std::vector<bool>& getConstCriterion() const { return _crit; }
728 void setPart(const std::vector< std::pair<int,int> >& part) { _part=part; }
729 std::vector< std::pair<int,int> >& getPart() { return _part; }
730 const std::vector< std::pair<int,int> >& getConstPart() const { return _part; }
731 bool presenceOfTrue() const { return _nb_of_true>0; }
732 std::vector<int> computeCGS() const { return MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(_part); }
733 std::vector< std::vector<int> > computeSignature() const { return MEDCouplingStructuredMesh::ComputeSignaturePerAxisOf(computeCGS(),getConstCriterion()); }
734 double getEfficiencyPerAxis(int axisId) const { return (double)_nb_of_true/((double)(_part[axisId].second-_part[axisId].first)); }
735 void zipToFitOnCriterion();
736 void updateNumberOfTrue() const;
737 MEDCouplingAutoRefCountObjectPtr<InternalPatch> extractPart(const std::vector< std::pair<int,int> >&partInGlobal) const;
738 MEDCouplingAutoRefCountObjectPtr<InternalPatch> deepCpy() const;
742 mutable int _nb_of_true;
743 std::vector<bool> _crit;
745 std::vector< std::pair<int,int> > _part;
748 void InternalPatch::zipToFitOnCriterion()
750 std::vector<int> cgs(computeCGS());
751 std::vector<bool> newCrit;
752 std::vector< std::pair<int,int> > newPart,newPart2;
753 int newNbOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(cgs,_crit,newCrit,newPart));
754 MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(_part,newPart,newPart2);
755 if(newNbOfTrue!=_nb_of_true)
756 throw INTERP_KERNEL::Exception("InternalPatch::zipToFitOnCrit : internal error !");
757 _crit=newCrit; _part=newPart2;
760 void InternalPatch::updateNumberOfTrue() const
762 _nb_of_true=(int)std::count(_crit.begin(),_crit.end(),true);
765 MEDCouplingAutoRefCountObjectPtr<InternalPatch> InternalPatch::extractPart(const std::vector< std::pair<int,int> >&partInGlobal) const
767 MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(new InternalPatch);
768 std::vector<int> cgs(computeCGS());
769 std::vector< std::pair<int,int> > newPart;
770 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(_part,partInGlobal,newPart);
771 MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom(cgs,_crit,newPart,ret->getCriterion());
772 ret->setPart(partInGlobal);
773 ret->updateNumberOfTrue();
777 MEDCouplingAutoRefCountObjectPtr<InternalPatch> InternalPatch::deepCpy() const
779 MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(new InternalPatch);
784 void DissectBigPatch(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int rangeOfAxisId, bool& cutFound, int& cutPlace)
786 cutFound=false; cutPlace=-1;
787 std::vector<double> ratio(rangeOfAxisId-1);
788 for(int id=0;id<rangeOfAxisId-1;id++)
790 double efficiency[2];
793 std::vector< std::pair<int,int> > rectH(patchToBeSplit->getConstPart());
795 rectH[axisId].second=patchToBeSplit->getConstPart()[axisId].first+id;
797 rectH[axisId].first=patchToBeSplit->getConstPart()[axisId].first+id;
798 MEDCouplingAutoRefCountObjectPtr<InternalPatch> p(patchToBeSplit->deepCpy());
799 p->zipToFitOnCriterion();
801 efficiency[h]=p->getEfficiencyPerAxis(axisId);
803 ratio[id]=std::max(efficiency[0],efficiency[1])/std::min(efficiency[0],efficiency[1]);
805 int minCellDirection(bso.getMinCellDirection()),indexMin(-1);
806 int dimRatioInner(rangeOfAxisId-1-2*(minCellDirection-1));
807 std::vector<double> ratio_inner(dimRatioInner);
808 double minRatio(1.e10);
809 for(int i=0; i<dimRatioInner; i++)
811 if(ratio[minCellDirection-1+i]<minRatio)
813 minRatio=ratio[minCellDirection-1+i];
814 indexMin=i+minCellDirection;
817 cutFound=true; cutPlace=indexMin+patchToBeSplit->getConstPart()[axisId].first-1;
820 void FindHole(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int& axisId, bool& cutFound, int& cutPlace)
822 cutPlace=-1; cutFound=false;
823 int minCellDirection(bso.getMinCellDirection());
824 const int dim(patchToBeSplit->getDimension());
825 std::vector< std::vector<int> > signatures(patchToBeSplit->computeSignature());
826 for(int id=0;id<dim;id++)
828 const std::vector<int>& signature(signatures[id]);
829 std::vector<int> hole;
830 std::vector<double> distance;
831 int len((int)signature.size());
832 for(int i=0;i<len;i++)
834 if(len>= 2*minCellDirection && i >= minCellDirection-1 && i <= len-minCellDirection-1)
838 double center(((double)len/2.));
839 for(std::size_t i=0;i<hole.size();i++)
840 distance.push_back(fabs(hole[i]+1.-center));
842 std::size_t posDistanceMin(std::distance(distance.begin(),std::min_element(distance.begin(),distance.end())));
845 cutPlace=hole[posDistanceMin]+patchToBeSplit->getConstPart()[axisId].first+1;
851 void FindInflection(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, bool& cutFound, int& cutPlace, int& axisId)
853 cutFound=false; cutPlace=-1;// do not set axisId before to be sure that cutFound was set to true
855 const std::vector< std::pair<int,int> >& part(patchToBeSplit->getConstPart());
856 int sign,minCellDirection(bso.getMinCellDirection());
857 const int dim(patchToBeSplit->getDimension());
859 std::vector<int> zeroCrossDims(dim,-1);
860 std::vector<int> zeroCrossVals(dim,-1);
861 std::vector< std::vector<int> > signatures(patchToBeSplit->computeSignature());
862 for (int id=0;id<dim;id++)
864 const std::vector<int>& signature(signatures[id]);
866 std::vector<int> derivate_second_order,gradient_absolute,signe_change,zero_cross,edge,max_cross_list ;
867 std::vector<double> distance ;
869 for (unsigned int i=1;i<signature.size()-1;i++)
870 derivate_second_order.push_back(signature[i-1]-2*signature[i]+signature[i+1]) ;
872 // Gradient absolute value
873 for ( unsigned int i=1;i<derivate_second_order.size();i++)
874 gradient_absolute.push_back(fabs(derivate_second_order[i]-derivate_second_order[i-1])) ;
875 if(derivate_second_order.empty())
877 for (unsigned int i=0;i<derivate_second_order.size()-1;i++)
879 if (derivate_second_order[i]*derivate_second_order[i+1] < 0 )
881 if (derivate_second_order[i]*derivate_second_order[i+1] > 0 )
883 if (derivate_second_order[i]*derivate_second_order[i+1] == 0 )
885 if ( sign==0 || sign==-1 )
886 if ( i >= (unsigned int)minCellDirection-2 && i <= signature.size()-minCellDirection-2 )
888 zero_cross.push_back(i) ;
889 edge.push_back(gradient_absolute[i]) ;
891 signe_change.push_back(sign) ;
893 if ( zero_cross.size() > 0 )
895 int max_cross=*max_element(edge.begin(),edge.end()) ;
896 for (unsigned int i=0;i<edge.size();i++)
897 if (edge[i]==max_cross)
898 max_cross_list.push_back(zero_cross[i]+1) ;
900 double center((signature.size()/2.0));
901 for (unsigned int i=0;i<max_cross_list.size();i++)
902 distance.push_back(fabs(max_cross_list[i]+1-center));
904 float distance_min=*min_element(distance.begin(),distance.end()) ;
905 int pos_distance_min=find(distance.begin(),distance.end(),distance_min)-distance.begin();
906 int best_place = max_cross_list[pos_distance_min] + part[id].first ;
909 zeroCrossDims[id] = best_place ;
910 zeroCrossVals[id] = max_cross ;
913 derivate_second_order.clear() ;
914 gradient_absolute.clear() ;
915 signe_change.clear() ;
918 max_cross_list.clear() ;
922 if ( zeroCrossDims[0]!=-1 || zeroCrossDims[1]!=-1 )
924 int max_cross_dims = *max_element(zeroCrossVals.begin(),zeroCrossVals.end()) ;
926 if (zeroCrossVals[0]==max_cross_dims && zeroCrossVals[1]==max_cross_dims )
928 int nl_left(part[0].second-part[0].first);
929 int nc_left(part[1].second-part[1].first);
930 if ( nl_left >= nc_left )
936 max_cross_dims=std::find(zeroCrossVals.begin(),zeroCrossVals.end(),max_cross_dims)-zeroCrossVals.begin();
938 cutPlace=zeroCrossDims[max_cross_dims];
939 axisId=max_cross_dims ;
943 void TryAction4(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int rangeOfAxisId, bool& cutFound, int& cutPlace)
946 if(patchToBeSplit->getEfficiency()<=bso.getEffeciencySnd())
948 if(rangeOfAxisId>=2*bso.getMinCellDirection())
951 cutPlace=rangeOfAxisId/2+patchToBeSplit->getConstPart()[axisId].first-1;
956 if(patchToBeSplit->getNumberOfCells()>bso.getMaxCells())
958 DissectBigPatch(bso,patchToBeSplit,axisId,rangeOfAxisId,cutFound,cutPlace);
963 MEDCouplingAutoRefCountObjectPtr<InternalPatch> DealWithNoCut(const InternalPatch *patch)
965 MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(const_cast<InternalPatch *>(patch));
970 void DealWithCut(const InternalPatch *patchToBeSplit, int axisId, int cutPlace, std::vector<MEDCouplingAutoRefCountObjectPtr<InternalPatch> >& listOfPatches)
972 MEDCouplingAutoRefCountObjectPtr<InternalPatch> leftPart,rightPart;
973 std::vector< std::pair<int,int> > rect(patchToBeSplit->getConstPart());
974 std::vector< std::pair<int,int> > leftRect(rect),rightRect(rect);
975 leftRect[axisId].second=cutPlace+1;
976 rightRect[axisId].first=cutPlace+1;
977 leftPart=patchToBeSplit->extractPart(leftRect);
978 rightPart=patchToBeSplit->extractPart(rightRect);
979 leftPart->zipToFitOnCriterion(); rightPart->zipToFitOnCriterion();
980 listOfPatches.push_back(leftPart);
981 listOfPatches.push_back(rightPart);
986 void MEDCouplingCartesianAMRMeshGen::removeAllPatches()
992 void MEDCouplingCartesianAMRMeshGen::removePatch(int patchId)
994 checkPatchId(patchId);
995 int sz((int)_patches.size()),j(0);
996 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> > patches(sz-1);
997 for(int i=0;i<sz;i++)
999 patches[j++]=_patches[i];
1000 (const_cast<MEDCouplingCartesianAMRMeshGen *>(_patches[patchId]->getMesh()))->detachFromFather();
1005 int MEDCouplingCartesianAMRMeshGen::getNumberOfPatches() const
1007 return (int)_patches.size();
1011 * 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.
1012 * This method only create patches at level 0 relative to \a this.
1014 void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const std::vector<bool>& criterion, const std::vector<int>& factors)
1016 int nbCells(getNumberOfCellsAtCurrentLevel());
1017 if(nbCells!=(int)criterion.size())
1018 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion : the number of tuples of criterion array must be equal to the number of cells at the current level !");
1020 std::vector<int> cgs(_mesh->getCellGridStructure());
1021 std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> > listOfPatches,listOfPatchesOK;
1023 MEDCouplingAutoRefCountObjectPtr<InternalPatch> p(new InternalPatch);
1024 p->setNumberOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(cgs,criterion,p->getCriterion(),p->getPart()));
1025 if(p->presenceOfTrue())
1026 listOfPatches.push_back(p);
1027 while(!listOfPatches.empty())
1029 std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> > listOfPatchesTmp;
1030 for(std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> >::iterator it=listOfPatches.begin();it!=listOfPatches.end();it++)
1033 int axisId,rangeOfAxisId,cutPlace;
1035 MEDCouplingStructuredMesh::FindTheWidestAxisOfGivenRangeInCompactFrmt((*it)->getConstPart(),axisId,rangeOfAxisId);
1036 if((*it)->getEfficiency()>=bso.getEffeciency() && (*it)->getNumberOfCells()<bso.getMaxCells())
1037 { listOfPatchesOK.push_back(DealWithNoCut(*it)); continue; }//action 1
1038 FindHole(bso,*it,axisId,cutFound,cutPlace);//axisId overwritten here if FindHole equal to true !
1040 { DealWithCut(*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 2
1041 FindInflection(bso,*it,cutFound,cutPlace,axisId);//axisId overwritten here if cutFound equal to true !
1043 { DealWithCut(*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 3
1044 TryAction4(bso,*it,axisId,rangeOfAxisId,cutFound,cutPlace);
1046 { DealWithCut(*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 4
1047 listOfPatchesOK.push_back(DealWithNoCut(*it));
1049 listOfPatches=listOfPatchesTmp;
1051 for(std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> >::const_iterator it=listOfPatchesOK.begin();it!=listOfPatchesOK.end();it++)
1052 addPatch((*it)->getConstPart(),factors);
1057 * 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.
1058 * This method only create patches at level 0 relative to \a this.
1060 void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector<int>& factors)
1062 if(!criterion || !criterion->isAllocated())
1063 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion : the criterion DataArrayByte instance must be allocated and not NULL !");
1064 std::vector<bool> crit(criterion->toVectorOfBool());//check that criterion has one component.
1065 createPatchesFromCriterion(bso,crit,factors);
1069 void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayDouble *criterion, const std::vector<int>& factors, double eps)
1072 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion : null criterion pointer !");
1073 std::vector<bool> inp(criterion->toVectorOfBool(eps));
1074 createPatchesFromCriterion(bso,inp,factors);
1077 int MEDCouplingCartesianAMRMeshGen::getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const
1080 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++,ret++)
1082 if((*it)->getMesh()==mesh)
1085 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchIdFromChildMesh : no such a mesh in my direct progeny !");
1088 std::vector< const MEDCouplingCartesianAMRPatch *> MEDCouplingCartesianAMRMeshGen::getPatches() const
1090 std::size_t sz(_patches.size());
1091 std::vector< const MEDCouplingCartesianAMRPatch *> ret(sz);
1092 for(std::size_t i=0;i<sz;i++)
1097 const MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRMeshGen::getPatch(int patchId) const
1099 checkPatchId(patchId);
1100 return _patches[patchId];
1104 * This method states if patch2 (with id \a patchId2) is in the neighborhood of patch1 (with id \a patchId1).
1105 * The neighborhood size is defined by \a ghostLev in the reference of \a this ( \b not in the reference of patches !).
1107 bool MEDCouplingCartesianAMRMeshGen::isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const
1109 const MEDCouplingCartesianAMRPatch *p1(getPatch(patchId1)),*p2(getPatch(patchId2));
1110 return p1->isInMyNeighborhood(p2,ghostLev);
1114 * 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.
1115 * 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
1116 * defined by the patch with id \a patchId.
1118 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
1119 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
1120 * \return DataArrayDouble * - The array of the cell field on the requested patch
1122 * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() )
1123 * \throw if \a cellFieldOnThis is NULL or not allocated
1124 * \sa fillCellFieldOnPatch, MEDCouplingIMesh::SpreadCoarseToFine
1126 DataArrayDouble *MEDCouplingCartesianAMRMeshGen::createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const
1128 if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
1129 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !");
1130 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
1131 const MEDCouplingIMesh *fine(patch->getMesh()->getImageMesh());
1132 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(fine->getNumberOfCells(),cellFieldOnThis->getNumberOfComponents());
1133 ret->copyStringInfoFrom(*cellFieldOnThis);
1134 MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),ret,patch->getBLTRRange(),getFactors());
1139 * This method is equivalent to MEDCouplingCartesianAMRMesh::createCellFieldOnPatch except that here instead of creating a new instance
1140 * it fills the value into the \a cellFieldOnPatch data.
1142 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
1143 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
1144 * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled.
1146 * \sa createCellFieldOnPatch, fillCellFieldComingFromPatch
1148 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, bool isConservative) const
1150 if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
1151 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !");
1152 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
1153 MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors());
1156 int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors()));
1157 std::transform(cellFieldOnPatch->begin(),cellFieldOnPatch->end(),cellFieldOnPatch->getPointer(),std::bind2nd(std::multiplies<double>(),1./((double)fact)));
1162 * This method is the generalization of fillCellFieldOnPatch method. This method only projects coarse to fine without considering the
1163 * potential neighbor patches covered by the ghost cells of patch with id \a patchId.
1165 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
1166 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
1167 * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled.
1168 * \param [in] ghostLev - The size of the ghost zone (must be >=0 !)
1170 * \sa fillCellFieldOnPatch, fillCellFieldOnPatchGhostAdv
1172 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev, bool isConservative) const
1174 if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
1175 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatchGhost : the input cell field array is NULL or not allocated !");
1176 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
1177 MEDCouplingIMesh::SpreadCoarseToFineGhost(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev);
1180 int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors()));
1181 std::transform(cellFieldOnPatch->begin(),cellFieldOnPatch->end(),cellFieldOnPatch->getPointer(),std::bind2nd(std::multiplies<double>(),1./((double)fact)));
1186 * This method is equivalent to fillCellFieldOnPatchGhost except that here \b ONLY \b the \b ghost \b zone will be updated
1187 * in \a cellFieldOnPatch.
1189 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
1190 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
1191 * \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.
1192 * \param [in] ghostLev - The size of the ghost zone (must be >=0 !)
1194 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const
1196 if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
1197 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyOnGhostZone : the input cell field array is NULL or not allocated !");
1198 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
1199 MEDCouplingIMesh::SpreadCoarseToFineGhostZone(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev);
1203 * This method is a refinement of fillCellFieldOnPatchGhost. fillCellFieldOnPatchGhost is first called.
1204 * Then for all other patches than those pointed by \a patchId that overlap the ghost zone of the patch impact the ghost zone adequately.
1206 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
1207 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
1208 * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled.
1209 * \param [in] ghostLev - The size of the ghost zone (must be >=0 !)
1210 * \param [in] arrsOnPatches - \b WARNING arrsOnPatches[patchId] is \b NOT \b const. All others are const.
1212 * \sa fillCellFieldOnPatchOnlyGhostAdv
1214 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches, bool isConservative) const
1216 int nbp(getNumberOfPatches());
1217 if(nbp!=(int)arrsOnPatches.size())
1219 std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !";
1220 throw INTERP_KERNEL::Exception(oss.str().c_str());
1222 DataArrayDouble *theFieldToFill(const_cast<DataArrayDouble *>(arrsOnPatches[patchId]));
1223 // first, do as usual
1224 fillCellFieldOnPatchGhost(patchId,cellFieldOnThis,theFieldToFill,ghostLev,isConservative);
1225 fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrsOnPatches);
1229 * This method updates the patch with id \a patchId considering the only the all the patches in \a this to fill ghost zone.
1230 * So \b warning, the DataArrayDouble instance \a arrsOnPatches[patchId] is non const.
1232 * \sa getPatchIdsInTheNeighborhoodOf
1234 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const
1236 int nbp(getNumberOfPatches());
1237 if(nbp!=(int)arrsOnPatches.size())
1239 std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !";
1240 throw INTERP_KERNEL::Exception(oss.str().c_str());
1242 const MEDCouplingCartesianAMRPatch *refP(getPatch(patchId));
1243 DataArrayDouble *theFieldToFill(const_cast<DataArrayDouble *>(arrsOnPatches[patchId]));
1244 std::vector<int> ids(getPatchIdsInTheNeighborhoodOf(patchId,ghostLev));
1245 for(std::vector<int>::const_iterator it=ids.begin();it!=ids.end();it++)
1247 const MEDCouplingCartesianAMRPatch *otherP(getPatch(*it));
1248 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,refP,otherP,theFieldToFill,arrsOnPatches[*it]);
1252 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const
1254 MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,patchToBeModified,neighborPatch,cellFieldOnPatch,cellFieldNeighbor);
1258 * This method updates \a cellFieldOnThis part of values coming from the cell field \a cellFieldOnPatch lying on patch having id \a patchId.
1260 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
1261 * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId.
1262 * \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.
1263 * \param [in] isConservative - true if the field needs to be conserved. false if maximum principle has to be applied.
1265 * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() )
1266 * \throw if \a cellFieldOnPatch is NULL or not allocated
1267 * \sa createCellFieldOnPatch, MEDCouplingIMesh::CondenseFineToCoarse,fillCellFieldComingFromPatchGhost
1269 void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative) const
1271 if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated())
1272 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch : the input cell field array is NULL or not allocated !");
1273 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
1274 MEDCouplingIMesh::CondenseFineToCoarse(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis);
1277 int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors()));
1278 MEDCouplingStructuredMesh::MultiplyPartOf(_mesh->getCellGridStructure(),patch->getBLTRRange(),1./((double)fact),cellFieldOnThis);
1283 * This method is the extension of MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch managing the ghost cells. If this
1284 * method is called with \a ghostLev equal to 0 it behaves exactly as MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch.
1286 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
1287 * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId.
1288 * \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.
1289 * \param [in] ghostLev The size of ghost zone (must be >= 0 !)
1290 * \param [in] isConservative - true if the field needs to be conserved. false if maximum principle has to be applied.
1292 * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() )
1293 * \throw if \a cellFieldOnPatch is NULL or not allocated
1294 * \sa fillCellFieldComingFromPatch
1296 void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative) const
1298 if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated())
1299 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatchGhost : the input cell field array is NULL or not allocated !");
1300 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
1301 MEDCouplingIMesh::CondenseFineToCoarseGhost(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis,ghostLev);
1304 int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors()));
1305 MEDCouplingStructuredMesh::MultiplyPartOfByGhost(_mesh->getCellGridStructure(),patch->getBLTRRange(),ghostLev,1./((double)fact),cellFieldOnThis);
1310 * This method finds all patches (located by their ids) that are in the neighborhood of patch with id \a patchId. The neighborhood size is
1311 * defined by ghostLev.
1313 * \param [in] patchId - the id of the considered patch.
1314 * \param [in] ghostLev - the size of the neighborhood.
1315 * \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.
1317 DataArrayInt *MEDCouplingCartesianAMRMeshGen::findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const
1319 int nbp(getNumberOfPatches());
1320 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1321 for(int i=0;i<nbp;i++)
1324 if(isPatchInNeighborhoodOf(i,patchId,ghostLev))
1325 ret->pushBackSilent(i);
1330 MEDCouplingUMesh *MEDCouplingCartesianAMRMeshGen::buildUnstructured() const
1332 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> part(_mesh->buildUnstructured());
1333 std::vector<bool> bs(_mesh->getNumberOfCells(),false);
1334 std::vector<int> cgs(_mesh->getCellGridStructure());
1335 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > msSafe(_patches.size()+1);
1337 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++,ii++)
1339 MEDCouplingStructuredMesh::SwitchOnIdsFrom(cgs,(*it)->getBLTRRange(),bs);
1340 msSafe[ii+1]=(*it)->getMesh()->buildUnstructured();
1342 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsOff(DataArrayInt::BuildListOfSwitchedOff(bs));
1343 msSafe[0]=static_cast<MEDCouplingUMesh *>(part->buildPartOfMySelf(eltsOff->begin(),eltsOff->end(),false));
1344 std::vector< const MEDCouplingUMesh * > ms(msSafe.size());
1345 for(std::size_t i=0;i<msSafe.size();i++)
1347 return MEDCouplingUMesh::MergeUMeshes(ms);
1351 * This method returns a mesh containing as cells that there is patches at the current level.
1352 * The patches are seen like 'boxes' that is too say the refinement will not appear here.
1354 * \return MEDCoupling1SGTUMesh * - A new object to be managed by the caller containing as cells as there are patches in \a this.
1356 MEDCoupling1SGTUMesh *MEDCouplingCartesianAMRMeshGen::buildMeshFromPatchEnvelop() const
1358 std::vector<const MEDCoupling1SGTUMesh *> cells;
1359 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > cellsSafe;
1360 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1362 const MEDCouplingCartesianAMRPatch *patch(*it);
1365 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> cell(patch->getMesh()->getImageMesh()->asSingleCell());
1366 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> cell1SGT(cell->build1SGTUnstructured());
1367 cellsSafe.push_back(cell1SGT); cells.push_back(cell1SGT);
1370 return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(cells);
1373 MEDCoupling1SGTUMesh *MEDCouplingCartesianAMRMeshGen::buildMeshOfDirectChildrenOnly() const
1375 std::vector<const MEDCoupling1SGTUMesh *> patches;
1376 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > patchesSafe;
1377 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1379 const MEDCouplingCartesianAMRPatch *patch(*it);
1382 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> patchMesh(patch->getMesh()->getImageMesh()->build1SGTUnstructured());
1383 patchesSafe.push_back(patchMesh); patches.push_back(patchMesh);
1386 return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(patches);
1390 * This method works same as buildUnstructured except that arrays are given in input to build a field on cell in output.
1391 * \return MEDCouplingFieldDouble * - a newly created instance the caller has reponsability to deal with.
1392 * \sa buildUnstructured
1394 MEDCouplingFieldDouble *MEDCouplingCartesianAMRMeshGen::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostSz, const std::vector<const DataArrayDouble *>& recurseArrs) const
1396 if(recurseArrs.empty())
1397 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::buildCellFieldOnRecurseWithoutOverlapWithoutGhost : array is empty ! Should never happen !");
1399 std::vector<bool> bs(_mesh->getNumberOfCells(),false);
1400 std::vector<int> cgs(_mesh->getCellGridStructure());
1401 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> > msSafe(_patches.size()+1);
1403 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++,ii++)
1405 MEDCouplingStructuredMesh::SwitchOnIdsFrom(cgs,(*it)->getBLTRRange(),bs);
1406 std::vector<const DataArrayDouble *> tmpArrs(extractSubTreeFromGlobalFlatten((*it)->getMesh(),recurseArrs));
1407 msSafe[ii+1]=(*it)->getMesh()->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(ghostSz,tmpArrs);
1409 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsOff(DataArrayInt::BuildListOfSwitchedOff(bs));
1411 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
1412 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(extractGhostFrom(ghostSz,recurseArrs[0]));
1413 arr2=arr2->selectByTupleIdSafe(eltsOff->begin(),eltsOff->end());
1414 ret->setArray(arr2);
1415 ret->setName(arr2->getName());
1416 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> part(_mesh->buildUnstructured());
1417 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mesh(part->buildPartOfMySelf(eltsOff->begin(),eltsOff->end(),false));
1421 std::vector< const MEDCouplingFieldDouble * > ms(msSafe.size());
1422 for(std::size_t i=0;i<msSafe.size();i++)
1425 return MEDCouplingFieldDouble::MergeFields(ms);
1429 * This method extracts from \arr arr the part inside \a arr by cutting the \a ghostSz external part.
1430 * \arr is expected to be an array having a number of tuples equal to \c getImageMesh()->buildWithGhost(ghostSz).
1432 DataArrayDouble *MEDCouplingCartesianAMRMeshGen::extractGhostFrom(int ghostSz, const DataArrayDouble *arr) const
1434 std::vector<int> st(_mesh->getCellGridStructure());
1435 std::vector< std::pair<int,int> > p(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(st));
1436 std::transform(st.begin(),st.end(),st.begin(),std::bind2nd(std::plus<int>(),2*ghostSz));
1437 MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(p,ghostSz);
1438 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(st,arr,p));
1443 * This method returns all the patches in \a this not equal to \a patchId that are in neighborhood of patch with id \a patchId.
1445 * \sa fillCellFieldOnPatchOnlyGhostAdv
1447 std::vector<int> MEDCouplingCartesianAMRMeshGen::getPatchIdsInTheNeighborhoodOf(int patchId, int ghostLev) const
1449 std::vector<int> ret;
1450 int nbp(getNumberOfPatches());
1452 for(int i=0;i<nbp;i++)
1455 if(isPatchInNeighborhoodOf(i,patchId,ghostLev))
1462 * This method returns a dump python of \a this. It is useful for users of createPatchesFromCriterion method for debugging.
1464 * \sa dumpPatchesOf, createPatchesFromCriterion, createPatchesFromCriterionML
1466 std::string MEDCouplingCartesianAMRMeshGen::buildPythonDumpOfThis() const
1468 std::ostringstream oss;
1469 oss << "amr=MEDCouplingCartesianAMRMesh(\""<< getImageMesh()->getName() << "\"," << getSpaceDimension() << ",[";
1470 std::vector<int> ngs(getImageMesh()->getNodeGridStructure());
1471 std::vector<double> orig(getImageMesh()->getOrigin()),dxyz(getImageMesh()->getDXYZ());
1472 std::copy(ngs.begin(),ngs.end(),std::ostream_iterator<int>(oss,","));
1474 std::copy(orig.begin(),orig.end(),std::ostream_iterator<double>(oss,","));
1476 std::copy(dxyz.begin(),dxyz.end(),std::ostream_iterator<double>(oss,","));
1478 dumpPatchesOf("amr",oss);
1482 MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(const MEDCouplingCartesianAMRMeshGen& other):RefCountObject(other),_mesh(other._mesh),_patches(other._patches),_factors(other._factors)
1484 const MEDCouplingIMesh *mesh(other._mesh);
1486 _mesh=static_cast<MEDCouplingIMesh *>(mesh->deepCpy());
1487 std::size_t sz(other._patches.size());
1488 for(std::size_t i=0;i<sz;i++)
1490 const MEDCouplingCartesianAMRPatch *patch(other._patches[i]);
1492 _patches[i]=patch->deepCpy(this);
1496 MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
1497 const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop)
1499 _mesh=MEDCouplingIMesh::New(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop);
1502 MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh)
1505 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh) constructor : The input mesh is null !");
1506 mesh->checkCoherency();
1507 _mesh=mesh; _mesh->incrRef();
1510 void MEDCouplingCartesianAMRMeshGen::checkPatchId(int patchId) const
1512 int sz(getNumberOfPatches());
1513 if(patchId<0 || patchId>=sz)
1515 std::ostringstream oss; oss << "MEDCouplingCartesianAMRMeshGen::checkPatchId : invalid patchId (" << patchId << ") ! Must be in [0," << sz << ") !";
1516 throw INTERP_KERNEL::Exception(oss.str().c_str());
1520 void MEDCouplingCartesianAMRMeshGen::checkFactorsAndIfNotSetAssign(const std::vector<int>& factors)
1522 if(getSpaceDimension()!=(int)factors.size())
1523 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::checkFactorsAndIfNotSetAssign : invalid size of factors ! size must be equal to the spaceDimension !");
1524 if(_factors.empty())
1530 if(_factors!=factors)
1531 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::checkFactorsAndIfNotSetAssign : the factors ");
1535 void MEDCouplingCartesianAMRMeshGen::retrieveGridsAtInternal(int lev, std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> >& grids) const
1539 const MEDCouplingCartesianAMRMesh *thisc(dynamic_cast<const MEDCouplingCartesianAMRMesh *>(this));//tony
1540 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGF> elt(new MEDCouplingCartesianAMRPatchGF(const_cast<MEDCouplingCartesianAMRMesh *>(thisc)));
1541 grids.push_back(DynamicCastSafe<MEDCouplingCartesianAMRPatchGF,MEDCouplingCartesianAMRPatchGen>(elt));
1545 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1547 const MEDCouplingCartesianAMRPatch *pt(*it);
1550 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> tmp1(*it);
1551 grids.push_back(DynamicCastSafe<MEDCouplingCartesianAMRPatch,MEDCouplingCartesianAMRPatchGen>(tmp1));
1557 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1559 const MEDCouplingCartesianAMRPatch *pt(*it);
1561 pt->getMesh()->retrieveGridsAtInternal(lev-1,grids);
1566 int MEDCouplingCartesianAMRMeshGen::GetGhostLevelInFineRef(int ghostLev, const std::vector<int>& factors)
1569 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::GetGhostLevelInFineRef : the ghost size must be >=0 !");
1571 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::GetGhostLevelInFineRef : no factors defined !");
1572 int ghostLevInPatchRef;
1574 ghostLevInPatchRef=0;
1577 ghostLevInPatchRef=(ghostLev-1)/factors[0]+1;
1578 for(std::size_t i=0;i<factors.size();i++)
1579 ghostLevInPatchRef=std::max(ghostLevInPatchRef,(ghostLev-1)/factors[i]+1);
1581 return ghostLevInPatchRef;
1585 * This method returns a sub set of \a all. The subset is defined by the \a head in the tree defined by \a this.
1586 * Elements in \a all are expected to be sorted from god father to most refined structure.
1588 std::vector<const DataArrayDouble *> MEDCouplingCartesianAMRMeshGen::extractSubTreeFromGlobalFlatten(const MEDCouplingCartesianAMRMeshGen *head, const std::vector<const DataArrayDouble *>& all) const
1590 int maxLev(getMaxNumberOfLevelsRelativeToThis());
1591 std::vector<const DataArrayDouble *> ret;
1592 std::vector<const MEDCouplingCartesianAMRMeshGen *> meshes(1,this);
1594 for(int i=0;i<maxLev;i++)
1596 std::vector<const MEDCouplingCartesianAMRMeshGen *> meshesTmp;
1597 for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it=meshes.begin();it!=meshes.end();it++)
1599 if((*it)==head || head->isObjectInTheProgeny(*it))
1600 ret.push_back(all[kk]);
1602 std::vector< const MEDCouplingCartesianAMRPatch *> ps((*it)->getPatches());
1603 for(std::vector< const MEDCouplingCartesianAMRPatch *>::const_iterator it0=ps.begin();it0!=ps.end();it0++)
1605 const MEDCouplingCartesianAMRMeshGen *mesh((*it0)->getMesh());
1606 meshesTmp.push_back(mesh);
1612 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::extractSubTreeFromGlobalFlatten : the size of input vector is not compatible with number of leaves in this !");
1616 void MEDCouplingCartesianAMRMeshGen::dumpPatchesOf(const std::string& varName, std::ostream& oss) const
1619 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1621 const MEDCouplingCartesianAMRPatch *patch(*it);
1624 std::ostringstream oss2; oss2 << varName << ".addPatch([";
1625 const std::vector< std::pair<int,int> >& bltr(patch->getBLTRRange());
1626 std::size_t sz(bltr.size());
1627 for(std::size_t i=0;i<sz;i++)
1629 oss2 << "(" << bltr[i].first << "," << bltr[i].second << ")";
1634 std::copy(_factors.begin(),_factors.end(),std::ostream_iterator<int>(oss2,","));
1637 std::ostringstream oss3; oss3 << varName << "[" << j++ << "]";
1638 patch->getMesh()->dumpPatchesOf(oss3.str(),oss);
1643 std::size_t MEDCouplingCartesianAMRMeshGen::getHeapMemorySizeWithoutChildren() const
1645 return sizeof(MEDCouplingCartesianAMRMeshGen);
1648 std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRMeshGen::getDirectChildren() const
1650 std::vector<const BigMemoryObject *> ret;
1651 if((const MEDCouplingIMesh *)_mesh)
1652 ret.push_back((const MEDCouplingIMesh *)_mesh);
1653 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1655 if((const MEDCouplingCartesianAMRPatch*)*it)
1656 ret.push_back((const MEDCouplingCartesianAMRPatch*)*it);
1661 void MEDCouplingCartesianAMRMeshGen::updateTime() const
1663 if((const MEDCouplingIMesh *)_mesh)
1664 updateTimeWith(*_mesh);
1665 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1667 const MEDCouplingCartesianAMRPatch *elt(*it);
1670 const MEDCouplingCartesianAMRMeshGen *mesh(elt->getMesh());
1672 updateTimeWith(*mesh);
1676 MEDCouplingCartesianAMRMeshSub::MEDCouplingCartesianAMRMeshSub(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh):MEDCouplingCartesianAMRMeshGen(mesh),_father(father)
1679 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh) constructor : empty father !");
1682 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshSub::getFather() const
1687 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshSub::getGodFather() const
1690 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getGodFather : Impossible to find a god father because there is a hole in chain !");
1691 return _father->getGodFather();
1695 * This method returns the level of \a this. 0 for god father. 1 for children of god father ...
1697 int MEDCouplingCartesianAMRMeshSub::getAbsoluteLevel() const
1700 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getAbsoluteLevel : Impossible to find a god father because there is a hole in chain !");
1701 return _father->getAbsoluteLevel()+1;
1704 void MEDCouplingCartesianAMRMeshSub::detachFromFather()
1710 int MEDCouplingCartesianAMRMeshSub::getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const
1715 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getAbsoluteLevelRelativeTo : ref is not in the progeny of this !");
1717 return _father->getAbsoluteLevelRelativeTo(ref)+1;
1720 MEDCouplingCartesianAMRMeshSub::MEDCouplingCartesianAMRMeshSub(const MEDCouplingCartesianAMRMeshSub& other, MEDCouplingCartesianAMRMeshGen *father):MEDCouplingCartesianAMRMeshGen(other),_father(father)
1724 MEDCouplingCartesianAMRMeshSub *MEDCouplingCartesianAMRMeshSub::deepCpy(MEDCouplingCartesianAMRMeshGen *fath) const
1726 return new MEDCouplingCartesianAMRMeshSub(*this,fath);
1730 * \sa getPositionRelativeTo
1732 void MEDCouplingCartesianAMRMeshSub::getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector<int>& ret) const
1737 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getPositionRelativeToInternal : ref is not in the progeny of this !");
1738 int myId(_father->getPatchIdFromChildMesh(this));
1739 ret.push_back(myId);
1740 _father->getPositionRelativeToInternal(ref,ret);
1743 MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
1744 const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop)
1746 return new MEDCouplingCartesianAMRMesh(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop);
1749 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMesh::getFather() const
1751 //I'm god father ! No father !
1755 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMesh::getGodFather() const
1760 int MEDCouplingCartesianAMRMesh::getAbsoluteLevel() const
1765 void MEDCouplingCartesianAMRMesh::detachFromFather()
1766 {//not a bug - do nothing
1769 int MEDCouplingCartesianAMRMesh::getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const
1773 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::getAbsoluteLevelRelativeTo : ref is not in the progeny of this !");
1776 std::vector<MEDCouplingCartesianAMRPatchGen *> MEDCouplingCartesianAMRMesh::retrieveGridsAt(int absoluteLev) const
1778 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > rets;
1779 retrieveGridsAtInternal(absoluteLev,rets);
1780 std::vector< MEDCouplingCartesianAMRPatchGen * > ret(rets.size());
1781 for(std::size_t i=0;i<rets.size();i++)
1783 ret[i]=rets[i].retn();
1788 MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::deepCpy(MEDCouplingCartesianAMRMeshGen *father) const
1791 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::deepCpy : specifying a not null father for a God Father object !");
1792 return new MEDCouplingCartesianAMRMesh(*this);
1796 * This method creates a multi level patches split at once.
1797 * This method calls as times as size of \a bso createPatchesFromCriterion. Size of \a bso and size of \a factors must be the same !
1798 * \b WARNING, after the call the number of levels in \a this is equal to bso.size() + 1 !
1801 * \param [in] criterion
1802 * \param [in] factors
1803 * \param [in] eps - See DataArrayDouble::toVectorOfBool for more information about the semantic of eps.
1805 * \sa createPatchesFromCriterion
1807 void MEDCouplingCartesianAMRMesh::createPatchesFromCriterionML(const std::vector<const INTERP_KERNEL::BoxSplittingOptions *>& bso, const DataArrayDouble *criterion, const std::vector< std::vector<int> >& factors, double eps)
1809 std::size_t nbOfLevs(bso.size());
1810 if(nbOfLevs!=factors.size())
1811 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterionML : size of vectors must be the same !");
1815 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterionML : pointers in 1st arg must be not NULL !");
1816 createPatchesFromCriterion(*bso[0],criterion,factors[0],eps);
1817 for(std::size_t i=1;i<nbOfLevs;i++)
1820 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterionML : presence of a NULL BoxSplittingOptions in input vector !");
1822 std::vector<MEDCouplingCartesianAMRPatchGen *> elts(retrieveGridsAt((int)(i)));
1823 std::size_t sz(elts.size());
1824 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > elts2(sz);
1825 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > elts3(sz);
1826 for(std::size_t ii=0;ii<sz;ii++)
1829 static const char TMP_STR[]="TMP";
1830 std::vector< std::pair<std::string,int> > fieldNames(1); fieldNames[0].first=TMP_STR; fieldNames[0].second=1;
1831 MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> att(MEDCouplingAMRAttribute::New(this,fieldNames,0));
1833 DataArrayDouble *tmpDa(const_cast<DataArrayDouble *>(att->getFieldOn(this,TMP_STR)));
1834 tmpDa->cpyFrom(*criterion);
1835 att->synchronizeCoarseToFine();
1836 for(std::size_t ii=0;ii<sz;ii++)
1838 const DataArrayDouble *critOnLeaf(att->getFieldOn(const_cast<MEDCouplingCartesianAMRMeshGen *>(elts[ii]->getMesh()),TMP_STR));
1839 elts3[ii]=const_cast<DataArrayDouble *>(critOnLeaf); elts3[ii]->incrRef();
1842 for(std::size_t ii=0;ii<sz;ii++)
1843 const_cast<MEDCouplingCartesianAMRMeshGen *>(elts[ii]->getMesh())->createPatchesFromCriterion(*bso[i],elts3[ii],factors[i],eps);
1847 void MEDCouplingCartesianAMRMesh::getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector<int>& ret) const
1852 MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(const MEDCouplingCartesianAMRMesh& other):MEDCouplingCartesianAMRMeshGen(other)
1856 MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
1857 const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop):MEDCouplingCartesianAMRMeshGen(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop)
1861 std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRMesh::getDirectChildren() const
1863 std::vector<const BigMemoryObject *> ret(MEDCouplingCartesianAMRMeshGen::getDirectChildren());
1867 MEDCouplingCartesianAMRMesh::~MEDCouplingCartesianAMRMesh()