Skip to content

Commit

Permalink
Merge pull request #81 from ValentinKaisermayer/patch-io
Browse files Browse the repository at this point in the history
Adds input/output meta data
  • Loading branch information
ChrisRackauckas authored Jun 19, 2022
2 parents c9af29e + e4eb600 commit 1100e95
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/Blocks/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ Output first input divided by second input.
"""
function Division(;name)
@named input1 = RealInput()
@named input2 = RealInput()
@named input2 = RealInput(u_start=1.0) # denominator can not be zero
@named output = RealOutput()
eqs= [
output.u ~ input1.u / input2.u
Expand Down
10 changes: 5 additions & 5 deletions src/Blocks/utils.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
@connector function RealInput(;name, nin=1, u_start=nin > 1 ? zeros(nin) : 0.0)
if nin == 1
@variables u(t) = u_start
@variables u(t) = u_start [input=true]
else
@variables u[1:nin](t) = u_start
@variables u[1:nin](t) = u_start [input=true]
u = collect(u)
end
ODESystem(Equation[], t, [u...], []; name=name)
Expand All @@ -22,9 +22,9 @@ Connector with one input signal of type Real.

@connector function RealOutput(;name, nout=1, u_start=nout > 1 ? zeros(nout) : 0.0)
if nout == 1
@variables u(t) = u_start
@variables u(t) = u_start [output=true]
else
@variables u[1:nout](t) = u_start
@variables u[1:nout](t) = u_start [output=true]
u = collect(u)
end
ODESystem(Equation[], t, [u...], []; name=name)
Expand Down Expand Up @@ -88,4 +88,4 @@ function MIMO(;name, nin=1, nout=1, u_start=zeros(nin), y_start=zeros(nout))
[y[i] ~ output.u[i] for i in 1:nout]...,
]
return ODESystem(eqs, t, vcat(u..., y...), []; name=name, systems=[input, output])
end
end
6 changes: 3 additions & 3 deletions src/Thermal/HeatTransfer/ideal_components.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function HeatCapacitor(; name, C, T_start=273.15 + 20)
@parameters C=C
sts = @variables begin
T(t)=T_start
der_T(t)
der_T(t)=0.0
end

D = Differential(t)
Expand Down Expand Up @@ -81,7 +81,7 @@ function ConvectiveConductor(; name, G)
@named solid = HeatPort()
@named fluid = HeatPort()
@parameters G=G
sts = @variables Q_flow(t) dT(t)
sts = @variables Q_flow(t)=0.0 dT(t)=0.0
eqs = [
dT ~ solid.T - fluid.T
solid.Q_flow ~ Q_flow
Expand All @@ -107,7 +107,7 @@ function ConvectiveResistor(; name, R)
@named solidport = HeatPort()
@named fluidport = HeatPort()
@parameters R=R
sts = @variables Q_flow(t) dT(t)
sts = @variables Q_flow(t)=0.0 dT(t)=0.0
eqs = [
dT ~ solidport.T - fluidport.T
solidport.Q_flow ~ Q_flow
Expand Down
42 changes: 30 additions & 12 deletions test/Blocks/math.jl
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
using ModelingToolkitStandardLibrary.Blocks
using ModelingToolkit, OrdinaryDiffEq
using ModelingToolkit, OrdinaryDiffEq, Test
using ModelingToolkitStandardLibrary.Blocks: _clamp, _dead_zone
using ModelingToolkit: inputs, unbound_inputs, bound_inputs

@parameters t


@testset "Gain" begin
@named c = Constant(; k=1)
@named gain = Gain(1;)
@named int = Integrator(; k=1)
@named model = ODESystem([connect(c.output, gain.input), connect(gain.output, int.input)], t, systems=[int, gain, c])

sys = structural_simplify(model)

prob = ODEProblem(sys, Pair[int.x=>1.0], (0.0, 1.0))

sol = solve(prob, Rodas4())

@test isequal(unbound_inputs(sys), [])
@test sol.retcode == :Success
@test all(sol[c.output.u] .≈ 1)
@test sol[int.output.u][end] 2 # expected solution after 1s
Expand All @@ -40,6 +41,7 @@ end
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 100.0))

sol = solve(prob, Rodas4())
@test isequal(unbound_inputs(sys), [])
@test sol.retcode == :Success
@test sol[int.output.u][end] 2 # expected solution after 1s
end
Expand All @@ -61,6 +63,7 @@ end
sys = structural_simplify(model)
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 1.0))
sol = solve(prob, Rodas4())
@test isequal(unbound_inputs(sys), [])
@test sol.retcode == :Success
@test sol[add.output.u] 1 .+ sin.(2*pi*sol.t)

Expand All @@ -80,6 +83,7 @@ end
sys = structural_simplify(model)
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 1.0))
sol = solve(prob, Rodas4())
@test isequal(unbound_inputs(sys), [])
@test sol.retcode == :Success
@test sol[add.output.u] k1 .* 1 .+ k2 .* sin.(2*pi*sol.t)
end
Expand All @@ -104,6 +108,7 @@ end
sys = structural_simplify(model)
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 1.0))
sol = solve(prob, Rodas4())
@test isequal(unbound_inputs(sys), [])
@test sol.retcode == :Success
@test sol[add.output.u] 1 .+ sin.(2*pi*sol.t) .+ sin.(2*pi*2*sol.t)

Expand All @@ -125,6 +130,7 @@ end
sys = structural_simplify(model)
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 1.0))
sol = solve(prob, Rodas4())
@test isequal(unbound_inputs(sys), [])
@test sol.retcode == :Success
@test sol[add.output.u] k1 .* 1 .+ k2 .* sin.(2*pi*sol.t) .+ k3 .* sin.(2*pi*2*sol.t)

Expand All @@ -148,6 +154,7 @@ end
sys = structural_simplify(model)
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 1.0))
sol = solve(prob, Rodas4())
@test isequal(unbound_inputs(sys), [])
@test sol.retcode == :Success
@test sol[prod.output.u] 2 * sin.(2*pi*sol.t)
end
Expand All @@ -169,6 +176,7 @@ end
sys = structural_simplify(model)
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 1.0))
sol = solve(prob, Rodas4())
@test isequal(unbound_inputs(sys), [])
@test sol.retcode == :Success
@test sol[div.output.u] sin.(2*pi*sol.t) ./ 2
end
Expand All @@ -188,6 +196,7 @@ end
sys = structural_simplify(model)
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 1.0))
sol = solve(prob, Rodas4())
@test isequal(unbound_inputs(sys), [])
@test sol.retcode == :Success
@test sol[absb.output.u] abs.(sin.(2*pi*sol.t))
end
Expand All @@ -207,34 +216,38 @@ end

@testset "Math" begin
for (block, func) in [(Abs, abs), (Sign, sign), (Sin, sin), (Cos, cos), (Tan, tan), (Asin, asin), (Acos, acos), (Atan, atan), (Sinh, sinh), (Cosh, cosh), (Tanh, tanh), (Exp, exp)]
@named source = Sine(frequency=1)
@info "testing $block"
@named source = Sine(frequency=1, amplitude=0.5)
@named b = block()
@named int = Integrator()
@named model = ODESystem([connect(source.output, b.input), connect(b.output, int.input)], t, systems=[int, b, source])
sys = structural_simplify(model)
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 1.0))
sol = solve(prob, Rodas4())
@test isequal(unbound_inputs(sys), [])
@test sol.retcode == :Success
@test sol[b.output.u] func.(sol[source.output.u])
end

# input must be positive
for (block, func) in [(Sqrt, sqrt), (Log, log), (Log10, log10)]
@named source = Sine(; frequency=1, offset=2)
for (block, func) in [(Sqrt, sqrt), (Log, log), (Log10, log10)]
@info "testing $block"
@named source = Sine(; frequency=1, offset=2, amplitude=0.5)
@named b = block()
@named int = Integrator()
@named model = ODESystem([connect(source.output, b.input), connect(b.output, int.input)], t, systems=[int, b, source])
sys = structural_simplify(model)
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 1.0))
prob = ODEProblem(sys, Pair[int.x=>0.0, b.input.u=>2.0], (0.0, 1.0))
sol = solve(prob, Rodas4())
@test isequal(unbound_inputs(sys), [])
@test sol.retcode == :Success
@test sol[b.output.u] func.(sol[source.output.u])
end
end

@testset "Atan2" begin
@named c1 = Constant(; k=1)
@named c2 = Constant(; k=2)
@named c1 = Sine(; frequency=1, offset=2)
@named c2 = Sine(; frequency=1, offset=1)
@named b = Atan2(;)
@named int = Integrator(; k=1)
@named model = ODESystem(
Expand All @@ -246,9 +259,14 @@ end
t,
systems=[int, b, c1, c2]
)

sys = structural_simplify(model)
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 1.0))
prob = ODEProblem(sys, Pair[int.x=>0.0, b.input1.u=>2, b.input2.u=>1], (0.0, 1.0))
sol = solve(prob, Rodas4())

@test isequal(unbound_inputs(sys), [])
@test all(map(u->u in Set([b.input1.u, b.input2.u, int.input.u]), bound_inputs(sys)))
@test all(map(u->u in Set([b.input1.u, b.input2.u, int.input.u]), inputs(sys)))
@test sol.retcode == :Success
@test sol[int.output.u][end] atan(1, 2)
@test sol[int.input.u] atan.(sol[c1.output.u], sol[c2.output.u])
end

0 comments on commit 1100e95

Please sign in to comment.