+/*!
+ * 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.
+ */
+void MEDCouplingIMesh::CondenseFineToCoarse(DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse)
+{
+ 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(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
+ {
+ std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Expecting " << nbOfTuplesInCoarseExp << " having " << coarseDA->getNumberOfTuples() << " !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ int nbTuplesFine(fineDA->getNumberOfTuples());
+ if(nbTuplesFine%nbOfTuplesInCoarseExp!=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));
+ // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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);
+ //
+ switch(meshDim)
+ {
+ case 2:
+ {
+ int kk(0);
+ std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+ for(int it=0;it<dims[1];it++)
+ {
+ for(int i=0;i<fact;i++)
+ {
+ for(int j=0;j<dims[0];j++,inPtr+=fact)
+ {
+ double *loc(outPtr+idsPtr[kk+j]*nbCompo);
+ std::transform(inPtr,inPtr+fact,loc,loc,std::plus<double>());
+ }
+ }
+ kk+=it;
+ }
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : only dimensions 2 supported !");
+ }
+}
+