]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Implementation of MEDCoupling1SGTUMesh.computeTriangleHeight and DataArrayDouble...
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 20 Dec 2022 15:13:16 +0000 (16:13 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 20 Dec 2022 15:13:16 +0000 (16:13 +0100)
src/INTERP_KERNEL/VolSurfUser.cxx
src/INTERP_KERNEL/VolSurfUser.hxx
src/MEDCoupling/MEDCoupling1GTUMesh.cxx
src/MEDCoupling/MEDCoupling1GTUMesh.hxx
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest7.py
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDCoupling_Swig/MEDCouplingMemArray.i

index 924d2bef57cbc37062490d9415fa7002e4ef41c2..fb9bb90f01f54df28b2c1c6efaeda419383ad65c 100644 (file)
@@ -21,6 +21,7 @@
 #include "VolSurfUser.hxx"
 #include "InterpKernelAutoPtr.hxx"
 #include "InterpolationUtils.hxx"
+#include "VectorUtils.hxx"
 
 #include <cmath>
 #include <limits>
@@ -276,5 +277,15 @@ namespace INTERP_KERNEL
     matrix[11]=-p0[0]*matrix[8]-p0[1]*matrix[9]-p0[2]*matrix[10];
     return true;
   }
-}
 
+  template<int SPACEDIM>
+  void ComputeTriangleHeight(const double *PA, const double *PB, const double *PC, double *res)
+  {
+    double AB = getDistanceBtw2Pts<SPACEDIM>(PA,PB);
+    double BC = getDistanceBtw2Pts<SPACEDIM>(PB,PC);
+    double CA = getDistanceBtw2Pts<SPACEDIM>(PC,PA);
+    double perim( (AB+BC+CA)*0.5 );
+    double num( 2*sqrt(perim*(perim-AB)*(perim-BC)*(perim-CA)) );
+    res[0] = num/AB; res[1] = num/BC; res[2] = num/CA;
+  }
+}
index 79e346f084f7b63ba9583024d2ee10c191697886..4682ed7ed65ebe2dd06377d914c2563f54418e3f 100644 (file)
@@ -49,6 +49,9 @@ namespace INTERP_KERNEL
   double INTERPKERNEL_EXPORT DistanceFromPtToPolygonInSpaceDim3(const double *pt, const mcIdType *connOfPolygonBg, const mcIdType *connOfPolygonEnd, const double *coords);
 
   bool ComputeRotTranslationMatrixToPut3PointsOnOXY(const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3, double *matrix);
+
+  template<int SPACEDIM>
+  void ComputeTriangleHeight(const double *PA, const double *PB, const double *PC, double *res);
 }
 
 #endif
index d0a5917c3290c0cdd9c53180c098fca218c8eb7b..8b656758300c9ff3eb8e5b065463498bf5f830fb 100644 (file)
@@ -27,6 +27,7 @@
 #include "DiameterCalculator.hxx"
 #include "OrientationInverter.hxx"
 #include "InterpKernelAutoPtr.hxx"
+#include "VolSurfUser.cxx"
 
 using namespace MEDCoupling;
 
@@ -1743,6 +1744,52 @@ MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
   return ret.retn();
 }
 
