@@ -383,3 +383,56 @@ sol[α * x - β * x * y]
383
383
``` @example init
384
384
plot(sol)
385
385
```
386
+
387
+ ## Solving for parameters during initialization
388
+
389
+ Sometimes, it is necessary to solve for a parameter during initialization. For example,
390
+ given a spring-mass system we want to find the un-stretched length of the spring given
391
+ that the initial condition of the system is its steady state.
392
+
393
+ ``` @example init
394
+ using ModelingToolkitStandardLibrary.Mechanical.TranslationalModelica: Fixed, Mass, Spring,
395
+ Force, Damper
396
+ using ModelingToolkitStandardLibrary.Blocks: Constant
397
+
398
+ @named mass = Mass(; m = 1.0, s = 1.0, v = 0.0, a = 0.0)
399
+ @named fixed = Fixed(; s0 = 0.0)
400
+ @named spring = Spring(; c = 2.0, s_rel0 = missing)
401
+ @named gravity = Force()
402
+ @named constant = Constant(; k = 9.81)
403
+ @named damper = Damper(; d = 0.1)
404
+ @mtkbuild sys = ODESystem(
405
+ [connect(fixed.flange, spring.flange_a), connect(spring.flange_b, mass.flange_a),
406
+ connect(mass.flange_a, gravity.flange), connect(constant.output, gravity.f),
407
+ connect(fixed.flange, damper.flange_a), connect(damper.flange_b, mass.flange_a)],
408
+ t;
409
+ systems = [fixed, spring, mass, gravity, constant, damper],
410
+ guesses = [spring.s_rel0 => 1.0])
411
+ ```
412
+
413
+ Note that we explicitly provide ` s_rel0 = missing ` to the spring. Parameters are only
414
+ solved for during initialization if their value (either default, or explicitly passed
415
+ to the ` ODEProblem ` constructor) is ` missing ` . We also need to provide a guess for the
416
+ parameter.
417
+
418
+ If a parameter is not given a value of ` missing ` , and does not have a default or initial
419
+ value, the ` ODEProblem ` constructor will throw an error. If the parameter _ does_ have a
420
+ value of ` missing ` , it must be given a guess.
421
+
422
+ ``` @example init
423
+ prob = ODEProblem(sys, [], (0.0, 1.0))
424
+ prob.ps[spring.s_rel0]
425
+ ```
426
+
427
+ Note that the value of the parameter in the problem is zero, similar to unknowns that
428
+ are solved for during initialization.
429
+
430
+ ``` @example init
431
+ integ = init(prob)
432
+ integ.ps[spring.s_rel0]
433
+ ```
434
+
435
+ The un-stretched length of the spring is now correctly calculated. The same result can be
436
+ achieved if ` s_rel0 = missing ` is omitted when constructing ` spring ` , and instead
437
+ ` spring.s_rel0 => missing ` is passed to the ` ODEProblem ` constructor along with values
438
+ of other parameters.
0 commit comments