+ case 3:
+ {
+ mcIdType 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(mcIdType kfact=0;kfact<fact2;kfact++)
+ {
+ for(int j=0;j<dims[1];j++)
+ {
+ for(mcIdType jfact=0;jfact<fact1;jfact++)
+ {
+ for(int i=0;i<dims[0];i++)
+ {
+ double *loc(outPtr+(kk+i+j*coarseSt[0])*nbCompo);
+ for(mcIdType 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 overlapping 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<mcIdType>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<mcIdType,mcIdType> >& fineLocInCoarse, const std::vector<mcIdType>& facts, DataArrayDouble *coarseDA, mcIdType 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<mcIdType> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind(std::plus<mcIdType>(),std::placeholders::_1,2*ghostSize));
+ std::size_t meshDim(coarseSt.size());
+ mcIdType nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
+ std::size_t 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!=fineLocInCoarse.size() || meshDim!=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<mcIdType> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+ std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<mcIdType>());
+ std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind(std::plus<mcIdType>(),std::placeholders::_1,2*ghostSize));
+ mcIdType 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<mcIdType> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+ switch(meshDim)
+ {
+ case 1:
+ {
+ mcIdType 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(mcIdType 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:
+ {
+ mcIdType nxwg(coarseSt[0]+2*ghostSize);
+ mcIdType 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(mcIdType jfact=0;jfact<fact1;jfact++)
+ {
+ inPtr+=ghostSize*nbCompo;
+ for(int i=0;i<dims[0];i++)
+ {
+ double *loc(outPtr+(kk+i)*nbCompo);
+ for(mcIdType 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:
+ {
+ mcIdType nxwg(coarseSt[0]+2*ghostSize),nxywg((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize));
+ mcIdType 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(mcIdType kfact=0;kfact<fact2;kfact++)
+ {
+ inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo;
+ for(int j=0;j<dims[1];j++)
+ {
+ mcIdType kky(j*nxwg);
+ for(mcIdType jfact=0;jfact<fact1;jfact++)
+ {
+ inPtr+=ghostSize*nbCompo;
+ for(int i=0;i<dims[0];i++)
+ {
+ double *loc(outPtr+(kky+kk+i)*nbCompo);
+ for(mcIdType 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<mcIdType>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<mcIdType,mcIdType> >& fineLocInCoarse, const std::vector<mcIdType>& 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 !");
+ std::size_t meshDim(coarseSt.size());
+ mcIdType nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
+ std::size_t 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!=fineLocInCoarse.size() || meshDim!=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());
+ }
+ mcIdType nbTuplesFine(fineDA->getNumberOfTuples());
+ if(nbTuplesFine%nbOfTuplesInFineExp!=0)
+ throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : Invalid nb of tuples in fine DataArray regarding its structure !");
+ mcIdType fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<mcIdType>()));
+ 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<mcIdType> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+ switch(meshDim)
+ {
+ case 1:
+ {
+ mcIdType offset(fineLocInCoarse[0].first),fact0(facts[0]);
+ for(int i=0;i<dims[0];i++)
+ {
+ const double *loc(inPtr+(offset+i)*nbCompo);
+ for(mcIdType ifact=0;ifact<fact0;ifact++)
+ outPtr=std::copy(loc,loc+nbCompo,outPtr);
+ }
+ break;
+ }
+ case 2:
+ {
+ mcIdType kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact0(facts[0]),fact1(facts[1]);
+ for(int j=0;j<dims[1];j++)
+ {
+ for(mcIdType jfact=0;jfact<fact1;jfact++)
+ {
+ for(int i=0;i<dims[0];i++)
+ {
+ const double *loc(inPtr+(kk+i)*nbCompo);
+ for(mcIdType ifact=0;ifact<fact0;ifact++)
+ outPtr=std::copy(loc,loc+nbCompo,outPtr);
+ }
+ }
+ kk+=coarseSt[0];
+ }
+ break;
+ }
+ case 3:
+ {
+ mcIdType 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(mcIdType kfact=0;kfact<fact2;kfact++)
+ {
+ for(int j=0;j<dims[1];j++)
+ {
+ for(mcIdType jfact=0;jfact<fact1;jfact++)
+ {
+ for(int i=0;i<dims[0];i++)
+ {
+ const double *loc(inPtr+(kk+i+j*coarseSt[0])*nbCompo);
+ for(mcIdType ifact=0;ifact<fact0;ifact++)
+ outPtr=std::copy(loc,loc+nbCompo,outPtr);
+ }
+ }
+ }
+ }
+ kk+=coarseSt[0]*coarseSt[1];
+ }
+ break;
+ }