Salome HOME
Merge branch 'master' of salome:modules/med
[tools/medcoupling.git] / src / MEDCoupling / MEDCoupling1GTUMesh.cxx
index 3e15f5255aa5459a5c40c0c87bb221d8574e510e..0724620a53155ffd4880dfcd4301b4d3e9260ab6 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2014  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
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 using namespace ParaMEDMEM;
 
-MEDCoupling1GTUMesh::MEDCoupling1GTUMesh()
+const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5};
+
+MEDCoupling1GTUMesh::MEDCoupling1GTUMesh():_cm(0)
 {
 }
 
-MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
+MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
 {
   setName(name);
 }
@@ -39,7 +41,7 @@ MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool
 {
 }
 
-MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type)
+MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
 {
   if(type==INTERP_KERNEL::NORM_ERROR)
     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
@@ -402,7 +404,7 @@ MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::v
     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
   const DataArrayDouble *coords(firstPart->getCoords());
   int meshDim(firstPart->getMeshDimension());
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName().c_str(),meshDim)); ret->setDescription(firstPart->getDescription().c_str());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription());
   ret->setCoords(coords);
   int nbOfCells(0),connSize(0);
   for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
@@ -465,7 +467,7 @@ MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bo
     }
 }
 
-MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
+MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
 {
 }
 
@@ -478,7 +480,7 @@ MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
   return new MEDCoupling1SGTUMesh;
 }
 
-MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type)
+MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
 {
   if(type==INTERP_KERNEL::NORM_ERROR)
     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
@@ -499,8 +501,8 @@ MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m)
   if(gts.size()!=1)
     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
   int geoType((int)*gts.begin());
-  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName().c_str(),*gts.begin()));
-  ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin()));
+  ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
   int nbCells(m->getNumberOfCells());
   int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
@@ -824,15 +826,15 @@ std::string MEDCoupling1SGTUMesh::advancedRepr() const
         {
           if(_conn->getNumberOfComponents()==1)
             {
-             int nbOfCells=getNumberOfCells();
-             int sz=getNumberOfNodesPerCell();
-             const int *connPtr=_conn->begin();
-             for(int i=0;i<nbOfCells;i++,connPtr+=sz)
-               {
-                 ret << "Cell #" << i << " : ";
-                 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
-                 ret << "\n";
-               }
+              int nbOfCells=getNumberOfCells();
+              int sz=getNumberOfNodesPerCell();
+              const int *connPtr=_conn->begin();
+              for(int i=0;i<nbOfCells;i++,connPtr+=sz)
+                {
+                  ret << "Cell #" << i << " : ";
+                  std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
+                  ret << "\n";
+                }
             }
           else
             ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
@@ -947,7 +949,7 @@ MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *ot
 
 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
   ret->setCoords(getCoords());
   const int *nodalConn=_conn->begin();
   int nbCells=getNumberOfCells();
@@ -968,18 +970,18 @@ MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy)
 {
   switch(policy)
-    {
+  {
     case 0:
       return simplexizePol0();
     case 1:
       return simplexizePol1();
     case (int) INTERP_KERNEL::PLANAR_FACE_5:
-      return simplexizePlanarFace5();
+        return simplexizePlanarFace5();
     case (int) INTERP_KERNEL::PLANAR_FACE_6:
-      return simplexizePlanarFace6();
+        return simplexizePlanarFace6();
     default:
       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::simplexize : unrecognized policy ! Must be :\n  - 0 or 1 (only available for meshdim=2) \n  - PLANAR_FACE_5, PLANAR_FACE_6  (only for meshdim=3)");
-    }
+  }
 }
 
 /// @cond INTERNAL
@@ -1102,10 +1104,9 @@ MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::ve
   if(!(*it))
     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
   std::vector<const DataArrayInt *> ncs(a.size());
-  int nbOfCells=(*it)->getNumberOfCells();
+  (*it)->getNumberOfCells();//to check that all is OK
   const DataArrayDouble *coords=(*it)->getCoords();
   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
