From 5ea5d543676f45ffb667271fecb5b727ce810858 Mon Sep 17 00:00:00 2001 From: matthew-kapp Date: Mon, 28 Apr 2025 10:14:10 +0200 Subject: [PATCH 1/7] Switch added --- src/Electrical/Analog/ideal_components.jl | 52 +++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/Electrical/Analog/ideal_components.jl b/src/Electrical/Analog/ideal_components.jl index 46ee0358..95c80b93 100644 --- a/src/Electrical/Analog/ideal_components.jl +++ b/src/Electrical/Analog/ideal_components.jl @@ -391,3 +391,55 @@ R = R_const + pos * R_ref * (1 + alpha * (port.T - T_ref)) v ~ i * R end end + +""" + Switch(; state_init = false, Gon = 1e5, τ = 1e-3) + +An electrical switch that is controlled by a boolean input. + +# States + + - See [OnePort](@ref) + - `state(t)`: Boolean input + - `state_filtered(t)`: Filtered delay of state(t) + - `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: + + - `state_init`: Initial switch state of type Bool. false: switch is open. true: switch is closed. + - `Gon`: [`S`] Conductance when switch is closed. + - `τ`: Parameter for filtered delay. +""" + +@mtkmodel Switch begin + @extend v, i = oneport = OnePort() + + @parameters begin + state_init = false + Gon = 1e5 + τ = 1e-3 + end + + @components begin + input = RealInput() + end + + @variables begin + state(t)::Bool + state_filtered(t) = Real(state_init) + G(t) + end + + @equations begin + state ~ input.u + D(state_filtered) ~ (state - state_filtered)/τ + G ~ state_filtered*Gon + i ~ G*v + end +end From 9b8c36befa88a05186bcf41b982c38af2addea8d Mon Sep 17 00:00:00 2001 From: matthew-kapp Date: Mon, 28 Apr 2025 12:15:10 +0200 Subject: [PATCH 2/7] Tests added --- src/Electrical/Analog/ideal_components.jl | 7 ++-- src/Electrical/Electrical.jl | 2 +- test/Electrical/analog.jl | 40 ++++++++++++++++++++++- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/Electrical/Analog/ideal_components.jl b/src/Electrical/Analog/ideal_components.jl index 95c80b93..623ba79a 100644 --- a/src/Electrical/Analog/ideal_components.jl +++ b/src/Electrical/Analog/ideal_components.jl @@ -421,9 +421,10 @@ An electrical switch that is controlled by a boolean input. @extend v, i = oneport = OnePort() @parameters begin - state_init = false - Gon = 1e5 - τ = 1e-3 + state_init = false, + [description = "Initial switch state of type Bool. false: switch is open. true: switch is closed."] + Gon = 1e5, [description = "Conductance when switch is closed"] + τ = 1e-3, [description = "Parameter for filtered delay"] end @components begin 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..bf68c335 100644 --- a/test/Electrical/analog.jl +++ b/test/Electrical/analog.jl @@ -413,7 +413,7 @@ end # Tests @test all(diode_current .>= -1e-3) - @test capacitor_voltage[end].≈8.26 rtol=3e-1 + @test capacitor_voltage[end] .≈ 8.26 rtol=3e-1 # For visual inspection # plt = plot(sol; idxs = [diode.i, resistor.i, capacitor.v], @@ -707,3 +707,41 @@ 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 = false) + switch = Switch() + voltage = Voltage() + resistor = Resistor(R = R) + capacitor = Capacitor(C = C, v = 0.0) + 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() + prob = ODEProblem(sys, [], (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 From ff6817b3f2d2aa17e4fe8486e94d9135410ccc6f Mon Sep 17 00:00:00 2001 From: matthew-kapp Date: Mon, 28 Apr 2025 12:46:53 +0200 Subject: [PATCH 3/7] Formatting --- src/Electrical/Analog/ideal_components.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Electrical/Analog/ideal_components.jl b/src/Electrical/Analog/ideal_components.jl index 623ba79a..84d5bf94 100644 --- a/src/Electrical/Analog/ideal_components.jl +++ b/src/Electrical/Analog/ideal_components.jl @@ -416,7 +416,6 @@ An electrical switch that is controlled by a boolean input. - `Gon`: [`S`] Conductance when switch is closed. - `τ`: Parameter for filtered delay. """ - @mtkmodel Switch begin @extend v, i = oneport = OnePort() From 8aec8160411ffb29de307991376de2a2fbff6604 Mon Sep 17 00:00:00 2001 From: matthew-kapp Date: Tue, 29 Apr 2025 20:41:49 +0200 Subject: [PATCH 4/7] Delay removed from switch and moved to step (in the test) --- src/Electrical/Analog/ideal_components.jl | 21 ++++++++++----------- test/Electrical/analog.jl | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Electrical/Analog/ideal_components.jl b/src/Electrical/Analog/ideal_components.jl index 84d5bf94..1c78bd9f 100644 --- a/src/Electrical/Analog/ideal_components.jl +++ b/src/Electrical/Analog/ideal_components.jl @@ -393,15 +393,21 @@ R = R_const + pos * R_ref * (1 + alpha * (port.T - T_ref)) end """ - Switch(; state_init = false, Gon = 1e5, τ = 1e-3) + 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 - - `state_filtered(t)`: Filtered delay of state(t) - `G(t)`: Conductance # Connectors @@ -412,18 +418,13 @@ An electrical switch that is controlled by a boolean input. # Parameters: - - `state_init`: Initial switch state of type Bool. false: switch is open. true: switch is closed. - - `Gon`: [`S`] Conductance when switch is closed. - - `τ`: Parameter for filtered delay. + - `Gon`: [`S`] Conductance when switch is closed. Value should be finite to avoid a singularity. """ @mtkmodel Switch begin @extend v, i = oneport = OnePort() @parameters begin - state_init = false, - [description = "Initial switch state of type Bool. false: switch is open. true: switch is closed."] Gon = 1e5, [description = "Conductance when switch is closed"] - τ = 1e-3, [description = "Parameter for filtered delay"] end @components begin @@ -432,14 +433,12 @@ An electrical switch that is controlled by a boolean input. @variables begin state(t)::Bool - state_filtered(t) = Real(state_init) G(t) end @equations begin state ~ input.u - D(state_filtered) ~ (state - state_filtered)/τ - G ~ state_filtered*Gon + G ~ state*Gon i ~ G*v end end diff --git a/test/Electrical/analog.jl b/test/Electrical/analog.jl index bf68c335..0fbd4fd6 100644 --- a/test/Electrical/analog.jl +++ b/test/Electrical/analog.jl @@ -719,7 +719,7 @@ end end @components begin - step = Step(start_time = 10.0, height = true, smooth = false) + step = Step(start_time = 10.0, height = true, smooth = 1e-5) switch = Switch() voltage = Voltage() resistor = Resistor(R = R) From 4c62fc16032924b45315b24a24c68cefcb26229d Mon Sep 17 00:00:00 2001 From: matthew-kapp Date: Wed, 30 Apr 2025 11:34:48 +0200 Subject: [PATCH 5/7] Switch initial state guess added --- src/Electrical/Analog/ideal_components.jl | 4 +++- test/Electrical/analog.jl | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Electrical/Analog/ideal_components.jl b/src/Electrical/Analog/ideal_components.jl index 1c78bd9f..ccd5b684 100644 --- a/src/Electrical/Analog/ideal_components.jl +++ b/src/Electrical/Analog/ideal_components.jl @@ -419,12 +419,14 @@ G will therefore be 0 when the input is false [0] and G_on when the input is tru # 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 @@ -432,7 +434,7 @@ G will therefore be 0 when the input is false [0] and G_on when the input is tru end @variables begin - state(t)::Bool + state(t)::Bool, [guess = state_init] G(t) end diff --git a/test/Electrical/analog.jl b/test/Electrical/analog.jl index 0fbd4fd6..86ce82d2 100644 --- a/test/Electrical/analog.jl +++ b/test/Electrical/analog.jl @@ -723,7 +723,7 @@ end switch = Switch() voltage = Voltage() resistor = Resistor(R = R) - capacitor = Capacitor(C = C, v = 0.0) + capacitor = Capacitor(C = C) ground = Ground() end @@ -738,7 +738,7 @@ end end @mtkbuild sys = SwitchTest() - prob = ODEProblem(sys, [], (0.0, 25.0)) + prob = ODEProblem(sys, [sys.capacitor.v => 0.0], (0.0, 25.0)) sol = solve(prob, Rodas4()) @test SciMLBase.successful_retcode(sol) From dff4f6567e1d0d0e646e348b87cfde7132d617a7 Mon Sep 17 00:00:00 2001 From: matthew-kapp Date: Thu, 1 May 2025 12:20:15 +0200 Subject: [PATCH 6/7] Test done with latest MTK version --- test/Electrical/analog.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/Electrical/analog.jl b/test/Electrical/analog.jl index 86ce82d2..ae62ba21 100644 --- a/test/Electrical/analog.jl +++ b/test/Electrical/analog.jl @@ -738,7 +738,11 @@ end end @mtkbuild sys = SwitchTest() - prob = ODEProblem(sys, [sys.capacitor.v => 0.0], (0.0, 25.0)) + 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) From 047a926d7ac3716621d38e5c821dbdffb8c726f8 Mon Sep 17 00:00:00 2001 From: matthew-kapp Date: Thu, 1 May 2025 13:01:54 +0200 Subject: [PATCH 7/7] JuliaFormatter v1 instead of v2 --- src/Electrical/Analog/ideal_components.jl | 4 ++-- test/Electrical/analog.jl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Electrical/Analog/ideal_components.jl b/src/Electrical/Analog/ideal_components.jl index ccd5b684..1e2a38d3 100644 --- a/src/Electrical/Analog/ideal_components.jl +++ b/src/Electrical/Analog/ideal_components.jl @@ -440,7 +440,7 @@ G will therefore be 0 when the input is false [0] and G_on when the input is tru @equations begin state ~ input.u - G ~ state*Gon - i ~ G*v + G ~ state * Gon + i ~ G * v end end diff --git a/test/Electrical/analog.jl b/test/Electrical/analog.jl index ae62ba21..3c99497e 100644 --- a/test/Electrical/analog.jl +++ b/test/Electrical/analog.jl @@ -413,7 +413,7 @@ end # Tests @test all(diode_current .>= -1e-3) - @test capacitor_voltage[end] .≈ 8.26 rtol=3e-1 + @test capacitor_voltage[end].≈8.26 rtol=3e-1 # For visual inspection # plt = plot(sol; idxs = [diode.i, resistor.i, capacitor.v],