Skip to content

Commit 2f81ea6

Browse files
authored
Merge pull request #2227 from ven-k/vkb/mtkmodel-docs
Document `@mtkmodel` and `@connector`
2 parents 66c3627 + b915769 commit 2f81ea6

File tree

2 files changed

+175
-0
lines changed

2 files changed

+175
-0
lines changed

docs/src/basics/MTKModel_Connector.md

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
## Defining components with `@mtkmodel`
2+
3+
`@mtkmodel` is a convenience macro to define ModelingToolkit components. It returns `ModelingToolkit.Model`, which includes a constructor that returns an ODESystem, a `structure` dictionary with metadata and flag `isconnector` which is set to `false`.
4+
5+
### What can an MTK-Model definition have?
6+
7+
`@mtkmodel` definition contains begin blocks of
8+
9+
- `@components`: for listing sub-components of the system
10+
- `@equations`: for the list of equations
11+
- `@extend`: for extending a base system and unpacking its states
12+
- `@parameters`: for specifying the symbolic parameters
13+
- `@structural_parameters`: for specifying non-symbolic parameters
14+
- `@variables`: for specifing the states
15+
16+
Let's explore these in more detail with the following example:
17+
18+
```@example mtkmodel-example
19+
using ModelingToolkit
20+
21+
@mtkmodel ModelA begin
22+
@parameters begin
23+
k1
24+
k2
25+
end
26+
end
27+
28+
@mtkmodel ModelB begin
29+
@parameters begin
30+
p1 = 1.0, [description = "Parameter of ModelB"]
31+
p2 = 1.0, [description = "Parameter of ModelB"]
32+
end
33+
end
34+
35+
@mtkmodel ModelC begin
36+
@structural_parameters begin
37+
f = sin
38+
end
39+
begin
40+
v_var = 1.0
41+
end
42+
@variables begin
43+
v(t) = v_var
44+
end
45+
@extend p1, p2 = model_b = ModelB(; p1)
46+
@components begin
47+
model_a = ModelA(; k1)
48+
end
49+
@equations begin
50+
model_a.k1 ~ f(v)
51+
end
52+
end
53+
```
54+
55+
#### `@parameters` and `@variables` begin block
56+
57+
- Parameters and variables are declared with respective begin blocks.
58+
- Variables must be functions of an independent variable.
59+
- Optionally, default values and metadata can be specified for these parameters and variables. See `ModelB` in the above example.
60+
- Along with creating parameters and variables, keyword arguments of same name with default value `nothing` are created.
61+
- Whenever a parameter or variable has default value, for example `v(t) = 0.0`, a symbolic variable named `v` with default value 0.0 and a keyword argument `v`, with default value `nothing` are created. <br> This way, users can optionally pass new value of `v` while creating a component.
62+
63+
```julia
64+
julia > @named model_c = ModelC(; v = 2.0);
65+
66+
julia > ModelingToolkit.getdefault(model_c.v)
67+
2.0
68+
```
69+
70+
#### `@structural_parameters` begin block
71+
72+
- This block is for non symbolic input arguements. These are for inputs that usually are not meant to be part of components; but influence how they are defined. One can list inputs like boolean flags, functions etc... here.
73+
- Whenever default values are specified, unlike parameters/variables, they are reflected in the keyword argument list.
74+
75+
#### `@extend` block
76+
77+
To extend a partial system,
78+
79+
- List the variables to unpack. If there is a single variable, explicitly specify it as a tuple.
80+
- Give a name to the base system
81+
- List the kwargs of the base system that should be listed as kwargs of the main component.
82+
- Note that in above example, `p1` is promoted as an argument of `ModelC`. Users can set the value of `p1` as
83+
84+
```julia
85+
julia> @named model_c = ModelC(; p1 = 2.0)
86+
87+
```
88+
89+
However, as `p2` isn't listed in the model definition, its default can't be modified by users.
90+
91+
#### `@components` begin block
92+
93+
- Declare the subcomponents within `@components` begin block.
94+
- The arguments in these subcomponents are promoted as keyword arguments as `subcomponent_name__argname` with `nothing` as default value.
95+
- Whenever components are created with `@named` macro, these can be accessed with `.` operator as `subcomponent_name.argname`
96+
- In the above example, `k1` of `model_a` can be set in following ways:
97+
98+
```julia
99+
julia> @named model_c1 = ModelC(; model_a.k1 = 1);
100+
# or as
101+
102+
julia> model_c2 = ModelC(; name = :model_c, model_a__k1 = 1);
103+
104+
```
105+
106+
And as `k2` isn't listed in the sub-component definition of `ModelC`, its default value can't be modified by users.
107+
108+
#### `@equations` begin block
109+
110+
- List all the equations here
111+
112+
#### A begin block
113+
114+
- Any other Julia operations can be included with dedicated begin blocks.
115+
116+
## Defining connectors with `@connector`
117+
118+
`@connector` returns `ModelingToolkit.Model`. It includes a constructor that returns a connector ODESystem, a `structure` dictionary with metadata and flag `isconnector` which is set to `true`.
119+
120+
A simple connector can be defined with syntax similar to following example:
121+
122+
```julia
123+
using ModelingToolkit
124+
125+
@connector Pin begin
126+
v(t) = 0.0, [description = "Voltage"]
127+
i(t), [connect = Flow]
128+
end
129+
```
130+
131+
- Variables (as function of independent variable) are listed out in the definition. These variables can optionally have default values and metadata like `descrption`, `connect` and so on.
132+
133+
`@connector`s accepts begin blocks of `@components`, `@equations`, `@extend`, `@parameters`, `@structural_parameters`, `@variables`. These keywords mean the same as described above for `@mtkmodel`.
134+
135+
!!! note
136+
137+
For more examples of usage, checkout [ModelingToolkitStandardLibrary.jl](https://github.com/SciML/ModelingToolkitStandardLibrary.jl/)
138+
139+
* * *
140+
141+
### What's a `structure` dictionary?
142+
143+
For components defined with `@mtkmodel` or `@connector`, a dictionary with metadata is created. It lists `:components` (sub-component list), `:extend` (the extended states and base system), `:parameters`, `:variables`, ``:kwargs`` (list of keyword arguments), `:independent_variable`, `:equations`.
144+
145+
For example, the structure of `ModelC` is:
146+
147+
```julia
148+
julia> ModelC.structure
149+
Dict{Symbol, Any} with 6 entries:
150+
:components => [[:model_a, :ModelA]]
151+
:variables => Dict{Symbol, Dict{Symbol, Any}}(:v=>Dict(:default=>:v_var))
152+
:kwargs => Dict{Symbol, Any}(:f=>:sin, :v=>:v_var, :p1=>nothing, :model_a__k1=>nothing)
153+
:independent_variable => t
154+
:extend => Any[[:p1, :p2], :model_b, :ModelB]
155+
:equations => ["model_a.k1 ~ f(v)"]
156+
```

src/systems/model_parsing.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
1+
"""
2+
$(TYPEDEF)
3+
4+
ModelingToolkit component or connector with metadata
5+
6+
# Fields
7+
$(FIELDS)
8+
"""
19
struct Model{F, S}
10+
"""The constructor that returns ODESystem."""
211
f::F
12+
"""
13+
The dictionary with metadata like keyword arguements (:kwargs), base
14+
system this Model extends (:extend), sub-components of the Model (:components),
15+
variables (:variables), parameters (:parameters), structural parameters
16+
(:structural_parameters) and equations (:equations).
17+
"""
318
structure::S
19+
"""
20+
This flag is `true` when the Model is a connector and is `false` when it is
21+
a component
22+
"""
423
isconnector::Bool
524
end
625
(m::Model)(args...; kw...) = m.f(args...; kw...)

0 commit comments

Comments
 (0)