The voltage on a lossless transmission line is given by
\begin{aligned} v(z,t) & = v_0 cos(\omega t - \beta z) + \left|{\Gamma_L}\right|v_o cos(\omega t + \beta z + \phi_L)\\ & = \Re(\tilde{V}(z) e^{j\omega t} )\end{aligned}where $\Re()$ is an operator that takes the real part of the enclosed expression, $\omega = 2\pi f$ ($f$ is the frequency of the sinusoidal voltage), $\beta$ is the wavenumber (propagation constant), and $\Gamma_L$ is the load reflection coefficient, which in general is complex such that $\Gamma_L = \left|\Gamma_L\right|exp(j \phi_L)$. The phase velocity, $u$, is $\omega / \beta$. Since $u = \lambda f$, $\beta = 2 \pi / \lambda$, where $\lambda$ is the wavelength of the sinusoidal voltage.
The voltage phasor is
$$ \tilde{V}(z) = V^+_0 e^{-j\beta z}[1 + \Gamma(z)]$$where we have used the generalized reflection coefficient
$$ \Gamma(z) = \Gamma_L e^{j2\beta z}. $$Note that $V^+_0$ can in general be complex such that $V^+_0 = \left|V^+_0\right|e^{j\theta_V}$. The magnitude of the voltage phasor, $\tilde{V}(z)$, is the envelope of the time-varying real voltage and is called the standing wave. It can be calculated as
$$ \left|\tilde{V}(z)\right| = \left|V^+_0\right|\sqrt{1 + 2\left|\Gamma_L\right|cos(2\beta z + \theta_L) + \left|\Gamma_L\right|^2}.$$The voltage standing wave ratio is given by
$$VSWR = \frac{\left|\tilde{V}(z)\right|_{max}}{\left|\tilde{V}(z)\right|_{min}}.$$
In [1]:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
# Switch to a backend that supports FuncAnimation
plt.switch_backend('tkagg')
print 'Matplotlib graphics backend in use:',plt.get_backend()
In [2]:
def vplus(v0,f,t,beta,z):
return v0*np.cos(2*np.pi*f*t - beta*z)
def vminus(v0,f,t,beta,z,gammaLmagnitude,gammaLphase_rad):
return gammaLmagnitude*v0*np.cos(2*np.pi*f*t + beta*z + gammaLphase_rad)
def vtotal(v0,f,t,beta,z,gammaLmagnitude,gammaLphase_rad):
return vplus(v0,f,t,beta,z) + vminus(v0,f,t,beta,z,gammaLmagnitude,gammaLphase_rad)
def phasormagnitude(v0,f,beta,z,gammaLmagnitude,gammaLphase_rad):
return v0*np.sqrt(1 + 2*gammaLmagnitude*np.cos(2*beta*z + gammaLphase_rad) + gammaLmagnitude**2)
# Return string containing text version of complex number
# Handle special cases: angle = 0, pi, -pi, pi/2, and -pi/2
def complextostring(complexnum):
tolerance = 1.0e-3
angle = np.angle(complexnum)
if angle < tolerance and angle > -tolerance: # angle is essentially 0.0
tempstr = "%.2f" % abs(complexnum)
elif angle > np.pi - tolerance or angle < -np.pi + tolerance: # angle close to +pi or -pi?
tempstr = "-%.2f" % abs(complexnum)
elif angle < np.pi/2 + tolerance and angle > np.pi/2 - tolerance: # angle close to np.pi/2?
tempstr = "j%.2f" % abs(complexnum)
elif angle < -np.pi/2 + tolerance and angle > -np.pi/2 - tolerance: # angle close to -np.pi/2?
tempstr = "-j%.2f" % abs(complexnum)
elif angle < 0.0: # put negative sign in front of j, otherwise it will be between j and the number
tempstr = "%.2f exp(-j%.2f)" % (abs(complexnum), -angle)
else:
tempstr = "%.2f exp(j%.2f)" % (abs(complexnum), angle)
return tempstr
In [ ]:
#-------------------------------------------------------------------------
#
# Set these parameters to model desired transmission line situation
#
#-------------------------------------------------------------------------
# Specify sinusoidal voltage parameters & reflection coefficient
wavelength_m = 2.0 # wavelength in meters
v0 = 1.0 # voltage amplitude in volts
reflcoeffmagn = 1.0 # magnitude of the reflection coefficient
reflcoeffphase_degrees = 0.0 # phase of the reflection coefficient IN DEGREES! (changed 1/21/15)
velocity_mps = 2.0e8 # voltage phase velocity along transmission line
#-------------------------------------------------------------------------
#
# Don't change anything below this point
#
#-------------------------------------------------------------------------
# Set up plot parameters for transmission line
zmin = -10
zmax = 0
numzpnts = 1000
# Set up animation parameters
numframes = 20
framespersec = 15
frameperiod_msec = int(1000.0*float(1)/framespersec)
#print 'Frame period = %d ms' % frameperiod_msec
# Calculate derived parameters
beta = 2*np.pi/wavelength_m
frequency_Hz = velocity_mps / wavelength_m
period_s = 1.0/frequency_Hz
reflcoeffphase_rad = np.radians(reflcoeffphase_degrees)
# Set up sampling grid along transmission line
z = np.linspace(zmin, zmax, numzpnts)
# Calculate standing wave
standingwave = phasormagnitude(v0,frequency_Hz,beta,z,reflcoeffmagn,reflcoeffphase_rad)
standingwavemax = max(standingwave)
standingwavemin = min(standingwave)
if standingwavemin > 1.0e-2:
vswr_text = standingwavemax/standingwavemin
vswr_text = '\nVSWR = %.2f' % vswr_text
else:
vswr_text = '\nVSWR = $\infty$'
# Set up text for plot label
reflcoeffcmplx = reflcoeffmagn * complex(np.cos(reflcoeffphase_rad),np.sin(reflcoeffphase_rad))
labeltext = '$\Gamma_L$ = ' + complextostring(reflcoeffcmplx)
labeltext += '\n$\lambda$ = %.2f m' % wavelength_m
labeltext += '\nf = %.2e Hz' % frequency_Hz
labeltext += '\nu = %.2e m/s' % velocity_mps
labeltext += '\n$V_0$ = %.2f V' % v0
labeltext += vswr_text
# Set up figure, axis, and plot elements, including those to animate (i.e., line1, line2, line3)
fig2 = plt.figure()
ax2 = plt.axes(xlim=(zmin, zmax), ylim=(-2, 4))
line1, = ax2.plot([], [], 'b--', label='$v^+$')
line2, = ax2.plot([], [], 'r--', label='$v^-$')
line3, = ax2.plot([], [], 'g', label='$v_{total} = v^+ + v^-$')
line4, = ax2.plot(z,standingwave, color='black', label='$\mathrm{Standing} \/ \mathrm{wave}$')
ax2.axhline(y=0.0,ls='dotted',color='k')
ax2.legend(loc='upper left')
ax2.set_xlabel('z (m)')
ax2.set_ylabel('Voltage (V)')
ax2.set_title('Transmission Line Voltage - Sinusoidal Steady State')
# initialization function (background of each frame)
def init():
ax2.text(0.55,0.75,labeltext, transform = ax2.transAxes)
line1.set_data([], [])
line2.set_data([], [])
line3.set_data([], [])
#ax2.legend.set_zorder(20)
return line1, line2, line3,
# animation function - called sequentially
def animate_vplusandminus(i):
t = period_s * float(i)/numframes
vp = vplus(v0,frequency_Hz,t,beta,z)
line1.set_data(z, vp)
vm = vminus(v0,frequency_Hz,t,beta,z,reflcoeffmagn,reflcoeffphase_rad)
line2.set_data(z, vm)
vtot = vp + vm
line3.set_data(z, vtot)
return line1, line2, line3,
# call the animator. blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig2, animate_vplusandminus, init_func=init,
frames=numframes, interval=frameperiod_msec, blit=True)
plt.show()
In [ ]:
In [ ]:
In [ ]:
In [ ]:
The current phasor is
$$ \tilde{I}(z) = \frac{V^+_0}{Z_0} e^{-j\beta z}[1 - \Gamma(z)]$$The current standing wave is the magnitude of the current phasor:
$$ \left|\tilde{I}(z)\right| = \frac{\left|V^+_0\right|}{Z_0}\sqrt{1 - 2\left|\Gamma_L\right|cos(2\beta z + \theta_L) + \left|\Gamma_L\right|^2}.$$
In [6]:
# Define function to calculate the magnitude of the current phasor
def currentphasormagnitude(v0,f,beta,z,gammaLmagnitude,gammaLphase_rad,z0):
return (v0/z0)*np.sqrt(1 - 2*gammaLmagnitude*np.cos(2*beta*z + gammaLphase_rad) + gammaLmagnitude**2)
In [5]:
#-------------------------------------------------------------------------
#
# Set these parameters to model desired transmission line situation
#
#-------------------------------------------------------------------------
# Specify sinusoidal voltage parameters & reflection coefficient
wavelength_m = 2.0 # wavelength in meters
v0 = 1.0 # voltage amplitude in volts
reflcoeffmagn = 0.5 # magnitude of the reflection coefficient
reflcoeffphase_degrees = 0.0 # phase of the reflection coefficient IN DEGREES! (changed 1/21/15)
velocity_mps = 2.0e8 # voltage phase velocity along transmission line
z0 = 50.0 # t-line characteristic impedance
#-------------------------------------------------------------------------
#
# Don't change anything below this point
#
#-------------------------------------------------------------------------
# Set up plot parameters for transmission line
zmin = -10
zmax = 0
numzpnts = 1000
# Set up animation parameters
numframes = 20
framespersec = 15
frameperiod_msec = int(1000.0*float(1)/framespersec)
#print 'Frame period = %d ms' % frameperiod_msec
# Calculate derived parameters
beta = 2*np.pi/wavelength_m
frequency_Hz = velocity_mps / wavelength_m
period_s = 1.0/frequency_Hz
reflcoeffphase_rad = np.radians(reflcoeffphase_degrees)
# Set up sampling grid along transmission line
z = np.linspace(zmin, zmax, numzpnts)
# Calculate standing wave
standingwave = currentphasormagnitude(v0,frequency_Hz,beta,z,reflcoeffmagn,reflcoeffphase_rad,z0)
standingwavemax = max(standingwave)
standingwavemin = min(standingwave)
if standingwavemin > 1.0e-2:
vswr_text = standingwavemax/standingwavemin
vswr_text = '\nVSWR = %.2f' % vswr_text
else:
vswr_text = '\nVSWR = $\infty$'
# Set up text for plot label
reflcoeffcmplx = reflcoeffmagn * complex(np.cos(reflcoeffphase_rad),np.sin(reflcoeffphase_rad))
labeltext = '$\Gamma_L$ = ' + complextostring(reflcoeffcmplx)
labeltext += '\n$\lambda$ = %.2f m' % wavelength_m
labeltext += '\nf = %.2e Hz' % frequency_Hz
labeltext += '\nu = %.2e m/s' % velocity_mps
labeltext += '\n$V_0$ = %.2f V' % v0
labeltext += '\n$Z_0$ = %.2f $\Omega$' % z0
labeltext += vswr_text
# Set up figure, axis, and plot elements, including those to animate (i.e., line1, line2, line3)
fig2 = plt.figure()
ax2 = plt.axes(xlim=(zmin, zmax), ylim=(-2.0/z0, 4.0/z0))
line1, = ax2.plot([], [], 'b--', label='$i^+$')
line2, = ax2.plot([], [], 'r--', label='$i^-$')
line3, = ax2.plot([], [], 'g', label='$i_{total} = i^+ + i^-$')
line4, = ax2.plot(z,standingwave, color='black', label='$\mathrm{Current} \/ \mathrm{standing} \/ \mathrm{wave}$')
ax2.axhline(y=0.0,ls='dotted',color='k')
ax2.legend(loc='upper left')
ax2.set_xlabel('z (m)')
ax2.set_ylabel('Current (A)')
ax2.set_title('Transmission Line Current - Sinusoidal Steady State')
# initialization function (background of each frame)
def init():
ax2.text(0.55,0.7,labeltext, transform = ax2.transAxes)
line1.set_data([], [])
line2.set_data([], [])
line3.set_data([], [])
#ax2.legend.set_zorder(20)
return line1, line2, line3,
# animation function - called sequentially
def animate_vplusandminus(i):
t = period_s * float(i)/numframes
ip = vplus(v0,frequency_Hz,t,beta,z) / z0
line1.set_data(z, ip)
im = -vminus(v0,frequency_Hz,t,beta,z,reflcoeffmagn,reflcoeffphase_rad) / z0
line2.set_data(z, im)
itot = ip + im
line3.set_data(z, itot)
return line1, line2, line3,
# call the animator. blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig2, animate_vplusandminus, init_func=init,
frames=numframes, interval=frameperiod_msec, blit=True)
plt.show()
In [ ]: