-
Notifications
You must be signed in to change notification settings - Fork 112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RodMeshSurfaceContact class init #294
Changes from 3 commits
2725342
780dfcd
560963d
24d919f
f012951
05824e3
046a3f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -426,31 +426,51 @@ def _calculate_contact_forces_self_rod( | |||||
|
||||||
|
||||||
@numba.njit(cache=True) | ||||||
def apply_normal_force_numba( | ||||||
faces_normals, | ||||||
faces_centers, | ||||||
element_position, | ||||||
position_idx_array, | ||||||
def _calculate_contact_forces_rod_mesh_surface( | ||||||
faces_normals: np.ndarray, | ||||||
faces_centers: np.ndarray, | ||||||
element_position: np.ndarray, | ||||||
position_idx_array: np.ndarray, | ||||||
face_idx_array, | ||||||
surface_tol, | ||||||
k, | ||||||
nu, | ||||||
radius, | ||||||
mass, | ||||||
position_collection, | ||||||
velocity_collection, | ||||||
internal_forces, | ||||||
external_forces, | ||||||
lengths, | ||||||
): | ||||||
surface_tol: float, | ||||||
k: float, | ||||||
nu: float, | ||||||
radius: np.array, | ||||||
mass: np.array, | ||||||
velocity_collection: np.ndarray, | ||||||
external_forces: np.ndarray, | ||||||
) -> tuple: | ||||||
""" | ||||||
This function computes the plane force response on the element, in the | ||||||
case of contact. Contact model given in Eqn 4.8 Gazzola et. al. RSoS 2018 paper | ||||||
is used. | ||||||
|
||||||
Parameters | ||||||
---------- | ||||||
system_one | ||||||
faces_normals: np.ndarray | ||||||
mesh cell's normal vectors | ||||||
faces_centers: np.ndarray | ||||||
mesh cell's center points | ||||||
element_position: np.ndarray | ||||||
rod element's center points | ||||||
position_idx_array: np.ndarray | ||||||
rod element's index array | ||||||
face_idx_array: np.ndarray | ||||||
mesh cell's index array | ||||||
surface_tol: float | ||||||
Penetration tolerance between the surface and the rod-like object | ||||||
k: float | ||||||
Contact spring constant | ||||||
nu: float | ||||||
Contact damping constant | ||||||
radius: np.array | ||||||
rod element's radius | ||||||
mass: np.array | ||||||
rod element's mass | ||||||
velocity_collection: np.ndarray | ||||||
rod element's velocity | ||||||
external_forces: np.ndarray | ||||||
rod element's external forces | ||||||
|
||||||
Returns | ||||||
------- | ||||||
|
@@ -464,22 +484,22 @@ def apply_normal_force_numba( | |||||
|
||||||
if len(face_idx_array) > 0: | ||||||
element_position_contacts = element_position[:, position_idx_array] | ||||||
contact_facet_centers = faces_centers[:, face_idx_array] | ||||||
contact_face_centers = faces_centers[:, face_idx_array] | ||||||
normals_on_elements = faces_normals[:, face_idx_array] | ||||||
radius_contacts = radius[position_idx_array] | ||||||
element_velocity_contacts = element_velocity[:, position_idx_array] | ||||||
|
||||||
else: | ||||||
element_position_contacts = element_position | ||||||
contact_facet_centers = np.zeros_like(element_position) | ||||||
contact_face_centers = np.zeros_like(element_position) | ||||||
normals_on_elements = np.zeros_like(element_position) | ||||||
radius_contacts = radius | ||||||
element_velocity_contacts = element_velocity | ||||||
|
||||||
# Elastic force response due to penetration | ||||||
|
||||||
distance_from_plane = _batch_dot( | ||||||
normals_on_elements, (element_position_contacts - contact_facet_centers) | ||||||
normals_on_elements, (element_position_contacts - contact_face_centers) | ||||||
) | ||||||
plane_penetration = ( | ||||||
-np.abs(np.minimum(distance_from_plane - radius_contacts, 0.0)) ** 1.5 | ||||||
|
@@ -825,7 +845,7 @@ def apply_contact( | |||||
) | ||||||
|
||||||
|
||||||
class RodMeshSurfaceContact(NoContact): | ||||||
class RodMeshSurfaceContactWithGridMethod(NoContact): | ||||||
""" | ||||||
This class is for applying contact forces between rod-mesh_surface. | ||||||
First system is always rod and second system is always mesh_surface. | ||||||
|
@@ -835,17 +855,16 @@ class RodMeshSurfaceContact(NoContact): | |||||
How to define contact between rod and mesh_surface. | ||||||
|
||||||
>>> simulator.detect_contact_between(rod, mesh_surface).using( | ||||||
... RodMeshSurfaceContact, | ||||||
... RodMeshSurfaceContactWithGridMethod, | ||||||
... k=1e4, | ||||||
... nu=10, | ||||||
... surface_tol=1e-2, | ||||||
... ) | ||||||
|
||||||
|
||||||
.. [1] Preclik T., Popa Constantin., Rude U., Regularizing a Time-Stepping Method for Rigid Multibody Dynamics, Multibody Dynamics 2011, ECCOMAS. URL: https://www10.cs.fau.de/publications/papers/2011/Preclik_Multibody_Ext_Abstr.pdf | ||||||
""" | ||||||
|
||||||
def __init__(self, k: float, nu: float, surface_tol=1e-4): | ||||||
def __init__( | ||||||
self, k: float, nu: float, faces_grid: dict, grid_size: float, surface_tol=1e-4 | ||||||
): | ||||||
""" | ||||||
|
||||||
Parameters | ||||||
|
@@ -854,24 +873,33 @@ def __init__(self, k: float, nu: float, surface_tol=1e-4): | |||||
Stiffness coefficient between the plane and the rod-like object. | ||||||
nu: float | ||||||
Dissipation coefficient between the plane and the rod-like object. | ||||||
faces_grid: dict | ||||||
Dictionary containing the grid information of the mesh surface. | ||||||
grid_size: float | ||||||
Grid size of the mesh surface. | ||||||
surface_tol: float | ||||||
Penetration tolerance between the surface and the rod-like object. | ||||||
|
||||||
""" | ||||||
super(RodMeshSurfaceContact, self).__init__() | ||||||
super(RodMeshSurfaceContactWithGridMethod, self).__init__() | ||||||
# n_faces = faces.shape[-1] | ||||||
self.k = k | ||||||
self.nu = nu | ||||||
self.faces_grid = faces_grid | ||||||
self.grid_size = grid_size | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. instead of requesting grid_size as input for the class, include it in the faces_grid "metadata". I explain it later in a different comment on the faces_grid generation. This should be something like self.grid_size = faces_grid["grid_size"] |
||||||
self.surface_tol = surface_tol | ||||||
|
||||||
def _check_systems_validity( | ||||||
self, | ||||||
system_one: SystemType, | ||||||
system_two: AllowedContactType, | ||||||
faces_grid: dict, | ||||||
grid_size: float, | ||||||
) -> None: | ||||||
""" | ||||||
This checks the contact order and type of a SystemType object and an AllowedContactType object. | ||||||
For the RodMeshSurfaceContact class first_system should be a rod and second_system should be a mesh_surface. | ||||||
For the RodMeshSurfaceContact class first_system should be a rod and second_system should be a mesh_surface; | ||||||
morever, the imported grid's attributes should match imported rod-mesh_surface(in contact) grid's attributes. | ||||||
|
||||||
Parameters | ||||||
---------- | ||||||
|
@@ -891,7 +919,22 @@ def _check_systems_validity( | |||||
) | ||||||
) | ||||||
|
||||||
Rahul-JOON marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
def apply_normal_force( | ||||||
elif not faces_grid["grid_size"] == grid_size: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what I would do here is check if the faces_grid["grid_size"] == max(2*system_one.radius[0],system_one.rest_lengths[0]). Essentially, checking if the grid_size of faces_grid is appropriate for the given rod. |
||||||
raise TypeError( | ||||||
"Imported grid size does not match with the current rod-mesh_surface grid size. " | ||||||
) | ||||||
|
||||||
elif not faces_grid["model_path"] == system_two.model_path: | ||||||
raise TypeError( | ||||||
"Imported grid's model path does not match with the current mesh_surface model path. " | ||||||
) | ||||||
|
||||||
elif not faces_grid["surface_reorient"] == system_two.mesh_orientation: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change "surface_reorient" to "mesh_orientation" |
||||||
raise TypeError( | ||||||
"Imported grid's surface orientation does not match with the current mesh_surface rientation. " | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
) | ||||||
|
||||||
def apply_contact( | ||||||
self, system_one: RodType, system_two: AllowedContactType | ||||||
) -> tuple: | ||||||
""" | ||||||
|
@@ -924,14 +967,14 @@ def apply_normal_force( | |||||
self.face_idx_array, | ||||||
self.element_position, | ||||||
) = find_contact_faces_idx( | ||||||
self.facets_grid, | ||||||
self.faces_grid, | ||||||
self.mesh_surface_x_min, | ||||||
self.mesh_surface_y_min, | ||||||
self.grid_size, | ||||||
system_one.position_collection, | ||||||
) | ||||||
|
||||||
return apply_normal_force_numba( | ||||||
return _calculate_contact_forces_rod_mesh_surface( | ||||||
self.mesh_surface_face_normals, | ||||||
self.mesh_surface_face_centers, | ||||||
self.element_position, | ||||||
|
@@ -942,9 +985,6 @@ def apply_normal_force( | |||||
self.nu, | ||||||
system_one.radius, | ||||||
system_one.mass, | ||||||
system_one.position_collection, | ||||||
system_one.velocity_collection, | ||||||
system_one.internal_forces, | ||||||
system_one.external_forces, | ||||||
system_one.lengths, | ||||||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we update docs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I will update this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we update this doc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you elaborate on what should we update?