Skip to content

Commit dca329e

Browse files
committed
feat: Complete restructure of src/ directory architecture
- Remove src/core/ directory entirely - Reorganize types into logical groups: * src/types/ - Base types (aliases, export/import) * src/ocp/types/ - OCP-specific types * src/nlp/types/ - NLP types * src/init/types/ - Initial guess types - Split utils into thematic files: * src/utils/interpolation.jl * src/utils/matrix_utils.jl * src/utils/function_utils.jl * src/utils/macros.jl - Refactor CTModels.jl from 285 to 113 lines with: * Logical dependency order * Detailed comments explaining each section * Clear separation of types vs implementations - Update documentation to reflect new structure - All tests pass and compilation successful This restructure improves maintainability, clarity, and follows single responsibility principle for each directory and file.
1 parent 6b07042 commit dca329e

20 files changed

Lines changed: 419 additions & 352 deletions

docs/api_reference.jl

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,42 @@ function generate_api_reference(src_dir::String, ext_dir::String)
4343
filename="ctmodels",
4444
),
4545
# ───────────────────────────────────────────────────────────────────
46-
# Core: Types
46+
# Core: OCP Types
4747
# ───────────────────────────────────────────────────────────────────
4848
CTBase.automatic_reference_documentation(;
4949
subdirectory=".",
5050
primary_modules=[
5151
CTModels => src(
52-
"core/types.jl",
53-
"core/types/ocp_model.jl",
54-
"core/types/ocp_components.jl",
55-
"core/types/ocp_solution.jl",
56-
"core/types/initial_guess.jl",
57-
"core/types/nlp.jl",
52+
"ocp/types/components.jl",
53+
"ocp/types/model.jl",
54+
"ocp/types/solution.jl",
5855
),
5956
],
6057
exclude=EXCLUDE_SYMBOLS,
6158
public=false,
6259
private=true,
63-
title="Types",
64-
title_in_menu="Types",
65-
filename="types",
60+
title="OCP Types",
61+
title_in_menu="OCP Types",
62+
filename="ocp_types",
63+
),
64+
# ───────────────────────────────────────────────────────────────────
65+
# Base Types & Export/Import
66+
# ───────────────────────────────────────────────────────────────────
67+
CTBase.automatic_reference_documentation(;
68+
subdirectory=".",
69+
primary_modules=[
70+
CTModels => src(
71+
"types/aliases.jl",
72+
"types/export_import.jl",
73+
"types/export_import_functions.jl",
74+
),
75+
],
76+
exclude=EXCLUDE_SYMBOLS,
77+
public=false,
78+
private=true,
79+
title="Base Types & Export/Import",
80+
title_in_menu="Base Types & Export/Import",
81+
filename="base_types_export_import",
6682
),
6783
# ───────────────────────────────────────────────────────────────────
6884
# Options Module - Public API
@@ -229,17 +245,25 @@ function generate_api_reference(src_dir::String, ext_dir::String)
229245
filename="orchestration_internal",
230246
),
231247
# ───────────────────────────────────────────────────────────────────
232-
# Core: Default & Utils
248+
# Defaults & Utils
233249
# ───────────────────────────────────────────────────────────────────
234250
CTBase.automatic_reference_documentation(;
235251
subdirectory=".",
236-
primary_modules=[CTModels => src("core/default.jl", "core/utils.jl")],
252+
primary_modules=[
253+
CTModels => src(
254+
"ocp/defaults.jl",
255+
"utils/interpolation.jl",
256+
"utils/matrix_utils.jl",
257+
"utils/function_utils.jl",
258+
"utils/macros.jl",
259+
),
260+
],
237261
exclude=EXCLUDE_SYMBOLS,
238262
public=false,
239263
private=true,
240-
title="Default & Utils",
241-
title_in_menu="Default & Utils",
242-
filename="default_utils",
264+
title="Defaults & Utils",
265+
title_in_menu="Defaults & Utils",
266+
filename="defaults_utils",
243267
),
244268
# ───────────────────────────────────────────────────────────────────
245269
# OCP: Model (model, definition, time_dependence)

src/CTModels.jl

Lines changed: 52 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -37,225 +37,45 @@ using .Strategies
3737
include("Orchestration/Orchestration.jl")
3838
using .Orchestration
3939

40-
# aliases
40+
# ============================================================================ #
41+
# TYPES AND FOUNDATIONS
42+
# ============================================================================ #
43+
# Load fundamental types first as they have no dependencies and are used
44+
# everywhere in the codebase.
45+
46+
# 1. Type aliases (Dimension, ctNumber, Time, etc.) and export/import types
47+
# These are the most basic types with no dependencies
48+
include("types/types.jl")
49+
50+
# 2. OCP defaults (functions returning default values)
51+
# Depends on: type aliases (uses Dimension, ctVector, etc.)
52+
include(joinpath(@__DIR__, "ocp", "defaults.jl"))
53+
54+
# 3. Utility functions (interpolation, matrix operations, macros)
55+
# Depends on: type aliases (uses ctNumber, etc.)
56+
# Must be loaded before OCP types because @ensure macro is used in OCP types
57+
include(joinpath(@__DIR__, "utils", "utils.jl"))
58+
59+
# 4. OCP type definitions (components, model, solution)
60+
# Depends on: type aliases, defaults, and utils (@ensure macro)
61+
include(joinpath(@__DIR__, "ocp", "types", "components.jl"))
62+
include(joinpath(@__DIR__, "ocp", "types", "model.jl"))
63+
include(joinpath(@__DIR__, "ocp", "types", "solution.jl"))
64+
65+
# 5. NLP types (backends, builders, modelers)
66+
# Depends on: OCP types (uses AbstractModel, AbstractSolution)
67+
include(joinpath(@__DIR__, "nlp", "types.jl"))
68+
69+
# 6. Export/import functions (require OCP types)
70+
# Depends on: OCP types (uses AbstractModel, AbstractSolution)
71+
include(joinpath(@__DIR__, "types", "export_import_functions.jl"))
72+
73+
# ============================================================================ #
74+
# COMPATIBILITY ALIASES
75+
# ============================================================================ #
76+
# Aliases for CTSolvers compatibility
77+
# Depends on: OCP types
4178

