Space Vector Representation

The space vector representation of three-phase voltages is given by

${\bf{f}}(t)=\displaystyle\frac{2}{3}\left(v_a(t)+v_b(t)\,e^{j2\pi/3}+ v_c(t)\,e^{j4\pi/3}\right)$.

In a three-phase voltage source,

$v_a(t) = V_m \sin(100\pi t)$,

$v_b(t) = 0.1\,V_m \sin(100\pi t - 120^\circ)$,

$v_c(t) = V_m \sin(100\pi t - 240^\circ)$,

where $V_m=325\,$V. Identify the shape of the space vector. Determine the frequency at which the magnitude of the space vector varies. Also determine the maximum and minimum magnitude of the space vector.

In [1]:
import numpy as np
import matplotlib.pyplot as plt 
import gseim_calc as calc
import cmath
from setsize import set_size
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator)
from matplotlib import animation
from matplotlib import ticker
from IPython.display import HTML

N1 = 1
N2 = 0

Vm0 = 325.0

Vm1_a = 1.0*Vm0
Vm1_b = 0.1*Vm0
Vm1_c = 1.0*Vm0

Vm2_a = 0.0
Vm2_b = 0.0
Vm2_c = 0.0

# Note: phi values are in degrees

phi1_a_deg = 0.0
phi1_b_deg = 120.0
phi1_c_deg = 240.0

phi2_a_deg = 0.0
phi2_b_deg = 120.0
phi2_c_deg = 240.0

k_deg_to_rad = np.pi/180.0

phi1_a = phi1_a_deg*k_deg_to_rad
phi1_b = phi1_b_deg*k_deg_to_rad
phi1_c = phi1_c_deg*k_deg_to_rad

phi2_a = phi2_a_deg*k_deg_to_rad
phi2_b = phi2_b_deg*k_deg_to_rad
phi2_c = phi2_c_deg*k_deg_to_rad

T = 20.0e-3
omg = 2.0*np.pi/T

t_total = 2.0*(T/N1)

theta1 = 2.0*np.pi/3

n_div = 100
t = np.linspace(0.0, t_total, (n_div+1))

Va = Vm1_a*np.sin(N1*(omg*t - phi1_a)) + \
     Vm2_a*np.sin(N2*(omg*t - phi2_a))
Vb = Vm1_b*np.sin(N1*(omg*t - phi1_b)) + \
     Vm2_b*np.sin(N2*(omg*t - phi2_b))
Vc = Vm1_c*np.sin(N1*(omg*t - phi1_c)) + \
     Vm2_c*np.sin(N2*(omg*t - phi2_c))

color_a = "blue"
color_b = "red"
color_c = "green"
color_v = "black"

t_ms = t*1e3

x1a = []
x1b = []
x1c = []

y1a = []
y1b = []
y1c = []

Vm1 = max(Vm1_a, Vm1_b)
Vm1 = max(Vm1,   Vm1_c)

Vm2 = max(Vm2_a, Vm2_b)
Vm2 = max(Vm2,   Vm2_c)

a1 = 5.0*(Vm1+Vm2)

# lines showing 0, 120, 240 deg

x1a.append(-a1)
x1a.append( a1)

y1a.append(0.0)
y1a.append(0.0)

x1b.append(a1*np.cos(theta1-np.pi))
x1b.append(a1*np.cos(theta1))

y1b.append(a1*np.sin(theta1-np.pi))
y1b.append(a1*np.sin(theta1))

x1c.append(a1*np.cos(-theta1+np.pi))
x1c.append(a1*np.cos(-theta1))

y1c.append(a1*np.sin(-theta1+np.pi))
y1c.append(a1*np.sin(-theta1))

vec_a = []
vec_b = []
vec_c = []
vec2 = []

k1 = 2/3

for i in range(len(Va)):
    vec_a1 = k1*Va[i]*(complex(1.0,0.0))
    vec_b1 = k1*Vb[i]*(cmath.exp(complex(0.0, theta1)))
    vec_c1 = k1*Vc[i]*(cmath.exp(complex(0.0,-theta1)))

    vec1 = vec_a1 + vec_b1 + vec_c1

    vec_a.append(vec_a1)
    vec_b.append(vec_b1)
    vec_c.append(vec_c1)

    vec2.append(vec1)

# axis limits for vector plot:

vec2_real = [x_dummy.real for x_dummy in vec2]
vec2_imag = [x_dummy.imag for x_dummy in vec2]
V         = [abs(x_dummy) for x_dummy in vec2]

vec2_real_min = min(vec2_real)
vec2_real_max = max(vec2_real)
vec2_real_delta = vec2_real_max - vec2_real_min

vec2_imag_min = min(vec2_imag)
vec2_imag_max = max(vec2_imag)
vec2_imag_delta = vec2_imag_max - vec2_imag_min

