(based on Example 3-1)
Calculate the net magetic field produced by a three-phase stator (adapted for 50Hz).
Showing a 2-pole and a 4-pole machine side by side
Import the PyLab namespace (provides set of useful commands and constants like $\pi$):
In [1]:
%pylab inline
Set up the basic conditions:
In [2]:
bmax = 1 # Normalize bmax to 1
freq = 50 # [Hz]
w = 2*pi*freq # [rad/s] angluar velocity
First, generate the three component magnetic fields
In [3]:
# specify number of pole pairs = 2 * number of poles
pp = 2
# create the time vector
t = linspace(0, 2*pp/freq, 100*pp) # 100 values for one period
wt = w*t # we are going to use this quite often
# amplitudes (changed them to see effect of unsymmetry):
B_amp = [[1.0], [1.0], [1.0]]
# time variants
B_time = array([sin(wt),
sin(wt-2*pi/3),
sin(wt+2*pi/3)])
# time variants for pole pairs
Bpp_time = array([sin(wt/pp),
sin((wt-2*pi/3)/pp),
sin((wt+2*pi/3)/pp)])
# vectorial shifts
B_shift = [[cos(0) + 1j*sin(0)],
[cos(2*pi/3) + 1j*sin(2*pi/3)],
[cos(-2*pi/3) + 1j*sin(-2*pi/3)]]
# vectorial shifts for pole pairs
Bpp_shift = [[cos(0) + 1j*sin(0)],
[cos(2*pi/3/pp) + 1j*sin(2*pi/3/pp)],
[cos(-2*pi/3/pp) + 1j*sin(-2*pi/3/pp)]]
# all combined
B = B_amp * B_time * B_shift
Bpp = B_amp * Bpp_time * Bpp_shift
Calculate total flux vector Btot
:
In [4]:
Btot = B[0] + B[1] + B[2]
Bpptot = Bpp[0] + Bpp[1] + Bpp[2]
Calculate a circle representing the expected maximum value of Btot
:
In [5]:
circle = 1.02 * 1.5 * (cos(wt) + 1j*sin(wt))
Generating the animation:
In [6]:
# First set up the figure, the axis, and the plot element we want to animate
from matplotlib import animation
fig = figure()
ax1 = fig.add_subplot(1, 2, 1)
ax2 = fig.add_subplot(1, 2, 2, sharey=ax1)
ax1.set_title('Flux for 2 pole machine')
ax1.set_xlabel('Real')
ax1.set_ylabel('Imag')
ax1.set_xlim(-1.6, 1.6)
ax1.set_ylim(-1.6, 1.6)
#ax1.set_aspect('equal', 'datalim')
ax1.set_aspect('equal')
ax2.set_title('Flux for {:.0f} pole machine'.format(2*pp))
ax2.set_xlabel('Real')
ax2.set_ylabel('Imag')
ax2.set_xlim(-1.6, 1.6)
ax2.set_ylim(-1.6, 1.6)
ax2.set_aspect('equal')
# set up the different line colours
la, lb, lc, ltot, circ = ax1.plot([], [], 'red',
[], [], 'green',
[], [], 'blue',
[], [], 'magenta',
[], [], 'magenta',
lw=2)
pa, pb, pc, ptot, pcirc = ax2.plot([], [], 'red',
[], [], 'green',
[], [], 'blue',
[], [], 'magenta',
[], [], 'magenta',
lw=2)
tight_layout() # sometimes useful when sub-plots get a bit crowded
# initialization function: plot the background of each frame
def init():
ax1.plot(real(circle), imag(circle), 'black', lw=0.1);
ax2.plot(real(circle), imag(circle), 'black', lw=0.1);
return
# animation function. This is called sequentially
def animate(simData):
i = simData - 1 # python index starts at 0
re = [real(B[0,i]), real(B[1,i]), real(B[2,i])]
im = [imag(B[0,i]), imag(B[1,i]), imag(B[2,i])]
la.set_data([0, re[0]], [0, im[0]])
lb.set_data([re[0], re[0]+re[1]], [im[0], im[0]+im[1]])
lc.set_data([re[0]+re[1], re[0]+re[1]+re[2]], [im[0]+im[1], im[0]+im[1]+im[2]])
ltot.set_data([0, real(Btot[i])], [0, imag(Btot[i])])
circ.set_data(real(Btot[:i]),imag(Btot[:i]))
pre = [real(Bpp[0,i]), real(Bpp[1,i]), real(Bpp[2,i])]
pim = [imag(Bpp[0,i]), imag(Bpp[1,i]), imag(Bpp[2,i])]
pa.set_data([0, pre[0]], [0, pim[0]])
pb.set_data([pre[0], pre[0]+pre[1]], [pim[0], pim[0]+pim[1]])
pc.set_data([pre[0]+pre[1], pre[0]+pre[1]+pre[2]], [pim[0]+pim[1], pim[0]+pim[1]+pim[2]])
ptot.set_data([0, real(Bpptot[i])], [0, imag(Bpptot[i])])
pcirc.set_data(real(Bpptot[:i]),imag(Bpptot[:i]))
return
# call the animator:
anim = animation.FuncAnimation(fig, animate, init_func=init, interval=50)
If run "normally" (and not in "inline" mode like we are doing here) the command above would have opened a window with the animation running. On the server we can only run "inline" mode but there is a solution to simply generate the animation as a video and embed it right here:
In [7]:
from IPython.display import HTML
HTML(anim.to_html5_video())
Out[7]: