Salome HOME
2D PointLocator remapping now works properly on non-convex polygons.
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingUMesh.cxx
index b764904fee4c0823f8c1fea2ba7542b27b4b679c..c20a00b273257223bf222b714f56ef62e6871086 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2020  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -618,7 +618,7 @@ void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayIdType *revNodal, Da
       const mcIdType *endNdlConnOfCurCell=conn+connIndex[eltId+1];
       for(const mcIdType *iter=strtNdlConnOfCurCell;iter!=endNdlConnOfCurCell;iter++)
         if(*iter>=0)//for polyhedrons
-          *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to<mcIdType>(),-1))=eltId;
+          *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind(std::equal_to<mcIdType>(),std::placeholders::_1,-1))=eltId;
     }
 }
 
@@ -1246,7 +1246,7 @@ bool MEDCouplingUMesh::unPolyze()
       INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[posOfCurCell];
       const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
       INTERP_KERNEL::NormalizedCellType newType=INTERP_KERNEL::NORM_ERROR;
-      mcIdType newLgth;
+      mcIdType newLgth=0;
       if(cm.isDynamic())
         {
           switch(cm.getDimension())
@@ -1265,11 +1265,12 @@ bool MEDCouplingUMesh::unPolyze()
                 newType=INTERP_KERNEL::CellSimplify::tryToUnPoly3D(zipFullReprOfPolyh,nbOfFaces,lgthOfPolyhConn,conn+newPos+1,newLgth);
                 break;
               }
-            case 1:
+         /*   case 1:  // Not supported yet
               {
                 newType=(lgthOfCurCell==3)?INTERP_KERNEL::NORM_SEG2:INTERP_KERNEL::NORM_POLYL;
                 break;
               }
+         */
           }
           ret=ret || (newType!=type);
           conn[newPos]=newType;
@@ -1663,8 +1664,6 @@ int MEDCouplingUMesh::AreCellsEqualPolicy7(const mcIdType *conn, const mcIdType
                       else
                         return 0;
                     }
