diff --git a/src/Electrical/Analog/ideal_components.jl b/src/Electrical/Analog/ideal_components.jl index da25edf15..0c1365c10 100644 --- a/src/Electrical/Analog/ideal_components.jl +++ b/src/Electrical/Analog/ideal_components.jl @@ -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"] + T_ref = 300.15, [description = "Reference temperature"] + alpha = 0.0, [description = "Temperature coefficient of resistance"] end - @equations begin - v ~ i * R + + if T_dep + @components begin + heat_port = HeatPort() + end + @variables begin + R_T(t), [description = "Temperature-dependent resistance"] + 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 @@ -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) @@ -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 @@ -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 @@ -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 @@ -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() diff --git a/src/Electrical/Electrical.jl b/src/Electrical/Electrical.jl index 68ba19cea..ceafa3619 100644 --- a/src/Electrical/Electrical.jl +++ b/src/Electrical/Electrical.jl @@ -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 diff --git a/test/Electrical/analog.jl b/test/Electrical/analog.jl index 0e7f23dd5..ef47f4590 100644 --- a/test/Electrical/analog.jl +++ b/test/Electrical/analog.jl @@ -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 @@ -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) @@ -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 diff --git a/test/multi_domain.jl b/test/multi_domain.jl index bb2baca03..95fc93043 100644 --- a/test/multi_domain.jl +++ b/test/multi_domain.jl @@ -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