Skip to content

Commit ba88719

Browse files
committed
update: remove layer of stepper protocol structure
1 parent f2eea94 commit ba88719

4 files changed

Lines changed: 52 additions & 68 deletions

File tree

elastica/timestepper/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def extend_stepper_interface(
2222
SteppersOperatorsType,
2323
]:
2424
try:
25-
stepper_methods: SteppersOperatorsType = stepper.steps_and_prefactors
25+
stepper_methods: SteppersOperatorsType = stepper.steps_and_prefactors # type: ignore
2626
do_step_method: Callable = stepper.do_step # type: ignore[attr-defined]
2727
except AttributeError as e:
2828
raise NotImplementedError(f"{stepper} stepper is not supported.") from e

elastica/timestepper/protocol.py

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
from typing import Protocol
44

55
from elastica.typing import (
6-
SteppersOperatorsType,
7-
StepType,
6+
SystemType,
87
SystemCollectionType,
98
)
109
from elastica.systems.protocol import SymplecticSystemProtocol
@@ -15,15 +14,6 @@
1514
class StepperProtocol(Protocol):
1615
"""Protocol for all time-steppers"""
1716

18-
steps_and_prefactors: SteppersOperatorsType
19-
20-
def __init__(self) -> None: ...
21-
22-
@property
23-
def n_stages(self) -> int: ...
24-
25-
def step_methods(self) -> SteppersOperatorsType: ...
26-
2717
def step(
2818
self,
2919
SystemCollection: SystemCollectionType,
@@ -32,13 +22,5 @@ def step(
3222
) -> np.float64: ...
3323

3424
def step_single_instance(
35-
self, System: SymplecticSystemProtocol, time: np.float64, dt: np.float64
25+
self, System: SystemType, time: np.float64, dt: np.float64
3626
) -> np.float64: ...
37-
38-
39-
class SymplecticStepperProtocol(StepperProtocol, Protocol):
40-
"""symplectic stepper protocol."""
41-
42-
def get_steps(self) -> list[StepType]: ...
43-
44-
def get_prefactors(self) -> list[StepType]: ...

elastica/timestepper/symplectic_steppers.py

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
__doc__ = """Symplectic time steppers and concepts for integrating the kinematic and dynamic equations of rod-like objects. """
22

3-
from typing import TYPE_CHECKING, Any
3+
from typing import TYPE_CHECKING, Any, Callable
44

55
from itertools import zip_longest
66

77
from elastica.typing import (
88
SystemCollectionType,
9+
SystemType,
910
StepType,
1011
SteppersOperatorsType,
1112
)
1213

1314
import numpy as np
1415

1516
from elastica.systems.protocol import SymplecticSystemProtocol
16-
from .protocol import SymplecticStepperProtocol
17+
from .protocol import StepperProtocol
1718

1819
"""
1920
Developer Note
@@ -25,10 +26,13 @@
2526

2627

2728
class SymplecticStepperMixin:
28-
def __init__(self: SymplecticStepperProtocol):
29+
get_steps: Callable[[], list[StepType]]
30+
get_prefactors: Callable[[], list[StepType]]
31+
32+
def __init__(self) -> None:
2933
self.steps_and_prefactors: SteppersOperatorsType = self.step_methods()
3034

31-
def step_methods(self: SymplecticStepperProtocol) -> SteppersOperatorsType:
35+
def step_methods(self) -> SteppersOperatorsType:
3236
# Let the total number of steps for the Symplectic method
3337
# be (2*n + 1) (for time-symmetry).
3438
_steps: list[StepType] = self.get_steps()
@@ -56,32 +60,14 @@ def no_operation(*args: Any) -> None:
5660
)
5761

5862
@property
59-
def n_stages(self: SymplecticStepperProtocol) -> int:
63+
def n_stages(self) -> int:
6064
return len(self.steps_and_prefactors)
6165

6266
def step(
63-
self: SymplecticStepperProtocol,
67+
self,
6468
SystemCollection: SystemCollectionType,
6569
time: np.float64 | float,
6670
dt: np.float64 | float,
67-
) -> np.float64:
68-
return SymplecticStepperMixin.do_step(
69-
self,
70-
self.steps_and_prefactors,
71-
SystemCollection,
72-
np.float64(time),
73-
np.float64(dt),
74-
)
75-
76-
# TODO: Merge with .step method in the future.
77-
# DEPRECATED: Use .step instead.
78-
@staticmethod
79-
def do_step(
80-
TimeStepper: SymplecticStepperProtocol,
81-
steps_and_prefactors: SteppersOperatorsType,
82-
SystemCollection: SystemCollectionType,
83-
time: np.float64,
84-
dt: np.float64,
8571
) -> np.float64:
8672
"""
8773
Function for doing symplectic stepper over the user defined rods (system).
@@ -92,53 +78,73 @@ def do_step(
9278
The time after the integration step.
9379
9480
"""
95-
for kin_prefactor, kin_step, dyn_step in steps_and_prefactors[:-1]:
81+
simulation_time = np.float64(time)
82+
simulation_dt = np.float64(dt)
9683

84+
for kin_prefactor, kin_step, dyn_step in self.steps_and_prefactors[:-1]:
9785
for system in SystemCollection.final_systems():
98-
kin_step(system, time, dt)
86+
kin_step(system, simulation_time, simulation_dt)
9987

100-
time += kin_prefactor(dt)
88+
simulation_time += kin_prefactor(simulation_dt)
10189

10290
# Constrain only values
103-
SystemCollection.constrain_values(time)
91+
SystemCollection.constrain_values(simulation_time)
10492

10593
# We need internal forces and torques because they are used by interaction module.
10694
for system in SystemCollection.final_systems():
107-
system.compute_internal_forces_and_torques(time)
95+
system.compute_internal_forces_and_torques(simulation_time)
10896

10997
# Add external forces, controls etc.
110-
SystemCollection.synchronize(time)
98+
SystemCollection.synchronize(simulation_time)
11199

112100
for system in SystemCollection.final_systems():
113-
dyn_step(system, time, dt)
101+
dyn_step(system, simulation_time, simulation_dt)
114102

115103
# Constrain only rates
116-
SystemCollection.constrain_rates(time)
104+
SystemCollection.constrain_rates(simulation_time)
117105

118106
# Peel the last kinematic step and prefactor alone
119-
last_kin_prefactor = steps_and_prefactors[-1][0]
120-
last_kin_step = steps_and_prefactors[-1][1]
107+
last_kin_prefactor = self.steps_and_prefactors[-1][0]
108+
last_kin_step = self.steps_and_prefactors[-1][1]
121109

122110
for system in SystemCollection.final_systems():
123-
last_kin_step(system, time, dt)
124-
time += last_kin_prefactor(dt)
125-
SystemCollection.constrain_values(time)
111+
last_kin_step(system, simulation_time, simulation_dt)
112+
simulation_time += last_kin_prefactor(simulation_dt)
113+
SystemCollection.constrain_values(simulation_time)
126114

127115
# Call back function, will call the user defined call back functions and store data
128-
SystemCollection.apply_callbacks(time, round(time / dt))
116+
SystemCollection.apply_callbacks(
117+
simulation_time, round(simulation_time / simulation_dt)
118+
)
129119

130120
# Zero out the external forces and torques
131121
for system in SystemCollection.final_systems():
132-
system.zeroed_out_external_forces_and_torques(time)
122+
system.zeroed_out_external_forces_and_torques(simulation_time)
123+
124+
return simulation_time
125+
126+
@staticmethod
127+
def do_step(
128+
TimeStepper: StepperProtocol,
129+
steps_and_prefactors: SteppersOperatorsType,
130+
SystemCollection: SystemCollectionType,
131+
time: np.float64,
132+
dt: np.float64,
133+
) -> np.float64: # pragma: no cover
134+
from warning import warn
133135

134-
return time
136+
warn("This method is deprecated. Use the instance method .step instead.")
137+
return Timestepper.step(SystemCollection, time, dt) # type: ignore
135138

136139
def step_single_instance(
137-
self: SymplecticStepperProtocol,
138-
System: SymplecticSystemProtocol,
140+
self,
141+
System: SystemType,
139142
time: np.float64,
140143
dt: np.float64,
141144
) -> np.float64:
145+
"""
146+
(The function is used for single system instance, mainly for testing purposes.)
147+
"""
142148

143149
for kin_prefactor, kin_step, dyn_step in self.steps_and_prefactors[:-1]:
144150
kin_step(System, time, dt)

elastica/typing.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@
2424
SystemProtocol,
2525
SymplecticSystemProtocol,
2626
)
27-
from .timestepper.protocol import (
28-
StepperProtocol,
29-
SymplecticStepperProtocol,
30-
)
27+
from .timestepper.protocol import StepperProtocol
3128
from .memory_block.protocol import BlockSystemProtocol
3229

3330
else:
@@ -40,7 +37,6 @@
4037
StaticSystemProtocol = "StaticSystemProtocol"
4138
SymplecticSystemProtocol = "SymplecticSystemProtocol"
4239
StepperProtocol = "StepperProtocol"
43-
SymplecticStepperProtocol = "SymplecticStepperProtocol"
4440
BlockSystemProtocol = "BlockSystemProtocol"
4541

4642

0 commit comments

Comments
 (0)