42-
"""
43-
Type alias for a dimension. This is used to define the dimension of the state space,
44-
the costate space, the control space, etc.
45-
46-
```@example
47-
julia> const Dimension = Integer
48-
```
49-
"""
50-
const Dimension = Int
51-
52-
"""
53-
Type alias for a real number.
54-
55-
```@example
56-
julia> const ctNumber = Real
57-
```
58-
"""
59-
const ctNumber = Real
60-
61-
"""
62-
Type alias for a time.
63-
64-
```@example
65-
julia> const Time = ctNumber
66-
```
67-
68-
See also: [`ctNumber`](@ref), [`Times`](@ref CTModels.Times), [`TimesDisc`](@ref).
69-
"""
70-
const Time = ctNumber
71-
72-
"""
73-
Type alias for a vector of real numbers.
74-
75-
```@example
76-
julia> const ctVector = AbstractVector{<:ctNumber}
77-
```
78-
79-
See also: [`ctNumber`](@ref).
80-
"""
81-
const ctVector = AbstractVector{<:ctNumber}
82-
83-
"""
84-
Type alias for a vector of times.
85-
86-
```@example
87-
julia> const Times = AbstractVector{<:Time}
88-
```
89-
90-
See also: [`Time`](@ref), [`TimesDisc`](@ref).
91-
"""
92-
const Times = AbstractVector{<:Time}
93-
94-
"""
95-
Type alias for a grid of times. This is used to define a discretization of time interval given to solvers.
96-
97-
```@example
98-
julia> const TimesDisc = Union{Times, StepRangeLen}
99-
```
100-
101-
See also: [`Time`](@ref), [`Times`](@ref CTModels.Times).
102-
"""
103-
const TimesDisc = Union{Times,StepRangeLen}
104-
105-
"""
106-
Type alias for a dictionary of constraints. This is used to store constraints before building the model.
107-
108-
```@example
109-
julia> const TimesDisc = Union{Times, StepRangeLen}
110-
```
111-
112-
See also: [`ConstraintsModel`](@ref), [`PreModel`](@ref) and [`Model`](@ref CTModels.Model).
113-
"""
114-
const ConstraintsDictType = OrderedDict{
115-
Symbol,Tuple{Symbol,Union{Function,OrdinalRange{<:Int}},ctVector,ctVector}
116-
}
117-
118-
#
119-
include(joinpath(@__DIR__, "core", "default.jl"))
120-
121-
#
122-
include(joinpath(@__DIR__, "core", "utils.jl"))
123-
include(joinpath(@__DIR__, "core", "types.jl"))
124-
125-
# export / import
126-
"""
127-
$(TYPEDEF)
128-
129-
Abstract type for export/import functions, used to choose between JSON or JLD extensions.
130-
"""
131-
abstract type AbstractTag end
132-
133-
"""
134-
$(TYPEDEF)
135-
136-
JLD tag for export/import functions.
137-
"""
138-
struct JLD2Tag <: AbstractTag end
139-
140-
"""
141-
$(TYPEDEF)
142-
143-
JSON tag for export/import functions.
144-
"""
145-
struct JSON3Tag <: AbstractTag end
146-
147-
# -----------------------------
148-
# to be extended
149-
function RecipesBase.plot(sol::AbstractSolution, description::Symbol...; kwargs...)
150-
throw(CTBase.ExtensionError(:Plots))
151-
end
152-
153-
function export_ocp_solution(::JLD2Tag, ::AbstractSolution; filename::String)
154-
throw(CTBase.ExtensionError(:JLD2))
155-
end
156-
157-
function import_ocp_solution(::JLD2Tag, ::AbstractModel; filename::String)
158-
throw(CTBase.ExtensionError(:JLD2))
159-
end
160-
161-
function export_ocp_solution(::JSON3Tag, ::AbstractSolution; filename::String)
162-
throw(CTBase.ExtensionError(:JSON3))
163-
end
164-
165-
function import_ocp_solution(::JSON3Tag, ::AbstractModel; filename::String)
166-
throw(CTBase.ExtensionError(:JSON3))
167-
end
168-
169-
"""
170-
export_ocp_solution(sol; format=:JLD, filename="solution")
171-
172-
Export an optimal control solution to a file.
173-
174-
# Arguments
175-
- `sol::AbstractSolution`: The solution to export.
176-
177-
# Keyword Arguments
178-
- `format::Symbol=:JLD`: Export format, either `:JLD` or `:JSON`.
179-
- `filename::String="solution"`: Base filename (extension added automatically).
180-
181-
# Notes
182-
Requires loading the appropriate package (`JLD2` or `JSON3`) before use.
183-
184-
See also: [`import_ocp_solution`](@ref)
185-
"""
186-
function export_ocp_solution(
187-
sol::AbstractSolution;
188-
format::Symbol=__format(),
189-
filename::String=__filename_export_import(),
190-
)
191-
if format == :JLD
192-
return export_ocp_solution(JLD2Tag(), sol; filename=filename)
193-
elseif format == :JSON
194-
return export_ocp_solution(JSON3Tag(), sol; filename=filename)
195-
else
196-
throw(
197-
CTBase.IncorrectArgument(
198-
"unknown format (should be :JLD or :JSON): " * string(format)
199-
),
200-
)
201-
end
202-
end
203-
204-
"""
205-
import_ocp_solution(ocp; format=:JLD, filename="solution")
206-
207-
Import an optimal control solution from a file.
208-
209-
# Arguments
210-
- `ocp::AbstractModel`: The model associated with the solution.
211-
212-
# Keyword Arguments
213-
- `format::Symbol=:JLD`: Import format, either `:JLD` or `:JSON`.
214-
- `filename::String="solution"`: Base filename (extension added automatically).
215-
216-
# Returns
217-
- `Solution`: The imported solution.
218-
219-
# Notes
220-
Requires loading the appropriate package (`JLD2` or `JSON3`) before use.
221-
222-
See also: [`export_ocp_solution`](@ref)
223-
"""
224-
function import_ocp_solution(
225-
ocp::AbstractModel;
226-
format::Symbol=__format(),
227-
filename::String=__filename_export_import(),
228-
)
229-
if format == :JLD
230-
return import_ocp_solution(JLD2Tag(), ocp; filename=filename)
231-
elseif format == :JSON
232-
return import_ocp_solution(JSON3Tag(), ocp; filename=filename)
233-
else
234-
throw(
235-
CTBase.IncorrectArgument(
236-
"unknown format (should be :JLD or :JSON): " * string(format)
237-
),
238-
)
239-
end
240-
end
241-
242-
#
243-
#include("init.jl")
244-
include(joinpath(@__DIR__, "ocp", "dual_model.jl"))
245-
include(joinpath(@__DIR__, "ocp", "state.jl"))
246-
include(joinpath(@__DIR__, "ocp", "control.jl"))
247-
include(joinpath(@__DIR__, "ocp", "variable.jl"))
248-
include(joinpath(@__DIR__, "ocp", "times.jl"))
249-
include(joinpath(@__DIR__, "ocp", "dynamics.jl"))
250-
include(joinpath(@__DIR__, "ocp", "objective.jl"))
251-
include(joinpath(@__DIR__, "ocp", "constraints.jl"))
252-
include(joinpath(@__DIR__, "ocp", "time_dependence.jl"))
253-
include(joinpath(@__DIR__, "ocp", "definition.jl"))
254-
include(joinpath(@__DIR__, "ocp", "print.jl"))
255-
include(joinpath(@__DIR__, "ocp", "model.jl"))
256-
include(joinpath(@__DIR__, "ocp", "solution.jl"))
257-
258-
# new from CTSolvers
25979
"""
26080
Type alias for [`AbstractModel`](@ref).
26181
@@ -270,11 +90,25 @@ Provides compatibility with CTSolvers naming conventions.
27090
"""
27191
const AbstractOptimalControlSolution = CTModels.AbstractSolution
27292

93+
# ============================================================================ #
94+
# IMPLEMENTATIONS
95+
# ============================================================================ #
96+
# Load implementations after all types are defined
97+
98+
# 6. OCP implementations (dynamics, constraints, model building, etc.)
99+
# Depends on: all OCP types
100+
include(joinpath(@__DIR__, "ocp", "ocp.jl"))
101+
102+
# 7. NLP implementations (problem core, backends, discretization)
103+
# Depends on: OCP and NLP types
273104
include(joinpath(@__DIR__, "nlp", "problem_core.jl"))
274105
include(joinpath(@__DIR__, "nlp", "nlp_backends.jl"))
275106
include(joinpath(@__DIR__, "nlp", "extract_solver_infos.jl"))
276107
include(joinpath(@__DIR__, "nlp", "discretized_ocp.jl"))
277108
include(joinpath(@__DIR__, "nlp", "model_api.jl"))
109+
# 8. Initialization (types and functions for initial guesses)
110+
# Depends on: OCP types (uses AbstractModel, AbstractSolution)
111+
include(joinpath(@__DIR__, "init", "types.jl"))
278112
include(joinpath(@__DIR__, "init", "initial_guess.jl"))
279113

280114
end

src/core/types.jl

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)