brown/particles.py

81 lines
2.4 KiB
Python
Raw Permalink Normal View History

2019-07-12 19:52:12 +00:00
from brown.interaction import UFuncWrapper
from brown.brown import BrownIterator
import numpy as np
from collections import deque
from copy import copy
import matplotlib.pyplot as plt
import matplotlib.animation as ani
from coefficients import c
2019-07-12 19:52:12 +00:00
#force_function = UFuncWrapper(0, c)
#interaction2D = UFuncWrapper(1, c)
2019-07-16 18:44:15 +00:00
# Borders for both the plot and the boundary condition
# (the boundary condition might be deactivated, when creating
# the BrownIterator).
borders_x = [-100, 100]
borders_y = [-100, 100]
n_particles = 600
2019-07-16 18:44:15 +00:00
# Idk, seems to not do anyting.
2019-07-13 13:20:50 +00:00
frames = 100
2019-07-16 18:44:15 +00:00
# Only spawn in 1/x of the borders.
spawn_restriction = 3
2019-07-16 18:44:15 +00:00
# Time resolution. Note that setting this to a too
# high value (i.e. low resolution) will lead to
# erratic behaviour, because potentials can be skipped.
dt = 0.1
2019-07-13 12:31:37 +00:00
c[-1] = dt
2019-07-12 19:52:12 +00:00
2019-07-16 18:44:15 +00:00
# Initial positions.
x_coords = np.random.uniform(borders_x[0] / spawn_restriction, borders_x[1] / spawn_restriction, n_particles).astype(np.float16)
y_coords = np.random.uniform(borders_y[0] / spawn_restriction, borders_y[1] / spawn_restriction, n_particles).astype(np.float16)
2019-07-12 19:52:12 +00:00
2019-07-16 18:44:15 +00:00
# Initial momenta are 0.
2019-07-12 19:52:12 +00:00
x_momenta = np.zeros(n_particles, dtype=np.float16)
y_momenta = np.zeros(n_particles, dtype=np.float16)
2019-07-16 18:44:15 +00:00
# Prepare the plot, remove axis & stuff.
2019-07-12 19:52:12 +00:00
fig = plt.figure(figsize=(7, 7))
ax = fig.add_axes([0, 0, 1, 1], frameon=False)
ax.set_xlim(*borders_x)
ax.set_xticks([])
ax.set_ylim(*borders_y)
ax.set_yticks([])
2019-07-16 18:44:15 +00:00
# Plot the initial values.
2019-07-12 19:52:12 +00:00
plot, = ax.plot(x_coords, y_coords, "b.")
center_of_mass, = ax.plot(x_coords.mean(), y_coords.mean(), "r-")
2019-07-16 18:44:15 +00:00
# Keep track of the center of mass.
2019-07-12 19:52:12 +00:00
center_of_mass_history_x = deque([x_coords.mean()])
center_of_mass_history_y = deque([y_coords.mean()])
2019-07-16 18:44:15 +00:00
brown = BrownIterator(-1, c # Max iterations, simulation parameters.
2019-07-12 19:52:12 +00:00
, x_coords, y_coords
, y_momenta, y_momenta
2019-07-16 18:44:15 +00:00
# The boundary condition: reflect at the borders,
2019-07-13 13:20:50 +00:00
, borders_x, borders_y
2019-07-16 18:44:15 +00:00
# or just let propagate to infinity.
2019-07-13 13:20:50 +00:00
#, [], []
2019-07-16 18:44:15 +00:00
# Let the border dampen the system, border_dampening < 1 => energy is absorbed.
2019-07-12 19:52:12 +00:00
, border_dampening=1
2019-07-13 12:31:37 +00:00
, dt=dt)
2019-07-12 19:52:12 +00:00
u = iter(brown)
def update(i):
2019-07-16 18:44:15 +00:00
# Get the next set of positions.
2019-07-12 19:52:12 +00:00
data = next(u)
center_of_mass_history_x.append(x_coords.mean())
center_of_mass_history_y.append(y_coords.mean())
plot.set_data(*data)
center_of_mass.set_data(center_of_mass_history_x, center_of_mass_history_y)
animation = ani.FuncAnimation(fig, update, range(frames), interval=1)
plt.show()
2019-07-13 12:31:37 +00:00
#animation.save("animation.mp4", fps=30)