Skip to content

Commit aa7f075

Browse files
Merge pull request #252 from control-toolbox/0.10.0
0.10.0
2 parents a9d072d + d203fbd commit aa7f075

30 files changed

+873
-31
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "OptimalControl"
22
uuid = "5f98b655-cc9a-415a-b60e-744165666948"
33
authors = ["Olivier Cots <olivier.cots@toulouse-inp.fr>"]
4-
version = "0.9.4"
4+
version = "0.10.0"
55

66
[deps]
77
CTBase = "54762871-cc72-4466-b8e8-f6c8b58076cd"
@@ -12,7 +12,7 @@ DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
1212

1313
[compat]
1414
CTBase = "0.11"
15-
CTDirect = "0.9"
15+
CTDirect = "0.10"
1616
CTFlows = "0.4"
1717
CommonSolve = "0.2"
1818
DocStringExtensions = "0.9"

docs/src/tutorial-nlp.md

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ We describe here some more advanced operations related to the discretized optima
88
When calling `solve(ocp)` three steps are performed internally:
99

1010
- first, the OCP is discretized into a DOCP (a nonlinear optimization problem) with [`direct_transcription`](@ref),
11-
- then, this DOCP is solved,
11+
- then, this DOCP is solved (with the internal function `solve_docp`),
1212
- finally, a functional solution of the OCP is rebuilt from the solution of the discretized problem, with [`build_solution`](@ref).
1313

1414
These steps can also be done separately, for instance if you want to use your own NLP solver. Let us load the modules
@@ -37,23 +37,18 @@ nothing # hide
3737
First let us discretize the problem.
3838

3939
```@example main
40-
docp = direct_transcription(ocp)
40+
docp, nlp = direct_transcription(ocp)
4141
nothing # hide
4242
```
4343

44-
The DOCP contains a copy of the original OCP, and the resulting discretized problem, in our case an `ADNLPModel`.
45-
You can extract this raw NLP problem with the [`get_nlp`](@ref) method.
46-
47-
```@example main
48-
nlp = get_nlp(docp)
49-
```
44+
The DOCP contains information related to the transcription, including a copy of the original OCP, and the NLP is the resulting discretized problem, in our case an `ADNLPModel`.
5045

