Private API

This page lists non-exported (internal) symbols of OptimalControl.


From OptimalControl

DescriptiveMode

OptimalControl.DescriptiveModeType
struct DescriptiveMode <: OptimalControl.SolveMode

Sentinel type indicating that the user provided a symbolic description.

An instance DescriptiveMode() is returned by _explicit_or_descriptive when no explicit components are found in kwargs.

Notes

  • This is a zero-field struct used purely for dispatch
  • Enables type-stable routing without runtime branching
  • Part of the solve architecture's mode detection system

See also: SolveMode, ExplicitMode, _explicit_or_descriptive

ExplicitMode

OptimalControl.ExplicitModeType
struct ExplicitMode <: OptimalControl.SolveMode

Sentinel type indicating that the user provided explicit resolution components.

An instance ExplicitMode() is returned by _explicit_or_descriptive when at least one of discretizer, modeler, or solver is present in kwargs with the correct abstract type.

Notes

  • This is a zero-field struct used purely for dispatch
  • Enables type-stable routing without runtime branching
  • Part of the solve architecture's mode detection system

See also: SolveMode, DescriptiveMode, _explicit_or_descriptive

SolveMode

_DEFAULT_DISPLAY

OptimalControl._DEFAULT_DISPLAYConstant
_DEFAULT_DISPLAY::Bool

Default value for the display action option in solve functions.

When true, the solve configuration and method information will be displayed to the user during the solving process.

Value

  • true: Display solve configuration (default)
  • false: Suppress configuration display

See also: _route_descriptive_options, solve

_DEFAULT_INITIAL_GUESS

OptimalControl._DEFAULT_INITIAL_GUESSConstant
_DEFAULT_INITIAL_GUESS::Nothing

Default value for the initial_guess action option in solve functions.

When nothing, no initial guess is provided and the solver will use its default initialization strategy.

Value

  • nothing: No initial guess provided (default)

See also: _route_descriptive_options, solve

_INITIAL_GUESS_ALIASES

_INITIAL_GUESS_ALIASES_ONLY

_build_components_from_routed

OptimalControl._build_components_from_routedFunction
_build_components_from_routed(
    ocp::CTModels.OCP.AbstractModel,
    complete_description::NTuple{4, Symbol},
    registry::CTSolvers.Strategies.StrategyRegistry,
    routed::NamedTuple
) -> NamedTuple{(:discretizer, :modeler, :solver, :initial_guess, :display), <:Tuple{Any, Any, Any, CTModels.Init.AbstractInitialGuess, Any}}

Build concrete strategy instances and extract action options from a routed options result.

Each strategy is constructed via CTSolvers.Orchestration.build_strategy_from_resolved using the options that were routed to its family by _route_descriptive_options.

Action options (initial_guess, display) are extracted from routed.action and unwrapped from their OptionValue wrappers. The initial guess is normalized via CTModels.Init.build_initial_guess.

Arguments

  • ocp: The optimal control problem (needed to normalize the initial guess)
  • complete_description: Complete method triplet (discretizer_id, modeler_id, solver_id)
  • registry: Strategy registry
  • routed: Result of _route_descriptive_options

Returns

  • NamedTuple{(:discretizer, :modeler, :solver, :initial_guess, :display)}

Example

julia> components = OptimalControl._build_components_from_routed(
           ocp, (:collocation, :adnlp, :ipopt), registry, routed
       )
julia> components.discretizer isa CTDirect.AbstractDiscretizer
true
julia> components.initial_guess isa CTModels.AbstractInitialGuess
true

See also: _route_descriptive_options, CTSolvers.Orchestration.build_strategy_from_resolved

_build_or_use_strategy

OptimalControl._build_or_use_strategyFunction
_build_or_use_strategy(
    resolved::CTSolvers.Orchestration.ResolvedMethod,
    provided::CTSolvers.Strategies.AbstractStrategy,
    family_name::Symbol,
    families::NamedTuple,
    registry::CTSolvers.Strategies.StrategyRegistry
) -> CTSolvers.Strategies.AbstractStrategy

Generic strategy builder that returns a provided strategy or builds one from a resolved method.

This function works for any strategy family (discretizer, modeler, or solver) using multiple dispatch to handle the two cases: provided strategy vs. building from registry.

Arguments

  • resolved::CTSolvers.ResolvedMethod: Resolved method information with parameter data
  • provided: Strategy instance or nothing
  • family_name::Symbol: Family name (e.g., :discretizer, :modeler, :solver)
  • families::NamedTuple: NamedTuple mapping family names to abstract types
  • registry::CTSolvers.StrategyRegistry: Strategy registry for building new strategies

Returns

  • T: Strategy instance (provided or built)

Notes

  • Fast path: strategy already provided by user
  • Build path: when strategy is nothing, constructs from resolved method using registry
  • Type-safe through Julia's multiple dispatch system
  • Allocation-free implementation
  • Uses ResolvedMethod for parameter-aware validation and construction

See also: CTSolvers.Orchestration.build_strategy_from_resolved, get_strategy_registry, _complete_description

_build_or_use_strategy(
    resolved::CTSolvers.Orchestration.ResolvedMethod,
    _::Nothing,
    family_name::Symbol,
    families::NamedTuple,
    registry::CTSolvers.Strategies.StrategyRegistry
) -> Any

Build strategy from registry when no strategy is provided.

This method handles the case where no strategy is provided (nothing), building a new strategy from the complete method description using the registry.

Arguments

  • resolved::CTSolvers.ResolvedMethod: Resolved method information
  • ::Nothing: Indicates no strategy provided
  • family_name::Symbol: Family name (e.g., :discretizer, :modeler, :solver)
  • families::NamedTuple: NamedTuple mapping family names to abstract types
  • registry::CTSolvers.StrategyRegistry: Strategy registry for building new strategies

Returns

  • T: Newly built strategy instance

Notes

  • Uses CTSolvers.build_strategy_from_resolved for construction
  • Registry lookup determines the concrete strategy type
  • Type-safe through Julia's dispatch system
  • Allocation-free when possible (depends on registry implementation)

See also: CTSolvers.Orchestration.build_strategy_from_resolved, get_strategy_registry

_build_partial_description

OptimalControl._build_partial_descriptionFunction
_build_partial_description(
    discretizer::Union{Nothing, CTDirect.AbstractDiscretizer},
    modeler::Union{Nothing, CTSolvers.Modelers.AbstractNLPModeler},
    solver::Union{Nothing, CTSolvers.Solvers.AbstractNLPSolver}
) -> Tuple{Vararg{Symbol}}

Extract strategy symbols from provided components to build a partial method description.

This function extracts the symbolic IDs from concrete strategy instances using CTSolvers.id(typeof(component)). It returns a tuple containing the symbols of all non-nothing components in the order: discretizer, modeler, solver.

Arguments

  • discretizer::Union{CTDirect.AbstractDiscretizer, Nothing}: Discretization strategy or nothing
  • modeler::Union{CTSolvers.AbstractNLPModeler, Nothing}: NLP modeling strategy or nothing
  • solver::Union{CTSolvers.AbstractNLPSolver, Nothing}: NLP solver strategy or nothing

Returns

  • Tuple{Vararg{Symbol}}: Tuple of strategy symbols (empty if all nothing)

Examples

julia> disc = CTDirect.Collocation()
julia> _build_partial_description(disc, nothing, nothing)
(:collocation,)

julia> mod = CTSolvers.ADNLP()
julia> sol = CTSolvers.Ipopt()
julia> _build_partial_description(nothing, mod, sol)
(:adnlp, :ipopt)

julia> _build_partial_description(nothing, nothing, nothing)
()

See Also

_build_partial_tuple

OptimalControl._build_partial_tupleFunction
_build_partial_tuple() -> Tuple{}

Base case for recursive tuple building.

Returns an empty tuple when no components are provided. This function serves as the terminal case for the recursive tuple building algorithm.

Returns

  • (): Empty tuple

Notes

  • This is the base case for the recursive tuple building algorithm
  • Used internally by _build_partial_description
  • Allocation-free implementation
_build_partial_tuple(
    discretizer::CTDirect.AbstractDiscretizer,
    modeler::Union{Nothing, CTSolvers.Modelers.AbstractNLPModeler},
    solver::Union{Nothing, CTSolvers.Solvers.AbstractNLPSolver}
) -> Union{Tuple{Symbol}, Tuple{Symbol, Any}, Tuple{Symbol, Symbol, Any}}

Build partial tuple starting with a discretizer component.

This method handles the case where a discretizer is provided, extracts its symbolic ID, and recursively processes the remaining modeler and solver components.

Arguments

  • discretizer::CTDirect.AbstractDiscretizer: Concrete discretization strategy
  • modeler::Union{CTSolvers.AbstractNLPModeler, Nothing}: NLP modeling strategy or nothing
  • solver::Union{CTSolvers.AbstractNLPSolver, Nothing}: NLP solver strategy or nothing

Returns

  • Tuple{Vararg{Symbol}}: Tuple containing discretizer symbol followed by remaining symbols

Notes

  • Uses CTSolvers.id to extract symbolic ID
  • Recursive call to process remaining components
  • Allocation-free implementation through tuple concatenation
_build_partial_tuple(
    _::Nothing,
    modeler::Union{Nothing, CTSolvers.Modelers.AbstractNLPModeler},
    solver::Union{Nothing, CTSolvers.Solvers.AbstractNLPSolver}
) -> Union{Tuple{}, Tuple{Any}, Tuple{Symbol, Any}}

Skip discretizer and continue with remaining components.

This method handles the case where no discretizer is provided, skipping directly to processing the modeler and solver components.

Arguments

  • ::Nothing: Indicates no discretizer provided
  • modeler: NLP modeling strategy or nothing
  • solver: NLP solver strategy or nothing

Returns

  • Tuple{Vararg{Symbol}}: Tuple containing symbols from modeler and/or solver

Notes

  • Delegates to recursive processing of remaining components
  • Maintains order: modeler then solver
_build_partial_tuple(
    modeler::CTSolvers.Modelers.AbstractNLPModeler,
    solver::Union{Nothing, CTSolvers.Solvers.AbstractNLPSolver}
) -> Union{Tuple{Symbol}, Tuple{Symbol, Any}}

Build partial tuple starting with a modeler component.

This method handles the case where a modeler is provided, extracts its symbolic ID, and recursively processes the solver.

Arguments

  • modeler::CTSolvers.AbstractNLPModeler: Concrete NLP modeling strategy
  • solver::Union{CTSolvers.AbstractNLPSolver, Nothing}: NLP solver strategy or nothing

Returns

  • Tuple{Vararg{Symbol}}: Tuple containing modeler symbol followed by solver symbol (if any)

Notes

  • Uses CTSolvers.id to extract symbolic ID
  • Recursive call to process solver component
  • Allocation-free implementation
_build_partial_tuple(
    _::Nothing,
    solver::Union{Nothing, CTSolvers.Solvers.AbstractNLPSolver}
) -> Union{Tuple{}, Tuple{Any}}

Skip modeler and continue with solver component.

This method handles the case where no modeler is provided, skipping directly to processing the solver component.

Arguments

  • ::Nothing: Indicates no modeler provided
  • solver: NLP solver strategy or nothing

Returns

  • Tuple{Vararg{Symbol}}: Tuple containing solver symbol (if any)

Notes

  • Delegates to solver processing
  • Terminal case in the recursion chain
_build_partial_tuple(
    solver::CTSolvers.Solvers.AbstractNLPSolver
) -> Tuple{Any}

Terminal case: extract solver symbol.

This method handles the case where a solver is provided, extracts its symbolic ID, and returns it as a single-element tuple.

Arguments

  • solver::CTSolvers.AbstractNLPSolver: Concrete NLP solver strategy

Returns

  • Tuple{Symbol}: Single-element tuple containing solver symbol

Notes

  • Uses CTSolvers.id to extract symbolic ID
  • Terminal case in the recursion
  • Allocation-free implementation
_build_partial_tuple(_::Nothing) -> Tuple{}

Terminal case: no solver provided.

This method handles the case where no solver is provided, returning an empty tuple to complete the recursion.

Arguments

  • ::Nothing: Indicates no solver provided

Returns

  • (): Empty tuple

Notes

  • Terminal case in the recursion
  • Represents the case where all components are nothing

_build_source_tag

OptimalControl._build_source_tagFunction
_build_source_tag(source, common_param, params, show_sources)

Build the source tag for an option based on its source and parameter context.

This helper function creates appropriate tags to indicate where an option came from (user-specified or computed) and its parameter dependency.

Arguments

  • source::Symbol: Either :user or :computed
  • common_param::Union{Symbol, Nothing}: Common parameter for the strategy (can be nothing)
  • params::Vector{Symbol}: Vector of all parameter symbols
  • show_sources::Bool: Whether to include source information in tags

Returns

  • String: The formatted source tag (empty string if no tag needed)

Notes

  • For :computed source, shows parameter dependency (e.g., [gpu-dependent])
  • For :user source, shows [user] when show_sources=true
  • Returns empty string when no tag is appropriate
  • Used by display_ocp_configuration for option source indication

See also: display_ocp_configuration

_complete_components

OptimalControl._complete_componentsFunction
_complete_components(
    discretizer::Union{Nothing, CTDirect.AbstractDiscretizer},
    modeler::Union{Nothing, CTSolvers.Modelers.AbstractNLPModeler},
    solver::Union{Nothing, CTSolvers.Solvers.AbstractNLPSolver},
    registry::CTSolvers.Strategies.StrategyRegistry
) -> NamedTuple{(:discretizer, :modeler, :solver), <:Tuple{Any, Any, Any}}

Complete missing resolution components using the registry.

This function orchestrates the component completion workflow:

  1. Extract symbols from provided components using _build_partial_description
  2. Complete the method description using _complete_description
  3. Resolve method with parameter information using CTSolvers.resolve_method
  4. Build or use strategies for each family using _build_or_use_strategy

Arguments

  • discretizer::Union{CTDirect.AbstractDiscretizer, Nothing}: Discretization strategy or nothing
  • modeler::Union{CTSolvers.AbstractNLPModeler, Nothing}: NLP modeling strategy or nothing
  • solver::Union{CTSolvers.AbstractNLPSolver, Nothing}: NLP solver strategy or nothing
  • registry::CTSolvers.StrategyRegistry: Strategy registry for building missing components

Returns

  • NamedTuple{(:discretizer, :modeler, :solver)}: Complete component triplet

Examples

# Complete from scratch
result = OptimalControl._complete_components(nothing, nothing, nothing, registry)
@test result.discretizer isa CTDirect.AbstractDiscretizer
@test result.modeler isa CTSolvers.AbstractNLPModeler
@test result.solver isa CTSolvers.AbstractNLPSolver

# Partial completion
disc = CTDirect.Collocation()
result = OptimalControl._complete_components(disc, nothing, nothing, registry)
@test result.discretizer === disc
@test result.modeler isa CTSolvers.AbstractNLPModeler
@test result.solver isa CTSolvers.AbstractNLPSolver

