Skip to content

docs: solve — direct methods, choosing and configuring them - #866

Open
ocots wants to merge 10 commits into
docs/modellingfrom
docs/solve
Open

docs: solve — direct methods, choosing and configuring them#866
ocots wants to merge 10 commits into
docs/modellingfrom
docs/solve

Conversation

@ocots

@ocots ocots commented Aug 20, 2026

Copy link
Copy Markdown
Member

Summary

Stacked on #865 (docs/modelling, not yet merged) — base branch is docs/modelling, not main, since PR 6 depends on PR 5 per the work board. Rebase onto main once #865 merges.

  • Writes the six "Solve" pages (docs/src/solve/), replacing the PR-2 stubs: overview.md, initial-guess.md, choosing-a-method.md (new page, split out of the old combined manual), options.md, explicit-mode.md, gpu.md.
  • Two code fixes bundled in, both scoped by the spec itself (docs/reports/04-solve-direct.md:4):
    • src/helpers/methods.jl's docstring claimed length(methods()) == 11 ("9 CPU + 2 GPU") and methods()[9] == (:collocation, :exa, :madnlp, :gpu). The real tuple has 12 entries (10 CPU + 2 GPU); methods()[9] is a CPU entry, (:collocation, :exa, :madncl, :cpu). Fixed, and choosing-a-method.md now prints methods() live rather than quoting any count.
    • Three module docstrings (src/OptimalControl.jl, src/solve/dispatch.jl, src/solve/canonical.jl) showed CTDirect.Collocation() / CTSolvers.Modelers.ADNLP() / CTSolvers.Solvers.Ipopt() — none re-exported, so undefined under using OptimalControl. Corrected to OptimalControl.Collocation() / OptimalControl.ADNLP() / OptimalControl.Ipopt(), verified to actually resolve.
  • Real findings caught by executing every page for real (Draft = false on 5 of 6 — gpu.md stays Draft = true, no CUDA-capable device in CI or in dev, explained at the top of that page):
    • A genuine inconsistency, not previously documented: supplying both init= and initial_guess= throws a clean "Conflicting aliases" error in explicit mode, but in descriptive mode (the common case) initial_guess is silently consumed first and the leftover init falls through to strategy-option routing, producing a confusing "unknown option :init" error instead. Documented as-is on initial-guess.md; not fixed in src/ since it's outside this PR's declared scope.
    • The same CTModelsPlots plot(sol) bug found in docs: modelling — describe an optimal control problem #865 (CTModels.jl#392) resurfaced once on initial-guess.md — same workaround (explicit description args).
    • strategy_ids/type_from_id/available_parameters (and create_registry) all require a populated StrategyRegistry; the only one with the real built-in strategies is internal (OptimalControl.get_strategy_registry(), not re-exported). Rather than present these as everyday API per the spec's literal "API covered" list, choosing-a-method.md documents this honestly in an "Advanced: the strategy registry" section — methods()/describe cover the same ground for actual callers.
    • Caught mid-review: an early pass of ad-hoc verification accidentally ran against the registered OptimalControl package instead of this worktree's source (LOAD_PATH not replicated outside docs/make.jl). Re-verified every finding once caught — one apparent "bug" (a stray option silently accepted in explicit mode) turned out to be a stale-package artifact and was dropped; the init/initial_guess inconsistency above was re-confirmed as real.

Test plan

  • julia --project=docs docs/make.jl — full rebuild, three iterations to clean: 0 undefined-binding/no-docs/duplicate-docs warnings, all five Draft = false pages' @example blocks execute, gpu.md stays inert as designed, 0 unresolved @refs from these six pages.
  • npx vitepress build on the Documenter output — site builds; spot-checked cross-links into docs: modelling — describe an optimal control problem #865's modelling-abstract-syntax anchor and the results-solution stub anchor resolve correctly in the built HTML.
  • test/suite/flows/test_gpu_routing.jl — 31 passed, 1 broken (expected, GPU-only assertion, no device here).
  • typos — clean.
  • docs/reports/04-solve-direct.md acceptance criteria re-checked against the real build (5/7 ticked; the other 2 left explicitly unticked with reasoning, not silently checked or dropped).

🤖 Generated with Claude Code

ocots and others added 10 commits August 20, 2026 20:14
…uctor paths

methods.jl's docstring claimed 11 methods (9 CPU + 2 GPU); the real
tuple has 12 (10 CPU + 2 GPU), and methods()[9] is a CPU entry, not
GPU. Also fixes three module docstrings that showed
CTDirect.Collocation()/CTSolvers.Modelers.ADNLP()/CTSolvers.Solvers.Ipopt(),
none of which are re-exported and so are undefined under `using
OptimalControl` — corrected to the OptimalControl.* spelling that
actually resolves.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ports the attic manual almost entirely, dropping the legacy
NamedTuple-construction section (still works, just superseded by
@init). Documents a real inconsistency found while verifying live:
supplying both init= and initial_guess= throws a clean
"conflicting aliases" error in explicit mode, but a confusing
"unknown option :init" error in descriptive mode (the common case) —
the two code paths don't share the same conflict check.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Scopes the "API covered" list down to what a caller can actually
reach directly (methods, describe, id, metadata, option_*, parameter,
default_parameter). strategy_ids/type_from_id/available_parameters/
create_registry all require a populated StrategyRegistry, and the
only one with the real built-in strategies is internal
(OptimalControl.get_strategy_registry, not re-exported) — documented
as advanced/orchestration tooling rather than everyday API.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
No CUDA-capable device in CI or in dev environments; loading
CUDA/MadNLPGPU builds CPU-side handles fine but the GPU-parameterized
strategies pull in extensions that only finish loading with real
hardware present. Kept as the one page in this section that does not
flip to Draft = false, with that explained at the top.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
has_option was listed but never invoked on options.md, methods()
likewise on explicit-mode.md, build_initial_guess on
initial-guess.md — add one small live example each so every symbol
in each page's covered-API list actually executes, not just links.
Also fixes the two real build failures from the first pass: the
CTModelsPlots VBox bug (CTModels.jl#392, same as PR 5 — explicit
description= on the affected plot() call) and two unresolved
[`Solution`](@ref) links, retargeted to the results-solution stub
anchor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…rk board

Full julia --project=docs docs/make.jl + npx vitepress build rebuild,
clean: 0 undefined-binding/no-docs/duplicate-docs warnings, all six
solve/ pages' @example blocks execute (gpu.md deliberately excepted,
Draft = true), 0 unresolved @refs from them. test/suite/flows/test_gpu_routing.jl
re-run (31 passed, 1 broken as expected without a GPU). typos clean.

Acceptance criteria ticked against that build; two left honestly
unticked with reasoning (DirectShooting silently omitted per the
page-level spec instruction, not "documented as a limitation"; three
choosing-a-method.md registry functions described in prose rather
than executed, since they need an internal-only populated registry).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant