Salome HOME
Windows compilation.
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingStructuredMesh.cxx
index 5c5e4be8c60ca1625489efd1a69aaa7efb7cfa68..e737159ea3d3a800979363d645c84559ad0186ec 100644 (file)
@@ -209,6 +209,20 @@ int MEDCouplingStructuredMesh::getSpaceDimensionOnNodeStruct() const
   return spd1;
 }
 
+void MEDCouplingStructuredMesh::getSplitCellValues(int *res) const
+{
+  std::vector<int> strct(getCellGridStructure());
+  std::vector<int> ret(MEDCouplingStructuredMesh::GetSplitVectFromStruct(strct));
+  std::copy(ret.begin(),ret.end(),res);
+}
+
+void MEDCouplingStructuredMesh::getSplitNodeValues(int *res) const
+{
+  std::vector<int> strct(getNodeGridStructure());
+  std::vector<int> ret(MEDCouplingStructuredMesh::GetSplitVectFromStruct(strct));
+  std::copy(ret.begin(),ret.end(),res);
+}
+
 /*!
  * This method returns the number of cells of unstructured sub level mesh, without building it.
  */
@@ -643,6 +657,48 @@ DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh
   }
 }
 
+/*!
+ * This method retrieves the number of entities (it can be cells or nodes) given a range in compact standard format
+ * used in methods like BuildExplicitIdsFrom,IsPartStructured.
+ *
+ * \sa BuildExplicitIdsFrom,IsPartStructured
+ */
+int MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(const std::vector< std::pair<int,int> >& partCompactFormat)
+{
+  int ret(1);
+  bool isFetched(false);
+  std::size_t ii(0);
+  for(std::vector< std::pair<int,int> >::const_iterator it=partCompactFormat.begin();it!=partCompactFormat.end();it++,ii++)
+    {
+      int a((*it).first),b((*it).second);
+      if(a<0 || b<0 || b-a<0)
+        {
+          std::ostringstream oss; oss << "MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt : invalid input at dimension " << ii << " !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      if(b-a>0)
+        {
+          isFetched=true;
+          ret*=(b-a);
+        }
+    }
+  return isFetched?ret:0;
+}
+
+int MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(const std::vector<int>& st)
+{
+  int ret(1);
+  bool isFetched(false);
+  for(std::size_t i=0;i<st.size();i++)
+    {
+      if(st[i]<0)
+        throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure : presence of a negative value in structure !");
+      ret*=st[i];
+      isFetched=true;
+    }
+  return isFetched?ret:0;
+}
+
 DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivity1D(const int *nodeStBg)
 {
   int nbOfCells(*nodeStBg-1);
@@ -862,11 +918,29 @@ std::vector<int> MEDCouplingStructuredMesh::getCellGridStructure() const
   return ret;
 }
 
+/*!
+ * Given a struct \a strct it returns a split vector [1,strct[0],strct[0]*strct[1]...]
+ * This decomposition allows to quickly find i,j,k given a global id.
+ */
+std::vector<int> MEDCouplingStructuredMesh::GetSplitVectFromStruct(const std::vector<int>& strct)
+{
+  int spaceDim((int)strct.size());
+  std::vector<int> res(spaceDim);
+  for(int l=0;l<spaceDim;l++)
+    {
+      int val=1;
+      for(int p=0;p<spaceDim-l-1;p++)
+        val*=strct[p];
+      res[spaceDim-l-1]=val;
+    }
+  return res;
+}
+
 /*!
  * This method states if given part ids [ \a startIds, \a stopIds) and a structure \a st returns if it can be considered as a structured dataset.
  * If true is returned \a partCompactFormat will contain the information to build the corresponding part.
  *
- * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom
+ * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt
  */
 bool MEDCouplingStructuredMesh::IsPartStructured(const int *startIds, const int *stopIds, const std::vector<int>& st, std::vector< std::pair<int,int> >& partCompactFormat)
 {
@@ -953,12 +1027,75 @@ bool MEDCouplingStructuredMesh::IsPartStructured(const int *startIds, const int
   }
 }
 
+std::vector<int> MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(const std::vector< std::pair<int,int> >& partCompactFormat)
+{
+  std::vector<int> ret(partCompactFormat.size());
+  for(std::size_t i=0;i<partCompactFormat.size();i++)
+    ret[i]=partCompactFormat[i].second-partCompactFormat[i].first;
+  return ret;
+}
+
+/*!
+ * This method is close to BuildExplicitIdsFrom except that instead of returning a DataArrayInt instance containing explicit ids it
+ * enable elems in the vector of booleans (for performance reasons). As it is method for performance, this method is \b not
+ * available in python.
+ *
+ * \param [in] st The entity structure.
+ * \param [in] partCompactFormat The compact subpart to be enabled.
+ * \param [in,out] vectToSwitchOn Vector which fetched items are enabled.
+ *
+ * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom
+ */
+void MEDCouplingStructuredMesh::SwitchOnIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat, std::vector<bool>& vectToSwitchOn)
+{
+  if(st.size()!=partCompactFormat.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : input arrays must have the same size !");
+  if((int)vectToSwitchOn.size()!=DeduceNumberOfGivenStructure(st))
+    throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : invalid size of input vector of boolean regarding the structure !");
+  std::vector<int> dims(GetDimensionsFromCompactFrmt(partCompactFormat));
+  switch(st.size())
+  {
+    case 3:
+      {
+        for(int i=0;i<dims[2];i++)
+          {
+            int a=(partCompactFormat[2].first+i)*st[0]*st[1];
+            for(int j=0;j<dims[1];j++)
+              {
+                int b=(partCompactFormat[1].first+j)*st[0];
+                for(int k=0;k<dims[0];k++)
+                  vectToSwitchOn[partCompactFormat[0].first+k+b+a]=true;
+              }
+          }
+        break;
+      }
+    case 2:
+      {
+        for(int j=0;j<dims[1];j++)
+          {
+            int b=(partCompactFormat[1].first+j)*st[0];
+            for(int k=0;k<dims[0];k++)
+              vectToSwitchOn[partCompactFormat[0].first+k+b]=true;
+          }
+        break;
+      }
+    case 1:
+      {
+        for(int k=0;k<dims[0];k++)
+          vectToSwitchOn[partCompactFormat[0].first+k]=true;
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : Dimension supported are 1,2 or 3 !");
+  }
+}
+
 /*!
  * This method builds the explicit entity array from the structure in \a st and the range in \a partCompactFormat.
- *If the range contains invalid values regarding sructure an exception will be thrown.
+ * If the range contains invalid values regarding sructure an exception will be thrown.
  *
  * \return DataArrayInt * - a new object.
- * \sa MEDCouplingStructuredMesh::IsPartStructured
+ * \sa MEDCouplingStructuredMesh::IsPartStructured, MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt, SwitchOnIdsFrom
  */
 DataArrayInt *MEDCouplingStructuredMesh::BuildExplicitIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat)
 {