5146
You could then use the solver of your choice to solve it.
5247
For an example we use the `ipopt` solver from [`NLPModelsIpopt.jl`](https://github.com/JuliaSmoothOptimizers/NLPModelsIpopt.jl) package to solve the NLP problem.
5348

5449
```@example main
5550
using NLPModelsIpopt
56-
nlp_sol = ipopt(get_nlp(docp); print_level=4, mu_strategy="adaptive", tol=1e-8, sb="yes")
51+
nlp_sol = ipopt(nlp; print_level=4, mu_strategy="adaptive", tol=1e-8, sb="yes")
5752
nothing # hide
5853
```
5954

@@ -67,13 +62,13 @@ plot(sol)
6762
An initial guess, including warm start, can be passed to [`direct_transcription`](@ref) the same way as for `solve`.
6863

6964
```@example main
70-
docp = direct_transcription(ocp, init=sol)
65+
docp, nlp = direct_transcription(ocp, init=sol)
7166
nothing # hide
7267
```
7368

7469
It can also be changed after the transcription is done, with [`set_initial_guess`](@ref).
7570

7671
```@example main
77-
set_initial_guess(docp, sol)
72+
set_initial_guess(docp, nlp, sol)
7873
nothing # hide
7974
```

src/OptimalControl.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,13 @@ export *
4242

4343
# CTDirect
4444
export direct_transcription
45-
export get_nlp
4645
export set_initial_guess
4746
export build_solution
4847
export save
4948
export load
5049
export export_ocp_solution
5150
export import_ocp_solution
5251

53-
5452
# CTBase
5553
export Index
5654
export Autonomous, NonAutonomous

src/solve.jl

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,6 @@ julia> sol = solve(ocp, init=(state=t->[-1+t, t*(t-1)], control=t->6-12*t))
6666
```
6767
6868
"""
69-
#=
70-
function solve(ocp::OptimalControlModel, description::Symbol...;
71-
display::Bool=__display(),
72-
init=__ocp_init(),
73-
kwargs...)
74-
=#
75-
76-
7769
function solve(ocp::OptimalControlModel, description::Symbol...;
7870
init=__ocp_init(),
7971
grid_size::Integer=CTDirect.__grid_size_direct(),
@@ -88,17 +80,16 @@ function solve(ocp::OptimalControlModel, description::Symbol...;
8880

8981
# print chosen method
9082
method = getFullDescription(description, available_methods())
91-
display ? println("Method = ", method) : nothing
83+
#display ? println("Method = ", method) : nothing
9284

9385
# if no error before, then the method is correct: no need of else
9486
if :direct method
95-
#return CTDirect.solve(ocp, clean(method)...; display=display, init=init, kwargs...)
9687

9788
# build discretized OCP
98-
docp = direct_transcription(ocp, description, init=init, grid_size=grid_size, time_grid=time_grid)
89+
docp, nlp = direct_transcription(ocp, description, init=init, grid_size=grid_size, time_grid=time_grid)
9990

10091
# solve DOCP (NB. init is already embedded in docp)
101-
docp_solution = CTDirect.solve_docp(docp, display=display, print_level=print_level, mu_strategy=mu_strategy, tol=tol, max_iter=max_iter, linear_solver=linear_solver; kwargs...)
92+
docp_solution = CTDirect.solve_docp(docp, nlp, display=display, print_level=print_level, mu_strategy=mu_strategy, tol=tol, max_iter=max_iter, linear_solver=linear_solver; kwargs...)
10293

10394
# build and return OCP solution
10495
return build_solution(docp, docp_solution)

test/problems/beam.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Beam example from bocop
2+
3+
function beam()
4+
5+
@def beam begin
6+
t [ 0, 1 ], time
7+
x R², state
8+
u R, control
9+
x(0) == [0,1]
10+
x(1) == [0,-1]
11+
(t) == [x₂(t), u(t)]
12+
0 x₁(t) 0.1
13+
-10 u(t) 10
14+
(u(t)^2) min
15+
end
16+
17+
return ((ocp=beam, obj=8.898598, name="beam", init=nothing))
18+
end

test/problems/beam.png

40 KB
Loading

test/problems/bioreactor.jl

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Bioreactor example from bocop
2+
3+
# METHANE PROBLEM
4+
# mu2 according to growth model
5+
# mu according to light model
6+
# time scale is [0,10] for 24h (day then night)
7+
8+
# growth model MONOD
9+
function growth(s, mu2m, Ks)
10+
return mu2m * s / (s+Ks)
11+
end
12+
13+
# light model: max^2 (0,sin) * mubar
14+
# DAY/NIGHT CYCLE: [0,2 halfperiod] rescaled to [0,2pi]
15+
function light(time, halfperiod)
16+
pi = 3.141592653589793
17+
days = time / (halfperiod*2)
18+
tau = (days - floor(days)) * 2*pi
19+
return max(0,sin(tau))^2
20+
end
21+
22+
# 1 day periodic problem
23+
function bioreactor_1day_periodic()
24+
@def bioreactor_1 begin
25+
# constants
26+
beta = 1
27+
c = 2
28+
gamma = 1
29+
Ks = 0.05
30+
mu2m = 0.1
31+
mubar = 1
32+
r = 0.005
33+
halfperiod = 5
34+
T = halfperiod * 2
35+
36+
# ocp
37+
t [ 0, T ], time
38+
x R³, state
39+
u R, control
40+
y = x[1]
41+
s = x[2]
42+
b = x[3]
43+
mu = light(t, halfperiod) * mubar
44+
mu2 = growth(s(t), mu2m, Ks)
45+
[0,0,0.001] x(t) [Inf, Inf, Inf]
46+
0 u(t) 1
47+
1 y(0) Inf
48+
1 b(0) Inf
49+
x(0)- x(T) == [0,0,0]
50+
(t) == [mu*y(t)/(1+y(t))-(r+u(t))*y(t),
51+
-mu2*b(t) + u(t)*beta*(gamma*y(t)-s(t)),
52+
(mu2-u(t)*beta)*b(t)]
53+
(mu2*b(t)/(beta+c)) max
54+
end
55+
56+
return ((ocp=bioreactor_1, obj=0.614134, name="bioreactor_1day_periodic", init=nothing))
57+
end
58+
59+
60+
# N days (non periodic)
61+
function bioreactor_Ndays()
62+
@def bioreactor_N begin
63+
# constants
64+
beta = 1
65+
c = 2
66+
gamma = 1
67+
halfperiod = 5
68+
Ks = 0.05
69+
mu2m = 0.1
70+
mubar = 1
71+
r = 0.005
72+
N = 30
73+
T = 10 * N
74+
75+
# ocp
76+
t [ 0, T ], time
77+
x R³, state
78+
u R, control
79+
y = x[1]
80+
s = x[2]
81+
b = x[3]
82+
mu = light(t, halfperiod) * mubar
83+
mu2 = growth(s(t), mu2m, Ks)
84+
[0,0,0.001] x(t) [Inf, Inf, Inf]
85+
0 u(t) 1
86+
0.05 y(0) 0.25
87+
0.5 s(0) 5
88+
0.5 b(0) 3
89+
(t) == [mu*y(t)/(1+y(t))-(r+u(t))*y(t),
90+
-mu2*b(t) + u(t)*beta*(gamma*y(t)-s(t)),
91+
(mu2-u(t)*beta)*b(t)]
92+
(mu2*b(t)/(beta+c)) max
93+
end
94+
95+
return ((ocp=bioreactor_N, obj=19.0745, init=(state=[50,50,50],), name="bioreactor_Ndays"))
96+
end
82.8 KB
Loading

test/problems/bioreactor_Ndays.png

62.1 KB
Loading

test/problems/fuller.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Fuller example
2+
function fuller()
3+
4+
@def fuller begin
5+
t [ 0, 3.5 ], time
6+
x R², state
7+
u R, control
8+
-1 u(t) 1
9+
x(0) == [ 0, 1 ]
10+
x(3.5) == [ 0, 0 ]
11+
(t) == [ x₂(t), u(t) ]
12+
(x₁(t)^2) min
13+
end
14+
15+
return((ocp=fuller, obj=2.683944e-1, name="fuller", init=nothing))
16+
end

0 commit comments

Comments
 (0)