xmin2 = vec2_real_min - 0.02*vec2_real_delta
xmax2 = vec2_real_max + 0.02*vec2_real_delta
ymin2 = vec2_imag_min - 0.02*vec2_imag_delta
ymax2 = vec2_imag_max + 0.02*vec2_imag_delta

V_min = min(V)
V_max = max(V)

print('Vmin:', "%11.4E"%V_min)
print('Vmax:', "%11.4E"%V_max)

# axis limits for V(t) plot:

xmin1 = 0.0
xmax1 = t_total*1e3

Va_min = min(Va)
Va_max = max(Va)
Va_delta = Va_max - Va_min

ymin1 = Va_min - 0.02*Va_delta
ymax1 = Va_max + 0.02*Va_delta
ymax1 = max(ymax1, ymax2)

fig, ax = plt.subplots(nrows=1, ncols=2, sharex=False)
plt.subplots_adjust(wspace=0, hspace=0.0)

set_size(6.0, 3, ax[0])

ax[1].set_aspect('equal', adjustable='box')

ax[0].set(xlim=[xmin1, xmax1], ylim=[ymin1, ymax1])
ax[1].set(xlim=[xmin2, xmax2], ylim=[ymin2, ymax2])

ax[0].set_xlabel(r'time (msec)', fontsize=12)
ax[0].set_ylabel(r'$V(t)$ (V)', fontsize=12)

ax[1].set_xlabel(r'Re(V)', fontsize=12)
ax[1].set_ylabel(r'Im(V)', fontsize=12)

ax[0].grid(color='#CCCCCC', linestyle='solid', linewidth=0.5)
ax[1].grid(color='#CCCCCC', linestyle='solid', linewidth=0.5)

# background V(t) plots (faint):

line1_Va = ax[0].plot(t_ms, Va, color=color_a, linestyle = '-', linewidth=1.0, alpha=0.2)[0]
line1_Vb = ax[0].plot(t_ms, Vb, color=color_b, linestyle = '-', linewidth=1.0, alpha=0.2)[0]
line1_Vc = ax[0].plot(t_ms, Vc, color=color_c, linestyle = '-', linewidth=1.0, alpha=0.2)[0]
line1_V  = ax[0].plot(t_ms, V,  color=color_v, linestyle = '-', linewidth=1.0, alpha=0.2)[0]

line3_Va = ax[1].plot(x1a, y1a, color=color_a, linestyle = '-', linewidth=1.0, alpha=0.2)[0]
line3_Vb = ax[1].plot(x1b, y1b, color=color_b, linestyle = '-', linewidth=1.0, alpha=0.2)[0]
line3_Vc = ax[1].plot(x1c, y1c, color=color_c, linestyle = '-', linewidth=1.0, alpha=0.2)[0]

# live V(t) plots (dark):

line2_Va = ax[0].plot([], [], color=color_a, linestyle = '-', linewidth=1.0)[0]
line2_Vb = ax[0].plot([], [], color=color_b, linestyle = '-', linewidth=1.0)[0]
line2_Vc = ax[0].plot([], [], color=color_c, linestyle = '-', linewidth=1.0)[0]
line2_V  = ax[0].plot([], [], color=color_v, linestyle = '-', linewidth=1.0)[0]

scat_Va = ax[0].scatter(0, 0, color=color_a, marker='o', s=15)
scat_Vb = ax[0].scatter(0, 0, color=color_b, marker='o', s=15)
scat_Vc = ax[0].scatter(0, 0, color=color_c, marker='o', s=15)
scat_V  = ax[0].scatter(0, 0, color=color_v, marker='o', s=15)

# locus traced by vector:

line4 = ax[1].plot([], [], color='grey', linestyle = '--', linewidth=0.8, dashes=(3,3))[0]

# vector diagram:

line5 = []

line5_a = []
line5_b = []
line5_c = []

line5_sum1 = []
line5_sum2 = []

for i in range(3):
    line6 = ax[1].plot([], [], color=color_v, linestyle = '-', linewidth=1.0)[0]

    line6_a = ax[1].plot([], [], color=color_a, linestyle = '-', linewidth=1.0)[0]
    line6_b = ax[1].plot([], [], color=color_b, linestyle = '-', linewidth=1.0)[0]
    line6_c = ax[1].plot([], [], color=color_c, linestyle = '-', linewidth=1.0)[0]

    line5.append(line6)

    line5_a.append(line6_a)
    line5_b.append(line6_b)
    line5_c.append(line6_c)

    line6_sum1 = ax[1].plot([], [], color=color_b, linestyle = '-', alpha=0.5, linewidth=0.8)[0]
    line6_sum2 = ax[1].plot([], [], color=color_c, linestyle = '-', alpha=0.5, linewidth=0.8)[0]

    line5_sum1.append(line6_sum1)
    line5_sum2.append(line6_sum2)

# projections of vector:

