The goal is to animate/simulate a sprinkler. The basic idea is to create multiple droplets at an instance, each exiting the sprinkler at a different angle. However, instead of having a point that moves along, I'm getting a straight, static line. I've tried the same code with only one or 2 drops/points, but I still get the same straight line. At first I thought it was because I included drag into the animation (in previous trials I got strange/unexpected results when I included the drag, so I was hoping it was the same problem)
Below is the code I wrote.
EDIT: dragx and dragy are no longer set to the same values. The initial velocities are calculated outside the update function.
Drag forces are recalculated at each index increase, since the drag depends on the velocity.
The imports are also now included.
I have also now tried to use a scatter plot instead of a line, which gave me a single dot at the origin. I reverted back to the line since then
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as animation
from math import sin, cos
import matplotlib.axes as axess
#pressure in system
def pressure(pump):
return 10.197*pump*10**5/998.2
#Initial velocity based on the pressure of the system
def vinit(init_head):
return (2*9.81*init_head)**0.5
# Number of droplets per iteration
n = 2
v0 = vinit(pressure(5.8))
cd = 0.5 #drag coefficient of a sphere;
rho = 1.225 #density of air; kg/m^3
fps = 20
runtime = 1*20
numframes = fps*runtime
time = np.linspace(0,runtime,numframes)
#Initialize droplets
droplets = np.zeros(numframes, dtype = [('position', float, 2),
('velocity', float, 2),
('force', float, 2),
('angle',float, 1),
('radius', float, 1)])
droplets['radius'] = np.random.normal(0.0045, 0.001, numframes)
A = 4*np.pi*droplets['radius']**2
mass = ((4*np.pi*droplets['radius']**3)/3)*1000 #mass of waterdroplet
drag = np.zeros(numframes,dtype = [('dragx', float, 1),('dragy', float, 1)])
rads = np.radians(np.random.normal(37,1,numframes))
droplets['angle'] = rads
droplets['force'][:,1] = -9.8*mass
#Initialize velocity
for i in range(0, numframes):
droplets['velocity'][i,0] = v0*cos(droplets['angle'][i])
droplets['velocity'][i,1] = v0*sin(droplets['angle'][i])
#Initialize the drag
drag['dragx'] = -0.5*rho*cd*A*droplets['velocity'][:,0]
drag['dragy'] = -0.5*rho*cd*A*droplets['velocity'][:,1]
droplets['position'][:,0] = 0
#Initialize the figure
fig,ax = plt.subplots()
axess.Axes.set_frame_on(ax,True)
ax.autoscale(True)
ax.set_xlim(0)
ax.set_ylim(0)
line = ax.plot(droplets['position'][0, 0], droplets['position'][0, 1],'b.')[0]
line = ax.plot(droplets['position'][:, 0], droplets['position'][:, 1],'b.')[0]
xdata = [droplets['position'][0, 0]]
ydata = [droplets['position'][0, 1]]
ln = plt.plot([],[],'b')[0]
def initfunc():
droplets['position'][0,:] = 0
ln.set_data(droplets['position'][0, 0], droplets['position'][0, 1])
return ln
def update(framenum):
index = framenum
cd = 0.5 #drag coefficient of a sphere;
rho = 1.225 #density of air; kg/m^3
A = 4*np.pi*droplets['radius']**2 #surface area of droplet; m^2
mass = ((4*np.pi*droplets['radius']**3)/3)*1000 #mass of waterdroplet
#Update the drag force on the droplet
drag['dragx'] = -0.5*rho*cd*A*droplets['velocity'][:,0]
drag['dragy'] = -0.5*rho*cd*A*droplets['velocity'][:,1]
droplets['force'][index,0] += drag['dragx'][index]
droplets['force'][index,1] += drag['dragy'][index]
#droplets['position'][0] = [0,0]
droplets['velocity'][index,0] = droplets['velocity'][index,0] + (droplets['force'][index,0]/mass[index])*index
droplets['velocity'][index,1] = droplets['velocity'][index,1] + (droplets['force'][index,1]/mass[index])*index
droplets['position'][index,0] = droplets['position'][index,0] + (droplets['velocity'][index,0])*index
droplets['position'][index,1] = droplets['position'][index,1] + (droplets['velocity'][index,1])*index
xdata.append(droplets['position'][index,0])
ydata.append(droplets['position'][index,1])
ln.set_data(xdata,ydata)
line.set_data(droplets['position'][:,0], droplets['position'][:,1])
return ln
sprink = animation.FuncAnimation(fig, update,init_func = initfunc,interval= 200, frames = numframes)
plt.show()
sprink.save('Sprinkler.mp4', fps = fps)