-  int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
   ncs[0]=(*it)->getNodalConnectivity();
   it++;
   for(int i=1;it!=a.end();i++,it++)
@@ -1167,7 +1168,7 @@ MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const
 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
 {
   int ncell=getNumberOfCells();
-  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
   ret->setCoords(_coords);
   std::size_t nbOfElemsRet=std::distance(begin,end);
   const int *inConn=_conn->getConstPointer();
@@ -1193,7 +1194,7 @@ MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int star
 {
   int ncell=getNumberOfCells();
   int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
-  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
   ret->setCoords(_coords);
   const int *inConn=_conn->getConstPointer();
   int sz=getNumberOfNodesPerCell();
@@ -1236,7 +1237,7 @@ void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) co
 
 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
   const DataArrayInt *nodalConn(_conn);
   if(!nodalConn)
@@ -1441,9 +1442,9 @@ void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD,
 {
   INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
   _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
-  setName(littleStrings[0].c_str());
-  setDescription(littleStrings[1].c_str());
-  setTimeUnit(littleStrings[2].c_str());
+  setName(littleStrings[0]);
+  setDescription(littleStrings[1]);
+  setTimeUnit(littleStrings[2]);
   setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
   int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
   //
@@ -1623,14 +1624,184 @@ MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
   if(!cm.isSimplex())
     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
   switch(getMeshDimension())
-    {
+  {
     case 3:
       return computeDualMesh3D();
     case 2:
       return computeDualMesh2D();
     default:
       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
+  }
+}
+
+/*!
+ * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
+ * 
+ * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
+ * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
+ * \throw If \a this is not properly allocated.
+ */
+MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
+{
+  const INTERP_KERNEL::CellModel& cm(getCellModel());
+  if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
+    throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
+  int nbHexa8(getNumberOfCells());
+  const int *inConnPtr(getNodalConnectivity()->begin());
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1);
+  int *cPtr(c->getPointer());
+  for(int i=0;i<nbHexa8;i++,inConnPtr+=8)
+    {
+      for(int j=0;j<6;j++,cPtr+=4)
+        cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
+    }
+  ret->setCoords(getCoords());
+  ret->setNodalConnectivity(c);
+  return ret.retn();
+}
+
+/// @cond INTERNAL
+
+bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours)
+{
+  static const int TAB[48]={
+    0,1,2,3,4,5,6,7,//0
+    4,7,6,5,0,3,2,1,//1
+    0,3,7,4,1,2,6,5,//2
+    4,0,3,7,5,1,2,6,//3
+    5,1,0,4,6,2,3,7,//4
+    3,7,4,0,2,6,5,1 //5
+  };
+  static const int TAB2[6]={0,0,3,3,3,3};
+  if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
+    return true;
+  int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
+  std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
+  std::size_t pos0(pos/2),pos1(pos%2);
+  int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
+  int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
+  oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
+  oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
+  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
+  for(int i=0;i<4;i++)
+    myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
+  for(int i=0;i<4;i++)
+    {
+      int nodeId(myConn2[i]);//the node id for which the opposite one will be found
+      bool found(false);
+      INTERP_KERNEL::NormalizedCellType typeOfSon;
+      for(int j=0;j<12 && !found;j++)
+        {
+          cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
+          if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
+            {
+              if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
+                {
+                  myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
+                  found=true;
+                }
+            }
+        }
+      if(!found)
+        throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
+    }
+  const int *myTab(TAB+8*validAxis);
+  for(int i=0;i<8;i++)
+    myConn[i]=myConn2[myTab[i]];
+  for(int i=0;i<6;i++)
+    {
+      cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
+      std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
+      bool found(false);
+      for(int j=0;j<6 && !found;j++)
+        {
+          std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
+          if(s==s1)
+            {
+              neighTmp[i]=myNeighbours[j];
+              found=true;
+            }
+        }
+      if(!found)
+        throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
     }
+  std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
+  std::copy(neighTmp,neighTmp+6,myNeighbours);
+  return false;
+}
+
+/// @endcond
+
+/*!
+ * This method expects the \a this contains NORM_HEXA8 cells only. This method will sort each cells in \a this so that their numbering was
+ * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
+ *
+ * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
+ *
+ * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
+ * \throw If \a this is not properly allocated.
+ * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
+ */
+DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
+  int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
+  int *ptNeigh(neighOfQuads->getPointer());
+  {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
+    MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
+    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ccSafe,cciSafe;
+    DataArrayInt *cc(0),*cci(0);
+    quadsTmp->findCommonCells(3,0,cc,cci);
+    ccSafe=cc; cciSafe=cci;
+    const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
+    for(int i=0;i<nbOfPair;i++)
+      { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
+  }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+  std::vector<bool> fetched(nbHexa8,false);
+  std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
+  while(it!=fetched.end())//it will turns as time as number of connected zones
+    {
+      int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
+      std::set<int> s; s.insert(cellId);//s contains already organized.
+      while(!s.empty())
+        {
+          std::set<int> sNext;
+          for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
+            {
+              fetched[*it0]=true;
+              int *myNeighb(ptNeigh+6*(*it0));
+              for(int i=0;i<6;i++)
+                {
+                  if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
+                    {
+                      std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
+                      std::size_t pos0(pos/2),pos1(pos%2);
+                      if(!UpdateHexa8Cell(HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2],*it0,cQuads+6*4*(*it0)+4*i,cQuads+6*4*myNeighb[i],ptNeigh+6*myNeighb[i]))
+                        ret->pushBackSilent(myNeighb[i]);
+                      fetched[myNeighb[i]]=true;
+                      sNext.insert(myNeighb[i]);
+                    }
+                }
+            }
+          s=sNext;
+        }
+      it=std::find(fetched.begin(),fetched.end(),false);
+    }
+  if(!ret->empty())
+    {
+      int *conn(getNodalConnectivity()->getPointer());
+      for(const int *pt=ret->begin();pt!=ret->end();pt++)
+        {
+          int cellId(*pt);
+          conn[8*cellId+0]=cQuads[24*cellId+0]; conn[8*cellId+1]=cQuads[24*cellId+1]; conn[8*cellId+2]=cQuads[24*cellId+2]; conn[8*cellId+3]=cQuads[24*cellId+3];
+          conn[8*cellId+4]=cQuads[24*cellId+4]; conn[8*cellId+5]=cQuads[24*cellId+7]; conn[8*cellId+6]=cQuads[24*cellId+6]; conn[8*cellId+7]=cQuads[24*cellId+5];
+        }
+      declareAsNew();
+    }
+  return ret.retn();
 }
 
 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
