Skip to content

Commit f228cee

Browse files
committed
solve #380
1 parent b9f6ed7 commit f228cee

7 files changed

Lines changed: 73 additions & 46 deletions

File tree

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ format-codestyle: black autoflake-format
5353
.PHONY: mypy
5454
mypy:
5555
uv run mypy --config-file pyproject.toml elastica # Main
56-
uv run mypy --config-file pyproject.toml --explicit-package-bases \ # Examples
56+
uv run mypy --config-file pyproject.toml --explicit-package-bases \
5757
examples/AxialStretchingCase \
5858
examples/ButterflyCase \
5959
examples/CatenaryCase \
60-
examples/KnotCase \your interest in PyElastica.
60+
examples/KnotCase \
6161
examples/ContinuumSnakeCase
6262

6363
.PHONY: test

elastica/contact_forces.py

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ def __init__(self) -> None:
4545
"""
4646
NoContact class does not need any input parameters.
4747
"""
48-
pass
4948

5049
@property
5150
def _allowed_system_one(self) -> list[Type]:
@@ -77,6 +76,7 @@ def apply_contact(
7776
self,
7877
system_one: S1,
7978
system_two: S2,
79+
time: np.float64 = np.float64(0.0),
8080
) -> None:
8181
"""
8282
Apply contact forces and torques between two system object..
@@ -88,7 +88,6 @@ def apply_contact(
8888
system_one
8989
system_two
9090
"""
91-
pass
9291

9392

9493
class RodRodContact(NoContact):
@@ -120,7 +119,12 @@ def __init__(self, k: np.float64, nu: np.float64) -> None:
120119
self.k = k
121120
self.nu = nu
122121

