I have a script with a while loop. When I run the code using “Shift+Enter”, “Alt+Enter” or even “Execute Code” everything is fine. But when I use “Execute file”, two errors I get (1) the global variables are not recognised inside the while loop, (2) it cannot exit the while loop.
Thanks for the rely. Below is the code, either loop can be safely commented out. In the first loop it does not recognise kWsum, and in the second loop, it just gets stuck.
using Pkg
Pkg.activate(pwd())
Pkg.add("OpenDSSDirect")
using OpenDSSDirect
dss("""
Clear
New Circuit.Kersting_nr_LineGeometry_Balanced phases=3 basekv=12.47 bus1=B1 MVASC1=1e8 MVASC3=1e8
New Wiredata.Hawk DIAM=0.858 GMR=0.029 RAC=0.216
~ NormAmps=530 // this param is not defined
~ Runits=mi radunits=in gmrunits=ft
New Linegeometry.OverHead1 nconds=4 nphases=3
~ cond=1 Wire=Hawk x=-48 h=348 units=in
~ cond=2 Wire=Hawk x=-21 h=348 units=in
~ cond=3 Wire=Hawk x=40 h=348 units=in
~ cond=4 Wire=Hawk x=0 h=286 units=in // h is not defined
New Line.Line1 bus1=B1.1.2.3.0 bus2=B2.1.2.3.4
~ Geometry=OverHead1
~ Length=1.893939 units=mi
~ EarthModel=Carson
New Reactor.grounding phases=1 bus1=B1.4 bus2=B1.0 R=100 X=0.01
New Load.LoadP1 phases=1 bus1=B2.1.4 kv=12.47 model=1 conn=wye kVA=3000 pf=0.9 vminpu=0.1 vmaxpu=2
New Load.LoadP2 phases=1 bus1=B2.2.4 kv=12.47 model=1 conn=wye kVA=3000 pf=0.9 vminpu=0.1 vmaxpu=2
New Load.LoadP3 phases=1 bus1=B2.3.4 kv=12.47 model=1 conn=wye kVA=3000 pf=0.9 vminpu=0.1 vmaxpu=2
Set Toler=0.00000001
Solve
""")
solution = Dict{String,Any}()
# load power
solution["load"] = Dict{String,Any}()
loadnumber = Loads.First()
kWsum = 0.0
kvarsum = 0.0
while loadnumber > 0
load_name = Loads.Name()
solution["load"][load_name] = Dict{String,Any}()
solution["load"][load_name]["pd"] = Loads.kW()
solution["load"][load_name]["qd"] = Loads.kvar()
kWsum += Loads.kW()
kvarsum += Loads.kvar()
loadnumber = Loads.Next()
end
# line currents
solution["line"] = Dict{String,Any}()
linenumber = PDElements.First()
while linenumber > 0
name = PDElements.Name()
Circuit.SetActiveElement(name)
if split(name,".")[1] == "Line"
line_name = split(name,".")[2]
@show line_name
solution["line"][line_name] = Dict{String,Any}()
solution["line"][line_name]["bus_fr"] = Lines.Bus1()
solution["line"][line_name]["bus_to"] = Lines.Bus2()
solution["line"][line_name]["nphases"] = Lines.Phases()
solution["line"][line_name]["linecode"] = Lines.LineCode()
solution["line"][line_name]["zmatrix"] = Lines.ZMatrix()
solution["line"][line_name]["length"] = Lines.Length()
solution["line"][line_name]["unit"] = Lines.Units()
solution["line"][line_name]["c"] = PDElements.AllCurrentsAllCurrents()[1:Lines.Phases()]
end
linenumber = PDElements.Next()
end
This is expected, you defined kWsum in a global scope, but the for loop will create its own local variable kWsum by default unless you make it explicitly global. This may look like a weird design decision, but it’s intended to reduce the risk of affecting unintentionally a distant global variable.
You are doing this.
var = 1.0 # global
for i in 1:10
var += 1 # uninitialized new local
end
println(var)
# ERROR: LoadError: UndefVarError: var not defined
# Stacktrace:
# [...]
To solve this the general advice, I think, is to grab all your code in a function (which introduce a local scope). This also have many other advantages (performance included). But if you wanna work in the global scope anyway you can do
var = 1.0 # global
for i in 1:10
global var += 1 # reusing global
end
println(var)
# 11.0
But to understand better I recommend you to read the manual and do a couple of examples.