Export & import

export_ocp_solution writes a Solution to disk; import_ocp_solution reads it back, given the Model it belongs to. Two formats are available, each behind its extension:

formatExtensionFile
:JLD (default)CTModelsJLD (JLD2)binary .jld2
:JSONCTModelsJSON (JSON3)text .json
using CTModels
using JSON3      # CTModelsJSON
using JLD2       # CTModelsJLD

pre = CTModels.PreModel()
CTModels.variable!(pre, 0)
CTModels.time!(pre; t0=0.0, tf=1.0)
CTModels.state!(pre, 2)
CTModels.control!(pre, 1)
CTModels.dynamics!(pre, (r, t, x, u, v) -> (r[1] = x[2]; r[2] = u[1]; nothing))
CTModels.objective!(pre, :min; lagrange=(t, x, u, v) -> u[1]^2)
CTModels.time_dependence!(pre; autonomous=true)
ocp = CTModels.build(pre)

N = 101
T = collect(range(0.0, 1.0; length=N))
sol = CTModels.build_solution(ocp, T, hcat(cos.(T), -sin.(T)),
    reshape(-cos.(T), N, 1), Float64[], zeros(N, 2);
    objective=0.5, iterations=10, constraints_violation=1e-9,
    message="ok", status=:optimal, successful=true)

Both formats round-trip

The filename is a base path; the extension is appended automatically.

base = joinpath(tempdir(), "ctmodels_demo")

CTModels.export_ocp_solution(sol; filename=base, format=:JSON)
CTModels.export_ocp_solution(sol; filename=base, format=:JLD)

from_json = CTModels.import_ocp_solution(ocp; filename=base, format=:JSON)
from_jld  = CTModels.import_ocp_solution(ocp; filename=base, format=:JLD)

(CTModels.objective(from_json), CTModels.objective(from_jld))
(0.5, 0.5)

The reloaded solution behaves exactly like the original — its trajectories are again callables of time:

x = CTModels.state(from_json)
x(0.5)
2-element Vector{Float64}:
  0.8775825618903728
 -0.479425538604203

How trajectories survive serialization

A trajectory is a function t -> x(t), which neither JSON nor JLD2 can store directly. CTModels works around this by resampling: before writing, each trajectory is evaluated on its time grid (the helpers in OCP/Building/discretization_utils.jl), and only the resulting arrays are persisted. On import, the arrays are wrapped back into interpolated callables — the same mechanism used when building a solution.

Low-level tags

The format keyword dispatches internally on the tags CTModels.JSON3Tag() and CTModels.JLD2Tag(). The extension methods export_ocp_solution(CTModels.JLD2Tag(), sol; …) etc. are what each ext/ file implements; the format= wrapper is the public, dependency-free entry point.