-
-                  return work!=tmp+sz1?1:0;
                 }
               else
                 {//case of SEG2 and SEG3
@@ -1695,9 +1694,11 @@ int MEDCouplingUMesh::AreCellsEqualPolicy7(const mcIdType *conn, const mcIdType
 
 
 /*!
- * This method find cells that are equal (regarding \a compType) in \a this. The comparison is specified
- * by \a compType.
- * This method keeps the coordiantes of \a this. This method is time consuming.
+ * This method find cells that are equal (regarding \a compType) in \a this. The comparison is specified by \a compType (see zipConnectivityTraducer).
+ * This method keeps the coordinates of \a this. The comparison starts at rank \a startCellId cell id (included).
+ * If \a startCellId is equal to 0 algorithm starts at cell #0 and for each cell candidates being searched have cell id higher than current cellId.
+ * If \a startCellId is greater than 0 algorithm starts at cell #startCellId but for each cell all candidates are considered.
+ * This method is time consuming.
  *
  * \param [in] compType input specifying the technique used to compare cells each other.
  *   - 0 : exactly. A cell is detected to be the same if and only if the connectivity is exactly the same without permutation and types same too. This is the strongest policy.
@@ -1708,7 +1709,6 @@ int MEDCouplingUMesh::AreCellsEqualPolicy7(const mcIdType *conn, const mcIdType
  * \param [in] startCellId specifies the cellId starting from which the equality computation will be carried out. By default it is 0, which it means that all cells in \a this will be scanned.
  * \param [out] commonCellsArr common cells ids (\ref numbering-indirect)
  * \param [out] commonCellsIArr common cells ids (\ref numbering-indirect)
- * \return the correspondence array old to new in a newly allocated array.
  *
  */
 void MEDCouplingUMesh::findCommonCells(int compType, mcIdType startCellId, DataArrayIdType *& commonCellsArr, DataArrayIdType *& commonCellsIArr) const
@@ -1729,11 +1729,11 @@ void MEDCouplingUMesh::FindCommonCellsAlg(int compType, mcIdType startCellId, co
   std::vector<bool> isFetched(nbOfCells,false);
   if(startCellId==0)
     {
-      for(mcIdType i=0;i<nbOfCells;i++)
+      for(mcIdType i=startCellId;i<nbOfCells;i++)
         {
           if(!isFetched[i])
             {
-              const mcIdType *connOfNode=std::find_if(connPtr+connIPtr[i]+1,connPtr+connIPtr[i+1],std::bind2nd(std::not_equal_to<mcIdType>(),-1));
+              const mcIdType *connOfNode=std::find_if(connPtr+connIPtr[i]+1,connPtr+connIPtr[i+1],std::bind(std::not_equal_to<mcIdType>(),std::placeholders::_1,-1));
               std::vector<mcIdType> v,v2;
               if(connOfNode!=connPtr+connIPtr[i+1])
                 {
@@ -1768,7 +1768,8 @@ void MEDCouplingUMesh::FindCommonCellsAlg(int compType, mcIdType startCellId, co
         {
           if(!isFetched[i])
             {
-              const mcIdType *connOfNode=std::find_if(connPtr+connIPtr[i]+1,connPtr+connIPtr[i+1],std::bind2nd(std::not_equal_to<mcIdType>(),-1));
+              const mcIdType *connOfNode=std::find_if(connPtr+connIPtr[i]+1,connPtr+connIPtr[i+1],std::bind(std::not_equal_to<mcIdType>(),std::placeholders::_1,-1));
+              // v2 contains the result of successive intersections using rev nodal on on each node of cell #i
               std::vector<mcIdType> v,v2;
               if(connOfNode!=connPtr+connIPtr[i+1])
                 {
@@ -1782,12 +1783,20 @@ void MEDCouplingUMesh::FindCommonCellsAlg(int compType, mcIdType startCellId, co
                     std::vector<mcIdType>::iterator it=std::set_intersection(v.begin(),v.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin());
                     v2.resize(std::distance(v2.begin(),it));
                   }
+              // v2 contains now candidates. Problem candidates are sorted using id rank.
               if(v2.size()>1)
                 {
+                  if(v2[0]!=i)
+                  {
+                    auto it(std::find(v2.begin(),v2.end(),i));
+                    std::swap(*v2.begin(),*it);
+                  }
                   if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells))
                     {
-                      mcIdType pos=commonCellsI->back();
-                      commonCellsI->pushBackSilent(commonCells->getNumberOfTuples());
+                      mcIdType newPos(commonCells->getNumberOfTuples());
+                      mcIdType pos(commonCellsI->back());
+                      std::sort(commonCells->getPointerSilent()+pos,commonCells->getPointerSilent()+newPos);
+                      commonCellsI->pushBackSilent(newPos);
                       for(const mcIdType *it=commonCells->begin()+pos;it!=commonCells->end();it++)
                         isFetched[*it]=true;
                     }
@@ -1835,13 +1844,30 @@ bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int com
       oss << " !";
       throw INTERP_KERNEL::Exception(oss.str());
     }
-  MCAuto<DataArrayIdType> o2n=mesh->zipConnectivityTraducer(compType,nbOfCells);
-  arr=o2n->subArray(nbOfCells);
-  arr->setName(other->getName());
-  mcIdType tmp;
+  //
   if(other->getNumberOfCells()==0)
+  {
+    MCAuto<DataArrayIdType> dftRet(DataArrayIdType::New()); dftRet->alloc(0,1); arr=dftRet.retn(); arr->setName(other->getName());
     return true;
-  return arr->getMaxValue(tmp)<nbOfCells;
+  }
+  DataArrayIdType *commonCells(nullptr),*commonCellsI(nullptr);
+  mesh->findCommonCells(compType,nbOfCells,commonCells,commonCellsI);
+  MCAuto<DataArrayIdType> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI);
+  mcIdType newNbOfCells=-1;
+  MCAuto<DataArrayIdType> o2n = DataArrayIdType::ConvertIndexArrayToO2N(ToIdType(mesh->getNumberOfCells()),commonCells->begin(),commonCellsI->begin(),commonCellsI->end(),newNbOfCells);
+  MCAuto<DataArrayIdType> p0(o2n->selectByTupleIdSafeSlice(0,nbOfCells,1));
+  mcIdType maxPart(p0->getMaxValueInArray());
+  bool ret(maxPart==newNbOfCells-1);
+  MCAuto<DataArrayIdType> p1(p0->invertArrayO2N2N2O(newNbOfCells));
+  // fill p1 array in case of presence of cells in other not in this
+  mcIdType *pt(p1->getPointer());
+  for(mcIdType i = maxPart ; i < newNbOfCells-1 ; ++i )
+    pt[i+1] = i+1;
+  //
+  MCAuto<DataArrayIdType> p2(o2n->subArray(nbOfCells));
+  p2->transformWithIndArr(p1->begin(),p1->end()); p2->setName(other->getName());
+  arr = p2.retn();
+  return ret;
 }
 
 /*!
@@ -1907,9 +1933,9 @@ MEDCouplingUMesh *MEDCouplingUMesh::mergeMyselfWithOnSameCoords(const MEDCouplin
  * By default coordinates are kept. This method is close to MEDCouplingUMesh::buildPartOfMySelf except that here input
  * cellIds is not given explicitly but by a range python like.
  *
- * \param start
- * \param end
- * \param step
+ * \param start starting ID
+ * \param end end ID (excluded)
+ * \param step step size
  * \param keepCoords that specifies if you want or not to keep coords as this or zip it (see MEDCoupling::MEDCouplingUMesh::zipCoords). If true zipCoords is \b NOT called, if false, zipCoords is called.
  * \return a newly allocated
  *
@@ -2204,7 +2230,7 @@ DataArrayIdType *MEDCouplingUMesh::findCellIdsOnBoundary() const
  * \throw if \b otherDimM1OnSameCoords is not part of constituent of \b this, or if coordinate pointer of \b this and \b otherDimM1OnSameCoords
  *        are not same, or if this->getMeshDimension()-1!=otherDimM1OnSameCoords.getMeshDimension()
  *
- * \param [in] otherDimM1OnSameCoords
+ * \param [in] otherDimM1OnSameCoords other mesh
  * \param [out] cellIdsRk0 a newly allocated array containing the cell ids of s0 (which are cell ids of \b this) in the above algorithm.
  * \param [out] cellIdsRk1 a newly allocated array containing the cell ids of s1 \b indexed into the \b cellIdsRk0 subset. To get the absolute ids of s1, simply invoke
  *              cellIdsRk1->transformWithIndArr(cellIdsRk0->begin(),cellIdsRk0->end());
@@ -2296,7 +2322,6 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildUnstructured() const
  * \param [out] cellIdsNeededToBeRenum cell ids in \b this in which the renumber of nodes should be performed.
  * \param [out] cellIdsNotModified cell ids mcIdType \b this that lies on \b otherDimM1OnSameCoords mesh whose connectivity do \b not need to be modified as it is the case for \b cellIdsNeededToBeRenum.
  *
- * \warning This method modifies param \b otherDimM1OnSameCoords (for speed reasons).
  */
 void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayIdType *& nodeIdsToDuplicate,
                                             DataArrayIdType *& cellIdsNeededToBeRenum, DataArrayIdType *& cellIdsNotModified) const
@@ -2313,14 +2338,15 @@ void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1On
 
   // Checking star-shaped M1 group:
   DAInt dt0=DataArrayIdType::New(),dit0=DataArrayIdType::New(),rdt0=DataArrayIdType::New(),rdit0=DataArrayIdType::New();
-  MCUMesh meshM2 = otherDimM1OnSameCoords.buildDescendingConnectivity(dt0, dit0, rdt0, rdit0);
+  MCUMesh meshM2 = otherDimM1OnSameCoords.buildDescendingConnectivity(dt0, dit0, rdt0, rdit0); // 2D: a mesh of points, 3D: a mesh of segs
   DAInt dsi = rdit0->deltaShiftIndex();
-  DAInt idsTmp0 = dsi->findIdsNotInRange(-1, 3);
+  DAInt idsTmp0 = dsi->findIdsNotInRange(-1, 3);  // for 2D: if a point is connected to more than 2 segs. For 3D: if a seg is connected to more than two faces.
   if(idsTmp0->getNumberOfTuples())
     throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group: group is too complex: some points (or edges) have more than two connected segments (or faces)!");
   dt0=0; dit0=0; rdt0=0; rdit0=0; idsTmp0=0;
 
-  // Get extreme nodes from the group (they won't be duplicated), ie nodes belonging to boundary cells of M1
+  // Get extreme nodes from the group (they won't be duplicated except if they also lie on bound of M0 -- see below),
+  // ie nodes belonging to the boundary "cells" (might be points) of M1
   DAInt xtremIdsM2 = dsi->findIdsEqual(1); dsi = 0;
   MCUMesh meshM2Part = static_cast<MEDCouplingUMesh *>(meshM2->buildPartOfMySelf(xtremIdsM2->begin(), xtremIdsM2->end(),true));
   DAInt xtrem = meshM2Part->computeFetchedNodeIds();
@@ -2328,15 +2354,17 @@ void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1On
   dt0=DataArrayIdType::New(),dit0=DataArrayIdType::New(),rdt0=DataArrayIdType::New(),rdit0=DataArrayIdType::New();
   MCUMesh m0desc = buildDescendingConnectivity(dt0, dit0, rdt0, rdit0); dt0=0; dit0=0; rdt0=0;
   dsi = rdit0->deltaShiftIndex();
-  DAInt boundSegs = dsi->findIdsEqual(1);   // boundary segs/faces of the M0 mesh
+  DAInt boundSegs = dsi->findIdsEqual(1);  dsi = 0; // boundary segs/faces of the M0 mesh
   MCUMesh m0descSkin = static_cast<MEDCouplingUMesh *>(m0desc->buildPartOfMySelf(boundSegs->begin(),boundSegs->end(), true));
   DAInt fNodes = m0descSkin->computeFetchedNodeIds();
-  // In 3D, some points on the boundary of M0 still need duplication:
+  // In 3D, some points on the boundary of M0 will NOT be duplicated (where as in 2D, points on the boundary of M0 are always duplicated)
+  // Think of a partial (plane) crack in a cube: the points at the tip of the crack and not located inside the volume of the cube are not duplicated
+  // although they are technically on the skin of the cube.
   DAInt notDup = 0;
   if (getMeshDimension() == 3)
     {
       DAInt dnu1=DataArrayIdType::New(), dnu2=DataArrayIdType::New(), dnu3=DataArrayIdType::New(), dnu4=DataArrayIdType::New();
-      MCUMesh m0descSkinDesc = m0descSkin->buildDescendingConnectivity(dnu1, dnu2, dnu3, dnu4);
+      MCUMesh m0descSkinDesc = m0descSkin->buildDescendingConnectivity(dnu1, dnu2, dnu3, dnu4); // all segments of the skin of the 3D (M0) mesh
       dnu1=0;dnu2=0;dnu3=0;dnu4=0;
       DataArrayIdType * corresp=0;
       meshM2->areCellsIncludedIn(m0descSkinDesc,2,corresp);
@@ -2344,10 +2372,26 @@ void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1On
       corresp->decrRef();
       if (validIds->getNumberOfTuples())
         {
+          // Build the set of segments which are: in the desc mesh of the skin of the 3D mesh (M0) **and** in the desc mesh of the M1 group:
           MCUMesh m1IntersecSkin = static_cast<MEDCouplingUMesh *>(m0descSkinDesc->buildPartOfMySelf(validIds->begin(), validIds->end(), true));
+          // Its boundary nodes should no be duplicated (this is for example the tip of the crack inside the cube described above)
           DAInt notDuplSkin = m1IntersecSkin->findBoundaryNodes();
           DAInt fNodes1 = fNodes->buildSubstraction(notDuplSkin);
-          notDup = xtrem->buildSubstraction(fNodes1);
+
+          // Also, in this (segment) mesh, nodes connected to more than 3 segs should not be dup either (singular points - see testBuildInnerBoundary6())
+          dt0=DataArrayIdType::New(),dit0=DataArrayIdType::New(),rdt0=DataArrayIdType::New(),rdit0=DataArrayIdType::New();
+          MCUMesh meshM2Desc = meshM2->buildDescendingConnectivity(dt0, dit0, rdt0, rdit0); dt0=0; dit0=0; rdt0=0;  // a mesh made of node cells
+          dsi = rdit0->deltaShiftIndex();
+          DAInt singPoints = dsi->findIdsNotInRange(-1,4);   // points connected to (strictly) more than 3 segments
+          const mcIdType *cc = meshM2Desc->getNodalConnectivity()->begin(), *ccI = meshM2Desc->getNodalConnectivityIndex()->begin();
+          mcIdType * singPointsP = singPoints->rwBegin();
+          for (mcIdType j=0; j < singPoints->getNumberOfTuples(); j++) // replace ids in singPoints by real coordinate index (was index of cells in notDuplSkin)
+            {
+              mcIdType nodeCellIdx = singPointsP[j];
+              singPointsP[j] = cc[ccI[nodeCellIdx]+1];  // +1 to skip type
+            }
+          DAInt fNodes2 = fNodes1->buildSubstraction(singPoints);
+          notDup = xtrem->buildSubstraction(fNodes2);
         }
       else
         notDup = xtrem->buildSubstraction(fNodes);
@@ -2610,7 +2654,7 @@ void MEDCouplingUMesh::duplicateNodesInConn(const mcIdType *nodeIdsToDuplicateBg
  * should be contained in[0;this->getNumberOfCells()).
  *
  * \param [in] old2NewBg is expected to be a dynamically allocated pointer of size at least equal to this->getNumberOfCells()
- * \param check
+ * \param check whether to check content of old2NewBg
  */
 void MEDCouplingUMesh::renumberCells(const mcIdType *old2NewBg, bool check)
 {
@@ -2988,7 +3032,7 @@ mcIdType MEDCouplingUMesh::getNumberOfNodesInCell(mcIdType cellId) const
   if(pt[ptI[cellId]]!=INTERP_KERNEL::NORM_POLYHED)
     return ptI[cellId+1]-ptI[cellId]-1;
   else
-    return ToIdType(std::count_if(pt+ptI[cellId]+1,pt+ptI[cellId+1],std::bind2nd(std::not_equal_to<mcIdType>(),-1)));
+    return ToIdType(std::count_if(pt+ptI[cellId]+1,pt+ptI[cellId+1],std::bind(std::not_equal_to<mcIdType>(),std::placeholders::_1,-1)));
 }
 
 /*!
@@ -3130,9 +3174,9 @@ bool MEDCouplingUMesh::isEmptyMesh(const std::vector<mcIdType>& tinyInfo) const
 /*!
  * Second step of serialization process.
  * \param tinyInfo must be equal to the result given by getTinySerializationInformation method.
- * \param a1
- * \param a2
- * \param littleStrings
+ * \param a1 DataArrayDouble
+ * \param a2 DataArrayDouble
+ * \param littleStrings string vector
  */
 void MEDCouplingUMesh::resizeForUnserialization(const std::vector<mcIdType>& tinyInfo, DataArrayIdType *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
 {
@@ -3225,7 +3269,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const
           area_vol[iel]=INTERP_KERNEL::computeVolSurfOfCell2<mcIdType,INTERP_KERNEL::ALL_C_MODE>(type,connec+ipt+1,connec_index[iel+1]-ipt-1,coords,dim_space);
         }
       if(isAbs)
-        std::transform(area_vol,area_vol+nbelem,area_vol,std::ptr_fun<double,double>(fabs));
+        std::transform(area_vol,area_vol+nbelem,area_vol,[](double c){return fabs(c);});
     }
   else
     {
@@ -3278,7 +3322,7 @@ DataArrayDouble *MEDCouplingUMesh::getPartMeasureField(bool isAbs, const mcIdTyp
           *area_vol++=INTERP_KERNEL::computeVolSurfOfCell2<mcIdType,INTERP_KERNEL::ALL_C_MODE>(type,connec+ipt+1,connec_index[*iel+1]-ipt-1,coords,dim_space);
         }
       if(isAbs)
-        std::transform(array->getPointer(),area_vol,array->getPointer(),std::ptr_fun<double,double>(fabs));
+        std::transform(array->getPointer(),area_vol,array->getPointer(),[](double c){return fabs(c);});
     }
   else
     {
@@ -3310,8 +3354,8 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureFieldOnNode(bool isAbs) cons
   mcIdType nbNodes=getNumberOfNodes();
   MCAuto<DataArrayDouble> nnpc;
   {
-    MCAuto<DataArrayIdType> tmp(computeNbOfNodesPerCell());
-    nnpc=tmp->convertToDblArr();
+    MCAuto<DataArrayIdType> tmp2(computeNbOfNodesPerCell());
+    nnpc=tmp2->convertToDblArr();
   }
   std::for_each(nnpc->rwBegin(),nnpc->rwEnd(),[](double& v) { v=1./v; });
   const double *nnpcPtr(nnpc->begin());
@@ -3375,7 +3419,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const
               mcIdType offset=connI[i];
               INTERP_KERNEL::crossprod<3>(locPtr+3*i,coords+3*conn[offset+1],coords+3*conn[offset+2],vals);
               double n=INTERP_KERNEL::norm<3>(vals);
-              std::transform(vals,vals+3,vals,std::bind2nd(std::multiplies<double>(),1./n));
+              std::transform(vals,vals+3,vals,std::bind(std::multiplies<double>(),std::placeholders::_1,1./n));
             }
         }
       else
@@ -3394,7 +3438,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const
           mcIdType offset=connI[i];
           std::transform(coords+2*conn[offset+2],coords+2*conn[offset+2]+2,coords+2*conn[offset+1],tmp,std::minus<double>());
           double n=INTERP_KERNEL::norm<2>(tmp);
-          std::transform(tmp,tmp+2,tmp,std::bind2nd(std::multiplies<double>(),1./n));
+          std::transform(tmp,tmp+2,tmp,std::bind(std::multiplies<double>(),std::placeholders::_1,1./n));
           *vals++=-tmp[1];
           *vals++=tmp[0];
         }
@@ -3454,7 +3498,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildPartOrthogonalField(const mcIdTyp
               mcIdType offset=connI[*i];
               INTERP_KERNEL::crossprod<3>(locPtr,coords+3*conn[offset+1],coords+3*conn[offset+2],vals);
               double n=INTERP_KERNEL::norm<3>(vals);
-              std::transform(vals,vals+3,vals,std::bind2nd(std::multiplies<double>(),1./n));
+              std::transform(vals,vals+3,vals,std::bind(std::multiplies<double>(),std::placeholders::_1,1./n));
             }
         }
       else
@@ -3471,7 +3515,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildPartOrthogonalField(const mcIdTyp
           mcIdType offset=connI[*i];
           std::transform(coords+2*conn[offset+2],coords+2*conn[offset+2]+2,coords+2*conn[offset+1],tmp,std::minus<double>());
           double n=INTERP_KERNEL::norm<2>(tmp);
-          std::transform(tmp,tmp+2,tmp,std::bind2nd(std::multiplies<double>(),1./n));
+          std::transform(tmp,tmp+2,tmp,std::bind(std::multiplies<double>(),std::placeholders::_1,1./n));
           *vals++=-tmp[1];
           *vals++=tmp[0];
         }
@@ -5783,7 +5827,7 @@ DataArrayIdType *MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vect
  * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType.
  * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
  *
- * \param [in] profile
+ * \param [in] profile list of IDs constituing the profile
  * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method.
  * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i,
  *              \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
@@ -6202,8 +6246,8 @@ DataArrayIdType *MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh()
 /*!
  * Convert the nodal connectivity of the mesh so that all the cells are of dynamic types (polygon or quadratic
  * polygon). This returns the corresponding new nodal connectivity in \ref numbering-indirect format.
- * \param nodalConn
- * \param nodalConnI
+ * \param nodalConn nodal connectivity
+ * \param nodalConnIndex nodal connectivity indices
  */
 void MEDCouplingUMesh::convertNodalConnectivityToDynamicGeoTypeMesh(DataArrayIdType *&nodalConn, DataArrayIdType *&nodalConnIndex) const
 {
@@ -6386,7 +6430,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::Normalized
         for(mcIdType j=0;j<code[3*i+1];j++)
           *idsPtr++=offset+j;
       else
-        idsPtr=std::transform(idsPerGeoTypeBg,idsPerGeoTypeEnd,idsPtr,std::bind2nd(std::plus<mcIdType>(),offset));
+        idsPtr=std::transform(idsPerGeoTypeBg,idsPerGeoTypeEnd,idsPtr,std::bind(std::plus<mcIdType>(),std::placeholders::_1,offset));
       offset+=code[3*i+1];
     }
   MCAuto<MEDCouplingUMesh> ret=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(idsTokeep->begin(),idsTokeep->end(),true));
@@ -6521,7 +6565,7 @@ DataArrayDouble *MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell() const
             }
           mcIdType nbOfNodesInCell=nodalI[i+1]-nodalI[i]-1;
           if(nbOfNodesInCell>0)
-            std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(double)nbOfNodesInCell));
+            std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind(std::multiplies<double>(),std::placeholders::_1,1./(double)nbOfNodesInCell));
           else
             {
               std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of cell with no nodes !";
@@ -6543,7 +6587,7 @@ DataArrayDouble *MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell() const
                 }
             }
           if(!s.empty())
