import matplotlib.pyplot as plt
from matplotlib.patches import Circle
import numpy as np
import scipy.stats as st
import numpy.random as rnd
rnd.seed(100) # Set the seed
from irfpy.util import collision as coll
lim = 200
n_particle = 500
r = 0.5
def main():
# Only 2D.
poslist = rnd.uniform(0, lim, size=[n_particle, 3])
poslist[:, 2] = 0
vellist = rnd.uniform(0.1, 0.4, size=[n_particle, 3])
vellist[:int(n_particle * 0.2)] = rnd.uniform(-0.4, -0.38, size=[int(n_particle * 0.2), 3])
vellist[:, 2] = 0
## Time series of mean, std, skew, and kutosis
vxmean = [np.mean(vellist[:, 0])] # bulk velocity
vxstd = [np.std(vellist[:, 0])] # thermal velocity
vxskew = [st.skew(vellist[:, 0])]
vxkurt = [st.kurtosis(vellist[:, 0])]
ncoll = [0]
snapshot(poslist, vellist, 0, ())
for t in range(1, 1000):
print('t={}'.format(t))
poslist, vellist, cpair = progress(poslist, vellist)
vxmean.append(np.mean(vellist[:, 0]))
vxstd.append(np.std(vellist[:, 0]))
vxskew.append(st.skew(vellist[:, 0]))
vxkurt.append(st.kurtosis(vellist[:, 0]))
ncoll.append(ncoll[-1] + len(cpair))
print(vxmean[-1], vxstd[-1], vxskew[-1], vxkurt[-1])
if t % 10 == 0 or t <= 100:
# if t % 60 == 0:
snapshot(poslist, vellist, t, cpair)
timeser(vxmean, vxstd, vxskew, vxkurt, ncoll)
def timeser(mean, std, skew, kurt, ncoll):
fig = plt.figure()
ax = fig.add_subplot(511)
ax.plot(mean)
ax.axhline(0, color='r', ls=':')
ax.set_ylabel('Mean')
ax = fig.add_subplot(512)
ax.plot(std)
ax.set_ylabel('StD')
ax = fig.add_subplot(513)
ax.plot(skew)
ax.axhline(0, color='r', ls=':')
ax.set_ylabel('Skewness')
ax = fig.add_subplot(514)
ax.plot(kurt)
ax.axhline(0, color='r', ls=':')
ax.set_ylabel('Kurtsis')
ax = fig.add_subplot(515)
ax.plot(ncoll)
ax.set_ylabel('N-coll')
fig.savefig('binary5_timeseries')
plt.close(fig)
def progress(poslist, vellist):
### Very crude way checking the collision.
coll_l = r * 2
collision_pair = []
n = n_particle
for i in range(n):
for j in range(i+1, n):
if np.linalg.norm(poslist[i, :] - poslist[j, :]) < coll_l: # Collision
print(' Collision between {} and {}'.format(i, j))
v1, v2 = coll.binary_collision(1, poslist[i, :], vellist[i, :], 1, poslist[j, :], vellist[j, :], coll_l)
vellist[i, :] = v1
vellist[j, :] = v2
collision_pair.append((i, j))
poslist = poslist + vellist
while poslist.max() >= lim:
poslist = np.where(poslist >= lim, poslist - lim, poslist)
while poslist.min() < 0:
poslist = np.where(poslist < 0, poslist + lim, poslist)
return poslist, vellist, collision_pair
def snapshot(poslist, vellist, t, cpair):
fig = plt.figure(figsize=(8, 14))
ax = fig.add_subplot(211)
for i in range(poslist.shape[0]):
c = Circle([poslist[i, 0], poslist[i, 1]], r, color='b', edgecolor='none')
ax.add_patch(c)
ax.plot([poslist[i, 0], poslist[i, 0] + vellist[i, 0]], [poslist[i, 1], poslist[i, 1] + vellist[i, 1]], 'k')
for i, j in cpair:
ax.plot([poslist[i, 0], poslist[j, 0]], [poslist[i, 1], poslist[j, 1]], 'r:')
ax.set_aspect(1)
ax.set_xlim(0, lim)
ax.set_ylim(0, lim)
ax.set_title('Position of atoms')
import scipy.stats
xvalue = np.linspace(-0.5, 0.5, 100)
normed = True
ax2 = fig.add_subplot(413)
ax2.hist(vellist[:, 0], bins=xvalue, normed=normed)
m1 = np.mean(vellist[:, 0])
m2 = np.std(vellist[:, 0])
pdf = scipy.stats.norm.pdf(xvalue, loc=m1, scale=m2)
ax2.plot(xvalue, pdf)
ax2.set_xlim(-0.5, 0.5)
ax2.set_ylim(0, 10)
ax2.set_title('Normalized probability dstrbtn (vx)')
ax2 = fig.add_subplot(414)
ax2.hist(vellist[:, 1], bins=xvalue, normed=normed)
m1 = np.mean(vellist[:, 1])
m2 = np.std(vellist[:, 1])
pdf = scipy.stats.norm.pdf(xvalue, loc=m1, scale=m2)
ax2.plot(xvalue, pdf)
ax2.set_xlim(-0.5, 0.5)
ax2.set_ylim(0, 10)
ax2.set_title('Normalized probability dstrbtn (vy)')
fig.savefig('binary5_t{:03d}.png'.format(t))
plt.close()
if __name__ == '__main__':
main()