From 9d91f95e7e50eaaab96319f07d509c1a02806076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Tue, 29 Apr 2025 13:48:58 +0300 Subject: [PATCH 1/6] refactor: add macro compatible interface for Interpolation --- src/Blocks/sources.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Blocks/sources.jl b/src/Blocks/sources.jl index 4839ed908..9619cd756 100644 --- a/src/Blocks/sources.jl +++ b/src/Blocks/sources.jl @@ -755,10 +755,10 @@ such as `LinearInterpolation`, `ConstantInterpolation` or `CubicSpline`. """ function Interpolation(interp_type, u, x, args...; name) itp = interp_type(u, x, args...) - Interpolation(itp; name) + Interpolation(; itp, name) end -function Interpolation(itp; name) +function Interpolation(; itp, name) @parameters (interpolator::typeof(itp))(..) = itp @named input = RealInput() @named output = RealOutput() From 28f17be5d985c2b1590fb3a6b07e17d5c2f7395e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Tue, 29 Apr 2025 13:49:36 +0300 Subject: [PATCH 2/6] test(Interpolation): add tests for Interpolation inside model macro --- test/Blocks/sources.jl | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/Blocks/sources.jl b/test/Blocks/sources.jl index 3f3de37c9..f8afafbb0 100644 --- a/test/Blocks/sources.jl +++ b/test/Blocks/sources.jl @@ -500,6 +500,44 @@ end @test SciMLBase.successful_retcode(sol) end +@testset "Interpolation in model macro" begin + + function MassSpringDamper(; name) + @named input = RealInput() + @variables f(t) x(t)=0 dx(t)=0 ddx(t) + @parameters m=10 k=1000 d=1 + + eqs = [f ~ input.u + ddx * 10 ~ k * x + d * dx + f + D(x) ~ dx + D(dx) ~ ddx] + + ODESystem(eqs, t; name, systems = [input]) + end + + table_data = [1.0, 2.0, 3.0] + table_bkp = [0.0, 0.5, 1.0] + itp = LinearInterpolation(table_data, table_bkp) + + @mtkmodel model_with_lut begin + @components begin + src = Interpolation(itp) + clk = ContinuousClock() + model = MassSpringDamper() + end + @equations begin + connect(src.input, clk.output) + connect(src.output, model.input) + end + end; + @mtkbuild sys = model_with_lut() + + prob = ODEProblem(sys, [], (0.0, 1)) + sol = solve(prob, Tsit5()) + + @test SciMLBase.successful_retcode(sol) +end + @testset "ParametrizedInterpolation" begin @variables y(t) = 0 u = rand(15) From 7a0a8a3fedef11e37871b1d056f589d6a50eaa16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Tue, 29 Apr 2025 14:58:33 +0300 Subject: [PATCH 3/6] docs: fix overdetermined system in Interpolation tutorial --- docs/src/tutorials/input_component.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/tutorials/input_component.md b/docs/src/tutorials/input_component.md index 292a8aa7a..a92998ea8 100644 --- a/docs/src/tutorials/input_component.md +++ b/docs/src/tutorials/input_component.md @@ -35,7 +35,7 @@ using Plots function MassSpringDamper(; name) @named input = RealInput() - @variables f(t)=0 x(t)=0 dx(t)=0 ddx(t)=0 + @variables f(t) x(t)=0 dx(t)=0 ddx(t) @parameters m=10 k=1000 d=1 eqs = [f ~ input.u @@ -145,7 +145,7 @@ plot(sol2) ``` !!! note - + Note that when changing the data, the length of the new data must be the same as the length of the original data. ## Custom Component with External Data From 6bbb55b6c990b6111568f253d0f973af701e5056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Tue, 29 Apr 2025 15:11:42 +0300 Subject: [PATCH 4/6] docs(Interpolation): add docs for the macro usage --- docs/src/tutorials/input_component.md | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/src/tutorials/input_component.md b/docs/src/tutorials/input_component.md index a92998ea8..05e769dd4 100644 --- a/docs/src/tutorials/input_component.md +++ b/docs/src/tutorials/input_component.md @@ -74,6 +74,35 @@ sol = solve(prob) plot(sol) ``` +Note that in the case of the `Interpolation` block, the `data` and the `time` act like +structural parameters. + +As such, we can also build the interpolation object outside of the model + +```@example interpolation_block +my_interpolation = LinearInterpolation(df.data, df.time) + +@mtkmodel MassSpringDamperSystem2 begin + @components begin + src = Interpolation(itp=my_interpolation) + clk = ContinuousClock() + model = MassSpringDamper() + end + @equations begin + connect(src.input, clk.output) + connect(src.output, model.input) + end +end; +@mtkbuild sys = MassSpringDamperSystem2() + +prob = ODEProblem(sys, [], (0, df.time[end])) +sol = solve(prob, Tsit5()) +plot(sol) +``` + +Note that the interpolation is constructed outside of the model, so we cannot use `remake` to change the +data. For that usecase, see the `ParametrizedInterpolation`. + ## `ParametrizedInterpolation` Block The `ModelingToolkitStandardLibrary.Blocks.ParametrizedInterpolation` component is similar to `Interpolation`, but as the name suggests, it is parametrized by the data, allowing one to change the underlying data without rebuilding the model as the data is represented via vector parameters. From 6c2e89d0bed7da151664c502fbaa03d6beb83c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Tue, 6 May 2025 17:17:25 +0300 Subject: [PATCH 5/6] refactor: add deprecation for Interpolation(itp; name) --- src/Blocks/sources.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Blocks/sources.jl b/src/Blocks/sources.jl index 9619cd756..4e6c4a8cb 100644 --- a/src/Blocks/sources.jl +++ b/src/Blocks/sources.jl @@ -758,6 +758,8 @@ function Interpolation(interp_type, u, x, args...; name) Interpolation(; itp, name) end +@deprecate Interpolation(itp; name) Interpolation(; itp, name) + function Interpolation(; itp, name) @parameters (interpolator::typeof(itp))(..) = itp @named input = RealInput() From 3108d0ce5fb3e7ca29996aa82b4784342370ae7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Tue, 6 May 2025 17:20:11 +0300 Subject: [PATCH 6/6] feat: add macro compatible ParametrizedInterpolation note that this does not fully support all the things that the non-macro version can do --- src/Blocks/sources.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Blocks/sources.jl b/src/Blocks/sources.jl index 4e6c4a8cb..abe3b34a8 100644 --- a/src/Blocks/sources.jl +++ b/src/Blocks/sources.jl @@ -870,3 +870,7 @@ function ParametrizedInterpolation( systems = [input, output], name) end + +function ParametrizedInterpolation(; interp_type, u::AbstractVector, x::AbstractVector, name) + ParametrizedInterpolation(interp_type, u, x; name) +end