Notes

  • Provided components are preserved (returned as-is)
  • Missing components are instantiated using the first available strategy from the registry
  • Supports both CPU and GPU parameterized strategies
  • Used by solve_explicit when components are partially specified

See also: _build_partial_description, _complete_description, _build_or_use_strategy, get_strategy_registry, solve_explicit

_complete_description

OptimalControl._complete_descriptionFunction
_complete_description(
    partial_description::Tuple{Vararg{Symbol}}
) -> NTuple{4, Symbol}

Complete a partial method description into a full triplet using CTBase.complete().

This function takes a partial description (tuple of strategy symbols) and completes it to a full (discretizer, modeler, solver) triplet using the available methods as the completion set.

Arguments

  • partial_description::Tuple{Vararg{Symbol}}: Tuple of strategy symbols (may be empty or partial)

Returns

  • Tuple{Symbol, Symbol, Symbol, Symbol}: Complete method triplet

Examples

julia> _complete_description((:collocation,))
(:collocation, :adnlp, :ipopt, :cpu)

julia> _complete_description(())
(:collocation, :adnlp, :ipopt, :cpu)  # First available method

julia> _complete_description((:collocation, :exa))
(:collocation, :exa, :ipopt, :cpu)

See Also

_descriptive_action_defs

OptimalControl._descriptive_action_defsFunction
_descriptive_action_defs(

) -> Vector{CTSolvers.Options.OptionDefinition}

Return the action-level option definitions for descriptive mode.

Action options are solve-level options consumed by the orchestrator before strategy-specific options are routed. They are extracted from kwargs first by CTSolvers.Orchestration.route_all_options, so they never reach the strategy router.

Currently defined action options:

  • initial_guess (aliases: init): Initial guess for the OCP solution. Defaults to nothing (automatic generation via CTModels.Init.build_initial_guess).
  • display: Whether to display solve configuration. Defaults to true.

Priority rule

If a strategy also declares an option with the same name (e.g., display), the action option takes priority when no CTSolvers.Strategies.route_to is used. To explicitly target a strategy, use route_to(strategy_id=value).

Returns

  • Vector{CTSolvers.Options.OptionDefinition}(@extref): Action option definitions

Example

julia> defs = OptimalControl._descriptive_action_defs()
julia> length(defs)
2
julia> defs[1].name
:initial_guess
julia> defs[1].aliases
(:init,)

See also: _route_descriptive_options

_descriptive_families

OptimalControl._descriptive_familiesFunction
_descriptive_families(

) -> @NamedTuple{discretizer::DataType, modeler::DataType, solver::DataType}

Return the strategy families used for option routing in descriptive mode.

The returned NamedTuple maps family names to their abstract types, as expected by CTSolvers.Orchestration.route_all_options.

Returns

  • NamedTuple: (discretizer, modeler, solver) mapped to their abstract types

Example

julia> fam = OptimalControl._descriptive_families()
(discretizer = CTDirect.AbstractDiscretizer, modeler = CTSolvers.AbstractNLPModeler, solver = CTSolvers.AbstractNLPSolver)

See also: _route_descriptive_options

_determine_parameter_display_strategy

OptimalControl._determine_parameter_display_strategyFunction
_determine_parameter_display_strategy(params)

Determine how to display parameters based on their values.

This function analyzes the parameter symbols to decide whether they should be displayed inline with each component or as a common parameter at the end.

Arguments

  • params::Vector{Symbol}: Vector of parameter symbols

Returns

  • NamedTuple: Contains fields:
    • show_inline::Bool: Whether to show parameters inline with each component
    • common: Common parameter to show at end, or nothing

Notes

  • If no parameters, shows nothing inline and no common parameter
  • If all parameters are equal, shows common parameter at end
  • If parameters differ, shows each parameter inline with its component

See also: _extract_strategy_parameters

_explicit_or_descriptive

OptimalControl._explicit_or_descriptiveFunction
_explicit_or_descriptive(
    description::Tuple{Vararg{Symbol}},
    kwargs::Base.Pairs
) -> Union{OptimalControl.DescriptiveMode, OptimalControl.ExplicitMode}

Detect the resolution mode from description and kwargs, and validate consistency.

Returns an instance of ExplicitMode if at least one explicit resolution component (of type CTDirect.AbstractDiscretizer, CTSolvers.AbstractNLPModeler, or CTSolvers.AbstractNLPSolver) is found in kwargs. Returns DescriptiveMode otherwise.

Raises CTBase.Exceptions.IncorrectArgument if both explicit components and a symbolic description are provided simultaneously.

Arguments

  • description::Tuple{Vararg{Symbol}}: Tuple of symbolic description tokens (e.g., (:collocation, :adnlp, :ipopt))
  • kwargs::Base.Pairs: Keyword arguments from the solve call

Returns

  • ExplicitMode() if explicit components are present
  • DescriptiveMode() if no explicit components are present

Throws

Examples

julia> using CTDirect
julia> disc = CTDirect.Collocation()
julia> kw = pairs((; discretizer=disc))

julia> OptimalControl._explicit_or_descriptive((), kw)
ExplicitMode()

julia> OptimalControl._explicit_or_descriptive((:collocation, :adnlp, :ipopt), pairs(NamedTuple()))
DescriptiveMode()

julia> OptimalControl._explicit_or_descriptive((:collocation,), kw)
# throws CTBase.IncorrectArgument

Notes

  • This function is used internally by the main solve dispatcher to determine the resolution path
  • Mode detection is based on the presence of typed components in kwargs
  • Validation ensures users don't accidentally mix both modes
  • The function uses type-based detection via _extract_kwarg for robustness

See also: _extract_kwarg, ExplicitMode, DescriptiveMode, solve

_extract_action_kwarg

OptimalControl._extract_action_kwargFunction
_extract_action_kwarg(
    kwargs::Base.Pairs,
    names::Tuple{Vararg{Symbol}},
    default
) -> Tuple{Any, Base.Pairs}

Extract an action-level option from kwargs by trying multiple alias names.

Returns the value and the remaining kwargs with the matched key removed. Raises an error if more than one alias is present simultaneously.

Arguments

  • kwargs::Base.Pairs: Keyword arguments from a solve call
  • names::Tuple{Vararg{Symbol}}: Tuple of accepted names/aliases, in priority order
  • default: Default value if none of the names is found

Returns

  • (value, remaining_kwargs): Extracted value and kwargs with the key removed

Throws

Examples

julia> kw = pairs((; init=x0, display=false))
julia> val, rest = OptimalControl._extract_action_kwarg(kw, (:initial_guess, :init), nothing)
julia> val === x0
true

Notes

  • Supports alias resolution with conflict detection
  • Used for extracting initial_guess/init and display options
  • Returns default value if none of the aliases are present

See also: _extract_kwarg, solve_explicit, solve_descriptive

_extract_kwarg

OptimalControl._extract_kwargFunction
_extract_kwarg(kwargs::Base.Pairs, _::Type{T}) -> Any

Extract the first value of abstract type T from kwargs, or return nothing.

This function enables type-based mode detection: explicit resolution components (discretizer, modeler, solver) are identified by their abstract type rather than by their keyword name. This avoids name collisions with strategy-specific options that might share the same keyword names.

Arguments

  • kwargs::Base.Pairs: Keyword arguments from a solve call
  • T::Type: Abstract type to search for

Returns

  • Union{T, Nothing}: First matching value, or nothing if none found

Examples

julia> using CTDirect
julia> disc = CTDirect.Collocation()
julia> kw = pairs((; discretizer=disc, print_level=0))
julia> OptimalControl._extract_kwarg(kw, CTDirect.AbstractDiscretizer)
Collocation(...)

julia> OptimalControl._extract_kwarg(kw, CTSolvers.AbstractNLPModeler)
nothing

Notes

  • Type-based extraction allows keyword name independence
  • Returns the first matching value found (order depends on kwargs iteration)
  • Used for mode detection and component extraction in explicit mode

See also: _explicit_or_descriptive, solve_explicit

_extract_strategy_parameters

OptimalControl._extract_strategy_parametersFunction
_extract_strategy_parameters(discretizer, modeler, solver)

Extract parameter types from strategies and convert to symbols.

This function analyzes the three strategy components (discretizer, modeler, solver) to determine their parameter types and converts them to symbolic representations for display purposes.

Arguments

  • discretizer: The discretization strategy
  • modeler: The NLP modeling strategy
  • solver: The NLP solving strategy

Returns

  • NamedTuple: Contains fields:
    • disc: Discretizer parameter symbol or nothing
    • mod: Modeler parameter symbol or nothing
    • sol: Solver parameter symbol or nothing
    • params: Vector of non-nothing parameter symbols

Notes

  • Uses CTSolvers.Strategies.get_parameter_type() to extract parameter types
  • Converts parameter types to symbols using CTSolvers.id()
  • Filters out nothing values from the parameters vector

See also: _determine_parameter_display_strategy

_has_complete_components

OptimalControl._has_complete_componentsFunction
_has_complete_components(
    discretizer::Union{Nothing, CTDirect.AbstractDiscretizer},
    modeler::Union{Nothing, CTSolvers.Modelers.AbstractNLPModeler},
    solver::Union{Nothing, CTSolvers.Solvers.AbstractNLPSolver}
) -> Bool

Check if all three resolution components are provided.

This is a pure predicate function with no side effects. It returns true if and only if all three components (discretizer, modeler, solver) are concrete instances (not nothing).

Arguments

  • discretizer::Union{CTDirect.AbstractDiscretizer, Nothing}: Discretization strategy or nothing
  • modeler::Union{CTSolvers.AbstractNLPModeler, Nothing}: NLP modeling strategy or nothing
  • solver::Union{CTSolvers.AbstractNLPSolver, Nothing}: NLP solver strategy or nothing

Returns

  • Bool: true if all components are provided, false otherwise

Examples

julia> disc = CTDirect.Collocation()
julia> mod = CTSolvers.ADNLP()
julia> sol = CTSolvers.Ipopt()
julia> OptimalControl._has_complete_components(disc, mod, sol)
true

julia> OptimalControl._has_complete_components(nothing, mod, sol)
false

