From: geay Date: Tue, 29 Apr 2014 17:29:45 +0000 (+0200) Subject: Addition of first AMR concepts. X-Git-Tag: V7_4_0rc1~2^2~5 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=adb05294eddb7cd796a4bebee7b3164ad1440f8f;p=tools%2Fmedcoupling.git Addition of first AMR concepts. --- diff --git a/src/MEDCoupling/CMakeLists.txt b/src/MEDCoupling/CMakeLists.txt index 6af998f0c..bbd0d8ea0 100644 --- a/src/MEDCoupling/CMakeLists.txt +++ b/src/MEDCoupling/CMakeLists.txt @@ -55,6 +55,7 @@ SET(medcoupling_SOURCES MEDCouplingMultiFields.cxx MEDCouplingDefinitionTime.cxx MEDCouplingFieldOverTime.cxx + MEDCouplingAHOGMesh.cxx ) SET(medcouplingremapper_SOURCES diff --git a/src/MEDCoupling/MEDCouplingAHOGMesh.cxx b/src/MEDCoupling/MEDCouplingAHOGMesh.cxx new file mode 100644 index 000000000..82e9bd83c --- /dev/null +++ b/src/MEDCoupling/MEDCouplingAHOGMesh.cxx @@ -0,0 +1,237 @@ +// 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 "MEDCouplingAHOGMesh.hxx" +#include "MEDCouplingIMesh.hxx" +#include "MEDCouplingUMesh.hxx" + +#include +#include + +using namespace ParaMEDMEM; + +/// @cond INTERNAL + +/*! + * \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. + */ +MEDCouplingAHOGPatch::MEDCouplingAHOGPatch(MEDCouplingAHOGMesh *mesh, const std::vector< std::pair >& bottomLeftTopRight) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("EDCouplingAHOGPatch constructor : input mesh is NULL !"); + _mesh=mesh; _mesh->incrRef(); + int dim((int)bottomLeftTopRight.size()); + if(dim!=_mesh->getSpaceDimension()) + throw INTERP_KERNEL::Exception("MEDCouplingAHOGPatch constructor : space dimension of father and input bottomLeft/topRight size mismatches !"); + _bl_tr=bottomLeftTopRight; +} + +int MEDCouplingAHOGPatch::getNumberOfCellsRecursiveWithOverlap() const +{ + return _mesh->getNumberOfCellsRecursiveWithOverlap(); +} + +int MEDCouplingAHOGPatch::getNumberOfCellsRecursiveWithoutOverlap() const +{ + return _mesh->getNumberOfCellsRecursiveWithoutOverlap(); +} + +int MEDCouplingAHOGPatch::getMaxNumberOfLevelsRelativeToThis() const +{ + return _mesh->getMaxNumberOfLevelsRelativeToThis(); +} + +void MEDCouplingAHOGPatch::addPatch(const std::vector< std::pair >& bottomLeftTopRight, int factor) +{ + return _mesh->addPatch(bottomLeftTopRight,factor); +} + +int MEDCouplingAHOGPatch::getNumberOfOverlapedCellsForFather() const +{ + return MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(_bl_tr); +} + +std::size_t MEDCouplingAHOGPatch::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(sizeof(MEDCouplingAHOGPatch)); + ret+=_bl_tr.capacity()*sizeof(std::pair); + return ret; +} + +std::vector MEDCouplingAHOGPatch::getDirectChildren() const +{ + std::vector ret; + if((const MEDCouplingAHOGMesh *)_mesh) + ret.push_back((const MEDCouplingAHOGMesh *)_mesh); + return ret; +} + +/// @endcond + + +MEDCouplingAHOGMesh *MEDCouplingAHOGMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, + const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop) +{ + return new MEDCouplingAHOGMesh(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop); +} + +int MEDCouplingAHOGMesh::getSpaceDimension() const +{ + return _mesh->getSpaceDimension(); +} + +int MEDCouplingAHOGMesh::getMaxNumberOfLevelsRelativeToThis() const +{ + int ret(1); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) + ret=std::max(ret,(*it)->getMaxNumberOfLevelsRelativeToThis()+1); + return ret; +} + +int MEDCouplingAHOGMesh::getNumberOfCellsAtCurrentLevel() const +{ + return _mesh->getNumberOfCells(); +} + +int MEDCouplingAHOGMesh::getNumberOfCellsRecursiveWithOverlap() const +{ + int ret(_mesh->getNumberOfCells()); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) + { + ret+=(*it)->getNumberOfCellsRecursiveWithOverlap(); + } + return ret; +} + +int MEDCouplingAHOGMesh::getNumberOfCellsRecursiveWithoutOverlap() const +{ + int ret(_mesh->getNumberOfCells()); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) + { + ret-=(*it)->getNumberOfOverlapedCellsForFather(); + ret+=(*it)->getNumberOfCellsRecursiveWithoutOverlap(); + } + return ret; +} + +const MEDCouplingAHOGMesh *MEDCouplingAHOGMesh::getFather() const +{ + return _father; +} + +const MEDCouplingAHOGMesh *MEDCouplingAHOGMesh::getGodFather() const +{ + if(_father==0) + return this; + else + return _father->getGodFather(); +} + +/*! + * \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. + */ +void MEDCouplingAHOGMesh::addPatch(const std::vector< std::pair >& bottomLeftTopRight, int factor) +{ + MEDCouplingAutoRefCountObjectPtr mesh(static_cast(_mesh->buildStructuredSubPart(bottomLeftTopRight))); + mesh->refineWithFactor(factor); + MEDCouplingAutoRefCountObjectPtr zeMesh(new MEDCouplingAHOGMesh(this,mesh)); + MEDCouplingAutoRefCountObjectPtr elt(new MEDCouplingAHOGPatch(zeMesh,bottomLeftTopRight)); + _patches.push_back(elt); +} + +int MEDCouplingAHOGMesh::getNumberOfPatches() const +{ + return (int)_patches.size(); +} + +const MEDCouplingAHOGPatch *MEDCouplingAHOGMesh::getPatch(int patchId) const +{ + int sz(getNumberOfPatches()); + if(patchId<0 || patchId>=sz) + { + std::ostringstream oss; oss << "MEDCouplingAHOGMesh::getPatch : invalid patchId (" << patchId << ") ! Must be in [0," << sz << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return _patches[patchId]; +} + +MEDCouplingUMesh *MEDCouplingAHOGMesh::buildUnstructured() const +{ + MEDCouplingAutoRefCountObjectPtr part(_mesh->buildUnstructured()); + std::vector bs(_mesh->getNumberOfCells(),false); + std::vector cgs(_mesh->getCellGridStructure()); + std::vector< MEDCouplingAutoRefCountObjectPtr > msSafe(_patches.size()+1); + std::size_t ii(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++,ii++) + { + MEDCouplingStructuredMesh::SwitchOnIdsFrom(cgs,(*it)->getBLTRRange(),bs); + msSafe[ii+1]=(*it)->getMesh()->buildUnstructured(); + } + MEDCouplingAutoRefCountObjectPtr eltsOff(DataArrayInt::BuildListOfSwitchedOff(bs)); + msSafe[0]=static_cast(part->buildPartOfMySelf(eltsOff->begin(),eltsOff->end(),false)); + std::vector< const MEDCouplingUMesh * > ms(msSafe.size()); + for(std::size_t i=0;icheckCoherency(); + _mesh=mesh; _mesh->incrRef(); +} + +std::size_t MEDCouplingAHOGMesh::getHeapMemorySizeWithoutChildren() const +{ + return sizeof(MEDCouplingAHOGMesh); +} + +std::vector MEDCouplingAHOGMesh::getDirectChildren() const +{ + std::vector ret; + if((const MEDCouplingIMesh *)_mesh) + ret.push_back((const MEDCouplingIMesh *)_mesh); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) + { + if((const MEDCouplingAHOGPatch*)*it) + ret.push_back((const MEDCouplingAHOGPatch*)*it); + } + return ret; +} + +void MEDCouplingAHOGMesh::updateTime() const +{ + if((const MEDCouplingIMesh *)_mesh) + updateTimeWith(*_mesh); +} diff --git a/src/MEDCoupling/MEDCouplingAHOGMesh.hxx b/src/MEDCoupling/MEDCouplingAHOGMesh.hxx new file mode 100644 index 000000000..b2e755457 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingAHOGMesh.hxx @@ -0,0 +1,101 @@ +// 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 __MEDCOUPLINGAHOGMESH_HXX__ +#define __MEDCOUPLINGAHOGMESH_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingTimeLabel.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include "InterpKernelException.hxx" + +namespace ParaMEDMEM +{ + class MEDCouplingIMesh; + class MEDCouplingUMesh; + class MEDCouplingAHOGMesh; + + /// @cond INTERNAL + class MEDCouplingAHOGPatch : public RefCountObject + { + public: + MEDCouplingAHOGPatch(MEDCouplingAHOGMesh *mesh, const std::vector< std::pair >& bottomLeftTopRight); + // 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 >& bottomLeftTopRight, int factor); + // end of direct forward to _mesh + MEDCOUPLING_EXPORT int getNumberOfOverlapedCellsForFather() const; + // basic set/get + MEDCOUPLING_EXPORT const std::vector< std::pair >& getBLTRRange() const { return _bl_tr; } + MEDCOUPLING_EXPORT const MEDCouplingAHOGMesh *getMesh() const { return _mesh; } + private: + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector getDirectChildren() const; + private: + //! bottom left/top right cell range relative to \a _father + std::vector< std::pair > _bl_tr; + MEDCouplingAutoRefCountObjectPtr _mesh; + }; + /// @endcond + + /*! + * This class is the base class dedicated to AMR using Adaptative Hierarchical Overlapped image Grid. + * This class does \b NOT inherit from MEDCouplingMesh because this class overlaps image grid structured meshes to perform adaptative mesh refinement. + * But this class aggregates MEDCouplingMesh instances ! + */ + class MEDCouplingAHOGMesh : public RefCountObject, public TimeLabel + { + public: + MEDCOUPLING_EXPORT static MEDCouplingAHOGMesh *New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, + const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); + MEDCOUPLING_EXPORT int getSpaceDimension() const; + MEDCOUPLING_EXPORT int getMaxNumberOfLevelsRelativeToThis() const; + MEDCOUPLING_EXPORT int getNumberOfCellsAtCurrentLevel() const; + MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithOverlap() const; + MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithoutOverlap() const; + // + MEDCOUPLING_EXPORT const MEDCouplingAHOGMesh *getFather() const; + MEDCOUPLING_EXPORT const MEDCouplingAHOGMesh *getGodFather() const; + MEDCOUPLING_EXPORT void addPatch(const std::vector< std::pair >& bottomLeftTopRight, int factor); + MEDCOUPLING_EXPORT int getNumberOfPatches() const; + MEDCOUPLING_EXPORT const MEDCouplingAHOGPatch *getPatch(int patchId) const; + // + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; + private: + MEDCouplingAHOGMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, + const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); + MEDCouplingAHOGMesh(MEDCouplingAHOGMesh *father, MEDCouplingIMesh *mesh); + protected: + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector getDirectChildren() const; + MEDCOUPLING_EXPORT void updateTime() const; + private: + MEDCouplingAHOGMesh *_father; + MEDCouplingAutoRefCountObjectPtr _mesh; + std::vector< MEDCouplingAutoRefCountObjectPtr > _patches; + }; +} + +#endif + diff --git a/src/MEDCoupling/MEDCouplingIMesh.cxx b/src/MEDCoupling/MEDCouplingIMesh.cxx index 43dd40d2c..dc2cf8793 100644 --- a/src/MEDCoupling/MEDCouplingIMesh.cxx +++ b/src/MEDCoupling/MEDCouplingIMesh.cxx @@ -176,6 +176,26 @@ MEDCouplingCMesh *MEDCouplingIMesh::convertToCartesian() const return ret.retn(); } +/*! + * This method refines \a this uniformaly along all of its dimensions. In case of success the space covered by \a this will remain + * the same before the invocation except that the number of cells will be multiplied by \a factor ^ this->getMeshDimension(). + * 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) +{ + if(factor==0) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::refineWithFactor : refinement factor must be != 0 !"); + checkCoherency(); + int factAbs(std::abs(factor)); + double fact2(1./(double)factor); + std::transform(_structure,_structure+_space_dim,_structure,std::bind2nd(std::plus(),-1)); + std::transform(_structure,_structure+_space_dim,_structure,std::bind2nd(std::multiplies(),factAbs)); + std::transform(_structure,_structure+_space_dim,_structure,std::bind2nd(std::plus(),1)); + std::transform(_dxyz,_dxyz+_space_dim,_dxyz,std::bind2nd(std::multiplies(),fact2)); + declareAsNew(); +} + void MEDCouplingIMesh::setSpaceDimension(int spaceDim) { if(spaceDim==_space_dim) diff --git a/src/MEDCoupling/MEDCouplingIMesh.hxx b/src/MEDCoupling/MEDCouplingIMesh.hxx index ecd679069..cba2da67a 100644 --- a/src/MEDCoupling/MEDCouplingIMesh.hxx +++ b/src/MEDCoupling/MEDCouplingIMesh.hxx @@ -46,6 +46,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT std::string getAxisUnit() const; MEDCOUPLING_EXPORT double getMeasureOfAnyCell() const; MEDCOUPLING_EXPORT MEDCouplingCMesh *convertToCartesian() const; + MEDCOUPLING_EXPORT void refineWithFactor(int factor); // MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; MEDCOUPLING_EXPORT MEDCouplingIMesh *clone(bool recDeepCpy) const; diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 6845713eb..86b8c8727 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -9630,6 +9630,53 @@ DataArrayInt *DataArrayInt::BuildIntersection(const std::vector& v) +{ + int sz((int)std::count(v.begin(),v.end(),true)); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(sz,1); + std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer())); + return ret.retn(); +} + +/*! + * This method returns the list of ids in ascending mode so that v[id]==false. + */ +DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector& v) +{ + int sz((int)std::count(v.begin(),v.end(),false)); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(sz,1); + std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer())); + return ret.retn(); +} + /*! * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). * This method is not available into python because no available optimized data structure available to map std::vector< std::vector >. diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index d77572698..38aa67d8f 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -574,6 +574,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static DataArrayInt *MakePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups); MEDCOUPLING_EXPORT static DataArrayInt *BuildUnion(const std::vector& arr); MEDCOUPLING_EXPORT static DataArrayInt *BuildIntersection(const std::vector& arr); + MEDCOUPLING_EXPORT static DataArrayInt *BuildListOfSwitchedOn(const std::vector& v); + MEDCOUPLING_EXPORT static DataArrayInt *BuildListOfSwitchedOff(const std::vector& v); MEDCOUPLING_EXPORT static void PutIntoToSkylineFrmt(const std::vector< std::vector >& v, DataArrayInt *& data, DataArrayInt *& dataIndex); MEDCOUPLING_EXPORT DataArrayInt *buildComplement(int nbOfElement) const; MEDCOUPLING_EXPORT DataArrayInt *buildSubstraction(const DataArrayInt *other) const; diff --git a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx index b5a8fb2ca..d716be479 100644 --- a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx +++ b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx @@ -671,6 +671,20 @@ int MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(const std:: return isFetched?ret:0; } +int MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(const std::vector& st) +{ + int ret(1); + bool isFetched(false); + for(std::size_t i=0;i& st, const std::vector< std::pair >& partCompactFormat, std::vector& vectToSwitchOn) +{ + if(st.size()!=partCompactFormat.size()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : input arrays must have the same size !"); + if((int)vectToSwitchOn.size()!=DeduceNumberOfGivenStructure(st)) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : invalid size of input vector of boolean regarding the structure !"); + std::vector dims(st.size()); + for(std::size_t i=0;i& st, const std::vector< std::pair >& partCompactFormat) { diff --git a/src/MEDCoupling/MEDCouplingStructuredMesh.hxx b/src/MEDCoupling/MEDCouplingStructuredMesh.hxx index cd4295399..cb12e85af 100644 --- a/src/MEDCoupling/MEDCouplingStructuredMesh.hxx +++ b/src/MEDCoupling/MEDCouplingStructuredMesh.hxx @@ -71,10 +71,12 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT std::vector getCellGridStructure() const; MEDCOUPLING_EXPORT virtual MEDCouplingStructuredMesh *buildStructuredSubPart(const std::vector< std::pair >& cellPart) const = 0; MEDCOUPLING_EXPORT static bool IsPartStructured(const int *startIds, const int *stopIds, const std::vector& st, std::vector< std::pair >& partCompactFormat); + MEDCOUPLING_EXPORT static void SwitchOnIdsFrom(const std::vector& st, const std::vector< std::pair >& partCompactFormat, std::vector& vectToSwitchOn); MEDCOUPLING_EXPORT static DataArrayInt *BuildExplicitIdsFrom(const std::vector& st, const std::vector< std::pair >& partCompactFormat); MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivity(const int *nodeStBg, const int *nodeStEnd); MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh(const int *nodeStBg, const int *nodeStEnd); MEDCOUPLING_EXPORT static int DeduceNumberOfGivenRangeInCompactFrmt(const std::vector< std::pair >& partCompactFormat); + MEDCOUPLING_EXPORT static int DeduceNumberOfGivenStructure(const std::vector& st); private: static int GetNumberOfCellsOfSubLevelMesh(const std::vector& cgs, int mdim); static void GetReverseNodalConnectivity1(const std::vector& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx); diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index b68019b0c..58eb47e11 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -13527,6 +13527,8 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(12,MEDCouplingStructuredMesh.DeduceNumberOfGivenRangeInCompactFrmt(b)) self.assertEqual(8,MEDCouplingStructuredMesh.DeduceNumberOfGivenRangeInCompactFrmt([(1,5),(1,3),(2,2)])) self.assertEqual(0,MEDCouplingStructuredMesh.DeduceNumberOfGivenRangeInCompactFrmt([(5,5),(3,3),(2,2)])) + self.assertEqual(36,MEDCouplingStructuredMesh.DeduceNumberOfGivenStructure([3,2,6])) + self.assertEqual(126,MEDCouplingStructuredMesh.DeduceNumberOfGivenStructure((3,7,6))) d20=DataArrayInt([1,2,3,4,12,11,13,14,21,22,23,24]) a,b=MEDCouplingStructuredMesh.IsPartStructured(d20,st) self.assertTrue(not a) @@ -14858,6 +14860,13 @@ class MEDCouplingBasicsTest(unittest.TestCase): m2bis=m2.deepCpy() self.assertTrue(m2bis.isEqual(m2,1e-12)) # + self.assertEqual(6,m2bis.getNumberOfCells())#3,2,4 + m2bis.refineWithFactor(3) + self.assertEqual(162,m2bis.getNumberOfCells()) + self.assertEqual((7,4,10),m2bis.getNodeStruct()) + self.assertEqual((1.5,3.5,2.5),m2bis.getOrigin()) + self.assertTrue(DataArrayDouble([0.16666666666666666,0.08333333333333333,0.3333333333333333]).isEqual(DataArrayDouble(m2bis.getDXYZ()),1e-12)) + # self.assertEqual(3,m.getMeshDimension()) self.assertAlmostEqual(0.125,m.getMeasureOfAnyCell(),16); mu=MEDCoupling1SGTUMesh(m.buildUnstructured()) diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index c01b16184..8f0dfb8c9 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -40,6 +40,7 @@ #include "MEDCouplingFieldOverTime.hxx" #include "MEDCouplingDefinitionTime.hxx" #include "MEDCouplingFieldDiscretization.hxx" +#include "MEDCouplingAHOGMesh.hxx" #include "MEDCouplingTypemaps.i" #include "InterpKernelAutoPtr.hxx" @@ -310,6 +311,14 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingMultiFields::New; %newobject ParaMEDMEM::MEDCouplingMultiFields::deepCpy; %newobject ParaMEDMEM::MEDCouplingFieldOverTime::New; +%newobject ParaMEDMEM::MEDCouplingAHOGPatch::getMesh; +%newobject ParaMEDMEM::MEDCouplingAHOGPatch::__getitem__; +%newobject ParaMEDMEM::MEDCouplingAHOGMesh::New; +%newobject ParaMEDMEM::MEDCouplingAHOGMesh::buildUnstructured; +%newobject ParaMEDMEM::MEDCouplingAHOGMesh::getGodFather; +%newobject ParaMEDMEM::MEDCouplingAHOGMesh::getFather; +%newobject ParaMEDMEM::MEDCouplingAHOGMesh::getPatch; +%newobject ParaMEDMEM::MEDCouplingAHOGMesh::__getitem__; %feature("unref") MEDCouplingPointSet "$this->decrRef();" %feature("unref") MEDCouplingMesh "$this->decrRef();" @@ -319,6 +328,8 @@ using namespace INTERP_KERNEL; %feature("unref") MEDCoupling1DGTUMesh "$this->decrRef();" %feature("unref") MEDCouplingExtrudedMesh "$this->decrRef();" %feature("unref") MEDCouplingCMesh "$this->decrRef();" +%feature("unref") MEDCouplingIMesh "$this->decrRef();" +%feature("unref") MEDCouplingCurveLinearMesh "$this->decrRef();" %feature("unref") MEDCouplingField "$this->decrRef();" %feature("unref") MEDCouplingFieldDiscretizationP0 "$this->decrRef();" %feature("unref") MEDCouplingFieldDiscretizationP1 "$this->decrRef();" @@ -329,6 +340,8 @@ using namespace INTERP_KERNEL; %feature("unref") MEDCouplingMultiFields "$this->decrRef();" %feature("unref") MEDCouplingFieldTemplate "$this->decrRef();" %feature("unref") MEDCouplingMultiFields "$this->decrRef();" +%feature("unref") MEDCouplingAHOGMesh "$this->decrRef();" +%feature("unref") MEDCouplingAHOGPatch "$this->decrRef();" %rename(assign) *::operator=; %ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo; @@ -369,7 +382,8 @@ namespace ParaMEDMEM EXTRUDED = 8, CURVE_LINEAR = 9, SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED = 10, - SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED = 11 + SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED = 11, + IMAGE_GRID = 12 } MEDCouplingMeshType; class DataArrayInt; @@ -2754,6 +2768,7 @@ namespace ParaMEDMEM MEDCoupling1SGTUMesh *build1SGTUnstructured() const throw(INTERP_KERNEL::Exception); static INTERP_KERNEL::NormalizedCellType GetGeoTypeGivenMeshDimension(int meshDim) throw(INTERP_KERNEL::Exception); MEDCoupling1SGTUMesh *build1SGTSubLevelMesh() const throw(INTERP_KERNEL::Exception); + static int DeduceNumberOfGivenStructure(const std::vector& st) throw(INTERP_KERNEL::Exception); %extend { virtual MEDCouplingStructuredMesh *buildStructuredSubPart(PyObject *cellPart) const throw(INTERP_KERNEL::Exception) @@ -2782,25 +2797,8 @@ namespace ParaMEDMEM static DataArrayInt *BuildExplicitIdsFrom(PyObject *st, PyObject *part) throw(INTERP_KERNEL::Exception) { - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListInt2(part,tmpp1,tmpp2); std::vector< std::pair > inp; - if(tmpp2==2) - { - inp.resize(tmpp1); - for(int i=0;i stdvecTyyppArr; @@ -2812,25 +2810,8 @@ namespace ParaMEDMEM static int DeduceNumberOfGivenRangeInCompactFrmt(PyObject *part) throw(INTERP_KERNEL::Exception) { - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListInt2(part,tmpp1,tmpp2); std::vector< std::pair > inp; - if(tmpp2==2) - { - inp.resize(tmpp1); - for(int i=0;i >& ret(self->getBLTRRange()); + return convertFromVectorPairInt(ret); + } + + const MEDCouplingAHOGMesh *getMesh() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingAHOGMesh *ret(const_cast(self->getMesh())); + if(ret) + ret->incrRef(); + return ret; + } + + void addPatch(PyObject *bottomLeftTopRight, int factor) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair > inp; + convertPyToVectorPairInt(bottomLeftTopRight,inp); + self->addPatch(inp,factor); + } + + MEDCouplingAHOGPatch *__getitem__(int patchId) const throw(INTERP_KERNEL::Exception) + { + const MEDCouplingAHOGMesh *mesh(self->getMesh()); + if(!mesh) + throw INTERP_KERNEL::Exception("wrap MEDCouplingAHOGPatch.__getitem__ : no underlying mesh !"); + if(patchId==mesh->getNumberOfPatches()) + { + std::ostringstream oss; + oss << "Requesting for patchId " << patchId << " having only " << mesh->getNumberOfPatches() << " patches !"; + PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); + return 0; + } + MEDCouplingAHOGPatch *ret(const_cast(mesh->getPatch(patchId))); + if(ret) + ret->incrRef(); + return ret; + } + + int __len__() const throw(INTERP_KERNEL::Exception) + { + const MEDCouplingAHOGMesh *mesh(self->getMesh()); + if(!mesh) + throw INTERP_KERNEL::Exception("wrap MEDCouplingAHOGPatch.__len__ : no underlying mesh !"); + return mesh->getNumberOfPatches(); + } + } + }; + + class MEDCouplingAHOGMesh : public RefCountObject, public TimeLabel + { + public: + + int getSpaceDimension() const throw(INTERP_KERNEL::Exception); + int getMaxNumberOfLevelsRelativeToThis() const throw(INTERP_KERNEL::Exception); + int getNumberOfCellsAtCurrentLevel() const throw(INTERP_KERNEL::Exception); + int getNumberOfCellsRecursiveWithOverlap() const throw(INTERP_KERNEL::Exception); + int getNumberOfCellsRecursiveWithoutOverlap() const throw(INTERP_KERNEL::Exception); + // + int getNumberOfPatches() const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); + %extend + { + static MEDCouplingAHOGMesh *New(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) + { + static const char msg0[]="MEDCouplingAHOGMesh::New : error on 'origin' parameter !"; + static const char msg1[]="MEDCouplingAHOGMesh::New : error on 'dxyz' parameter !"; + const int *nodeStrctPtr(0); + const double *originPtr(0),*dxyzPtr(0); + int sw,sz,val0; + std::vector bb0; + nodeStrctPtr=convertObjToPossibleCpp1_Safe(nodeStrct,sw,sz,val0,bb0); + // + double val,val2; + std::vector bb,bb2; + int sz1,sz2; + originPtr=convertObjToPossibleCpp5_SingleCompo(origin,sw,val,bb,msg0,false,sz1); + dxyzPtr=convertObjToPossibleCpp5_SingleCompo(dxyz,sw,val2,bb2,msg1,false,sz2); + // + return MEDCouplingAHOGMesh::New(meshName,spaceDim,nodeStrctPtr,nodeStrctPtr+sz,originPtr,originPtr+sz1,dxyzPtr,dxyzPtr+sz2); + } + + MEDCouplingAHOGMesh(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_MEDCouplingAHOGMesh_New(meshName,spaceDim,nodeStrct,origin,dxyz); + } + + void addPatch(PyObject *bottomLeftTopRight, int factor) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair > inp; + convertPyToVectorPairInt(bottomLeftTopRight,inp); + self->addPatch(inp,factor); + } + + MEDCouplingAHOGMesh *getFather() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingAHOGMesh *ret(const_cast(self->getFather())); + if(ret) + ret->incrRef(); + return ret; + } + + MEDCouplingAHOGMesh *getGodFather() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingAHOGMesh *ret(const_cast(self->getGodFather())); + if(ret) + ret->incrRef(); + return ret; + } + + MEDCouplingAHOGPatch *getPatch(int patchId) const throw(INTERP_KERNEL::Exception) + { + MEDCouplingAHOGPatch *ret(const_cast(self->getPatch(patchId))); + if(ret) + ret->incrRef(); + return ret; + } + + MEDCouplingAHOGPatch *__getitem__(int patchId) const throw(INTERP_KERNEL::Exception) + { + if(patchId==self->getNumberOfPatches()) + { + std::ostringstream oss; + oss << "Requesting for patchId " << patchId << " having only " << self->getNumberOfPatches() << " patches !"; + PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); + return 0; + } + MEDCouplingAHOGPatch *ret(const_cast(self->getPatch(patchId))); + if(ret) + ret->incrRef(); + return ret; + } + + int __len__() const throw(INTERP_KERNEL::Exception) + { + return self->getNumberOfPatches(); + } + } + }; } %pythoncode %{ diff --git a/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i b/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i index 01df00d9c..5eb5af871 100644 --- a/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i +++ b/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i @@ -624,6 +624,19 @@ static int *convertPyToNewIntArr2(PyObject *pyLi, int *size) throw(INTERP_KERNEL } } +static PyObject *convertFromVectorPairInt(const std::vector< std::pair >& arr) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=PyList_New(arr.size()); + for(std::size_t i=0;i >& arr) throw(INTERP_KERNEL::Exception) { const char msg[]="list must contain tuples of 2 integers only or tuple must contain tuples of 2 integers only !";