Salome HOME
[Intersect2D] Bug fix: residual cell construction
[tools/medcoupling.git] / src / MEDCoupling_Swig / MEDCouplingIntersectTest.py
index a53fe2f592cba3b7ba0adc0e1b1cec062ba22d07..3887e6f723c1f5796f98481bad8b4539eecce6d5 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: utf-8 -*-
-# Copyright (C) 2007-2019  CEA/DEN, EDF R&D
+# Copyright (C) 2007-2021  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
@@ -23,7 +23,7 @@ import sys
 if sys.platform == "win32":
     from MEDCouplingCompat import *
 else:
-    from MEDCoupling import *
+    from medcoupling import *
 import unittest
 from math import pi,e,sqrt,cos,sin
 from datetime import datetime
@@ -439,6 +439,32 @@ class MEDCouplingIntersectTest(unittest.TestCase):
         self.assertEqual(e2, res2Tool.getValues())
         pass
 
+    def testIntersect2DMeshes11(self):
+        """ Dealing properly with respective polygon orientation in QuadraticPolygon::haveIAChanceToBeCompletedBy()
+        The two polygons below have same orientation, but one edge of pol1 is colinear to pol2 in opposite directions.
+        """
+        eps = 1.0e-8
+        back = MEDCouplingUMesh('lback', 2)
+        coo = DataArrayDouble([(-2.5,-2.5),(-2.5,2.5),(2.5,2.5),(2.5,-2.5),(0,0),(0,1.66667),(1.66667,1.66667),(1.66667,0)])
+        back.setCoords(coo)
+        c = DataArrayInt([5, 6, 7, 4, 5, 2, 3, 7, 6, 5, 3, 0, 1, 2, 6, 4, 7])
+        cI = DataArrayInt([0, 4, 9, 17])
+        back.setConnectivity(c, cI)
+
+        tool = MEDCouplingUMesh('ltool', 2)
+        coo = DataArrayDouble([(0,0),(0,2.5),(2.5,2.5),(2.5,0)])
+        tool.setCoords(coo)
+        c = DataArrayInt([5, 0, 1, 2, 3])
+        cI = DataArrayInt([0, 5])
+        tool.setConnectivity(c, cI)
+
+        result, res2Back, res2Tool = MEDCouplingUMesh.Intersect2DMeshes(back, tool, eps)
+        self.assertEqual(result.getNodalConnectivity().getValues(), [5, 7, 8, 6, 5, 7, 6, 10, 11, 5, 11, 3, 7, 5, 9, 10, 6, 8, 5, 8, 7, 3, 0, 1, 9])
+        self.assertEqual(result.getNodalConnectivityIndex().getValues(), [0, 4, 9, 13, 18, 25])
+        self.assertEqual(res2Back.getValues(), [0, 1, 1, 2, 2])
+        self.assertEqual(res2Tool.getValues(), [0, 0, -1, 0, -1])
+        pass
+
     def testSwig2Intersect2DMeshesQuadra1(self):
         import cmath
         def createDiagCircle(lX, lY, R, cells=[0,1]):
@@ -671,6 +697,43 @@ class MEDCouplingIntersectTest(unittest.TestCase):
         self.assertEqual(res2Tool.getValues(), [0, -1, -1])
         pass
 
+    def testIntersect2DMeshesTmp13(self):
+        """ Bug fix: when part of mesh2 is fully included in mesh1 and some points of mesh2 are touching edges of mesh1, reconstruction of
+        residual cells was not properly done.
+        """
+        eps = 1.0e-6
+        # First case: only two points of mesh2 touching edges of mesh1
+        coo1 = DataArrayDouble([(0,0) , (1,1),  (1,0)])
+        mesh1 = MEDCouplingUMesh("mesh1", 2)
+        mesh1.setCoords(coo1)
+        c = DataArrayInt([NORM_TRI3, 0,1,2])
+        cI = DataArrayInt([0,4])
+        mesh1.setConnectivity(c, cI)
+
+        coo2 = DataArrayDouble([(0.5,0) , (0.5,0.5),  (0.7,0.25)])
+        mesh2 = MEDCouplingUMesh("mesh1", 2)
+        mesh2.setCoords(coo2)
+        c = DataArrayInt([NORM_TRI3, 0,1,2])
+        cI = DataArrayInt([0,4])
+        mesh2.setConnectivity(c, cI)
+
+        meshinter, res2Back, res2Tool = MEDCouplingUMesh.Intersect2DMeshes(mesh1,mesh2,eps)
+        self.assertEqual(meshinter.getNodalConnectivity().getValues(), [5, 3, 4, 5, 5, 4, 1, 2, 3, 5, 5, 3, 0, 4])
+        self.assertEqual(meshinter.getNodalConnectivityIndex().getValues(), [0, 4, 10, 14])
+        self.assertEqual(res2Back.getValues(), [0, 0, 0])
+        self.assertEqual(res2Tool.getValues(), [0, -1, -1])
+
+        # Second case: all three points of mesh2 touching edges of mesh1
+        coo2[2, 0] = 1.0
+        mesh2.setConnectivity(c, cI)
+
+        meshinter, res2Back, res2Tool = MEDCouplingUMesh.Intersect2DMeshes(mesh1,mesh2,eps)
+        self.assertEqual(meshinter.getNodalConnectivity().getValues(), [5, 3, 4, 5, 5, 4, 1, 5, 5, 5, 2, 3, 5, 3, 0, 4])
+        self.assertEqual(meshinter.getNodalConnectivityIndex().getValues(), [0, 4, 8, 12, 16])
+        self.assertEqual(res2Back.getValues(), [0,0,0,0])
+        self.assertEqual(res2Tool.getValues(), [0,-1,-1,-1])
+        pass
+
     def testSwig2Intersect2DMeshWith1DLine1(self):
         """A basic test with no colinearity between m1 and m2."""
         i=MEDCouplingIMesh("mesh",2,[5,5],[0.,0.],[1.,1.])
