+/*!
+ * 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(const std::vector<int>& factors)
+{
+ if((int)factors.size()!=_space_dim)
+ throw INTERP_KERNEL::Exception("MEDCouplingIMesh::refineWithFactor : refinement factors must have size equal to spaceDim !");
+ checkConsistencyLight();
+ std::vector<int> structure(_structure,_structure+3);
+ std::vector<double> dxyz(_dxyz,_dxyz+3);
+ for(int i=0;i<_space_dim;i++)
+ {
+ if(factors[i]<=0)
+ {
+ std::ostringstream oss; oss << "MEDCouplingIMesh::refineWithFactor : factor for axis #" << i << " (" << factors[i] << ")is invalid ! Must be > 0 !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ int factAbs(std::abs(factors[i]));
+ double fact2(1./(double)factors[i]);
+ structure[i]=(_structure[i]-1)*factAbs+1;
+ dxyz[i]=fact2*_dxyz[i];
+ }
+ std::copy(structure.begin(),structure.end(),_structure);
+ std::copy(dxyz.begin(),dxyz.end(),_dxyz);
+ declareAsNew();
+}
+
+/*!
+ * 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 checkConsistencyLight test.
+ */
+MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const
+{
+ checkConsistencyLight();
+ int spaceDim(getSpaceDimension()),nodeSt[3];
+ double dxyz[3];
+ for(int i=0;i<spaceDim;i++)
+ {
+ if(_structure[i]>=2)
+ {
+ nodeSt[i]=2;
+ dxyz[i]=(_structure[i]-1)*_dxyz[i];
+ }
+ else
+ {
+ nodeSt[i]=_structure[i];
+ dxyz[i]=_dxyz[i];
+ }
+ }
+ MCAuto<MEDCouplingIMesh> 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] 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(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& 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((int)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() || 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 << " tuples having " << coarseDA->getNumberOfTuples() << " !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ int nbTuplesFine(fineDA->getNumberOfTuples());
+ 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 fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
+ 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
+ double *outPtr(coarseDA->getPointer());
+ const double *inPtr(fineDA->begin());
+ //
+ std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+ switch(meshDim)
+ {
+ case 1:
+ {
+ int offset(fineLocInCoarse[0].first),fact0(facts[0]);
+ for(int i=0;i<dims[0];i++)
+ {
+ double *loc(outPtr+(offset+i)*nbCompo);
+ for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
+ {
+ if(ifact!=0)
+ std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
+ else
+ std::copy(inPtr,inPtr+nbCompo,loc);
+ }
+ }
+ break;
+ }
+ case 2:
+ {
+ int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact1(facts[1]),fact0(facts[0]);
+ for(int j=0;j<dims[1];j++)
+ {
+ for(int jfact=0;jfact<fact1;jfact++)
+ {
+ for(int i=0;i<dims[0];i++)
+ {
+ double *loc(outPtr+(kk+i)*nbCompo);
+ for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
+ {
+ if(jfact!=0 || ifact!=0)
+ std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
+ 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<dims[2];k++)
+ {
+ for(int kfact=0;kfact<fact2;kfact++)
+ {
+ for(int j=0;j<dims[1];j++)
+ {
+ for(int jfact=0;jfact<fact1;jfact++)
+ {
+ for(int i=0;i<dims[0];i++)
+ {
+ double *loc(outPtr+(kk+i+j*coarseSt[0])*nbCompo);
+ for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
+ {
+ if(kfact!=0 || jfact!=0 || ifact!=0)
+ std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
+ 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<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& 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<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+ int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
+ int nbCompo(fineDA->getNumberOfComponents());
+ if((int)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<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+ std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
+ std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),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<int> 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<dims[0];i++)
+ {
+ double *loc(outPtr+(offset+i)*nbCompo);
+ for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
+ {
+ if(ifact!=0)
+ std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
+ 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<dims[1];j++)
+ {
+ for(int jfact=0;jfact<fact1;jfact++)
+ {
+ inPtr+=ghostSize*nbCompo;
+ for(int i=0;i<dims[0];i++)
+ {
+ double *loc(outPtr+(kk+i)*nbCompo);
+ for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
+ {
+ if(jfact!=0 || ifact!=0)
+ std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
+ 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<dims[2];k++)
+ {
+ for(int kfact=0;kfact<fact2;kfact++)
+ {
+ inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo;
+ for(int j=0;j<dims[1];j++)
+ {
+ int kky(j*nxwg);
+ for(int jfact=0;jfact<fact1;jfact++)
+ {
+ inPtr+=ghostSize*nbCompo;
+ for(int i=0;i<dims[0];i++)
+ {
+ double *loc(outPtr+(kky+kk+i)*nbCompo);
+ for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
+ {
+ if(kfact!=0 || jfact!=0 || ifact!=0)
+ std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
+ 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<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& 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((int)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<int>()));
+ 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<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+ switch(meshDim)
+ {
+ case 1:
+ {
+ int offset(fineLocInCoarse[0].first),fact0(facts[0]);
+ for(int i=0;i<dims[0];i++)
+ {
+ const double *loc(inPtr+(offset+i)*nbCompo);
+ for(int ifact=0;ifact<fact0;ifact++)
+ outPtr=std::copy(loc,loc+nbCompo,outPtr);
+ }
+ break;
+ }
+ case 2:
+ {
+ int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact0(facts[0]),fact1(facts[1]);
+ for(int j=0;j<dims[1];j++)
+ {
+ for(int jfact=0;jfact<fact1;jfact++)
+ {
+ for(int i=0;i<dims[0];i++)
+ {
+ const double *loc(inPtr+(kk+i)*nbCompo);
+ for(int ifact=0;ifact<fact0;ifact++)
+ outPtr=std::copy(loc,loc+nbCompo,outPtr);
+ }
+ }
+ kk+=coarseSt[0];
+ }
+ break;
+ }
+ case 3:
+ {
+ int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first+coarseSt[0]*coarseSt[1]*fineLocInCoarse[2].first),fact0(facts[0]),fact1(facts[2]),fact2(facts[2]);
+ for(int k=0;k<dims[2];k++)
+ {
+ for(int kfact=0;kfact<fact2;kfact++)
+ {
+ for(int j=0;j<dims[1];j++)
+ {
+ for(int jfact=0;jfact<fact1;jfact++)
+ {
+ for(int i=0;i<dims[0];i++)
+ {
+ const double *loc(inPtr+(kk+i+j*coarseSt[0])*nbCompo);
+ for(int ifact=0;ifact<fact0;ifact++)
+ outPtr=std::copy(loc,loc+nbCompo,outPtr);
+ }
+ }
+ }
+ }
+ kk+=coarseSt[0]*coarseSt[1];
+ }
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : only dimensions 1, 2 and 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.
+ * \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, SpreadCoarseToFineGhostZone
+ */
+void MEDCouplingIMesh::SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& 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<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+ int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
+ int nbCompo(fineDA->getNumberOfComponents());
+ if((int)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<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+ std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
+ std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),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<int> 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<ghostSize;i++)
+ outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
+ offset=fineLocInCoarse[0].first+ghostSize;
+ for(int i=0;i<dims[0];i++)
+ {
+ const double *loc(inPtr+(offset+i)*nbCompo);
+ for(int ifact=0;ifact<fact0;ifact++)
+ outPtr=std::copy(loc,loc+nbCompo,outPtr);
+ }
+ offset=fineLocInCoarse[0].second+ghostSize;
+ for(int i=0;i<ghostSize;i++)
+ outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
+ break;
+ }
+ case 2:
+ {
+ SpreadCoarseToFineGhost2D(inPtr,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+ break;
+ }
+ case 3:
+ {
+ std::vector<int> 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<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
+ SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+ offset+=nxyWgCoarse;
+ for(int i=0;i<dims[2];i++,offset+=nxyWgCoarse)
+ for(int j=0;j<fact2;j++,outPtr+=nxyWgFine*nbCompo)
+ SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+ for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
+ SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : only dimensions 1, 2, 3 supported !");
+ }
+}
+
+/*!
+ * This method spreads the values of coarse data \a coarseDA into \a fineDA \b ONLY \b in \b the \b ghost \b zone (contrary to SpreadCoarseToFineGhost that spread the values everywhere).
+ *
+ * \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 SpreadCoarseToFineGhost
+ */
+void MEDCouplingIMesh::SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& 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<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+ int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
+ int nbCompo(fineDA->getNumberOfComponents());
+ if((int)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<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+ std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
+ std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),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<int> 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<ghostSize;i++)
+ outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
+ outPtr+=nbCompo*fact0*dims[0];
+ offset=fineLocInCoarse[0].second+ghostSize;
+ for(int i=0;i<ghostSize;i++)
+ outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
+ break;
+ }
+ case 2:
+ {
+ SpreadCoarseToFineGhostZone2D(inPtr,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+ break;
+ }
+ case 3:
+ {
+ 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<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
+ SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+ offset+=nxyWgCoarse;
+ for(int i=0;i<dims[2];i++,offset+=nxyWgCoarse)
+ for(int j=0;j<fact2;j++,outPtr+=nxyWgFine*nbCompo)
+ SpreadCoarseToFineGhostZone2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+ for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
+ SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : only dimensions 1, 2, 3 supported !");
+ }
+}
+