@@ -1660,14 +1831,14 @@ MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
   const int *d1(d1Arr->begin());
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr));  thisu=0;
-  const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
+  const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
   const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
   edges=0; faces=0;
   std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
   std::string name("DualOf_"); name+=getName();
-  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
   for(int i=0;i<nbOfNodes;i++,revNodI++)
     {
@@ -1732,14 +1903,14 @@ MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
   const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr));  thisu=0;
-  const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
+  const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
   const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
   edges=0;
   std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
   std::string name("DualOf_"); name+=getName();
-  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
   for(int i=0;i<nbOfNodes;i++,revNodI++)
     {
@@ -1789,12 +1960,14 @@ MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
 /*!
  * This method aggregate the bbox of each cell and put it into bbox 
  *
+ * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12)
+ *                         For all other cases this input parameter is ignored.
  * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
  * 
  * \throw If \a this is not fully set (coordinates and connectivity).
  * \throw If a cell in \a this has no valid nodeId.
  */
-DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree() const
+DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
 {
   int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
@@ -1838,7 +2011,7 @@ MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
   return new MEDCoupling1DGTUMesh;
 }
 
-MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type)
+MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
 {
   if(type==INTERP_KERNEL::NORM_ERROR)
     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
@@ -1855,7 +2028,7 @@ MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
 {
 }
 
-MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
+MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
 {
 }
 
@@ -2285,10 +2458,10 @@ std::string MEDCoupling1DGTUMesh::simpleRepr() const
   ret << "Number of cells : ";
   bool isOK=true;
   try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
-    {
+  {
       ret << "Nodal connectivity arrays are not set or badly set !\n";
       isOK=false;
-    }
+  }
   if(isOK)
     ret << getNumberOfCells() << "\n";
   ret << "Cell type : " << _cm->getRepr() << "\n";
@@ -2308,10 +2481,10 @@ std::string MEDCoupling1DGTUMesh::advancedRepr() const
   //
   bool isOK=true;
   try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */)
-    {
+  {
       ret << "Nodal connectivity arrays are not set or badly set !\n";
       isOK=false;
-    }
+  }
   if(!isOK)
     return ret.str();
   int nbOfCells=getNumberOfCells();
@@ -2434,7 +2607,6 @@ void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
   //
   for(int i=0;i<nbCells;i++,conni++)
     {
-      int sz=conni[1]-conni[0];
       int newp=o2nPtr[i];
       std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
     }
@@ -2452,7 +2624,7 @@ MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *ot
 
 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
   ret->setCoords(getCoords());
   const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
   int nbCells=getNumberOfCells();//checkCoherency
@@ -2504,10 +2676,10 @@ void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
   bool isOK=true;
   try { checkCoherency(); } catch(INTERP_KERNEL::Exception&  /* e */)
-    {
+  {
       stream << std::endl << "Nodal connectivity NOT set properly !\n";
       isOK=false;
-    }
+  }
   if(isOK)
     stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
 }
@@ -2538,7 +2710,7 @@ MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MED
 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
 {
   checkCoherency();
-  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
   ret->setCoords(_coords);
   DataArrayInt *c=0,*ci=0;
   MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
@@ -2550,7 +2722,7 @@ MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int
 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
 {
   checkCoherency();
-  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
   ret->setCoords(_coords);
   DataArrayInt *c=0,*ci=0;
   MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
@@ -2728,9 +2900,9 @@ void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD,
 {
   INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
   _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
-  setName(littleStrings[0].c_str());
-  setDescription(littleStrings[1].c_str());
-  setTimeUnit(littleStrings[2].c_str());
+  setName(littleStrings[0]);
+  setDescription(littleStrings[1]);
+  setTimeUnit(littleStrings[2]);
   setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
   int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
   //
@@ -2967,7 +3139,7 @@ DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
  */
 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
   DataArrayInt *nc=0,*nci=0;
   isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
@@ -3083,7 +3255,7 @@ MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::ve
     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
-  int nbOfCells=(*it)->getNumberOfCells();
+  (*it)->getNumberOfCells();//to check that all is OK
   const DataArrayDouble *coords=(*it)->getCoords();
   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
   bool tmp;
@@ -3150,7 +3322,7 @@ MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const
 
 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
   const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
   if(!nodalConn)
@@ -3182,12 +3354,14 @@ MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDi
 /*!
  * This method aggregate the bbox of each cell and put it into bbox parameter.
  * 
+ * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12)
+ *                         For all other cases this input parameter is ignored.
  * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
  * 
  * \throw If \a this is not fully set (coordinates and connectivity).
  * \throw If a cell in \a this has no valid nodeId.
  */
-DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree() const
+DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
 {
   checkFullyDefined();
   int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
@@ -3307,8 +3481,8 @@ MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
   if(gts.size()!=1)
     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
   int geoType((int)*gts.begin());
-  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName().c_str(),*gts.begin()));
-  ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
+  ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
   int nbCells(m->getNumberOfCells());
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
   conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);