@@ -1174,6 +1237,61 @@ class MEDCouplingIntersectTest(unittest.TestCase):
         self.assertEqual(m1.getValues(), [0, 0, 0])
         self.assertEqual(m2.getValues(), [-1, -1, 0, 2, -1, -1, 0, 1, -1, -1])
 
+    def testSwig2Intersect2DMeshWith1DLine20(self):
+        """ A line intersecting a cell more than 3 times was triggering an internal error. """
+        mesh = MEDCouplingUMesh('merge', 2)
+        coo = DataArrayDouble([(0,0),(0,9),(3,9),(3,0),(0,1),(2,1),(0,2),(2,2),(3,3),(1,3),(3,4),(1,4),(0,5),(2,5),(0,6),(2,6),(3,7),(1,7),(3,8),(1,8)])
+        mesh.setCoords(coo)
+        c = DataArrayInt([5, 3, 0, 4, 5, 7, 6, 12, 13, 15, 14, 1, 2, 18, 19, 17, 16, 10, 11, 9, 8]) # offset 20
+        cI = DataArrayInt([0, 21])
+        mesh.setConnectivity(c, cI)
+
+        tool = MEDCouplingUMesh('tool', 1)
+        coo = DataArrayDouble([(1.5, 9.5),  (1.5, 1.5)])  # line crossing 4 times
+        tool.setCoords(coo)
+        c = DataArrayInt([NORM_SEG2,0,1])
+        cI = DataArrayInt([0, 3])
+        tool.setConnectivity(c, cI)
+
+        eps=1.0e-4 # not the pb here
+        res2D, res1D, resToSelf, mapLeftRight = MEDCouplingUMesh.Intersect2DMeshWith1DLine(mesh, tool, eps)
+        self.assertEqual(res1D.getNodalConnectivity().getValues(),[1, 20, 25,   1, 25, 26,   1, 26, 27,   1, 27, 24,   1, 24, 23,   1, 23, 28,   1, 28, 29,   1, 29, 22,   1, 22, 21])
+        self.assertEqual(res1D.getNodalConnectivityIndex().getValues(),[0, 3, 6, 9, 12, 15, 18, 21, 24, 27])
+        self.assertEqual(res2D.getNodalConnectivity().getValues(),[5, 2, 18, 26, 25,   5, 13, 15, 24, 27, 16, 10, 28, 23,   5, 8, 3, 0, 4, 5, 7, 22, 29,   5, 6, 12, 23, 28, 11, 9, 29, 22,   5, 14, 1, 25, 26, 19, 17, 27, 24])
+        self.assertEqual(res2D.getNodalConnectivityIndex().getValues(),[0, 5, 14, 23, 32, 41])
+
+        self.assertEqual(resToSelf.getValues(), [0, 0, 0, 0, 0])
+        self.assertEqual(mapLeftRight.getValues(), [-1, -1, 0, 4, -1, -1, 1, 4, -1, -1, 1, 3, -1, -1, 2, 3, -1, -1])
+        pass
+
+    def testSwig2Intersect2DMeshWith1DLine21(self):
+        """ A line intersecting a cell very close to one of its node (collinearity not detected) """
+        eps=1.0e-5  # was working at 1.0e-8, but should also really work with 1.0e-5
+        mesh = MEDCouplingUMesh('mesh', 2)
+        coo = DataArrayDouble([(110.65324,180.56968),(112.01128,182.78580),(113.36932,185.00192),(118.27200,181.90669),(118.27200,178.79852),(118.27200,175.67380)])
+        mesh.setCoords(coo)
+        c = DataArrayInt([NORM_QUAD4, 0, 1, 4, 5, NORM_QUAD4, 1, 2, 3, 4])
+        cI = DataArrayInt([0, 5, 10])
+        mesh.setConnectivity(c, cI)
+
+        tool = MEDCouplingUMesh('tool', 1)
+        coo = DataArrayDouble([(0.0, 182.78400),  (182.78400, 182.78400)])
+        tool.setCoords(coo)
+        c = DataArrayInt([NORM_SEG2,0,1])
+        cI = DataArrayInt([0, 3])
+        tool.setConnectivity(c, cI)
+
+        res2D, res1D, resToSelf, mapLeftRight = MEDCouplingUMesh.Intersect2DMeshWith1DLine(mesh, tool, eps)
+        self.assertEqual(res1D.getNodalConnectivity().getValues(), [1, 6, 1, 1, 1, 8, 1, 8, 9, 1, 9, 7])
+        self.assertEqual(res1D.getNodalConnectivityIndex().getValues(),[0, 3, 6, 9, 12])
+        self.assertEqual(res2D.getNodalConnectivity().getValues(), [5, 0, 1, 8, 4, 5, 5, 1, 2, 9, 8, 5, 3, 4, 8, 9])
+        self.assertEqual(res2D.getNodalConnectivityIndex().getValues(),[0, 6, 11, 16])
+
+        self.assertEqual(resToSelf.getValues(), [0, 1, 1])
+        self.assertEqual(mapLeftRight.getValues(), [-1, -1, 1, 0, 1, 2, -1, -1])
+
+
+
     def testSwig2Conformize2D1(self):
         eps = 1.0e-8
         coo = [0.,-0.5,0.,0.,0.5,0.,0.5,-0.5,0.25,