diff --git a/sim.py b/sim.py index ea402c4..e400744 100644 --- a/sim.py +++ b/sim.py @@ -137,7 +137,7 @@ class Simulation: self.spatial_grid = {k: set(v) for k, v in cell_lists.items()} - """def _check_dormant_state(self, x, y, particle): + def _check_dormant_state(self, x, y, particle): key = (x, y) if particle.particle_type == 'wall': self.dormant_particles.add(key) @@ -157,7 +157,7 @@ class Simulation: particle.last_position = (x, y) self.particle_movement_counter[key] = 0 self.dormant_particles.discard(key) - return False""" + return False def handle_phase_transitions(self, particle, x, y): # this is where we handle all the phase transitions. """Handle all phase transitions for a particle""" @@ -308,7 +308,53 @@ class Simulation: return fx, fy - + def _process_particle_batch(self, batch, dt): + updates = [] + new_active = set() + + # Filter out dormant particles from the batch + active_batch = [pos for pos in batch if pos not in self.dormant_particles] + + for x, y in active_batch: + particle = self.particles[x][y] + if not particle: + continue + + if particle.particle_type == 'wall': + new_active.add((x, y)) + continue + + # Check if particle should become dormant + if self._check_dormant_state(x, y, particle): + new_active.add((x, y)) + continue + + # physics calculations + fx, fy = self.calculate_forces(particle, x, y) + # Use max() to ensure mass is never zero + mass = max(particle.mass, 0.001) + particle.velocity[0] += (fx / mass) * dt + particle.velocity[1] += (fy / mass) * dt + + new_x = int(x + particle.velocity[0] * dt) + new_y = int(y + particle.velocity[1] * dt) + + if 0 <= new_x < self.width and 0 <= new_y < self.height: + if self.particles[new_x][new_y] is None: + updates.append((x, y, new_x, new_y, particle)) + new_active.add((new_x, new_y)) + # Wake up neighboring dormant particles + self._wake_neighbors(new_x, new_y) + else: + new_active.add((x, y)) + + # Apply updates and return new active set + for old_x, old_y, new_x, new_y, particle in updates: + self.particles[old_x][old_y] = None + self.particles[new_x][new_y] = particle + particle.position = (new_x, new_y) + + return new_active def _get_quick_neighbors(self, x, y): """Quick neighbor lookup without full spatial grid"""