Skip to content

Commit

Permalink
Add variable resistor component
Browse files Browse the repository at this point in the history
  • Loading branch information
langestefan committed Nov 25, 2024
1 parent 1827d63 commit 957e755
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/src/API/electrical.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Inductor
IdealOpAmp
Diode
HeatingDiode
VariableResistor
```

## Analog Sensors
Expand Down
89 changes: 88 additions & 1 deletion src/Electrical/Analog/ideal_components.jl
Original file line number Diff line number Diff line change
Expand Up @@ -342,4 +342,91 @@ Temperature dependent diode based on the Shockley diode equation.
i ~ Is * (exp(v / (n * Vt)) - 1) # Shockley diode equation
port.Q_flow ~ -v * i # -LossPower
end
end
end

"""
VariableResistor(; name, R_ref = 1.0, T_ref = 300.15, R_const = 1e-3, T_dep = false)
Variable resistor with optinal temperature dependency.

Check warning on line 350 in src/Electrical/Analog/ideal_components.jl

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"optinal" should be "optional".
The total resistance R ∈ [R_const, R_const + R_ref], where pos is the
position of the wiper and R_ref is the variable resistance between p and n.
The total resistance is then:
R = R_const + pos * R_ref
If T_dep is true, then R also depends on the temperature of the heat port with
temperature coefficient alpha. The total resistance is then:
R = R_const + pos * R_ref * (1 + alpha * (port.T - T_ref))
# States
- See [OnePort](@ref)
- `pos(t)`: Position of the wiper (normally 0-1)
- `R(t)`: Resistance
# 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
# 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)
"""
@mtkmodel VariableResistor begin
@extend v, i = oneport = OnePort()

@structural_parameters begin
T_dep = false
enforce_bounds = true
end

@parameters begin
R_ref = 1.0,
[description = "Resistance at temperature T_ref when fully closed (pos=1.0)",
unit = "Ω"]
T_ref = 300.15, [description = "Reference temperature", unit = "K"]
R_const = 1e-3, [description = "Constant resistance between p and n", unit = "Ω"]
end

@components begin
position = RealInput()
end

@variables begin
pos(t), [description = "Position of the wiper (normally 0-1)"]
R(t), [description = "Resistance", unit = "Ω"]
end

if T_dep
@parameters begin
alpha = 1e-3,
[description = "Temperature coefficient of resistance", unit = "K^-1"]
end
@components begin
port = HeatPort()
end
@equations begin
port.Q_flow ~ -v * i # -LossPower
R ~ R_const + pos * R_ref * (1 + alpha * (port.T - T_ref))
end
else
@equations begin
R ~ R_const + pos * R_ref
end
end

@equations begin
pos ~ (enforce_bounds ? clamp(position.u, 0, 1) : position.u)
v ~ i * R
end
end
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
HeatingResistor, Diode, HeatingDiode, VariableResistor
include("Analog/ideal_components.jl")

export CurrentSensor, PotentialSensor, VoltageSensor, PowerSensor, MultiSensor
Expand Down
54 changes: 54 additions & 0 deletions test/Electrical/analog.jl
Original file line number Diff line number Diff line change
Expand Up @@ -486,3 +486,57 @@ end
@test SciMLBase.successful_retcode(sol)
@test sol[capacitor.v][end] < capacitor_voltage[end]
end

@testset "VariableResistor with Temperature Dependency" begin
R_ref = 2.0
R_const = 1.0

# Define the RC model as described
@mtkmodel RC begin
@parameters begin
R = R_ref # Variable resistance reference value
C = 1.0 # Capacitance
k = 10.0 # Voltage source scaling factor
f = 0.2 # Frequency of sine input
T = 300.0 # Ambient temperature in Kelvin
end
@components begin
res_input = Sine(frequency = f, amplitude = 1.0, offset = 0.0)
volt_input = Constant(k = 1.0)
resistor = VariableResistor(R_ref = R_ref, R_const = R_const, T_dep = true)
capacitor = Capacitor(C = C, v = 0.0)
source = Voltage()
temp = FixedTemperature(T = T)
ground = Ground()
end
@equations begin
connect(temp.port, resistor.port)
connect(res_input.output, resistor.position)
connect(volt_input.output, source.V)
connect(source.p, resistor.p)
connect(resistor.n, capacitor.p)
connect(capacitor.n, source.n, ground.g)
end
end

# Build and solve the system
@mtkbuild sys = RC()
prob = ODEProblem(sys, [0.0, 0.0], (0.0, 10.0)) # No state variables initially
sol = solve(prob)

# Perform Tests
resistor_resistance = sol[sys.resistor.R]
capacitor_voltage = sol[sys.capacitor.v]

@test SciMLBase.successful_retcode(sol) # Ensure the simulation is successful
@test all(resistor_resistance .>= R_const) # Resistance should be >= constant value
@test maximum(resistor_resistance) R_const + R_ref # Maximum resistance when pos=1 (R_const + R_ref)
@test all(capacitor_voltage .>= 0.0) # Capacitor voltage should not be negative

# For visual inspection
# plt = plot(sol; vars = [sys.resistor.R, sys.capacitor.v],
# size = (800, 600), dpi = 300,
# labels = ["Variable Resistor Resistance" "Capacitor Voltage"],
# title = "RC Circuit Test with VariableResistor")
# savefig(plt, "rc_circuit_test_variable_resistor")
end

0 comments on commit 957e755

Please sign in to comment.