From a9d2df5328a4229fc63cb871686919c82af03618 Mon Sep 17 00:00:00 2001 From: geay Date: Fri, 23 May 2014 18:48:05 +0200 Subject: [PATCH] Spread and condense on cell fields on images meshes with ghost management in 1D and 2D. --- .../MEDCouplingCartesianAMRMesh.cxx | 132 ++++++++-- .../MEDCouplingCartesianAMRMesh.hxx | 13 +- src/MEDCoupling/MEDCouplingIMesh.cxx | 247 +++++++++++++++++- src/MEDCoupling/MEDCouplingIMesh.hxx | 5 +- src/MEDCoupling/MEDCouplingMemArray.cxx | 31 +++ src/MEDCoupling/MEDCouplingMemArray.hxx | 1 + src/MEDCoupling_Swig/MEDCouplingBasicsTest.py | 44 +++- src/MEDCoupling_Swig/MEDCouplingCommon.i | 27 +- .../MEDCouplingRemapperTest.py | 2 +- 9 files changed, 466 insertions(+), 36 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx index 9436290c9..fd2fde384 100644 --- a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx @@ -35,9 +35,8 @@ using namespace ParaMEDMEM; * \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 >& bottomLeftTopRight, const std::vector& factors) +MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMesh *mesh, const std::vector< std::pair >& bottomLeftTopRight) { if(!mesh) throw INTERP_KERNEL::Exception("EDCouplingCartesianAMRPatch constructor : input mesh is NULL !"); @@ -46,9 +45,6 @@ MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(MEDCouplingCartesianA 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 @@ -105,6 +101,22 @@ int MEDCouplingCartesianAMRMesh::getSpaceDimension() const return _mesh->getSpaceDimension(); } +void MEDCouplingCartesianAMRMesh::setFactors(const std::vector& newFactors) +{ + if(getSpaceDimension()!=(int)newFactors.size()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::setFactors : size of input factors is not equal to the space dimension !"); + if(_factors.empty()) + { + _factors=newFactors; + return ; + } + if(_factors==newFactors) + return ; + if(!_patches.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::setFactors : modification of factors is not allowed when presence of patches !"); + _factors=newFactors; +} + int MEDCouplingCartesianAMRMesh::getMaxNumberOfLevelsRelativeToThis() const { int ret(1); @@ -160,14 +172,15 @@ void MEDCouplingCartesianAMRMesh::detachFromFather() /*! * \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 != 0 factor of refinement per axis. + * \param [in] factors The factor of refinement per axis (different from 0). */ void MEDCouplingCartesianAMRMesh::addPatch(const std::vector< std::pair >& bottomLeftTopRight, const std::vector& factors) { + checkFactorsAndIfNotSetAssign(factors); MEDCouplingAutoRefCountObjectPtr mesh(static_cast(_mesh->buildStructuredSubPart(bottomLeftTopRight))); mesh->refineWithFactor(factors); MEDCouplingAutoRefCountObjectPtr zeMesh(new MEDCouplingCartesianAMRMesh(this,mesh)); - MEDCouplingAutoRefCountObjectPtr elt(new MEDCouplingCartesianAMRPatch(zeMesh,bottomLeftTopRight,factors)); + MEDCouplingAutoRefCountObjectPtr elt(new MEDCouplingCartesianAMRPatch(zeMesh,bottomLeftTopRight)); _patches.push_back(elt); } @@ -330,7 +343,7 @@ void FindInflection(const INTERP_KERNEL::BoxSplittingOptions& bso, const Interna // Gradient absolute value for ( unsigned int i=1;i si empty le reste plante ! + if(derivate_second_order.empty()) continue; for (unsigned int i=0;i& factors) +void MEDCouplingCartesianAMRMesh::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const std::vector& criterion, const std::vector& 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()) + if(nbCells!=(int)criterion.size()) 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 cgs(_mesh->getCellGridStructure()); - std::vector crit(criterion->toVectorOfBool());//check that criterion has one component. std::vector< MEDCouplingAutoRefCountObjectPtr > listOfPatches,listOfPatchesOK; // MEDCouplingAutoRefCountObjectPtr p(new InternalPatch); - p->setNumberOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(cgs,crit,p->getCriterion(),p->getPart())); + p->setNumberOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(cgs,criterion,p->getCriterion(),p->getPart())); if(p->presenceOfTrue()) listOfPatches.push_back(p); while(!listOfPatches.empty()) @@ -489,6 +498,23 @@ void MEDCouplingCartesianAMRMesh::createPatchesFromCriterion(const INTERP_KERNEL addPatch((*it)->getConstPart(),factors); } +/*! + * 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. + */ +void MEDCouplingCartesianAMRMesh::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector& factors) +{ + if(!criterion || !criterion->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterion : the criterion DataArrayByte instance must be allocated and not NULL !"); + std::vector crit(criterion->toVectorOfBool());//check that criterion has one component. + createPatchesFromCriterion(bso,crit,factors); +} + +void MEDCouplingCartesianAMRMesh::removeAllPatches() +{ + _patches.clear(); + declareAsNew(); +} + void MEDCouplingCartesianAMRMesh::removePatch(int patchId) { checkPatchId(patchId); @@ -513,6 +539,67 @@ const MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRMesh::getPatch(int pa return _patches[patchId]; } +/*! + * 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. + * 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 + * defined by the patch with id \a patchId. + * + * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. + * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. + * \return DataArrayDouble * - The array of the cell field on the requested patch + * + * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() ) + * \throw if \a cellFieldOnThis is NULL or not allocated + * \sa fillCellFieldOnPatch, MEDCouplingIMesh::SpreadCoarseToFine + */ +DataArrayDouble *MEDCouplingCartesianAMRMesh::createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const +{ + if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !"); + const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); + const MEDCouplingIMesh *fine(patch->getMesh()->getImageMesh()); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(fine->getNumberOfCells(),cellFieldOnThis->getNumberOfComponents()); + ret->copyStringInfoFrom(*cellFieldOnThis); + MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),ret,patch->getBLTRRange(),getFactors()); + return ret.retn(); +} + +/*! + * This method is equivalent to MEDCouplingCartesianAMRMesh::createCellFieldOnPatch except that here instead of + * + * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. + * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. + * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled. + * + * \sa createCellFieldOnPatch, fillCellFieldComingFromPatch + */ +void MEDCouplingCartesianAMRMesh::fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch) const +{ + if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !"); + const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); + MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors()); +} + +/*! + * This method updates \a cellFieldOnThis part of values coming from the cell field \a cellFieldOnPatch lying on patch having id \a patchId. + * + * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. + * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId. + * \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. + * + * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() ) + * \throw if \a cellFieldOnPatch is NULL or not allocated + * \sa createCellFieldOnPatch, MEDCouplingIMesh::CondenseFineToCoarse + */ +void MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const +{ + if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch : the input cell field array is NULL or not allocated !"); + const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); + MEDCouplingIMesh::CondenseFineToCoarse(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis); +} + MEDCouplingUMesh *MEDCouplingCartesianAMRMesh::buildUnstructured() const { MEDCouplingAutoRefCountObjectPtr part(_mesh->buildUnstructured()); @@ -582,6 +669,21 @@ void MEDCouplingCartesianAMRMesh::checkPatchId(int patchId) const } } +void MEDCouplingCartesianAMRMesh::checkFactorsAndIfNotSetAssign(const std::vector& factors) +{ + if(getSpaceDimension()!=(int)factors.size()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::checkFactorsAndIfNotSetAssign : invalid size of factors ! size must be equal to the spaceDimension !"); + if(_factors.empty()) + { + _factors=factors; + } + else + { + if(_factors!=factors) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::checkFactorsAndIfNotSetAssign : the factors "); + } +} + std::size_t MEDCouplingCartesianAMRMesh::getHeapMemorySizeWithoutChildren() const { return sizeof(MEDCouplingCartesianAMRMesh); diff --git a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx index d0ab4a421..bfade9b4f 100644 --- a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx +++ b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx @@ -34,6 +34,7 @@ namespace ParaMEDMEM class MEDCouplingIMesh; class MEDCouplingUMesh; class DataArrayByte; + class DataArrayDouble; class MEDCoupling1SGTUMesh; class MEDCouplingCartesianAMRMesh; @@ -41,7 +42,7 @@ namespace ParaMEDMEM class MEDCouplingCartesianAMRPatch : public RefCountObject { public: - MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMesh *mesh, const std::vector< std::pair >& bottomLeftTopRight, const std::vector& factors); + MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMesh *mesh, const std::vector< std::pair >& bottomLeftTopRight); // direct forward to _mesh MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithOverlap() const; MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithoutOverlap() const; @@ -58,7 +59,6 @@ namespace ParaMEDMEM private: //! bottom left/top right cell range relative to \a _father std::vector< std::pair > _bl_tr; - std::vector _factors; MEDCouplingAutoRefCountObjectPtr _mesh; }; /// @endcond @@ -74,6 +74,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static MEDCouplingCartesianAMRMesh *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 const std::vector& getFactors() const { return _factors; } + MEDCOUPLING_EXPORT void setFactors(const std::vector& newFactors); MEDCOUPLING_EXPORT int getMaxNumberOfLevelsRelativeToThis() const; MEDCOUPLING_EXPORT int getNumberOfCellsAtCurrentLevel() const; MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithOverlap() const; @@ -84,10 +86,15 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMesh *getGodFather() const; MEDCOUPLING_EXPORT void detachFromFather(); MEDCOUPLING_EXPORT void addPatch(const std::vector< std::pair >& bottomLeftTopRight, const std::vector& factors); + MEDCOUPLING_EXPORT void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const std::vector& criterion, const std::vector& factors); MEDCOUPLING_EXPORT void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector& factors); + MEDCOUPLING_EXPORT void removeAllPatches(); MEDCOUPLING_EXPORT void removePatch(int patchId); MEDCOUPLING_EXPORT int getNumberOfPatches() const; MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRPatch *getPatch(int patchId) const; + MEDCOUPLING_EXPORT DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const; + MEDCOUPLING_EXPORT void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch) const; + MEDCOUPLING_EXPORT void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const; // MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *buildMeshFromPatchEnvelop() const; @@ -96,6 +103,7 @@ namespace ParaMEDMEM const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); MEDCouplingCartesianAMRMesh(MEDCouplingCartesianAMRMesh *father, MEDCouplingIMesh *mesh); void checkPatchId(int patchId) const; + void checkFactorsAndIfNotSetAssign(const std::vector& factors); protected: MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; MEDCOUPLING_EXPORT std::vector getDirectChildren() const; @@ -104,6 +112,7 @@ namespace ParaMEDMEM MEDCouplingCartesianAMRMesh *_father; MEDCouplingAutoRefCountObjectPtr _mesh; std::vector< MEDCouplingAutoRefCountObjectPtr > _patches; + std::vector _factors; }; } diff --git a/src/MEDCoupling/MEDCouplingIMesh.cxx b/src/MEDCoupling/MEDCouplingIMesh.cxx index 4b3da324a..30458429b 100644 --- a/src/MEDCoupling/MEDCouplingIMesh.cxx +++ b/src/MEDCoupling/MEDCouplingIMesh.cxx @@ -75,6 +75,33 @@ MEDCouplingIMesh *MEDCouplingIMesh::clone(bool recDeepCpy) const return new MEDCouplingIMesh(*this,recDeepCpy); } +/*! + * This method creates a copy of \a this enlarged by \a ghostLev cells on each axis. + * If \a ghostLev equal to 0 this method behaves as MEDCouplingIMesh::clone. + * + * \param [in] ghostLev - the ghost level expected + * \return MEDCouplingIMesh * - a newly alloacted object to be managed by the caller. + * \throw if \a ghostLev < 0. + */ +MEDCouplingIMesh *MEDCouplingIMesh::buildWithGhost(int ghostLev) const +{ + if(ghostLev<0) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::buildWithGhost : the ghostLev must be >= 0 !"); + checkCoherency(); + int spaceDim(getSpaceDimension()); + double origin[3],dxyz[3]; + int structure[3]; + for(int i=0;i ret(MEDCouplingIMesh::New(getName(),spaceDim,structure,structure+spaceDim,origin,origin+spaceDim,dxyz,dxyz+spaceDim)); + ret->copyTinyInfoFrom(this); + return ret.retn(); +} + void MEDCouplingIMesh::setNodeStruct(const int *nodeStrctStart, const int *nodeStrctStop) { checkSpaceDimension(); @@ -241,14 +268,15 @@ MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged. * - * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. * \param [in] coarseSt The cell structure of coarse mesh. * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. * \param [in] facts The refinement coefficient per axis. - * \sa SpreadCoarseToFine + * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. + * + * \sa CondenseFineToCoarseGhost,SpreadCoarseToFine */ -void MEDCouplingIMesh::CondenseFineToCoarse(DataArrayDouble *coarseDA, const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts) +void MEDCouplingIMesh::CondenseFineToCoarse(const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA) { if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the parameters 1 or 3 are NULL or not allocated !"); @@ -352,6 +380,102 @@ void MEDCouplingIMesh::CondenseFineToCoarse(DataArrayDouble *coarseDA, const std } } +/*! + * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example) + * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh + * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged. + * + * \param [in] coarseSt The cell structure of coarse mesh. + * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh + * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. + * \param [in] facts The refinement coefficient per axis. + * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. + * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes. + * + * \sa CondenseFineToCoarse,SpreadCoarseToFineGhost + */ +void MEDCouplingIMesh::CondenseFineToCoarseGhost(const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA, int ghostSize) +{ + if(ghostSize<0) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : ghost level >= 0 !"); + if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the parameters 1 or 3 are NULL or not allocated !"); + std::vector coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); + //std::vector fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + //std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); + int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG)); + int nbCompo(fineDA->getNumberOfComponents()); + if(coarseDA->getNumberOfComponents()!=nbCompo) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the number of components of fine DA and coarse one mismatches !"); + if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); + if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + //int nbTuplesFine(fineDA->getNumberOfTuples()); + //int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies())); + /*if(nbTuplesFine!=fact*nbOfTuplesInFineExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + }*/ + double *outPtr(coarseDA->getPointer()); + const double *inPtr(fineDA->begin()); + // + std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + switch(meshDim) + { + case 1: + { + int offset(fineLocInCoarse[0].first+ghostSize),fact0(facts[0]); + inPtr+=ghostSize*nbCompo; + for(int i=0;i()); + else + std::copy(inPtr,inPtr+nbCompo,loc); + } + } + break; + } + case 2: + { + int nxwg(coarseSt[0]+2*ghostSize); + int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)),fact1(facts[1]),fact0(facts[0]); + inPtr+=(dims[0]*fact0+2*ghostSize)*nbCompo; + for(int j=0;j()); + else + std::copy(inPtr,inPtr+nbCompo,loc); + } + } + inPtr+=ghostSize*nbCompo; + } + kk+=nxwg; + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : only dimensions 1, 2 supported !"); + } +} + /*! * This method spreads the values of coarse data \a coarseDA into \a fineDA. * @@ -360,7 +484,7 @@ void MEDCouplingIMesh::CondenseFineToCoarse(DataArrayDouble *coarseDA, const std * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. * \param [in] facts The refinement coefficient per axis. - * \sa CondenseFineToCoarse + * \sa SpreadCoarseToFineGhost, CondenseFineToCoarse */ void MEDCouplingIMesh::SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts) { @@ -451,6 +575,121 @@ void MEDCouplingIMesh::SpreadCoarseToFine(const DataArrayDouble *coarseDA, const } } +/*! + * This method spreads the values of coarse data \a coarseDA into \a fineDA. + * + * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. + * \param [in] coarseSt The cell structure of coarse mesh. + * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh + * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. + * \param [in] facts The refinement coefficient per axis. + * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes. + * \sa CondenseFineToCoarse + */ +void MEDCouplingIMesh::SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize) +{ + if(ghostSize<0) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level >= 0 !"); + if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the parameters 1 or 3 are NULL or not allocated !"); + std::vector coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); + //std::vector fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); + int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG)); + int nbCompo(fineDA->getNumberOfComponents()); + if(coarseDA->getNumberOfComponents()!=nbCompo) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the number of components of fine DA and coarse one mismatches !"); + if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); + if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + /*int nbTuplesFine(fineDA->getNumberOfTuples()); + if(nbTuplesFine%nbOfTuplesInFineExp!=0) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : Invalid nb of tuples in fine DataArray regarding its structure !"); + int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies())); + if(nbTuplesFine!=fact*nbOfTuplesInFineExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + }*/ + // + double *outPtr(fineDA->getPointer()); + const double *inPtr(coarseDA->begin()); + // + std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + switch(meshDim) + { + case 1: + { + int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 ! + for(int i=0;i=0 thanks to the fact that ghostSize>=1 ! + for(int jg=0;jg& factors); MEDCOUPLING_EXPORT MEDCouplingIMesh *asSingleCell() const; - MEDCOUPLING_EXPORT static void CondenseFineToCoarse(DataArrayDouble *coarseDA, const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts); + MEDCOUPLING_EXPORT static void CondenseFineToCoarse(const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA); + MEDCOUPLING_EXPORT static void CondenseFineToCoarseGhost(const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA, int ghostSize); MEDCOUPLING_EXPORT static void SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts); + MEDCOUPLING_EXPORT static void SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize); // MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; MEDCOUPLING_EXPORT MEDCouplingIMesh *clone(bool recDeepCpy) const; + MEDCOUPLING_EXPORT MEDCouplingIMesh *buildWithGhost(int ghostLev) const; MEDCOUPLING_EXPORT void updateTime() const; MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; MEDCOUPLING_EXPORT std::vector getDirectChildren() const; diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index e2ccfd8ea..44a708d7c 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -5584,6 +5584,37 @@ void DataArrayDouble::powEqual(const DataArrayDouble *other) declareAsNew(); } +/*! + * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context. + * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true. + * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown. + * + * \throw if \a this is not allocated. + * \throw if \a this has not exactly one component. + */ +std::vector DataArrayDouble::toVectorOfBool(double eps) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !"); + int nbt(getNumberOfTuples()); + std::vector ret(nbt); + const double *pt(begin()); + for(int i=0;i& accessToMemArray() { return _mem; } MEDCOUPLING_EXPORT const MemArray& accessToMemArray() const { return _mem; } + MEDCOUPLING_EXPORT std::vector toVectorOfBool(double eps) const; public: MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector& tinyInfo) const; diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 3a0d610bb..f96bc4d48 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -14953,26 +14953,26 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(1,amr.getNumberOfPatches()) self.assertEqual(2,amr.getMaxNumberOfLevelsRelativeToThis()) self.assertEqual(2,amr.getSpaceDimension()) - amr[0].addPatch([(2,3),(1,3)],[2,2]) + amr[0].addPatch([(2,3),(1,3)],[3,2]) self.assertEqual(amr[0].getBLTRRange(),[(1,2),(0,1)]) self.assertEqual(4,amr.getNumberOfCellsAtCurrentLevel()) - self.assertEqual(28,amr.getNumberOfCellsRecursiveWithOverlap()) - self.assertEqual(25,amr.getNumberOfCellsRecursiveWithoutOverlap()) + self.assertEqual(32,amr.getNumberOfCellsRecursiveWithOverlap()) + self.assertEqual(29,amr.getNumberOfCellsRecursiveWithoutOverlap()) self.assertEqual(1,amr.getNumberOfPatches()) self.assertEqual(3,amr.getMaxNumberOfLevelsRelativeToThis()) self.assertEqual(2,amr.getSpaceDimension()) - amr[0].addPatch([(0,2),(3,4)],[3,3]) + amr[0].addPatch([(0,2),(3,4)],[3,2]) self.assertEqual(16,amr[0].getMesh().getNumberOfCellsAtCurrentLevel()) - self.assertEqual(46,amr.getNumberOfCellsRecursiveWithOverlap()) - self.assertEqual(41,amr.getNumberOfCellsRecursiveWithoutOverlap()) + self.assertEqual(44,amr.getNumberOfCellsRecursiveWithOverlap()) + self.assertEqual(39,amr.getNumberOfCellsRecursiveWithoutOverlap()) self.assertEqual(2,amr[0].getMesh().getNumberOfPatches()) self.assertEqual(3,amr.getMaxNumberOfLevelsRelativeToThis()) self.assertEqual(2,amr.getSpaceDimension()) del amr[0][1] self.assertEqual(amr[0].getBLTRRange(),[(1,2),(0,1)]) self.assertEqual(4,amr.getNumberOfCellsAtCurrentLevel()) - self.assertEqual(28,amr.getNumberOfCellsRecursiveWithOverlap()) - self.assertEqual(25,amr.getNumberOfCellsRecursiveWithoutOverlap()) + self.assertEqual(32,amr.getNumberOfCellsRecursiveWithOverlap()) + self.assertEqual(29,amr.getNumberOfCellsRecursiveWithoutOverlap()) self.assertEqual(1,amr.getNumberOfPatches()) self.assertEqual(3,amr.getMaxNumberOfLevelsRelativeToThis()) self.assertEqual(2,amr.getSpaceDimension()) @@ -15080,17 +15080,17 @@ class MEDCouplingBasicsTest(unittest.TestCase): """ Test condensation of fine IMesh instance into a coarse one, with a factor. See testRemapperAMR1 in MEDCouplingRemapperTest.py file to see how the expected value is obtained.""" coarse=DataArrayDouble(35) ; coarse.iota(0) #X=5,Y=7 fine=DataArrayDouble(3*2*4*4) ; fine.iota(0) #X=3,Y=2 refined by 4 - MEDCouplingIMesh.CondenseFineToCoarse(coarse,[5,7],fine,[(1,4),(2,4)],[4,4]) + MEDCouplingIMesh.CondenseFineToCoarse([5,7],fine,[(1,4),(2,4)],[4,4],coarse) self.assertTrue(coarse.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,312,376,440,14,15,1080,1144,1208,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34]),1e-12)) # 3D coarse=DataArrayDouble(175) ; coarse.iota(0) #X=5,Y=7,Z=5 fine=DataArrayDouble(3*2*3*4*4*4) ; fine.iota(0) #X=3,Y=2,Z=3 refined by 4 - MEDCouplingIMesh.CondenseFineToCoarse(coarse,[5,7,5],fine,[(1,4),(2,4),(1,4)],[4,4,4]) + MEDCouplingIMesh.CondenseFineToCoarse([5,7,5],fine,[(1,4),(2,4),(1,4)],[4,4,4],coarse) self.assertTrue(coarse.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,10464.,10720.,10976.,49.,50.,13536.,13792.,14048.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.,64.,65.,66.,67.,68.,69.,70.,71.,72.,73.,74.,75.,76.,77.,78.,79.,80.,35040.,35296.,35552.,84.,85.,38112.,38368.,38624.,89.,90.,91.,92.,93.,94.,95.,96.,97.,98.,99.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.,111.,112.,113.,114.,115.,59616.,59872.,60128.,119.,120.,62688.,62944.,63200.,124.,125.,126.,127.,128.,129.,130.,131.,132.,133.,134.,135.,136.,137.,138.,139.,140.,141.,142.,143.,144.,145.,146.,147.,148.,149.,150.,151.,152.,153.,154.,155.,156.,157.,158.,159.,160.,161.,162.,163.,164.,165.,166.,167.,168.,169.,170.,171.,172.,173.,174.]),1e-12)) # 1D coarse=DataArrayDouble(5) ; coarse.iota(0) #X=5 fine=DataArrayDouble(3*4) ; fine.iota(0) #X=3 refined by 4 - MEDCouplingIMesh.CondenseFineToCoarse(coarse,[5],fine,[(1,4)],[4]) + MEDCouplingIMesh.CondenseFineToCoarse([5],fine,[(1,4)],[4],coarse) self.assertTrue(coarse.isEqual(DataArrayDouble([0,6,22,38,4]),1e-12)) pass @@ -15142,6 +15142,28 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertTrue(m.getCoords().isEqualWithoutConsideringStr(DataArrayDouble([(0,0),(2,0),(0,2),(2,2)]),1e-12)) pass + def testAMR5(self): + """ Idem testAMR3, test spread of coarse IMesh instance into a fine one, with a factor, but here ghost is used !""" + # 1D + coarse=DataArrayDouble(5+2) ; coarse.iota(-1) #X=5 with ghostLev=1 + fine=DataArrayDouble(3*4+2) ; fine.iota(1000) #X=3 refined by 4 with ghostLev=1 + MEDCouplingIMesh.SpreadCoarseToFineGhost(coarse,[5],fine,[(1,4)],[4],1) + self.assertTrue(fine.isEqual(DataArrayDouble([0,1,1,1,1,2,2,2,2,3,3,3,3,4]),1e-12)) + coarse.iota(-1000) + MEDCouplingIMesh.CondenseFineToCoarseGhost([5],fine,[(1,4)],[4],coarse,1) + self.assertTrue(coarse.isEqual(DataArrayDouble([-1000.,-999.,4.,8.,12.,-995.,-994.]),1e-12)) + # 2D + coarse=DataArrayDouble((5+2*1)*(7+2*1)) ; coarse.iota(0) #X=5,Y=7 with ghostLev=1 + fine=DataArrayDouble((3*4+2*1)*(2*4+2*1)) ; fine.iota(1000) #X=3,Y=2 refined by 4 + MEDCouplingIMesh.SpreadCoarseToFineGhost(coarse,[5,7],fine,[(1,4),(2,4)],[4,4],1) + self.assertTrue(fine.isEqual(DataArrayDouble([15.,16.,16.,16.,16.,17.,17.,17.,17.,18.,18.,18.,18.,19.,22.,23.,23.,23.,23.,24.,24.,24.,24.,25.,25.,25.,25.,26.,22.,23.,23.,23.,23.,24.,24.,24.,24.,25.,25.,25.,25.,26.,22.,23.,23.,23.,23.,24.,24.,24.,24.,25.,25.,25.,25.,26.,22.,23.,23.,23.,23.,24.,24.,24.,24.,25.,25.,25.,25.,26.,29.,30.,30.,30.,30.,31.,31.,31.,31.,32.,32.,32.,32.,33.,29.,30.,30.,30.,30.,31.,31.,31.,31.,32.,32.,32.,32.,33.,29.,30.,30.,30.,30.,31.,31.,31.,31.,32.,32.,32.,32.,33.,29.,30.,30.,30.,30.,31.,31.,31.,31.,32.,32.,32.,32.,33.,36.,37.,37.,37.,37.,38.,38.,38.,38.,39.,39.,39.,39.,40.]),1e-12)) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(MEDCouplingIMesh("",2,DataArrayInt([8,10]),[0.,0.],DataArrayDouble((1.,1.)))) ; f.setArray(coarse) ; f.setName("tutu") ; f.checkCoherency() ; f.writeVTK("coarse.vti") + coarse.iota(-1000) + MEDCouplingIMesh.CondenseFineToCoarseGhost([5,7],fine,[(1,4),(2,4)],[4,4],coarse,1) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(MEDCouplingIMesh("",2,DataArrayInt([8,10]),[0.,0.],DataArrayDouble((1.,1.)))) ; f.setArray(coarse) ; f.setName("tutu") ; f.checkCoherency() ; f.writeVTK("coarse.vti") + self.assertTrue(coarse.isEqual(DataArrayDouble([-1000.,-999.,-998.,-997.,-996.,-995.,-994.,-993.,-992.,-991.,-990.,-989.,-988.,-987.,-986.,-985.,-984.,-983.,-982.,-981.,-980.,-979.,-978.,368.,384.,400.,-974.,-973.,-972.,-971.,480.,496.,512.,-967.,-966.,-965.,-964.,-963.,-962.,-961.,-960.,-959.,-958.,-957.,-956.,-955.,-954.,-953.,-952.,-951.,-950.,-949.,-948.,-947.,-946.,-945.,-944.,-943.,-942.,-941.,-940.,-939.,-938.]),1e-12)) + pass + def setUp(self): pass pass diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index cc6307736..a6bc608f4 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -307,6 +307,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingCMesh::getCoordsAt; %newobject ParaMEDMEM::MEDCouplingIMesh::New; %newobject ParaMEDMEM::MEDCouplingIMesh::asSingleCell; +%newobject ParaMEDMEM::MEDCouplingIMesh::buildWithGhost; %newobject ParaMEDMEM::MEDCouplingIMesh::convertToCartesian; %newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::New; %newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::clone; @@ -323,6 +324,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::getGodFather; %newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::getFather; %newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::getPatch; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::createCellFieldOnPatch; %newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::__getitem__; %newobject ParaMEDMEM::DenseMatrix::New; %newobject ParaMEDMEM::DenseMatrix::deepCpy; @@ -3065,6 +3067,7 @@ namespace ParaMEDMEM MEDCouplingCMesh *convertToCartesian() const throw(INTERP_KERNEL::Exception); void refineWithFactor(const std::vector& factors) throw(INTERP_KERNEL::Exception); MEDCouplingIMesh *asSingleCell() const throw(INTERP_KERNEL::Exception); + MEDCouplingIMesh *buildWithGhost(int ghostLev) const throw(INTERP_KERNEL::Exception); %extend { MEDCouplingIMesh() @@ -3127,11 +3130,18 @@ namespace ParaMEDMEM self->setDXYZ(originPtr,originPtr+nbTuples); } - static void CondenseFineToCoarse(DataArrayDouble *coarseDA, const std::vector& coarseSt, const DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts) throw(INTERP_KERNEL::Exception) + static void CondenseFineToCoarse(const std::vector& coarseSt, const DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA) throw(INTERP_KERNEL::Exception) { std::vector< std::pair > inp; convertPyToVectorPairInt(fineLocInCoarse,inp); - MEDCouplingIMesh::CondenseFineToCoarse(coarseDA,coarseSt,fineDA,inp,facts); + MEDCouplingIMesh::CondenseFineToCoarse(coarseSt,fineDA,inp,facts,coarseDA); + } + + static void CondenseFineToCoarseGhost(const std::vector& coarseSt, const DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA, int ghostSize) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair > inp; + convertPyToVectorPairInt(fineLocInCoarse,inp); + MEDCouplingIMesh::CondenseFineToCoarseGhost(coarseSt,fineDA,inp,facts,coarseDA,ghostSize); } static void SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts) throw(INTERP_KERNEL::Exception) @@ -3141,6 +3151,13 @@ namespace ParaMEDMEM MEDCouplingIMesh::SpreadCoarseToFine(coarseDA,coarseSt,fineDA,inp,facts); } + static void SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts, int ghostSize) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair > inp; + convertPyToVectorPairInt(fineLocInCoarse,inp); + MEDCouplingIMesh::SpreadCoarseToFineGhost(coarseDA,coarseSt,fineDA,inp,facts,ghostSize); + } + std::string __str__() const throw(INTERP_KERNEL::Exception) { return self->simpleRepr(); @@ -4750,6 +4767,8 @@ namespace ParaMEDMEM public: int getSpaceDimension() const throw(INTERP_KERNEL::Exception); + const std::vector& getFactors() const throw(INTERP_KERNEL::Exception); + void setFactors(const std::vector& newFactors) 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); @@ -4758,9 +4777,13 @@ namespace ParaMEDMEM int getNumberOfPatches() const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); MEDCoupling1SGTUMesh *buildMeshFromPatchEnvelop() const throw(INTERP_KERNEL::Exception); + void removeAllPatches() throw(INTERP_KERNEL::Exception); void removePatch(int patchId) throw(INTERP_KERNEL::Exception); void detachFromFather() throw(INTERP_KERNEL::Exception); void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector& factors) throw(INTERP_KERNEL::Exception); + DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const throw(INTERP_KERNEL::Exception); + void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch) const throw(INTERP_KERNEL::Exception); + void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const throw(INTERP_KERNEL::Exception); %extend { static MEDCouplingCartesianAMRMesh *New(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) diff --git a/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py b/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py index 72f92c59e..44b0f8bd3 100644 --- a/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py @@ -765,7 +765,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): """ This test is the origin of the ref values for MEDCouplingBasicsTest.testAMR2""" coarse=DataArrayDouble(35) ; coarse.iota(0) #X=5,Y=7 fine=DataArrayDouble(3*2*4*4) ; fine.iota(0) #X=3,Y=2 refined by 4 - MEDCouplingIMesh.CondenseFineToCoarse(coarse,[5,7],fine,[(1,4),(2,4)],[4,4]) + MEDCouplingIMesh.CondenseFineToCoarse([5,7],fine,[(1,4),(2,4)],[4,4],coarse) # m=MEDCouplingCartesianAMRMesh("mesh",2,[6,8],[0.,0.],[1.,1.]) trgMesh=m.buildUnstructured() -- 2.39.2