Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify temperature dependency for analog components #349

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 72 additions & 107 deletions src/Electrical/Analog/ideal_components.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,57 @@ node.
end

"""
Resistor(; name, R)
Resistor(; name, R_ref = 1.0, T_ref = 300.15, alpha = 0, T_dep = false)

Creates an ideal Resistor following Ohm's Law.
Generic resistor with optional temperature dependency.

# States:

See [OnePort](@ref)
- See [OnePort](@ref)
- `R(t)`: [`Ω`] Resistance (temperature dependent if `T_dep = true`)

# Connectors:

- `p` Positive pin
- `n` Negative pin
- `heat_port` [HeatPort](@ref) (only if `T_dep = true`) Heat port to model the temperature dependency

# Parameters:

- `R`: [`Ohm`] Resistance
- `R`: [`Ω`] Reference resistance
- `T_ref`: [K] Reference temperature
- `alpha`: [K⁻¹] Temperature coefficient of resistance
- `T_dep`: [bool] Temperature dependency
"""
@mtkmodel Resistor begin
@extend v, i = oneport = OnePort()

@structural_parameters begin
T_dep = false
end

@parameters begin
R, [description = "Resistance"]
R = 1.0, [description = "Reference resistance", unit = "Ω"]
T_ref = 300.15, [description = "Reference temperature", unit = "K"]
alpha = 0.0, [description = "Temperature coefficient of resistance", unit = "K⁻¹"]
end
@equations begin
v ~ i * R

if T_dep
@components begin
heat_port = HeatPort()
end
@variables begin
R_T(t), [description = "Temperature-dependent resistance", unit = "Ω"]
end
@equations begin
R_T ~ R * (1 + alpha * (heat_port.T - T_ref)) # Temperature-dependent resistance
heat_port.Q_flow ~ -v * i # -LossPower
v ~ i * R_T # Ohm's Law
end
else
@equations begin
v ~ i * R # Ohm's Law for constant resistance
end
end
end

Expand Down Expand Up @@ -178,47 +205,6 @@ See [OnePort](@ref)
end
end

"""
HeatingResistor(; name, R_ref = 1.0, T_ref = 300.15, alpha = 0)

Temperature dependent electrical resistor

# States

- See [OnePort](@ref)
- `R(t)`: [`Ohm`] Temperature dependent resistance `R ~ R_ref*(1 + alpha*(heat_port.T(t) - T_ref))`

# Connectors

- `p` Positive pin
- `n` Negative pin

# Parameters:

- `R_ref`: [`Ω`] Reference resistance
- `T_ref`: [K] Reference temperature
- `alpha`: [K⁻¹] Temperature coefficient of resistance
"""
@mtkmodel HeatingResistor begin
@extend v, i = oneport = OnePort()
@components begin
heat_port = HeatPort()
end
@parameters begin
R_ref = 1.0, [description = "Reference resistance"]
T_ref = 300.15, [description = "Reference temperature"]
alpha = 0, [description = "Temperature coefficient of resistance"]
end
@variables begin
R(t) = R_ref
end
@equations begin
R ~ R_ref * (1 + alpha * (heat_port.T - T_ref))
heat_port.Q_flow ~ -v * i # -LossPower
v ~ i * R
end
end

"""
EMF(; name, k)

Expand Down Expand Up @@ -264,9 +250,9 @@ Electromotoric force (electric/mechanic transformer)
end

"""
Diode(; name, Is = 1e-6, n = 1, T = 300.15)
Diode(; name, Is = 1e-6, n = 1, T_ref = 300.15, T_dep = false)

Ideal diode based on the Shockley diode equation.
Generic diode with optional temperature dependency.

# States

Expand All @@ -276,12 +262,14 @@ Ideal diode based on the Shockley diode equation.

- `p` Positive pin
- `n` Negative pin
- `port` [HeatPort](@ref) (only if `T_dep = true`) Heat port to model the temperature dependency

# Parameters
# Parameters:

- `Is`: [`A`] Saturation current
- `n`: Ideality factor
- `T`: [K] Ambient temperature
- `T_ref`: [K] Reference temperature
- `T_dep`: [bool] Temperature dependency
"""
@mtkmodel Diode begin
begin
Expand All @@ -290,57 +278,34 @@ Ideal diode based on the Shockley diode equation.
end

@extend v, i = oneport = OnePort(; v = 0.0)
@parameters begin
Is = 1e-6, [description = "Saturation current (A)"]
n = 1, [description = "Ideality factor"]
T = 300.15, [description = "Ambient temperature"]
end
@equations begin
i ~ Is * (exp(v * q / (n * k * T)) - 1)
end
end

"""
HeatingDiode(; name, Is = 1e-6, n = 1)

Temperature dependent diode based on the Shockley diode equation.

# States

- See [OnePort](@ref)

# Connectors

- `p` Positive pin
- `n` Negative pin
- `port` [HeatPort](@ref) Heat port to model the temperature dependency

# Parameters:

