+ synchronizeSizeOfSideMatricesAfterMatrixComputation(src_mesh->getNumberOfCells());
+ return 1;
+}
+
+int MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss()
+{
+ if(getIntersectionType()!=INTERP_KERNEL::PointLocator)
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss : The intersection type is not supported ! Only PointLocator is supported for Gauss->Gauss interpolation ! Please invoke setIntersectionType(PointLocator) on the MEDCouplingRemapper instance !");
+ MCAuto<DataArrayDouble> trgLoc=_target_ft->getLocalizationOfDiscr();
+ const double *trgLocPtr=trgLoc->begin();
+ mcIdType trgSpaceDim=ToIdType(trgLoc->getNumberOfComponents());
+ MCAuto<DataArrayIdType> srcOffsetArr=_src_ft->getDiscretization()->getOffsetArr(_src_ft->getMesh());
+ if(trgSpaceDim!=_src_ft->getMesh()->getSpaceDimension())
+ {
+ std::ostringstream oss; oss << "MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss : space dimensions mismatch between source and target !";
+ oss << " Target discretization localization has dimension " << trgSpaceDim << ", whereas the space dimension of source is equal to ";
+ oss << _src_ft->getMesh()->getSpaceDimension() << " !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ const mcIdType *srcOffsetArrPtr=srcOffsetArr->begin();
+ MCAuto<DataArrayDouble> srcLoc=_src_ft->getLocalizationOfDiscr();
+ const double *srcLocPtr=srcLoc->begin();
+ MCAuto<DataArrayIdType> eltsArr,eltsIndexArr;
+ mcIdType trgNbOfGaussPts=trgLoc->getNumberOfTuples();
+ _matrix.resize(trgNbOfGaussPts);
+ _src_ft->getMesh()->getCellsContainingPointsLinearPartOnlyOnNonDynType(trgLoc->begin(),trgNbOfGaussPts,getPrecision(),eltsArr,eltsIndexArr);
+ const mcIdType *elts(eltsArr->begin()),*eltsIndex(eltsIndexArr->begin());
+ MCAuto<DataArrayIdType> nbOfSrcCellsShTrgPts(eltsIndexArr->deltaShiftIndex());
+ MCAuto<DataArrayIdType> ids0=nbOfSrcCellsShTrgPts->findIdsNotEqual(0);
+ for(const mcIdType *trgId=ids0->begin();trgId!=ids0->end();trgId++)
+ {
+ const double *ptTrg=trgLocPtr+trgSpaceDim*(*trgId);
+ mcIdType srcCellId=elts[eltsIndex[*trgId]];
+ double dist=std::numeric_limits<double>::max();
+ mcIdType srcEntry=-1;
+ for(mcIdType srcId=srcOffsetArrPtr[srcCellId];srcId<srcOffsetArrPtr[srcCellId+1];srcId++)
+ {
+ const double *ptSrc=srcLocPtr+trgSpaceDim*srcId;
+ double tmp=0.;
+ for(mcIdType i=0;i<trgSpaceDim;i++)
+ tmp+=(ptTrg[i]-ptSrc[i])*(ptTrg[i]-ptSrc[i]);
+ if(tmp<dist)
+ { dist=tmp; srcEntry=srcId; }
+ }
+ _matrix[*trgId][srcEntry]=1.;
+ }
+ if(ids0->getNumberOfTuples()!=trgNbOfGaussPts)
+ {
+ MCAuto<DataArrayIdType> orphanTrgIds=nbOfSrcCellsShTrgPts->findIdsEqual(0);
+ MCAuto<DataArrayDouble> orphanTrg=trgLoc->selectByTupleId(orphanTrgIds->begin(),orphanTrgIds->end());
+ MCAuto<DataArrayIdType> srcIdPerTrg=srcLoc->findClosestTupleId(orphanTrg);
+ const mcIdType *srcIdPerTrgPtr=srcIdPerTrg->begin();
+ for(const mcIdType *orphanTrgId=orphanTrgIds->begin();orphanTrgId!=orphanTrgIds->end();orphanTrgId++,srcIdPerTrgPtr++)
+ _matrix[*orphanTrgId][*srcIdPerTrgPtr]=2.;
+ }
+ synchronizeSizeOfSideMatricesAfterMatrixComputation( srcLoc->getNumberOfTuples() );
+ return 1;
+}
+
+int MEDCouplingRemapper::prepareNotInterpKernelOnlyFEFE()
+{
+ if(getIntersectionType()!=INTERP_KERNEL::PointLocator)
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareNotInterpKernelOnlyFEFE : The intersection type is not supported ! Only PointLocator is supported for FE->FE interpolation ! Please invoke setIntersectionType(PointLocator) on the MEDCouplingRemapper instance !");
+ MCAuto<DataArrayDouble> trgLoc=_target_ft->getLocalizationOfDiscr();
+ mcIdType trgSpaceDim=ToIdType(trgLoc->getNumberOfComponents());
+ if(trgSpaceDim!=3)
+ THROW_IK_EXCEPTION("prepareNotInterpKernelOnlyFEFE : only spacedim 3 supported for target !")
+ if(_src_ft->getMesh()->getSpaceDimension() != 3)
+ THROW_IK_EXCEPTION("prepareNotInterpKernelOnlyFEFE : only spacedim 3 supported for source !")
+ const MEDCouplingUMesh *srcUMesh( dynamic_cast<const MEDCouplingUMesh *>(_src_ft->getMesh()) );
+ const MEDCouplingPointSet *trgMesh( dynamic_cast<const MEDCouplingPointSet *>(_target_ft->getMesh()) );
+ if( !srcUMesh )
+ THROW_IK_EXCEPTION("prepareNotInterpKernelOnlyFEFE : only 3D UMesh supported as source !");
+ if( !trgMesh )
+ THROW_IK_EXCEPTION("prepareNotInterpKernelOnlyFEFE : only 3D PointSet mesh supported as target !");
+
+ _matrix.clear();
+ _matrix.resize(trgMesh->getNumberOfNodes());
+ mcIdType rowId(0);
+
+ auto matrixFeeder = [this,&rowId](const MEDCouplingGaussLocalization& gl, const std::vector<mcIdType>& conn)
+ {
+ auto& row = this->_matrix[rowId++];
+ MCAuto<DataArrayDouble> resVector( gl.getShapeFunctionValues() );
+ for(int iPt = 0 ; iPt < gl.getNumberOfPtsInRefCell(); ++iPt)
+ {
+ row[ conn[iPt] ] = resVector->getIJ(0,iPt);
+ }
+ };
+
+ MEDCouplingFieldDiscretizationOnNodesFE::GetRefCoordOfListOf3DPtsIn3D(srcUMesh,trgMesh->getCoords()->begin(),trgMesh->getNumberOfNodes(),matrixFeeder);
+ synchronizeSizeOfSideMatricesAfterMatrixComputation( srcUMesh->getNumberOfNodes() );
+ return 1;
+}
+
+/*!
+ * This method checks that the input interpolation \a method is managed by not INTERP_KERNEL only methods.
+ * If no an INTERP_KERNEL::Exception will be thrown. If yes, a magic number will be returned to switch in the MEDCouplingRemapper::prepareNotInterpKernelOnly method.
+ */
+int MEDCouplingRemapper::CheckInterpolationMethodManageableByNotOnlyInterpKernel(const std::string& method)
+{
+ if(method=="GAUSSGAUSS")
+ return 0;
+ if(method=="FEFE")
+ return 1;
+ std::ostringstream oss; oss << "MEDCouplingRemapper::CheckInterpolationMethodManageableByNotOnlyInterpKernel : ";
+ oss << "The method \"" << method << "\" is not manageable by not INTERP_KERNEL only method.";
+ oss << " Not only INTERP_KERNEL methods dealed are : GAUSSGAUSS FEFE !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+}
+
+/*!
+ * This method determines regarding \c _interp_matrix_pol attribute ( set by MEDCouplingRemapper::setInterpolationMatrixPolicy and by default equal
+ * to IK_ONLY_PREFERED, which method will be applied. If \c true is returned the INTERP_KERNEL only method should be applied to \c false the \b not
+ * only INTERP_KERNEL method should be applied.
+ */
+bool MEDCouplingRemapper::isInterpKernelOnlyOrNotOnly() const
+{
+ std::string srcm,trgm,method;
+ method=checkAndGiveInterpolationMethodStr(srcm,trgm);
+ switch(_interp_matrix_pol)
+ {
+ case IK_ONLY_PREFERED:
+ {
+ try
+ {
+ std::string tmp1,tmp2;
+ INTERP_KERNEL::Interpolation<INTERP_KERNEL::Interpolation3D>::CheckAndSplitInterpolationMethod(method,tmp1,tmp2);
+ return true;
+ }
+ catch(INTERP_KERNEL::Exception& /*e*/)
+ {
+ return false;
+ }
+ }
+ case NOT_IK_ONLY_PREFERED:
+ {
+ try
+ {
+ CheckInterpolationMethodManageableByNotOnlyInterpKernel(method);
+ return false;
+ }
+ catch(INTERP_KERNEL::Exception& /*e*/)
+ {
+ return true;
+ }
+ }
+ case IK_ONLY_FORCED:
+ return true;
+ case NOT_IK_ONLY_FORCED:
+ return false;
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::isInterpKernelOnlyOrNotOnly : internal error ! The interpolation matrix policy is not managed ! Try to change it using MEDCouplingRemapper::setInterpolationMatrixPolicy !");
+ }
+}
+
+void MEDCouplingRemapper::updateTime() const
+{
+}
+
+void MEDCouplingRemapper::checkPrepare() const
+{
+ const MEDCouplingFieldTemplate *s(_src_ft),*t(_target_ft);
+ if(!s || !t)
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkPrepare : it appears that MEDCouplingRemapper::prepare(Ex) has not been called !");
+ if(!s->getMesh() || !t->getMesh())
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkPrepare : it appears that no all field templates have their mesh set !");
+}
+
+void MEDCouplingRemapper::synchronizeSizeOfSideMatricesAfterMatrixComputation(mcIdType nbOfColsInMatrix)
+{