julia> OptimalControl._has_complete_components(disc, nothing, sol)
false

Notes

  • This is a pure predicate function with no side effects
  • Allocation-free and type-stable
  • Used by solve_explicit to determine if component completion is needed

See also: _complete_components, solve_explicit

_print_component_with_param

OptimalControl._print_component_with_paramFunction
_print_component_with_param(io, component_id, show_inline, param_sym)

Print a component ID with optional inline parameter.

This helper function formats and prints a component identifier with an optional parameter displayed inline when appropriate.

Arguments

  • io::IO: Output stream for printing
  • component_id::String: The component identifier to print
  • show_inline::Bool: Whether to show the parameter inline
  • param_sym::Union{Symbol, Nothing}: Parameter symbol to display (can be nothing)

Notes

  • Component ID is printed in cyan with bold formatting
  • Parameter (if shown) is printed in magenta with bold formatting
  • Used by display_ocp_configuration for consistent formatting

See also: display_ocp_configuration

_route_descriptive_options

OptimalControl._route_descriptive_optionsFunction
_route_descriptive_options(
    complete_description::NTuple{4, Symbol},
    registry::CTSolvers.Strategies.StrategyRegistry,
    kwargs
) -> NamedTuple{(:action, :strategies), <:Tuple{NamedTuple, NamedTuple}}

Route all keyword options to the appropriate strategy families for descriptive mode.

This function wraps CTSolvers.Orchestration.route_all_options with the families and action definitions specific to OptimalControl's descriptive mode.

Options are routed in :strict mode: any unknown option raises an CTBase.Exceptions.IncorrectArgument. Ambiguous options (belonging to multiple strategies) must be disambiguated with CTSolvers.Strategies.route_to.

Arguments

  • complete_description: Complete method triplet (discretizer_id, modeler_id, solver_id)
  • registry: Strategy registry
  • kwargs: All keyword arguments from the user's solve call (action + strategy options)

Returns

  • NamedTuple with fields:
    • action: action-level options (initial_guess, display) as OptionValue wrappers
    • strategies: NamedTuple with discretizer, modeler, solver sub-tuples

Throws

Example

julia> routed = OptimalControl._route_descriptive_options(
           (:collocation, :adnlp, :ipopt), registry,
           pairs((; grid_size=100, max_iter=500))
       )
julia> routed.strategies.discretizer
(grid_size = 100,)
julia> routed.strategies.solver
(max_iter = 500,)

See also: _descriptive_families, _descriptive_action_defs, _build_components_from_routed

_unwrap_option

OptimalControl._unwrap_optionFunction
_unwrap_option(opt, fallback)

Unwrap an CTSolvers.Options.OptionValue to its raw value, with fallback support.

If opt is an OptionValue, returns opt.value. Otherwise, returns opt if it's not nothing, or fallback if opt is nothing.

Arguments

Returns

  • The unwrapped value or the fallback

Example

julia> opt_val = CTSolvers.Options.OptionValue(42, :user)
OptionValue(42, :user)

julia> _unwrap_option(opt_val, 0)
42

julia> _unwrap_option(nothing, 0)
0

See also: _route_descriptive_options, CTSolvers.Options.OptionValue

display_ocp_configuration

OptimalControl.display_ocp_configurationFunction
display_ocp_configuration(
    io::IO,
    discretizer::CTDirect.AbstractDiscretizer,
    modeler::CTSolvers.Modelers.AbstractNLPModeler,
    solver::CTSolvers.Solvers.AbstractNLPSolver;
    display,
    show_options,
    show_sources
)

Display the optimal control problem resolution configuration (discretizer → modeler → solver) with user options.

This function prints a formatted representation of the solving strategy, showing the component types and their configuration options. The display is compact by default and only shows user-specified options.

Arguments

  • io::IO: Output stream for printing
  • discretizer::CTDirect.AbstractDiscretizer: Discretization strategy
  • modeler::CTSolvers.AbstractNLPModeler: NLP modeling strategy
  • solver::CTSolvers.AbstractNLPSolver: NLP solver strategy
  • display::Bool: Whether to print the configuration (default: true)
  • show_options::Bool: Whether to show component options (default: true)
  • show_sources::Bool: Whether to show option sources (default: false)

Examples

julia> disc = CTDirect.Collocation()
julia> mod = CTSolvers.ADNLP()
julia> sol = CTSolvers.Ipopt()
julia> OptimalControl.display_ocp_configuration(stdout, disc, mod, sol)
▫ OptimalControl v1.1.8-beta solving with: collocation → adnlp → ipopt

  📦 Configuration: 
   ├─ Discretizer: collocation
   ├─ Modeler: adnlp
   └─ Solver: ipopt

With parameterized strategies (parameter extracted automatically):

julia> disc = CTDirect.Collocation()
julia> mod = CTSolvers.Exa()  # GPU-optimized
julia> sol = CTSolvers.MadNLP()
julia> OptimalControl.display_ocp_configuration(stdout, disc, mod, sol)
▫ OptimalControl v1.1.8-beta solving with: collocation → exa (gpu) → madnlp

  📦 Configuration:
   ├─ Discretizer: collocation
   ├─ Modeler: exa (backend = cuda [gpu-dependent])
   └─ Solver: madnlp