line7_Va = ax[1].plot([], [], color=color_a, linestyle = '-', linewidth=1.0)[0]
line7_Vb = ax[1].plot([], [], color=color_b, linestyle = '-', linewidth=1.0)[0]
line7_Vc = ax[1].plot([], [], color=color_c, linestyle = '-', linewidth=1.0)[0]

theta_deg = 20.0
length_arrow = 0.08*Vm1

l1 = []

l1_a = []
l1_b = []
l1_c = []

l1_sum1 = []
l1_sum2 = []

l1_labels = []

l1_a_labels = []
l1_b_labels = []
l1_c_labels = []

l1_sum1_colors = []
l1_sum2_colors = []

def update(frame):
    scat_Va.set_offsets([t_ms[frame], Va[frame]])
    scat_Vb.set_offsets([t_ms[frame], Vb[frame]])
    scat_Vc.set_offsets([t_ms[frame], Vc[frame]])
    scat_V .set_offsets([t_ms[frame], V [frame]])

    x0 = t_ms[:frame+1]
    ya = Va[:frame+1]
    yb = Vb[:frame+1]
    yc = Vc[:frame+1]
    y  = V [:frame+1]

    line2_Va.set_xdata(x0)
    line2_Vb.set_xdata(x0)
    line2_Vc.set_xdata(x0)
    line2_V .set_xdata(x0)

    line2_Va.set_ydata(ya)
    line2_Vb.set_ydata(yb)
    line2_Vc.set_ydata(yc)
    line2_V .set_ydata(y )

    l1.clear()
    l1_labels.clear()

    calc.phasor_append_1(l1, l1_labels, vec2[frame], "$V$")

    l2 = calc.phasor_2(l1, theta_deg, length_arrow, 0.4)

    for k, t in enumerate(l2[0]):
        line5[k].set_xdata(t[0])
        line5[k].set_ydata(t[1])

    l1_a.clear()
    l1_a_labels.clear()

    calc.phasor_append_1(l1_a, l1_a_labels, vec_a[frame], "$V_a$")

    l2_a = calc.phasor_2(l1_a, theta_deg, length_arrow, 0.4)

    for k, t in enumerate(l2_a[0]):
        line5_a[k].set_xdata(t[0])
        line5_a[k].set_ydata(t[1])

    l1_b.clear()
    l1_b_labels.clear()

    calc.phasor_append_1(l1_b, l1_b_labels, vec_b[frame], "$V_b$")

    l2_b = calc.phasor_2(l1_b, theta_deg, length_arrow, 0.4)

    for k, t in enumerate(l2_b[0]):
        line5_b[k].set_xdata(t[0])
        line5_b[k].set_ydata(t[1])

    l1_c.clear()
    l1_c_labels.clear()

    calc.phasor_append_1(l1_c, l1_c_labels, vec_c[frame], "$V_c$")

    l2_c = calc.phasor_2(l1_c, theta_deg, length_arrow, 0.4)

    for k, t in enumerate(l2_c[0]):
        line5_c[k].set_xdata(t[0])
        line5_c[k].set_ydata(t[1])

    l1_sum1.clear()
    l1_sum1_colors.clear()

    calc.phasor_append_2(l1_sum1, l1_sum1_colors, vec_a[frame],
      (vec_a[frame] + vec_b[frame]), color_b)

    l1_sum1_arrow = calc.phasor_2(l1_sum1, theta_deg, length_arrow, 0.4)

    for k, t in enumerate(l1_sum1_arrow[0]):
        line5_sum1[k].set_xdata(t[0])
        line5_sum1[k].set_ydata(t[1])

    l1_sum2.clear()
    l1_sum2_colors.clear()

    calc.phasor_append_2(l1_sum2, l1_sum2_colors,
      (vec_a[frame] + vec_b[frame]),
      (vec_a[frame] + vec_b[frame] + vec_c[frame]), color_c)

    l1_sum2_arrow = calc.phasor_2(l1_sum2, theta_deg, length_arrow, 0.4)

    for k, t in enumerate(l1_sum2_arrow[0]):
        line5_sum2[k].set_xdata(t[0])
        line5_sum2[k].set_ydata(t[1])

    # locus

    rx = []
    ry = []

    for i in range(frame+1):
        rx.append(vec2[i].real)
        ry.append(vec2[i].imag)

    line4.set_xdata(rx)
    line4.set_ydata(ry)

    return

anim = animation.FuncAnimation(
    fig=fig,
    func=update,
    frames=(n_div+1),
    interval=200,
    repeat=False)

plt.tight_layout()
plt.close()

HTML(anim.to_jshtml())
Vmin:  1.3015E+02
Vmax:  3.2476E+02
Out[1]:
No description has been provided for this image

This notebook was contributed by Prof. Nakul Narayanan K, Govt. Engineering College, Thrissur. He may be contacted at nakul@gectcr.ac.in.

In [ ]: