Skip to content

Commit 9966109

Browse files
committed
Add describe function for strategy options and update documentation
- Add src/helpers/describe.jl with describe() function to inspect strategy options - Update src/OptimalControl.jl to export describe function - Update docs/src/manual-solve.md to use describe() for strategy option inspection - Reorganize documentation structure for better clarity - Update docs/src/assets/Manifest.toml for documentation build
1 parent 28bd509 commit 9966109

4 files changed

Lines changed: 106 additions & 73 deletions

File tree

docs/src/assets/Manifest.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,9 @@ version = "0.8.9-beta"
244244

245245
[[deps.CTSolvers]]
246246
deps = ["ADNLPModels", "CTBase", "CTModels", "CommonSolve", "DocStringExtensions", "ExaModels", "KernelAbstractions", "NLPModels", "SolverCore"]
247-
git-tree-sha1 = "914e4e30b6335ed64f9d51573a5914bda4dd9f3d"
247+
git-tree-sha1 = "a815a0e8128bd2d967a0200a08e31decf47fdc71"
248248
uuid = "d3e8d392-8e4b-4d9b-8e92-d7d4e3650ef6"
249-
version = "0.4.6"
249+
version = "0.4.7-beta"
250250

251251
[deps.CTSolvers.extensions]
252252
CTSolversCUDA = "CUDA"
@@ -1750,9 +1750,9 @@ version = "1.22.0"
17501750

