Skip to content

Commit 40f5248

Browse files
docs: add release notes to NEWS.md
1 parent 7043677 commit 40f5248

File tree

1 file changed

+211
-0
lines changed

1 file changed

+211
-0
lines changed

NEWS.md

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,214 @@
1+
# ModelingToolkit v11 Release Notes
2+
3+
## Symbolics@7 and SymbolicUtils@4 compatibility
4+
5+
SymbolicUtils version 4 involved a major overhaul of the core symbolic infrastructure, which
6+
propagated to Symbolics as Symbolics version 7. ModelingToolkit has now updated to these versions.
7+
This includes significant type-stability improvements, enabling precompilation of large parts
8+
of the symbolic infrastructure and faster TTFX. It is highly recommended to read the
9+
[Release Notes for SymbolicUtils@4](https://github.com/JuliaSymbolics/SymbolicUtils.jl/releases/tag/v4.0.0)
10+
and the [doc page](https://docs.sciml.ai/SymbolicUtils/dev/manual/variants/) describing the new
11+
variant structure before these release notes.
12+
13+
As part of these changes, ModelingToolkit has changed how some data is represented to allow
14+
precompilation. Notably, `variable => value` mappings (such as guesses) are stored as an
15+
`AbstractDict{SymbolicT, SymbolicT}`. Here, `SymbolicT` is a type that comes from Symbolics.jl,
16+
and is the type for all unwrapped symbolic values. This means that any non-symbolic values
17+
are stored as `SymbolicUtils.Const` variants. Mutation such as `guesses(sys)[x] = 1.0` is still
18+
possible, and values are automatically converted. However, obtaining the value back requires
19+
usage of `SymbolicUtils.unwrap_const` or `Symbolics.value`.
20+
21+
## Semantic separation of discretes
22+
23+
ModelingToolkit has long overloaded the meaning of `@parameters` to the point that it means
24+
"anything that isn't `@variables`." This isn't a very intuitive or clear definition. This is
25+
now improved with the introduction of `@discretes`. Any quantities that vary on a different
26+
time-scale than those in `@variables` are now `@discretes`. `@parameters` can only be used to
27+
create "time-independent parameters". For clarity, the following continues to work:
28+
29+
```julia
30+
@parameters p q[1:3] f(::Real, ::Real)
31+
```
32+
33+
However, this is now disallowed:
34+
35+
```julia
36+
@parameters value(t)
37+
```
38+
39+
Instead, it must be declared as:
40+
41+
```julia
42+
@discretes value(t)
43+
```
44+
45+
And can be passed along with the `@variables`. Essentially, for time-varying systems
46+
the constructor syntax is
47+
48+
```julia
49+
System(equations, independent_variable, time_varying_variables, constant_values, [brownians])
50+
```
51+
52+
In the subsequent release notes and in documentation, "variables" refers to either `@variables`
53+
or `@discretes` unless explicitly mentioned otherwise.
54+
55+
An important note is that while this is a difference in declaration, the semantics are defined
56+
by their usage in the system. More concretely, a variable declared via `@discretes` is only
57+
actually considered discrete if it is part of the variables updated in a callback in the system.
58+
Otherwise, it is treated identically to a variable declared via `@variables`.
59+
60+
## Changes to `defaults` and initialization semantics
61+
62+
The concept of `defaults` is a relic of earlier ModelingToolkit versions, from when initialization
63+
did not exist and they served as convenient initial conditions. The package has evolved greatly since then
64+
and `defaults` have taken on many different meanings in different contexts. This makes their usage
65+
complicated and unintuitive.
66+
67+
`defaults` have now been removed. They are replaced by two new concepts, with simple and well-defined
68+
semantics. Firstly, `initial_conditions` is a variable-value mapping aimed solely at being a convenient
69+
way to provide initial conditions to `SciMLProblem`s constructed from the system. Specifying them is
70+
identical to providing initial values to the `ODEProblem` constructor. Secondly, `bindings` is an
71+
immutable variable-value mapping representing strong constraints between variables/parameters.
72+
A binding for a variable is a function of other variables/parameters that is enforced during initialization.
73+
A binding for a parameter is a function of other parameters that exclusively defines the value of that
74+
parameter. Bound variables or parameters cannot be given initial conditions, either through the
75+
`initial_conditions` keyword or by passing them to the problem constructor. In effect, bindings
76+
serve to mark specific variables as aliases of others during initialization, and parameters as aliases
77+
of other parameters. This supersedes the previous concept of parameter bindings, and explicit parameter
78+
equations passed along with the equations of the model. Since bound parameters are computed as functions
79+
of other parameters, they are treated akin to observed variables. They are not stored in the parameter
80+
object, and instead are computed on the fly as required.
81+
82+
Sometimes, it is useful to enforce a relation between parameters while allowing them to be given initial
83+
values. For example, one might relate the radius `r` and area `A` of a pipe as `A ~ pi * r * r`. Users of
84+
the model should be able to provide a value for either `r` or `A`, and the other should be calculated
85+
automatically. This is done by providing the relation `A ~ pi * r * r` to the `initialization_eqs`
86+
keyword of the model and binding both `A` and `r` to `missing`. Similar to v10, the equation represents
87+
a constraint to be enforced. The bindings act similar to the `missing` defaults in v9 and v10, indicating
88+
that the parameters are to be solved for. They are part of bindings since a parameter to be solved for
89+
cannot be an alias for a different value. As such, the choice of parameters that can be solved for is
90+
an immutable property of the system. Note that making a parameter solvable no longer requires specifying a
91+
guess. If a guess is required to solve the initialization, ModelingToolkit will error with an informative
92+
message during problem construction. Note that since parameters can only be bound to other parameters,
93+
a parameter `x0` can be bound to the initial value of a variable `x` using the binding `x0 = Initial(x)`.
94+
95+
The formulation of the initialization system can now be summarized succinctly. The system solves for:
96+
97+
- Unknowns of the system.
98+
- Observables (observed variables) of the system.
99+
- All unknowns for which derivatives are known (differential variables, and ones for which derivative
100+
information is available due to the index reduction process).
101+
- Discrete variables (created via `@discretes`).
102+
- Parameters with a binding of `missing`.
103+
104+
It is composed of:
105+
106+
- Algebraic equations.
107+
- Observed equations.
108+
- Initialization equations.
109+
- The `initial_conditions` of the system.
110+
- Initial conditions passed to the problem constructor. These override values in `initial_conditions`
111+
for the same variable.
112+
113+
Additionally, `Initial` parameters exist for the following variables:
114+
115+
- Unknowns
116+
- Observables
117+
- First derivatives of all unknowns and observables
118+
- Discrete variables
119+
- Parameters with a binding of `missing`
120+
121+
"Defaults" specified via variable metadata are now translated into either `initial_conditions` or
122+
`bindings` depending on the value. If the value is a constant, it is part of `initial_conditions`.
123+
If it is an expression involving other variables/parameters, it is part of `bindings`. For example,
124+
the following are `initial_conditions`:
125+
126+
```julia
127+
@variables x(t) = 1 y(t)[1:3] = zeros(3)
128+
@parameters f(::Real) = sin
129+
```
130+
131+
The following are bindings:
132+
133+
```julia
134+
@variables z(t) = x w(t)[1:2] = [1.5, z]
135+
@parameters p[1:3] = f(3)
136+
```
137+
138+
Notably, arrays are considered atomic. This means that if even one element of an array default is
139+
symbolic, the entire array variable is considered bound. Partial bindings can be constructed by
140+
destructuring the array:
141+
142+
```julia
143+
@parameters par[1:3] = [par1, par2, par3]
144+
```
145+
146+
Where `par1`, `par2` and `par3` can independently have initial conditions or bindings. In a
147+
similar vein, `guesses`, `initial_conditions` and `bindings` are all stored in special
148+
`AbstractDict` types that disallow scalarized keys. For example, `par[1]` cannot be a key
149+
of these dictionaries. `par` is allowed as a key. Initial values can still be given to the
150+
problem constructor in scalarized form.
151+
152+
As mentioned previously, bindings cannot be mutated. To change the bindings of a system,
153+
the following pattern can be employed:
154+
155+
```julia
156+
binds = bindings(sys)
157+
# the `ReadOnlyDict` wrapper uses `Base.parent` to get the underlying mutable container
158+
new_binds = parent(copy(binds))
159+
160+
# mutate `new_binds`...
161+
162+
using Setfield: @set!
163+
164+
@set! sys.bindings = new_binds
165+
sys = complete(sys) # Important!
166+
```
167+
168+
Mutation of bindings without copying them is undefined behavior and can lead to unpredictable bugs.
169+
170+
## Array variables as inputs
171+
172+
Previously, ModelingToolkit allowed part of an array variable to be an input. For example, the following
173+
used to be valid:
174+
175+
```julia
176+
@variables u(t)[1:2] [input = true]
177+
@named sys = # Some system involving `u`
178+
179+
sys = mtkcompile(sys; inputs = [u[1]])
180+
```
181+
182+
This is now disallowed. `mtkcompile` will throw an informative error if part of an array is passed as an
183+
input.
184+
185+
## Deprecation of `@mtkmodel`
186+
187+
The `@mtkmodel` originated as a convenient DSL for creating models. However, it has not received the same
188+
level of support as other features due to the complexity of the parsing. It is also a major source of bugs,
189+
and is thus a tripping hazard for new and old users alike. The macro is now deprecated. It is moved to a new
190+
package, SciCompDSL.jl. Enough updates have been made to allow it to create systems in v11, but it will not
191+
receive more maintenance from the core developers. It is, however, still open to community contribution. For
192+
more details, please refer to the discussion in [this Discourse thread](https://discourse.julialang.org/t/using-mtk-when-i-import-modelingtoolkit/133681/12).
193+
194+
## Splitting into `ModelingToolkitBase` and relicensing of parts of ModelingToolkit
195+
196+
The advanced structural simplification algorithms in ModelingToolkit, such as index reduction, structural
197+
singularity removal and tearing, are now moved to the [StateSelection.jl](https://github.com/JuliaComputing/StateSelection.jl/)
198+
and ModelingToolkitTearing.jl (`lib/ModelingToolkitTearing` in the same repo) packages. These packages are
199+
AGPL licensed. ModelingToolkitBase.jl contains the `System` representation, callbacks, all of the code-generation
200+
targets (problem constructors), and initialization infrastructure. Items that depend on structural simplification
201+
and/or require highly specialized code generation (`SCCNonlinearProblem` prominent among them) have been moved
202+
to ModelingToolkit.jl, which depends on the aforementioned AGPL packages. ModelingToolkitBase still contains
203+
a simple version of `mtkcompile` suitable for most use cases. It does not perform index reduction and requires
204+
that all differential equations are explicit in the derivative. However, it does have a simpler tearing algorithm
205+
that is capable of identifying observed equations in many scenarios. In fact, it is also able to reduce many
206+
systems created using modular components and the `connect` infrastructure. Contributions to improve this
207+
are also welcome.
208+
209+
For more information on the split and surrounding changes, please follow the discussion in
210+
[this Discourse thread](https://discourse.julialang.org/t/modelingtoolkit-v11-library-split-and-licensing-community-feedback-requested/134396).
211+
1212
# ModelingToolkit v10 Release Notes
2213

3214
## Callbacks

0 commit comments

Comments
 (0)