Source code for optimism.contact.test.test_NeighborSearch
from optimism.JaxConfig import *
from optimism import Mesh
from optimism.test.MeshFixture import MeshFixture
from optimism.contact import MortarContact
import unittest
[docs]
class SelfContactPenaltyFixture(MeshFixture):
[docs]
def setUp(self):
self.targetDispGrad = np.array([[0.1, -0.2],[0.4, -0.1]])
m1 = self.create_mesh_and_disp(2, 4, [0.0, 1.0], [0.0, 1.0],
lambda x : self.targetDispGrad.dot(x), '1')
# Have second block offest (not penetrating) to test that neighbor search excludes edges on opposite faces of the same body
# by using maxPenetrationDistance = 1/2 the body length
m2 = self.create_mesh_and_disp(2, 3, [2.1, 3.1], [0.0, 1.0],
lambda x : self.targetDispGrad.dot(x), '2')
# 6 o ----------- o 7 12 o ----------- o 13
# | | | |
# 4 o ----------- o 5 | |
# | | 10 o ----------- o 11
# 2 o ----------- o 3 | |
# | | | |
# 0 o ----------- o 1 8 o ----------- o 9
self.mesh, _ = Mesh.combine_mesh(m1, m2)
self.disp = np.zeros(self.mesh.coords.shape)
self.maxPenetrationDistance = 0.5
[docs]
def min_distance_squared(self, edge1, edge2, coords):
xs1 = coords[edge1] + self.disp[edge1]
xs2 = coords[edge2] + self.disp[edge2]
return MortarContact.minimum_squared_distance(xs1, xs2)
[docs]
def test_pacman_detection_1(self):
edgeA = np.array([0,1], dtype=int)
xA = np.array([[1.0,0.0],[0.0,0.0]])
edgeB = np.array([1,2], dtype=int)
xB = np.array([[0.0,0.0],[-1.0,0.5]])
self.assertFalse(MortarContact.edges_are_adjacent_non_pacman(edgeA, edgeB, xA, xB))
xB = np.array([[0.0,0.0],[1.0,0.001]])
self.assertFalse(MortarContact.edges_are_adjacent_non_pacman(edgeA, edgeB, xA, xB))
xB = np.array([[0.0,0.0],[1.0,-0.001]])
self.assertTrue(MortarContact.edges_are_adjacent_non_pacman(edgeA, edgeB, xA, xB))
xB = np.array([[0.0,0.0],[-1.0,-0.5]])
self.assertTrue(MortarContact.edges_are_adjacent_non_pacman(edgeA, edgeB, xA, xB))
xB = np.array([[0.0,0.0],[-0.5,0.00001]])
self.assertFalse(MortarContact.edges_are_adjacent_non_pacman(edgeA, edgeB, xA, xB))
xB = np.array([[0.0,0.0],[-0.5,-0.00001]])
self.assertTrue(MortarContact.edges_are_adjacent_non_pacman(edgeA, edgeB, xA, xB))
edgeB = np.array([2,3], dtype=int)
self.assertFalse(MortarContact.edges_are_adjacent_non_pacman(edgeA, edgeB, xA, xB))
[docs]
def test_pacman_detection_2(self):
edgeA = np.array([0,1], dtype=int)
xA = np.array([[1.0,0.0],[0.0,0.0]])
edgeB = np.array([1,2], dtype=int)
xB = np.array([[0.0,0.0],[-1.0,0.5]])
self.assertFalse(MortarContact.edges_are_adjacent_non_pacman(edgeB, edgeA, xB, xA))
xB = np.array([[0.0,0.0],[1.0,0.001]])
self.assertFalse(MortarContact.edges_are_adjacent_non_pacman(edgeB, edgeA, xB, xA))
xB = np.array([[0.0,0.0],[1.0,-0.001]])
self.assertTrue(MortarContact.edges_are_adjacent_non_pacman(edgeB, edgeA, xB, xA))
xB = np.array([[0.0,0.0],[-1.0,-0.5]])
self.assertTrue(MortarContact.edges_are_adjacent_non_pacman(edgeB, edgeA, xB, xA))
xB = np.array([[0.0,0.0],[-0.5,0.00001]])
self.assertFalse(MortarContact.edges_are_adjacent_non_pacman(edgeB, edgeA, xB, xA))
xB = np.array([[0.0,0.0],[-0.5,-0.00001]])
self.assertTrue(MortarContact.edges_are_adjacent_non_pacman(edgeB, edgeA, xB, xA))
edgeB = np.array([2,3], dtype=int)
self.assertFalse(MortarContact.edges_are_adjacent_non_pacman(edgeB, edgeA, xB, xA))
[docs]
def test_exclusion_of_current_edge(self):
coordsSegA = np.array([[0, 1], [1, 3], [3, 5], [12, 10]])
coordsSegB = np.array([[1, 3]])
numNeighbors = 1
neighborList = MortarContact.get_closest_neighbors_for_self_contact(coordsSegA, coordsSegB, self.mesh, self.disp, numNeighbors, self.maxPenetrationDistance)
goldNeighbors = np.array([[3]])
self.assertArrayEqual(neighborList, goldNeighbors)
[docs]
def test_exclusion_of_edges_on_opposite_face(self):
coordsSegA = np.array([[2, 0], [12, 10]])
coordsSegB = np.array([[1, 3]])
numNeighbors = 1
neighborList = MortarContact.get_closest_neighbors_for_self_contact(coordsSegA, coordsSegB, self.mesh, self.disp, numNeighbors, self.maxPenetrationDistance)
# Edge 0 is closer so should be preferred
minDistEdge0 = self.min_distance_squared(coordsSegA[0], coordsSegB[0], self.mesh.coords)
minDistEdge1 = self.min_distance_squared(coordsSegA[1], coordsSegB[0], self.mesh.coords)
self.assertTrue(minDistEdge0 < minDistEdge1)
# Edge 1 is returned since edge 0 is invalid
goldNeighbors = np.array([[1]])
self.assertArrayEqual(neighborList, goldNeighbors)
[docs]
def test_inclusion_of_edges_on_adjacent_face(self):
coordsSegA = np.array([[0, 1], [1, 3], [3, 5], [12, 10], [10, 8], [5, 7], [2, 0]])
coordsSegB = np.array([[1, 3]])
numNeighbors = 3
neighborList = MortarContact.get_closest_neighbors_for_self_contact(coordsSegA, coordsSegB, self.mesh, self.disp, numNeighbors, self.maxPenetrationDistance)
goldNeighbors = np.array([[5, 4, 3]])
self.assertArrayEqual(neighborList, goldNeighbors)
[docs]
def test_invalid_entries_have_minus_one_if_included(self):
coordsSegA = np.array([[0, 1], [1, 3], [3, 5], [12, 10]])
coordsSegB = np.array([[1, 3]])
numNeighbors = 2
neighborList = MortarContact.get_closest_neighbors_for_self_contact(coordsSegA, coordsSegB, self.mesh, self.disp, numNeighbors, self.maxPenetrationDistance)
goldNeighbors = np.array([[3, -1]])
self.assertArrayEqual(neighborList, goldNeighbors)
if __name__ == '__main__':
unittest.main()