X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingIMesh.cxx;h=e7a4ae0ac97c2afebd90fbcb6326949858fb4112;hb=d7738d8c9d71b3002133b6267e2329a1f1daf97e;hp=16dc17763bc9d3ad709b6ed5f1783e1e12e23b00;hpb=bd13bd39e00dc8959bb35296a385a71606e6acb5;p=modules%2Fmed.git diff --git a/src/MEDCoupling/MEDCouplingIMesh.cxx b/src/MEDCoupling/MEDCouplingIMesh.cxx index 16dc17763..e7a4ae0ac 100644 --- a/src/MEDCoupling/MEDCouplingIMesh.cxx +++ b/src/MEDCoupling/MEDCouplingIMesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D +// Copyright (C) 2007-2015 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 @@ -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(); @@ -182,79 +209,597 @@ MEDCouplingCMesh *MEDCouplingIMesh::convertToCartesian() 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& 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(),-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)); + std::vector structure(_structure,_structure+3); + std::vector 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(); } +/*! + * This method returns a newly created mesh containing a single cell in it. This returned cell covers exactly the space covered by \a this. + * + * \return MEDCouplingIMesh * - A newly created object (to be managed by the caller with decrRef) containing simply one cell. + * + * \throw if \a this does not pass the \c checkCoherency test. + */ +MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const +{ + checkCoherency(); + int spaceDim(getSpaceDimension()),nodeSt[3]; + double dxyz[3]; + for(int i=0;i=2) + { + nodeSt[i]=2; + dxyz[i]=(_structure[i]-1)*_dxyz[i]; + } + else + { + nodeSt[i]=_structure[i]; + dxyz[i]=_dxyz[i]; + } + } + MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingIMesh::New(getName(),getSpaceDimension(),nodeSt,nodeSt+spaceDim,_origin,_origin+spaceDim,dxyz,dxyz+spaceDim)); + ret->copyTinyInfoFrom(this); + return ret.retn(); +} + /*! * 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,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. + * \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) +void MEDCouplingIMesh::CondenseFineToCoarse(const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA) { + if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : All input vectors (dimension) must have the same size !"); if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the parameters 1 or 3 are NULL or not allocated !"); int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse)); int nbCompo(fineDA->getNumberOfComponents()); if(coarseDA->getNumberOfComponents()!=nbCompo) throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the number of components of fine DA and coarse one mismatches !"); - if(meshDim!=(int)fineLocInCoarse.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the size of fineLocInCoarse (4th param) must be equal to the sier of coarseSt (2nd param) !"); + if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : 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::CondenseFineToCoarse : Expecting " << nbOfTuplesInCoarseExp << " having " << coarseDA->getNumberOfTuples() << " !"; + std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } int nbTuplesFine(fineDA->getNumberOfTuples()); - if(nbTuplesFine%nbOfTuplesInCoarseExp!=0) + if(nbOfTuplesInFineExp==0) + { + 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 factN(nbTuplesFine/nbOfTuplesInFineExp); - int fact(FindIntRoot(factN,meshDim)); + int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies())); + if(nbTuplesFine!=fact*nbOfTuplesInFineExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom - MEDCouplingAutoRefCountObjectPtr ids(BuildExplicitIdsFrom(coarseSt,fineLocInCoarse)); - const int *idsPtr(ids->begin()); double *outPtr(coarseDA->getPointer()); const double *inPtr(fineDA->begin()); - coarseDA->setPartOfValuesSimple3(0.,ids->begin(),ids->end(),0,nbCompo,1); // + std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); switch(meshDim) { + case 1: + { + int offset(fineLocInCoarse[0].first),fact0(facts[0]); + for(int i=0;i()); + else + std::copy(inPtr,inPtr+nbCompo,loc); + } + } + break; + } case 2: { - int kk(0); - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - for(int it=0;it()); + else + std::copy(inPtr,inPtr+nbCompo,loc); + } + } + } + kk+=coarseSt[0]; + } + break; + } + case 3: + { + int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first+coarseSt[0]*coarseSt[1]*fineLocInCoarse[2].first),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]); + for(int k=0;k()); + else + std::copy(inPtr,inPtr+nbCompo,loc); + } + } + } + } + } + kk+=coarseSt[0]*coarseSt[1]; + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : only dimensions 1, 2 and 3 supported !"); + } +} + +/*! + * 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 has to be >= 0 !"); + if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : All input vectors (dimension) must have the same size !"); + 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)); + 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 in coarse DataArray having " << coarseDA->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // + std::vector fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies()); + std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); + int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG)); + if(fineDA->getNumberOfTuples()!=nbTuplesFineExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !"; + 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)*ghostSize*nbCompo; + for(int j=0;j()); + else + std::copy(inPtr,inPtr+nbCompo,loc); + } + } + inPtr+=ghostSize*nbCompo; + } + kk+=nxwg; + } + break; + } + case 3: + { + int nxwg(coarseSt[0]+2*ghostSize),nxywg((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)); + int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)+nxywg*(fineLocInCoarse[2].first+ghostSize)),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]); + inPtr+=(dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)*ghostSize*nbCompo; + for(int k=0;k()); + else + std::copy(inPtr,inPtr+nbCompo,loc); + } + } + inPtr+=ghostSize*nbCompo; + } + } + inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo; + } + kk+=nxywg; + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : only dimensions 1, 2, 3 supported !"); + } +} + +/*! + * 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. + * \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) +{ + if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : All input vectors (dimension) must have the same size !"); + if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the parameters 1 or 3 are NULL or not allocated !"); + int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse)); + int nbCompo(fineDA->getNumberOfComponents()); + if(coarseDA->getNumberOfComponents()!=nbCompo) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : 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::SpreadCoarseToFine : 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::SpreadCoarseToFine : 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::SpreadCoarseToFine : 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::SpreadCoarseToFine : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom + double *outPtr(fineDA->getPointer()); + const double *inPtr(coarseDA->begin()); + // + std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + switch(meshDim) + { + case 1: + { + int offset(fineLocInCoarse[0].first),fact0(facts[0]); + for(int i=0;i()); + const double *loc(inPtr+(kk+i)*nbCompo); + for(int ifact=0;ifact& 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 has to be >= 0 !"); + if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : All input vectors (dimension) must have the same size !"); + 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)); + 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()); + } + // + std::vector fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies()); + std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); + int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG)); + if(fineDA->getNumberOfTuples()!=nbTuplesFineExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // + double *outPtr(fineDA->getPointer()); + const double *inPtr(coarseDA->begin()); + // + switch(meshDim) + { + case 1: + { + std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + 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 dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + int fact0(facts[0]),fact1(facts[1]),fact2(facts[2]); + int nxyWgCoarse((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)),nxyWgFine((dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)); + int offset((fineLocInCoarse[2].first+ghostSize-1)*nxyWgCoarse);//offset is always >=0 thanks to the fact that ghostSize>=1 ! + for(int i=0;i& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize) +{ + if(ghostSize<0) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : ghost level has to be >= 0 !"); + if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : All input vectors (dimension) must have the same size !"); + if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : 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)); + int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG)); + int nbCompo(fineDA->getNumberOfComponents()); + if(coarseDA->getNumberOfComponents()!=nbCompo) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : 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::SpreadCoarseToFineGhostZone : 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::SpreadCoarseToFineGhostZone : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // + std::vector fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies()); + std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); + int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG)); + if(fineDA->getNumberOfTuples()!=nbTuplesFineExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !"; + 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 i=0;i MEDCouplingIMesh::getDirectChildren() const +std::vector MEDCouplingIMesh::getDirectChildrenWithNull() const { return std::vector(); } @@ -509,7 +1054,15 @@ void MEDCouplingIMesh::getBoundingBox(double *bbox) const for(int idim=0; idim1) + coeff=_structure[idim]-1; + bbox[2*idim+1]=_origin[idim]+_dxyz[idim]*coeff; } } @@ -781,6 +1334,11 @@ void MEDCouplingIMesh::reprQuickOverview(std::ostream& stream) const stream << stream1.str(); } +std::string MEDCouplingIMesh::getVTKFileExtension() const +{ + return std::string("vti"); +} + std::string MEDCouplingIMesh::getVTKDataSetType() const { return std::string("ImageData"); @@ -834,7 +1392,7 @@ int MEDCouplingIMesh::FindIntRoot(int val, int order) { double retf(std::pow(val,0.3333333333333333)); int ret((int)retf),ret2(ret+1); - if(ret*ret*ret!=val || ret2*ret2*ret2!=val) + if(ret*ret*ret!=val && ret2*ret2*ret2!=val) throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect cublic root !"); if(ret*ret*ret==val) return ret; @@ -842,3 +1400,96 @@ int MEDCouplingIMesh::FindIntRoot(int val, int order) return ret2; } } + +void MEDCouplingIMesh::SpreadCoarseToFineGhost2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector& coarseSt, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize) +{ + double *outPtrWork(outPtr); + std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]); + int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 ! + for(int jg=0;jg= ghostlev + for(int i=0;i& coarseSt, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize) +{ + double *outPtr2(outPtr); + std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]); + int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 ! + for(int jg=0;jg= ghostlev + outPtr2+=fact0*nbCompo*dims[0]; + for(int ig=0;ig