Skip to content

Commit c12374f

Browse files
docs: add documentation for Initial parameters
1 parent 158f3f8 commit c12374f

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

docs/src/tutorials/initialization.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,73 @@ long enough you will see that `λ = 0` is required for this equation, but since
203203
problem constructor. Additionally, any warning about not being fully determined can
204204
be suppressed via passing `warn_initialize_determined = false`.
205205

206+
## Constant constraints in initialization
207+
208+
Consider the pendulum system again:
209+
210+
```@repl init
211+
equations(pend)
212+
observed(pend)
213+
```
214+
215+
Suppose we want to solve the same system with multiple different initial
216+
y-velocities from a given position.
217+
218+
```@example init
219+
prob = ODEProblem(
220+
pend, [x => 1, D(y) => 0], (0.0, 1.5), [g => 1], guesses = [λ => 0, y => 1, x => 1])
221+
sol1 = solve(prob, Rodas5P())
222+
```
223+
224+
```@example init
225+
sol1[D(y), 1]
226+
```
227+
228+
Repeatedly re-creating the `ODEProblem` with different values of `D(y)` and `x` or
229+
repeatedly calling `remake` is slow. Instead, for any `variable => constant` constraint
230+
in the `ODEProblem` initialization (whether provided to the `ODEProblem` constructor or
231+
a default value) we can update the `constant` value. ModelingToolkit refers to these
232+
values using the `Initial` operator. For example:
233+
234+
```@example init
235+
prob.ps[[Initial(x), Initial(D(y))]]
236+
```
237+
238+
To solve with a different starting y-velocity, we can simply do
239+
240+
```@example init
241+
prob.ps[Initial(D(y))] = -0.1
242+
sol2 = solve(prob, Rodas5P())
243+
```
244+
245+
```@example init
246+
sol2[D(y), 1]
247+
```
248+
249+
Note that this _only_ applies for constant constraints for the current ODEProblem.
250+
For example, `D(x)` does not have a constant constraint - it is solved for by
251+
initialization. Thus, mutating `Initial(D(x))` does not have any effect:
252+
253+
```@repl init
254+
sol2[D(x), 1]
255+
prob.ps[Initial(D(x))] = 1.0
256+
sol3 = solve(prob, Rodas5P())
257+
sol3[D(x), 1]
258+
```
259+
260+
To enforce this constraint, we would have to `remake` the problem (or construct a new one).
261+
262+
```@repl init
263+
prob2 = remake(prob; u0 = [y => 0.0, D(x) => 0.0, x => nothing, D(y) => nothing]);
264+
sol4 = solve(prob2, Rodas5P())
265+
sol4[D(x), 1]
266+
```
267+
268+
Note the need to provide `x => nothing, D(y) => nothing` to override the previously
269+
provided initial conditions. Since `remake` is a partial update, the constraints provided
270+
to it are merged with the ones already present in the problem. Existing constraints can be
271+
removed by providing a value of `nothing`.
272+
206273
## Initialization of parameters
207274

208275
Parameters may also be treated as unknowns in the initialization system. Doing so works
@@ -231,6 +298,9 @@ constraints provided to it. The new values will be combined with the original
231298
variable-value mapping provided to `ODEProblem` and used to construct the initialization
232299
problem.
233300

301+
The variable on the left hand side of all parameter dependencies also has an `Initial`
302+
variant, which is used if a constant constraint is provided for the variable.
303+
234304
### Parameter initialization by example
235305

236306
Consider the following system, where the sum of two unknowns is a constant parameter

0 commit comments

Comments
 (0)