Stray Voltage Calculator

Y.addline = function(Y, Zseries, from, to) {
    n = NROW(Zseries)
    fromNodes = from + 1:n - 1
    toNodes = to + 1:n - 1
    Yseries = solve(Zseries)
    Y[fromNodes,fromNodes] = Y[fromNodes,fromNodes] + Yseries # diagonal
    Y[toNodes,toNodes]     = Y[toNodes,  toNodes]   + Yseries
    Y[fromNodes,toNodes]   = Y[fromNodes,toNodes]   - Yseries # off diagonal
    Y[toNodes,fromNodes]   = Y[toNodes,  fromNodes] - Yseries
    Y
}

Y.addshunt = function(Y, Zshunt, busnum) {
    n = NROW(Zshunt)
    fromNodes = busnum:(busnum+n-1)
    Yshunt = solve(Zshunt)
    Y[fromNodes,fromNodes] = Y[fromNodes,fromNodes] + Yshunt # diagonal
    Y
}
load(RpadBaseFile("AA_conductors.RData"))
HTMLon()
cat("Neutral conductor: ")
HTMLselect("neutralConductor1", a$label, default=16)
ohm Substation ground resistance
Grounds per 1000 feet
ohm Average ground
ohm-m Earth resistivity
mile Line length
Harmonic (multiples of the fundamental)
A Unbalance current
Load lumped at the circuit end
Evenly distributed load
Load on another circuit
numberOfSections = 50
subBus = 1
totalLength = totalLengthMi * 5.28 # ohms/kfeet
sectionLength = totalLength/numberOfSections # kfeet
Zgrnd = averageGround/(groundsPerKFeet * totalLength) *
        numberOfSections # ohms (average ground per section)
d.ab = 6 # feet (distance between the phase and neutral)

aa.n1 = a[a$label==neutralConductor1,]

r = 0.0001 # ohms per 1000 feet
gmr = 0.04 # feet
r.n = aa.n1$rac/5.28 # ohms per 1000 feet
gmr.n = aa.n1$gmr

Zcond = array(0i,c(2,2)) # ohms per 1000 feet
Zcond[1,1] = r + .01807*harmonic +
             harmonic*1i*.0529*log10(278.9*sqrt(rho/harmonic)/gmr)
Zcond[2,2] = r.n + .01807*harmonic +
             harmonic*1i*.0529*log10(278.9*sqrt(rho/harmonic)/gmr.n)
Zcond[1,2] = Zcond[2,1] = .01807*harmonic +
             harmonic*1i*.0529*log10(278.9*sqrt(rho/harmonic)/d.ab)

Zcond = Zcond * sectionLength # actual ohms
numberOfConductors = NROW(Zcond)

# preallocate the Ybus
n = (numberOfSections + 1)*numberOfConductors
Y = array(0i,c(n,n))

# make the Ybus from the impedances
for (i in seq(from=1,to=n-numberOfConductors,by=numberOfConductors))
    Y = Y.addline(Y,Zcond,from=i,to=i+numberOfConductors)

# add the shunt grounds
for (i in seq(from=2*numberOfConductors,to=n-1,by=numberOfConductors))
     Y = Y.addshunt(Y,Zgrnd,busnum=i) # the last one is the grounded neutral

# add the sub ground
Y = Y.addshunt(Y,Zsub,busnum=numberOfConductors*subBus) 

# ground the phase wire at the sub
Y = Y.addline(Y, .00001, from = 1+numberOfConductors*(subBus-1),
              to = numberOfConductors*subBus)

# make I
Isrc = array(0i,n)
# inject evenly distributed loads
if (loadType == "evenlyDistributed") {
    from = seq(from=1+numberOfConductors*subBus,to=n,by=numberOfConductors)
    # phase A
    to = seq(from=numberOfConductors*(1+subBus),to=n,by=numberOfConductors)
    # neutral
    Isrc[from] = UnbalanceI/(numberOfSections-subBus) # amperes
    Isrc[to] = -Isrc[from]
} else if (loadType == "lumpedAtEnd") {
    # inject isolated load at the end
    to = n - numberOfConductors + 1
    from = n
    Isrc[from] = Isrc[from] + UnbalanceI # amperes
    Isrc[to] = Isrc[to] - Isrc[from]
} else {
    Isrc[numberOfConductors*subBus] = Isrc[numberOfConductors*subBus] + 
                                      UnbalanceI # amperes
}
# Find the voltages:
V = solve(Y,Isrc)

Vn = V[seq(from=numberOfConductors,to=n,by=numberOfConductors)]

x = 0:numberOfSections * sectionLength / 5.28

idx.p = seq(from=1,to=n,by=numberOfConductors)
idx.n = seq(from=numberOfConductors,to=n,by=numberOfConductors)
V = rbind(V[idx.p] - V[idx.p + numberOfConductors],
          V[idx.n] - V[idx.n + numberOfConductors])
Ycond = solve(Zcond)
I = Ycond %*% V
Ip = I[1,]
In = I[numberOfConductors,]
Ig = Ip + In
cat("Substation Vn =",abs(Vn[subBus]),"V\n")

newgraph(width=6,height=3)
par(mfcol = c(1,2), mar = c(3, 3, 2, 1))

plot(x, abs(Vn),
     type = "l", ylim = c(0,2*abs(Vn[subBus])), 
     xlab = "", ylab = "")
mtext("Neutral-to-earth voltage, V",side=3,line=.7)
mtext("Distance from the sub, miles",side=1,line=-1,outer=TRUE)

plot(x, abs(Ig), 
     type = "l", col = "blue", ylim = c(0,UnbalanceI),
     xlab = "", ylab = "")
mtext("Currents, A",side=3,line=.7)
lines(x,abs(In),col="red")
lines(x,abs(Ip))
legend(.5, 5, c("phase","neutral","ground"), 
       col = c("black","red","blue"), 
       lty = 1, bty = "n", cex = .7)
HTMLon()
showgraph()



by Tom Short, tshort@epri.com, Copyright 2005. EPRI Solutions, Inc., license: GNU GPL v2 or greater