- `Is`: [`A`] Saturation current
- `n`: Ideality factor
"""
@mtkmodel HeatingDiode begin
begin
k = 1.380649e-23 # Boltzmann constant (J/K)
q = 1.602176634e-19 # Elementary charge (C)
@structural_parameters begin
T_dep = false
end

@extend v, i = oneport = OnePort(; v = 0.0)
@components begin
port = HeatPort()
end
@parameters begin
Is = 1e-6, [description = "Saturation current (A)"]
n = 1, [description = "Ideality factor"]
T_ref = 300.15, [description = "Reference temperature (K)"]
Vt_const = k * T_ref / q, [description = "Constant thermal voltage"]
end
@variables begin
Vt(t), [description = "Thermal voltage"]
end
@equations begin
Vt ~ k * port.T / q # Thermal voltage equation
i ~ Is * (exp(v / (n * Vt)) - 1) # Shockley diode equation
port.Q_flow ~ -v * i # -LossPower

if T_dep
@components begin
port = HeatPort()
end
@variables begin
Vt(t), [description = "Thermal voltage"]
end
@equations begin
Vt ~ k * port.T / q # Thermal voltage equation
i ~ Is * (exp(v / (n * Vt)) - 1) # Shockley diode equation with temperature dependence
port.Q_flow ~ -v * i # -LossPower
end
else
@equations begin
i ~ Is * (exp(v / (n * Vt_const)) - 1) # Shockley diode equation
end
end
end

Expand Down Expand Up @@ -368,19 +333,19 @@ R = R_const + pos * R_ref * (1 + alpha * (port.T - T_ref))

# Connectors

- `p` Positive pin
- `n` Negative pin
- `position` RealInput to set the position of the wiper
- `port` [HeatPort](@ref) Heat port to model the temperature dependency
- `p` Positive pin
- `n` Negative pin
- `position` RealInput to set the position of the wiper
- `port` [HeatPort](@ref) Heat port to model the temperature dependency

# Parameters

- `R_ref`: [`Ω`] Resistance at temperature T_ref when fully closed (pos=1.0)
- `T_ref`: [K] Reference temperature
- `R_const`: [`Ω`] Constant resistance between p and n
- `T_dep`: Temperature dependency
- `alpha`: [K⁻¹] Temperature coefficient of resistance
- `enforce_bounds`: Enforce bounds for the position of the wiper (0-1)
- `R_ref`: [`Ω`] Resistance at temperature T_ref when fully closed (pos=1.0)
- `T_ref`: [K] Reference temperature
- `R_const`: [`Ω`] Constant resistance between p and n
- `T_dep`: [bool] Temperature dependency
- `alpha`: [K⁻¹] Temperature coefficient of resistance
- `enforce_bounds`: Enforce bounds for the position of the wiper (0-1)
"""
@mtkmodel VariableResistor begin
@extend v, i = oneport = OnePort()
Expand Down
2 changes: 1 addition & 1 deletion src/Electrical/Electrical.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ include("utils.jl")

export Capacitor,
Ground, Inductor, Resistor, Conductor, Short, IdealOpAmp, EMF,
HeatingResistor, Diode, HeatingDiode, VariableResistor
Diode, VariableResistor
include("Analog/ideal_components.jl")

export CurrentSensor, PotentialSensor, VoltageSensor, PowerSensor, MultiSensor
Expand Down
12 changes: 6 additions & 6 deletions test/Electrical/analog.jl
Original file line number Diff line number Diff line change
Expand Up @@ -416,14 +416,14 @@ end
@test capacitor_voltage[end].≈V rtol=3e-1

# For visual inspection
# plt = plot(sol; vars = [diode.i, resistor.i, capacitor.v],
# plt = plot(sol; idxs = [diode.i, resistor.i, capacitor.v],
# size = (800, 600), dpi = 300,
# labels = ["Diode Current" "Resistor Current" "Capacitor Voltage"],
# title = "Diode Test")
# savefig(plt, "diode_test")
end

@testset "HeatingDiode component test" begin
@testset "Diode with temperature dependency component test" begin
# Parameter values
R = 1.0
C = 1.0
Expand All @@ -437,7 +437,7 @@ end
@named resistor = Resistor(R = R)
@named capacitor = Capacitor(C = C, v = 0.0)
@named source = Voltage()
@named heating_diode = HeatingDiode(n = n, Is = Is)
@named heating_diode = Diode(n = n, Is = Is, T_dep = true)
@named ac = Sine(frequency = f, amplitude = V)
@named ground = Ground()
@named temp = FixedTemperature(T = T)
Expand Down Expand Up @@ -473,10 +473,10 @@ end
@test capacitor_voltage[end]≈V rtol=3e-1 # Final capacitor voltage close to input voltage

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

# Remake model with higher amb. temperature, final capacitor voltage should be lower
Expand Down
3 changes: 2 additions & 1 deletion test/multi_domain.jl
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ end
ground = Ground()
source = Voltage()
voltage_sine = Blocks.Sine(amplitude = 220, frequency = 1)
heating_resistor = HeatingResistor(R_ref = 100, alpha = 1e-3, T_ref = 293.15)
heating_resistor = Resistor(R = 100, alpha = 1e-3,
T_ref = 293.15, T_dep = true)
thermal_conductor = ThermalConductor(G = 50)
env = FixedTemperature(T = 273.15 + 20)
end
Expand Down
Loading