def test_collision_with_corner(self):
     boundery = SlipperyBounceBounderyConditions_2D()
     ball1 = Ball((0.5, 0.5), (1, 1), 0.1)
     simulation = SimulationModule(boundery_conditions=boundery,
                                   balls_arr=[ball1])
     conductor = ConductorWithNoOutput(simulation_time_timeout=1,
                                       simulation_module=simulation)
     conductor.run_simulation()
     self.assert_ball_is_in_bounds(ball1, boundery)
 def test_ball_collition_physics(self):
     ball1 = Ball((2**0.5 / 20, 0.9), (0, -1), 0.1)
     ball2 = Ball((-2**0.5 / 20, -0.9), (0, 1), 0.1)
     simulation = SimulationModule(balls_arr=[ball1, ball2])
     conductor = ConductorWithNoOutput(simulation_module=simulation,
                                       simulation_time_timeout=1.4 -
                                       2**0.5 / 10)
     conductor.run_simulation()
     self.assert_ball_is_in_position(ball1, (0.5, 2**0.5 / 20))
     self.assert_ball_is_in_position(ball2, (-0.5, -2**0.5 / 20))
 def test_collide_with_wall(self):
     boundery = SlipperyBounceBounderyConditions_2D()
     ball1 = Ball((0, 0), (1, 0), 0.1)
     simulation = SimulationModule(
         boundery_conditions=boundery,
         balls_arr=[ball1],
         halt_condition=HaltConditions.HaltAtGivenSimulationTime(1.8))
     conductor = ConductorWithNoOutput(simulation_module=simulation)
     conductor.run_simulation()
     self.assert_ball_is_in_position(ball1, (0, 0))
 def test_multiple_halt_conditions_2(self):
     boundery = SlipperyBounceBounderyConditions_2D()
     ball1 = Ball((0, 0), (1, 0), 0.1)
     halt_condition = HaltConditions.HaltAtGivenSimulationTime(
         0.4) | HaltConditions.HaltAtBallExitsRectangle((-1, -1), (0.3, 1))
     simulation = SimulationModule(boundery_conditions=boundery,
                                   balls_arr=[ball1],
                                   halt_condition=halt_condition)
     conductor = ConductorWithNoOutput(simulation_module=simulation)
     conductor.run_simulation()
     self.assert_ball_is_in_position(ball1, (0.3, 0))
 def test_multiple_instantaneous_wall_collisions(self):
     boundery = SlipperyBounceBounderyConditions_2D()
     ball1 = Ball((-0.8, 0.5), (-1, 0), 0.1)
     ball2 = Ball((0.8, 0.5), (1, 0), 0.1)
     simulation = SimulationModule(boundery_conditions=boundery,
                                   balls_arr=[ball1, ball2])
     conductor = ConductorWithNoOutput(simulation_time_timeout=0.5,
                                       simulation_module=simulation)
     conductor.run_simulation()
     self.assert_ball_is_in_bounds(ball1, boundery)
     self.assert_ball_is_in_bounds(ball2, boundery)
 def test_many_collitions_1d(self):
     boundery = SlipperyBounceBounderyConditions_2D()
     balls_arr = [
         Ball((-0.5, 0), (1.2, 0), 0.1),
         Ball((0.4, 0), (0.5, 0), 0.1)
     ]
     balls_arr[0].mass *= 10000
     balls_arr[1].color = (1, 0, 0)
     simulation = SimulationModule(boundery_conditions=boundery,
                                   balls_arr=balls_arr)
     conductor = ConductorWithNoOutput(simulation_time_timeout=4,
                                       simulation_module=simulation)
     conductor.run_simulation()
     self.assert_ball_is_in_bounds(balls_arr[0], boundery)
     self.assert_ball_is_in_bounds(balls_arr[1], boundery)
def get_p(volume,
          temperature,
          number_of_balls,
          ball_radius,
          acceptable_relative_uncertainty,
          random_seed=None):
    p_avr = None
    p_relative_uncertainty = None
    wall_collisions_impulse_array = []
    wall_collisions_dt_array = []
    last_collision_time = 0

    def on_wall_collition(*args, wall_index, ball: Ball, **kwargs):
        nonlocal last_collision_time, p_avr, p_relative_uncertainty
        time = simulation.time
        dt = time - last_collision_time
        last_collision_time = time
        v_1d = ball.velocity[
            0] if wall_index in SlipperyBounceBounderyConditions_2D.wall_x_keys else ball.velocity[
                1]
        wall_collisions_impulse_array.append(abs(v_1d) * ball.mass * 2)
        wall_collisions_dt_array.append(dt)
        if len(wall_collisions_impulse_array) % 100 == 0:
            p_avr, p_relative_uncertainty = calculate_pressure(
                wall_collisions_dt_array, wall_collisions_impulse_array,
                side_len)
            if acceptable_relative_uncertainty > p_relative_uncertainty:
                conductor.force_stop()

    side_len = volume**0.5
    boundery = SlipperyBounceBounderyConditions_2D(
        wall_x_0=0,
        wall_x_1=side_len,
        wall_y_0=0,
        wall_y_1=side_len,
        on_wall_collision_event=on_wall_collition)
    ball_1d_locations = np.linspace(ball_radius, side_len - ball_radius,
                                    int(np.ceil(number_of_balls**0.5)))
    np.random.seed(random_seed)
    balls_arr = [
        Ball((x, y), get_random_velocity(temperature), ball_radius)
        for x in ball_1d_locations for y in ball_1d_locations
    ][:number_of_balls]
    simulation = SimulationModule(boundery_conditions=boundery,
                                  balls_arr=balls_arr)
    conductor = ConductorWithNoOutput(simulation_module=simulation)
    conductor.run_simulation()
    return p_avr, p_relative_uncertainty * p_avr