Skip to content

Commit 7017acd

Browse files
langestefanmatthew-kapp
authored andcommitted
Simplify temperature dependency for analog components
1 parent b6801d4 commit 7017acd

File tree

4 files changed

+113
-106
lines changed

4 files changed

+113
-106
lines changed

src/Electrical/Analog/ideal_components.jl

Lines changed: 74 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,57 @@ node.
1818
end
1919

2020
"""
21-
Resistor(; name, R)
21+
Resistor(; name, R_ref = 1.0, T_ref = 300.15, alpha = 0, T_dep = false)
2222
23-
Creates an ideal Resistor following Ohm's Law.
23+
Generic resistor with optional temperature dependency.
2424
2525
# States:
2626
27-
See [OnePort](@ref)
27+
- See [OnePort](@ref)
28+
- `R(t)`: [`Ω`] Resistance (temperature dependent if `T_dep = true`)
2829
2930
# Connectors:
3031
3132
- `p` Positive pin
3233
- `n` Negative pin
34+
- `heat_port` [HeatPort](@ref) (only if `T_dep = true`) Heat port to model the temperature dependency
3335
3436
# Parameters:
3537
36-
- `R`: [`Ohm`] Resistance
38+
- `R`: [`Ω`] Reference resistance
39+
- `T_ref`: [K] Reference temperature
40+
- `alpha`: [K⁻¹] Temperature coefficient of resistance
41+
- `T_dep`: [bool] Temperature dependency
3742
"""
3843
@mtkmodel Resistor begin
3944
@extend v, i = oneport = OnePort()
45+
46+
@structural_parameters begin
47+
T_dep = false
48+
end
49+
4050
@parameters begin
41-
R, [description = "Resistance"]
51+
R = 1.0, [description = "Reference resistance", unit = "Ω"]
52+
T_ref = 300.15, [description = "Reference temperature", unit = "K"]
53+
alpha = 0.0, [description = "Temperature coefficient of resistance", unit = "K⁻¹"]
4254
end
43-
@equations begin
44-
v ~ i * R
55+
56+
if T_dep
57+
@components begin
58+
heat_port = HeatPort()
59+
end
60+
@variables begin
61+
R_T(t), [description = "Temperature-dependent resistance", unit = "Ω"]
62+
end
63+
@equations begin
64+
R_T ~ R * (1 + alpha * (heat_port.T - T_ref)) # Temperature-dependent resistance
65+
heat_port.Q_flow ~ -v * i # -LossPower
66+
v ~ i * R_T # Ohm's Law
67+
end
68+
else
69+
@equations begin
70+
v ~ i * R # Ohm's Law for constant resistance
71+
end
4572
end
4673
end
4774

@@ -264,9 +291,9 @@ Electromotoric force (electric/mechanic transformer)
264291
end
265292

266293
"""
267-
Diode(; name, Is = 1e-6, n = 1, T = 300.15)
294+
Diode(; name, Is = 1e-6, n = 1, T_ref = 300.15, T_dep = false)
268295
269-
Ideal diode based on the Shockley diode equation.
296+
Generic diode with optional temperature dependency.
270297
271298
# States
272299
@@ -276,70 +303,49 @@ Ideal diode based on the Shockley diode equation.
276303
277304
- `p` Positive pin
278305
- `n` Negative pin
306+
- `port` [HeatPort](@ref) (only if `T_dep = true`) Heat port to model the temperature dependency
279307
280-
# Parameters
281-
308+
# Parameters:
309+
282310
- `Is`: [`A`] Saturation current
283311
- `n`: Ideality factor
284-
- `T`: [K] Ambient temperature
312+
- `T_ref`: [K] Reference temperature
313+
- `T_dep`: [bool] Temperature dependency
285314
"""
286315
@mtkmodel Diode begin
287316
@constants begin
288317
k = 1.380649e-23 # Boltzmann constant (J/K)
289318
q = 1.602176634e-19 # Elementary charge (C)
290319
end
291320
@extend v, i = oneport = OnePort(; v = 0.0)
292-
@parameters begin
293-
Is = 1e-6, [description = "Saturation current (A)"]
294-
n = 1, [description = "Ideality factor"]
295-
T = 300.15, [description = "Ambient temperature"]
296-
end
297-
@equations begin
298-
i ~ Is * (exp(v * q / (n * k * T)) - 1)
299-
end
300-
end
301-
302-
"""
303-
HeatingDiode(; name, Is = 1e-6, n = 1)
304321

305-
Temperature dependent diode based on the Shockley diode equation.
306-
307-
# States
308-
309-
- See [OnePort](@ref)
310-
311-
# Connectors
312-
313-
- `p` Positive pin
314-
- `n` Negative pin
315-
- `port` [HeatPort](@ref) Heat port to model the temperature dependency
316-
317-
# Parameters:
318-
319-
- `Is`: [`A`] Saturation current
320-
- `n`: Ideality factor
321-
"""
322-
@mtkmodel HeatingDiode begin
323-
begin
324-
k = 1.380649e-23 # Boltzmann constant (J/K)
325-
q = 1.602176634e-19 # Elementary charge (C)
322+
@structural_parameters begin
323+
T_dep = false
326324
end
327325