-            std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(double)s.size()));
+            std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind(std::multiplies<double>(),std::placeholders::_1,1./(double)s.size()));
           else
             {
               std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on polyhedron cell #" << i << " there are no nodes !";
@@ -6658,7 +6702,7 @@ DataArrayDouble *MEDCouplingUMesh::computePlaneEquationOf3DFaces() const
               for(mcIdType offset=nodalI[0]+1;offset<nodalI[1];offset++)
                 std::transform(coor+3*nodal[offset],coor+3*(nodal[offset]+1),dd,dd,std::plus<double>());
               mcIdType nbOfNodesInCell(nodalI[1]-nodalI[0]-1);
-              std::transform(dd,dd+3,dd,std::bind2nd(std::multiplies<double>(),1./(double)nbOfNodesInCell));
+              std::transform(dd,dd+3,dd,std::bind(std::multiplies<double>(),std::placeholders::_1,1./(double)nbOfNodesInCell));
               std::copy(dd,dd+3,matrix+4*2);
               INTERP_KERNEL::inverseMatrix(matrix,4,matrix2);
               retPtr[0]=matrix2[3]; retPtr[1]=matrix2[7]; retPtr[2]=matrix2[11]; retPtr[3]=matrix2[15];
@@ -6867,7 +6911,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const std::vector<c
       mcIdType meshLgth2=(*iter)->getNodalConnectivityArrayLen();
       nodalPtr=std::copy(nod,nod+meshLgth2,nodalPtr);
       if(iter!=meshes.begin())
-        nodalIndexPtr=std::transform(index+1,index+nbOfCells+1,nodalIndexPtr,std::bind2nd(std::plus<mcIdType>(),offset));
+        nodalIndexPtr=std::transform(index+1,index+nbOfCells+1,nodalIndexPtr,std::bind(std::plus<mcIdType>(),std::placeholders::_1,offset));
       else
         nodalIndexPtr=std::copy(index,index+nbOfCells+1,nodalIndexPtr);
       offset+=meshLgth2;
@@ -7161,8 +7205,7 @@ bool MEDCouplingUMesh::IsPyra5WellOriented(const mcIdType *begin, const mcIdType
  *
  * \param [in] eps is a relative precision that allows to establish if some 3D plane are coplanar or not.
  * \param [in] coords the coordinates with nb of components exactly equal to 3
- * \param [in] begin begin of the nodal connectivity (geometric type included) of a single polyhedron cell
- * \param [in] end end of nodal connectivity of a single polyhedron cell (excluded)
+ * \param [in] index begin of the nodal connectivity (geometric type included) of a single polyhedron cell
  * \param [out] res the result is put at the end of the vector without any alteration of the data.
  */
 void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, mcIdType index, DataArrayIdType *res, MEDCouplingUMesh *faces,
@@ -7336,7 +7379,7 @@ void MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(mcIdType *begin, mcIdTy
           nbOfEdgesInFace=std::distance(bgFace,endFace);
           if(!isPerm[i])
             {
-              bool b;
+              bool b=false;
               for(std::size_t j=0;j<nbOfEdgesInFace;j++)
                 {
                   std::pair<mcIdType,mcIdType> p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]);