Skip to content

Commit bfc0f7c

Browse files
baggepinnenclaude
andauthored
docs: update MTK example for ModelingToolkit v11 (#200)
* docs: update MTK example for ModelingToolkit v11 The `@mtkmodel` DSL was removed in ModelingToolkit v11 in favor of the functional component form (`@component function ... System(eqs, t; name) end`). This updates the quad-tank parameter-fitting example accordingly: - `@mtkmodel QuadtankModel begin ... end` -> `@component function QuadtankModel(; name) ... end` - array variable defaults must match size: `h(t)[1:4] = 0` -> `= zeros(4)` - `ModelingToolkit.defaults(io_sys)[pi]` -> `ModelingToolkit.getdefault(pi)` Verified end-to-end on ModelingToolkit v11.36.0; the estimated parameters still match the true values. Output block, benchmark timing, and the tested-version note in the warning are updated to match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: fix wrapper name in MTK example prose The prose referred to `discrete_dynamics_mtk` but the code defines the wrapper as `discrete_dynamics_wrapper`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent f1af47c commit bfc0f7c

1 file changed

Lines changed: 15 additions & 16 deletions

File tree

‎docs/src/examples/modelingtoolkit.md‎

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ t = ModelingToolkit.t_nounits
1717
ssqrt(x) = √(max(x, zero(x)) + 1e-3) # For numerical robustness at x = 0
1818
@register_symbolic ssqrt(x)
1919

20-
@mtkmodel QuadtankModel begin
20+
@component function QuadtankModel(; name)
2121
@parameters begin
2222
k1 = 1.4
2323
k2 = 1.4
@@ -26,21 +26,20 @@ ssqrt(x) = √(max(x, zero(x)) + 1e-3) # For numerical robustness at x = 0
2626
a = 0.03
2727
γ = 0.25
2828
end
29-
begin
30-
A1 = A2 = A3 = A4 = A
31-
a1 = a3 = a2 = a4 = a
32-
γ1 = γ2 = γ
33-
end
3429
@variables begin
35-
h(t)[1:4] = 0
36-
u(t)[1:2] = 0
30+
h(t)[1:4] = zeros(4)
31+
u(t)[1:2] = zeros(2)
3732
end
38-
@equations begin
33+
A1 = A2 = A3 = A4 = A
34+
a1 = a3 = a2 = a4 = a
35+
γ1 = γ2 = γ
36+
eqs = [
3937
D(h[1]) ~ -a1/A1 * ssqrt(2g*h[1]) + a3/A1*ssqrt(2g*h[3]) + γ1*k1/A1 * u[1]
4038
D(h[2]) ~ -a2/A2 * ssqrt(2g*h[2]) + a4/A2*ssqrt(2g*h[4]) + γ2*k2/A2 * u[2]
4139
D(h[3]) ~ -a3/A3*ssqrt(2g*h[3]) + (1-γ2)*k2/A3 * u[2]
4240
D(h[4]) ~ -a4/A4*ssqrt(2g*h[4]) + (1-γ1)*k1/A4 * u[1]
43-
end
41+
]
42+
return System(eqs, t; name)
4443
end
4544

4645
@named mtkmodel = QuadtankModel()
@@ -59,7 +58,7 @@ We then specify the inputs and outputs of this model, since they are arrays in t
5958
```math
6059
\dot x = f(x, u, p, t)
6160
```
62-
from MTK, we call `ModelingToolkit.generate_control_function`. This example assumes that the system model has an external input, ``u``. If your example does not have this, you may leave this argument empty. This returns two versions of this function, where the second one operates in place (modifying its first argument). This function also returns the state variables chosen, the parameters of the model as well as a simplified system with inputs and outputs. The function returned from `ModelingToolkit.generate_control_function` expects all the parameters of the system to be provided, but we only want to optimize a few of them. We thus wrap this function in `discrete_dynamics_mtk` in order to insert the optimized parameters into a parameter array that contains also the non-optimized parameters. We make use of the function `similar` to ensure that the final parameter array has the correct type (Dual numbers for AD will be used).
61+
from MTK, we call `ModelingToolkit.generate_control_function`. This example assumes that the system model has an external input, ``u``. If your example does not have this, you may leave this argument empty. This returns two versions of this function, where the second one operates in place (modifying its first argument). This function also returns the state variables chosen, the parameters of the model as well as a simplified system with inputs and outputs. The function returned from `ModelingToolkit.generate_control_function` expects all the parameters of the system to be provided, but we only want to optimize a few of them. We thus wrap this function in `discrete_dynamics_wrapper` in order to insert the optimized parameters into a parameter array that contains also the non-optimized parameters. We make use of the function `similar` to ensure that the final parameter array has the correct type (Dual numbers for AD will be used).
6362

6463
For good performance, we wrap all the glue code in a function `get_mtk_dynamics` so that we avoid the use of too many global variables.
6564

@@ -77,7 +76,7 @@ function get_mtk_dynamics(mtkmodel, inputs, outputs, tunable_p) # A wrapper func
7776
continuous_dynamics = f_oop # This is ẋ = f(x, u, p, t)
7877
inner_discrete_dynamics = SeeToDee.Rk4(continuous_dynamics, Ts::Float64) # x⁺ = f(x, u, p, t)
7978
tunable_indices = [findfirst(isequal(pi), p) for pi in tunable_p] # Figure out what indices of the parameter array correspond to our tunable parameters
80-
p0 = [ModelingToolkit.defaults(io_sys)[pi] for pi in p]
79+
p0 = [ModelingToolkit.getdefault(pi) for pi in p]
8180
full_p = deepcopy(p0)
8281
output_indices = [findfirst(isequal(yi), statevars) for yi in outputs] # Figure out what indices of the state array correspond to our outputs
8382

@@ -141,8 +140,8 @@ model = ControlSystemIdentification.nonlinear_pem(d, discrete_dynamics, measurem
141140

142141
```
143142
NonlinearPredictionErrorModel
144-
p: [1.6130151977611773, 1.5995448472434575, 4.887899044534598, 0.20437506116084214]
145-
x0: [2.5590156863624642, 1.674133802252665, 2.890730509103397, 2.114949939609547]
143+
p: [1.611987373192685, 1.599185391084847, 4.877360360086102, 0.2044771473506988]
144+
x0: [1.8477043095652341, 1.1766588459161196, 3.3770895080106467, 2.876924813784857]
146145
Ts: 1.0
147146
ny = 2, nu = 2, nx = 4
148147
```
@@ -161,10 +160,10 @@ using BenchmarkTools
161160
@btime ControlSystemIdentification.nonlinear_pem(d, discrete_dynamics, measurement, p_guess, x0_guess, R1, R2, nu)
162161
```
163162
```
164-
91.923 ms (876913 allocations: 97.23 MiB)
163+
118.966 ms (876188 allocations: 106.92 MiB)
165164
```
166165

167166

168167

169168
!!! warning
170-
ModelingToolkit is a fast moving target that breaks frequently. The example below was tested with ModelingToolkit v10.0.1, but is not run as part of the build process for this documentation and is not to be considered a supported interface between ControlSystemIdentification and ModelingToolkit.
169+
ModelingToolkit is a fast moving target that breaks frequently. This example was tested with ModelingToolkit v11.36.0, but is not run as part of the build process for this documentation and is not to be considered a supported interface between ControlSystemIdentification and ModelingToolkit.

0 commit comments

Comments
 (0)