Skip to content

Commit 198eed4

Browse files
committed
docs: add discretization schemes documentation
- Add list of available integration schemes for collocation discretizer - Document ADNLP-specific Gauss-Legendre schemes (2-point and 3-point) - Remove Draft=false meta blocks from example files - Update Manifest.toml
1 parent e61d601 commit 198eed4

5 files changed

Lines changed: 41 additions & 14 deletions

File tree

docs/src/assets/Manifest.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,9 @@ weakdeps = ["OrdinaryDiffEq"]
242242

243243
[[deps.CTModels]]
244244
deps = ["CTBase", "DocStringExtensions", "LinearAlgebra", "MLStyle", "MacroTools", "OrderedCollections", "Parameters", "RecipesBase"]
245-
git-tree-sha1 = "c878ed38da4040f618a459c30cec8e53286ddc26"
245+
git-tree-sha1 = "3e9df6b6cb96ccb05051ded9a5d4f76f649f6d0c"
246246
uuid = "34c4fa32-2049-4079-8329-de33c2a22e2d"
247-
version = "0.9.11"
247+
version = "0.9.12-beta"
248248
weakdeps = ["JLD2", "JSON3", "Plots"]
249249

250250
[deps.CTModels.extensions]

docs/src/example-double-integrator-energy.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,10 @@ We are now ready to solve the shooting equations.
135135
# auxiliary in-place NLE function
136136
nle!(s, p0, _) = s[:] = S(p0)
137137
138-
# initial guess for the Newton solver
139-
p0_guess = [1, 1]
138+
# initial guess for the Newton solver from the direct solution
139+
t = time_grid(direct_sol) # the time grid as a vector
140+
p = costate(direct_sol) # the costate as a function of time
141+
p0_guess = p(t0) # initial costate
140142
141143
# NLE problem with initial guess
142144
prob = NonlinearProblem(nle!, p0_guess)

docs/src/example-double-integrator-time.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,14 @@ nothing # hide
9090
Let us solve it with a direct method (we set the number of time steps to 200):
9191

9292
```@example main
93-
sol = solve(ocp; grid_size=200)
93+
direct_sol = solve(ocp; grid_size=200)
9494
nothing # hide
9595
```
9696

9797
and plot the solution:
9898

9999
```@example main
100-
plt = plot(sol; label="Direct", size=(800, 600))
100+
plt = plot(direct_sol; label="Direct", size=(800, 600))
101101
```
102102

103103
!!! note "Nota bene"
@@ -161,15 +161,24 @@ We are now ready to solve the shooting equations:
161161
# in-place shooting function
162162
nle!(s, ξ, λ) = shoot!(s, ξ[1:2], ξ[3], ξ[4])
163163
164-
# initial guess: costate and final time
165-
ξ_guess = [0.1, 0.1, 0.5, 1]
164+
# initial guess for the Newton solver from direct method
165+
t = time_grid(direct_sol) # the time grid as a vector
166+
p = costate(direct_sol) # the costate as a function of time
167+
p0_guess = p(t0) # initial costate
168+
tf_guess = variable(direct_sol) # final time
169+
170+
# find switching time t1 where p2(t) changes sign
171+
p2_values = [p(ti)[2] for ti in t]
172+
t1_guess = t[findfirst(i -> i > 1 && p2_values[i] * p2_values[i-1] < 0, 2:length(p2_values))]
173+
174+
ξ_guess = [p0_guess[1], p0_guess[2], t1_guess, tf_guess]
166175
167176
# NLE problem
168177
prob = NonlinearProblem(nle!, ξ_guess)
169178
170179
# resolution of the shooting equations
171-
sol = solve(prob; show_trace=Val(true))
172-
p0, t1, tf = sol.u[1:2], sol.u[3], sol.u[4]
180+
shoot_sol = solve(prob; show_trace=Val(true))
181+
p0, t1, tf = shoot_sol.u[1:2], shoot_sol.u[3], shoot_sol.u[4]
173182
174183
# print the solution
175184
println("\np0 = ", p0, "\nt1 = ", t1, "\ntf = ", tf)
@@ -182,10 +191,10 @@ Finally, we reconstruct and plot the solution obtained by the indirect method:
182191
φ = f_max * (t1, f_min)
183192
184193
# compute the solution: state, costate, control...
185-
flow_sol = φ((t0, tf), x0, p0; saveat=range(t0, tf, 200))
194+
indirect_sol = φ((t0, tf), x0, p0; saveat=range(t0, tf, 200))
186195
187196
# plot the solution on the previous plot
188-
plot!(plt, flow_sol; label="Indirect", color=2, linestyle=:dash)
197+
plot!(plt, indirect_sol; label="Indirect", color=2, linestyle=:dash)
189198
```
190199

191200
!!! note

docs/src/example-singular-control.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ Let's plot the solution:
7777

7878
```@example main
7979
opt = (state_bounds_style=:none, control_bounds_style=:none)
80-
plt = plot(direct_sol; label="direct", size=(800, 800), opt...)
80+
plt = plot(direct_sol; label="Direct", size=(800, 800), opt...)
8181
```
8282

8383
## Singular control by hand
@@ -340,7 +340,7 @@ nothing # hide
340340
Plot the indirect solution alongside the direct solution:
341341

342342
```@example main
343-
plot!(plt, indirect_sol; label="indirect", color=2, linestyle=:dash, opt...)
343+
plot!(plt, indirect_sol; label="Indirect", color=2, linestyle=:dash, opt...)
344344
```
345345

346346
The indirect and direct solutions match very well, confirming that our singular control computation is correct.

docs/src/manual-solve.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,22 @@ Each strategy declares its available options. You can inspect them using `descri
230230

231231
### Discretizer options
232232

233+
The collocation discretizer supports multiple integration schemes:
234+
235+
- `:trapeze` - Trapezoidal rule (second-order accurate)
236+
- `:midpoint` - Midpoint rule (second-order accurate)
237+
- `:euler` or `:euler_explicit` or `:euler_forward` - Explicit Euler method (first-order accurate)
238+
- `:euler_implicit` or `:euler_backward` - Implicit Euler method (first-order accurate, more stable for stiff problems)
239+
240+
!!! note "Additional schemes with ADNLP modeler"
241+
242+
When using the `:adnlp` modeler, two additional high-order collocation schemes are available:
243+
244+
- `:gauss_legendre_2` - 2-point Gauss-Legendre collocation (fourth-order accurate)
245+
- `:gauss_legendre_3` - 3-point Gauss-Legendre collocation (sixth-order accurate)
246+
247+
These schemes provide higher accuracy but require more computational effort.
248+
233249
```@example main
234250
describe(:collocation)
235251
```

0 commit comments

Comments
 (0)