328-
@extend v, i = oneport = OnePort(; v = 0.0)
329-
@components begin
330-
port = HeatPort()
331-
end
332326
@parameters begin
333327
Is = 1e-6, [description = "Saturation current (A)"]
334328
n = 1, [description = "Ideality factor"]
329+
T_ref = 300.15, [description = "Reference temperature (K)"]
330+
Vt_const = k * T_ref / q, [description = "Constant thermal voltage"]
335331
end
336-
@variables begin
337-
Vt(t), [description = "Thermal voltage"]
338-
end
339-
@equations begin
340-
Vt ~ k * port.T / q # Thermal voltage equation
341-
i ~ Is * (exp(v / (n * Vt)) - 1) # Shockley diode equation
342-
port.Q_flow ~ -v * i # -LossPower
332+
333+
if T_dep
334+
@components begin
335+
port = HeatPort()
336+
end
337+
@variables begin
338+
Vt(t), [description = "Thermal voltage"]
339+
end
340+
@equations begin
341+
Vt ~ k * port.T / q # Thermal voltage equation
342+
i ~ Is * (exp(v / (n * Vt)) - 1) # Shockley diode equation with temperature dependence
343+
port.Q_flow ~ -v * i # -LossPower
344+
end
345+
else
346+
@equations begin
347+
i ~ Is * (exp(v / (n * Vt_const)) - 1) # Shockley diode equation
348+
end
343349
end
344350
end
345351