Notes

  • Both user-specified and computed options are always displayed
  • Computed options show [parameter-dependent] tag (e.g., [cpu-dependent])
  • Set show_sources=true to also see [user]/[computed] source tags
  • Set show_options=false to show only component IDs
  • The function returns nothing and only produces side effects

See also: solve_explicit, get_strategy_registry

display_ocp_configuration(
    discretizer::CTDirect.AbstractDiscretizer,
    modeler::CTSolvers.Modelers.AbstractNLPModeler,
    solver::CTSolvers.Solvers.AbstractNLPSolver;
    display,
    show_options,
    show_sources
)

Display the optimal control problem resolution configuration to standard output.

This is a convenience method that prints to stdout by default. See the main method for full documentation of all parameters and behavior.

Arguments

  • discretizer::CTDirect.AbstractDiscretizer: Discretization strategy
  • modeler::CTSolvers.AbstractNLPModeler: NLP modeling strategy
  • solver::CTSolvers.AbstractNLPSolver: NLP solver strategy
  • display::Bool: Whether to print the configuration (default: true)
  • show_options::Bool: Whether to show component options (default: true)
  • show_sources::Bool: Whether to show option sources (default: false)

Examples

julia> disc = CTDirect.Collocation()
julia> mod = CTSolvers.ADNLP()
julia> sol = CTSolvers.Ipopt()
julia> OptimalControl.display_ocp_configuration(disc, mod, sol)
▫ OptimalControl v1.1.8-beta solving with: collocation → adnlp → ipopt

  📦 Configuration:
   ├─ Discretizer: collocation
   ├─ Modeler: adnlp
   └─ Solver: ipopt

get_strategy_registry

OptimalControl.get_strategy_registryFunction
get_strategy_registry(

) -> CTSolvers.Strategies.StrategyRegistry

Create and return the strategy registry for the solve system.

The registry maps abstract strategy families to their concrete implementations with their supported parameters:

  • CTDirect.AbstractDiscretizer → Discretization strategies
  • CTSolvers.AbstractNLPModeler → NLP modeling strategies (with CPU/GPU support)
  • CTSolvers.AbstractNLPSolver → NLP solver strategies (with CPU/GPU support)

Each strategy entry specifies which parameters it supports:

  • CPU: All strategies support CPU execution
  • GPU: Only GPU-capable strategies support GPU execution (Exa, MadNLP, MadNCL)

Returns

  • CTSolvers.StrategyRegistry: Registry with all available strategies and their parameters

Examples

julia> registry = OptimalControl.get_strategy_registry()
StrategyRegistry with 3 families

julia> CTSolvers.strategy_ids(CTSolvers.AbstractNLPModeler, registry)
(:adnlp, :exa)

julia> CTSolvers.strategy_ids(CTSolvers.AbstractNLPSolver, registry)  
(:ipopt, :madnlp, :madncl, :knitro)

julia> # Check which parameters a strategy supports
julia> CTSolvers.available_parameters(:modeler, CTSolvers.Exa, registry)
(CPU, GPU)

julia> CTSolvers.available_parameters(:solver, CTSolvers.Ipopt, registry)
(CPU,)

Notes

  • Returns a precomputed registry (allocation-free, type-stable)
  • GPU-capable strategies (Exa, MadNLP, MadNCL) support both CPU and GPU parameters
  • CPU-only strategies (ADNLP, Ipopt, Knitro) support only CPU parameter
  • Parameterization is handled at the method level in methods()
  • GPU strategies automatically get appropriate default configurations when parameterized
  • Used by solve functions for component completion and strategy building

See also: methods, _complete_components, solve

solve_descriptive

OptimalControl.solve_descriptiveFunction
solve_descriptive(
    ocp::CTModels.OCP.AbstractModel,
    description::Symbol...;
    registry,
    kwargs...
)

Resolve an OCP in descriptive mode (Layer 2).

Accepts a partial or complete symbolic method description and flat keyword options, then completes the description, routes options to the appropriate strategies, builds concrete components, and calls the canonical Layer 3 solver.

Arguments

  • ocp::CTModels.AbstractModel: The optimal control problem to solve
  • description::Symbol...: Symbolic description tokens (e.g., :collocation, :adnlp, :ipopt). May be empty, partial, or complete — completed via _complete_description.
  • registry::CTSolvers.StrategyRegistry: Strategy registry for building strategies
  • kwargs...: All keyword arguments, including action options (initial_guess/init, display) and strategy-specific options, optionally disambiguated with CTSolvers.Strategies.route_to

Returns

  • CTModels.AbstractSolution: Solution to the optimal control problem

Throws

Examples

# Complete description with options
solve(ocp, :collocation, :adnlp, :ipopt; grid_size=100, display=false)

# Alias for initial_guess
solve(ocp, :collocation; init=x0, display=false)

# Disambiguation for ambiguous options
solve(ocp, :collocation, :adnlp, :ipopt;
    backend=route_to(adnlp=:sparse, ipopt=:cpu), display=false)

Notes

  • This is Layer 2 of the solve architecture - handles symbolic descriptions and option routing
  • The function performs: (1) description completion, (2) option routing, (3) component building, (4) Layer 3 dispatch
  • Action options (initial_guess/init, display) are extracted and normalized at this layer
  • Strategy-specific options are routed to the appropriate component families
  • This function is typically called by the main solve dispatcher in descriptive mode

See also: solve, solve_explicit, _complete_description, _route_descriptive_options, _build_components_from_routed

solve_explicit

OptimalControl.solve_explicitFunction
solve_explicit(
    ocp::CTModels.OCP.AbstractModel;
    registry,
    kwargs...
)

Resolve an OCP in explicit mode (Layer 2).

Receives typed components (discretizer, modeler, solver) as named keyword arguments, then completes missing components via the registry before calling Layer 3.

Arguments

  • ocp::CTModels.AbstractModel: The optimal control problem to solve
  • registry::CTSolvers.StrategyRegistry: Strategy registry for completing partial components
  • kwargs...: All keyword arguments. Action options extracted here:
    • initial_guess (alias: init): Initial guess, default nothing
    • display: Whether to display configuration information, default true
    • Typed components: discretizer, modeler, solver (identified by abstract type)

Returns

  • CTModels.AbstractSolution: Solution to the optimal control problem

Notes

  • This is Layer 2 of the solve architecture - handles explicit component mode
  • The function performs: (1) action option extraction, (2) initial guess normalization, (3) component completion, (4) Layer 3 dispatch
  • Missing components are completed using the first available strategy from the registry
  • All three components must be either provided or completable via the registry
  • This function is typically called by the main solve dispatcher in explicit mode

See also: solve, solve_descriptive, _has_complete_components, _complete_components, _explicit_or_descriptive

will_solver_print

OptimalControl.will_solver_printFunction
will_solver_print(
    solver::CTSolvers.Solvers.AbstractNLPSolver
) -> Any

Check if a solver will produce output based on its options.

This function uses multiple dispatch to check solver-specific options that control output verbosity. It is used to conditionally print a symbol before the solver starts printing.

Arguments

  • solver::CTSolvers.AbstractNLPSolver: The solver instance to check

Returns

  • Bool: true if the solver will print output, false otherwise

Examples

julia> sol = CTSolvers.Ipopt(print_level=0)
julia> OptimalControl.will_solver_print(sol)
false

julia> sol = CTSolvers.Ipopt(print_level=5)
julia> OptimalControl.will_solver_print(sol)
true

Notes

  • Default behavior assumes solver will print (returns true)
  • Each solver type has a specialized method checking its specific options
  • Used internally by display_ocp_configuration to conditionally print

See also: display_ocp_configuration

will_solver_print(solver::CTSolvers.Solvers.Ipopt) -> Any

Check if Ipopt will produce output based on print_level option.

Ipopt is silent when print_level = 0, verbose otherwise.

Arguments

  • solver::CTSolvers.Ipopt: The Ipopt solver instance to check

Returns

  • Bool: true if Ipopt will print output, false otherwise

Notes

  • When print_level is not specified, Ipopt defaults to verbose output
  • This method allows the display system to conditionally show the symbol

See also: will_solver_print(::CTSolvers.AbstractNLPSolver)

will_solver_print(solver::CTSolvers.Solvers.Knitro) -> Any

Check if Knitro will produce output based on outlev option.

Knitro is silent when outlev = 0, verbose otherwise.

Arguments

  • solver::CTSolvers.Knitro: The Knitro solver instance to check

Returns

  • Bool: true if Knitro will print output, false otherwise

Notes

  • When outlev is not specified, Knitro defaults to verbose output
  • This method allows the display system to conditionally show the symbol

See also: will_solver_print(::CTSolvers.AbstractNLPSolver)

will_solver_print(solver::CTSolvers.Solvers.MadNLP) -> Any

Check if MadNLP will produce output based on print_level option.

MadNLP is silent when print_level = MadNLP.ERROR, verbose otherwise. Default is MadNLP.INFO which prints output.

Arguments

  • solver::CTSolvers.MadNLP: The MadNLP solver instance to check

Returns

  • Bool: true if MadNLP will print output, false otherwise

Notes

  • Uses string comparison to avoid requiring MadNLP to be loaded
  • Default print level is MadNLP.INFO which produces output
  • Only MadNLP.ERROR level suppresses output

See also: will_solver_print(::CTSolvers.AbstractNLPSolver)

will_solver_print(solver::CTSolvers.Solvers.MadNCL) -> Bool

Check if MadNCL will produce output based on print_level and ncl_options.verbose.

MadNCL is silent when either:

  • print_level = MadNLP.ERROR, or
  • ncl_options.verbose = false

Arguments

  • solver::CTSolvers.MadNCL: The MadNCL solver instance to check

Returns

  • Bool: true if MadNCL will print output, false otherwise

Notes

  • Checks both the global print level and NCL-specific verbose option
  • Uses string comparison to avoid requiring MadNLP to be loaded
  • Either condition being false will suppress output

See also: will_solver_print(::CTSolvers.AbstractNLPSolver)