def test_drag_velocity_implicit_explicit(self): """ Tests simulated terminal velocity against a calculated value using implicit and explicit integration. """ v = 5 # Fluid speed def get_vel_fluid(self): return [v, 0, 0] data = [] tau = None for timestep in [1]: p_implicit = Particle(0, [0, 0, 0], [0, 0, 0], get_vel_fluid=get_vel_fluid, get_gravity=lambda dummy: [0, 0, 0], diameter=0.001) p_explicit = Particle(1, [0, 0, 0], [0, 0, 0], get_vel_fluid=get_vel_fluid, get_gravity=lambda dummy: [0, 0, 0], diameter=0.001) times = [] explicit = [] implicit = [] analytic = [] last_time = 0 for time in np.arange(0, 40, timestep): p_explicit.iterate(time - last_time, implicit=False) p_implicit.iterate(time - last_time, implicit=True) times.append(time) explicit.append(vect.mag(p_explicit.vel)) implicit.append(vect.mag(p_implicit.vel)) tau = p_explicit.get_tau() analytic.append(v * (1 - math.exp(- time / tau))) last_time = time data.append([times, explicit]) data.append([times, implicit]) data.append([times, analytic]) fig = plt.figure() fig.patch.set_facecolor('white') ax = fig.gca() plots = [] for i in range(len(data[0][0])): data[0][0][i] /= tau for d in data: for j in range(len(d[1])): d[1][j] = d[1][j] / v plots.append(ax.plot(d[0], d[1])[0]) ax.set_xlabel(r'$t/\tau$') ax.set_ylabel(r'Speed / Max Speed') plt.legend(plots, ['Explicit', 'Implicit', 'Analytic'], loc=4) plt.show() print("Explicit terminal velocity = {0}".format(data[0][1][-1])) print("Implicit terminal velocity = {0}".format(data[1][1][-1])) # Test if terminal velocity is within 0.1% of a calculated value. explicit_diff_sum = 0 implicit_diff_sum = 0 length = len(data[0][0]) for i in range(1, length): # Start at 1 to avoid division by zero at the initial conditions. explicit_diff_sum += (data[0][1][i] - data[2][1][i]) / data[2][1][i] implicit_diff_sum += (data[1][1][i] - data[2][1][i]) / data[2][1][i] explicit_avg = 100 * np.abs(explicit_diff_sum / length) print("Explicit average percentage difference = {0}".format(explicit_avg)) implicit_avg = 100 * np.abs(implicit_diff_sum / length) print("Implicit average percentage difference = {0}".format(implicit_avg))
def test_bouncing_collision_timesteps(self): p1 = Particle(1, [0, 0.5, 0], [0, 0, 0], 0.1) p2 = Particle(2, [0, 0, 0], [0, 0, 0], 0.1, density=1e99, get_gravity=lambda dummy: [0, 0, 0]) col = Collision(p1, p2, 1e5, restitution=0.8) tau = p1.get_tau() timesteps = np.arange(0.0005, 0.001, 0.00001) overlap_errors = [] for timestep in timesteps: last_time = 0 for time in np.arange(0, 10, timestep): delta_t = time - last_time col.calculate(delta_t) p1.iterate(delta_t) p2.iterate(delta_t) last_time = time predicted_overlap = p1.get_mass() * vect.mag(p1.get_gravity(p1)) / col.stiffness percent_dif = 100 * np.abs(col.get_particle_overlap() / predicted_overlap) - 100 overlap_errors.append(percent_dif) for i in range(len(timesteps)): timesteps[i] /= tau fig = plt.figure() fig.patch.set_facecolor('white') ax = fig.add_subplot(111) # ax.set_title('Percentage error against timestep') ax.set_ylabel('Percentage error (%)') ax.set_xlabel('Timestep (seconds)') ax.plot(timesteps, overlap_errors) plt.show()
def test_get_collision_normal(self): p1 = Particle(1, [0, 0, 0], [0, 0, 0]) p2 = Particle(2, [1, 1, 1], [0, 0, 0]) col = Collision(p1, p2) TestCase.assertAlmostEquals(self, vect.mag( col.get_collision_normal() - (np.array([1, 1, 1]) / vect.mag([1, 1, 1]))), 0)
def calculate_tangential_friction_force(self, normal_force, delta_t): f_dyn = -self.friction_coefficient * vect.mag( normal_force) * self.get_collision_tangent() f_static = -self.friction_stiffness * self.get_tangential_displacement( delta_t) * self.get_collision_tangent() if vect.mag_squared(f_dyn) < vect.mag_squared(f_static): return f_dyn else: return f_static
def get_percent_dif(particle1, particle2, delta_t): print(" Testing " + str(delta_t)) last_time = 0 for time in np.arange(0, 10, delta_t): delta_t = time - last_time col.calculate(delta_t) particle1.iterate(delta_t) particle2.iterate(delta_t) last_time = time predicted_overlap = particle1.get_mass() * vect.mag(particle1.get_gravity(particle1)) / col.stiffness percent_dif = 100 * np.abs(col.get_particle_overlap() / predicted_overlap) - 100 return percent_dif
def test_terminal_velocity(self): """ Tests simulated terminal velocity against a calculated value. """ data = [] for timestep in [0.1, 1, 2, 3, 4, 5, 6]: p = Particle(1, [0, 0, 0], [0, 0, 0]) times = [] speeds = [] last_time = 0 for time in np.arange(0, 40, timestep): p.iterate(time - last_time) times.append(time) speeds.append(vect.mag(p.vel)) last_time = time data.append([times, speeds]) fig = plt.figure() fig.patch.set_facecolor('white') ax = fig.gca() for d in data: ax.plot(d[0], d[1]) plt.show() # Test if terminal velocity is within 0.1% of a calculated value. self.assertLess(np.abs(vect.mag(data[0][1][-1]) / 56.442091968912 - 1), 0.001)
def test_bouncing_collision(self): p1 = Particle(1, [0, 0.5, 0], [0, 0, 0], 0.1) p2 = Particle(2, [0, 0, 0], [0, 0, 0], 0.1, density=1e99, get_gravity=lambda dummy: [0, 0, 0]) col = Collision(p1, p2, 1e5, restitution=0.8) timestep = 0.0005 last_time = 0 for time in np.arange(0, 10, timestep): delta_t = time - last_time col.calculate(delta_t) p1.iterate(delta_t) p2.iterate(delta_t) last_time = time predicted_overlap = p1.get_mass() * vect.mag(p1.get_gravity(p1)) / col.stiffness print("Predicted overlap = {0}".format(predicted_overlap)) print("Calculated overlap = {0}".format(col.get_particle_overlap())) print("Percentage difference = {0}".format(100 * predicted_overlap / col.get_particle_overlap() - 100)) TestCase.assertAlmostEqual(self, predicted_overlap, col.get_particle_overlap()) particles_to_paraview([p1, p2], "bounce_col", "../../run/bounce_collision/")
def test_low_mem_logging(self): p1 = Particle(1, [0, 0.5, 0], [0, 0, 0], 0.1) p2 = Particle(2, [0, 0, 0], [0, 0, 0], 0.1, density=1e99, get_gravity=lambda dummy: [0, 0, 0]) col = Collision(p1, p2, 1e5, restitution=0.8) timestep = 0.0005 logger = Logger([p1, p2], "low_mem_logging", "../../run/low_mem_logging/") logger.log(0) last_time = 0 for time in np.arange(0, 10, timestep): delta_t = time - last_time col.calculate(delta_t) p1.iterate(delta_t) p2.iterate(delta_t) last_time = time logger.log(time) predicted_overlap = p1.get_mass() * vect.mag(p1.get_gravity(p1)) / col.stiffness print("Predicted overlap = {0}".format(predicted_overlap)) print("Calculated overlap = {0}".format(col.get_particle_overlap())) print("Percentage difference = {0}".format(100 * predicted_overlap / col.get_particle_overlap() - 100))
def get_speed_at_time(self, time): try: index = self.times.index(time) return vect.mag(self.vel_history[index]) except ValueError: return 0
def get_speed(self): return vect.mag(self.vel)
def get_speed_at_index(self, index): return vect.mag(self.vel_history[index])
def get_tangential_displacement(self, delta_t): # TODO: Investigate more accurate methods of numerically integrating this. return vect.mag( (self.get_relative_velocity() - self.get_normal_velocity()) * math.pi * math.sqrt(self.get_reduced_particle_mass() / self.stiffness))
def get_particle_centre_separation(self): return vect.mag(self.p2.pos - self.p1.pos)
def get_tangential_displacement(self, vel, delta_t): # TODO: Investigate more accurate methods of numerically integrating this. return vect.mag(vel * math.pi * math.sqrt(self.p.get_mass() / self.stiffness))
def test_drag_velocity_implicit_explicit_timestep(self): """ Tests simulated terminal velocity against a calculated value using implicit and explicit integration. """ v = 5 # Fluid speed def get_vel_fluid(self): return [v, 0, 0] timesteps = np.arange(0.01, 5, 0.01) explicit_avgs = [] implicit_avgs = [] tau = None for timestep in timesteps: p_implicit = Particle(0, [0, 0, 0], [0, 0, 0], get_vel_fluid=get_vel_fluid, get_gravity=lambda dummy: [0, 0, 0], diameter=0.001) p_explicit = Particle(1, [0, 0, 0], [0, 0, 0], get_vel_fluid=get_vel_fluid, get_gravity=lambda dummy: [0, 0, 0], diameter=0.001) times = [] explicit = [] implicit = [] analytic = [] last_time = 0 data = [] duration = 40 for time in np.arange(0, duration, timestep): p_explicit.iterate(time - last_time, implicit=False) p_implicit.iterate(time - last_time, implicit=True) times.append(time) explicit.append(vect.mag(p_explicit.vel)) implicit.append(vect.mag(p_implicit.vel)) tau = p_explicit.get_tau() analytic.append(v * (1 - math.exp(- time / tau))) last_time = time data.append([times, explicit]) data.append([times, implicit]) data.append([times, analytic]) # fig = plt.figure() # ax = fig.gca() # plots = [] # for d in data: # plots.append(ax.plot(d[0], d[1])[0]) # ax.set_xlabel('Time ($s$)') # ax.set_ylabel(r'Speed ($ms^{-1}$)') # plt.legend(plots, ['Explicit', 'Implicit', 'Analytic'], loc=4) # plt.show() explicit_dif_sum = 0 implicit_dif_sum = 0 for i in range(1, len(times)): # Start at 1 to avoid division by zero at the initial conditions. explicit_dif = (explicit[i] - analytic[i]) / analytic[i] explicit_dif_sum += timestep * explicit_dif implicit_dif = (implicit[i] - analytic[i]) / analytic[i] implicit_dif_sum += timestep * implicit_dif explicit_avg = 100 * np.abs(explicit_dif_sum / duration) # print("Explicit average percentage difference = {0}".format(explicit_avg)) implicit_avg = 100 * np.abs(implicit_dif_sum / duration) # print("Implicit average percentage difference = {0}".format(implicit_avg)) explicit_avgs.append(explicit_avg) implicit_avgs.append(implicit_avg) for i in range(len(timesteps)): timesteps[i] /= tau fig = plt.figure() fig.patch.set_facecolor('white') ax = fig.gca() explicit_avgs_plot, = ax.plot(timesteps, explicit_avgs) implicit_avgs_plot, = ax.plot(timesteps, implicit_avgs) ax.set_xlabel(r'$timestep/\tau$') ax.set_ylabel(r'Average percentage difference') plt.legend([explicit_avgs_plot, implicit_avgs_plot], ['Explicit', 'Implicit'], loc=4) plt.show()