Skip to content

Commit

Permalink
Merge pull request #157 from derek-mcblane/simple-frictional-inelastic
Browse files Browse the repository at this point in the history
Fix Error in Ball-Ball Frictional Inelastic No-Slip Velocity Calculation
  • Loading branch information
ekiefl authored Nov 25, 2024
2 parents 8713464 + 51ad9d9 commit 8d973a0
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,12 @@ def _resolve_ball_ball(rvw1, rvw2, R, u_b, e_b):
# then slip condition is invalid so we need to calculate no-slip condition
if not has_relative_velocity or np.dot(v12_c, v12_c_slip) <= 0: # type: ignore
# velocity tangent component for no-slip condition
D_v1_t = (
2.0 * rvw2[1] - R * ptmath.cross(2.0 * rvw1[2] + 7.0 * rvw2[2], unit_x)
) / 9.0
D_w1 = (
5.0
* (rvw2[2] - rvw1[2] + ptmath.cross(unit_x, rvw2[1] - rvw1[1]) / R)
/ 9.0
D_v1_t = -(1.0 / 9.0) * (
2.0 * (rvw1[1] - rvw2[1])
+ R * ptmath.cross(2.0 * rvw1[2] + 7.0 * rvw2[2], unit_x)
)
D_w1 = (5.0 / 9.0) * (
rvw2[2] - rvw1[2] + ptmath.cross(unit_x, rvw2[1] - rvw1[1]) / R
)
rvw1_f[1] = rvw1[1] + D_v1_t
rvw1_f[2] = rvw1[2] + D_w1
Expand Down
30 changes: 30 additions & 0 deletions tests/physics/resolve/ball_ball/test_ball_ball.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@ def head_on() -> Tuple[Ball, Ball]:
return cb, ob


def translating_head_on() -> Tuple[Ball, Ball]:
cb = Ball.create("cue", xy=(0, 0))
ob = Ball.create("cue", xy=(2 * cb.params.R, 0))

# Cue ball makes head-on collision with object ball at 1 m/s in +x direction
# while both balls move together at 1 m/s in +y direction
cb.state.rvw[1] = np.array([1, 1, 0])
ob.state.rvw[1] = np.array([0, 1, 0])

assert cb.params.m == ob.params.m, "Balls expected to be equal mass"
return cb, ob


@pytest.mark.parametrize("model", [FrictionlessElastic()])
def test_head_on_zero_spin(model: BallBallCollisionStrategy):
cb_i, ob_i = head_on()
Expand Down Expand Up @@ -63,6 +76,23 @@ def test_head_on_zero_spin_inelastic(model: BallBallCollisionStrategy, e_b: floa
assert cb_f.state.rvw[1][0] > 0


@pytest.mark.parametrize("model", [FrictionalInelastic(), FrictionalMathavan()])
@pytest.mark.parametrize("e_b", [0.5, 0.6, 0.7, 0.8, 0.9, 1.0])
def test_translating_head_on_zero_spin_inelastic(
model: BallBallCollisionStrategy, e_b: float
):
cb_i, ob_i = translating_head_on()

# Update coefficient of restitutions
cb_i.params = attrs.evolve(cb_i.params, e_b=e_b)
ob_i.params = attrs.evolve(ob_i.params, e_b=e_b)

cb_f, ob_f = model.resolve(cb_i, ob_i, inplace=False)

# Balls should still be moving together in +y direction
assert np.isclose(cb_f.vel[1], ob_f.vel[1], atol=1e-10)


@pytest.mark.parametrize("model", [FrictionalInelastic(), FrictionalMathavan()])
@pytest.mark.parametrize("cb_wz_i", [0.1, 1, 10, 100])
def test_head_on_z_spin(model: BallBallCollisionStrategy, cb_wz_i: float):
Expand Down

0 comments on commit 8d973a0

Please sign in to comment.