In [1]:
import es1d
import numpy as np
nx = 120
box = 4 * np.pi
dt = 0.1
tmax = 50.0
ppc = 500
vfl = 0.1
vth = 0.001
right = es1d.Species( "right", -1.0, ppc, vfl = vfl, vth = vth )
vfl = -vfl
left = es1d.Species( "left", -1.0, ppc, vfl = vfl, vth = vth )
# Initialize the simulation without diagnostics
sim = es1d.Simulation( nx, box, dt, species = [right,left] )
Instead of calling the run method as usual, we chose to call the iter method instead, that advances the simulation 1 time step. This is done inside an animate function that is responsible for updating the movie frames.
To lower the overall frame count and speed up things, we don't create a frame for every iteration, and automatically skip a few iterations based on the movie parameters.
Note that for this particular example, the time is mostly spent generating the animation, the simulation time is almost negligible.
In [2]:
import matplotlib.pyplot as plt
from matplotlib import animation
from IPython.display import display
import ipywidgets
# Movie parameters
nframes = 200
tmax = 150.0
fps = 16
# Create progress bar
bar = ipywidgets.FloatProgress( min = 0, max = 200 )
label = ipywidgets.HTML()
prog = ipywidgets.VBox(children=[label, bar])
display(prog)
# Create plot
x = lambda s : (s.particles['ix'] + s.particles['x']) * s.dx
fig, ax = plt.subplots()
plt.rc('font', size=12)
fig.set_size_inches( (10.66,6.0) )
(v1,) = ax.plot([], [], '.', ms=1,alpha=0.3, label = "Left")
(v2,) = ax.plot([], [], '.', ms=1,alpha=0.3, label = "Right")
ax.set_xlabel("x")
ax.set_ylabel("v")
ax.set_title("v-x phasespace\nt = {:.1f}".format(sim.t))
ax.grid(True)
ax.set_xlim( (0,box ))
ax.set_ylim( (-0.4, 0.4) )
# Function to create each movie frame
skip = np.int32(np.ceil((tmax / dt ) / (nframes-1) ))
def animate(i):
label.value = "Generating frame {:d}/200 ...".format(i+1)
bar.value = i
if ( i > 0 ):
for j in range(skip):
sim.iter()
v1.set_xdata(x(left))
v1.set_ydata(left.particles['vx'])
v2.set_xdata(x(right))
v2.set_ydata(right.particles['vx'])
ax.set_title("v-x phasespace\nt = {:.1f}".format(sim.t))
return (v1,v2)
# Create the movie
anim = animation.FuncAnimation( fig, animate, frames = nframes, repeat = False, blit = True, interval = 1000.0/fps )
movie = ipywidgets.HTML(anim.to_html5_video())
# Show the completed movie
label.value = "Done!"
bar.bar_style = "success"
display(movie)
In [ ]: