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 "MEDCoupling1GTUMesh.hxx"
23 #include "MEDCouplingIMesh.hxx"
24 #include "MEDCouplingUMesh.hxx"
30 using namespace ParaMEDMEM;
34 int MEDCouplingCartesianAMRPatchGen::getNumberOfCellsRecursiveWithOverlap() const
36 return _mesh->getNumberOfCellsRecursiveWithOverlap();
39 int MEDCouplingCartesianAMRPatchGen::getNumberOfCellsRecursiveWithoutOverlap() const
41 return _mesh->getNumberOfCellsRecursiveWithoutOverlap();
44 int MEDCouplingCartesianAMRPatchGen::getMaxNumberOfLevelsRelativeToThis() const
46 return _mesh->getMaxNumberOfLevelsRelativeToThis();
49 MEDCouplingCartesianAMRPatchGen::MEDCouplingCartesianAMRPatchGen(MEDCouplingCartesianAMRMeshGen *mesh)
52 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen constructor : input mesh is NULL !");
53 _mesh=mesh; _mesh->incrRef();
56 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatchGen::getMeshSafe() const
58 const MEDCouplingCartesianAMRMeshGen *mesh(_mesh);
60 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen::getMeshSafe const : the mesh is NULL !");
64 MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatchGen::getMeshSafe()
66 MEDCouplingCartesianAMRMeshGen *mesh(_mesh);
68 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen::getMeshSafe : the mesh is NULL !");
72 std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRPatchGen::getDirectChildren() const
74 std::vector<const BigMemoryObject *> ret;
75 if((const MEDCouplingCartesianAMRMeshGen *)_mesh)
76 ret.push_back((const MEDCouplingCartesianAMRMeshGen *)_mesh);
81 * \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.
82 * \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,
83 * a the end cell (\b excluded) of the range for the second element of the pair.
85 MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMeshGen *mesh, const std::vector< std::pair<int,int> >& bottomLeftTopRight):MEDCouplingCartesianAMRPatchGen(mesh),_bl_tr(bottomLeftTopRight)
87 int dim((int)bottomLeftTopRight.size()),dimExp(_mesh->getSpaceDimension());
89 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch constructor : space dimension of father and input bottomLeft/topRight size mismatches !");
92 void MEDCouplingCartesianAMRPatch::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors)
94 return getMeshSafe()->addPatch(bottomLeftTopRight,factors);
97 int MEDCouplingCartesianAMRPatch::getNumberOfOverlapedCellsForFather() const
99 return MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(_bl_tr);
103 * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter
106 * \param [in] other - The other patch
107 * \param [in] ghostLev - The size of the neighborhood zone.
109 * \throw if \a this or \a other are invalid (end before start).
110 * \throw if \a ghostLev is \b not >= 0 .
111 * \throw if \a this and \a other have not the same space dimension.
113 bool MEDCouplingCartesianAMRPatch::isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const
116 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the size of the neighborhood must be >= 0 !");
118 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the input patch is NULL !");
119 const std::vector< std::pair<int,int> >& thisp(getBLTRRange());
120 const std::vector< std::pair<int,int> >& otherp(other->getBLTRRange());
121 std::size_t thispsize(thisp.size());
122 if(thispsize!=otherp.size())
123 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the dimensions must be the same !");
124 for(std::size_t i=0;i<thispsize;i++)
126 const std::pair<int,int>& thispp(thisp[i]);
127 const std::pair<int,int>& otherpp(otherp[i]);
128 if(thispp.second<thispp.first)
129 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : this patch is invalid !");
130 if(otherpp.second<otherpp.first)
131 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : this patch is invalid !");
132 if(otherpp.first==thispp.second+ghostLev-1)
134 if(otherpp.second+ghostLev-1==thispp.first)
136 int start(std::max(thispp.first,otherpp.first)),end(std::min(thispp.second,otherpp.second));
143 std::size_t MEDCouplingCartesianAMRPatch::getHeapMemorySizeWithoutChildren() const
145 std::size_t ret(sizeof(MEDCouplingCartesianAMRPatch));
146 ret+=_bl_tr.capacity()*sizeof(std::pair<int,int>);
150 MEDCouplingCartesianAMRPatchGF::MEDCouplingCartesianAMRPatchGF(MEDCouplingCartesianAMRMesh *mesh):MEDCouplingCartesianAMRPatchGen(mesh)
154 std::size_t MEDCouplingCartesianAMRPatchGF::getHeapMemorySizeWithoutChildren() const
156 return sizeof(MEDCouplingCartesianAMRPatchGF);
159 MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf)
162 throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !");
166 void MEDCouplingDataForGodFather::checkGodFatherFrozen() const
171 bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
173 bool ret(_tlc.keepTrackOfNewTL(gf));
183 int MEDCouplingCartesianAMRMeshGen::getSpaceDimension() const
185 return _mesh->getSpaceDimension();
188 void MEDCouplingCartesianAMRMeshGen::setFactors(const std::vector<int>& newFactors)
190 if(getSpaceDimension()!=(int)newFactors.size())
191 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::setFactors : size of input factors is not equal to the space dimension !");
197 if(_factors==newFactors)
199 if(!_patches.empty())
200 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::setFactors : modification of factors is not allowed when presence of patches !");
205 int MEDCouplingCartesianAMRMeshGen::getMaxNumberOfLevelsRelativeToThis() const
208 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
209 ret=std::max(ret,(*it)->getMaxNumberOfLevelsRelativeToThis()+1);
213 int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsAtCurrentLevel() const
215 return _mesh->getNumberOfCells();
218 int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithOverlap() const
220 int ret(_mesh->getNumberOfCells());
221 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
223 ret+=(*it)->getNumberOfCellsRecursiveWithOverlap();
228 int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithoutOverlap() const
230 int ret(_mesh->getNumberOfCells());
231 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
233 ret-=(*it)->getNumberOfOverlapedCellsForFather();
234 ret+=(*it)->getNumberOfCellsRecursiveWithoutOverlap();
239 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshGen::getFather() const
244 const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshGen::getGodFather() const
249 return _father->getGodFather();
253 * This method returns the level of \a this. 0 for god father. -1 for children of god father ...
255 int MEDCouplingCartesianAMRMeshGen::getAbsoluteLevel() const
260 return _father->getAbsoluteLevel()-1;
264 * This method returns grids relative to god father to specified level \a absoluteLev.
266 * \return std::vector<MEDCouplingCartesianAMRPatchGen *> - objects in vector are to be managed (decrRef) by the caller.
268 std::vector<MEDCouplingCartesianAMRPatchGen *> MEDCouplingCartesianAMRMeshGen::retrieveGridsAt(int absoluteLev) const
271 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::retrieveGridsAt : absolute level must be >=0 !");
273 return getGodFather()->retrieveGridsAt(absoluteLev);
275 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > rets;
276 retrieveGridsAtInternal(absoluteLev,rets);
277 std::vector< MEDCouplingCartesianAMRPatchGen * > ret(rets.size());
278 for(std::size_t i=0;i<rets.size();i++)
280 ret[i]=rets[i].retn();
285 void MEDCouplingCartesianAMRMeshGen::detachFromFather()
292 * \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,
293 * a the end cell (\b excluded) of the range for the second element of the pair.
294 * \param [in] factors The factor of refinement per axis (different from 0).
296 void MEDCouplingCartesianAMRMeshGen::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors)
298 checkFactorsAndIfNotSetAssign(factors);
299 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> mesh(static_cast<MEDCouplingIMesh *>(_mesh->buildStructuredSubPart(bottomLeftTopRight)));
300 mesh->refineWithFactor(factors);
301 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRMeshSub> zeMesh(new MEDCouplingCartesianAMRMeshSub(this,mesh));
302 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> elt(new MEDCouplingCartesianAMRPatch(zeMesh,bottomLeftTopRight));
303 _patches.push_back(elt);
309 class InternalPatch : public RefCountObjectOnly
312 InternalPatch():_nb_of_true(0) { }
313 int getDimension() const { return (int)_part.size(); }
314 double getEfficiency() const { return (double)_nb_of_true/(double)_crit.size(); }
315 int getNumberOfCells() const { return (int)_crit.size(); }
316 void setNumberOfTrue(int nboft) { _nb_of_true=nboft; }
317 std::vector<bool>& getCriterion() { return _crit; }
318 const std::vector<bool>& getConstCriterion() const { return _crit; }
319 void setPart(const std::vector< std::pair<int,int> >& part) { _part=part; }
320 std::vector< std::pair<int,int> >& getPart() { return _part; }
321 const std::vector< std::pair<int,int> >& getConstPart() const { return _part; }
322 bool presenceOfTrue() const { return _nb_of_true>0; }
323 std::vector<int> computeCGS() const { return MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(_part); }
324 std::vector< std::vector<int> > computeSignature() const { return MEDCouplingStructuredMesh::ComputeSignaturePerAxisOf(computeCGS(),getConstCriterion()); }
325 double getEfficiencyPerAxis(int axisId) const { return (double)_nb_of_true/((double)(_part[axisId].second-_part[axisId].first)); }
326 void zipToFitOnCriterion();
327 void updateNumberOfTrue() const;
328 MEDCouplingAutoRefCountObjectPtr<InternalPatch> extractPart(const std::vector< std::pair<int,int> >&partInGlobal) const;
329 MEDCouplingAutoRefCountObjectPtr<InternalPatch> deepCpy() const;
333 mutable int _nb_of_true;
334 std::vector<bool> _crit;
336 std::vector< std::pair<int,int> > _part;
339 void InternalPatch::zipToFitOnCriterion()
341 std::vector<int> cgs(computeCGS());
342 std::vector<bool> newCrit;
343 std::vector< std::pair<int,int> > newPart,newPart2;
344 int newNbOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(cgs,_crit,newCrit,newPart));
345 MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(_part,newPart,newPart2);
346 if(newNbOfTrue!=_nb_of_true)
347 throw INTERP_KERNEL::Exception("InternalPatch::zipToFitOnCrit : internal error !");
348 _crit=newCrit; _part=newPart2;
351 void InternalPatch::updateNumberOfTrue() const
353 _nb_of_true=(int)std::count(_crit.begin(),_crit.end(),true);
356 MEDCouplingAutoRefCountObjectPtr<InternalPatch> InternalPatch::extractPart(const std::vector< std::pair<int,int> >&partInGlobal) const
358 MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(new InternalPatch);
359 std::vector<int> cgs(computeCGS());
360 std::vector< std::pair<int,int> > newPart;
361 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(_part,partInGlobal,newPart);
362 MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom(cgs,_crit,newPart,ret->getCriterion());
363 ret->setPart(partInGlobal);
364 ret->updateNumberOfTrue();
368 MEDCouplingAutoRefCountObjectPtr<InternalPatch> InternalPatch::deepCpy() const
370 MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(new InternalPatch);
375 void DissectBigPatch(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int rangeOfAxisId, bool& cutFound, int& cutPlace)
377 cutFound=false; cutPlace=-1;
378 std::vector<double> ratio(rangeOfAxisId-1);
379 for(int id=0;id<rangeOfAxisId-1;id++)
381 double efficiency[2];
384 std::vector< std::pair<int,int> > rectH(patchToBeSplit->getConstPart());
386 rectH[axisId].second=patchToBeSplit->getConstPart()[axisId].first+id;
388 rectH[axisId].first=patchToBeSplit->getConstPart()[axisId].first+id;
389 MEDCouplingAutoRefCountObjectPtr<InternalPatch> p(patchToBeSplit->deepCpy());
390 p->zipToFitOnCriterion();
392 efficiency[h]=p->getEfficiencyPerAxis(axisId);
394 ratio[id]=std::max(efficiency[0],efficiency[1])/std::min(efficiency[0],efficiency[1]);
396 int minCellDirection(bso.getMinCellDirection()),indexMin(-1);
397 int dimRatioInner(rangeOfAxisId-1-2*(minCellDirection-1));
398 std::vector<double> ratio_inner(dimRatioInner);
399 double minRatio(1.e10);
400 for(int i=0; i<dimRatioInner; i++)
402 if(ratio[minCellDirection-1+i]<minRatio)
404 minRatio=ratio[minCellDirection-1+i];
405 indexMin=i+minCellDirection;
408 cutFound=true; cutPlace=indexMin+patchToBeSplit->getConstPart()[axisId].first-1;
411 void FindHole(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int& axisId, bool& cutFound, int& cutPlace)
413 cutPlace=-1; cutFound=false;
414 int minCellDirection(bso.getMinCellDirection());
415 const int dim(patchToBeSplit->getDimension());
416 std::vector< std::vector<int> > signatures(patchToBeSplit->computeSignature());
417 for(int id=0;id<dim;id++)
419 const std::vector<int>& signature(signatures[id]);
420 std::vector<int> hole;
421 std::vector<double> distance;
422 int len((int)signature.size());
423 for(int i=0;i<len;i++)
425 if(len>= 2*minCellDirection && i >= minCellDirection-1 && i <= len-minCellDirection-1)
429 double center(((double)len/2.));
430 for(std::size_t i=0;i<hole.size();i++)
431 distance.push_back(fabs(hole[i]+1.-center));
433 std::size_t posDistanceMin(std::distance(distance.begin(),std::min_element(distance.begin(),distance.end())));
436 cutPlace=hole[posDistanceMin]+patchToBeSplit->getConstPart()[axisId].first+1;
442 void FindInflection(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, bool& cutFound, int& cutPlace, int& axisId)
444 cutFound=false; cutPlace=-1;// do not set axisId before to be sure that cutFound was set to true
446 const std::vector< std::pair<int,int> >& part(patchToBeSplit->getConstPart());
447 int sign,minCellDirection(bso.getMinCellDirection());
448 const int dim(patchToBeSplit->getDimension());
450 std::vector<int> zeroCrossDims(dim,-1);
451 std::vector<int> zeroCrossVals(dim,-1);
452 std::vector< std::vector<int> > signatures(patchToBeSplit->computeSignature());
453 for (int id=0;id<dim;id++)
455 const std::vector<int>& signature(signatures[id]);
457 std::vector<int> derivate_second_order,gradient_absolute,signe_change,zero_cross,edge,max_cross_list ;
458 std::vector<double> distance ;
460 for (unsigned int i=1;i<signature.size()-1;i++)
461 derivate_second_order.push_back(signature[i-1]-2*signature[i]+signature[i+1]) ;
463 // Gradient absolute value
464 for ( unsigned int i=1;i<derivate_second_order.size();i++)
465 gradient_absolute.push_back(fabs(derivate_second_order[i]-derivate_second_order[i-1])) ;
466 if(derivate_second_order.empty())
468 for (unsigned int i=0;i<derivate_second_order.size()-1;i++)
470 if (derivate_second_order[i]*derivate_second_order[i+1] < 0 )
472 if (derivate_second_order[i]*derivate_second_order[i+1] > 0 )
474 if (derivate_second_order[i]*derivate_second_order[i+1] == 0 )
476 if ( sign==0 || sign==-1 )
477 if ( i >= (unsigned int)minCellDirection-2 && i <= signature.size()-minCellDirection-2 )
479 zero_cross.push_back(i) ;
480 edge.push_back(gradient_absolute[i]) ;
482 signe_change.push_back(sign) ;
484 if ( zero_cross.size() > 0 )
486 int max_cross=*max_element(edge.begin(),edge.end()) ;
487 for (unsigned int i=0;i<edge.size();i++)
488 if (edge[i]==max_cross)
489 max_cross_list.push_back(zero_cross[i]+1) ;
491 double center((signature.size()/2.0));
492 for (unsigned int i=0;i<max_cross_list.size();i++)
493 distance.push_back(fabs(max_cross_list[i]+1-center));
495 float distance_min=*min_element(distance.begin(),distance.end()) ;
496 int pos_distance_min=find(distance.begin(),distance.end(),distance_min)-distance.begin();
497 int best_place = max_cross_list[pos_distance_min] + part[id].first ;
500 zeroCrossDims[id] = best_place ;
501 zeroCrossVals[id] = max_cross ;
504 derivate_second_order.clear() ;
505 gradient_absolute.clear() ;
506 signe_change.clear() ;
509 max_cross_list.clear() ;
513 if ( zeroCrossDims[0]!=-1 || zeroCrossDims[1]!=-1 )
515 int max_cross_dims = *max_element(zeroCrossVals.begin(),zeroCrossVals.end()) ;
517 if (zeroCrossVals[0]==max_cross_dims && zeroCrossVals[1]==max_cross_dims )
519 int nl_left(part[0].second-part[0].first);
520 int nc_left(part[1].second-part[1].first);
521 if ( nl_left >= nc_left )
527 max_cross_dims=std::find(zeroCrossVals.begin(),zeroCrossVals.end(),max_cross_dims)-zeroCrossVals.begin();
529 cutPlace=zeroCrossDims[max_cross_dims];
530 axisId=max_cross_dims ;
534 void TryAction4(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int rangeOfAxisId, bool& cutFound, int& cutPlace)
537 if(patchToBeSplit->getEfficiency()<=bso.getEffeciencySnd())
539 if(rangeOfAxisId>=2*bso.getMinCellDirection())
542 cutPlace=rangeOfAxisId/2+patchToBeSplit->getConstPart()[axisId].first-1;
547 if(patchToBeSplit->getNumberOfCells()>bso.getMaxCells())
549 DissectBigPatch(bso,patchToBeSplit,axisId,rangeOfAxisId,cutFound,cutPlace);
554 MEDCouplingAutoRefCountObjectPtr<InternalPatch> DealWithNoCut(const InternalPatch *patch)
556 MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(const_cast<InternalPatch *>(patch));
561 void DealWithCut(const InternalPatch *patchToBeSplit, int axisId, int cutPlace, std::vector<MEDCouplingAutoRefCountObjectPtr<InternalPatch> >& listOfPatches)
563 MEDCouplingAutoRefCountObjectPtr<InternalPatch> leftPart,rightPart;
564 std::vector< std::pair<int,int> > rect(patchToBeSplit->getConstPart());
565 std::vector< std::pair<int,int> > leftRect(rect),rightRect(rect);
566 leftRect[axisId].second=cutPlace+1;
567 rightRect[axisId].first=cutPlace+1;
568 leftPart=patchToBeSplit->extractPart(leftRect);
569 rightPart=patchToBeSplit->extractPart(rightRect);
570 leftPart->zipToFitOnCriterion(); rightPart->zipToFitOnCriterion();
571 listOfPatches.push_back(leftPart);
572 listOfPatches.push_back(rightPart);
578 * 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.
580 void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const std::vector<bool>& criterion, const std::vector<int>& factors)
582 int nbCells(getNumberOfCellsAtCurrentLevel());
583 if(nbCells!=(int)criterion.size())
584 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 !");
586 std::vector<int> cgs(_mesh->getCellGridStructure());
587 std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> > listOfPatches,listOfPatchesOK;
589 MEDCouplingAutoRefCountObjectPtr<InternalPatch> p(new InternalPatch);
590 p->setNumberOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(cgs,criterion,p->getCriterion(),p->getPart()));
591 if(p->presenceOfTrue())
592 listOfPatches.push_back(p);
593 while(!listOfPatches.empty())
595 std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> > listOfPatchesTmp;
596 for(std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> >::iterator it=listOfPatches.begin();it!=listOfPatches.end();it++)
599 int axisId,rangeOfAxisId,cutPlace;
601 MEDCouplingStructuredMesh::FindTheWidestAxisOfGivenRangeInCompactFrmt((*it)->getConstPart(),axisId,rangeOfAxisId);
602 if((*it)->getEfficiency()>=bso.getEffeciency() && (*it)->getNumberOfCells()<bso.getMaxCells())
603 { listOfPatchesOK.push_back(DealWithNoCut(*it)); continue; }//action 1
604 FindHole(bso,*it,axisId,cutFound,cutPlace);//axisId overwritten here if FindHole equal to true !
606 { DealWithCut(*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 2
607 FindInflection(bso,*it,cutFound,cutPlace,axisId);//axisId overwritten here if cutFound equal to true !
609 { DealWithCut(*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 3
610 TryAction4(bso,*it,axisId,rangeOfAxisId,cutFound,cutPlace);
612 { DealWithCut(*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 4
613 listOfPatchesOK.push_back(DealWithNoCut(*it));
615 listOfPatches=listOfPatchesTmp;
617 for(std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> >::const_iterator it=listOfPatchesOK.begin();it!=listOfPatchesOK.end();it++)
618 addPatch((*it)->getConstPart(),factors);
623 * 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.
625 void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector<int>& factors)
627 if(!criterion || !criterion->isAllocated())
628 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterion : the criterion DataArrayByte instance must be allocated and not NULL !");
629 std::vector<bool> crit(criterion->toVectorOfBool());//check that criterion has one component.
630 createPatchesFromCriterion(bso,crit,factors);
634 void MEDCouplingCartesianAMRMeshGen::removeAllPatches()
640 void MEDCouplingCartesianAMRMeshGen::removePatch(int patchId)
642 checkPatchId(patchId);
643 int sz((int)_patches.size()),j(0);
644 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> > patches(sz-1);
645 for(int i=0;i<sz;i++)
647 patches[j++]=_patches[i];
648 (const_cast<MEDCouplingCartesianAMRMeshGen *>(_patches[patchId]->getMesh()))->detachFromFather();
653 int MEDCouplingCartesianAMRMeshGen::getNumberOfPatches() const
655 return (int)_patches.size();
658 const MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRMeshGen::getPatch(int patchId) const
660 checkPatchId(patchId);
661 return _patches[patchId];
665 * This method states if patch2 (with id \a patchId2) is in the neighborhood of patch1 (with id \a patchId1).
666 * The neighborhood size is defined by \a ghostLev in the reference of \a this ( \b not in the reference of patches !).
668 bool MEDCouplingCartesianAMRMeshGen::isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const
671 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::isPatchInNeighborhoodOf : the ghost size must be >=0 !");
672 const MEDCouplingCartesianAMRPatch *p1(getPatch(patchId1)),*p2(getPatch(patchId2));
674 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::isPatchInNeighborhoodOf : no factors defined !");
675 int ghostLevInPatchRef;
677 ghostLevInPatchRef=0;
680 ghostLevInPatchRef=(ghostLev-1)/_factors[0]+1;
681 for(std::size_t i=0;i<_factors.size();i++)
682 ghostLevInPatchRef=std::max(ghostLevInPatchRef,(ghostLev-1)/_factors[i]+1);
684 return p1->isInMyNeighborhood(p2,ghostLevInPatchRef);
688 * 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.
689 * 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
690 * defined by the patch with id \a patchId.
692 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
693 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
694 * \return DataArrayDouble * - The array of the cell field on the requested patch
696 * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() )
697 * \throw if \a cellFieldOnThis is NULL or not allocated
698 * \sa fillCellFieldOnPatch, MEDCouplingIMesh::SpreadCoarseToFine
700 DataArrayDouble *MEDCouplingCartesianAMRMeshGen::createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const
702 if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
703 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !");
704 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
705 const MEDCouplingIMesh *fine(patch->getMesh()->getImageMesh());
706 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(fine->getNumberOfCells(),cellFieldOnThis->getNumberOfComponents());
707 ret->copyStringInfoFrom(*cellFieldOnThis);
708 MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),ret,patch->getBLTRRange(),getFactors());
713 * This method is equivalent to MEDCouplingCartesianAMRMesh::createCellFieldOnPatch except that here instead of creating a new instance
714 * it fills the value into the \a cellFieldOnPatch data.
716 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
717 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
718 * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled.
720 * \sa createCellFieldOnPatch, fillCellFieldComingFromPatch
722 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch) const
724 if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
725 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !");
726 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
727 MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors());
731 * This method is the generalization of fillCellFieldOnPatch method. This method only projects coarse to fine without considering the
732 * potential neighbor patches covered by the ghost cells of patch with id \a patchId.
734 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
735 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
736 * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled.
737 * \param [in] ghostLev - The size of the ghost zone (must be >=0 !)
739 * \sa fillCellFieldOnPatch, fillCellFieldOnPatchGhostAdv
741 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const
743 if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
744 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatchGhost : the input cell field array is NULL or not allocated !");
745 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
746 MEDCouplingIMesh::SpreadCoarseToFineGhost(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev);
750 * This method is a refinement of fillCellFieldOnPatchGhost. fillCellFieldOnPatchGhost is first called.
751 * Then for all other patches than those pointed by \a patchId that overlap the ghost zone of the patch impact the ghost zone adequately.
753 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
754 * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
755 * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled.
756 * \param [in] ghostLev - The size of the ghost zone (must be >=0 !)
757 * \param [in] arrsOnPatches - \b WARNING arrsOnPatches[patchId] is \b NOT \b const. All others are const.
759 * \sa fillCellFieldOnPatchOnlyGhostAdv
761 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const
763 int nbp(getNumberOfPatches());
764 if(nbp!=(int)arrsOnPatches.size())
766 std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !";
767 throw INTERP_KERNEL::Exception(oss.str().c_str());
769 DataArrayDouble *theFieldToFill(const_cast<DataArrayDouble *>(arrsOnPatches[patchId]));
770 // first, do as usual
771 fillCellFieldOnPatchGhost(patchId,cellFieldOnThis,theFieldToFill,ghostLev);
772 fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrsOnPatches);
775 void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const
777 int nbp(getNumberOfPatches()),dim(getSpaceDimension());
778 if(nbp!=(int)arrsOnPatches.size())
780 std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !";
781 throw INTERP_KERNEL::Exception(oss.str().c_str());
783 DataArrayDouble *theFieldToFill(const_cast<DataArrayDouble *>(arrsOnPatches[patchId]));
784 const MEDCouplingCartesianAMRPatch *refP(getPatch(patchId));
785 const std::vector< std::pair<int,int> >& refBLTR(refP->getBLTRRange());//[(1,4),(2,4)]
786 std::vector<int> dimsCoarse(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(refBLTR));//[3,2]
787 std::transform(dimsCoarse.begin(),dimsCoarse.end(),_factors.begin(),dimsCoarse.begin(),std::multiplies<int>());//[12,8]
788 std::transform(dimsCoarse.begin(),dimsCoarse.end(),dimsCoarse.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));//[14,10]
789 std::vector< std::pair<int,int> > rangeCoarse(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsCoarse));//[(0,14),(0,10)]
790 std::vector<int> fakeFactors(dim,1);
792 for(int i=0;i<nbp;i++)
795 if(isPatchInNeighborhoodOf(i,patchId,ghostLev))
797 const MEDCouplingCartesianAMRPatch *otherP(getPatch(i));
798 const std::vector< std::pair<int,int> >& otherBLTR(otherP->getBLTRRange());//[(4,5),(3,4)]
799 std::vector< std::pair<int,int> > tmp0,tmp1,tmp2;
800 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(refBLTR,otherBLTR,tmp0,false);//tmp0=[(3,4),(1,2)]
801 ApplyFactorsOnCompactFrmt(tmp0,_factors);//tmp0=[(12,16),(4,8)]
802 ApplyGhostOnCompactFrmt(tmp0,ghostLev);//tmp0=[(13,17),(5,9)]
803 std::vector< std::pair<int,int> > interstRange(MEDCouplingStructuredMesh::IntersectRanges(tmp0,rangeCoarse));//interstRange=[(13,14),(5,9)]
804 MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(otherBLTR,refBLTR,tmp1,false);//tmp1=[(-3,0),(-1,1)]
805 ApplyFactorsOnCompactFrmt(tmp1,_factors);//tmp1=[(-12,-4),(-4,0)]
806 MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(tmp1,interstRange,tmp2,false);//tmp2=[(1,2),(1,5)]
808 std::vector< std::pair<int,int> > dimsFine(otherBLTR);
809 ApplyFactorsOnCompactFrmt(dimsFine,_factors);
810 ApplyAllGhostOnCompactFrmt(dimsFine,ghostLev);
812 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ghostVals(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(dimsFine),arrsOnPatches[i],tmp2));
813 MEDCouplingIMesh::CondenseFineToCoarse(dimsCoarse,ghostVals,interstRange,fakeFactors,theFieldToFill);
819 * This method updates \a cellFieldOnThis part of values coming from the cell field \a cellFieldOnPatch lying on patch having id \a patchId.
821 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
822 * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId.
823 * \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.
825 * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() )
826 * \throw if \a cellFieldOnPatch is NULL or not allocated
827 * \sa createCellFieldOnPatch, MEDCouplingIMesh::CondenseFineToCoarse,fillCellFieldComingFromPatchGhost
829 void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const
831 if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated())
832 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch : the input cell field array is NULL or not allocated !");
833 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
834 MEDCouplingIMesh::CondenseFineToCoarse(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis);
838 * This method is the extension of MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch managing the ghost cells. If this
839 * method is called with \a ghostLev equal to 0 it behaves exactly as MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch.
841 * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
842 * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId.
843 * \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.
844 * \param [in] ghostLev The size of ghost zone (must be >= 0 !)
846 * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() )
847 * \throw if \a cellFieldOnPatch is NULL or not allocated
848 * \sa fillCellFieldComingFromPatch
850 void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev) const
852 if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated())
853 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatchGhost : the input cell field array is NULL or not allocated !");
854 const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
855 MEDCouplingIMesh::CondenseFineToCoarseGhost(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis,ghostLev);
859 * This method finds all patches (located by their ids) that are in the neighborhood of patch with id \a patchId. The neighborhood size is
860 * defined by ghostLev.
862 * \param [in] patchId - the id of the considered patch.
863 * \param [in] ghostLev - the size of the neighborhood.
864 * \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.
866 DataArrayInt *MEDCouplingCartesianAMRMeshGen::findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const
868 int nbp(getNumberOfPatches());
869 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
870 for(int i=0;i<nbp;i++)
873 if(isPatchInNeighborhoodOf(i,patchId,ghostLev))
874 ret->pushBackSilent(i);
879 MEDCouplingUMesh *MEDCouplingCartesianAMRMeshGen::buildUnstructured() const
881 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> part(_mesh->buildUnstructured());
882 std::vector<bool> bs(_mesh->getNumberOfCells(),false);
883 std::vector<int> cgs(_mesh->getCellGridStructure());
884 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > msSafe(_patches.size()+1);
886 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++,ii++)
888 MEDCouplingStructuredMesh::SwitchOnIdsFrom(cgs,(*it)->getBLTRRange(),bs);
889 msSafe[ii+1]=(*it)->getMesh()->buildUnstructured();
891 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsOff(DataArrayInt::BuildListOfSwitchedOff(bs));
892 msSafe[0]=static_cast<MEDCouplingUMesh *>(part->buildPartOfMySelf(eltsOff->begin(),eltsOff->end(),false));
893 std::vector< const MEDCouplingUMesh * > ms(msSafe.size());
894 for(std::size_t i=0;i<msSafe.size();i++)
896 return MEDCouplingUMesh::MergeUMeshes(ms);
900 * This method returns a mesh containing as cells that there is patches at the current level.
901 * The patches are seen like 'boxes' that is too say the refinement will not appear here.
903 * \return MEDCoupling1SGTUMesh * - A new object to be managed by the caller containing as cells as there are patches in \a this.
905 MEDCoupling1SGTUMesh *MEDCouplingCartesianAMRMeshGen::buildMeshFromPatchEnvelop() const
907 std::vector<const MEDCoupling1SGTUMesh *> cells;
908 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > cellsSafe;
909 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
911 const MEDCouplingCartesianAMRPatch *patch(*it);
914 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> cell(patch->getMesh()->getImageMesh()->asSingleCell());
915 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> cell1SGT(cell->build1SGTUnstructured());
916 cellsSafe.push_back(cell1SGT); cells.push_back(cell1SGT);
919 return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(cells);
922 MEDCoupling1SGTUMesh *MEDCouplingCartesianAMRMeshGen::buildMeshOfDirectChildrenOnly() const
924 std::vector<const MEDCoupling1SGTUMesh *> patches;
925 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > patchesSafe;
926 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
928 const MEDCouplingCartesianAMRPatch *patch(*it);
931 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> patchMesh(patch->getMesh()->getImageMesh()->build1SGTUnstructured());
932 patchesSafe.push_back(patchMesh); patches.push_back(patchMesh);
935 return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(patches);
938 MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
939 const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop):_father(0)
941 _mesh=MEDCouplingIMesh::New(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop);
944 MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh):_father(father)
947 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh) constructor : empty father !");
949 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh) constructor : The input mesh is null !");
950 mesh->checkCoherency();
951 _mesh=mesh; _mesh->incrRef();
954 void MEDCouplingCartesianAMRMeshGen::checkPatchId(int patchId) const
956 int sz(getNumberOfPatches());
957 if(patchId<0 || patchId>=sz)
959 std::ostringstream oss; oss << "MEDCouplingCartesianAMRMeshGen::checkPatchId : invalid patchId (" << patchId << ") ! Must be in [0," << sz << ") !";
960 throw INTERP_KERNEL::Exception(oss.str().c_str());
964 void MEDCouplingCartesianAMRMeshGen::checkFactorsAndIfNotSetAssign(const std::vector<int>& factors)
966 if(getSpaceDimension()!=(int)factors.size())
967 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::checkFactorsAndIfNotSetAssign : invalid size of factors ! size must be equal to the spaceDimension !");
974 if(_factors!=factors)
975 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::checkFactorsAndIfNotSetAssign : the factors ");
979 void MEDCouplingCartesianAMRMeshGen::retrieveGridsAtInternal(int lev, std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> >& grids) const
983 const MEDCouplingCartesianAMRMesh *thisc(dynamic_cast<const MEDCouplingCartesianAMRMesh *>(this));//tony
984 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGF> elt(new MEDCouplingCartesianAMRPatchGF(const_cast<MEDCouplingCartesianAMRMesh *>(thisc)));
985 grids.push_back(DynamicCastSafe<MEDCouplingCartesianAMRPatchGF,MEDCouplingCartesianAMRPatchGen>(elt));
989 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
991 const MEDCouplingCartesianAMRPatch *pt(*it);
994 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> tmp1(*it);
995 grids.push_back(DynamicCastSafe<MEDCouplingCartesianAMRPatch,MEDCouplingCartesianAMRPatchGen>(tmp1));
1001 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1003 const MEDCouplingCartesianAMRPatch *pt(*it);
1005 pt->getMesh()->retrieveGridsAtInternal(lev-1,grids);
1011 * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in refined reference.
1012 * \param [in] factors - the factors per axis.
1014 void MEDCouplingCartesianAMRMeshGen::ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors)
1016 std::size_t sz(factors.size());
1017 if(sz!=partBeforeFact.size())
1018 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::ApplyFactorsOnCompactFrmt : size of input vectors must be the same !");
1019 for(std::size_t i=0;i<sz;i++)
1021 partBeforeFact[i].first*=factors[i];
1022 partBeforeFact[i].second*=factors[i];
1027 * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
1028 * \param [in] ghostSize - the ghost size of zone for all axis.
1030 void MEDCouplingCartesianAMRMeshGen::ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize)
1033 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::ApplyGhostOnCompactFrmt : ghost size must be >= 0 !");
1034 std::size_t sz(partBeforeFact.size());
1035 for(std::size_t i=0;i<sz;i++)
1037 partBeforeFact[i].first+=ghostSize;
1038 partBeforeFact[i].second+=ghostSize;
1043 * This method is different than ApplyGhostOnCompactFrmt
1045 * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
1046 * \param [in] ghostSize - the ghost size of zone for all axis.
1048 void MEDCouplingCartesianAMRMeshGen::ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize)
1051 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::ApplyAllGhostOnCompactFrmt : ghost size must be >= 0 !");
1052 std::size_t sz(partBeforeFact.size());
1053 for(std::size_t i=0;i<sz;i++)
1055 partBeforeFact[i].first-=ghostSize;
1056 partBeforeFact[i].second+=ghostSize;
1060 std::size_t MEDCouplingCartesianAMRMeshGen::getHeapMemorySizeWithoutChildren() const
1062 return sizeof(MEDCouplingCartesianAMRMeshGen);
1065 std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRMeshGen::getDirectChildren() const
1067 std::vector<const BigMemoryObject *> ret;
1068 if((const MEDCouplingIMesh *)_mesh)
1069 ret.push_back((const MEDCouplingIMesh *)_mesh);
1070 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1072 if((const MEDCouplingCartesianAMRPatch*)*it)
1073 ret.push_back((const MEDCouplingCartesianAMRPatch*)*it);
1078 void MEDCouplingCartesianAMRMeshGen::updateTime() const
1080 if((const MEDCouplingIMesh *)_mesh)
1081 updateTimeWith(*_mesh);
1082 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
1084 const MEDCouplingCartesianAMRPatch *elt(*it);
1087 const MEDCouplingCartesianAMRMeshGen *mesh(elt->getMesh());
1089 updateTimeWith(*mesh);
1093 MEDCouplingCartesianAMRMeshSub::MEDCouplingCartesianAMRMeshSub(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh):MEDCouplingCartesianAMRMeshGen(father,mesh)
1097 MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
1098 const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop)
1100 return new MEDCouplingCartesianAMRMesh(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop);
1103 void MEDCouplingCartesianAMRMesh::setData(MEDCouplingDataForGodFather *data)
1105 MEDCouplingDataForGodFather *myData(_data);
1109 myData->changeGodFather(0);
1115 void MEDCouplingCartesianAMRMesh::allocData() const
1121 void MEDCouplingCartesianAMRMesh::deallocData() const
1127 MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
1128 const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop):MEDCouplingCartesianAMRMeshGen(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop)
1132 std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRMesh::getDirectChildren() const
1134 std::vector<const BigMemoryObject *> ret(MEDCouplingCartesianAMRMeshGen::getDirectChildren());
1135 const MEDCouplingDataForGodFather *pt(_data);
1141 void MEDCouplingCartesianAMRMesh::checkData() const
1143 const MEDCouplingDataForGodFather *data(_data);
1145 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::checkData : no data set !");
1148 MEDCouplingCartesianAMRMesh::~MEDCouplingCartesianAMRMesh()
1150 MEDCouplingDataForGodFather *data(_data);
1152 data->changeGodFather(0);