Hi everyone,
I am new to the Julia community and I’m interested in the applications of the ModelingToolkit
package.
In particular, I’m trying to simulate a switching circuit using an External Control Signal and a Controllable Switch. The Switch is designed as a non-ideal resistor where the resistance value varies from high to low in response to the Control Signal. I tried a simple test circuit as below with two approaches :
+V
|
┌┴┐ Control (Square Wave)
│S│<─────●
└┬┘
|
[R] ← Load resistor R
|
GND
- Using a sinusoidal wave as Control Signal. In this case the model works. Here’s the plot of the Voltage on the load and the resistance of the Cotrollable “Switch”:
- Using a square wave as Control Signal. In this case the model has convergence problems. It don’t show any “error” but two warnings:
┌ Warning: Rosenbrock methods on equations without differential states do not bound the error on interpolations.
and
┌ Warning: At t=0.0, dt was forced below floating point epsilon 5.0e-324, and step error estimate = NaN. Aborting. There is either an error in your model specification or the true solution is unstable (or the true solution can not be represented in the precision of Float64).
and the resulting plot is empty :
So I’m having some questions as I’m stuck in the implementation
- Which solver and settings (tolerances, max step size) work best for fast switching circuits in ModelingToolkit.jl?
- Are there any references or examples of switching models using MTK?
- Can ModelingToolkit.jl reliably handle non-linear, hybrid systems like this?
Here’s the code of the Circuit model:
@mtkmodel R_Test begin
@parameters begin
RLoad_param = 10, [description = "Output Load (Ohm)"]
Vin_param = 200, [description = "Vin Souce (Vdc)"]
f = 100, [description = "Switch input Frequency (Hz)"]
end
@components begin
switch_input = squareWave(frequency = f, amplitude = 1, offset = 0, dutyCycle = 0.3)
#switch_input = Sine(frequency = f, amplitude = 0.99, offset = 1.0)
voltage_input = Constant(k = Vin_param)
switch = IdealSwitch(Ron = 1e-3, Roff = 1)
source = Voltage()
RLoad = Resistor(R = RLoad_param)
ground = Ground()
end
@equations begin
connect(voltage_input.output, source.V)
connect(switch_input.output, switch.conduction)
connect(source.p, switch.p)
connect(switch.n,RLoad.p)
connect(source.n, RLoad.n, ground.g)
end
end
The Switch is defined as
@mtkmodel IdealSwitch begin
@extend v, i = oneport = OnePort()
@parameters begin
Ron = 1e-3, [description = "On resistance magnitud"]
Roff = 1e6, [description = "Off resistance magnitud"]
end
@components begin
conduction = RealInput()
end
@variables begin
q(t), [description = "Control Signal "]
R(t), [description = "Resistance "]
end
@equations begin
q ~ conduction.u
R ~ Ron + q * Roff
v ~ i * R
end
end
The square wave is defined as
@component function squareWave(;name, frequency, amplitude = 1, offset = 0, dutyCycle = 0.5)
@named output = RealOutput()
pars = @parameters amplitude=amplitude frequency=frequency dutyCycle=dutyCycle
equation = amplitude * mod1(t, 1/frequency) < dutyCycle/frequency
eqs = output.u ~ equation
compose(System(eqs, t, [], pars; name = name), [output])
end
and the solver configuration is
@mtkcompile sys = R_Test()
prob = ODEProblem(sys, Pair[], (0.0, 100e-3); guesses = [sys.switch.i => 5.0])
sol = solve(prob, Rodas5();
reltol=1e-8,
abstol=1e-10,
dt=1e-7,
dtmax=1e-5,
saveat=1e-5)
Any pointers or references to prior work are greatly appreciated!
Thanks!