def check_forces(pool): """ Compares the forces calculated by the octtree method to those calculated through brute force on 25 particles """ sample_size = 25 sim.send_data(pool) if sample_size > sim.PARTICLE_COUNT: sample_size = sim.PARTICLE_COUNT indices = random.sample(range(len(sim.PARTICLES)), sample_size) pool.imap(sim.get_forces_raw, indices) results = [] for arr in sim.get_results(pool): results += arr raw_forces = sorted(results, key=lambda item: item[0]) raw_forces = np.array([i[1] for i in raw_forces]) pool.imap(sim.get_forces_tree, indices) results = [] for arr in sim.get_results(pool): results += arr approx_forces = sorted(results, key=lambda item: item[0]) approx_forces = np.array([i[1] for i in approx_forces]) factors = np.abs(approx_forces / raw_forces) factors = np.array([np.sum(i) / 3 for i in factors]) return [factors.mean(), factors.std()]
def get_timing(pool): """ Measures and returns the time taken to calculate the forces on all the particles using both the particle mesh method and the octtree """ sim.send_data(pool) start_tree = time.time() pool.imap(sim.get_forces_tree, range(sim.PARTICLE_COUNT)) sim.get_results(pool) end_tree = time.time() start_mesh = time.time() sim.get_forces_mesh() end_mesh = time.time() return [end_tree - start_tree, end_mesh - start_mesh]
def apply_forces(pool, timestep): """ Calculates and applies the forces over the provided timestep using the octtree method """ sim.send_data(pool) pool.imap(sim.get_forces_tree, range(len(sim.PARTICLES))) results = sim.get_results(pool) for array in results: for index, force in array: sim.PARTICLES[index].apply_force(force, timestep)