diff --git a/src/Electrical/Analog/ideal_components.jl b/src/Electrical/Analog/ideal_components.jl index 46ee0358..1e2a38d3 100644 --- a/src/Electrical/Analog/ideal_components.jl +++ b/src/Electrical/Analog/ideal_components.jl @@ -391,3 +391,56 @@ R = R_const + pos * R_ref * (1 + alpha * (port.T - T_ref)) v ~ i * R end end + +""" + Switch(; Gon = 1e5, state_init = false) + +An electrical switch that is controlled by a boolean input. + +The switch is modelled as follows: +- i = G*v +- G = state*G_on +- state: boolean input + +G will therefore be 0 when the input is false [0] and G_on when the input is true [1]. + +# States + + - See [OnePort](@ref) + - `state(t)`: Boolean input + - `G(t)`: Conductance + +# Connectors + + - `p` Positive pin + - `n` Negative pin + - `input` [RealInput](@ref) Input of type Bool. false: switch is open. true: switch is closed. + +# Parameters: + + - `Gon`: [`S`] Conductance when switch is closed. Value should be finite to avoid a singularity. + - `state_init`: Initial guess for the state of the switch. +""" +@mtkmodel Switch begin + @extend v, i = oneport = OnePort() + + @parameters begin + Gon = 1e5, [description = "Conductance when switch is closed"] + state_init = false, [description = "Initial guess for the state of the switch"] + end + + @components begin + input = RealInput() + end + + @variables begin + state(t)::Bool, [guess = state_init] + G(t) + end + + @equations begin + state ~ input.u + G ~ state * Gon + i ~ G * v + end +end diff --git a/src/Electrical/Electrical.jl b/src/Electrical/Electrical.jl index baac5138..2b2d1ac1 100644 --- a/src/Electrical/Electrical.jl +++ b/src/Electrical/Electrical.jl @@ -15,7 +15,7 @@ include("utils.jl") export Capacitor, Ground, Inductor, Resistor, Conductor, Short, IdealOpAmp, EMF, - Diode, VariableResistor + Diode, VariableResistor, Switch include("Analog/ideal_components.jl") export CurrentSensor, PotentialSensor, VoltageSensor, PowerSensor, MultiSensor diff --git a/test/Electrical/analog.jl b/test/Electrical/analog.jl index 1fcc02e4..3c99497e 100644 --- a/test/Electrical/analog.jl +++ b/test/Electrical/analog.jl @@ -707,3 +707,45 @@ end 0.0, atol = 1e-16) end + +@testset "Switch test" begin + V_value = 10.0 + + @mtkmodel SwitchTest begin + @parameters begin + V = V_value + C = 1.0 + R = 1.0 + end + + @components begin + step = Step(start_time = 10.0, height = true, smooth = 1e-5) + switch = Switch() + voltage = Voltage() + resistor = Resistor(R = R) + capacitor = Capacitor(C = C) + ground = Ground() + end + + @equations begin + connect(voltage.p, switch.p) + connect(switch.n, resistor.p) + connect(resistor.n, capacitor.p) + connect(voltage.n, capacitor.n, ground.g) + connect(step.output, switch.input) + voltage.V.u ~ V + end + end + + @mtkbuild sys = SwitchTest() + u0 = [ + sys.capacitor.v => 0.0, + sys.capacitor.i => 0.0 + ] + prob = ODEProblem(sys, u0, (0.0, 25.0)) + sol = solve(prob, Rodas4()) + + @test SciMLBase.successful_retcode(sol) + @test isapprox(sol[sys.capacitor.v][end], V_value, atol = 1e-3) + @test isapprox(sol[sys.capacitor.i][end], 0.0, atol = 1e-3) +end