123-
def apply_contact(self, system_one: RodType, system_two: RodType) -> None:
122+
def apply_contact(
123+
self,
124+
system_one: RodType,
125+
system_two: RodType,
126+
time: np.float64 = np.float64(0.0),
127+
) -> None:
124128
"""
125129
Apply contact forces and torques between RodType object and RodType object.
126130
@@ -226,7 +230,12 @@ def _allowed_system_two(self) -> list[Type]:
226230
# Modify this list to include the allowed system types for contact
227231
return [Cylinder]
228232

229-
def apply_contact(self, system_one: RodType, system_two: Cylinder) -> None:
233+
def apply_contact(
234+
self,
235+
system_one: RodType,
236+
system_two: Cylinder,
237+
time: np.float64 = np.float64(0.0),
238+
) -> None:
230239
# First, check for a global AABB bounding box, and see whether that
231240
# intersects
232241
if _prune_using_aabbs_rod_cylinder(
@@ -313,7 +322,12 @@ def _check_systems_validity(
313322
common_check_systems_validity(system_two, self._allowed_system_two)
314323
common_check_systems_different(system_one, system_two)
315324

316-
def apply_contact(self, system_one: RodType, system_two: RodType) -> None:
325+
def apply_contact(
326+
self,
327+
system_one: RodType,
328+
system_two: RodType,
329+
time: np.float64 = np.float64(0.0),
330+
) -> None:
317331
"""
318332
Apply contact forces and torques between RodType object and itself.
319333
@@ -392,7 +406,12 @@ def __init__(
392406
def _allowed_system_two(self) -> list[Type]:
393407
return [Sphere]
394408

395-
def apply_contact(self, system_one: RodType, system_two: Sphere) -> None:
409+
def apply_contact(
410+
self,
411+
system_one: RodType,
412+
system_two: Sphere,
413+
time: np.float64 = np.float64(0.0),
414+
) -> None:
396415
"""
397416
Apply contact forces and torques between RodType object and Sphere object.
398417
@@ -485,7 +504,12 @@ def __init__(
485504
def _allowed_system_two(self) -> list[Type]:
486505
return [SurfaceBase]
487506

488-
def apply_contact(self, system_one: RodType, system_two: SurfaceType) -> None:
507+
def apply_contact(
508+
self,
509+
system_one: RodType,
510+
system_two: SurfaceType,
511+
time: np.float64 = np.float64(0.0),
512+
) -> None:
489513
"""
490514
Apply contact forces and torques between RodType object and Plane object.
491515
@@ -577,7 +601,12 @@ def __init__(
577601
def _allowed_system_two(self) -> list[Type]:
578602
return [SurfaceBase]
579603

580-
def apply_contact(self, system_one: RodType, system_two: SurfaceType) -> None:
604+
def apply_contact(
605+
self,
606+
system_one: RodType,
607+
system_two: SurfaceType,
608+
time: np.float64 = np.float64(0.0),
609+
) -> None:
581610
"""
582611
Apply contact forces and torques between RodType object and Plane object with anisotropic friction.
583612
@@ -659,7 +688,12 @@ def _allowed_system_one(self) -> list[Type]:
659688
def _allowed_system_two(self) -> list[Type]:
660689
return [SurfaceBase]
661690

662-
def apply_contact(self, system_one: Cylinder, system_two: SurfaceType) -> None:
691+
def apply_contact(
692+
self,
693+
system_one: Cylinder,
694+
system_two: SurfaceType,
695+
time: np.float64 = np.float64(0.0),
696+
) -> None:
663697
"""
664698
This function computes the plane force response on the cylinder, in the
665699
case of contact. Contact model given in Eqn 4.8 Gazzola et. al. RSoS 2018 paper

elastica/dissipation.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
Built in damper module implementations
55
"""
66

7-
import logging
87
from abc import ABC, abstractmethod
98
from typing import Any, Generic, TypeVar, TypeAlias, Callable
109

@@ -159,10 +158,6 @@ def __init__(self, time_step: np.float64, **kwargs: Any) -> None:
159158
and (translational_damping_constant is None)
160159
and (rotational_damping_constant is None)
161160
):
162-
logging.warning(
163-
"Analytical linear damping using generic damping constant "
164-
"will be deprecated in 0.4.0"
165-
)
166161
self._dampen_rates_protocol = self._deprecated_damping_protocol(
167162
damping_constant=damping_constant, time_step=time_step
168163
)

elastica/joint.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def apply_forces(
5050
index_one: ConnectionIndex,
5151
system_two: "RodType | RigidBodyType",
5252
index_two: ConnectionIndex,
53+
time: np.float64 = np.float64(0.0),
5354
) -> None:
5455
"""
5556
Apply joint force to the connected rod objects.
@@ -93,6 +94,7 @@ def apply_torques(
9394
index_one: ConnectionIndex,
9495
system_two: "RodType | RigidBodyType",
9596
index_two: ConnectionIndex,
97+
time: np.float64 = np.float64(0.0),
9698
) -> None:
9799
"""
98100
Apply restoring joint torques to the connected rod objects.
@@ -174,6 +176,7 @@ def apply_forces(
174176
index_one: ConnectionIndex,
175177
system_two: "RodType | RigidBodyType",
176178
index_two: ConnectionIndex,
179+
time: np.float64 = np.float64(0.0),
177180
) -> None:
178181
return super().apply_forces(system_one, index_one, system_two, index_two)
179182

@@ -183,6 +186,7 @@ def apply_torques(
183186
index_one: ConnectionIndex,
184187
system_two: "RodType | RigidBodyType",
185188
index_two: ConnectionIndex,
189+
time: np.float64 = np.float64(0.0),
186190
) -> None:
187191
# current tangent direction of the `index_two` element of system two
188192
system_two_tangent = system_two.director_collection[2, :, index_two]
@@ -281,6 +285,7 @@ def apply_forces(
281285
index_one: ConnectionIndex,
282286
system_two: "RodType | RigidBodyType",
283287
index_two: ConnectionIndex,
288+
time: np.float64 = np.float64(0.0),
284289
) -> None:
285290
return super().apply_forces(system_one, index_one, system_two, index_two)
286291

@@ -290,6 +295,7 @@ def apply_torques(
290295
index_one: ConnectionIndex,
291296
system_two: "RodType | RigidBodyType",
292297
index_two: ConnectionIndex,
298+
time: np.float64 = np.float64(0.0),
293299
) -> None:
294300
# collect directors of systems one and two
295301
# note that systems can be either rods or rigid bodies

elastica/modules/connections.py

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -87,44 +87,30 @@ def _finalize_connections(self: ConnectedSystemCollectionProtocol) -> None:
8787
# (first rod index, second_rod_idx, connection_idx_on_first_rod, connection_idx_on_second_rod)
8888
# to apply the connections to.
8989

90-
def apply_forces_and_torques(
91-
time: np.float64,
92-
connect_instance: FreeJoint,
93-
system_one: "RodType | RigidBodyType",
94-
first_connect_idx: ConnectionIndex,
95-
system_two: "RodType | RigidBodyType",
96-
second_connect_idx: ConnectionIndex,
97-
) -> None:
98-
connect_instance.apply_forces(
99-
system_one=system_one,
100-
index_one=first_connect_idx,
101-
system_two=system_two,
102-
index_two=second_connect_idx,
103-
)
104-
connect_instance.apply_torques(
105-
system_one=system_one,
106-
index_one=first_connect_idx,
107-
system_two=system_two,
108-
index_two=second_connect_idx,
109-
)
110-
11190
for connection in self._connections:
11291
first_sys_idx, second_sys_idx, first_connect_idx, second_connect_idx = (
11392
connection.id()
11493
)
11594
connect_instance: FreeJoint = connection.instantiate()
11695

117-
# FIXME: lambda t is included because OperatorType takes time as an argument
118-
func = functools.partial(
119-
apply_forces_and_torques,
120-
connect_instance=connect_instance,
96+
func_force = functools.partial(
97+
connect_instance.apply_forces,
12198
system_one=self[first_sys_idx],
122-
first_connect_idx=first_connect_idx,
99+
index_one=first_connect_idx,
123100
system_two=self[second_sys_idx],
124-
second_connect_idx=second_connect_idx,
101+
index_two=second_connect_idx,
102+
)
103+
func_torque = functools.partial(
104+
connect_instance.apply_torques,
105+
system_one=self[first_sys_idx],
106+
index_one=first_connect_idx,
107+
system_two=self[second_sys_idx],
108+
index_two=second_connect_idx,
125109
)
126110

127-
self._feature_group_synchronize.add_operators(connection, [func])
111+
self._feature_group_synchronize.add_operators(
112+
connection, [func_force, func_torque]
113+
)
128114

129115
self._connections = []
130116
del self._connections

elastica/modules/contact.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
"""
88
from typing import Type, Any
99
from typing_extensions import Self
10+
11+
import functools
1012
from elastica.typing import (
1113
SystemIdxType,
1214
OperatorType,
@@ -86,7 +88,9 @@ def _finalize_contact(self: ContactedSystemCollectionProtocol) -> None:
8688
self[first_sys_idx],
8789
self[second_sys_idx],
8890
)
89-
func: OperatorType = lambda time: contact_instance.apply_contact(
91+
92+
func = functools.partial(
93+
contact_instance.apply_contact,
9094
system_one=self[first_sys_idx],
9195
system_two=self[second_sys_idx],
9296
)

elastica/modules/damping.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ def _finalize_dampers(self: DampenedSystemCollectionProtocol) -> None:
7878
sys_id = damping.id()
7979
damping_instance = damping.instantiate(self[sys_id])
8080

81-
dampen_rate = functools.partial(damping_instance.dampen_rates, self[sys_id])
81+
dampen_rate = functools.partial(
82+
damping_instance.dampen_rates, system=self[sys_id]
83+
)
8284
self._feature_group_constrain_rates.add_operators(damping, [dampen_rate])
8385

8486
self._damping_list = []

0 commit comments

Comments
 (0)