From ed1d9af305e1ebba9365bf919a6b3586350edcf7 Mon Sep 17 00:00:00 2001 From: geay Date: Thu, 12 Jun 2014 11:55:50 +0200 Subject: [PATCH] Debug for ghostlev > 1. Optimization of neighbors. --- src/MEDCoupling/MEDCouplingAMRAttribute.cxx | 33 +++++++ src/MEDCoupling/MEDCouplingAMRAttribute.hxx | 19 ++++ .../MEDCouplingCartesianAMRMesh.cxx | 87 +++++++++++-------- .../MEDCouplingCartesianAMRMesh.hxx | 20 +---- src/MEDCoupling/MEDCouplingIMesh.cxx | 7 +- src/MEDCoupling_Swig/MEDCouplingCommon.i | 1 + 6 files changed, 112 insertions(+), 55 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingAMRAttribute.cxx b/src/MEDCoupling/MEDCouplingAMRAttribute.cxx index 96dbe2d07..9ab932819 100644 --- a/src/MEDCoupling/MEDCouplingAMRAttribute.cxx +++ b/src/MEDCoupling/MEDCouplingAMRAttribute.cxx @@ -546,6 +546,39 @@ void MEDCouplingGridCollection::updateTime() const } } +MEDCouplingCartesianAMRPatchGF::MEDCouplingCartesianAMRPatchGF(MEDCouplingCartesianAMRMesh *mesh):MEDCouplingCartesianAMRPatchGen(mesh) +{ +} + +std::size_t MEDCouplingCartesianAMRPatchGF::getHeapMemorySizeWithoutChildren() const +{ + return sizeof(MEDCouplingCartesianAMRPatchGF); +} + +MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMeshGen *gf):_gf(gf),_tlc(gf) +{ + if(!gf) + throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !"); + gf->incrRef(); +} + +void MEDCouplingDataForGodFather::checkGodFatherFrozen() const +{ + _tlc.checkConst(); +} + +bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMeshGen *gf) +{ + bool ret(_tlc.keepTrackOfNewTL(gf)); + if(ret) + { + _gf=gf; + if(gf) + gf->incrRef(); + } + return ret; +} + /*! * This method creates, attach to a main AMR mesh \a gf ( called god father :-) ) and returns a data linked to \a gf ready for the computation. */ diff --git a/src/MEDCoupling/MEDCouplingAMRAttribute.hxx b/src/MEDCoupling/MEDCouplingAMRAttribute.hxx index deb5aba72..b05f704d8 100644 --- a/src/MEDCoupling/MEDCouplingAMRAttribute.hxx +++ b/src/MEDCoupling/MEDCouplingAMRAttribute.hxx @@ -86,6 +86,25 @@ namespace ParaMEDMEM /// @endcond + class MEDCouplingDataForGodFather : public RefCountObject + { + friend class MEDCouplingCartesianAMRMesh; + public: + MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarse() = 0; + MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFine() = 0; + MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZones() = 0; + MEDCOUPLING_EXPORT virtual void alloc() = 0; + MEDCOUPLING_EXPORT virtual void dealloc() = 0; + protected: + MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMeshGen *gf); + void checkGodFatherFrozen() const; + protected: + virtual bool changeGodFather(MEDCouplingCartesianAMRMeshGen *gf); + protected: + MEDCouplingAutoRefCountObjectPtr _gf; + TimeLabelConstOverseer _tlc; + }; + class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel { public: diff --git a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx index 7a5298327..3b38301ef 100644 --- a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx @@ -161,7 +161,7 @@ bool MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt(const MEDCouplingCartes /*! * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter * the must be >= 0. This method works even if \a this and \a other does not share the same father. - * This is expected to be more refined than \a other. That is to say lev of \a this is greater than level of \a other. + * \a this is expected to be more refined than \a other. That is to say lev of \a this is greater than level of \a other. * * \param [in] other - The other patch * \param [in] ghostLev - The size of the neighborhood zone. @@ -178,7 +178,7 @@ bool MEDCouplingCartesianAMRPatch::isInMyNeighborhoodDiffLev(const MEDCouplingCa std::vector< std::pair > thispp,otherpp; std::vector factors; ComputeZonesOfTwoRelativeToOneDiffLev(ghostLev,this,other,thispp,otherpp,factors); - return IsInMyNeighborhood(ghostLev,thispp,otherpp); + return IsInMyNeighborhood(ghostLev>0?1:0,thispp,otherpp);//1 not ghostLev ! It is not a bug ( I hope :) ) ! Because as \a this is a refinement of \a other ghostLev is supposed to be <= factors } std::vector MEDCouplingCartesianAMRPatch::computeCellGridSt() const @@ -237,7 +237,7 @@ std::vector< std::vector< std::pair::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++) { - if((*it1)->isInMyNeighborhoodExt(*it2,ghostLev)) + if((*it1)->isInMyNeighborhoodExt(*it2,ghostLev>0?1:0))//1 not ghostLev ! It is not a bug ( I hope :) ) ! Because as \a this is a refinement of \a other ghostLev is supposed to be <= factors retTmp.push_back(std::pair(*it1,*it2)); } std::vector tmp1((*it1)->getMesh()->getPatches()); @@ -511,39 +511,6 @@ void MEDCouplingCartesianAMRPatch::ApplyAllGhostOnCompactFrmt(std::vector< std:: } } -MEDCouplingCartesianAMRPatchGF::MEDCouplingCartesianAMRPatchGF(MEDCouplingCartesianAMRMesh *mesh):MEDCouplingCartesianAMRPatchGen(mesh) -{ -} - -std::size_t MEDCouplingCartesianAMRPatchGF::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(MEDCouplingCartesianAMRPatchGF); -} - -MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMeshGen *gf):_gf(gf),_tlc(gf) -{ - if(!gf) - throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !"); - gf->incrRef(); -} - -void MEDCouplingDataForGodFather::checkGodFatherFrozen() const -{ - _tlc.checkConst(); -} - -bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMeshGen *gf) -{ - bool ret(_tlc.keepTrackOfNewTL(gf)); - if(ret) - { - _gf=gf; - if(gf) - gf->incrRef(); - } - return ret; -} - /// @endcond int MEDCouplingCartesianAMRMeshGen::getSpaceDimension() const @@ -1495,6 +1462,27 @@ std::vector MEDCouplingCartesianAMRMeshGen::getPatchIdsInTheNeighborhoodOf( return ret; } +/*! + * This method returns a dump python of \a this. It is useful for users of createPatchesFromCriterion method for debugging. + * + * \sa dumpPatchesOf, createPatchesFromCriterion, createPatchesFromCriterionML + */ +std::string MEDCouplingCartesianAMRMeshGen::buildPythonDumpOfThis() const +{ + std::ostringstream oss; + oss << "amr=MEDCouplingCartesianAMRMesh(\""<< getImageMesh()->getName() << "\"," << getSpaceDimension() << ",["; + std::vector ngs(getImageMesh()->getNodeGridStructure()); + std::vector orig(getImageMesh()->getOrigin()),dxyz(getImageMesh()->getDXYZ()); + std::copy(ngs.begin(),ngs.end(),std::ostream_iterator(oss,",")); + oss << "],["; + std::copy(orig.begin(),orig.end(),std::ostream_iterator(oss,",")); + oss << "],["; + std::copy(dxyz.begin(),dxyz.end(),std::ostream_iterator(oss,",")); + oss << "])\n"; + dumpPatchesOf("amr",oss); + return oss.str(); +} + MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop):_father(0) { @@ -1617,6 +1605,33 @@ std::vector MEDCouplingCartesianAMRMeshGen::extractSubT return ret; } +void MEDCouplingCartesianAMRMeshGen::dumpPatchesOf(const std::string& varName, std::ostream& oss) const +{ + std::size_t j(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) + { + const MEDCouplingCartesianAMRPatch *patch(*it); + if(patch) + { + std::ostringstream oss2; oss2 << varName << ".addPatch(["; + const std::vector< std::pair >& bltr(patch->getBLTRRange()); + std::size_t sz(bltr.size()); + for(std::size_t i=0;i(oss2,",")); + oss2 << "])\n"; + oss << oss2.str(); + std::ostringstream oss3; oss3 << varName << "[" << j++ << "]"; + patch->getMesh()->dumpPatchesOf(oss3.str(),oss); + } + } +} + std::size_t MEDCouplingCartesianAMRMeshGen::getHeapMemorySizeWithoutChildren() const { return sizeof(MEDCouplingCartesianAMRMeshGen); diff --git a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx index 1c911beef..00fb07239 100644 --- a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx +++ b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx @@ -113,24 +113,6 @@ namespace ParaMEDMEM std::size_t getHeapMemorySizeWithoutChildren() const; }; - class MEDCouplingDataForGodFather : public RefCountObject - { - friend class MEDCouplingCartesianAMRMesh; - public: - MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarse() = 0; - MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFine() = 0; - MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZones() = 0; - MEDCOUPLING_EXPORT virtual void alloc() = 0; - MEDCOUPLING_EXPORT virtual void dealloc() = 0; - protected: - MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMeshGen *gf); - void checkGodFatherFrozen() const; - protected: - virtual bool changeGodFather(MEDCouplingCartesianAMRMeshGen *gf); - protected: - MEDCouplingAutoRefCountObjectPtr _gf; - TimeLabelConstOverseer _tlc; - }; /// @endcond /*! @@ -190,6 +172,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostSz, const std::vector& recurseArrs) const; MEDCOUPLING_EXPORT DataArrayDouble *extractGhostFrom(int ghostSz, const DataArrayDouble *arr) const; MEDCOUPLING_EXPORT std::vector getPatchIdsInTheNeighborhoodOf(int patchId, int ghostLev) const; + MEDCOUPLING_EXPORT std::string buildPythonDumpOfThis() const; protected: MEDCouplingCartesianAMRMeshGen(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); @@ -199,6 +182,7 @@ namespace ParaMEDMEM void retrieveGridsAtInternal(int lev, std::vector< MEDCouplingAutoRefCountObjectPtr >& grids) const; static int GetGhostLevelInFineRef(int ghostLev, const std::vector& factors); std::vector extractSubTreeFromGlobalFlatten(const MEDCouplingCartesianAMRMeshGen *head, const std::vector& all) const; + void dumpPatchesOf(const std::string& varName, std::ostream& oss) const; protected: MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; MEDCOUPLING_EXPORT std::vector getDirectChildren() const; diff --git a/src/MEDCoupling/MEDCouplingIMesh.cxx b/src/MEDCoupling/MEDCouplingIMesh.cxx index a61d4fab2..0e2eeca19 100644 --- a/src/MEDCoupling/MEDCouplingIMesh.cxx +++ b/src/MEDCoupling/MEDCouplingIMesh.cxx @@ -295,7 +295,12 @@ void MEDCouplingIMesh::CondenseFineToCoarse(const std::vector& coarseSt, co } int nbTuplesFine(fineDA->getNumberOfTuples()); if(nbOfTuplesInFineExp==0) - return ; + { + if(nbTuplesFine==0) + return ; + else + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Nothing to condense considering the range specified ! But DataArray is not empty !"); + } if(nbTuplesFine%nbOfTuplesInFineExp!=0) throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Invalid nb of tuples in fine DataArray regarding its structure !"); int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies())); diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index d63d8bcbf..1a4313ddf 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -4953,6 +4953,7 @@ namespace ParaMEDMEM void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative=true) const throw(INTERP_KERNEL::Exception); void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative=true) const throw(INTERP_KERNEL::Exception); DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const throw(INTERP_KERNEL::Exception); + std::string buildPythonDumpOfThis() const throw(INTERP_KERNEL::Exception); %extend { void addPatch(PyObject *bottomLeftTopRight, const std::vector& factors) throw(INTERP_KERNEL::Exception) -- 2.39.2