Skip to content

Commit 621d670

Browse files
committed
chore: release v2.0.0 with CHANGELOG and BREAKING.md
- Bump version to 2.0.0 in Project.toml - Add comprehensive CHANGELOG entry for v2.0.0 - Create BREAKING.md documenting migration from v1.1.6 to v2.0.0 Major changes: - Complete solve architecture redesign (descriptive/explicit modes) - GPU/CPU parameter system with 4-tuple methods - Advanced option routing (describe, route_to, bypass) - New solvers: Uno, MadNCL - Control-free problems support - @init macro for initial guess - Additional discretization schemes Breaking changes: - Removed: direct_transcription, set_initial_guess, build_OCP_solution - Changed exports: CTBase exceptions, CTFlows types - New solve architecture with 4-tuple methods See BREAKING.md for detailed migration guide.
1 parent 3fd68f1 commit 621d670

File tree

3 files changed

+369
-1
lines changed

3 files changed

+369
-1
lines changed

BREAKING.md

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
# Breaking Changes: v1.x → v2.0
2+
3+
This document describes the breaking changes when migrating from **OptimalControl.jl v1.1.6** (last stable release) to **v2.0.0**.
4+
5+
## Overview
6+
7+
Version 2.0.0 represents a major architectural redesign of OptimalControl.jl, introducing:
8+
9+
- **Complete solve architecture redesign** with descriptive and explicit modes
10+
- **GPU/CPU parameter system** for heterogeneous computing
11+
- **Advanced option routing** with introspection and disambiguation tools
12+
- **New solver integrations** (Uno, MadNCL)
13+
- **Control-free problems** support
14+
- **Modernized reexport system** using `@reexport import`
15+
16+
## Removed Functions
17+
18+
The following functions from v1.1.6 have been removed and replaced:
19+
20+
### CTDirect Functions
21+
22+
| v1.1.6 Function | v2.0.0 Replacement | Notes |
23+
| ---------------------- | ------------------ | ------------------------------------------------------ |
24+
| `direct_transcription` | `discretize` | New function from CTDirect.jl |
25+
| `set_initial_guess` | `@init` macro | Use the `@init` macro for initial guess construction |
26+
| `build_OCP_solution` | `ocp_solution` | New function from CTSolvers.jl |
27+
28+
**Migration example:**
29+
30+
```julia
31+
# v1.1.6
32+
docp = direct_transcription(ocp, grid_size=100)
33+
set_initial_guess(docp, x_init, u_init)
34+
sol = build_OCP_solution(docp, nlp_sol)
35+
36+
# v2.0.0
37+
docp = discretize(ocp, Collocation(); grid_size=100)
38+
init = @init ocp begin
39+
x = x_init
40+
u = u_init
41+
end
42+
sol = ocp_solution(docp, nlp_sol)
43+
```
44+
45+
## Changed Exports
46+
47+
### CTBase Exceptions
48+
49+
**Removed exports:**
50+
51+
- `IncorrectMethod`
52+
- `IncorrectOutput`
53+
- `UnauthorizedCall`
54+
55+
**Added exports:**
56+
57+
- `PreconditionError`
58+
59+
These exceptions are still available via `CTBase.IncorrectMethod`, etc., but are no longer re-exported by OptimalControl.jl.
60+
61+
### CTFlows Types
62+
63+
The following types are **no longer exported** (but still available via qualified access):
64+
65+
- `VectorField` → use `OptimalControl.VectorField` or `CTFlows.VectorField`
66+
- `Hamiltonian` → use `OptimalControl.Hamiltonian` or `CTFlows.Hamiltonian`
67+
- `HamiltonianLift` → use `OptimalControl.HamiltonianLift` or `CTFlows.HamiltonianLift`
68+
- `HamiltonianVectorField` → use `OptimalControl.HamiltonianVectorField` or `CTFlows.HamiltonianVectorField`
69+
70+
**Migration example:**
71+
72+
```julia
73+
# v1.1.6
74+
X = VectorField(f)
75+
76+
# v2.0.0
77+
X = OptimalControl.VectorField(f)
78+
# or
79+
using CTFlows: VectorField
80+
X = VectorField(f)
81+
```
82+
83+
## New Solve Architecture
84+
85+
The `solve` function has been completely redesigned with two modes:
86+
87+
### Descriptive Mode (Symbolic)
88+
89+
```julia
90+
# Specify strategies using symbols
91+
sol = solve(ocp, :collocation, :adnlp, :ipopt, :cpu)
92+
93+
# Partial specification (auto-completed)
94+
sol = solve(ocp, :ipopt) # Uses first matching method
95+
sol = solve(ocp, :gpu) # Uses first GPU method
96+
```
97+
98+
### Explicit Mode (Typed Components)
99+
100+
```julia
101+
# Specify strategies using typed components
102+
sol = solve(ocp;
103+
discretizer=Collocation(),
104+
modeler=ADNLP(),
105+
solver=Ipopt()
106+
)
107+
```
108+
109+
### Methods System
110+
111+
The `methods()` function now returns **4-tuples** instead of 3-tuples:
112+
113+
```julia
114+
# v1.1.6
115+
methods() # Returns (discretizer, modeler, solver)
116+
117+
# v2.0.0
118+
methods() # Returns (discretizer, modeler, solver, parameter)
119+
# Example: (:collocation, :adnlp, :ipopt, :cpu)
120+
```
121+
122+
The 4th element is the **parameter** (`:cpu` or `:gpu`) for execution backend.
123+
124+
## Option Routing System
125+
126+
v2.0.0 introduces automatic option routing with new introspection tools:
127+
128+
### New Functions
129+
130+
- `describe(strategy)` — Display available options for a strategy
131+
- `route_to(strategy=value)` — Disambiguate shared options
132+
- `bypass(option=value)` — Pass undeclared options to strategies
133+
134+
**Example:**
135+
136+
```julia
137+
# Inspect available options
138+
describe(:ipopt)
139+
describe(:collocation)
140+
141+
# Disambiguate shared options
142+
sol = solve(ocp, :ipopt;
143+
max_iter=100, # Shared option (auto-routed)
144+
route_to(solver=:print_level=>0) # Explicitly route to solver
145+
)
146+
147+
# Pass undeclared options
148+
sol = solve(ocp, :ipopt;
149+
bypass(solver=:custom_option=>42)
150+
)
151+
```
152+
153+
## Initial Guess with @init Macro
154+
155+
v2.0.0 introduces the `@init` macro for constructing initial guesses:
156+
157+
```julia
158+
# v2.0.0
159+
init = @init ocp begin
160+
u = 0.5
161+
x = [1.0, 2.0]
162+
end
163+
164+
sol = solve(ocp; initial_guess=init)
165+
# or using alias
166+
sol = solve(ocp; init=init)
167+
```
168+
169+
The old functional approach is no longer supported.
170+
171+
## New Features (Non-Breaking)
172+
173+
These features are new in v2.0.0 but don't break existing code:
174+
175+
### Control-Free Problems
176+
177+
Support for optimal control problems without control variables:
178+
179+
```julia
180+
ocp = @def begin
181+
tf R, variable
182+
t [0, tf], time
183+
x R², state
184+
(t) == f(x(t)) # No control
185+
(L(x(t))) min
186+
end
187+
```
188+
189+
### New Solvers
190+
191+
- **Uno**: CPU-only nonlinear optimization solver
192+
- **MadNCL**: GPU-capable solver
193+
194+
Total of 5 solvers: Ipopt, MadNLP, Uno, MadNCL, Knitro
195+
196+
### Additional Discretization Schemes
197+
198+
**Basic schemes:**
199+
200+
- `:trapeze` — Trapezoidal rule
201+
- `:midpoint` — Midpoint rule
202+
- `:euler` / `:euler_explicit` / `:euler_forward` — Explicit Euler
203+
- `:euler_implicit` / `:euler_backward` — Implicit Euler
204+
205+
**ADNLP-only schemes:**
206+
207+
- `:gauss_legendre_2` — 2-point Gauss-Legendre collocation
208+
- `:gauss_legendre_3` — 3-point Gauss-Legendre collocation
209+
210+
### GPU Support
211+
212+
Explicit GPU/CPU selection via parameter:
213+
214+
```julia
215+
# CPU execution (default)
216+
sol = solve(ocp, :collocation, :adnlp, :ipopt, :cpu)
217+
218+
# GPU execution (requires ExaModels + MadNLP/MadNCL)
219+
using CUDA, MadNLPGPU
220+
sol = solve(ocp, :collocation, :exa, :madnlp, :gpu)
221+
```
222+
223+
## Dependency Updates
224+
225+
v2.0.0 requires updated versions of CTX packages:
226+
227+
| Package | v1.1.6 | v2.0.0 |
228+
| --------- | --------- | ------ |
229+
| CTBase | 0.16-0.17 | 0.18 |
230+
| CTModels | 0.6 | 0.9 |
231+
| CTDirect | 0.x | 1.0 |
232+
| CTSolvers | N/A | 0.4 |
233+
| CTParser | 0.7-0.8 | 0.8 |
234+
235+
**New dependency:** CTSolvers.jl (handles NLP modeling and solving)
236+
237+
## Summary
238+
239+
The main breaking changes are:
240+
241+
1. **Removed functions**: `direct_transcription`, `set_initial_guess`, `build_OCP_solution`
242+
2. **Changed exports**: Some CTBase exceptions and CTFlows types no longer exported
243+
3. **New solve architecture**: Descriptive/explicit modes with 4-tuple methods
244+
4. **Initial guess**: Use `@init` macro instead of functional approach
245+
246+
For detailed usage examples, see the [documentation](https://control-toolbox.org/OptimalControl.jl/stable/).

CHANGELOG.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,128 @@ Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
---
99

10+
## [2.0.0] — 2026-04-03
11+
12+
**Major version release** with complete solve architecture redesign. This release introduces breaking changes from v1.1.6 (last stable release). See [BREAKING.md](BREAKING.md) for detailed migration guide.
13+
14+
### Breaking Changes
15+
16+
- **Removed functions** from v1.1.6:
17+
- `direct_transcription` → replaced by `discretize`
18+
- `set_initial_guess` → replaced by `@init` macro
19+
- `build_OCP_solution` → replaced by `ocp_solution`
20+
21+
- **Changed exports**:
22+
- CTBase exceptions: removed `IncorrectMethod`, `IncorrectOutput`, `UnauthorizedCall`; added `PreconditionError`
23+
- CTFlows types: `VectorField`, `Hamiltonian`, `HamiltonianLift`, `HamiltonianVectorField` no longer exported (use qualified access)
24+
25+
- **New solve architecture**:
26+
- `methods()` now returns 4-tuples `(discretizer, modeler, solver, parameter)` instead of 3-tuples
27+
- Parameter (`:cpu` or `:gpu`) is now required for complete method specification
28+
29+
### Added
30+
31+
- **Complete solve architecture redesign**:
32+
- **Descriptive mode**: `solve(ocp, :collocation, :adnlp, :ipopt, :cpu)` with symbolic strategy specification
33+
- **Explicit mode**: `solve(ocp; discretizer=Collocation(), modeler=ADNLP(), solver=Ipopt())` with typed components
34+
- **Partial specification**: Auto-completion of missing strategies using first matching method
35+
- **Method introspection**: `methods()` lists all available solving methods
36+
37+
- **GPU/CPU parameter system**:
38+
- 4th parameter in method tuples for execution backend (`:cpu` or `:gpu`)
39+
- Explicit GPU support via `:gpu` parameter with ExaModels + MadNLP/MadNCL
40+
- 12 total methods: 10 CPU methods + 2 GPU methods
41+
42+
- **Advanced option routing system**:
43+
- `describe(strategy)`: Display available options for any strategy (discretizer, modeler, solver)
44+
- `route_to(strategy=option=>value)`: Disambiguate shared options between strategies
45+
- `bypass(strategy=option=>value)`: Pass undeclared options to strategies
46+
- Automatic option routing to appropriate components
47+
- Option introspection: `options()`, `option_names()`, `option_type()`, `option_description()`, `option_default()`
48+
49+
- **Initial guess with @init macro**:
50+
- New `@init` macro for constructing initial guesses
51+
- Alias `init` for `initial_guess` keyword argument in solve
52+
- Replaces functional initial guess construction from v1.1.6
53+
54+
- **Control-free problems support**:
55+
- Optimal control problems without control variables
56+
- Optimization of constant parameters in dynamical systems
57+
- Full integration with solve pipeline
58+
59+
- **New solvers**:
60+
- **Uno**: CPU-only nonlinear optimization solver (methods with `:uno`)
61+
- **MadNCL**: GPU-capable solver (methods with `:madncl`)
62+
- Total of 5 solvers: Ipopt, MadNLP, Uno, MadNCL, Knitro
63+
64+
- **Additional discretization schemes**:
65+
- Basic schemes: `:trapeze`, `:midpoint`, `:euler` (and aliases), `:euler_implicit` (and aliases)
66+
- ADNLP-specific schemes: `:gauss_legendre_2`, `:gauss_legendre_3` (high-order collocation)
67+
68+
- **Comprehensive documentation rewrite**:
69+
- New solve manual with descriptive/explicit modes
70+
- Advanced options guide with routing and disambiguation
71+
- GPU solving guide
72+
- Initial guess guide with `@init` macro
73+
- Differential geometry tools manual
74+
- Control-free problems example
75+
76+
- **Modernized reexport system**:
77+
- Using `@reexport import` from Reexport.jl
78+
- Organized by source package (ctbase.jl, ctdirect.jl, ctflows.jl, ctmodels.jl, ctparser.jl, ctsolvers.jl)
79+
- Cleaner separation between imported and exported symbols
80+
81+
- **Strategy registry system**:
82+
- `StrategyRegistry` with metadata for all strategies
83+
- `StrategyMetadata` with id, options, and parameter support
84+
- `OptionDefinition` with type, default, description, and aliases
85+
- Dependency injection support for testing
86+
87+
### Changed
88+
89+
- **Solve function signatures**:
90+
- Layer 3 (canonical): `solve(ocp, strategies...; kwargs...)`
91+
- Layer 2 descriptive: `solve_descriptive(ocp, strategies...; kwargs...)`
92+
- Layer 2 explicit: `solve_explicit(ocp; discretizer, modeler, solver, kwargs...)`
93+
- Automatic mode detection based on argument types
94+
95+
- **Component completion**:
96+
- Intelligent completion of missing strategies using registry
97+
- First-match priority from `methods()` list
98+
- Support for partial method specifications
99+
100+
- **Display system**:
101+
- Configuration box showing applied strategies and options
102+
- Option source tracking (user, default, computed)
103+
- Parameter display for GPU/CPU distinction
104+
- Improved formatting and clarity
105+
106+
- **Test infrastructure**:
107+
- Comprehensive test suite for solve pipeline (422+ tests)
108+
- Integration tests with real strategies
109+
- Mock registry for dispatch testing
110+
- Parametric mocks for strategy testing
111+
- Level 3 signature freezing tests for API stability
112+
113+
### Dependencies
114+
115+
- **CTBase**: 0.18.x (was 0.16-0.17)
116+
- **CTModels**: 0.9.x (was 0.6.x)
117+
- **CTDirect**: 1.x (was 0.x)
118+
- **CTSolvers**: 0.4.x (new dependency)
119+
- **CTParser**: 0.8.x (was 0.7-0.8)
120+
- **CTFlows**: 0.8.x
121+
122+
**New dependency**: CTSolvers.jl handles NLP modeling, solving, and strategy orchestration.
123+
124+
### Notes
125+
126+
This release consolidates all beta versions (1.2.0-beta through 1.3.1-beta) into a stable 2.0.0 release. The comparison is made against v1.1.6, the last stable release before the architectural redesign.
127+
128+
For users migrating from v1.1.6, please consult [BREAKING.md](BREAKING.md) for detailed migration instructions and examples.
129+
130+
---
131+
10132
## [1.3.1-beta] — 2026-03-17
11133

12134
### Added

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "OptimalControl"
22
uuid = "5f98b655-cc9a-415a-b60e-744165666948"
3-
version = "1.3.3-beta"
3+
version = "2.0.0"
44
authors = ["Olivier Cots <olivier.cots@toulouse-inp.fr>"]
55

66
[deps]

0 commit comments

Comments
 (0)