+/*!
+ * This method for each cell in \a this the triangle height for each edge in a newly allocated/created array instance.
+ *
+ * \return DataArrayDouble * - a newly allocated instance with this->getNumberOfCells() tuples and 3 components storing for each cell in \a this the corresponding  height.
+ * \throw If \a this is not a mesh containing only NORM_TRI3 cells.
+ * \throw If \a this is not properly allocated.
+ * \throw If spaceDimension is not in 2 or 3.
+ */
+MCAuto<DataArrayDouble> MEDCoupling1SGTUMesh::computeTriangleHeight() const
+{
+  checkConsistencyLight();
+  const INTERP_KERNEL::CellModel& cm(getCellModel());
+  if(cm.getEnum()!=INTERP_KERNEL::NORM_TRI3)
+    THROW_IK_EXCEPTION("MEDCoupling1SGTUMesh::computeTriangleHeight : this method can be applied only on TRI3 mesh !");
+  MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
+  mcIdType nbTri3( getNumberOfCells() );
+  const double *coordPtr( this->getCoords()->begin() );
+  const mcIdType *inConnPtr(getNodalConnectivity()->begin());
+  ret->alloc(nbTri3,3);
+  double *retPtr( ret->getPointer() );
+  switch( this->getSpaceDimension())
+  {
+    case 2:
+    {
+      constexpr unsigned SPACEDIM = 2;
+      for(mcIdType iCell = 0 ; iCell < nbTri3 ; ++iCell)
+      {
+        INTERP_KERNEL::ComputeTriangleHeight<SPACEDIM>(coordPtr + SPACEDIM*inConnPtr[3*iCell+0], coordPtr + SPACEDIM*inConnPtr[3*iCell+1], coordPtr + SPACEDIM*inConnPtr[3*iCell+2],retPtr+3*iCell);
+      }
+      break;
+    }
+    case 3:
+    {
+      constexpr unsigned SPACEDIM = 3;
+      for(mcIdType iCell = 0 ; iCell < nbTri3 ; ++iCell)
+      {
+        INTERP_KERNEL::ComputeTriangleHeight<SPACEDIM>(coordPtr + SPACEDIM*inConnPtr[3*iCell+0], coordPtr + SPACEDIM*inConnPtr[3*iCell+1], coordPtr + SPACEDIM*inConnPtr[3*iCell+2],retPtr+3*iCell);
+      }
+      break;
+    }
+    default:
+      THROW_IK_EXCEPTION("MEDCoupling1SGTUMesh::computeTriangleHeight : only spacedim in [2,3] supported !");
+  }
+  return ret;
+}
+
 /*!
  * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
  * If it is not the case, an exception will be thrown.
index c5ee4fb32f55acfcebbf5dcb21ad151ec191d952..fdfc7a7453b2abaf3d06aeaea4fbc0659f68de94 100644 (file)
@@ -158,6 +158,7 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT MEDCoupling1GTUMesh *computeDualMesh() const;
     MEDCOUPLING_EXPORT DataArrayIdType *sortHexa8EachOther();
     MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *explodeEachHexa8To6Quad4() const;
+    MEDCOUPLING_EXPORT MCAuto<DataArrayDouble> computeTriangleHeight() const;
     MEDCOUPLING_EXPORT MEDCouplingCMesh *structurizeMe(DataArrayIdType *& cellPerm, DataArrayIdType *& nodePerm, double eps=1e-12) const;
   public://serialization
     MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<mcIdType>& tinyInfo, std::vector<std::string>& littleStrings) const;
index 60d04080607fb88487e8e8e2c8c18e9219c24d3e..5006c10a8a7d002d5288c10e1a800c69207c5520 100755 (executable)
@@ -2337,16 +2337,7 @@ DataArrayDouble *DataArrayDouble::magnitude() const
   return ret;
 }
 
-/*!
- * Computes the maximal value within every tuple of \a this array.
- *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
- *          same number of tuples as \a this array and one component.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If \a this is not allocated.
- *  \sa DataArrayDouble::maxPerTupleWithCompoId
- */
-DataArrayDouble *DataArrayDouble::maxPerTuple() const
+DataArrayDouble *DataArrayDouble::operatePerTuple(std::function<double(const double *bg, const double *endd)> func) const
 {
   checkAllocated();
   std::size_t nbOfComp(getNumberOfComponents());
@@ -2356,10 +2347,38 @@ DataArrayDouble *DataArrayDouble::maxPerTuple() const
   const double *src=getConstPointer();
   double *dest=ret->getPointer();
   for(mcIdType i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
-    *dest=*std::max_element(src,src+nbOfComp);
+    *dest=func(src,src+nbOfComp);
   return ret.retn();
 }
 
+/*!
+ * Computes the maximal value within every tuple of \a this array.
+ *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
+ *          same number of tuples as \a this array and one component.
+ *          The caller is to delete this result array using decrRef() as it is no more
+ *          needed.
+ *  \throw If \a this is not allocated.
+ *  \sa DataArrayDouble::maxPerTupleWithCompoId, DataArrayDouble::minPerTuple
+ */
+DataArrayDouble *DataArrayDouble::maxPerTuple() const
+{
+  return this->operatePerTuple([](const double *bg, const double *endd) { return *std::max_element(bg,endd); });
+}
+
+/*!
+ * Computes the minimal value within every tuple of \a this array.
+ *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
+ *          same number of tuples as \a this array and one component.
+ *          The caller is to delete this result array using decrRef() as it is no more
+ *          needed.
+ *  \throw If \a this is not allocated.
+ *  \sa DataArrayDouble::maxPerTuple
+ */
+DataArrayDouble *DataArrayDouble::minPerTuple() const
+{
+  return this->operatePerTuple([](const double *bg, const double *endd) { return *std::min_element(bg,endd); });
+}
+
 /*!
  * Computes the maximal value within every tuple of \a this array and it returns the first component
  * id for each tuple that corresponds to the maximal value within the tuple.
index cc846eeae19a9490457827feab740075a392647e..ea18707e304a0e952e082f6e708ac18a335a8101 100755 (executable)
@@ -33,6 +33,7 @@
 #include <string>
 #include <vector>
 #include <iterator>
+#include <functional>
 
 namespace MEDCoupling
 {
@@ -497,6 +498,7 @@ namespace MEDCoupling
     DataArrayDouble *trace() const;
     DataArrayDouble *deviator() const;
     DataArrayDouble *magnitude() const;
+    DataArrayDouble *minPerTuple() const;
     DataArrayDouble *maxPerTuple() const;
     DataArrayDouble *maxPerTupleWithCompoId(DataArrayIdType* &compoIdOfMaxPerTuple) const;
     DataArrayDouble *buildEuclidianDistanceDenseMatrix() const;
@@ -544,6 +546,8 @@ namespace MEDCoupling
     template<int SPACEDIM>
     static void FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,mcIdType>& myTree, const double *pos, mcIdType nbOfTuples, double eps,
                                           DataArrayIdType *c, DataArrayIdType *cI);
+  private:
+    DataArrayDouble *operatePerTuple(std::function<double(const double *bg, const double *endd)> func) const;
   private:
     ~DataArrayDouble() { }
     DataArrayDouble() { }
index 36d144b4fa55f44fbd60a7a38764c0ee03b12b4e..a9a0c6006ea4bfb060e474885b3fa1701f436fad 100644 (file)
@@ -1119,6 +1119,19 @@ class MEDCouplingBasicsTest7(unittest.TestCase):
             delta_Z.abs()
             self.assertTrue(delta_Z.findIdsNotInRange(-1e-5,+1e-5).empty())
 
+    def testComputeTriangleHeight0(self):
+        arr = DataArrayDouble([0,1])
+        m = MEDCouplingCMesh() ; m.setCoords(arr,arr)
+        m = m.buildUnstructured() ; m.simplexize(0) ; m = MEDCoupling1SGTUMesh(m)
+        res = m.computeTriangleHeight()
+        expected = DataArrayDouble([(1.0, 1.0, sqrt(2)/2.0), (sqrt(2)/2.0, 1.0, 1.0)])
+        self.assertTrue( res.isEqual(expected,1e-12) )
+        m.changeSpaceDimension(3,100)
+        res2 = m.computeTriangleHeight()
+        self.assertTrue( res2.isEqual(expected,1e-12) )
+        expected2 = DataArrayDouble([sqrt(2)/2.0, sqrt(2)/2.0])
+        self.assertTrue( res2.minPerTuple().isEqual(expected2,1e-12) )
+
     pass
 
 if __name__ == '__main__':
index 7acf25f32b37f3425ea4c82832425e3256d20d06..1793504a52499ce337150f8dadaac754ad6f67d5 100644 (file)
@@ -413,6 +413,7 @@ typedef long mcPyPtrType;
 %newobject MEDCoupling::MEDCoupling1SGTUMesh::buildSetInstanceFromThis;
 %newobject MEDCoupling::MEDCoupling1SGTUMesh::computeDualMesh;
 %newobject MEDCoupling::MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4;
+%newobject MEDCoupling::MEDCoupling1SGTUMesh::computeTriangleHeight;
 %newobject MEDCoupling::MEDCoupling1SGTUMesh::sortHexa8EachOther;
 %newobject MEDCoupling::MEDCoupling1SGTUMesh::Merge1SGTUMeshes;
 %newobject MEDCoupling::MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords;
@@ -3204,6 +3205,12 @@ namespace MEDCoupling
         return ret;
       }
 
+      DataArrayDouble *MEDCoupling1SGTUMesh::computeTriangleHeight() const
+      {
+        MCAuto<DataArrayDouble> ret = self->computeTriangleHeight();
+        return ret.retn();
+      }
+
       static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(PyObject *li)
       {
         std::vector<const MEDCoupling::MEDCoupling1SGTUMesh *> tmp;
index bacf22e552481e27b2f7c1bf907b43921a5c25ae..f9ba14216295ba9e525edf3651c92ad5bc89eaaa 100644 (file)
 %newobject MEDCoupling::DataArrayDouble::deviator;
 %newobject MEDCoupling::DataArrayDouble::magnitude;
 %newobject MEDCoupling::DataArrayDouble::maxPerTuple;
+%newobject MEDCoupling::DataArrayDouble::minPerTuple;
 %newobject MEDCoupling::DataArrayDouble::sumPerTuple;
 %newobject MEDCoupling::DataArrayDouble::computeBBoxPerTuple;
 %newobject MEDCoupling::DataArrayDouble::buildEuclidianDistanceDenseMatrix;
@@ -1048,6 +1049,7 @@ typedef DataArrayInt64 DataArrayIdType;
     DataArrayDouble *deviator() const;
     DataArrayDouble *magnitude() const;
     DataArrayDouble *maxPerTuple() const;
+    DataArrayDouble *minPerTuple() const;
     DataArrayDouble *sumPerTuple() const;
     DataArrayDouble *buildEuclidianDistanceDenseMatrix() const;
     DataArrayDouble *buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const;