Greetings,
I am new to Julia community and, in particular, to the use of ModelingToolkit
package. I would like to implement an IdealDiode
component to be replaced by a short circuit when the controlled variable (i.e. integral of the current flowing into the Diode) has reached one of the two thresholds (being either 0 or Vin_th
).
Initially, i had thought of implementing a model for a simple ideal diode and a model of an ideal controlled switch. Such devices would be connected in parallel in the final circuit.
I had faced some difficulties:
- Ideal Diode returns instability (dt < dtmin) probably dued to the rising edge. This is why I have decided to go for a Shockley Diode.
- Ideal Switch works this way: if controlled variable is <= 0 or >=
Vin_th
, the switch is closed, so that the diode is excluded. The switch is otherwise open. I am getting the very same error. I decided to introduce atanh
function in the current equation of such device in order to reduce this behavior.
These workarounds seem not to have worked when simulating, considering the full circuit. In some Threads on Discourse and in the Documentation, Iâve read about Callbacks but I havenât understood how to write them properly and where to insert them in the DSL code and if there exist some macro helping in this process. Should I drop the usage of new macros (i.e. @mtkmodel, @mtkbuild âŠ) for the old format in order to add Callbacks?
Another possibility could be to use conditionals, in order to include/exclude the IdealDiode in the circuit but i donât think this will solve instability, in the end. I write here to ask some suggestion to avoid workarounds and for some help facing these problems directly.
This is the code i used for modeling. Forgive my English, itâs not my first language. Thanks in advance for any feedback.
Used libraries
using ModelingToolkit
using ModelingToolkitStandardLibrary.Blocks
using ModelingToolkitStandardLibrary.Electrical
using OrdinaryDiffEq
using Plots
Diode
@mtkmodel Diode begin
@extend v, i = oneport = OnePort()
@parameters begin
threshold = 0, [description = "Voltage Threshold"]
end
@components begin
input = RealInput()
end
@equations begin
0 ~ ifelse(input.u > 0, v, i)
end
end
ver. 2
exlin(x, max_x) = ifelse(x > max_x,
exp(max_x)*(1 + x - max_x),
exp(x))
@mtkmodel Diode begin
@extend v, i = oneport = OnePort()
@parameters begin
Ids = 1e-6,
[description = "Reverse-bias current"]
max_exp = 15,
[description = "Value after which linearization is applied"]
R = 1e8,
[description = "Diode Resistance"]
Vth = 1e-3,
[description = "Threshold voltage"]
k = 1e3,
[description = "Speed of exponential"]
end
@equations begin
i ~ Ids * (exlin(k * (v - Vth) / Vth, max_exp) - 1) + (v / R)
end
end
Switch:
@mtkmodel Switch begin
@extend v, i = oneport = OnePort()
@parameters begin
V_FRC, [description = "Airway Volume at FRC"]
end
@variables begin
â«i(t) = 0, [description = "Current integral"]
end
@equations begin
0 ~ ifelse(â«i / V_FRC <= 0, v,
ifelse(â«i / V_FRC < 0.9, i, v))
end
end
Switch ver. 2
@mtkmodel Switch begin
@extend v, i = oneport = OnePort()
@parameters begin
V_FRC, [description = "Airway Volume at FRC"]
Rclosed = 1e-12, [description = "Switch Resistance when Closed"]
Ropen = 2.5e5, [description = "Switch Resistance when Open"]
k = 1e3
end
@variables begin
â«i(t) = 0, [description = "Current integral"]
R(t) = 0, [description = "Switch Resistance"]
end
@equations begin
R ~ Rclosed + (Ropen - Rclosed) * (1 / 2) * (tanh(k * (â«i / V_FRC) * (1 - (â«i / V_FRC))))
v ~ R * i
end
end
For performing the simulation Iâve used:
@mtkbuild system = System()
prob = ODEProblem(system, Pair[], (0, 2));
sol = solve(prob, Rodas4());