Sinusoidal Steady State Voltage on a Transmission Line

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}}.$$

Import packages and switch to correct matplotlib graphics backend for animations


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()


Matplotlib graphics backend in use: TkAgg

Function definitions


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

Set transmission line parameters and plot voltages


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 [ ]:

Sinusoidal Steady State Current on a Transmission Line

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)

Set transmission line parameters and plot CURRENTS


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 [ ]: