Salome HOME
scotch6.0.4 needs pthread... Quick and dirty solution to be improved
[tools/medcoupling.git] / src / MEDCoupling / MEDCoupling1GTUMesh.cxx
index 5dafba902b7cf6050cdd25a670904fbc92a6cd93..93b40394995c4343170959de07726eda2be8d589 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2016  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
@@ -25,6 +25,7 @@
 
 #include "SplitterTetra.hxx"
 #include "DiameterCalculator.hxx"
+#include "OrientationInverter.hxx"
 #include "InterpKernelAutoPtr.hxx"
 
 using namespace MEDCoupling;
@@ -107,7 +108,7 @@ DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCe
 /*!
  * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
  */
-int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
+std::size_t MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
 {
   return type==getCellModelEnum()?getNumberOfCells():0;
 }
@@ -118,9 +119,9 @@ int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellT
  *  \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
  *  \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
  */
-INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
+INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(std::size_t cellId) const
 {
-  if(cellId>=0 && cellId<getNumberOfCells())
+  if(cellId<getNumberOfCells())
     return getCellModelEnum();
   std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
   throw INTERP_KERNEL::Exception(oss.str().c_str());
@@ -144,7 +145,7 @@ std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes(
  * \a this is composed in cell types.
  * The returned array is of size 3*n where n is the number of different types present in \a this. 
  * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here. 
- * This parameter is kept only for compatibility with other methode listed above.
+ * This parameter is kept only for compatibility with other method listed above.
  */
 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const
 {
@@ -177,7 +178,7 @@ std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const
  *          - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
 
  */
-void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
+void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType, bool smartPflKiller) const
 {
   if(!profile)
     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
@@ -187,7 +188,7 @@ void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::
   code.resize(3); idsInPflPerType.resize(1);
   code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
   idsInPflPerType.resize(1);
-  if(profile->isIota(nbOfCells))
+  if(smartPflKiller && profile->isIota(nbOfCells))
     {
       code[2]=-1;
       idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
@@ -329,10 +330,19 @@ MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) c
  */
 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
 {
-  MCAuto<MEDCouplingUMesh> m=buildUnstructured();
+  MCAuto<MEDCouplingUMesh> m(buildUnstructured());
   return m->getCellContainingPoint(pos,eps);
 }
 
+/*!
+ * to improve perf !
+ */
+void MEDCoupling1GTUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
+{
+  MCAuto<MEDCouplingUMesh> m(buildUnstructured());
+  return m->getCellsContainingPoint(pos,eps,elts);
+}
+
 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
 {
   MCAuto<MEDCouplingUMesh> m=buildUnstructured();
@@ -377,7 +387,7 @@ void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArr
   m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
 }
 
-int MEDCoupling1GTUMesh::getNodalConnectivityLength() const
+std::size_t MEDCoupling1GTUMesh::getNodalConnectivityLength() const
 {
   const DataArrayInt *c1(getNodalConnectivity());
   if(!c1)
@@ -690,10 +700,10 @@ void MEDCoupling1SGTUMesh::checkConsistency(double eps) const
       }
 }
 
-int MEDCoupling1SGTUMesh::getNumberOfCells() const
+std::size_t MEDCoupling1SGTUMesh::getNumberOfCells() const
 {
-  int nbOfTuples=getNodalConnectivityLength();
-  int nbOfNodesPerCell=getNumberOfNodesPerCell();
+  std::size_t nbOfTuples(getNodalConnectivityLength());
+  int nbOfNodesPerCell(getNumberOfNodesPerCell());
   if(nbOfTuples%nbOfNodesPerCell!=0)
     {
       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh:getNumberOfCells: : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
@@ -748,11 +758,11 @@ DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const
   return ret.retn();
 }
 
-void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
+void MEDCoupling1SGTUMesh::getNodeIdsOfCell(std::size_t cellId, std::vector<int>& conn) const
 {
   int sz=getNumberOfNodesPerCell();
   conn.resize(sz);
-  if(cellId>=0 && cellId<getNumberOfCells())
+  if(cellId<getNumberOfCells())
     std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
   else
     {
@@ -1625,7 +1635,7 @@ void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn)
 }
 
 /*!
- * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
+ * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not responsible to deallocate it.
  */
 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
 {
@@ -1636,7 +1646,7 @@ DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
 /*!
  * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
  * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
- * If a nodal connectivity previouly existed before the call of this method, it will be reset.
+ * If a nodal connectivity previously existed before the call of this method, it will be reset.
  *
  *  \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
  */
@@ -1656,7 +1666,7 @@ void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells)
  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
  * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type
  *        attached to \a this.
- * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
+ * \throw If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
  */
 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
 {
@@ -2129,6 +2139,22 @@ MEDCouplingFieldDouble *MEDCoupling1SGTUMesh::computeDiameterField() const
   return ret.retn();
 }
 
+/*!
+ * This method invert orientation of all cells in \a this. 
+ * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
+ * This method only operates on the connectivity so coordinates are not touched at all.
+ */
+void MEDCoupling1SGTUMesh::invertOrientationOfAllCells()
+{
+  checkConsistencyOfConnectivity();
+  INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
+  int nbOfNodesPerCell((int)_cm->getNumberOfNodes()),nbCells(getNumberOfCells());
+  int *conn(_conn->getPointer());
+  for(int i=0;i<nbCells;i++)
+    oi->operate(conn+i*nbOfNodesPerCell,conn+(i+1)*nbOfNodesPerCell);
+  updateTime();
+}
+
 //== 
 
 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
@@ -2357,7 +2383,7 @@ void MEDCoupling1DGTUMesh::checkConsistencyOfConnectivity() const
       if(c1->getInfoOnComponent(0)!="")
         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
       int f=c1->front(),ll=c1->back();
-      if(f<0 || f>=sz2)
+      if(f<0 || (sz2>0 && f>=sz2))
         {
           std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
@@ -2415,7 +2441,7 @@ void MEDCoupling1DGTUMesh::checkConsistency(double eps) const
     }
 }
 
-int MEDCoupling1DGTUMesh::getNumberOfCells() const
+std::size_t MEDCoupling1DGTUMesh::getNumberOfCells() const
 {
   checkConsistencyOfConnectivity();//do not remove
   return _conn_indx->getNumberOfTuples()-1;
@@ -2510,10 +2536,10 @@ DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
   return ret.retn();
 }
 
-void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
+void MEDCoupling1DGTUMesh::getNodeIdsOfCell(std::size_t cellId, std::vector<int>& conn) const
 {
-  int nbOfCells(getNumberOfCells());//performs checks
-  if(cellId>=0 && cellId<nbOfCells)
+  std::size_t nbOfCells(getNumberOfCells());//performs checks
+  if(cellId<nbOfCells)
     {
       int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
       int nbOfNodes=stp-strt;
@@ -3276,16 +3302,16 @@ void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
  * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type
  *        attached to \a this.
- * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
+ * \throw If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
  */
 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
 {
-  int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
+  std::size_t sz(std::distance(nodalConnOfCellBg,nodalConnOfCellEnd));
   DataArrayInt *c(_conn),*c2(_conn_indx);
   if(c && c2)
     {
       int pos=c2->back();
-      if(pos==c->getNumberOfTuples())
+      if(pos==(int)c->getNumberOfTuples())
         {
           c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
           c2->pushBackSilent(pos+sz);
@@ -3312,7 +3338,7 @@ void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArr
 }
 
 /*!
- * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
+ * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not responsible to deallocate it.
  */
 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
 {
@@ -3321,7 +3347,7 @@ DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
 }
 
 /*!
- * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
+ * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not responsible to deallocate it.
  */
 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
 {
@@ -3402,7 +3428,7 @@ bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalC
 bool MEDCoupling1DGTUMesh::isPacked() const
 {
   checkConsistencyLight();
-  return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
+  return _conn_indx->front()==0 && _conn_indx->back()==(int)_conn->getNumberOfTuples();
 }
 
 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
@@ -3638,6 +3664,23 @@ std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector<
   return ret;
 }
 
+/*!
+ * This method invert orientation of all cells in \a this. 
+ * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
+ * This method only operates on the connectivity so coordinates are not touched at all.
+ */
+void MEDCoupling1DGTUMesh::invertOrientationOfAllCells()
+{
+  checkConsistencyOfConnectivity();
+  INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
+  int nbCells(getNumberOfCells());
+  const int *connI(_conn_indx->begin());
+  int *conn(_conn->getPointer());
+  for(int i=0;i<nbCells;i++)
+    oi->operate(conn+connI[i],conn+connI[i+1]);
+  updateTime();
+}
+
 /*!
  * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the 
  * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.