@@ -366,20 +372,20 @@ R = R_const + pos * R_ref * (1 + alpha * (port.T - T_ref))
366372
- `R(t)`: Resistance
367373
368374
# Connectors
369-
370-
- `p` Positive pin
371-
- `n` Negative pin
372-
- `position` RealInput to set the position of the wiper
373-
- `port` [HeatPort](@ref) Heat port to model the temperature dependency
375+
376+
- `p` Positive pin
377+
- `n` Negative pin
378+
- `position` RealInput to set the position of the wiper
379+
- `port` [HeatPort](@ref) Heat port to model the temperature dependency
374380
375381
# Parameters
376-
377-
- `R_ref`: [`Ω`] Resistance at temperature T_ref when fully closed (pos=1.0)
378-
- `T_ref`: [K] Reference temperature
379-
- `R_const`: [`Ω`] Constant resistance between p and n
380-
- `T_dep`: Temperature dependency
381-
- `alpha`: [K⁻¹] Temperature coefficient of resistance
382-
- `enforce_bounds`: Enforce bounds for the position of the wiper (0-1)
382+
383+
- `R_ref`: [`Ω`] Resistance at temperature T_ref when fully closed (pos=1.0)
384+
- `T_ref`: [K] Reference temperature
385+
- `R_const`: [`Ω`] Constant resistance between p and n
386+
- `T_dep`: [bool] Temperature dependency
387+
- `alpha`: [K⁻¹] Temperature coefficient of resistance
388+
- `enforce_bounds`: Enforce bounds for the position of the wiper (0-1)
383389
"""
384390
@mtkmodel VariableResistor begin
385391
@extend v, i = oneport = OnePort()

src/Electrical/Electrical.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ include("utils.jl")
1515

1616
export Capacitor,
1717
Ground, Inductor, Resistor, Conductor, Short, IdealOpAmp, EMF,
18-
HeatingResistor, Diode, HeatingDiode, VariableResistor
18+
Diode, VariableResistor
1919
include("Analog/ideal_components.jl")
2020

2121
export CurrentSensor, PotentialSensor, VoltageSensor, PowerSensor, MultiSensor

test/Electrical/analog.jl

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -416,45 +416,45 @@ end
416416
@test capacitor_voltage[end].8.26 rtol=3e-1
417417

418418
# For visual inspection
419-
# plt = plot(sol; vars = [diode.i, resistor.i, capacitor.v],
419+
# plt = plot(sol; idxs = [diode.i, resistor.i, capacitor.v],
420420
# size = (800, 600), dpi = 300,
421421
# labels = ["Diode Current" "Resistor Current" "Capacitor Voltage"],
422422
# title = "Diode Test")
423423
# savefig(plt, "diode_test")
424424
end
425425

426-
@testset "HeatingDiode component test" begin
427-
@mtkmodel HeatingDiodeTest begin
428-
@parameters begin
429-
R = 1.0
430-
C = 1.0
431-
V = 10.0
432-
T = 300.0 # Ambient temperature in Kelvin
433-
n = 2.0
434-
Is = 1e-6
435-
f = 1.0
436-
end
437-
@components begin
438-
resistor = Resistor(R = R)
439-
capacitor = Capacitor(C = C, v = 0.0)
440-
source = Voltage()
441-
heating_diode = HeatingDiode(n = n, Is = Is)
442-
ac = Sine(frequency = f, amplitude = V)
443-
ground = Ground()
444-
temp = FixedTemperature(T = T)
445-
end
446-
@equations begin
447-
connect(ac.output, source.V)
448-
connect(source.p, heating_diode.p)
449-
connect(heating_diode.n, resistor.p)
450-
connect(resistor.n, capacitor.p)
451-
connect(capacitor.n, ground.g)
452-
connect(source.n, ground.g)
453-
connect(temp.port, heating_diode.port)
454-
end
455-
end
456-
457-
@mtkbuild sys = HeatingDiodeTest()
426+
@testset "Diode with temperature dependency component test" begin
427+
# Parameter values
428+
R = 1.0
429+
C = 1.0
430+
V = 10.0
431+
T = 300.0 # Ambient temperature in Kelvin
432+
n = 2.0
433+
Is = 1e-6
434+
f = 1.0
435+
436+
# Components
437+
@named resistor = Resistor(R = R)
438+
@named capacitor = Capacitor(C = C, v = 0.0)
439+
@named source = Voltage()
440+
@named heating_diode = Diode(n = n, Is = Is, T_dep = true)
441+
@named ac = Sine(frequency = f, amplitude = V)
442+
@named ground = Ground()
443+
@named temp = FixedTemperature(T = T)
444+
445+
# Connections
446+
connections = [connect(ac.output, source.V),
447+
connect(source.p, heating_diode.p),
448+
connect(heating_diode.n, resistor.p),
449+
connect(resistor.n, capacitor.p),
450+
connect(capacitor.n, ground.g),
451+
connect(source.n, ground.g),
452+
connect(temp.port, heating_diode.port)]
453+
454+
# Model
455+
@named model = ODESystem(connections, t;
456+
systems = [resistor, capacitor, source, heating_diode, ac, ground, temp])
457+
sys = structural_simplify(model)
458458
prob = ODEProblem(sys, Pair[], (0.0, 10.0))
459459
sol = solve(prob, Rodas4())
460460

@@ -473,10 +473,10 @@ end
473473
@test capacitor_voltage[end]7.75 rtol=3e-1 # Final capacitor voltage close to input voltage
474474

475475
# For visual inspection
476-
# plt = plot(sol; vars = [heating_diode.i, resistor.i, capacitor.v],
476+
# plt = plot(sol; idxs = [heating_diode.i, resistor.i, capacitor.v],
477477
# size = (800, 600), dpi = 300,
478-
# labels = ["HeatingDiode Current" "Resistor Current" "Capacitor Voltage"],
479-
# title = "HeatingDiode Test")
478+
# labels = ["Diode Current" "Resistor Current" "Capacitor Voltage"],
479+
# title = "Diode Test")
480480
# savefig(plt, "heating_diode_test")
481481

482482
# Remake model with higher amb. temperature, final capacitor voltage should be lower

test/multi_domain.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ end
181181
ground = Ground()
182182
source = Voltage()
183183
voltage_sine = Blocks.Sine(amplitude = 220, frequency = 1)
184-
heating_resistor = HeatingResistor(R_ref = 100, alpha = 1e-3, T_ref = 293.15)
184+
heating_resistor = Resistor(R = 100, alpha = 1e-3,
185+
T_ref = 293.15, T_dep = true)
185186
thermal_conductor = ThermalConductor(G = 50)
186187
env = FixedTemperature(T = 273.15 + 20)
187188
end

0 commit comments

Comments
 (0)