+int MEDCouplingRemapper::prepareInterpKernelOnlyUC()
+{
+ std::string srcMeth,trgMeth;
+ std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth);
+ if(methodCpp!="P0P0")
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC: only P0P0 interpolation supported for the moment !");
+ if(InterpolationOptions::getIntersectionType()!=INTERP_KERNEL::Triangulation)
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC: only 'Triangulation' intersection type supported!");
+ const MEDCouplingUMesh *src_mesh=static_cast<const MEDCouplingUMesh *>(_src_ft->getMesh());
+ const MEDCouplingCMesh *target_mesh=static_cast<const MEDCouplingCMesh *>(_target_ft->getMesh());
+ const int srcMeshDim=src_mesh->getMeshDimension();
+ const int srcSpceDim=src_mesh->getSpaceDimension();
+ const int trgMeshDim=target_mesh->getMeshDimension();
+ if(srcMeshDim!=srcSpceDim || srcMeshDim!=trgMeshDim)
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC: space dimension of unstructured source mesh should be equal to mesh dimension of unstructured source mesh, and should also be equal to target cartesian dimension!");
+ std::vector<std::map<int,double> > res;
+ switch(srcMeshDim)
+ {
+ case 1:
+ {
+ MEDCouplingNormalizedCartesianMesh<1> targetWrapper(target_mesh);
+ MEDCouplingNormalizedUnstructuredMesh<1,1> sourceWrapper(src_mesh);
+ INTERP_KERNEL::InterpolationCU myInterpolator(*this);
+ myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0");
+ break;
+ }
+ case 2:
+ {
+ MEDCouplingNormalizedCartesianMesh<2> targetWrapper(target_mesh);
+ MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(src_mesh);
+ INTERP_KERNEL::InterpolationCU myInterpolator(*this);
+ myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0");
+ break;
+ }
+ case 3:
+ {
+ MEDCouplingNormalizedCartesianMesh<3> targetWrapper(target_mesh);
+ MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(src_mesh);
+ INTERP_KERNEL::InterpolationCU myInterpolator(*this);
+ myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0");
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC : only dimension 1 2 or 3 supported !");
+ }
+ ReverseMatrix(res,target_mesh->getNumberOfCells(),_matrix);
+ nullifiedTinyCoeffInCrudeMatrixAbs(0.);
+ //
+ _deno_multiply.clear();
+ _deno_multiply.resize(_matrix.size());
+ _deno_reverse_multiply.clear();
+ _deno_reverse_multiply.resize(src_mesh->getNumberOfCells());
+ declareAsNew();
+ return 1;
+}
+
+int MEDCouplingRemapper::prepareInterpKernelOnlyCU()
+{
+ std::string srcMeth,trgMeth;
+ std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth);
+ if(methodCpp!="P0P0")
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : only P0P0 interpolation supported for the moment !");
+ if(InterpolationOptions::getIntersectionType()!=INTERP_KERNEL::Triangulation)
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU: only 'Triangulation' intersection type supported!");
+ const MEDCouplingCMesh *src_mesh=static_cast<const MEDCouplingCMesh *>(_src_ft->getMesh());
+ const MEDCouplingUMesh *target_mesh=static_cast<const MEDCouplingUMesh *>(_target_ft->getMesh());
+ const int srcMeshDim=src_mesh->getMeshDimension();
+ const int trgMeshDim=target_mesh->getMeshDimension();
+ const int trgSpceDim=target_mesh->getSpaceDimension();
+ if(trgMeshDim!=trgSpceDim || trgMeshDim!=srcMeshDim)
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC: space dimension of unstructured target mesh should be equal to mesh dimension of unstructured target mesh, and should also be equal to source cartesian dimension!");
+ switch(srcMeshDim)
+ {
+ case 1:
+ {
+ MEDCouplingNormalizedCartesianMesh<1> sourceWrapper(src_mesh);
+ MEDCouplingNormalizedUnstructuredMesh<1,1> targetWrapper(target_mesh);
+ INTERP_KERNEL::InterpolationCU myInterpolator(*this);
+ myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0");
+ break;
+ }
+ case 2:
+ {
+ MEDCouplingNormalizedCartesianMesh<2> sourceWrapper(src_mesh);
+ MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(target_mesh);
+ INTERP_KERNEL::InterpolationCU myInterpolator(*this);
+ myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0");
+ break;
+ }
+ case 3:
+ {
+ MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(src_mesh);
+ MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(target_mesh);
+ INTERP_KERNEL::InterpolationCU myInterpolator(*this);
+ myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0");
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : only dimension 1 2 or 3 supported !");
+ }
+ nullifiedTinyCoeffInCrudeMatrixAbs(0.);
+ //
+ _deno_multiply.clear();
+ _deno_multiply.resize(_matrix.size());
+ _deno_reverse_multiply.clear();
+ _deno_reverse_multiply.resize(src_mesh->getNumberOfCells());
+ declareAsNew();
+ return 1;
+}
+
+int MEDCouplingRemapper::prepareInterpKernelOnlyCC()
+{
+ std::string srcMeth,trgMeth;
+ std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth);
+ if(methodCpp!="P0P0")
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : only P0P0 interpolation supported for the moment !");
+ if(InterpolationOptions::getIntersectionType()!=INTERP_KERNEL::Triangulation)
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC: only 'Triangulation' intersection type supported!");
+ const MEDCouplingCMesh *src_mesh=static_cast<const MEDCouplingCMesh *>(_src_ft->getMesh());
+ const MEDCouplingCMesh *target_mesh=static_cast<const MEDCouplingCMesh *>(_target_ft->getMesh());
+ const int srcMeshDim=src_mesh->getMeshDimension();
+ const int trgMeshDim=target_mesh->getMeshDimension();
+ if(trgMeshDim!=srcMeshDim)
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : dimension of target cartesian mesh should be equal to dimension of source cartesian mesh !");
+ switch(srcMeshDim)
+ {
+ case 1:
+ {
+ MEDCouplingNormalizedCartesianMesh<1> sourceWrapper(src_mesh);
+ MEDCouplingNormalizedCartesianMesh<1> targetWrapper(target_mesh);
+ INTERP_KERNEL::InterpolationCC myInterpolator(*this);
+ myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0");
+ break;
+ }
+ case 2:
+ {
+ MEDCouplingNormalizedCartesianMesh<2> sourceWrapper(src_mesh);
+ MEDCouplingNormalizedCartesianMesh<2> targetWrapper(target_mesh);
+ INTERP_KERNEL::InterpolationCC myInterpolator(*this);
+ myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0");
+ break;
+ }
+ case 3:
+ {
+ MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(src_mesh);
+ MEDCouplingNormalizedCartesianMesh<3> targetWrapper(target_mesh);
+ INTERP_KERNEL::InterpolationCC myInterpolator(*this);
+ myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0");
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : only dimension 1 2 or 3 supported !");
+ }
+ nullifiedTinyCoeffInCrudeMatrixAbs(0.);
+ //
+ _deno_multiply.clear();
+ _deno_multiply.resize(_matrix.size());
+ _deno_reverse_multiply.clear();
+ _deno_reverse_multiply.resize(src_mesh->getNumberOfCells());
+ declareAsNew();
+ 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();
+ int trgSpaceDim=trgLoc->getNumberOfComponents();
+ MCAuto<DataArrayInt> 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 int *srcOffsetArrPtr=srcOffsetArr->begin();
+ MCAuto<DataArrayDouble> srcLoc=_src_ft->getLocalizationOfDiscr();
+ const double *srcLocPtr=srcLoc->begin();
+ MCAuto<DataArrayInt> eltsArr,eltsIndexArr;
+ int trgNbOfGaussPts=trgLoc->getNumberOfTuples();
+ _matrix.resize(trgNbOfGaussPts);
+ _src_ft->getMesh()->getCellsContainingPoints(trgLoc->begin(),trgNbOfGaussPts,getPrecision(),eltsArr,eltsIndexArr);
+ const int *elts(eltsArr->begin()),*eltsIndex(eltsIndexArr->begin());
+ MCAuto<DataArrayInt> nbOfSrcCellsShTrgPts(eltsIndexArr->deltaShiftIndex());
+ MCAuto<DataArrayInt> ids0=nbOfSrcCellsShTrgPts->findIdsNotEqual(0);
+ for(const int *trgId=ids0->begin();trgId!=ids0->end();trgId++)
+ {
+ const double *ptTrg=trgLocPtr+trgSpaceDim*(*trgId);
+ int srcCellId=elts[eltsIndex[*trgId]];
+ double dist=std::numeric_limits<double>::max();
+ int srcEntry=-1;
+ for(int srcId=srcOffsetArrPtr[srcCellId];srcId<srcOffsetArrPtr[srcCellId+1];srcId++)
+ {
+ const double *ptSrc=srcLocPtr+trgSpaceDim*srcId;
+ double tmp=0.;
+ for(int 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<DataArrayInt> orphanTrgIds=nbOfSrcCellsShTrgPts->findIdsEqual(0);
+ MCAuto<DataArrayDouble> orphanTrg=trgLoc->selectByTupleId(orphanTrgIds->begin(),orphanTrgIds->end());
+ MCAuto<DataArrayInt> srcIdPerTrg=srcLoc->findClosestTupleId(orphanTrg);
+ const int *srcIdPerTrgPtr=srcIdPerTrg->begin();
+ for(const int *orphanTrgId=orphanTrgIds->begin();orphanTrgId!=orphanTrgIds->end();orphanTrgId++,srcIdPerTrgPtr++)
+ _matrix[*orphanTrgId][*srcIdPerTrgPtr]=2.;
+ }
+ _deno_multiply.clear();
+ _deno_multiply.resize(_matrix.size());
+ _deno_reverse_multiply.clear();
+ _deno_reverse_multiply.resize(srcLoc->getNumberOfTuples());
+ declareAsNew();
+ 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;
+ 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 !";
+ 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 !");
+ }
+}
+