Here is a seemingly working example.
Moving the equations definition to before the parameter definition makes the ifelse evaluate OK.
I guess that there are still problems left here…
To go back to your question about how the switches are defined, I guess it would be better to be able to define the state (open/closed) with parameter when the ODAEProblem is defined? Not sure if that would work with the equations being defined as they are now though…
Anyway, code below, laced with quite a few debug printouts in the IdealSwitch
I realise the isequal(isClosed,True) is redundant at start, but it is needed (but failing)
after the @parameter step.
using Revise
using ModelingToolkit
using ModelingToolkitStandardLibrary.Electrical
using ModelingToolkitStandardLibrary.Electrical: OnePort, Ground
using OrdinaryDiffEq
using Plots
using IfElse: ifelse
@parameters t
# No switch... need to define that.
@component function IdealSwitch(; name, isClosed=true)
println("Creating switch, isClosed=$(isClosed)")
println(" Before param assign: $(isClosed) -> t? $(isequal(isClosed,true)) -> f? $(isequal(isClosed, false))")
println("typeof(isClosed): $(typeof(isClosed))")
@named oneport = OnePort()
@unpack v, i = oneport
@variables closed # Dummy to include in eqs
eqs = [ v ~ ifelse(isequal(isClosed, true), 0, v)
i ~ ifelse(isequal(isClosed, true), i, 0)
closed ~ isequal(isClosed, true)
]
println(" eqs: $(eqs)")
ps = @parameters isClosed = isClosed
println("ps: $ps")
# Original placement of eqs definition - ie _after_ params: here isequal always evaluate to false
#eqs = [ v ~ ifelse(isequal(isClosed, true), 0, v)
# i ~ ifelse(isequal(isClosed, true), i, 0)
# closed ~ isequal(isClosed, true)
#]
#println(" eqs: $(eqs)")
println("After param assign: $(isClosed) -> t? $(isequal(isClosed,true)) -> f? $(isequal(isClosed, false))")
println(" typeof(isClosed): $(typeof(isClosed))")
println(" Switch is $(ifelse(isequal(isClosed, true), "CLOSED", "OPEN"))")
extend(ODESystem(eqs, t, [], ps; name = name), oneport)
end
@named s_closed = IdealSwitch(;isClosed=true)
# equations(s_closed)
# @named s_open = IdealSwitch(;isClosed=false)
# equations(s_open)
@component function ConstantVoltage(; name, V = 12.0)
@named oneport = OnePort()
@unpack v = oneport
ps = @parameters V = V
eqs = [
V ~ v
]
extend(ODESystem(eqs, t, [], ps; name = name), oneport)
end
@named vcc = ConstantVoltage()
@named resistor = Resistor(R=2)
@named switch = IdealSwitch(isClosed=true)
@named ground = Ground()
eqs = [
connect(vcc.p, resistor.p)
connect(resistor.n, switch.p)
connect(vcc.n, switch.n, ground.g)]
@named switch_sys = ODESystem(eqs, t;
systems = [vcc, resistor, switch, ground])
sys = structural_simplify(switch_sys)
prob = ODAEProblem(sys, [], (0, 10.0))
sol = solve(prob, Tsit5())
plot(sol, idxs = [resistor.v, resistor.i],
title = "Switch Demonstration",
labels = ["Resistor Voltage" "Resistor Current"])