--- /dev/null
+// Copyright (C) 2007-2014 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay
+
+#include "BoxSplittingOptions.hxx"
+
+#include <sstream>
+
+const double INTERP_KERNEL::BoxSplittingOptions::DFT_EFFECIENCY=0.5;
+
+const double INTERP_KERNEL::BoxSplittingOptions::DFT_EFFECIENCY_SND=0.5;
+
+void INTERP_KERNEL::BoxSplittingOptions::init()
+{
+ _effeciency=DFT_EFFECIENCY;
+ _effeciency_snd=DFT_EFFECIENCY_SND;
+ _min_cell_direction=DFT_MIN_CELL_DIRECTION;
+ _max_cells=DFT_MAX_CELLS;
+}
+
+std::string INTERP_KERNEL::BoxSplittingOptions::printOptions() const
+{
+ std::ostringstream oss;
+ oss << "Efficiency threshold: " << 100*_effeciency << "%"<< std::endl;
+ oss << "Efficiency Snd threshold: " << 100*_effeciency_snd << "%"<< std::endl;
+ oss << "Min. box side length: " << _min_cell_direction << std::endl;
+ oss << "Max. box cells : " << _max_cells << std::endl;
+ return oss.str();
+}
--- /dev/null
+// Copyright (C) 2007-2014 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay
+
+#ifndef __BOXSPLITTINGOPTIONS_HXX__
+#define __BOXSPLITTINGOPTIONS_HXX__
+
+#include "INTERPKERNELDefines.hxx"
+#include "NormalizedUnstructuredMesh.hxx"
+
+#include <string>
+
+namespace INTERP_KERNEL
+{
+ /*!
+ * \class BoxSplittingOptions
+ * Class defining the options for box splitting used for AMR algorithm like creation of patches following a criterion.
+ */
+ class INTERPKERNEL_EXPORT BoxSplittingOptions
+ {
+ private:
+ double _effeciency;
+ double _effeciency_snd;
+ int _min_cell_direction;
+ int _max_cells;
+ public:
+ BoxSplittingOptions() { init(); }
+ void init();
+ double getEffeciency() const { return _effeciency; }
+ void setEffeciency(double effeciency) { _effeciency=effeciency; }
+ double getEffeciencySnd() const { return _effeciency_snd; }
+ void setEffeciencySnd(double effeciencySnd) { _effeciency_snd=effeciencySnd; }
+ int getMinCellDirection() const { return _min_cell_direction; }
+ void setMinCellDirection(int minCellDirection) { _min_cell_direction=minCellDirection; }
+ int getMaxCells() const { return _max_cells; }
+ void setMaxCells(int maxCells) { _max_cells=maxCells; }
+ void copyOptions(const BoxSplittingOptions & other) { *this=other; }
+ std::string printOptions() const;
+ private:
+ static const int DFT_MIN_CELL_DIRECTION=3;
+ static const int DFT_MAX_CELLS=1000;
+ static const double DFT_EFFECIENCY;
+ static const double DFT_EFFECIENCY_SND;
+ public:
+ static const char PRECISION_STR[];
+ };
+}
+
+#endif
CellModel.cxx
UnitTetraIntersectionBary.cxx
InterpolationOptions.cxx
+ BoxSplittingOptions.cxx
DirectedBoundingBox.cxx
Interpolation2DCurve.cxx
Interpolation3DSurf.cxx
* \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.
* \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,
* a the end cell (\b excluded) of the range for the second element of the pair.
+ * \param [in] factors The refinement per axis relative to the father of \a this.
*/
-MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMesh *mesh, const std::vector< std::pair<int,int> >& bottomLeftTopRight)
+MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMesh *mesh, const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors)
{
if(!mesh)
throw INTERP_KERNEL::Exception("EDCouplingCartesianAMRPatch constructor : input mesh is NULL !");
_mesh=mesh; _mesh->incrRef();
- int dim((int)bottomLeftTopRight.size());
- if(dim!=_mesh->getSpaceDimension())
+ int dim((int)bottomLeftTopRight.size()),dimExp(_mesh->getSpaceDimension());
+ if(dim!=dimExp)
throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch constructor : space dimension of father and input bottomLeft/topRight size mismatches !");
_bl_tr=bottomLeftTopRight;
+ if((int)factors.size()!=dimExp)
+ throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch constructor : space dimension of father and input factors per axis size mismatches !");
+ _factors=factors;
}
int MEDCouplingCartesianAMRPatch::getNumberOfCellsRecursiveWithOverlap() const
return _mesh->getMaxNumberOfLevelsRelativeToThis();
}
-void MEDCouplingCartesianAMRPatch::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, int factor)
+void MEDCouplingCartesianAMRPatch::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors)
{
- return _mesh->addPatch(bottomLeftTopRight,factor);
+ return _mesh->addPatch(bottomLeftTopRight,factors);
}
int MEDCouplingCartesianAMRPatch::getNumberOfOverlapedCellsForFather() const
/*!
* \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,
* a the end cell (\b excluded) of the range for the second element of the pair.
- * \param [in] factor The != 0 factor of refinement.
+ * \param [in] factors The != 0 factor of refinement per axis.
*/
-void MEDCouplingCartesianAMRMesh::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, int factor)
+void MEDCouplingCartesianAMRMesh::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors)
{
MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> mesh(static_cast<MEDCouplingIMesh *>(_mesh->buildStructuredSubPart(bottomLeftTopRight)));
- mesh->refineWithFactor(factor);
+ mesh->refineWithFactor(factors);
MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRMesh> zeMesh(new MEDCouplingCartesianAMRMesh(this,mesh));
- MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> elt(new MEDCouplingCartesianAMRPatch(zeMesh,bottomLeftTopRight));
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> elt(new MEDCouplingCartesianAMRPatch(zeMesh,bottomLeftTopRight,factors));
_patches.push_back(elt);
}
+/// @cond INTERNAL
+
+class InternalPatch : public RefCountObjectOnly
+{
+public:
+ InternalPatch():_nb_of_true(0) { }
+ double getEfficiency() const { return (double)_nb_of_true/(double)_crit.size(); }
+ int getNumberOfCells() const { return (int)_crit.size(); }
+ void setNumberOfTrue(int nboft) { _nb_of_true=nboft; }
+ std::vector<bool>& getCriterion() { return _crit; }
+ std::vector< std::pair<int,int> >& getPart() { return _part; }
+ const std::vector< std::pair<int,int> >& getConstPart() const { return _part; }
+ bool presenceOfTrue() const { return _nb_of_true>0; }
+protected:
+ ~InternalPatch() { }
+private:
+ int _nb_of_true;
+ std::vector<bool> _crit;
+ std::vector< std::pair<int,int> > _part;
+};
+
+#if 0
+void dissectBigPatch (const Mesh& mesh, const Field& fieldFlag, const unsigned int minCellDirection,
+ const unsigned int big_dims, const int dissect_direction, int cut[3] ) const
+{
+ int cut_found = 0 ;
+ int cut_place = -1 ;
+ float * ratio = NULL ;
+ float * ratio_inner = NULL ;
+
+ ratio = new float [big_dims-1];
+ for(unsigned int id=0; id<big_dims-1; id++)
+ {
+ float efficiency[2] ;
+ for(int h=0; h<2; h++)
+ {
+ int rect_h[4] ;
+ copy(getIndexCorners(),getIndexCorners()+4,rect_h) ;
+ if (h == 0 )
+ rect_h[dissect_direction+2] = _indexCorners[dissect_direction]+id ;
+ else if ( h == 1)
+ rect_h[dissect_direction] = _indexCorners[dissect_direction]+id+1;
+
+ Patch patch_h(rect_h);
+ patch_h.computeMesh(mesh);
+ patch_h.computeFieldFlag(fieldFlag);
+
+ int nb_cells_h ;
+ if ( dissect_direction == 0 )
+ nb_cells_h = patch_h.getNx() ;
+ else
+ nb_cells_h = patch_h.getNy() ;
+
+ int nb_cells_flag_h = patch_h.getNumberOfCellsFlags();
+ efficiency[h] = float (nb_cells_flag_h) / float(nb_cells_h) ;
+ }
+ ratio[id] = max(efficiency[0],efficiency[1])/
+ min(efficiency[0],efficiency[1]) ;
+ }
+
+ int dim_ratio_inner = big_dims-1-2*(minCellDirection-1) ;
+ ratio_inner = new float [dim_ratio_inner];
+ float min_ratio = 1.E10 ;
+ int index_min = -1 ;
+ for(int i=0; i<dim_ratio_inner; i++)
+ {
+ if ( ratio[minCellDirection-1+i] < min_ratio )
+ {
+ min_ratio = ratio[minCellDirection-1+i] ;
+ index_min = i+minCellDirection ;
+ }
+ }
+ cut_found = 1 ;
+ cut_place = index_min + _indexCorners[dissect_direction] - 1 ;
+ cut[0] = cut_found ;
+ cut[1] = cut_place ;
+ cut[2] = dissect_direction ;
+ delete [] ratio ;
+ delete [] ratio_inner ;
+}
+#endif
+/// @endcond
+
+/*!
+ * This method creates patches in \a this (by destroying the patches if any). This method uses \a criterion
+ */
+void MEDCouplingCartesianAMRMesh::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector<int>& factors)
+{
+ if(!criterion || !criterion->isAllocated())
+ throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterion : the criterion DataArrayByte instance must be allocated and not NULL !");
+ int nbCells(getNumberOfCellsAtCurrentLevel());
+ if(nbCells!=criterion->getNumberOfTuples())
+ 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 !");
+ _patches.clear();
+ //
+ std::vector<int> cgs(_mesh->getCellGridStructure());
+ std::vector<bool> crit(criterion->toVectorOfBool());//check that criterion has one component.
+ std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> > listOfPatches,listOfPatchesOK;
+ //
+ MEDCouplingAutoRefCountObjectPtr<InternalPatch> p(new InternalPatch);
+ p->setNumberOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(cgs,crit,p->getCriterion(),p->getPart()));
+ if(p->presenceOfTrue())
+ listOfPatches.push_back(p);
+ while(!listOfPatches.empty())
+ {
+ std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> > listOfPatchesTmp;
+ for(std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> >::iterator it=listOfPatches.begin();it!=listOfPatches.end();it++)
+ {
+ //
+ if((*it)->getEfficiency()>=bso.getEffeciency())
+ {
+ if((*it)->getNumberOfCells()>=bso.getMaxCells())
+ {
+
+ }
+ }
+ }
+ listOfPatches=listOfPatchesTmp;
+ }
+ for(std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> >::const_iterator it=listOfPatchesOK.begin();it!=listOfPatchesOK.end();it++)
+ {
+ addPatch((*it)->getConstPart(),factors);
+ }
+}
+
void MEDCouplingCartesianAMRMesh::removePatch(int patchId)
{
checkPatchId(patchId);
#include "MEDCouplingRefCountObject.hxx"
#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+#include "BoxSplittingOptions.hxx"
#include "InterpKernelException.hxx"
namespace ParaMEDMEM
{
class MEDCouplingIMesh;
class MEDCouplingUMesh;
+ class DataArrayByte;
class MEDCouplingCartesianAMRMesh;
/// @cond INTERNAL
class MEDCouplingCartesianAMRPatch : public RefCountObject
{
public:
- MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMesh *mesh, const std::vector< std::pair<int,int> >& bottomLeftTopRight);
+ MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMesh *mesh, const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors);
// direct forward to _mesh
MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithOverlap() const;
MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithoutOverlap() const;
MEDCOUPLING_EXPORT int getMaxNumberOfLevelsRelativeToThis() const;
- MEDCOUPLING_EXPORT void addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, int factor);
+ MEDCOUPLING_EXPORT void addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors);
// end of direct forward to _mesh
MEDCOUPLING_EXPORT int getNumberOfOverlapedCellsForFather() const;
// basic set/get
private:
//! bottom left/top right cell range relative to \a _father
std::vector< std::pair<int,int> > _bl_tr;
+ std::vector<int> _factors;
MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRMesh> _mesh;
};
/// @endcond
MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMesh *getFather() const;
MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMesh *getGodFather() const;
MEDCOUPLING_EXPORT void detachFromFather();
- MEDCOUPLING_EXPORT void addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, int factor);
+ MEDCOUPLING_EXPORT void addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors);
+ MEDCOUPLING_EXPORT void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector<int>& factors);
MEDCOUPLING_EXPORT void removePatch(int patchId);
MEDCOUPLING_EXPORT int getNumberOfPatches() const;
MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRPatch *getPatch(int patchId) const;
* The origin of \a this will be not touched only spacing and node structure will be changed.
* This method can be useful for AMR users.
*/
-void MEDCouplingIMesh::refineWithFactor(int factor)
+void MEDCouplingIMesh::refineWithFactor(const std::vector<int>& factors)
{
- if(factor==0)
- throw INTERP_KERNEL::Exception("MEDCouplingIMesh::refineWithFactor : refinement factor must be != 0 !");
+ if((int)factors.size()!=_space_dim)
+ throw INTERP_KERNEL::Exception("MEDCouplingIMesh::refineWithFactor : refinement factors must have size equal to spaceDim !");
checkCoherency();
- int factAbs(std::abs(factor));
- double fact2(1./(double)factor);
- std::transform(_structure,_structure+_space_dim,_structure,std::bind2nd(std::plus<int>(),-1));
- std::transform(_structure,_structure+_space_dim,_structure,std::bind2nd(std::multiplies<int>(),factAbs));
- std::transform(_structure,_structure+_space_dim,_structure,std::bind2nd(std::plus<int>(),1));
- std::transform(_dxyz,_dxyz+_space_dim,_dxyz,std::bind2nd(std::multiplies<double>(),fact2));
+ std::vector<int> structure(_structure,_structure+3);
+ std::vector<double> dxyz(_dxyz,_dxyz+3);
+ for(int i=0;i<_space_dim;i++)
+ {
+ if(factors[i]<=0)
+ {
+ std::ostringstream oss; oss << "MEDCouplingIMesh::refineWithFactor : factor for axis #" << i << " (" << factors[i] << ")is invalid ! Must be > 0 !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ int factAbs(std::abs(factors[i]));
+ double fact2(1./(double)factors[i]);
+ structure[i]=(_structure[i]-1)*factAbs+1;
+ dxyz[i]=fact2*_dxyz[i];
+ }
+ std::copy(structure.begin(),structure.end(),_structure);
+ std::copy(dxyz.begin(),dxyz.end(),_dxyz);
declareAsNew();
}
MEDCOUPLING_EXPORT std::string getAxisUnit() const;
MEDCOUPLING_EXPORT double getMeasureOfAnyCell() const;
MEDCOUPLING_EXPORT MEDCouplingCMesh *convertToCartesian() const;
- MEDCOUPLING_EXPORT void refineWithFactor(int factor);
+ MEDCOUPLING_EXPORT void refineWithFactor(const std::vector<int>& factors);
MEDCOUPLING_EXPORT static void CondenseFineToCoarse(DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts);
MEDCOUPLING_EXPORT static void SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts);
//
MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const;
MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const;
MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const;
+ MEDCOUPLING_EXPORT std::vector<bool> toVectorOfBool() const;
private:
~DataArrayByte() { }
DataArrayByte() { }
return DataArrayChar::isEqualIfNotWhy(other,reason);
}
+/*!
+ * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
+ * \throw if \a this is not allocated.
+ * \throw if \a this has not exactly one component.
+ */
+std::vector<bool> DataArrayByte::toVectorOfBool() const
+{
+ checkAllocated();
+ if(getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("DataArrayByte::toVectorOfBool : this method can be used only if this has one component !");
+ int nbt(getNumberOfTuples());
+ std::vector<bool> ret(nbt,false);
+ const char *pt(begin());
+ for(int i=0;i<nbt;i++,pt++)
+ if(*pt!=0)
+ ret[i]=true;
+ return ret;
+}
+
DataArrayByteIterator::DataArrayByteIterator(DataArrayByte *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
{
if(_da)
return isFetched?ret:0;
}
+void MEDCouplingStructuredMesh::FindTheWidestAxisOfGivenRangeInCompactFrmt(const std::vector< std::pair<int,int> >& partCompactFormat, int& axisId, int& sizeOfRange)
+{
+ int dim((int)partCompactFormat.size());
+ int ret(-1);
+ for(int i=0;i<dim;i++)
+ {
+ int curDelta(partCompactFormat[i].second-partCompactFormat[i].first);
+ if(curDelta<0)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::FindTheWidestAxisOfGivenRangeInCompactFrmt : at axis #" << i << " the range is invalid (first value < second value) !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ if(curDelta>ret)
+ {
+ axisId=i; sizeOfRange=curDelta;
+ ret=curDelta;
+ }
+ }
+}
+
+/*!
+ * This method is \b NOT wrapped in python because it has no sense in python (for performance reasons).
+ * This method starts from a structured mesh with structure \a st on which a boolean field \a crit is set.
+ * This method find for such minimalist information of mesh and field which is the part of the mesh, given by the range per axis in output parameter
+ * \a partCompactFormat that contains all the True in \a crit. The returned vector of boolean is the field reduced to that part.
+ * So the number of True is equal in \a st and in returned vector of boolean.
+ *
+ * \param [in] st - The structure per axis of the structured mesh considered.
+ * \param [in] crit - The field of boolean (for performance reasons) lying on the mesh defined by \a st.
+ * \param [out] partCompactFormat - The minimal part of \a st containing all the true of \a crit.
+ * \param [out] reducedCrit - The reduction of \a criterion on \a partCompactFormat.
+ * \return - The number of True in \a st (that is equal to those in \a reducedCrit)
+ */
+int MEDCouplingStructuredMesh::FindMinimalPartOf(const std::vector<int>& st, const std::vector<bool>& crit, std::vector<bool>& reducedCrit, std::vector< std::pair<int,int> >& partCompactFormat)
+{
+ if((int)crit.size()!=DeduceNumberOfGivenStructure(st))
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : size of vector of boolean is invalid regarding the declared structure !");
+ switch((int)st.size())
+ {
+ case 1:
+ {
+ return FindMinimalPartOf1D(st,crit,reducedCrit,partCompactFormat);
+ break;
+ }
+ case 2:
+ {
+ return FindMinimalPartOf2D(st,crit,reducedCrit,partCompactFormat);
+ break;
+ }
+ case 3:
+ {
+ return FindMinimalPartOf3D(st,crit,reducedCrit,partCompactFormat);
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : only dimension 1, 2 and 3 are supported actually !");
+ }
+}
+
DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivity1D(const int *nodeStBg)
{
int nbOfCells(*nodeStBg-1);
return conn.retn();
}
+/*!
+ * \sa MEDCouplingStructuredMesh::FindMinimalPartOf
+ */
+int MEDCouplingStructuredMesh::FindMinimalPartOf1D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector<bool>& reducedCrit, std::vector< std::pair<int,int> >& partCompactFormat)
+{
+ if(st.size()!=1)
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf1D : the input size of st must be equal to 1 !");
+ int nxMin(std::numeric_limits<int>::max()),nxMax(-std::numeric_limits<int>::max());
+ int nx(st[0]),ret(0);
+ for(int i=0;i<nx;i++)
+ {
+ if(crit[i])
+ {
+ nxMin=std::min(nxMin,i); nxMax=std::max(nxMax,i);
+ ret++;
+ }
+ }
+ if(ret==0)
+ return ret;
+ partCompactFormat.resize(1);
+ partCompactFormat[0].first=nxMin; partCompactFormat[0].second=nxMax+1;
+ ExtractVecOfBool(st,crit,partCompactFormat,reducedCrit);
+ return ret;
+}
+
+/*!
+ * \sa MEDCouplingStructuredMesh::FindMinimalPartOf
+ */
+int MEDCouplingStructuredMesh::FindMinimalPartOf2D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector<bool>& reducedCrit, std::vector< std::pair<int,int> >& partCompactFormat)
+{
+ if(st.size()!=2)
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf2D : the input size of st must be equal to 2 !");
+ int nxMin(std::numeric_limits<int>::max()),nxMax(-std::numeric_limits<int>::max()),nyMin(std::numeric_limits<int>::max()),nyMax(-std::numeric_limits<int>::max());
+ int it(0),nx(st[0]),ny(st[1]);
+ int ret(0);
+ for(int i=0;i<ny;i++)
+ for(int j=0;j<nx;j++,it++)
+ {
+ if(crit[it])
+ {
+ nxMin=std::min(nxMin,j); nxMax=std::max(nxMax,j);
+ nyMin=std::min(nyMin,i); nyMax=std::max(nyMax,i);
+ ret++;
+ }
+ }
+ if(ret==0)
+ return ret;
+ partCompactFormat.resize(2);
+ partCompactFormat[0].first=nxMin; partCompactFormat[0].second=nxMax+1;
+ partCompactFormat[1].first=nyMin; partCompactFormat[1].second=nyMax+1;
+ ExtractVecOfBool(st,crit,partCompactFormat,reducedCrit);
+ return ret;
+}
+
+/*!
+ * \sa MEDCouplingStructuredMesh::FindMinimalPartOf
+ */
+int MEDCouplingStructuredMesh::FindMinimalPartOf3D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector<bool>& reducedCrit, std::vector< std::pair<int,int> >& partCompactFormat)
+{
+ if(st.size()!=3)
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf3D : the input size of st must be equal to 3 !");
+ int nxMin(std::numeric_limits<int>::max()),nxMax(-std::numeric_limits<int>::max()),nyMin(std::numeric_limits<int>::max()),nyMax(-std::numeric_limits<int>::max()),nzMin(std::numeric_limits<int>::max()),nzMax(-std::numeric_limits<int>::max());
+ int it(0),nx(st[0]),ny(st[1]),nz(st[2]);
+ int ret(0);
+ for(int i=0;i<nz;i++)
+ for(int j=0;j<ny;j++)
+ for(int k=0;k<nx;k++,it++)
+ {
+ if(crit[it])
+ {
+ nxMin=std::min(nxMin,k); nxMax=std::max(nxMax,k);
+ nyMin=std::min(nyMin,j); nyMax=std::max(nyMax,j);
+ nzMin=std::min(nyMin,i); nzMax=std::max(nyMax,i);
+ ret++;
+ }
+ }
+ if(ret==0)
+ return ret;
+ partCompactFormat.resize(3);
+ partCompactFormat[0].first=nxMin; partCompactFormat[0].second=nxMax+1;
+ partCompactFormat[1].first=nyMin; partCompactFormat[1].second=nyMax+1;
+ partCompactFormat[2].first=nzMin; partCompactFormat[2].second=nzMax+1;
+ ExtractVecOfBool(st,crit,partCompactFormat,reducedCrit);
+ return ret;
+}
+
+void MEDCouplingStructuredMesh::ExtractVecOfBool(const std::vector<int>& st, const std::vector<bool>& crit, const std::vector< std::pair<int,int> >& partCompactFormat, std::vector<bool>& reducedCrit)
+{
+ int nbt(DeduceNumberOfGivenRangeInCompactFrmt(partCompactFormat));
+ std::vector<int> dims(GetDimensionsFromCompactFrmt(partCompactFormat));
+ reducedCrit.resize(nbt);
+ switch((int)st.size())
+ {
+ case 1:
+ {
+ int nx(dims[0]);
+ int kk(partCompactFormat[0].first);
+ for(int i=0;i<nx;i++)
+ reducedCrit[i]=crit[kk+i];
+ break;
+ }
+ case 2:
+ {
+ int nx(dims[0]),ny(dims[1]);
+ int kk(partCompactFormat[0].first+partCompactFormat[1].first*nx),it(0);
+ for(int j=0;j<ny;j++,kk+=nx)
+ for(int i=0;i<nx;i++,it++)
+ reducedCrit[it]=crit[kk+i];
+ break;
+ }
+ case 3:
+ {
+ int nx(dims[0]),ny(dims[1]),nz(dims[2]);
+ int kk(partCompactFormat[0].first+partCompactFormat[1].first*nx+partCompactFormat[2].first*nx*ny),it(0);
+ for(int k=0;k<nz;k++,kk+=nx*ny)
+ for(int j=0;j<ny;j++)
+ {
+ int kk2(j*nx);
+ for(int i=0;i<nx;i++,it++)
+ reducedCrit[it]=crit[kk+kk2+i];
+ }
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractVecOfBool : Only dimension 1, 2 and 3 are supported actually !");
+ }
+}
+
/*!
* This method computes given the nodal structure defined by [ \a nodeStBg , \a nodeStEnd ) the zipped form.
* std::distance( \a nodeStBg, \a nodeStEnd ) is equal to the space dimension. The returned value is equal to
MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh(const int *nodeStBg, const int *nodeStEnd);
MEDCOUPLING_EXPORT static int DeduceNumberOfGivenRangeInCompactFrmt(const std::vector< std::pair<int,int> >& partCompactFormat);
MEDCOUPLING_EXPORT static int DeduceNumberOfGivenStructure(const std::vector<int>& st);
+ MEDCOUPLING_EXPORT static void FindTheWidestAxisOfGivenRangeInCompactFrmt(const std::vector< std::pair<int,int> >& partCompactFormat, int& axisId, int& sizeOfRange);
+ MEDCOUPLING_EXPORT static int FindMinimalPartOf(const std::vector<int>& st, const std::vector<bool>& crit, std::vector<bool>& reducedCrit, std::vector< std::pair<int,int> >& partCompactFormat);
private:
static int GetNumberOfCellsOfSubLevelMesh(const std::vector<int>& cgs, int mdim);
static void GetReverseNodalConnectivity1(const std::vector<int>& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx);
static DataArrayInt *Build1GTNodalConnectivity3D(const int *nodeStBg);
static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh2D(const int *nodeStBg);
static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh3D(const int *nodeStBg);
+ static int FindMinimalPartOf1D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector<bool>& reducedCrit, std::vector< std::pair<int,int> >& partCompactFormat);
+ static int FindMinimalPartOf2D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector<bool>& reducedCrit, std::vector< std::pair<int,int> >& partCompactFormat);
+ static int FindMinimalPartOf3D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector<bool>& reducedCrit, std::vector< std::pair<int,int> >& partCompactFormat);
+ static void ExtractVecOfBool(const std::vector<int>& st, const std::vector<bool>& crit, const std::vector< std::pair<int,int> >& partCompactFormat, std::vector<bool>& reducedCrit);
protected:
static int ZipNodeStructure(const int *nodeStBg, const int *nodeStEnd, int zipNodeSt[3]);
protected:
self.assertTrue(m2bis.isEqual(m2,1e-12))
#
self.assertEqual(6,m2bis.getNumberOfCells())#3,2,4
- m2bis.refineWithFactor(3)
+ m2bis.refineWithFactor([3,3,3])
self.assertEqual(162,m2bis.getNumberOfCells())
self.assertEqual((7,4,10),m2bis.getNodeStruct())
self.assertEqual((1.5,3.5,2.5),m2bis.getOrigin())
self.assertEqual(0,amr.getNumberOfPatches())
self.assertEqual(1,amr.getMaxNumberOfLevelsRelativeToThis())
self.assertEqual(2,amr.getSpaceDimension())
- amr.addPatch([(1,2),(0,1)],4)
+ amr.addPatch([(1,2),(0,1)],[4,4])
self.assertEqual(4,amr.getNumberOfCellsAtCurrentLevel())
self.assertEqual(20,amr.getNumberOfCellsRecursiveWithOverlap())
self.assertEqual(19,amr.getNumberOfCellsRecursiveWithoutOverlap())
self.assertEqual(1,amr.getNumberOfPatches())
self.assertEqual(2,amr.getMaxNumberOfLevelsRelativeToThis())
self.assertEqual(2,amr.getSpaceDimension())
- amr[0].addPatch([(2,3),(1,3)],2)
+ amr[0].addPatch([(2,3),(1,3)],[2,2])
self.assertEqual(amr[0].getBLTRRange(),[(1,2),(0,1)])
self.assertEqual(4,amr.getNumberOfCellsAtCurrentLevel())
self.assertEqual(28,amr.getNumberOfCellsRecursiveWithOverlap())
self.assertEqual(1,amr.getNumberOfPatches())
self.assertEqual(3,amr.getMaxNumberOfLevelsRelativeToThis())
self.assertEqual(2,amr.getSpaceDimension())
- amr[0].addPatch([(0,2),(3,4)],3)
+ amr[0].addPatch([(0,2),(3,4)],[3,3])
self.assertEqual(16,amr[0].getMesh().getNumberOfCellsAtCurrentLevel())
self.assertEqual(46,amr.getNumberOfCellsRecursiveWithOverlap())
self.assertEqual(41,amr.getNumberOfCellsRecursiveWithoutOverlap())
#include "MEDCouplingTypemaps.i"
#include "InterpKernelAutoPtr.hxx"
+#include "BoxSplittingOptions.hxx"
using namespace ParaMEDMEM;
using namespace INTERP_KERNEL;
%include "MEDCouplingRefCountObject.i"
%include "MEDCouplingMemArray.i"
+namespace INTERP_KERNEL
+{
+ /*!
+ * \class BoxSplittingOptions
+ * Class defining the options for box splitting used for AMR algorithm like creation of patches following a criterion.
+ */
+ class BoxSplittingOptions
+ {
+ public:
+ BoxSplittingOptions();
+ void init() throw(INTERP_KERNEL::Exception);
+ double getEffeciency() const throw(INTERP_KERNEL::Exception);
+ void setEffeciency(double effeciency) throw(INTERP_KERNEL::Exception);
+ double getEffeciencySnd() const throw(INTERP_KERNEL::Exception);
+ void setEffeciencySnd(double effeciencySnd) throw(INTERP_KERNEL::Exception);
+ int getMinCellDirection() const throw(INTERP_KERNEL::Exception);
+ void setMinCellDirection(int minCellDirection) throw(INTERP_KERNEL::Exception);
+ int getMaxCells() const throw(INTERP_KERNEL::Exception);
+ void setMaxCells(int maxCells) throw(INTERP_KERNEL::Exception);
+ void copyOptions(const BoxSplittingOptions & other) throw(INTERP_KERNEL::Exception);
+ std::string printOptions() const throw(INTERP_KERNEL::Exception);
+ };
+}
+
namespace ParaMEDMEM
{
typedef enum
std::string getAxisUnit() const throw(INTERP_KERNEL::Exception);
double getMeasureOfAnyCell() const throw(INTERP_KERNEL::Exception);
MEDCouplingCMesh *convertToCartesian() const throw(INTERP_KERNEL::Exception);
- void refineWithFactor(int factor) throw(INTERP_KERNEL::Exception);
+ void refineWithFactor(const std::vector<int>& factors) throw(INTERP_KERNEL::Exception);
%extend
{
MEDCouplingIMesh()
return ret;
}
- void addPatch(PyObject *bottomLeftTopRight, int factor) throw(INTERP_KERNEL::Exception)
+ void addPatch(PyObject *bottomLeftTopRight, const std::vector<int>& factors) throw(INTERP_KERNEL::Exception)
{
std::vector< std::pair<int,int> > inp;
convertPyToVectorPairInt(bottomLeftTopRight,inp);
- self->addPatch(inp,factor);
+ self->addPatch(inp,factors);
}
MEDCouplingCartesianAMRPatch *__getitem__(int patchId) const throw(INTERP_KERNEL::Exception)
return ParaMEDMEM_MEDCouplingCartesianAMRMesh_New(meshName,spaceDim,nodeStrct,origin,dxyz);
}
- void addPatch(PyObject *bottomLeftTopRight, int factor) throw(INTERP_KERNEL::Exception)
+ void addPatch(PyObject *bottomLeftTopRight, const std::vector<int>& factors) throw(INTERP_KERNEL::Exception)
{
std::vector< std::pair<int,int> > inp;
convertPyToVectorPairInt(bottomLeftTopRight,inp);
- self->addPatch(inp,factor);
+ self->addPatch(inp,factors);
}
MEDCouplingCartesianAMRMesh *getFather() const throw(INTERP_KERNEL::Exception)
return ParaMEDMEM_DataArrayByte_presenceOfTuple(self,obj);
}
}
+
+ DataArrayByte *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception)
+ {
+ self->checkAllocated();
+ const char msg[]="Unexpected situation in __setitem__ !";
+ int nbOfTuples(self->getNumberOfTuples()),nbOfComponents(self->getNumberOfComponents());
+ int sw1,sw2;
+ int i1;
+ std::vector<int> v1;
+ DataArrayInt *d1=0;
+ DataArrayIntTuple *dd1=0;
+ convertObjToPossibleCpp1(value,sw1,i1,v1,d1,dd1);
+ int it1,ic1;
+ std::vector<int> vt1,vc1;
+ std::pair<int, std::pair<int,int> > pt1,pc1;
+ DataArrayInt *dt1=0,*dc1=0;
+ convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw2,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp;
+ switch(sw2)
+ {
+ case 1:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple1(i1,it1,it1+1,1,0,nbOfComponents,1);
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 2:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1);
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 3:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1);
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 4:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1);
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 5:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple1(i1,it1,it1+1,1,ic1,ic1+1,1);
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 6:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1);
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 7:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1);
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 8:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1);
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 9:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple2(i1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size());
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 10:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple2(i1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size());
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 11:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple4(i1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size());
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 12:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple2(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size());
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 13:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple1(i1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second);
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 14:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second);
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 15:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second);
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ case 16:
+ {
+ switch(sw1)
+ {
+ case 1:
+ self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second);
+ return self;
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception(msg);
+ }
+ return self;
+ }
}
};