Skip to content

bouncing_ball

Bouncing ball benchmark.

bouncing_ball(gravity=9.81, restitution=0.8, initial_state=None)

Create a bouncing ball benchmark system.

Parameters:

Name Type Description Default
gravity float

Downward acceleration.

9.81
restitution float

Velocity multiplier on bounce.

0.8
initial_state ndarray | None

Optional initial [height, velocity].

None

Returns:

Type Description
HybridSystem

HybridSystem configured for a bouncing ball.

Source code in src/flowcean/hybrid/benchmarks/bouncing_ball.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
def bouncing_ball(
    gravity: float = 9.81,
    restitution: float = 0.8,
    initial_state: np.ndarray | None = None,
) -> HybridSystem:
    """Create a bouncing ball benchmark system.

    Args:
        gravity: Downward acceleration.
        restitution: Velocity multiplier on bounce.
        initial_state: Optional initial [height, velocity].

    Returns:
        HybridSystem configured for a bouncing ball.
    """

    def flow(
        _t: float,
        state: np.ndarray,
        params: Parameters,
        _input_stream: InputStream,
    ) -> np.ndarray:
        _height, velocity = state
        return np.array([velocity, -params["gravity"]], dtype=float)

    def ground_event_surface(
        _t: float,
        state: np.ndarray,
        _parameters: Parameters,
        _input_stream: InputStream,
    ) -> float:
        return state[0]

    def reset(
        _t: float,
        state: np.ndarray,
        params: Parameters,
        _input_stream: InputStream,
    ) -> np.ndarray:
        height, velocity = state
        return np.array(
            [height, -params["restitution"] * velocity],
            dtype=float,
        )

    dynamics = ContinuousDynamics(flow, label="flight")
    location = Location(
        dynamics,
        label="flight",
        parameters={"restitution": restitution},
    )
    event = EventSurface(
        ground_event_surface,
        direction=CrossingDirection.FALLING,
        label="ground",
    )
    reset_map = Reset(
        reset,
        label="bounce",
    )
    transition = Transition(
        source=location,
        target=location,
        event=event,
        reset=reset_map,
    )

    if initial_state is None:
        initial_state = np.array([1.0, 0.0], dtype=float)

    return HybridSystem(
        locations=[location],
        transitions=[transition],
        initial_location=location,
        initial_state=initial_state,
        parameters={"gravity": gravity},
    )