17511751
[[deps.OrdinaryDiffEqCore]]
17521752
deps = ["ADTypes", "Accessors", "Adapt", "ArrayInterface", "ConcreteStructs", "DataStructures", "DiffEqBase", "DocStringExtensions", "EnumX", "EnzymeCore", "FastBroadcast", "FastClosures", "FastPower", "FillArrays", "FunctionWrappersWrappers", "InteractiveUtils", "LinearAlgebra", "Logging", "MacroTools", "MuladdMacro", "Polyester", "PrecompileTools", "Preferences", "Random", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLLogging", "SciMLOperators", "SciMLStructures", "Static", "StaticArrayInterface", "StaticArraysCore", "SymbolicIndexingInterface", "TruncatedStacktraces"]
1753-
git-tree-sha1 = "fa1b29e844d9e118b1c8fbd778de6da0a1d25fa1"
1753+
git-tree-sha1 = "d783e7f540774792c945019ab7774f41cdc6331f"
17541754
uuid = "bbf590c4-e513-4bbe-9b18-05decba2e5d8"
1755-
version = "3.18.0"
1755+
version = "3.19.0"
17561756

17571757
[deps.OrdinaryDiffEqCore.extensions]
17581758
OrdinaryDiffEqCoreMooncakeExt = "Mooncake"

docs/src/manual-solve.md

Lines changed: 63 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,38 @@ This uses default strategies: collocation discretization, ADNLP modeler, and Ipo
5454
ERROR: ExtensionError. Please make: julia> using NLPModelsIpopt
5555
```
5656

57+
## Display
58+
59+
Control the configuration display with the `display` option:
60+
61+
```@example main
62+
# Suppress all output
63+
sol = solve(ocp; display=false)
64+
nothing # hide
65+
```
66+
67+
## Initial guess
68+
69+
Provide an initial guess using `initial_guess` (or the alias `init`):
70+
71+
```@example main
72+
# Using the @init macro
73+
init = @init ocp begin
74+
u = 0.5
75+
end
76+
77+
sol = solve(ocp; initial_guess=init, grid_size=50, display=false)
78+
nothing # hide
79+
```
80+
81+
```@example main
82+
# Or using the alias
83+
sol = solve(ocp; init=init, grid_size=50, display=false)
84+
nothing # hide
85+
```
86+
87+
For more details on initial guess specification, see [Set an initial guess](@ref manual-initial-guess).
88+
5789
## Available methods
5890

5991
OptimalControl.jl provides multiple solving strategies. To see all available combinations, call:
@@ -74,7 +106,7 @@ Each method is a **quadruplet** `(discretizer, modeler, solver, parameter)`:
74106
3. **Solver** — which NLP solver to use:
75107
- `:ipopt`: [Ipopt](https://coin-or.github.io/Ipopt/) interior point solver
76108
- `:madnlp`: [MadNLP](https://madnlp.github.io/MadNLP.jl/) pure-Julia solver (GPU-capable)
77-
- `:madncl`: [MadNCL](https://madnlp.github.io/MadNLP.jl/) (GPU-capable)
109+
- `:madncl`: [MadNCL](https://github.com/MadNLP/MadNCL.jl) (GPU-capable)
78110
- `:knitro`: [Knitro](https://www.artelys.com/solvers/knitro/) commercial solver (license required)
79111

80112
4. **Parameter** — execution backend:
@@ -111,7 +143,7 @@ Or provide a **partial description**. Missing tokens are auto-completed using th
111143

112144
```@example main
113145
# Only specify the solver → defaults to :collocation, :adnlp, :cpu
114-
sol = solve(ocp, :madnlp)
146+
sol = solve(ocp, :madnlp; print_level=MadNLP.ERROR)
115147
nothing # hide
116148
```
117149

@@ -124,13 +156,13 @@ The completion algorithm searches `methods()` from top to bottom and selects the
124156
All of these are equivalent (they all complete to `:collocation, :adnlp, :ipopt, :cpu`):
125157

126158
```julia
127-
solve(ocp) # empty → use first method
128-
solve(ocp, :collocation) # specify discretizer
129-
solve(ocp, :adnlp) # specify modeler
130-
solve(ocp, :ipopt) # specify solver
131-
solve(ocp, :cpu) # specify parameter
132-
solve(ocp, :collocation, :adnlp) # specify discretizer + modeler
133-
solve(ocp, :collocation, :ipopt) # specify discretizer + solver
159+
solve(ocp) # empty → use first method
160+
solve(ocp, :collocation) # specify discretizer
161+
solve(ocp, :adnlp) # specify modeler
162+
solve(ocp, :ipopt) # specify solver
163+
solve(ocp, :cpu) # specify parameter
164+
solve(ocp, :collocation, :adnlp) # specify discretizer + modeler
165+
solve(ocp, :collocation, :ipopt) # specify discretizer + solver
134166
solve(ocp, :collocation, :adnlp, :ipopt, :cpu) # complete description
135167
```
136168

@@ -140,9 +172,9 @@ You can pass options as keyword arguments. They are **automatically routed** to
140172

141173
```@example main
142174
sol = solve(ocp, :madnlp;
143-
grid_size=100, # → discretizer (Collocation)
144-
max_iter=500, # → solver (MadNLP)
145-
print_level=MadNLP.ERROR # → solver (MadNLP)
175+
grid_size=100, # → discretizer (Collocation)
176+
max_iter=500, # → solver (MadNLP)
177+
print_level=MadNLP.ERROR # → solver (MadNLP)
146178
)
147179
nothing # hide
148180
```
@@ -167,82 +199,44 @@ Notice the `📦 Configuration` box showing:
167199

168200
## Strategy options
169201

170-
Each strategy declares its available options. You can inspect them using `describe`:
202+
Each strategy declares its available options. You can inspect them using `describe`.
203+
204+
### Discretizer options
171205

172206
```@example main
173-
using CTDirect, CTSolvers
174-
describe(Collocation)
207+
describe(:collocation)
175208
```
176209

210+
### Modeler options
211+
177212
```@example main
178-
describe(ADNLP)
213+
describe(:adnlp)
179214
```
180215

181216
```@example main
182-
describe(Ipopt)
217+
describe(:exa)
183218
```
184219

185-
Common options include:
186-
187-
**Discretizer (Collocation)**:
188-
189-
- `grid_size` (default: `250`): number of time steps
190-
- `scheme` (default: `:midpoint`): discretization scheme (`:midpoint`, `:trapeze`, `:euler`, `:euler_implicit`, `:gauss_legendre_2`, `:gauss_legendre_3`)
191-
192-
**Modeler (ADNLP)**:
193-
194-
- `backend` (default: `:optimized`): AD backend (`:optimized`, `:manual`, `:default`)
195-
- `show_time` (default: `false`): display model building time
196-
197-
**Solver (Ipopt)**:
198-
199-
- `max_iter` (default: `3000`): maximum iterations
200-
- `tol` (default: `1e-8`): convergence tolerance
201-
- `print_level` (default: `5`): output verbosity (0-12)
202-
203-
For complete option lists, see:
204-
205-
- [Ipopt options](https://coin-or.github.io/Ipopt/OPTIONS.html)
206-
- [MadNLP options](https://madnlp.github.io/MadNLP.jl/stable/options/)
207-
208-
!!! note "ExaModels syntax limitations"
209-
210-
When using `:exa` modeler (especially for [GPU solving](@ref manual-solve-gpu)):
211-
- Dynamics must be declared coordinate-by-coordinate: `∂(q)(t) == v(t)` instead of `ẋ(t) == [v(t), u(t)]`
212-
- Nonlinear constraints must be scalar expressions
213-
- Only ExaModels-supported operations are allowed (see [ExaModels documentation](https://exanauts.github.io/ExaModels.jl/stable))
214-
215-
## Initial guess
216-
217-
Provide an initial guess using `initial_guess` (or the alias `init`):
220+
### Solver options
218221

219222
```@example main
220-
# Using the @init macro (recommended)
221-
init = @init begin
222-
u = 0.5
223-
end
224-
225-
sol = solve(ocp; initial_guess=init, grid_size=50, print_level=0)
226-
nothing # hide
223+
describe(:ipopt)
227224
```
228225

229226
```@example main
230-
# Or using the alias
231-
sol = solve(ocp; init=init, grid_size=50, print_level=0)
232-
nothing # hide
227+
describe(:madnlp)
233228
```
234229

235-
For more details on initial guess specification, see [Set an initial guess](@ref manual-initial-guess).
236-
237-
## Display control
230+
### Official documentation
238231

239-
Control the configuration display with the `display` option:
232+
For complete option lists, see the official documentation:
240233

241-
```@example main
242-
# Suppress all output
243-
sol = solve(ocp; display=false)
244-
nothing # hide
245-
```
234+
- **ADNLP**: [ADNLPModels documentation](https://jso.dev/ADNLPModels.jl/stable/)
235+
- **Exa**: [ExaModels documentation](https://exanauts.github.io/ExaModels.jl/stable/)
236+
- **Ipopt**: [Ipopt options](https://coin-or.github.io/Ipopt/OPTIONS.html)
237+
- **MadNLP**: [MadNLP options](https://madnlp.github.io/MadNLP.jl/stable/options/)
238+
- **MadNCL**: [MadNCL documentation](https://github.com/MadNLP/MadNCL.jl)
239+
- **Knitro**: [Knitro options](https://www.artelys.com/docs/knitro/3_referenceManual/userOptions.html)
246240

247241
## See also
248242

src/OptimalControl.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ include(joinpath(@__DIR__, "helpers", "kwarg_extraction.jl"))
7575
include(joinpath(@__DIR__, "helpers", "print.jl"))
7676
include(joinpath(@__DIR__, "helpers", "methods.jl"))
7777
include(joinpath(@__DIR__, "helpers", "registry.jl"))
78+
include(joinpath(@__DIR__, "helpers", "describe.jl"))
7879
include(joinpath(@__DIR__, "helpers", "component_checks.jl"))
7980
include(joinpath(@__DIR__, "helpers", "strategy_builders.jl"))
8081
include(joinpath(@__DIR__, "helpers", "component_completion.jl"))

src/helpers/describe.jl

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
$(TYPEDSIGNATURES)
3+
4+
Display detailed information about a strategy identified by its symbol.
5+
6+
This is a convenience wrapper around `CTSolvers.describe` that uses OptimalControl's
7+
strategy registry. It shows the strategy's available options, their types, defaults,
8+
and descriptions.
9+
10+
# Arguments
11+
- `strategy_id::Symbol`: Strategy identifier (e.g., `:collocation`, `:adnlp`, `:ipopt`, `:madnlp`)
12+
13+
# Returns
14+
- Nothing (prints to stdout)
15+
16+
# Example
17+
```julia-repl
18+
julia> using OptimalControl
19+
20+
julia> describe(:collocation)
21+
```
22+
23+
# Notes
24+
- For the complete list of options for each strategy, refer to:
25+
- **Collocation**: [CTDirect documentation](https://control-toolbox.org/CTDirect.jl/stable/)
26+
- **ADNLP**: [CTSolvers documentation](https://control-toolbox.org/CTSolvers.jl/stable/)
27+
- **Exa**: [ExaModels documentation](https://exanauts.github.io/ExaModels.jl/stable/)
28+
- **Ipopt**: [Ipopt options](https://coin-or.github.io/Ipopt/OPTIONS.html)
29+
- **MadNLP**: [MadNLP options](https://madnlp.github.io/MadNLP.jl/stable/options/)
30+
- **MadNCL**: [MadNCL documentation](https://github.com/MadNLP/MadNCL.jl)
31+
- **Knitro**: [Knitro options](https://www.artelys.com/docs/knitro/3_referenceManual/userOptions.html)
32+
33+
See also: [`methods`](@ref), [`get_strategy_registry`](@ref), [`solve`](@ref)
34+
"""
35+
function CTSolvers.describe(strategy_id::Symbol)
36+
registry = get_strategy_registry()
37+
CTSolvers.describe(strategy_id, registry)
38+
end

0 commit comments

Comments
 (0)