diff --git a/.gitignore b/.gitignore index ec2f89bcd..739d6204b 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,4 @@ Manifest.toml # docs/tmp/ +save/ \ No newline at end of file diff --git a/Project.toml b/Project.toml index a48815028..ae141e2c9 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "OptimalControl" uuid = "5f98b655-cc9a-415a-b60e-744165666948" +version = "1.1.8-beta" authors = ["Olivier Cots "] -version = "1.1.6" [deps] ADNLPModels = "54578032-b7ea-4c30-94aa-7cbd1cce6c9a" @@ -10,20 +10,51 @@ CTDirect = "790bbbee-bee9-49ee-8912-a9de031322d5" CTFlows = "1c39547c-7794-42f7-af83-d98194f657c2" CTModels = "34c4fa32-2049-4079-8329-de33c2a22e2d" CTParser = "32681960-a1b1-40db-9bff-a1ca817385d1" +CTSolvers = "d3e8d392-8e4b-4d9b-8e92-d7d4e3650ef6" CommonSolve = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" ExaModels = "1037b233-b668-4ce9-9b63-f9f681f55dd2" +NLPModels = "a4795742-8479-5a88-8948-cc11e1c8c1a6" RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +SolverCore = "ff4d7338-4cf1-434d-91df-b86cb86fb843" [compat] ADNLPModels = "0.8" -CTBase = "0.16" -CTDirect = "0.17" +CTBase = "0.17" +CTDirect = "0.18" CTFlows = "0.8" -CTModels = "0.6" -CTParser = "0.7" +CTModels = "0.7" +CTParser = "0.7, 0.8" +CTSolvers = "0.2" CommonSolve = "0.2" +DifferentiationInterface = "0.7" DocStringExtensions = "0.9" ExaModels = "0.9" +ForwardDiff = "0.10, 1.0" +LinearAlgebra = "1" +MadNLP = "0.8" +MadNLPMumps = "0.5" +NLPModels = "0.21.7" +NLPModelsIpopt = "0.11" +NonlinearSolve = "4" +OrdinaryDiffEq = "6" RecipesBase = "1" +SolverCore = "0.3.9" +SplitApplyCombine = "1" +Test = "1" julia = "1.10" + +[extras] +DifferentiationInterface = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" +ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +MadNLP = "2621e9c9-9eb4-46b1-8089-e8c72242dfb6" +MadNLPMumps = "3b83494e-c0a4-4895-918b-9157a7a085a1" +NLPModelsIpopt = "f4238b75-b362-5c4c-b852-0801c9a21d71" +NonlinearSolve = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["DifferentiationInterface", "ForwardDiff", "LinearAlgebra", "MadNLP", "MadNLPMumps", "NLPModelsIpopt", "NonlinearSolve", "OrdinaryDiffEq", "SplitApplyCombine", "Test"] diff --git a/diag.jl b/diag.jl new file mode 100644 index 000000000..80b18af97 --- /dev/null +++ b/diag.jl @@ -0,0 +1,15 @@ +using Pkg +Pkg.activate(".") + +# We want to see if AbstractOptimalControlProblem is defined BEFORE ctmodels.jl:4 +# So we can't just use OptimalControl because it errors. + +# Let's manually include things up to ctmodels.jl +include("src/imports/ctbase.jl") +include("src/imports/ctparser.jl") +include("src/imports/plots.jl") + +println("Defined before ctmodels: ", isdefined(Main, :AbstractOptimalControlProblem)) +if isdefined(Main, :AbstractOptimalControlProblem) + println("Parent: ", parentmodule(Main.AbstractOptimalControlProblem)) +end diff --git a/docs/src/assets/Manifest.toml b/docs/src/assets/Manifest.toml index 78e84667e..6410a51a7 100644 --- a/docs/src/assets/Manifest.toml +++ b/docs/src/assets/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.12.1" manifest_format = "2.0" -project_hash = "ed383b814e8d550b2e19c67b5eb177cab6b8ccff" +project_hash = "11c602d38b004951acad78f34429b3755c176e10" [[deps.ADNLPModels]] deps = ["ADTypes", "ForwardDiff", "LinearAlgebra", "NLPModels", "Requires", "ReverseDiff", "SparseArrays", "SparseConnectivityTracer", "SparseMatrixColorings"] @@ -11,9 +11,9 @@ uuid = "54578032-b7ea-4c30-94aa-7cbd1cce6c9a" version = "0.8.13" [[deps.ADTypes]] -git-tree-sha1 = "27cecae79e5cc9935255f90c53bb831cc3c870d7" +git-tree-sha1 = "f7304359109c768cf32dc5fa2d371565bb63b68a" uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" -version = "1.18.0" +version = "1.21.0" weakdeps = ["ChainRulesCore", "ConstructionBase", "EnzymeCore"] [deps.ADTypes.extensions] @@ -45,9 +45,9 @@ version = "0.4.5" [[deps.Accessors]] deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] -git-tree-sha1 = "3b86719127f50670efe356bc11073d84b4ed7a5d" +git-tree-sha1 = "856ecd7cebb68e5fc87abecd2326ad59f0f911f3" uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.42" +version = "0.1.43" [deps.Accessors.extensions] AxisKeysExt = "AxisKeys" @@ -122,16 +122,6 @@ version = "7.22.0" StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" -[[deps.ArrayLayouts]] -deps = ["FillArrays", "LinearAlgebra", "StaticArrays"] -git-tree-sha1 = "355ab2d61069927d4247cd69ad0e1f140b31e30d" -uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" -version = "1.12.0" -weakdeps = ["SparseArrays"] - - [deps.ArrayLayouts.extensions] - ArrayLayoutsSparseArraysExt = "SparseArrays" - [[deps.Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" version = "1.11.0" @@ -159,9 +149,9 @@ version = "0.1.6" [[deps.BracketingNonlinearSolve]] deps = ["CommonSolve", "ConcreteStructs", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "57f9f59bec88ce80cd3e46efc39f126395789bb0" +git-tree-sha1 = "750f782fcc7e09283be7d8a7aa687a95e4911b60" uuid = "70df07ce-3d50-431d-a3e7-ca6ddb60ac1e" -version = "1.5.0" +version = "1.6.2" weakdeps = ["ChainRulesCore", "ForwardDiff"] [deps.BracketingNonlinearSolve.extensions] @@ -191,10 +181,10 @@ weakdeps = ["HTTP", "JSON"] CTBaseDocstrings = ["HTTP", "JSON"] [[deps.CTDirect]] -deps = ["CTBase", "CTModels", "DocStringExtensions", "HSL", "MKL", "SparseArrays"] -git-tree-sha1 = "a3e796c81478034446feb316816ccfe1f250f211" +deps = ["CTBase", "CTModels", "DocStringExtensions", "HSL", "MKL", "NLPModels", "SolverCore", "SparseArrays"] +git-tree-sha1 = "66244d746db32e51fc27229079e355f675e017ea" uuid = "790bbbee-bee9-49ee-8912-a9de031322d5" -version = "0.17.3" +version = "0.17.4" weakdeps = ["ADNLPModels", "ExaModels", "MadNLP", "NLPModelsIpopt", "NLPModelsKnitro"] [deps.CTDirect.extensions] @@ -216,9 +206,9 @@ weakdeps = ["OrdinaryDiffEq"] [[deps.CTModels]] deps = ["CTBase", "DocStringExtensions", "Interpolations", "LinearAlgebra", "MLStyle", "MacroTools", "OrderedCollections", "Parameters", "RecipesBase"] -git-tree-sha1 = "072e5e867715b060729158d4c5fb3b16ff7e82b0" +git-tree-sha1 = "64b5821c4a8d254d0b2905e2a1647c40867696ad" uuid = "34c4fa32-2049-4079-8329-de33c2a22e2d" -version = "0.6.9" +version = "0.6.10-beta" weakdeps = ["JLD2", "JSON3", "Plots"] [deps.CTModels.extensions] @@ -228,9 +218,9 @@ weakdeps = ["JLD2", "JSON3", "Plots"] [[deps.CTParser]] deps = ["CTBase", "DocStringExtensions", "MLStyle", "OrderedCollections", "Parameters", "Unicode"] -git-tree-sha1 = "48ec8193487a79277ff278752337c4ffb8fff691" +git-tree-sha1 = "d2682ff1d764cc6a3ccdc98921b2c328d4d19d3d" uuid = "32681960-a1b1-40db-9bff-a1ca817385d1" -version = "0.7.1" +version = "0.7.3-beta" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] @@ -249,9 +239,9 @@ weakdeps = ["SparseArrays"] ChainRulesCoreSparseArraysExt = "SparseArrays" [[deps.ChunkCodecCore]] -git-tree-sha1 = "51f4c10ee01bda57371e977931de39ee0f0cdb3e" +git-tree-sha1 = "1a3ad7e16a321667698a19e77362b35a1e94c544" uuid = "0b6fb165-00bc-4d37-ab8b-79f91016dbe1" -version = "1.0.0" +version = "1.0.1" [[deps.ChunkCodecLibZlib]] deps = ["ChunkCodecCore", "Zlib_jll"] @@ -310,9 +300,9 @@ uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.13.1" [[deps.CommonSolve]] -git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +git-tree-sha1 = "78ea4ddbcf9c241827e7035c3a03e2e456711470" uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" -version = "0.2.4" +version = "0.2.6" [[deps.CommonSubexpressions]] deps = ["MacroTools"] @@ -404,9 +394,9 @@ version = "1.8.1" [[deps.DataStructures]] deps = ["OrderedCollections"] -git-tree-sha1 = "6c72198e6a101cccdd4c9731d3985e904ba26037" +git-tree-sha1 = "e357641bb3e0638d353c4b29ea0e40ea644066a6" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.19.1" +version = "0.19.3" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -431,10 +421,10 @@ uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" version = "1.9.1" [[deps.DiffEqBase]] -deps = ["ArrayInterface", "ConcreteStructs", "DocStringExtensions", "EnzymeCore", "FastBroadcast", "FastClosures", "FastPower", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SciMLStructures", "Setfield", "Static", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "TruncatedStacktraces"] -git-tree-sha1 = "087632db966c90079a5534e4147afea9136ca39a" +deps = ["ArrayInterface", "BracketingNonlinearSolve", "ConcreteStructs", "DocStringExtensions", "EnzymeCore", "FastBroadcast", "FastClosures", "FastPower", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SciMLStructures", "Setfield", "Static", "StaticArraysCore", "SymbolicIndexingInterface", "TruncatedStacktraces"] +git-tree-sha1 = "0514bf55835444420ce81f8e32c5e2369d4af456" uuid = "2b5f629d-d688-5b77-993f-72d75c75574e" -version = "6.190.2" +version = "6.199.0" [deps.DiffEqBase.extensions] DiffEqBaseCUDAExt = "CUDA" @@ -483,9 +473,9 @@ version = "1.15.1" [[deps.DifferentiationInterface]] deps = ["ADTypes", "LinearAlgebra"] -git-tree-sha1 = "529bebbc74b36a4cfea09dd2aecb1288cd713a6d" +git-tree-sha1 = "44d9321761ed99e1d444b5081b3166d3259adcf0" uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" -version = "0.7.9" +version = "0.7.14" [deps.DifferentiationInterface.extensions] DifferentiationInterfaceChainRulesCoreExt = "ChainRulesCore" @@ -549,9 +539,9 @@ version = "0.9.5" [[deps.Documenter]] deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"] -git-tree-sha1 = "352b9a04e74edd16429aec79f033620cf8e780d4" +git-tree-sha1 = "b37458ae37d8bdb643d763451585cd8d0e5b4a9e" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.15.0" +version = "1.16.1" [[deps.DocumenterInterLinks]] deps = ["CodecZlib", "DocInventories", "Documenter", "Markdown", "MarkdownAST", "TOML"] @@ -576,13 +566,14 @@ uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" version = "1.0.5" [[deps.EnzymeCore]] -git-tree-sha1 = "f91e7cb4c17dae77c490b75328f22a226708557c" +git-tree-sha1 = "990991b8aa76d17693a98e3a915ac7aa49f08d1a" uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" -version = "0.8.15" -weakdeps = ["Adapt"] +version = "0.8.18" +weakdeps = ["Adapt", "ChainRulesCore"] [deps.EnzymeCore.extensions] AdaptExt = "Adapt" + EnzymeCoreChainRulesCoreExt = "ChainRulesCore" [[deps.EpollShim_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -592,9 +583,9 @@ version = "0.0.20230411+1" [[deps.ExaModels]] deps = ["NLPModels", "Printf", "SolverCore"] -git-tree-sha1 = "228b2c8a02228fb28179c620d8337a8b7a781a15" +git-tree-sha1 = "dc835385717dec62837d32ea0f46a8a91bdf00e4" uuid = "1037b233-b668-4ce9-9b63-f9f681f55dd2" -version = "0.9.1" +version = "0.9.3" [deps.ExaModels.extensions] ExaModelsAMDGPU = "AMDGPU" @@ -635,9 +626,9 @@ version = "2.7.3+0" [[deps.ExponentialUtilities]] deps = ["Adapt", "ArrayInterface", "GPUArraysCore", "GenericSchur", "LinearAlgebra", "PrecompileTools", "Printf", "SparseArrays", "libblastrampoline_jll"] -git-tree-sha1 = "cae251c76f353e32d32d76fae2fea655eab652af" +git-tree-sha1 = "cc294ead6a85e975a8519dd4a0a6cb294eeb18d1" uuid = "d4d017d3-3776-5f7e-afef-a10c40355c18" -version = "1.27.0" +version = "1.30.0" weakdeps = ["StaticArrays"] [deps.ExponentialUtilities.extensions] @@ -661,9 +652,9 @@ version = "0.4.5" [[deps.FFMPEG_jll]] deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] -git-tree-sha1 = "ccc81ba5e42497f4e76553a5545665eed577a663" +git-tree-sha1 = "01ba9d15e9eae375dc1eb9589df76b3572acd3f2" uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "8.0.0+0" +version = "8.0.1+0" [[deps.FastBroadcast]] deps = ["ArrayInterface", "LinearAlgebra", "Polyester", "Static", "StaticArrayInterface", "StrideArraysCore"] @@ -683,9 +674,9 @@ uuid = "442a2c76-b920-505d-bb47-c5924d526838" version = "1.1.0" [[deps.FastPower]] -git-tree-sha1 = "e47c70bf430175e077d1955d7f04923504acc74c" +git-tree-sha1 = "1dd291358e0e3a31f77dbbb76ce7abbcca38d410" uuid = "a4df4552-cc26-4903-aec0-212e50a0e84b" -version = "1.2.0" +version = "1.3.0" [deps.FastPower.extensions] FastPowerEnzymeExt = "Enzyme" @@ -721,18 +712,20 @@ version = "1.11.0" [[deps.FillArrays]] deps = ["LinearAlgebra"] -git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" +git-tree-sha1 = "2f979084d1e13948a3352cf64a25df6bd3b4dca3" uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.14.0" +version = "1.16.0" [deps.FillArrays.extensions] FillArraysPDMatsExt = "PDMats" FillArraysSparseArraysExt = "SparseArrays" + FillArraysStaticArraysExt = "StaticArrays" FillArraysStatisticsExt = "Statistics" [deps.FillArrays.weakdeps] PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" [[deps.FiniteDiff]] @@ -772,9 +765,9 @@ version = "1.3.7" [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "ba6ce081425d0afb2bedd00d9884464f764a9225" +git-tree-sha1 = "b2977f86ed76484de6f29d5b36f2fa686f085487" uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "1.2.2" +version = "1.3.1" weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] @@ -810,9 +803,9 @@ version = "1.11.0" [[deps.GLFW_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "libdecor_jll", "xkbcommon_jll"] -git-tree-sha1 = "fcb0584ff34e25155876418979d4c8971243bb89" +git-tree-sha1 = "b7bfd56fa66616138dfe5237da4dc13bbd83c67f" uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" -version = "3.4.0+2" +version = "3.4.1+0" [[deps.GPUArraysCore]] deps = ["Adapt"] @@ -822,15 +815,21 @@ version = "0.2.0" [[deps.GR]] deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Preferences", "Printf", "Qt6Wayland_jll", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "p7zip_jll"] -git-tree-sha1 = "1828eb7275491981fa5f1752a5e126e8f26f8741" +git-tree-sha1 = "f305bdb91e1f3fcc687944c97f2ede40585b1bd5" uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" -version = "0.73.17" +version = "0.73.19" + + [deps.GR.extensions] + GRIJuliaExt = "IJulia" + + [deps.GR.weakdeps] + IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" [[deps.GR_jll]] deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "27299071cc29e409488ada41ec7643e0ab19091f" +git-tree-sha1 = "de439fbc02b9dc0e639e67d7c5bd5811ff3b6f06" uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" -version = "0.73.17+0" +version = "0.73.19+1" [[deps.GenericSchur]] deps = ["LinearAlgebra", "Printf"] @@ -864,15 +863,15 @@ version = "3.7.0+0" [[deps.Git_jll]] deps = ["Artifacts", "Expat_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "Libiconv_jll", "OpenSSL_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "96fbb1a5c700942301cf65d8546690dd3b2a6a79" +git-tree-sha1 = "46bd50c245fe49ed87377c014a928a549b9ef7ed" uuid = "f8c6e375-362e-5223-8a59-34ff63f689eb" -version = "2.51.2+0" +version = "2.52.0+0" [[deps.Glib_jll]] deps = ["Artifacts", "GettextRuntime_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "50c11ffab2a3d50192a228c313f05b5b5dc5acb2" +git-tree-sha1 = "6b4d2dc81736fe3980ff0e8879a9fc7c33c44ddf" uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.86.0+0" +version = "2.86.2+0" [[deps.Graphite2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -887,9 +886,9 @@ version = "1.0.2" [[deps.HSL]] deps = ["HSL_jll", "Libdl", "LinearAlgebra", "OpenBLAS32_jll", "Quadmath", "SparseArrays"] -git-tree-sha1 = "4898d678a6f7549c41bd9f187233f979da18bc36" +git-tree-sha1 = "20e883b46d2a06ccd37d516b1f5415aa97d97655" uuid = "34c5aeac-e683-54a6-a0e9-6e0fdc586c50" -version = "0.5.1" +version = "0.5.2" [[deps.HSL_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] @@ -922,9 +921,9 @@ version = "2.12.2+0" [[deps.IOCapture]] deps = ["Logging", "Random"] -git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +git-tree-sha1 = "0ee181ec08df7d7c911901ea38baf16f755114dc" uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" -version = "0.2.5" +version = "1.0.0" [[deps.IfElse]] git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" @@ -986,9 +985,9 @@ version = "1.3.1" [[deps.Ipopt]] deps = ["Ipopt_jll", "LinearAlgebra", "OpenBLAS32_jll", "PrecompileTools"] -git-tree-sha1 = "84be69cbb8229dd4ac8776f37d4cfd0a16a44482" +git-tree-sha1 = "30feb540d41fbc54ca46cc9d811380bf7c8877d9" uuid = "b6b21f68-93f8-5de0-b562-5493be1d77c9" -version = "1.12.1" +version = "1.14.0" [deps.Ipopt.extensions] IpoptMathOptInterfaceExt = "MathOptInterface" @@ -998,9 +997,9 @@ version = "1.12.1" [[deps.Ipopt_jll]] deps = ["ASL_jll", "Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "MUMPS_seq_jll", "SPRAL_jll", "libblastrampoline_jll"] -git-tree-sha1 = "b33cbc78b8d4de87d18fcd705054a82e2999dbac" +git-tree-sha1 = "8e9d217c63a8c8af96949300180ba0558f7f88b5" uuid = "9cc047cb-c261-5740-88fc-0cf96f7bdcc7" -version = "300.1400.1900+0" +version = "300.1400.1901+0" [[deps.IrrationalConstants]] git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" @@ -1014,9 +1013,9 @@ version = "1.0.0" [[deps.JLD2]] deps = ["ChunkCodecLibZlib", "ChunkCodecLibZstd", "FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues"] -git-tree-sha1 = "da2e9b4d1abbebdcca0aa68afa0aa272102baad7" +git-tree-sha1 = "8f8ff711442d1f4cfc0d86133e7ee03d62ec9b98" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.6.2" +version = "0.6.3" weakdeps = ["UnPack"] [deps.JLD2.extensions] @@ -1060,9 +1059,9 @@ version = "0.2.1" [[deps.JpegTurbo_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +git-tree-sha1 = "b6893345fd6658c8e475d40155789f4860ac3b21" uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "3.1.3+0" +version = "3.1.4+0" [[deps.JuliaSyntaxHighlighting]] deps = ["StyledStrings"] @@ -1083,15 +1082,15 @@ version = "0.14.10" [[deps.KNITRO_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "bdf7d90222a1624de37928c5847425194bf9c8ff" +git-tree-sha1 = "f1fa02f8494c06bf1b3f771b3e090095db4403b9" uuid = "0e6b36f8-8e90-4eb5-b54e-06f667ea875c" -version = "15.0.1" +version = "15.1.0" [[deps.Krylov]] deps = ["LinearAlgebra", "Printf", "SparseArrays"] -git-tree-sha1 = "d1fc961038207e43982851e57ee257adc37be5e8" +git-tree-sha1 = "09895a8e17b0aa97df8964ed13c94d1b6d9de666" uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" -version = "0.10.2" +version = "0.10.3" [[deps.LAME_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1157,24 +1156,6 @@ git-tree-sha1 = "0f2da712350b020bc3957f269c9caad516383ee0" uuid = "0e77f7df-68c5-4e49-93ce-4cd80f5598bf" version = "1.3.0" -[[deps.LazyArrays]] -deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "MacroTools", "SparseArrays"] -git-tree-sha1 = "79ee64f6ba0a5a49930f51c86f60d7526b5e12c8" -uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02" -version = "2.8.0" - - [deps.LazyArrays.extensions] - LazyArraysBandedMatricesExt = "BandedMatrices" - LazyArraysBlockArraysExt = "BlockArrays" - LazyArraysBlockBandedMatricesExt = "BlockBandedMatrices" - LazyArraysStaticArraysExt = "StaticArrays" - - [deps.LazyArrays.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - [[deps.LazyArtifacts]] deps = ["Artifacts", "Pkg"] uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" @@ -1246,20 +1227,20 @@ uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" version = "2.41.2+0" [[deps.LineSearch]] -deps = ["ADTypes", "CommonSolve", "ConcreteStructs", "FastClosures", "LinearAlgebra", "MaybeInplace", "SciMLBase", "SciMLJacobianOperators", "StaticArraysCore"] -git-tree-sha1 = "97d502765cc5cf3a722120f50da03c2474efce04" +deps = ["ADTypes", "CommonSolve", "ConcreteStructs", "FastClosures", "LinearAlgebra", "MaybeInplace", "PrecompileTools", "SciMLBase", "SciMLJacobianOperators", "StaticArraysCore"] +git-tree-sha1 = "9f7253c0574b4b585c8909232adb890930da980a" uuid = "87fe0de2-c867-4266-b59a-2f0a94fc965b" -version = "0.1.4" +version = "0.1.6" weakdeps = ["LineSearches"] [deps.LineSearch.extensions] LineSearchLineSearchesExt = "LineSearches" [[deps.LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] -git-tree-sha1 = "4adee99b7262ad2a1a4bbbc59d993d24e55ea96f" +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Printf"] +git-tree-sha1 = "738bdcacfef25b3a9e4a39c28613717a6b23751e" uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.4.0" +version = "7.6.0" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] @@ -1289,10 +1270,10 @@ version = "2.11.0" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" [[deps.LinearSolve]] -deps = ["ArrayInterface", "ChainRulesCore", "ConcreteStructs", "DocStringExtensions", "EnumX", "GPUArraysCore", "InteractiveUtils", "Krylov", "LazyArrays", "Libdl", "LinearAlgebra", "MKL_jll", "Markdown", "OpenBLAS_jll", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLLogging", "SciMLOperators", "Setfield", "StaticArraysCore", "UnPack"] -git-tree-sha1 = "b5def83652705bdc00035dff671039e707588a00" +deps = ["ArrayInterface", "ChainRulesCore", "ConcreteStructs", "DocStringExtensions", "EnumX", "GPUArraysCore", "InteractiveUtils", "Krylov", "Libdl", "LinearAlgebra", "MKL_jll", "Markdown", "OpenBLAS_jll", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLLogging", "SciMLOperators", "Setfield", "StaticArraysCore"] +git-tree-sha1 = "1fdeafa25801ec2e0caa88fbe0afd7c41d3d087a" uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -version = "3.46.1" +version = "3.57.0" [deps.LinearSolve.extensions] LinearSolveAMDGPUExt = "AMDGPU" @@ -1303,7 +1284,7 @@ version = "3.46.1" LinearSolveCUDSSExt = "CUDSS" LinearSolveCUSOLVERRFExt = ["CUSOLVERRF", "SparseArrays"] LinearSolveCliqueTreesExt = ["CliqueTrees", "SparseArrays"] - LinearSolveEnzymeExt = "EnzymeCore" + LinearSolveEnzymeExt = ["EnzymeCore", "SparseArrays"] LinearSolveFastAlmostBandedMatricesExt = "FastAlmostBandedMatrices" LinearSolveFastLapackInterfaceExt = "FastLapackInterface" LinearSolveForwardDiffExt = "ForwardDiff" @@ -1400,9 +1381,9 @@ version = "0.4.17" [[deps.MUMPS_seq_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "METIS_jll", "libblastrampoline_jll"] -git-tree-sha1 = "fc0c8442887b48c15aec2b1787a5fc812a99b2fd" +git-tree-sha1 = "afbaaa0fa2f001ad8091e27885d69973f8eae3d7" uuid = "d7ed1dd3-d0ae-5e8e-bfb4-87a502085b8d" -version = "500.800.100+0" +version = "500.800.200+0" [[deps.MacroTools]] git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" @@ -1461,14 +1442,14 @@ version = "1.1.9" [[deps.MbedTLS_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3cce3511ca2c6f87b19c34ffc623417ed2798cbd" +git-tree-sha1 = "ff69a2b1330bcb730b9ac1ab7dd680176f5896b8" uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.10+0" +version = "2.28.1010+0" [[deps.Measures]] -git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102" +git-tree-sha1 = "b513cedd20d9c914783d8ad83d08120702bf2c77" uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" -version = "0.3.2" +version = "0.3.3" [[deps.Missings]] deps = ["DataAPI"] @@ -1497,15 +1478,15 @@ version = "0.2.4" [[deps.NLPModels]] deps = ["FastClosures", "LinearAlgebra", "LinearOperators", "Printf", "SparseArrays"] -git-tree-sha1 = "ac58082a07f0bd559292e869770d462d7ad0a7e2" +git-tree-sha1 = "c7a422b71bf5568f7e25ebb0ec47d0800445bd2e" uuid = "a4795742-8479-5a88-8948-cc11e1c8c1a6" -version = "0.21.5" +version = "0.21.7" [[deps.NLPModelsIpopt]] -deps = ["Ipopt", "NLPModels", "SolverCore"] -git-tree-sha1 = "06782efc249b21d7b7c538fec4593d72420a36e3" +deps = ["Ipopt", "NLPModels", "NLPModelsModifiers", "SolverCore"] +git-tree-sha1 = "7c6b8ff5258756b7d50e7b63283f789ca9e9de05" uuid = "f4238b75-b362-5c4c-b852-0801c9a21d71" -version = "0.10.4" +version = "0.11.1" [[deps.NLPModelsKnitro]] deps = ["KNITRO", "NLPModels", "NLPModelsModifiers", "SolverCore"] @@ -1520,10 +1501,10 @@ uuid = "e01155f1-5c6f-4375-a9d8-616dd036575f" version = "0.7.2" [[deps.NLSolversBase]] -deps = ["ADTypes", "DifferentiationInterface", "Distributed", "FiniteDiff", "ForwardDiff"] -git-tree-sha1 = "25a6638571a902ecfb1ae2a18fc1575f86b1d4df" +deps = ["ADTypes", "DifferentiationInterface", "FiniteDiff", "LinearAlgebra"] +git-tree-sha1 = "b3f76b463c7998473062992b246045e6961a074e" uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.10.0" +version = "8.0.0" [[deps.NaNMath]] deps = ["OpenLibm_jll"] @@ -1536,10 +1517,10 @@ uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.3.0" [[deps.NonlinearSolve]] -deps = ["ADTypes", "ArrayInterface", "BracketingNonlinearSolve", "CommonSolve", "ConcreteStructs", "DifferentiationInterface", "FastClosures", "FiniteDiff", "ForwardDiff", "LineSearch", "LinearAlgebra", "LinearSolve", "NonlinearSolveBase", "NonlinearSolveFirstOrder", "NonlinearSolveQuasiNewton", "NonlinearSolveSpectralMethods", "PrecompileTools", "Preferences", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "StaticArraysCore", "SymbolicIndexingInterface"] -git-tree-sha1 = "1d091cfece012662b06d25c792b3a43a0804c47b" +deps = ["ADTypes", "ArrayInterface", "BracketingNonlinearSolve", "CommonSolve", "ConcreteStructs", "DifferentiationInterface", "FastClosures", "FiniteDiff", "ForwardDiff", "LineSearch", "LinearAlgebra", "LinearSolve", "NonlinearSolveBase", "NonlinearSolveFirstOrder", "NonlinearSolveQuasiNewton", "NonlinearSolveSpectralMethods", "PrecompileTools", "Preferences", "Reexport", "SciMLBase", "SciMLLogging", "SimpleNonlinearSolve", "StaticArraysCore", "SymbolicIndexingInterface"] +git-tree-sha1 = "5db62e7c18af752a7a5260ed7576e7429ca87be4" uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" -version = "4.12.0" +version = "4.14.0" [deps.NonlinearSolve.extensions] NonlinearSolveFastLevenbergMarquardtExt = "FastLevenbergMarquardt" @@ -1569,10 +1550,10 @@ version = "4.12.0" Sundials = "c3572dad-4567-51f8-b174-8c6c989267f4" [[deps.NonlinearSolveBase]] -deps = ["ADTypes", "Adapt", "ArrayInterface", "CommonSolve", "Compat", "ConcreteStructs", "DifferentiationInterface", "EnzymeCore", "FastClosures", "LinearAlgebra", "Markdown", "MaybeInplace", "Preferences", "Printf", "RecursiveArrayTools", "SciMLBase", "SciMLJacobianOperators", "SciMLOperators", "SciMLStructures", "Setfield", "StaticArraysCore", "SymbolicIndexingInterface", "TimerOutputs"] -git-tree-sha1 = "9dba8e7ccfaf4c10b3a3b4cc52abf639f8558efd" +deps = ["ADTypes", "Adapt", "ArrayInterface", "CommonSolve", "Compat", "ConcreteStructs", "DifferentiationInterface", "EnzymeCore", "FastClosures", "LinearAlgebra", "Markdown", "MaybeInplace", "Preferences", "Printf", "RecursiveArrayTools", "SciMLBase", "SciMLJacobianOperators", "SciMLLogging", "SciMLOperators", "SciMLStructures", "Setfield", "StaticArraysCore", "SymbolicIndexingInterface", "TimerOutputs"] +git-tree-sha1 = "db10be07416f36da7928e2a934047948cb6430ad" uuid = "be0214bd-f91f-a760-ac4e-3421ce2b2da0" -version = "2.0.0" +version = "2.9.1" [deps.NonlinearSolveBase.extensions] NonlinearSolveBaseBandedMatricesExt = "BandedMatrices" @@ -1602,15 +1583,15 @@ version = "2.0.0" [[deps.NonlinearSolveFirstOrder]] deps = ["ADTypes", "ArrayInterface", "CommonSolve", "ConcreteStructs", "FiniteDiff", "ForwardDiff", "LineSearch", "LinearAlgebra", "LinearSolve", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase", "SciMLJacobianOperators", "Setfield", "StaticArraysCore"] -git-tree-sha1 = "01c48c37ba47721ec6489a1668ab3bb1f5b603c0" +git-tree-sha1 = "bd6bb56e107fe9bea276982a03b8ed13332583b4" uuid = "5959db7a-ea39-4486-b5fe-2dd0bf03d60d" -version = "1.9.0" +version = "1.11.0" [[deps.NonlinearSolveQuasiNewton]] deps = ["ArrayInterface", "CommonSolve", "ConcreteStructs", "LinearAlgebra", "LinearSolve", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase", "SciMLOperators", "StaticArraysCore"] -git-tree-sha1 = "a233b7bbb32426170b238e2e2b82b0f9f1c5caba" +git-tree-sha1 = "ade27e8e9566b6cec63ee62f6a6650a11cf9a2eb" uuid = "9a2c21bd-3a47-402d-9113-8faf9a0ee114" -version = "1.10.0" +version = "1.12.0" weakdeps = ["ForwardDiff"] [deps.NonlinearSolveQuasiNewton.extensions] @@ -1618,9 +1599,9 @@ weakdeps = ["ForwardDiff"] [[deps.NonlinearSolveSpectralMethods]] deps = ["CommonSolve", "ConcreteStructs", "LineSearch", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "139bf9211930a829703481b3ffd86b1ab309cd07" +git-tree-sha1 = "eafd027b5cd768f19bb5de76c0e908a9065ddd36" uuid = "26075421-4e9a-44e1-8bd1-420ed7ad02b2" -version = "1.5.0" +version = "1.6.0" weakdeps = ["ForwardDiff"] [deps.NonlinearSolveSpectralMethods.extensions] @@ -1664,10 +1645,10 @@ uuid = "9bd350c2-7e96-507f-8002-3f2e150b4e1b" version = "10.2.1+0" [[deps.OpenSSL]] -deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "NetworkOptions", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "1d1aaa7d449b58415f97d2839c318b70ffb525a0" uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.5.0" +version = "1.6.1" [[deps.OpenSSL_jll]] deps = ["Artifacts", "Libdl"] @@ -1684,13 +1665,13 @@ version = "0.5.6+0" deps = ["ADNLPModels", "CTBase", "CTDirect", "CTFlows", "CTModels", "CTParser", "CommonSolve", "DocStringExtensions", "ExaModels", "RecipesBase"] path = "/Users/ocots/Research/logiciels/dev/control-toolbox/OptimalControl" uuid = "5f98b655-cc9a-415a-b60e-744165666948" -version = "1.1.5" +version = "1.1.7" [[deps.Opus_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "c392fc5dd032381919e3b22dd32d6443760ce7ea" +git-tree-sha1 = "39a11854f0cba27aa41efaedf43c77c5daa6be51" uuid = "91d4177d-7536-5919-b921-800302f37372" -version = "1.5.2+0" +version = "1.6.0+0" [[deps.OrderedCollections]] git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" @@ -1698,28 +1679,28 @@ uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" version = "1.8.1" [[deps.OrdinaryDiffEq]] -deps = ["ADTypes", "Adapt", "ArrayInterface", "CommonSolve", "DataStructures", "DiffEqBase", "DocStringExtensions", "EnumX", "ExponentialUtilities", "FastBroadcast", "FastClosures", "FillArrays", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "InteractiveUtils", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "MacroTools", "MuladdMacro", "NonlinearSolve", "OrdinaryDiffEqAdamsBashforthMoulton", "OrdinaryDiffEqBDF", "OrdinaryDiffEqCore", "OrdinaryDiffEqDefault", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqExplicitRK", "OrdinaryDiffEqExponentialRK", "OrdinaryDiffEqExtrapolation", "OrdinaryDiffEqFIRK", "OrdinaryDiffEqFeagin", "OrdinaryDiffEqFunctionMap", "OrdinaryDiffEqHighOrderRK", "OrdinaryDiffEqIMEXMultistep", "OrdinaryDiffEqLinear", "OrdinaryDiffEqLowOrderRK", "OrdinaryDiffEqLowStorageRK", "OrdinaryDiffEqNonlinearSolve", "OrdinaryDiffEqNordsieck", "OrdinaryDiffEqPDIRK", "OrdinaryDiffEqPRK", "OrdinaryDiffEqQPRK", "OrdinaryDiffEqRKN", "OrdinaryDiffEqRosenbrock", "OrdinaryDiffEqSDIRK", "OrdinaryDiffEqSSPRK", "OrdinaryDiffEqStabilizedIRK", "OrdinaryDiffEqStabilizedRK", "OrdinaryDiffEqSymplecticRK", "OrdinaryDiffEqTsit5", "OrdinaryDiffEqVerner", "Polyester", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SciMLStructures", "SimpleNonlinearSolve", "SimpleUnPack", "SparseArrays", "Static", "StaticArrayInterface", "StaticArrays", "TruncatedStacktraces"] -git-tree-sha1 = "89172157d16139165d470602f1e552484b357771" +deps = ["ADTypes", "Adapt", "ArrayInterface", "CommonSolve", "DataStructures", "DiffEqBase", "DocStringExtensions", "EnumX", "ExponentialUtilities", "FastBroadcast", "FastClosures", "FillArrays", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "InteractiveUtils", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "MacroTools", "MuladdMacro", "NonlinearSolve", "OrdinaryDiffEqAdamsBashforthMoulton", "OrdinaryDiffEqBDF", "OrdinaryDiffEqCore", "OrdinaryDiffEqDefault", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqExplicitRK", "OrdinaryDiffEqExponentialRK", "OrdinaryDiffEqExtrapolation", "OrdinaryDiffEqFIRK", "OrdinaryDiffEqFeagin", "OrdinaryDiffEqFunctionMap", "OrdinaryDiffEqHighOrderRK", "OrdinaryDiffEqIMEXMultistep", "OrdinaryDiffEqLinear", "OrdinaryDiffEqLowOrderRK", "OrdinaryDiffEqLowStorageRK", "OrdinaryDiffEqNonlinearSolve", "OrdinaryDiffEqNordsieck", "OrdinaryDiffEqPDIRK", "OrdinaryDiffEqPRK", "OrdinaryDiffEqQPRK", "OrdinaryDiffEqRKN", "OrdinaryDiffEqRosenbrock", "OrdinaryDiffEqSDIRK", "OrdinaryDiffEqSSPRK", "OrdinaryDiffEqStabilizedIRK", "OrdinaryDiffEqStabilizedRK", "OrdinaryDiffEqSymplecticRK", "OrdinaryDiffEqTsit5", "OrdinaryDiffEqVerner", "Polyester", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SciMLStructures", "SimpleNonlinearSolve", "SparseArrays", "Static", "StaticArrayInterface", "StaticArrays", "TruncatedStacktraces"] +git-tree-sha1 = "dc70b19f140e9cbd02864c96ccfc833cbc6b8dd7" uuid = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -version = "6.103.0" +version = "6.106.0" [[deps.OrdinaryDiffEqAdamsBashforthMoulton]] deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqLowOrderRK", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "09aae1486c767caa6bce9de892455cbdf5a6fbc8" +git-tree-sha1 = "8307937159c3aeec5f19f4b661d82d96d25a3ff1" uuid = "89bda076-bce5-4f1c-845f-551c83cdda9a" -version = "1.5.0" +version = "1.9.0" [[deps.OrdinaryDiffEqBDF]] deps = ["ADTypes", "ArrayInterface", "DiffEqBase", "FastBroadcast", "LinearAlgebra", "MacroTools", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "OrdinaryDiffEqSDIRK", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "StaticArrays", "TruncatedStacktraces"] -git-tree-sha1 = "ce8db53fd1e4e41c020fd53961e7314f75e4c21c" +git-tree-sha1 = "156f2623ac97e7cf340848ba606f1226998980af" uuid = "6ad6398a-0878-4a85-9266-38940aa047c8" -version = "1.10.1" +version = "1.14.0" [[deps.OrdinaryDiffEqCore]] -deps = ["ADTypes", "Accessors", "Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "EnumX", "FastBroadcast", "FastClosures", "FastPower", "FillArrays", "FunctionWrappersWrappers", "InteractiveUtils", "LinearAlgebra", "Logging", "MacroTools", "MuladdMacro", "Polyester", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SciMLStructures", "SimpleUnPack", "Static", "StaticArrayInterface", "StaticArraysCore", "SymbolicIndexingInterface", "TruncatedStacktraces"] -git-tree-sha1 = "4b68f9ca0cfa68cb9ee544df96391d47ca0e62a9" +deps = ["ADTypes", "Accessors", "Adapt", "ArrayInterface", "ConcreteStructs", "DataStructures", "DiffEqBase", "DocStringExtensions", "EnumX", "FastBroadcast", "FastClosures", "FastPower", "FillArrays", "FunctionWrappersWrappers", "InteractiveUtils", "LinearAlgebra", "Logging", "MacroTools", "MuladdMacro", "Polyester", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLLogging", "SciMLOperators", "SciMLStructures", "Static", "StaticArrayInterface", "StaticArraysCore", "SymbolicIndexingInterface", "TruncatedStacktraces"] +git-tree-sha1 = "8d8e8fd5c80b38c0cc2de5a8fcca8db1a2e77a06" uuid = "bbf590c4-e513-4bbe-9b18-05decba2e5d8" -version = "1.36.0" +version = "3.1.0" [deps.OrdinaryDiffEqCore.extensions] OrdinaryDiffEqCoreEnzymeCoreExt = "EnzymeCore" @@ -1731,15 +1712,15 @@ version = "1.36.0" [[deps.OrdinaryDiffEqDefault]] deps = ["ADTypes", "DiffEqBase", "EnumX", "LinearAlgebra", "LinearSolve", "OrdinaryDiffEqBDF", "OrdinaryDiffEqCore", "OrdinaryDiffEqRosenbrock", "OrdinaryDiffEqTsit5", "OrdinaryDiffEqVerner", "PrecompileTools", "Preferences", "Reexport", "SciMLBase"] -git-tree-sha1 = "7d5ddeee97e1bdcc848f1397cbc3d03bd57f33e7" +git-tree-sha1 = "eef7a901d2a38462c13c12a39da7876c7b9b4a25" uuid = "50262376-6c5a-4cf5-baba-aaf4f84d72d7" -version = "1.8.0" +version = "1.12.0" [[deps.OrdinaryDiffEqDifferentiation]] deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "ConstructionBase", "DiffEqBase", "DifferentiationInterface", "FastBroadcast", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "LinearAlgebra", "LinearSolve", "OrdinaryDiffEqCore", "SciMLBase", "SciMLOperators", "SparseMatrixColorings", "StaticArrayInterface", "StaticArrays"] -git-tree-sha1 = "320b5f3e4e61ca0ad863c63c803f69973ba6efce" +git-tree-sha1 = "c3706545346a550a2669d8bcfe6db683af04a21c" uuid = "4302a76b-040a-498a-8c04-15b101fed76b" -version = "1.16.1" +version = "1.22.0" weakdeps = ["SparseArrays"] [deps.OrdinaryDiffEqDifferentiation.extensions] @@ -1747,153 +1728,153 @@ weakdeps = ["SparseArrays"] [[deps.OrdinaryDiffEqExplicitRK]] deps = ["DiffEqBase", "FastBroadcast", "LinearAlgebra", "MuladdMacro", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "TruncatedStacktraces"] -git-tree-sha1 = "4c0633f587395d7aaec0679dc649eb03fcc74e73" +git-tree-sha1 = "9d9b6bc309574d95acbf52e0f98a163f670e8dee" uuid = "9286f039-9fbf-40e8-bf65-aa933bdc4db0" -version = "1.4.0" +version = "1.8.0" [[deps.OrdinaryDiffEqExponentialRK]] deps = ["ADTypes", "DiffEqBase", "ExponentialUtilities", "FastBroadcast", "LinearAlgebra", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "RecursiveArrayTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "3b81416ff11e55ea0ae7b449efc818256d9d450b" +git-tree-sha1 = "65f2e40d7e9b1415c41838ec762777a4c36e4804" uuid = "e0540318-69ee-4070-8777-9e2de6de23de" -version = "1.8.0" +version = "1.12.0" [[deps.OrdinaryDiffEqExtrapolation]] deps = ["ADTypes", "DiffEqBase", "FastBroadcast", "FastPower", "LinearSolve", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "9e1b11cf448a2c1bca640103c1c848a20aa2f967" +git-tree-sha1 = "e2f3ebd6cd7ed9c8d551fb10192644e8f6dd3cbb" uuid = "becaefa8-8ca2-5cf9-886d-c06f3d2bd2c4" -version = "1.9.0" +version = "1.13.0" [[deps.OrdinaryDiffEqFIRK]] deps = ["ADTypes", "DiffEqBase", "FastBroadcast", "FastGaussQuadrature", "FastPower", "LinearAlgebra", "LinearSolve", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators"] -git-tree-sha1 = "b968d66de3de5ffcf18544bc202ca792bad20710" +git-tree-sha1 = "cbb6a36f09f1357a526c55a0a6805b60121eafb8" uuid = "5960d6e9-dd7a-4743-88e7-cf307b64f125" -version = "1.16.0" +version = "1.20.0" [[deps.OrdinaryDiffEqFeagin]] deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "815b54211201ec42b8829e0275ab3c9632d16cbe" +git-tree-sha1 = "b123f64a8635a712ceb037a7d2ffe2a1875325d3" uuid = "101fe9f7-ebb6-4678-b671-3a81e7194747" -version = "1.4.0" +version = "1.8.0" [[deps.OrdinaryDiffEqFunctionMap]] deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "fe750e4b8c1b1b9e1c1319ff2e052e83ad57b3ac" +git-tree-sha1 = "cbd291508808caf10cf455f974c2025e886ed2a3" uuid = "d3585ca7-f5d3-4ba6-8057-292ed1abd90f" -version = "1.5.0" +version = "1.9.0" [[deps.OrdinaryDiffEqHighOrderRK]] deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "42096f72136078fa02804515f1748ddeb1f0d47d" +git-tree-sha1 = "9584dcc90cf10216de7aa0f2a1edc0f54d254cf6" uuid = "d28bc4f8-55e1-4f49-af69-84c1a99f0f58" -version = "1.5.0" +version = "1.9.0" [[deps.OrdinaryDiffEqIMEXMultistep]] deps = ["ADTypes", "DiffEqBase", "FastBroadcast", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "Reexport", "SciMLBase"] -git-tree-sha1 = "a5dcd75959dada0005b1707a5ca9359faa1734ba" +git-tree-sha1 = "23602428114124a3e3df85fcbc5b461c79fb91bf" uuid = "9f002381-b378-40b7-97a6-27a27c83f129" -version = "1.7.0" +version = "1.11.0" [[deps.OrdinaryDiffEqLinear]] deps = ["DiffEqBase", "ExponentialUtilities", "LinearAlgebra", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators"] -git-tree-sha1 = "925fc0136e8128fd19abf126e9358ec1f997390f" +git-tree-sha1 = "c92913fa5942ed9bc748f3e79a5c693c8ec0c3d7" uuid = "521117fe-8c41-49f8-b3b6-30780b3f0fb5" -version = "1.6.0" +version = "1.10.0" [[deps.OrdinaryDiffEqLowOrderRK]] deps = ["DiffEqBase", "FastBroadcast", "LinearAlgebra", "MuladdMacro", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "3cc4987c8e4725276b55a52e08b56ded4862917e" +git-tree-sha1 = "78223e34d4988070443465cd3f2bdc38d6bd14b0" uuid = "1344f307-1e59-4825-a18e-ace9aa3fa4c6" -version = "1.6.0" +version = "1.10.0" [[deps.OrdinaryDiffEqLowStorageRK]] deps = ["Adapt", "DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static", "StaticArrays"] -git-tree-sha1 = "e6bd0a7fb6643a57b06a90415608a81aaf7bd772" +git-tree-sha1 = "708c362418bd4503fd158f4f4e53151fbe57b46a" uuid = "b0944070-b475-4768-8dec-fb6eb410534d" -version = "1.7.0" +version = "1.11.0" [[deps.OrdinaryDiffEqNonlinearSolve]] -deps = ["ADTypes", "ArrayInterface", "DiffEqBase", "FastBroadcast", "FastClosures", "ForwardDiff", "LinearAlgebra", "LinearSolve", "MuladdMacro", "NonlinearSolve", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "PreallocationTools", "RecursiveArrayTools", "SciMLBase", "SciMLOperators", "SciMLStructures", "SimpleNonlinearSolve", "StaticArrays"] -git-tree-sha1 = "f59c1c07cfa674c1d3f5dd386c4274d9bc2be221" +deps = ["ADTypes", "ArrayInterface", "DiffEqBase", "FastBroadcast", "FastClosures", "ForwardDiff", "LinearAlgebra", "LinearSolve", "MuladdMacro", "NonlinearSolve", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "PreallocationTools", "RecursiveArrayTools", "SciMLBase", "SciMLOperators", "SciMLStructures", "SimpleNonlinearSolve", "SparseArrays", "StaticArrays"] +git-tree-sha1 = "9f0be4bd586829a28a04c8f923598497f56ac226" uuid = "127b3ac7-2247-4354-8eb6-78cf4e7c58e8" -version = "1.15.0" +version = "1.19.0" [[deps.OrdinaryDiffEqNordsieck]] deps = ["DiffEqBase", "FastBroadcast", "LinearAlgebra", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqTsit5", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "c90aa7fa0d725472c4098096adf6a08266c2f682" +git-tree-sha1 = "05f3319c3bf1440897dc613194eb3db4d2d3e692" uuid = "c9986a66-5c92-4813-8696-a7ec84c806c8" -version = "1.4.0" +version = "1.8.0" [[deps.OrdinaryDiffEqPDIRK]] deps = ["ADTypes", "DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "Polyester", "Reexport", "SciMLBase", "StaticArrays"] -git-tree-sha1 = "9d599d2eafdf74ab26ea6bf3feb28183a2ade143" +git-tree-sha1 = "7d63467f59f6504672ba93226f156f99c6095f60" uuid = "5dd0a6cf-3d4b-4314-aa06-06d4e299bc89" -version = "1.6.0" +version = "1.10.0" [[deps.OrdinaryDiffEqPRK]] deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "Reexport", "SciMLBase"] -git-tree-sha1 = "8e35132689133255be6d63df4190b5fc97b6cf2b" +git-tree-sha1 = "baa77b7f874cda1f58f8c793fc7a9778e78a91c5" uuid = "5b33eab2-c0f1-4480-b2c3-94bc1e80bda1" -version = "1.4.0" +version = "1.8.0" [[deps.OrdinaryDiffEqQPRK]] deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "63fb643a956b27cd0e33a3c6d910c3c118082e0f" +git-tree-sha1 = "9e351a8f923c843adb48945318437e051f6ee139" uuid = "04162be5-8125-4266-98ed-640baecc6514" -version = "1.4.0" +version = "1.8.0" [[deps.OrdinaryDiffEqRKN]] deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "a31c41f9dbea7c7179c6e544c25c7e144d63868c" +git-tree-sha1 = "98e22bd36729281743f77dd87a6036a9c3611370" uuid = "af6ede74-add8-4cfd-b1df-9a4dbb109d7a" -version = "1.5.0" +version = "1.9.0" [[deps.OrdinaryDiffEqRosenbrock]] deps = ["ADTypes", "DiffEqBase", "DifferentiationInterface", "FastBroadcast", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "LinearSolve", "MacroTools", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "Polyester", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "f34bc2f58656843596d09a4c4de8c20724ebc2f1" +git-tree-sha1 = "e4605c3930703b5d38083ce1a998ee824dd67266" uuid = "43230ef6-c299-4910-a778-202eb28ce4ce" -version = "1.18.1" +version = "1.22.0" [[deps.OrdinaryDiffEqSDIRK]] deps = ["ADTypes", "DiffEqBase", "FastBroadcast", "LinearAlgebra", "MacroTools", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "RecursiveArrayTools", "Reexport", "SciMLBase", "TruncatedStacktraces"] -git-tree-sha1 = "20caa72c004414435fb5769fadb711e96ed5bcd4" +git-tree-sha1 = "5d0a230f4e431e53af19502eaea8778f8f15edd4" uuid = "2d112036-d095-4a1e-ab9a-08536f3ecdbf" -version = "1.7.0" +version = "1.11.0" [[deps.OrdinaryDiffEqSSPRK]] deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static", "StaticArrays"] -git-tree-sha1 = "3bce87977264916bd92455754ab336faec68bf8a" +git-tree-sha1 = "8abc61382a0c6469aa9c3bff2d61c9925a088320" uuid = "669c94d9-1f4b-4b64-b377-1aa079aa2388" -version = "1.7.0" +version = "1.11.0" [[deps.OrdinaryDiffEqStabilizedIRK]] deps = ["ADTypes", "DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "OrdinaryDiffEqStabilizedRK", "RecursiveArrayTools", "Reexport", "SciMLBase", "StaticArrays"] -git-tree-sha1 = "75abe7462f4b0b2a2463bb512c8a5458bbd39185" +git-tree-sha1 = "1719060baf014a3c1a6506113bc09d82a0903f0e" uuid = "e3e12d00-db14-5390-b879-ac3dd2ef6296" -version = "1.6.0" +version = "1.10.0" [[deps.OrdinaryDiffEqStabilizedRK]] deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "StaticArrays"] -git-tree-sha1 = "7e94d3d1b3528b4bcf9e0248198ee0a2fd65a697" +git-tree-sha1 = "d156a972fa7bc37bf8377d33a7d51d152e354d4c" uuid = "358294b1-0aab-51c3-aafe-ad5ab194a2ad" -version = "1.4.0" +version = "1.8.0" [[deps.OrdinaryDiffEqSymplecticRK]] deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "e8dd5ab225287947016dc144a5ded1fb83885638" +git-tree-sha1 = "9b783806fe2dc778649231cb3932cb71b63222d9" uuid = "fa646aed-7ef9-47eb-84c4-9443fc8cbfa8" -version = "1.7.0" +version = "1.11.0" [[deps.OrdinaryDiffEqTsit5]] deps = ["DiffEqBase", "FastBroadcast", "LinearAlgebra", "MuladdMacro", "OrdinaryDiffEqCore", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static", "TruncatedStacktraces"] -git-tree-sha1 = "778c7d379265f17f40dbe9aaa6f6a2a08bc7fa3e" +git-tree-sha1 = "8be4cba85586cd2efa6c76d1792c548758610901" uuid = "b1df2697-797e-41e3-8120-5422d3b24e4a" -version = "1.5.0" +version = "1.9.0" [[deps.OrdinaryDiffEqVerner]] deps = ["DiffEqBase", "FastBroadcast", "LinearAlgebra", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static", "TruncatedStacktraces"] -git-tree-sha1 = "185578fa7c38119d4318326f9375f1cba0f0ce53" +git-tree-sha1 = "7c50b87bc8f00a38ef7acb8457828585f9ba4300" uuid = "79d7bb75-1356-48c1-b8c0-6832512096c2" -version = "1.6.0" +version = "1.10.0" [[deps.PCRE2_jll]] deps = ["Artifacts", "Libdl"] @@ -1902,9 +1883,9 @@ version = "10.44.0+1" [[deps.Pango_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1f7f9bbd5f7a2e5a9f7d96e51c9754454ea7f60b" +git-tree-sha1 = "0662b083e11420952f2e62e17eddae7fc07d5997" uuid = "36c8627f-9965-5494-a995-c6b170f724f3" -version = "1.56.4+0" +version = "1.57.0+0" [[deps.Parameters]] deps = ["OrderedCollections", "UnPack"] @@ -1941,15 +1922,15 @@ version = "3.3.0" [[deps.PlotUtils]] deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"] -git-tree-sha1 = "3ca9a356cd2e113c420f2c13bea19f8d3fb1cb18" +git-tree-sha1 = "26ca162858917496748aad52bb5d3be4d26a228a" uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "1.4.3" +version = "1.4.4" [[deps.Plots]] deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "TOML", "UUIDs", "UnicodeFun", "Unzip"] -git-tree-sha1 = "12ce661880f8e309569074a61d3767e5756a199f" +git-tree-sha1 = "063ef757a1e0e15af77bbe92be92da672793fd4e" uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -version = "1.41.1" +version = "1.41.4" [deps.Plots.extensions] FileIOExt = "FileIO" @@ -1985,9 +1966,9 @@ version = "1.4.3" [[deps.PreallocationTools]] deps = ["Adapt", "ArrayInterface", "PrecompileTools"] -git-tree-sha1 = "c05b4c6325262152483a1ecb6c69846d2e01727b" +git-tree-sha1 = "6c6925c42710b794dbb8fe7ab0cbc393c5b59fbe" uuid = "d236fae5-4411-538c-8e31-a6e3d9e00b46" -version = "0.4.34" +version = "1.0.0" weakdeps = ["ForwardDiff", "ReverseDiff", "SparseConnectivityTracer"] [deps.PreallocationTools.extensions] @@ -2003,15 +1984,15 @@ version = "1.3.3" [[deps.Preferences]] deps = ["TOML"] -git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +git-tree-sha1 = "522f093a29b31a93e34eaea17ba055d850edea28" uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.5.0" +version = "1.5.1" [[deps.PrettyTables]] deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "6b8e2f0bae3f678811678065c09571c1619da219" +git-tree-sha1 = "c5a07210bd060d6a8491b0ccdee2fa0235fc00bf" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "3.1.0" +version = "3.1.2" [[deps.Printf]] deps = ["Unicode"] @@ -2086,10 +2067,10 @@ uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" version = "0.6.12" [[deps.RecursiveArrayTools]] -deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "LinearAlgebra", "RecipesBase", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface"] -git-tree-sha1 = "51bdb23afaaa551f923a0e990f7c44a4451a26f1" +deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "LinearAlgebra", "PrecompileTools", "RecipesBase", "StaticArraysCore", "SymbolicIndexingInterface"] +git-tree-sha1 = "31b3d7b7e14faad39583475b89aadbd9c3e7ef8b" uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "3.39.0" +version = "3.44.0" [deps.RecursiveArrayTools.extensions] RecursiveArrayToolsFastBroadcastExt = "FastBroadcast" @@ -2099,6 +2080,7 @@ version = "3.39.0" RecursiveArrayToolsMonteCarloMeasurementsExt = "MonteCarloMeasurements" RecursiveArrayToolsReverseDiffExt = ["ReverseDiff", "Zygote"] RecursiveArrayToolsSparseArraysExt = ["SparseArrays"] + RecursiveArrayToolsStatisticsExt = "Statistics" RecursiveArrayToolsStructArraysExt = "StructArrays" RecursiveArrayToolsTablesExt = ["Tables"] RecursiveArrayToolsTrackerExt = "Tracker" @@ -2112,6 +2094,7 @@ version = "3.39.0" MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" @@ -2142,15 +2125,15 @@ version = "1.3.1" [[deps.ReverseDiff]] deps = ["ChainRulesCore", "DiffResults", "DiffRules", "ForwardDiff", "FunctionWrappers", "LinearAlgebra", "LogExpFunctions", "MacroTools", "NaNMath", "Random", "SpecialFunctions", "StaticArrays", "Statistics"] -git-tree-sha1 = "3ab8eee3620451b09f0272c271875b4bc02146d9" +git-tree-sha1 = "f1b07322a8cdc0d46812473b37fb72f69ec07b22" uuid = "37e2e3b7-166d-5795-8a7a-e32c996b4267" -version = "1.16.1" +version = "1.16.2" [[deps.RuntimeGeneratedFunctions]] deps = ["ExprTools", "SHA", "Serialization"] -git-tree-sha1 = "86a8a8b783481e1ea6b9c91dd949cb32191f8ab4" +git-tree-sha1 = "2f609ec2295c452685d3142bc4df202686e555d2" uuid = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47" -version = "0.5.15" +version = "0.5.16" [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" @@ -2163,15 +2146,15 @@ version = "0.1.0" [[deps.SPRAL_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "Libdl", "METIS_jll", "libblastrampoline_jll"] -git-tree-sha1 = "4f9833187a65ead66ed1907b44d5f20606282e3f" +git-tree-sha1 = "139fa63f03a16b3d859d925ee9149dfc15f21ece" uuid = "319450e9-13b8-58e8-aa9f-8fd1420848ab" -version = "2025.5.20+0" +version = "2025.9.18+0" [[deps.SciMLBase]] deps = ["ADTypes", "Accessors", "Adapt", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "Moshi", "PreallocationTools", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLLogging", "SciMLOperators", "SciMLPublic", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface"] -git-tree-sha1 = "7614a1b881317b6800a8c66eb1180c6ea5b986f3" +git-tree-sha1 = "9923adc7defeba6a52a99eb493ec317ac6c65942" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.124.0" +version = "2.134.0" [deps.SciMLBase.extensions] SciMLBaseChainRulesCoreExt = "ChainRulesCore" @@ -2214,21 +2197,21 @@ version = "2.124.0" [[deps.SciMLJacobianOperators]] deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "ConstructionBase", "DifferentiationInterface", "FastClosures", "LinearAlgebra", "SciMLBase", "SciMLOperators"] -git-tree-sha1 = "a273b291c90909ba6fe08402dd68e09aae423008" +git-tree-sha1 = "e96d5e96debf7f80a50d0b976a13dea556ccfd3a" uuid = "19f34311-ddf3-4b8b-af20-060888a46c0e" -version = "0.1.11" +version = "0.1.12" [[deps.SciMLLogging]] deps = ["Logging", "LoggingExtras", "Preferences"] -git-tree-sha1 = "5a026f5549ad167cda34c67b62f8d3dc55754da3" +git-tree-sha1 = "7eebb9985e35b123e12025a3a2ad020cd6059f71" uuid = "a6db7da4-7206-11f0-1eab-35f2a5dbe1d1" -version = "1.3.1" +version = "1.8.0" [[deps.SciMLOperators]] deps = ["Accessors", "ArrayInterface", "DocStringExtensions", "LinearAlgebra", "MacroTools"] -git-tree-sha1 = "c1053ba68ede9e4005fc925dd4e8723fcd96eef8" +git-tree-sha1 = "d1d14b15bbebf48dc80e8a7cfe640e2d835e22ea" uuid = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" -version = "1.9.0" +version = "1.14.1" weakdeps = ["SparseArrays", "StaticArraysCore"] [deps.SciMLOperators.extensions] @@ -2236,15 +2219,15 @@ weakdeps = ["SparseArrays", "StaticArraysCore"] SciMLOperatorsStaticArraysCoreExt = "StaticArraysCore" [[deps.SciMLPublic]] -git-tree-sha1 = "ed647f161e8b3f2973f24979ec074e8d084f1bee" +git-tree-sha1 = "0ba076dbdce87ba230fff48ca9bca62e1f345c9b" uuid = "431bcebd-1456-4ced-9d72-93c2757fff0b" -version = "1.0.0" +version = "1.0.1" [[deps.SciMLStructures]] -deps = ["ArrayInterface"] -git-tree-sha1 = "566c4ed301ccb2a44cbd5a27da5f885e0ed1d5df" +deps = ["ArrayInterface", "PrecompileTools"] +git-tree-sha1 = "607f6867d0b0553e98fc7f725c9f9f13b4d01a32" uuid = "53ae85a6-f571-4167-b2af-e1d143709226" -version = "1.7.0" +version = "1.10.0" [[deps.ScopedValues]] deps = ["HashArrayMappedTries", "Logging"] @@ -2260,9 +2243,9 @@ version = "1.3.0" [[deps.SentinelArrays]] deps = ["Dates", "Random"] -git-tree-sha1 = "712fb0231ee6f9120e005ccd56297abbc053e7e0" +git-tree-sha1 = "ebe7e59b37c400f694f52b58c93d26201387da70" uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.8" +version = "1.4.9" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" @@ -2292,9 +2275,9 @@ version = "1.2.0" [[deps.SimpleNonlinearSolve]] deps = ["ADTypes", "ArrayInterface", "BracketingNonlinearSolve", "CommonSolve", "ConcreteStructs", "DifferentiationInterface", "FastClosures", "FiniteDiff", "ForwardDiff", "LineSearch", "LinearAlgebra", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase", "Setfield", "StaticArraysCore"] -git-tree-sha1 = "8825064775bf4ae0f22d04ea63979d8c868fd510" +git-tree-sha1 = "315da09948861edbc6d18e066c08903487bb580d" uuid = "727e6d20-b764-4bd8-a329-72de5adea6c7" -version = "2.9.0" +version = "2.10.0" [deps.SimpleNonlinearSolve.extensions] SimpleNonlinearSolveChainRulesCoreExt = "ChainRulesCore" @@ -2306,20 +2289,19 @@ version = "2.9.0" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" -[[deps.SimpleUnPack]] -git-tree-sha1 = "58e6353e72cde29b90a69527e56df1b5c3d8c437" -uuid = "ce78b400-467f-4804-87d8-8f486da07d0a" -version = "1.1.0" - [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" version = "1.11.0" [[deps.SolverCore]] -deps = ["LinearAlgebra", "NLPModels", "Printf"] -git-tree-sha1 = "03a1e0d2d39b9ebc9510f2452c0adfbe887b9cb2" +deps = ["Printf"] +git-tree-sha1 = "83289e4a837c2cced03bf8efc138bbaf42f4983b" uuid = "ff4d7338-4cf1-434d-91df-b86cb86fb843" -version = "0.3.8" +version = "0.3.9" +weakdeps = ["NLPModels"] + + [deps.SolverCore.extensions] + SolverCoreNLPModelsExt = "NLPModels" [[deps.SortingAlgorithms]] deps = ["DataStructures"] @@ -2334,9 +2316,9 @@ version = "1.12.0" [[deps.SparseConnectivityTracer]] deps = ["ADTypes", "DocStringExtensions", "FillArrays", "LinearAlgebra", "Random", "SparseArrays"] -git-tree-sha1 = "ba6dc9b87304964647bd1c750b903cb360003a36" +git-tree-sha1 = "322365aa23098275562cbad6a1c2539ee40d9618" uuid = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" -version = "1.1.2" +version = "1.1.3" [deps.SparseConnectivityTracer.extensions] SparseConnectivityTracerChainRulesCoreExt = "ChainRulesCore" @@ -2354,19 +2336,22 @@ version = "1.1.2" [[deps.SparseMatrixColorings]] deps = ["ADTypes", "DocStringExtensions", "LinearAlgebra", "PrecompileTools", "Random", "SparseArrays"] -git-tree-sha1 = "d3f3b7bb8a561b5ff20ee7cf9574841ee4e4e137" +git-tree-sha1 = "6ed48d9a3b22417c765dc273ae3e1e4de035e7c8" uuid = "0a514795-09f3-496d-8182-132a7b665d35" -version = "0.4.22" +version = "0.4.23" [deps.SparseMatrixColorings.extensions] SparseMatrixColoringsCUDAExt = "CUDA" SparseMatrixColoringsCliqueTreesExt = "CliqueTrees" SparseMatrixColoringsColorsExt = "Colors" + SparseMatrixColoringsJuMPExt = ["JuMP", "MathOptInterface"] [deps.SparseMatrixColorings.weakdeps] CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" CliqueTrees = "60701a23-6482-424a-84db-faee86b9b1f8" Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" + JuMP = "4076af6c-e467-56ae-b986-b466b2749572" + MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] @@ -2380,9 +2365,9 @@ weakdeps = ["ChainRulesCore"] [[deps.StableRNGs]] deps = ["Random"] -git-tree-sha1 = "95af145932c2ed859b63329952ce8d633719f091" +git-tree-sha1 = "4f96c596b8c8258cc7d3b19797854d368f243ddc" uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" -version = "1.0.3" +version = "1.0.4" [[deps.Static]] deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools", "SciMLPublic"] @@ -2403,9 +2388,9 @@ weakdeps = ["OffsetArrays", "StaticArrays"] [[deps.StaticArrays]] deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98" +git-tree-sha1 = "eee1b9ad8b29ef0d936e3ec9838c7ec089620308" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.15" +version = "1.9.16" weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] @@ -2429,15 +2414,15 @@ weakdeps = ["SparseArrays"] [[deps.StatsAPI]] deps = ["LinearAlgebra"] -git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +git-tree-sha1 = "178ed29fd5b2a2cfc3bd31c13375ae925623ff36" uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.1" +version = "1.8.0" [[deps.StatsBase]] -deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "a136f98cefaf3e2924a66bd75173d1c891ab7453" +deps = ["AliasTables", "DataAPI", "DataStructures", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "aceda6f4e598d331548e04cc6b2124a6148138e3" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.34.7" +version = "0.34.10" [[deps.StrideArraysCore]] deps = ["ArrayInterface", "CloseOpenIntervals", "IfElse", "LayoutPointers", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface", "ThreadingUtilities"] @@ -2447,9 +2432,9 @@ version = "0.5.8" [[deps.StringManipulation]] deps = ["PrecompileTools"] -git-tree-sha1 = "725421ae8e530ec29bcbdddbe91ff8053421d023" +git-tree-sha1 = "a3c1536470bf8c5e02096ad4853606d7c8f62721" uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" -version = "0.4.1" +version = "0.4.2" [[deps.StructTypes]] deps = ["Dates", "UUIDs"] @@ -2592,9 +2577,9 @@ version = "1.24.0+0" [[deps.WoodburyMatrices]] deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" +git-tree-sha1 = "248a7031b3da79a127f14e5dc5f417e26f9f6db7" uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "1.0.0" +version = "1.1.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] @@ -2604,9 +2589,9 @@ version = "2.13.9+0" [[deps.XZ_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" +git-tree-sha1 = "9cce64c0fdd1960b597ba7ecda2950b5ed957438" uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" -version = "5.8.1+0" +version = "5.8.2+0" [[deps.Xorg_libICE_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -2824,9 +2809,9 @@ version = "1.28.1+0" [[deps.libpng_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "07b6a107d926093898e82b3b1db657ebe33134ec" +git-tree-sha1 = "6ab498eaf50e0495f89e7a5b582816e2efb95f64" uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.50+0" +version = "1.6.54+0" [[deps.libvorbis_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] @@ -2870,6 +2855,6 @@ version = "4.1.0+0" [[deps.xkbcommon_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] -git-tree-sha1 = "fbf139bce07a534df0e699dbb5f5cc9346f95cc1" +git-tree-sha1 = "a1fc6507a40bf504527d0d4067d718f8e179b2b8" uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" -version = "1.9.2+0" +version = "1.13.0+0" diff --git a/docs/src/assets/Project.toml b/docs/src/assets/Project.toml index 2d7c27e44..5677beda0 100644 --- a/docs/src/assets/Project.toml +++ b/docs/src/assets/Project.toml @@ -48,7 +48,7 @@ LinearAlgebra = "1" MINPACK = "1" MadNLP = "0.8" MadNLPMumps = "0.5" -NLPModelsIpopt = "0.10" +NLPModelsIpopt = "0.11" NLPModelsKnitro = "0.9" NonlinearSolve = "4" OrdinaryDiffEq = "6" diff --git a/docs/src/manual-model.md b/docs/src/manual-model.md index 38cbf477a..a5fed6d0e 100644 --- a/docs/src/manual-model.md +++ b/docs/src/manual-model.md @@ -123,7 +123,7 @@ definition(ocp) !!! note - We refer to [CTModels API](@extref CTModels Types) for more details about this struct and its fields. + We refer to the CTModels documentation for more details about this struct and its fields. ## [Attributes and properties](@id manual-model-attributes) diff --git a/src/OptimalControl.jl b/src/OptimalControl.jl index 72b3d37db..cc87c12c3 100644 --- a/src/OptimalControl.jl +++ b/src/OptimalControl.jl @@ -9,276 +9,19 @@ module OptimalControl using DocStringExtensions -# CTBase -import CTBase: - CTBase, - ParsingError, - CTException, - AmbiguousDescription, - IncorrectArgument, - IncorrectMethod, - IncorrectOutput, - NotImplemented, - UnauthorizedCall, - ExtensionError -export ParsingError, - CTException, - AmbiguousDescription, - IncorrectArgument, - IncorrectMethod, - IncorrectOutput, - NotImplemented, - UnauthorizedCall, - ExtensionError - -# CTParser -import CTParser: CTParser, @def -export @def - -function __init__() - CTParser.prefix_fun!(:OptimalControl) - CTParser.prefix_exa!(:OptimalControl) - CTParser.e_prefix!(:OptimalControl) -end - -# RecipesBase.plot -import RecipesBase: RecipesBase, plot -export plot - -# CTModels -import CTModels: - CTModels, - # setters - variable!, - time!, - state!, - control!, - dynamics!, - # constraint!, - objective!, - definition!, - time_dependence!, - # model - build, - Model, - PreModel, - Solution, - # getters - constraints, - get_build_examodel, - times, - definition, - dual, - initial_time, - initial_time_name, - final_time, - final_time_name, - time_name, - variable_dimension, - variable_components, - variable_name, - state_dimension, - state_components, - state_name, - control_dimension, - control_components, - control_name, - # constraint, - dynamics, - mayer, - lagrange, - criterion, - has_fixed_final_time, - has_fixed_initial_time, - has_free_final_time, - has_free_initial_time, - has_lagrange_cost, - has_mayer_cost, - is_autonomous, - export_ocp_solution, - import_ocp_solution, - time_grid, - control, - state, - # variable, - costate, - constraints_violation, - # objective, - iterations, - status, - message, - infos, - successful -export Model, Solution -export constraints, - get_build_examodel, - times, - definition, - dual, - initial_time, - initial_time_name, - final_time, - final_time_name, - time_name, - variable_dimension, - variable_components, - variable_name, - state_dimension, - state_components, - state_name, - control_dimension, - control_components, - control_name, - # constraint, - dynamics, - mayer, - lagrange, - criterion, - has_fixed_final_time, - has_fixed_initial_time, - has_free_final_time, - has_free_initial_time, - has_lagrange_cost, - has_mayer_cost, - is_autonomous, - export_ocp_solution, - import_ocp_solution, - time_grid, - control, - state, - # variable, - costate, - constraints_violation, - # objective, - iterations, - status, - message, - infos, - successful - -# CTDirect -import CTDirect: - CTDirect, - direct_transcription, - set_initial_guess, - build_OCP_solution, - nlp_model, - ocp_model -export direct_transcription, set_initial_guess, build_OCP_solution, nlp_model, ocp_model - -# CTFlows -import CTFlows: - CTFlows, - VectorField, - Lift, - Hamiltonian, - HamiltonianLift, - HamiltonianVectorField, - Flow, - ⋅, - Lie, - Poisson, - @Lie, - * # debug: complete? -export VectorField, - Lift, - Hamiltonian, - HamiltonianLift, - HamiltonianVectorField, - Flow, - ⋅, - Lie, - Poisson, - @Lie, - * - -# To trigger CTDirectExtADNLP and CTDirectExtExa -using ADNLPModels: ADNLPModels -import ExaModels: - ExaModels, - ExaModel, - ExaCore, - variable, - constraint, - constraint!, - objective, - solution, - multipliers, - multipliers_L, - multipliers_U, - Constraint - -# Conflicts of functions defined in several packages -# ExaModels.variable, CTModels.variable -# ExaModels.constraint, CTModels.constraint -# ExaModels.constraint!, CTModels.constraint! -# ExaModels.objective, CTModels.objective -""" -$(TYPEDSIGNATURES) - -See CTModels.variable. -""" -variable(ocp::Model) = CTModels.variable(ocp) - -""" -$(TYPEDSIGNATURES) - -Return the variable or `nothing`. - -```@example -julia> v = variable(sol) -``` -""" -variable(sol::Solution) = CTModels.variable(sol) - -""" -$(TYPEDSIGNATURES) - -Get a labelled constraint from the model. Returns a tuple of the form -`(type, f, lb, ub)` where `type` is the type of the constraint, `f` is the function, -`lb` is the lower bound and `ub` is the upper bound. - -The function returns an exception if the label is not found in the model. - -## Arguments - -- `model`: The model from which to retrieve the constraint. -- `label`: The label of the constraint to retrieve. - -## Returns - -- `Tuple`: A tuple containing the type, function, lower bound, and upper bound of the constraint. -""" -constraint(ocp::Model, label::Symbol) = CTModels.constraint(ocp, label) - -""" -$(TYPEDSIGNATURES) - -See CTModels.constraint!. -""" -function constraint!(ocp::PreModel, type::Symbol; kwargs...) - CTModels.constraint!(ocp, type; kwargs...) -end - -""" -$(TYPEDSIGNATURES) - -See CTModels.objective. -""" -objective(ocp::Model) = CTModels.objective(ocp) - -""" -$(TYPEDSIGNATURES) - -Return the objective value. -""" -objective(sol::Solution) = CTModels.objective(sol) - -export variable, constraint, objective - -# CommonSolve -import CommonSolve: CommonSolve, solve -include("solve.jl") +# Imports +include(joinpath(@__DIR__, "imports", "ctbase.jl")) +include(joinpath(@__DIR__, "imports", "ctparser.jl")) +include(joinpath(@__DIR__, "imports", "plots.jl")) +include(joinpath(@__DIR__, "imports", "ctmodels.jl")) +include(joinpath(@__DIR__, "imports", "ctdirect.jl")) +include(joinpath(@__DIR__, "imports", "ctflows.jl")) +include(joinpath(@__DIR__, "imports", "ctsolvers.jl")) +include(joinpath(@__DIR__, "imports", "modelers.jl")) +include(joinpath(@__DIR__, "imports", "commonsolve.jl")) + +# solve +include(joinpath(@__DIR__, "solve.jl")) export solve export available_methods diff --git a/src/imports/commonsolve.jl b/src/imports/commonsolve.jl new file mode 100644 index 000000000..57bd8f16f --- /dev/null +++ b/src/imports/commonsolve.jl @@ -0,0 +1 @@ +import CommonSolve: CommonSolve, solve \ No newline at end of file diff --git a/src/imports/ctbase.jl b/src/imports/ctbase.jl new file mode 100644 index 000000000..285cfa841 --- /dev/null +++ b/src/imports/ctbase.jl @@ -0,0 +1,23 @@ +import CTBase: CTBase + +# Exceptions +import CTBase: + IncorrectArgument +# ParsingError, +# CTException, +# AmbiguousDescription, +# IncorrectMethod, +# IncorrectOutput, +# NotImplemented, +# UnauthorizedCall, +# ExtensionError + +# export ParsingError, +# CTException, +# AmbiguousDescription, +# IncorrectArgument, +# IncorrectMethod, +# IncorrectOutput, +# NotImplemented, +# UnauthorizedCall, +# ExtensionError \ No newline at end of file diff --git a/src/imports/ctdirect.jl b/src/imports/ctdirect.jl new file mode 100644 index 000000000..e2c55f00d --- /dev/null +++ b/src/imports/ctdirect.jl @@ -0,0 +1,18 @@ +import CTDirect: CTDirect + +# # Abstract types +# import CTDirect: +# AbstractOptimalControlDiscretizer + +# Discretizers +import CTDirect: + Collocation + +# direct_transcription, +# set_initial_guess, +# build_OCP_solution, +# nlp_model, +# ocp_model, +# AbstractOptimalControlDiscretizer +# export AbstractOptimalControlDiscretizer +# export direct_transcription, set_initial_guess, build_OCP_solution, nlp_model, ocp_model \ No newline at end of file diff --git a/src/imports/ctflows.jl b/src/imports/ctflows.jl new file mode 100644 index 000000000..06032bbf7 --- /dev/null +++ b/src/imports/ctflows.jl @@ -0,0 +1,25 @@ + +import CTFlows: + CTFlows #, +# VectorField, +# Lift, +# Hamiltonian, +# HamiltonianLift, +# HamiltonianVectorField, +# Flow, +# ⋅, +# Lie, +# Poisson, +# @Lie, +# * # debug: complete? +# export VectorField, +# Lift, +# Hamiltonian, +# HamiltonianLift, +# HamiltonianVectorField, +# Flow, +# ⋅, +# Lie, +# Poisson, +# @Lie, +# * \ No newline at end of file diff --git a/src/imports/ctmodels.jl b/src/imports/ctmodels.jl new file mode 100644 index 000000000..508478c5e --- /dev/null +++ b/src/imports/ctmodels.jl @@ -0,0 +1,153 @@ +import CTModels: CTModels + +# # Abstract types +# import CTModels: +# AbstractOptimalControlProblem, +# AbstractOptimalControlInitialGuess, +# AbstractOptimalControlSolution, +# AbstractOptimizationProblem, +# AbstractOptimizationModeler, +# AbstractOptimizationSolver + +# PreModel +import CTModels: PreModel + +# Modelers +import CTModels: + ADNLPModeler, + ExaModeler + +# OptimalControlProblem setters, builders +import CTModels: + variable!, + time!, + state!, + control!, + dynamics!, + constraint!, + objective!, + definition!, + time_dependence!, + build + +# Initial guess +import CTModels: initial_guess + +#, +# # setters +# variable!, +# time!, +# state!, +# control!, +# dynamics!, +# # constraint!, +# objective!, +# definition!, +# time_dependence!, +# # model +# build, +# Model, +# PreModel, +# Solution, +# # getters +# constraints, +# get_build_examodel, +# times, +# definition, +# dual, +# initial_time, +# initial_time_name, +# final_time, +# final_time_name, +# time_name, +# variable_dimension, +# variable_components, +# variable_name, +# state_dimension, +# state_components, +# state_name, +# control_dimension, +# control_components, +# control_name, +# # constraint, +# dynamics, +# mayer, +# lagrange, +# criterion, +# has_fixed_final_time, +# has_fixed_initial_time, +# has_free_final_time, +# has_free_initial_time, +# has_lagrange_cost, +# has_mayer_cost, +# is_autonomous, +# export_ocp_solution, +# import_ocp_solution, +# time_grid, +# control, +# state, +# # variable, +# costate, +# constraints_violation, +# # objective, +# iterations, +# status, +# message, +# infos, +# successful, +# AbstractOptimalControlProblem, +# AbstractOptimizationProblem, +# AbstractOptimalControlInitialGuess, +# AbstractOptimalControlSolution, +# AbstractOptimizationModeler +# # export AbstractOptimalControlProblem, +# # AbstractOptimizationProblem, +# # AbstractOptimalControlInitialGuess, +# # AbstractOptimalControlSolution, +# # AbstractOptimizationModeler +# export Model, Solution +# export constraints, +# get_build_examodel, +# times, +# definition, +# dual, +# initial_time, +# initial_time_name, +# final_time, +# final_time_name, +# time_name, +# variable_dimension, +# variable_components, +# variable_name, +# state_dimension, +# state_components, +# state_name, +# control_dimension, +# control_components, +# control_name, +# # constraint, +# dynamics, +# mayer, +# lagrange, +# criterion, +# has_fixed_final_time, +# has_fixed_initial_time, +# has_free_final_time, +# has_free_initial_time, +# has_lagrange_cost, +# has_mayer_cost, +# is_autonomous, +# export_ocp_solution, +# import_ocp_solution, +# time_grid, +# control, +# state, +# # variable, +# costate, +# constraints_violation, +# # objective, +# iterations, +# status, +# message, +# infos, +# successful \ No newline at end of file diff --git a/src/imports/ctparser.jl b/src/imports/ctparser.jl new file mode 100644 index 000000000..d2e81b86a --- /dev/null +++ b/src/imports/ctparser.jl @@ -0,0 +1,8 @@ +import CTParser: CTParser, @def, @init +export @def, @init + +function __init__() + CTParser.prefix_fun!(:OptimalControl) + CTParser.prefix_exa!(:OptimalControl) + CTParser.e_prefix!(:OptimalControl) +end \ No newline at end of file diff --git a/src/imports/ctsolvers.jl b/src/imports/ctsolvers.jl new file mode 100644 index 000000000..c751d4110 --- /dev/null +++ b/src/imports/ctsolvers.jl @@ -0,0 +1,8 @@ +import CTSolvers: CTSolvers + +# Solvers +import CTSolvers: + IpoptSolver, + MadNLPSolver + +# AbstractOptimizationSolver \ No newline at end of file diff --git a/src/imports/modelers.jl b/src/imports/modelers.jl new file mode 100644 index 000000000..cca31e888 --- /dev/null +++ b/src/imports/modelers.jl @@ -0,0 +1,84 @@ +# To trigger CTDirectExtADNLP and CTDirectExtExa +using ADNLPModels: ADNLPModels + +import ExaModels: + ExaModels #, +# ExaModel, +# ExaCore, +# variable, +# constraint, +# constraint!, +# objective, +# solution, +# multipliers, +# multipliers_L, +# multipliers_U, +# Constraint + +# # Conflicts of functions defined in several packages +# # ExaModels.variable, CTModels.variable +# # ExaModels.constraint, CTModels.constraint +# # ExaModels.constraint!, CTModels.constraint! +# # ExaModels.objective, CTModels.objective +# """ +# $(TYPEDSIGNATURES) + +# See CTModels.variable. +# """ +# variable(ocp::Model) = CTModels.variable(ocp) + +# """ +# $(TYPEDSIGNATURES) + +# Return the variable or `nothing`. + +# ```@example +# julia> v = variable(sol) +# ``` +# """ +# variable(sol::Solution) = CTModels.variable(sol) + +# """ +# $(TYPEDSIGNATURES) + +# Get a labelled constraint from the model. Returns a tuple of the form +# `(type, f, lb, ub)` where `type` is the type of the constraint, `f` is the function, +# `lb` is the lower bound and `ub` is the upper bound. + +# The function returns an exception if the label is not found in the model. + +# ## Arguments + +# - `model`: The model from which to retrieve the constraint. +# - `label`: The label of the constraint to retrieve. + +# ## Returns + +# - `Tuple`: A tuple containing the type, function, lower bound, and upper bound of the constraint. +# """ +# constraint(ocp::Model, label::Symbol) = CTModels.constraint(ocp, label) + +# """ +# $(TYPEDSIGNATURES) + +# See CTModels.constraint!. +# """ +# function constraint!(ocp::PreModel, type::Symbol; kwargs...) +# CTModels.constraint!(ocp, type; kwargs...) +# end + +# """ +# $(TYPEDSIGNATURES) + +# See CTModels.objective. +# """ +# objective(ocp::Model) = CTModels.objective(ocp) + +# """ +# $(TYPEDSIGNATURES) + +# Return the objective value. +# """ +# objective(sol::Solution) = CTModels.objective(sol) + +# export variable, constraint, objective \ No newline at end of file diff --git a/src/imports/plots.jl b/src/imports/plots.jl new file mode 100644 index 000000000..8b57b4e93 --- /dev/null +++ b/src/imports/plots.jl @@ -0,0 +1,2 @@ +import RecipesBase: RecipesBase, plot +export plot \ No newline at end of file diff --git a/src/solve.jl b/src/solve.jl index e8a5d56bf..cc0059698 100644 --- a/src/solve.jl +++ b/src/solve.jl @@ -1,137 +1,669 @@ -""" -$(TYPEDSIGNATURES) - -Used to set the default display toggle. -The default value is true. -""" +# ------------------------------------------------------------------------ +# ------------------------------------------------------------------------ +# Default options __display() = true +__initial_guess() = nothing + +# ------------------------------------------------------------------------ +# ------------------------------------------------------------------------ +# Main solve function +function _solve( + ocp::CTModels.AbstractOptimalControlProblem, + initial_guess, + discretizer::CTDirect.AbstractOptimalControlDiscretizer, + modeler::CTModels.AbstractOptimizationModeler, + solver::CTSolvers.AbstractOptimizationSolver; + display::Bool=__display(), +)::CTModels.AbstractOptimalControlSolution + + # Validate initial guess against the optimal control problem before discretization. + # Any inconsistency should trigger a CTBase.IncorrectArgument from the validator. + normalized_init = CTModels.build_initial_guess(ocp, initial_guess) + CTModels.validate_initial_guess(ocp, normalized_init) + + discrete_problem = CTDirect.discretize(ocp, discretizer) + return CommonSolve.solve( + discrete_problem, normalized_init, modeler, solver; display=display + ) +end -""" -Return the version of the current module as a string. +# ------------------------------------------------------------------------ +# ------------------------------------------------------------------------ +# Method registry: available resolution methods for optimal control problems. -This function returns the version number defined in the `Project.toml` of the package -to which the current module belongs. It uses `@__MODULE__` to infer the calling context. +const AVAILABLE_METHODS = ( + (:collocation, :adnlp, :ipopt), + (:collocation, :adnlp, :madnlp), + (:collocation, :adnlp, :knitro), + (:collocation, :exa, :ipopt), + (:collocation, :exa, :madnlp), + (:collocation, :exa, :knitro), +) -# Example -```julia-repl -julia> version() # e.g., "1.2.3" -``` -""" -version() = string(pkgversion(@__MODULE__)) +available_methods() = AVAILABLE_METHODS -""" -$(TYPEDSIGNATURES) +# ------------------------------------------------------------------------ +# ------------------------------------------------------------------------ +# Discretizer helpers (symbol type and options). -Return the list of available methods that can be used to solve optimal control problems. -""" -function available_methods() - # by order of preference: from top to bottom - methods = () - for method in CTDirect.available_methods() - methods = CTBase.add(methods, (:direct, method...)) +function _get_unique_symbol( + method::Tuple{Vararg{Symbol}}, allowed::Tuple{Vararg{Symbol}}, tool_name::AbstractString +) + hits = Symbol[] + for s in method + if s in allowed + push!(hits, s) + end + end + if length(hits) == 1 + return hits[1] + elseif isempty(hits) + msg = "No $(tool_name) symbol from $(allowed) found in method $(method)." + throw(CTBase.IncorrectArgument(msg)) + else + msg = "Multiple $(tool_name) symbols $(hits) found in method $(method); at most one is allowed." + throw(CTBase.IncorrectArgument(msg)) end - return methods end -""" -$(TYPEDSIGNATURES) +function _get_discretizer_symbol(method::Tuple) + return _get_unique_symbol(method, CTDirect.discretizer_symbols(), "discretizer") +end -When calling the function `solve`, the user can provide a description of the method to use to solve the optimal control problem. -The description can be a partial description or a full description. -The function `solve` will find the best match from the available methods, thanks to the function `getFullDescription`. -Then, the description is cleaned by the function `clean` to remove the Symbols that are specific to -[OptimalControl.jl](https://control-toolbox.org/OptimalControl.jl) and so must not be passed to the solver. -For instance, the Symbol `:direct` is specific to [OptimalControl.jl](https://control-toolbox.org/OptimalControl.jl) and must be removed. -It must not be passed to the CTDirect.jl solver. -""" -function clean(d::CTBase.Description) - return CTBase.remove(d, (:direct,)) +function _build_discretizer_from_method(method::Tuple, discretizer_options::NamedTuple) + disc_sym = _get_discretizer_symbol(method) + return CTDirect.build_discretizer_from_symbol(disc_sym; discretizer_options...) end -""" -$(TYPEDSIGNATURES) +function _discretizer_options_keys(method::Tuple) + disc_sym = _get_discretizer_symbol(method) + disc_type = CTDirect._discretizer_type_from_symbol(disc_sym) + keys = CTModels.options_keys(disc_type) + keys === missing && return () + return keys +end -Solve the optimal control problem `ocp` by the method given by the (optional) description. -The get the list of available methods: -```julia-repl -julia> available_methods() -``` -The higher in the list, the higher is the priority. -The keyword arguments are specific to the chosen method and represent the options of the solver. +# ------------------------------------------------------------------------ +# ------------------------------------------------------------------------ +# Modeler helpers (symbol type). -# Arguments +function _get_modeler_symbol(method::Tuple) + return _get_unique_symbol(method, CTModels.modeler_symbols(), "NLP model") +end -- `ocp::OptimalControlModel`: the optimal control problem to solve. -- `description::Symbol...`: the description of the method used to solve the problem. -- `kwargs...`: the options of the method. +function _normalize_modeler_options(options) + if options === nothing + return NamedTuple() + elseif options isa NamedTuple + return options + elseif options isa Tuple + return (; options...) + else + msg = "modeler_options must be a NamedTuple or tuple of pairs, got $(typeof(options))." + throw(CTBase.IncorrectArgument(msg)) + end +end -# Examples +function _modeler_options_keys(method::Tuple) + model_sym = _get_modeler_symbol(method) + model_type = CTModels._modeler_type_from_symbol(model_sym) + keys = CTModels.options_keys(model_type) + keys === missing && return () + return keys +end -The simplest way to solve the optimal control problem is to call the function without any argument. +function _build_modeler_from_method(method::Tuple, modeler_options::NamedTuple) + model_sym = _get_modeler_symbol(method) + return CTModels.build_modeler_from_symbol(model_sym; modeler_options...) +end -```julia-repl -julia> sol = solve(ocp) -``` +# ------------------------------------------------------------------------ +# ------------------------------------------------------------------------ +# Solver helpers (symbol type). -The method description is a list of Symbols. The default is +function _get_solver_symbol(method::Tuple) + return _get_unique_symbol(method, CTSolvers.solver_symbols(), "solver") +end -```julia-repl -julia> sol = solve(ocp, :direct, :adnlp, :ipopt) -``` +function _build_solver_from_method(method::Tuple, solver_options::NamedTuple) + solver_sym = _get_solver_symbol(method) + return CTSolvers.build_solver_from_symbol(solver_sym; solver_options...) +end -You can provide a partial description, the function will find the best match. +function _solver_options_keys(method::Tuple) + solver_sym = _get_solver_symbol(method) + solver_type = CTSolvers._solver_type_from_symbol(solver_sym) + keys = CTModels.options_keys(solver_type) + keys === missing && return () + return keys +end -```julia-repl -julia> sol = solve(ocp, :direct) -``` +# ------------------------------------------------------------------------ +# ------------------------------------------------------------------------ +# Option routing helpers for description mode. -!!! note - - See the [resolution methods section](@ref manual-solve-methods) for more details about the available methods. +const _OCP_TOOLS = (:discretizer, :modeler, :solver, :solve) -The keyword arguments are specific to the chosen method and correspond to the options of the different solvers. -For example, the keyword `max_iter` is an Ipopt option that may be used to set the maximum number of iterations. +function _extract_option_tool(raw) + if raw isa Tuple{Any,Symbol} + value, tool = raw + if tool in _OCP_TOOLS + return value, tool + end + end + return raw, nothing +end -```julia-repl -julia> sol = solve(ocp, :direct, :ipopt, max_iter=100) -``` +function _route_option_for_description( + key::Symbol, raw_value, owners::Vector{Symbol}, source_mode::Symbol +) + value, explicit_tool = _extract_option_tool(raw_value) -!!! note - - See the [direct method section](@ref manual-solve-direct-method) for more details about associated options. - These options also detailed in the [`CTDirect.solve`](@extref) documentation. - This main `solve` method redirects to `CTDirect.solve` when the `:direct` Symbol is given in the description. - See also the [NLP solvers section](@ref manual-solve-solvers-specific-options) for more details about Ipopt or MadNLP options. + if explicit_tool !== nothing + if !(explicit_tool in owners) + msg = "Keyword option $(key) cannot be routed to $(explicit_tool); valid tools are $(owners)." + throw(CTBase.IncorrectArgument(msg)) + end + return value, explicit_tool + end -To help the solve converge, an initial guess can be provided within the keyword `init`. -You can provide the initial guess for the state, control, and variable. + if isempty(owners) + msg = "Keyword option $(key) does not belong to any recognized component for the selected method." + throw(CTBase.IncorrectArgument(msg)) + elseif length(owners) == 1 + return value, owners[1] + else + if source_mode === :description + msg = + "Keyword option $(key) is ambiguous between tools $(owners). " * + "Disambiguate it by writing $(key) = (value, :tool), for example " * + "$(key) = (value, :discretizer) or $(key) = (value, :solver)." + throw(CTBase.IncorrectArgument(msg)) + else + msg = + "Ambiguous keyword option $(key) when routing from explicit mode; " * + "internal calls should use the (value, tool) form." + throw(CTBase.IncorrectArgument(msg)) + end + end +end -```julia-repl -julia> sol = solve(ocp, init=(state=[-0.5, 0.2], control=0.5)) -``` +# ------------------------------------------------------------------------ +# ------------------------------------------------------------------------ +# Display helpers. -!!! note +function _display_ocp_method( + io::IO, + method::Tuple, + discretizer::CTDirect.AbstractOptimalControlDiscretizer, + modeler::CTModels.AbstractOptimizationModeler, + solver::CTSolvers.AbstractOptimizationSolver; + display::Bool, +) + display || return nothing - See [how to set an initial guess](@ref manual-initial-guess) for more details. -""" -function CommonSolve.solve( - ocp::CTModels.Model, description::Symbol...; display::Bool=__display(), kwargs... -)::CTModels.Solution + version_str = string(Base.pkgversion(@__MODULE__)) + + print(io, "▫ This is CTSolvers version v", version_str, " running with: ") + for (i, m) in enumerate(method) + sep = i == length(method) ? ".\n\n" : ", " + printstyled(io, string(m) * sep; color=:cyan, bold=true) + end + + model_pkg = CTModels.tool_package_name(modeler) + solver_pkg = CTModels.tool_package_name(solver) + + if model_pkg !== missing && solver_pkg !== missing + println( + io, + " ┌─ The NLP is modelled with ", + model_pkg, + " and solved with ", + solver_pkg, + ".", + ) + println(io, " │") + end + + # Discretizer options (including grid size and scheme) + disc_vals = CTModels._options_values(discretizer) + disc_srcs = CTModels._option_sources(discretizer) + + mod_vals = CTModels._options_values(modeler) + mod_srcs = CTModels._option_sources(modeler) + + sol_vals = CTModels._options_values(solver) + sol_srcs = CTModels._option_sources(solver) + + has_disc = !isempty(propertynames(disc_vals)) + has_mod = !isempty(propertynames(mod_vals)) + has_sol = !isempty(propertynames(sol_vals)) - # get the full description - method = CTBase.complete(description; descriptions=available_methods()) + if has_disc || has_mod || has_sol + println(io, " Options:") - # display the chosen method - if display - print("▫ This is OptimalControl version v$(version()) running with: ") - for (i, m) in enumerate(method) - sep = i == length(method) ? ".\n\n" : ", " - printstyled(string(m) * sep; color=:cyan, bold=true) + if has_disc + println(io, " ├─ Discretizer:") + for name in propertynames(disc_vals) + src = haskey(disc_srcs, name) ? disc_srcs[name] : :unknown + println(io, " │ ", name, " = ", disc_vals[name], " (", src, ")") + end end + + if has_mod + println(io, " ├─ Modeler:") + for name in propertynames(mod_vals) + src = haskey(mod_srcs, name) ? mod_srcs[name] : :unknown + println(io, " │ ", name, " = ", mod_vals[name], " (", src, ")") + end + end + + if has_sol + println(io, " └─ Solver:") + for name in propertynames(sol_vals) + src = haskey(sol_srcs, name) ? sol_srcs[name] : :unknown + println(io, " ", name, " = ", sol_vals[name], " (", src, ")") + end + end + end + + println(io) + + return nothing +end + +function _display_ocp_method( + method::Tuple, + discretizer::CTDirect.AbstractOptimalControlDiscretizer, + modeler::CTModels.AbstractOptimizationModeler, + solver::CTSolvers.AbstractOptimizationSolver; + display::Bool, +) + return _display_ocp_method( + stdout, method, discretizer, modeler, solver; display=display + ) +end + +# ------------------------------------------------------------------------ +# ------------------------------------------------------------------------ +# Top-level solve entry: unifies explicit and description modes. + +const _SOLVE_INITIAL_GUESS_ALIASES = (:initial_guess, :init, :i) +const _SOLVE_DISCRETIZER_ALIASES = (:discretizer, :d) +const _SOLVE_MODELER_ALIASES = (:modeler, :modeller, :m) +const _SOLVE_SOLVER_ALIASES = (:solver, :s) +const _SOLVE_DISPLAY_ALIASES = (:display,) +const _SOLVE_MODELER_OPTIONS_ALIASES = (:modeler_options,) + +solve_ocp_option_keys_explicit_mode() = (:initial_guess, :display) + +struct _ParsedTopLevelKwargs + initial_guess + display + discretizer + modeler + solver + modeler_options + other_kwargs::NamedTuple +end + +function _take_solve_kwarg( + kwargs::NamedTuple, names::Tuple{Vararg{Symbol}}, default; only_solve_owner::Bool=false +) + present = Symbol[] + for n in names + if haskey(kwargs, n) + if only_solve_owner + raw = kwargs[n] + _, explicit_tool = _extract_option_tool(raw) + if !(explicit_tool === nothing || explicit_tool === :solve) + continue + end + end + push!(present, n) + end + end + + if isempty(present) + return default, kwargs + elseif length(present) == 1 + name = present[1] + value = kwargs[name] + remaining = (; (k => v for (k, v) in pairs(kwargs) if k != name)...) + return value, remaining + else + msg = + "Conflicting aliases $(present) for argument $(names[1]). " * + "Use only one of $(names)." + throw(CTBase.IncorrectArgument(msg)) + end +end + +function _parse_top_level_kwargs(kwargs::NamedTuple) + initial_guess, kwargs1 = _take_solve_kwarg( + kwargs, _SOLVE_INITIAL_GUESS_ALIASES, __initial_guess() + ) + display, kwargs2 = _take_solve_kwarg(kwargs1, _SOLVE_DISPLAY_ALIASES, __display()) + discretizer, kwargs3 = _take_solve_kwarg(kwargs2, _SOLVE_DISCRETIZER_ALIASES, nothing) + modeler, kwargs4 = _take_solve_kwarg(kwargs3, _SOLVE_MODELER_ALIASES, nothing) + solver, kwargs5 = _take_solve_kwarg(kwargs4, _SOLVE_SOLVER_ALIASES, nothing) + modeler_options, other_kwargs = _take_solve_kwarg( + kwargs5, _SOLVE_MODELER_OPTIONS_ALIASES, nothing + ) + + return _ParsedTopLevelKwargs( + initial_guess, display, discretizer, modeler, solver, modeler_options, other_kwargs + ) +end + +function _parse_top_level_kwargs_description(kwargs::NamedTuple) + # Defaults identical to the explicit-mode parser, but reserved keywords can + # be routed through the central option router in the future if they become + # shared between components. For now, initial_guess, display and + # modeler_options are treated as belonging solely to the top-level solve. + + initial_guess = __initial_guess() + display = __display() + discretizer = nothing + modeler = nothing + solver = nothing + modeler_options = nothing + + # Reserved keywords + initial_guess_raw, kwargs1 = _take_solve_kwarg( + kwargs, _SOLVE_INITIAL_GUESS_ALIASES, __initial_guess(); only_solve_owner=true + ) + value, _ = _route_option_for_description( + :initial_guess, initial_guess_raw, Symbol[:solve], :description + ) + initial_guess = value + + display_raw, kwargs2 = _take_solve_kwarg( + kwargs1, _SOLVE_DISPLAY_ALIASES, __display(); only_solve_owner=true + ) + display_unwrapped, _ = _extract_option_tool(display_raw) + display = display_unwrapped + + modeler_options_raw, kwargs3 = _take_solve_kwarg( + kwargs2, _SOLVE_MODELER_OPTIONS_ALIASES, nothing; only_solve_owner=true + ) + modeler_options_unwrapped, _ = _extract_option_tool(modeler_options_raw) + modeler_options = modeler_options_unwrapped + + # Explicit components, if any + discretizer, kwargs4 = _take_solve_kwarg(kwargs3, _SOLVE_DISCRETIZER_ALIASES, nothing) + modeler, kwargs5 = _take_solve_kwarg(kwargs4, _SOLVE_MODELER_ALIASES, nothing) + solver, kwargs6 = _take_solve_kwarg(kwargs5, _SOLVE_SOLVER_ALIASES, nothing) + + # Everything else goes to other_kwargs and will be routed to discretizer + # or solver by the description-mode splitter. + other_pairs = Pair{Symbol,Any}[] + for (k, v) in pairs(kwargs6) + push!(other_pairs, k => v) + end + + return _ParsedTopLevelKwargs( + initial_guess, + display, + discretizer, + modeler, + solver, + modeler_options, + (; other_pairs...), + ) +end + +function _ensure_no_ambiguous_description_kwargs(method::Tuple, kwargs::NamedTuple) + disc_keys = Set(_discretizer_options_keys(method)) + model_keys = Set(_modeler_options_keys(method)) + solver_keys = Set(_solver_options_keys(method)) + + for (k, raw) in pairs(kwargs) + owners = Symbol[] + + if (k in _SOLVE_INITIAL_GUESS_ALIASES) || + (k in _SOLVE_DISCRETIZER_ALIASES) || + (k in _SOLVE_MODELER_ALIASES) || + (k in _SOLVE_SOLVER_ALIASES) || + (k in _SOLVE_DISPLAY_ALIASES) || + (k in _SOLVE_MODELER_OPTIONS_ALIASES) + push!(owners, :solve) + end + + if k in disc_keys + push!(owners, :discretizer) + end + if k in model_keys + push!(owners, :modeler) + end + if k in solver_keys + push!(owners, :solver) + end + + _route_option_for_description(k, raw, owners, :description) + end + + return nothing +end + +function _has_explicit_components(parsed::_ParsedTopLevelKwargs) + return (parsed.discretizer !== nothing) || + (parsed.modeler !== nothing) || + (parsed.solver !== nothing) +end + +function _ensure_no_unknown_explicit_kwargs(parsed::_ParsedTopLevelKwargs) + allowed = Set(solve_ocp_option_keys_explicit_mode()) + union!(allowed, Set((:discretizer, :modeler, :solver))) + unknown = [k for (k, _) in pairs(parsed.other_kwargs) if !(k in allowed)] + if !isempty(unknown) + msg = "Unknown keyword options in explicit mode: $(unknown)." + throw(CTBase.IncorrectArgument(msg)) + end +end + +function _build_description_from_components(discretizer, modeler, solver) + syms = Symbol[] + if discretizer !== nothing + push!(syms, CTModels.get_symbol(discretizer)) + end + if modeler !== nothing + push!(syms, CTModels.get_symbol(modeler)) + end + if solver !== nothing + push!(syms, CTModels.get_symbol(solver)) + end + return Tuple(syms) +end + +function _solve_from_components_and_description( + ocp::CTModels.AbstractOptimalControlProblem, method::Tuple, parsed::_ParsedTopLevelKwargs +) + # method is a COMPLETE description (e.g., (:collocation, :adnlp, :ipopt)) + + # 1. Discretizer + discretizer = if parsed.discretizer === nothing + _build_discretizer_from_method(method, NamedTuple()) + else + parsed.discretizer + end + + # 2. Modeler (no modeler_options in explicit mode) + modeler = if parsed.modeler === nothing + _build_modeler_from_method(method, NamedTuple()) + else + parsed.modeler + end + + # 3. Solver (no solver-specific kwargs in explicit mode) + solver = if parsed.solver === nothing + _build_solver_from_method(method, NamedTuple()) + else + parsed.solver + end + + _display_ocp_method(method, discretizer, modeler, solver; display=parsed.display) + + return _solve( + ocp, parsed.initial_guess, discretizer, modeler, solver; display=parsed.display + ) +end + +function _solve_explicit_mode( + ocp::CTModels.AbstractOptimalControlProblem, parsed::_ParsedTopLevelKwargs +) + # 1. No modeler_options in explicit mode + if parsed.modeler_options !== nothing + msg = "modeler_options is not allowed in explicit mode; pass a modeler instance instead." + throw(CTBase.IncorrectArgument(msg)) + end + + # 2. Unknown options check + _ensure_no_unknown_explicit_kwargs(parsed) + + # 3. If all components are provided explicitly, call the low-level API + # directly without going through the description/method registry. This + # allows arbitrary user-defined components (e.g., test doubles) that do + # not participate in the symbol registry. + has_discretizer = parsed.discretizer !== nothing + has_modeler = parsed.modeler !== nothing + has_solver = parsed.solver !== nothing + + if has_discretizer && has_modeler && has_solver + return _solve( + ocp, + parsed.initial_guess, + parsed.discretizer, + parsed.modeler, + parsed.solver; + display=parsed.display, + ) + end + + # 4. Otherwise, build a partial description from the provided components + # and delegate to the description-based pipeline to complete missing + # pieces using the central method registry. + partial_desc = _build_description_from_components( + parsed.discretizer, parsed.modeler, parsed.solver + ) + method = CTBase.complete(partial_desc...; descriptions=available_methods()) + + return _solve_from_components_and_description(ocp, method, parsed) +end + +# ------------------------------------------------------------------------ +# ------------------------------------------------------------------------ +# Description-based solve (including the default solve(ocp) case). + +function _split_kwargs_for_description(method::Tuple, parsed::_ParsedTopLevelKwargs) + # All top-level kwargs except initial_guess, display, modeler_options + # are in parsed.other_kwargs. Among them, some belong to the discretizer, + # some to the modeler, and some to the solver. + disc_keys = Set(_discretizer_options_keys(method)) + model_keys = Set(_modeler_options_keys(method)) + solver_keys = Set(_solver_options_keys(method)) + + disc_pairs = Pair{Symbol,Any}[] + model_pairs = Pair{Symbol,Any}[] + solver_pairs = Pair{Symbol,Any}[] + for (k, raw) in pairs(parsed.other_kwargs) + owners = Symbol[] + if k in disc_keys + push!(owners, :discretizer) + end + if k in model_keys + push!(owners, :modeler) + end + if k in solver_keys + push!(owners, :solver) + end + + value, tool = _route_option_for_description(k, raw, owners, :description) + + if tool === :discretizer + push!(disc_pairs, k => value) + elseif tool === :modeler + push!(model_pairs, k => value) + elseif tool === :solver + push!(solver_pairs, k => value) + else + msg = "Unsupported tool $(tool) for option $(k)." + throw(CTBase.IncorrectArgument(msg)) + end + end + + disc_kwargs = (; disc_pairs...) + model_kwargs = (; model_pairs...) + solver_kwargs = (; solver_pairs...) + + # Normalize user-supplied modeler_options (which may be nothing, a NamedTuple, + # or a tuple of pairs) and merge them with any untagged options that belong + # to the modeler for the selected method. We explicitly build a NamedTuple + # here instead of relying on generic union operators, to avoid type surprises + # and keep the API contract of _build_modeler_from_method, which expects a + # NamedTuple of keyword arguments. + base_modeler_opts = _normalize_modeler_options(parsed.modeler_options) + combined_modeler_opts = (; base_modeler_opts..., model_kwargs...) + + return ( + initial_guess=parsed.initial_guess, + display=parsed.display, + disc_kwargs=disc_kwargs, + modeler_options=combined_modeler_opts, + solver_kwargs=solver_kwargs, + ) +end + +function _solve_from_complete_description( + ocp::CTModels.AbstractOptimalControlProblem, + method::Tuple{Vararg{Symbol}}, + parsed::_ParsedTopLevelKwargs, +)::CTModels.AbstractOptimalControlSolution + pieces = _split_kwargs_for_description(method, parsed) + + discretizer = _build_discretizer_from_method(method, pieces.disc_kwargs) + modeler = _build_modeler_from_method(method, pieces.modeler_options) + solver = _build_solver_from_method(method, pieces.solver_kwargs) + + _display_ocp_method(method, discretizer, modeler, solver; display=pieces.display) + + return _solve( + ocp, pieces.initial_guess, discretizer, modeler, solver; display=pieces.display + ) +end + +function _solve_descriptif_mode( + ocp::CTModels.AbstractOptimalControlProblem, description::Symbol...; kwargs... +)::CTModels.AbstractOptimalControlSolution + method = CTBase.complete(description...; descriptions=available_methods()) + + _ensure_no_ambiguous_description_kwargs(method, (; kwargs...)) + + parsed = _parse_top_level_kwargs_description((; kwargs...)) + + if _has_explicit_components(parsed) + msg = "Cannot mix explicit components (discretizer/modeler/solver) with a description." + throw(CTBase.IncorrectArgument(msg)) + end + + return _solve_from_complete_description(ocp, method, parsed) +end + +function CommonSolve.solve( + ocp::CTModels.AbstractOptimalControlProblem, description::Symbol...; kwargs... +)::CTModels.AbstractOptimalControlSolution + parsed = _parse_top_level_kwargs((; kwargs...)) + + if _has_explicit_components(parsed) && !isempty(description) + msg = "Cannot mix explicit components (discretizer/modeler/solver) with a description." + throw(CTBase.IncorrectArgument(msg)) end - # solve the problem - if :direct ∈ method - return CTDirect.solve(ocp, clean(description)...; display=display, kwargs...) + if _has_explicit_components(parsed) + # Explicit mode: components provided directly by the user. + return _solve_explicit_mode(ocp, parsed) + else + # Description mode: description may be empty (solve(ocp)) or partial. + return _solve_descriptif_mode(ocp, description...; kwargs...) end end diff --git a/test/Project.toml b/test/Project.toml deleted file mode 100644 index 52425599e..000000000 --- a/test/Project.toml +++ /dev/null @@ -1,26 +0,0 @@ -[deps] -CTModels = "34c4fa32-2049-4079-8329-de33c2a22e2d" -DifferentiationInterface = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" -ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" -LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -MadNLP = "2621e9c9-9eb4-46b1-8089-e8c72242dfb6" -MadNLPMumps = "3b83494e-c0a4-4895-918b-9157a7a085a1" -NLPModelsIpopt = "f4238b75-b362-5c4c-b852-0801c9a21d71" -NonlinearSolve = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[compat] -CTModels = "0.6" -DifferentiationInterface = "0.7" -ForwardDiff = "0.10, 1.0" -LinearAlgebra = "1" -MadNLP = "0.8" -MadNLPMumps = "0.5" -NLPModelsIpopt = "0.11" -NonlinearSolve = "4" -OrdinaryDiffEq = "6" -SplitApplyCombine = "1" -Test = "1" -julia = "1.10" diff --git a/test/extras/check_ownership.jl b/test/extras/check_ownership.jl new file mode 100644 index 000000000..f9ed6550d --- /dev/null +++ b/test/extras/check_ownership.jl @@ -0,0 +1,39 @@ +using OptimalControl +using CTBase +using CTSolvers +using CTDirect +using CTFlows +using CTModels +using CTParser + +# Symbol to check +sym_to_check = :initial_guess + +# List of modules to check +modules = [ + (:CTBase, CTBase), + (:CTSolvers, CTSolvers), + (:CTDirect, CTDirect), + (:CTFlows, CTFlows), + (:CTModels, CTModels), + (:CTParser, CTParser), + (:OptimalControl, OptimalControl) +] + +println("Checking symbol: :$(sym_to_check)") +println("-"^30) + +for (name, mod) in modules + is_defined = isdefined(mod, sym_to_check) + is_exported = sym_to_check in names(mod) + + status = if is_exported + "Exported" + elseif is_defined + "Defined (internal)" + else + "Not found" + end + + println("$(name): $(status)") +end diff --git a/test/problems/beam.jl b/test/problems/beam.jl new file mode 100644 index 000000000..542d75009 --- /dev/null +++ b/test/problems/beam.jl @@ -0,0 +1,28 @@ +# Beam optimal control problem definition used by tests and examples. +# +# Returns a NamedTuple with fields: +# - ocp :: the CTParser-defined optimal control problem +# - obj :: reference optimal objective value (Ipopt / MadNLP, Collocation) +# - name :: a short problem name +# - init :: NamedTuple of components for CTSolvers.initial_guess +function Beam() + ocp = @def begin + t ∈ [0, 1], time + x ∈ R², state + u ∈ R, control + + x(0) == [0, 1] + x(1) == [0, -1] + 0 ≤ x₁(t) ≤ 0.1 + -10 ≤ u(t) ≤ 10 + + ∂(x₁)(t) == x₂(t) + ∂(x₂)(t) == u(t) + + ∫(u(t)^2) → min + end + + init = (state=[0.05, 0.1], control=0.1) + + return (ocp=ocp, obj=8.898598, name="beam", init=init) +end diff --git a/test/problems/goddard.jl b/test/problems/goddard.jl new file mode 100644 index 000000000..310adcdb5 --- /dev/null +++ b/test/problems/goddard.jl @@ -0,0 +1,64 @@ +# Goddard rocket optimal control problem used by CTSolvers tests. + +""" + Goddard(; vmax=0.1, Tmax=3.5) + +Return data for the classical Goddard rocket ascent, formulated as a +*maximization* of the final altitude `r(tf)`. + +The function returns a NamedTuple with fields: + + * `ocp` – CTParser/@def optimal control problem + * `obj` – reference optimal objective value + * `name` – short problem name (`"goddard"`) + * `init` – NamedTuple of components for `CTSolvers.initial_guess`, similar + in spirit to `Beam()`. +""" +function Goddard(; vmax=0.1, Tmax=3.5) + # constants + Cd = 310 + beta = 500 + b = 2 + r0 = 1 + v0 = 0 + m0 = 1 + mf = 0.6 + x0 = [r0, v0, m0] + + @def goddard begin + tf ∈ R, variable + t ∈ [0, tf], time + x ∈ R^3, state + u ∈ R, control + + 0.01 ≤ tf ≤ Inf + + r = x[1] + v = x[2] + m = x[3] + + x(0) == x0 + m(tf) == mf + + r0 ≤ r(t) ≤ r0 + 0.1 + v0 ≤ v(t) ≤ vmax + mf ≤ m(t) ≤ m0 + 0 ≤ u(t) ≤ 1 + + # Component-wise dynamics (Goddard rocket) + D = Cd * v(t)^2 * exp(-beta * (r(t) - r0)) + g = 1 / r(t)^2 + T = Tmax * u(t) + + ∂(r)(t) == v(t) + ∂(v)(t) == (T - D - m(t) * g) / m(t) + ∂(m)(t) == -b * T + + r(tf) → max + end + + # Components for a reasonable initial guess around a feasible trajectory. + init = (state=[1.01, 0.05, 0.8], control=0.5, variable=[0.1]) + + return (ocp=goddard, obj=1.01257, name="goddard", init=init) +end diff --git a/test/runtests.jl b/test/runtests.jl index a2c007763..0ae5916d5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,33 +1,52 @@ using Test +using ADNLPModels +using CommonSolve +using CTBase +using CTDirect +using CTModels +using CTSolvers using OptimalControl using NLPModelsIpopt using MadNLP using MadNLPMumps +using NLPModels using LinearAlgebra using OrdinaryDiffEq using DifferentiationInterface using ForwardDiff: ForwardDiff -using SplitApplyCombine # for flatten in some tests using NonlinearSolve +using SolverCore +using SplitApplyCombine # for flatten in some tests # NB some direct tests use functional definition and are `using CTModels` -@testset verbose = true showtiming = true "Optimal control tests" begin +# @testset verbose = true showtiming = true "Optimal control tests" begin + +# # ctdirect tests +# @testset verbose = true showtiming = true "CTDirect tests" begin +# # run all scripts in subfolder suite/ +# include.(filter(contains(r".jl$"), readdir("./ctdirect/suite"; join=true))) +# end + +# # other tests: indirect +# include("./indirect/Goddard.jl") +# for name in (:goddard_indirect,) +# @testset "$(name)" begin +# test_name = Symbol(:test_, name) +# println("Testing: " * string(name)) +# include("./indirect/$(test_name).jl") +# @eval $test_name() +# end +# end +# end + +const VERBOSE = true +const SHOWTIMING = true - # ctdirect tests - @testset verbose = true showtiming = true "CTDirect tests" begin - # run all scripts in subfolder suite/ - include.(filter(contains(r".jl$"), readdir("./ctdirect/suite"; join=true))) - end +include(joinpath(@__DIR__, "problems", "beam.jl")) +include(joinpath(@__DIR__, "problems", "goddard.jl")) - # other tests: indirect - include("./indirect/Goddard.jl") - for name in (:goddard_indirect,) - @testset "$(name)" begin - test_name = Symbol(:test_, name) - println("Testing: " * string(name)) - include("./indirect/$(test_name).jl") - @eval $test_name() - end - end -end +@testset verbose = VERBOSE showtiming = SHOWTIMING "Optimal control tests" begin + include(joinpath(@__DIR__, "test_optimalcontrol_solve_api.jl")) + test_optimalcontrol_solve_api() +end \ No newline at end of file diff --git a/test/test_optimalcontrol_solve_api.jl b/test/test_optimalcontrol_solve_api.jl new file mode 100644 index 000000000..57739a043 --- /dev/null +++ b/test/test_optimalcontrol_solve_api.jl @@ -0,0 +1,796 @@ +# Optimal control-level tests for solve on OCPs. + +struct OCDummyOCP <: CTModels.AbstractOptimalControlProblem end + +struct OCDummyDiscretizedOCP <: CTModels.AbstractOptimizationProblem end + +struct OCDummyInit <: CTModels.AbstractOptimalControlInitialGuess + x0::Vector{Float64} +end + +struct OCDummyStats <: SolverCore.AbstractExecutionStats + tag::Symbol +end + +struct OCDummySolution <: CTModels.AbstractOptimalControlSolution end + +struct OCFakeDiscretizer <: CTDirect.AbstractOptimalControlDiscretizer + calls::Base.RefValue{Int} +end + +function (d::OCFakeDiscretizer)(ocp::CTModels.AbstractOptimalControlProblem) + d.calls[] += 1 + return OCDummyDiscretizedOCP() +end + +struct OCFakeModeler <: CTModels.AbstractOptimizationModeler + model_calls::Base.RefValue{Int} + solution_calls::Base.RefValue{Int} +end + +function (m::OCFakeModeler)( + prob::CTModels.AbstractOptimizationProblem, init::OCDummyInit +)::NLPModels.AbstractNLPModel + m.model_calls[] += 1 + f(z) = sum(z .^ 2) + return ADNLPModels.ADNLPModel(f, init.x0) +end + +function (m::OCFakeModeler)( + prob::CTModels.AbstractOptimizationProblem, + nlp_solution::SolverCore.AbstractExecutionStats, +) + m.solution_calls[] += 1 + return OCDummySolution() +end + +struct OCFakeSolverNLP <: CTSolvers.AbstractOptimizationSolver + calls::Base.RefValue{Int} +end + +function (s::OCFakeSolverNLP)( + nlp::NLPModels.AbstractNLPModel; display::Bool +)::SolverCore.AbstractExecutionStats + s.calls[] += 1 + return OCDummyStats(:solver_called) +end + +function test_optimalcontrol_solve_api() + Test.@testset "raw defaults" verbose = VERBOSE showtiming = SHOWTIMING begin + Test.@test OptimalControl.OptimalControl.__initial_guess() === nothing + end + + Test.@testset "description helpers" verbose = VERBOSE showtiming = SHOWTIMING begin + methods = OptimalControl.available_methods() + Test.@test !isempty(methods) + + first_method = methods[1] + Test.@test first_method[1] === :collocation + Test.@test any( + m -> m[1] === :collocation && (:adnlp in m) && (:ipopt in m), methods + ) + + # Partial descriptions are completed using complete with priority order. + method_from_disc = CTBase.complete(:collocation; descriptions=methods) + Test.@test :collocation in method_from_disc + + method_from_solver = CTBase.complete(:ipopt; descriptions=methods) + Test.@test :ipopt in method_from_solver + + # Discretizer options registry: keys inferred from the Collocation tool + method = (:collocation, :adnlp, :ipopt) + keys_from_method = OptimalControl._discretizer_options_keys(method) + keys_from_type = CTModels.options_keys(OptimalControl.Collocation) + Test.@test keys_from_method == keys_from_type + + # Discretizer symbol helper + for m in methods + Test.@test OptimalControl._get_discretizer_symbol(m) === :collocation + end + + # Error when no discretizer symbol is present in the method + Test.@test_throws OptimalControl.IncorrectArgument OptimalControl._get_discretizer_symbol(( + :adnlp, :ipopt + )) + + # Modeler and solver symbol helpers using registries + for m in methods + msym = OptimalControl._get_modeler_symbol(m) + Test.@test msym in OptimalControl.CTModels.modeler_symbols() + ssym = OptimalControl._get_solver_symbol(m) + Test.@test ssym in CTSolvers.solver_symbols() + end + + # _modeler_options_keys / _solver_options_keys should match options_keys + method_ad_ip = (:collocation, :adnlp, :ipopt) + Test.@test Set(OptimalControl._modeler_options_keys(method_ad_ip)) == + Set(CTModels.options_keys(OptimalControl.ADNLPModeler)) + Test.@test Set(OptimalControl._solver_options_keys(method_ad_ip)) == + Set(CTModels.options_keys(OptimalControl.IpoptSolver)) + + method_exa_mad = (:collocation, :exa, :madnlp) + Test.@test Set(OptimalControl._modeler_options_keys(method_exa_mad)) == + Set(CTModels.options_keys(OptimalControl.ExaModeler)) + Test.@test Set(OptimalControl._solver_options_keys(method_exa_mad)) == + Set(CTModels.options_keys(OptimalControl.MadNLPSolver)) + + # Multiple symbols of the same family in a method should raise an error + Test.@test_throws OptimalControl.IncorrectArgument OptimalControl._get_modeler_symbol(( + :collocation, :adnlp, :exa, :ipopt + )) + Test.@test_throws OptimalControl.IncorrectArgument OptimalControl._get_solver_symbol(( + :collocation, :adnlp, :ipopt, :madnlp + )) + + # _build_modeler_from_method should construct the appropriate modeler + m_ad = OptimalControl._build_modeler_from_method( + (:collocation, :adnlp, :ipopt), (; backend=:manual) + ) + Test.@test m_ad isa OptimalControl.ADNLPModeler + + m_exa = OptimalControl._build_modeler_from_method( + (:collocation, :exa, :ipopt), NamedTuple() + ) + Test.@test m_exa isa OptimalControl.ExaModeler + + # _build_solver_from_method should construct the appropriate solver + s_ip = OptimalControl._build_solver_from_method( + (:collocation, :adnlp, :ipopt), NamedTuple() + ) + Test.@test s_ip isa OptimalControl.IpoptSolver + + s_mad = OptimalControl._build_solver_from_method( + (:collocation, :adnlp, :madnlp), NamedTuple() + ) + Test.@test s_mad isa OptimalControl.MadNLPSolver + + # Modeler options normalization helper + Test.@test OptimalControl._normalize_modeler_options(nothing) === NamedTuple() + Test.@test OptimalControl._normalize_modeler_options((backend=:manual,)) == + (backend=:manual,) + Test.@test OptimalControl._normalize_modeler_options((; backend=:manual)) == + (backend=:manual,) + + Test.@testset "description ambiguity pre-check (ownerless key)" verbose = VERBOSE showtiming = SHOWTIMING begin + method = (:collocation, :adnlp, :ipopt) + + # foo does not correspond to any tool nor to solve -> error + Test.@test_throws OptimalControl.IncorrectArgument begin + OptimalControl._ensure_no_ambiguous_description_kwargs(method, (foo=1,)) + end + end + end + + Test.@testset "option routing helpers" verbose = VERBOSE showtiming = SHOWTIMING begin + # _extract_option_tool without explicit tool tag + v, tool = OptimalControl._extract_option_tool(1.0) + Test.@test v == 1.0 + Test.@test tool === nothing + + # _extract_option_tool with explicit tool tag + v2, tool2 = OptimalControl._extract_option_tool((42, :solver)) + Test.@test v2 == 42 + Test.@test tool2 === :solver + + # Non-ambiguous routing: single owner + v3, owner3 = OptimalControl._route_option_for_description( + :tol, 1e-6, Symbol[:solver], :description + ) + Test.@test v3 == 1e-6 + Test.@test owner3 === :solver + + # Unknown ownership: empty owner list + owners_empty = Symbol[] + Test.@test_throws OptimalControl.IncorrectArgument OptimalControl._route_option_for_description( + :foo, 1, owners_empty, :description + ) + + # Ambiguous ownership in description mode + owners_amb = Symbol[:discretizer, :solver] + err = nothing + try + OptimalControl._route_option_for_description(:foo, 1.0, owners_amb, :description) + catch e + err = e + end + Test.@test err isa OptimalControl.IncorrectArgument + + # Disambiguation via (value, tool) + v4, owner4 = OptimalControl._route_option_for_description( + :foo, (2.0, :solver), owners_amb, :description + ) + Test.@test v4 == 2.0 + Test.@test owner4 === :solver + + # Ambiguous when coming from explicit mode should also throw + Test.@test_throws OptimalControl.IncorrectArgument OptimalControl._route_option_for_description( + :foo, 1.0, owners_amb, :explicit + ) + end + + Test.@testset "description kwarg splitting" verbose = VERBOSE showtiming = SHOWTIMING begin + # Ensure that description-mode parsing and splitting of kwargs produces + # well-typed NamedTuples and routes options to the expected tools. + parsed = OptimalControl._parse_top_level_kwargs_description(( + initial_guess=OCDummyInit([1.0, 2.0]), + display=false, + modeler_options=(backend=:manual,), + tol=1e-6, + )) + + pieces = OptimalControl._split_kwargs_for_description( + (:collocation, :adnlp, :ipopt), parsed + ) + + Test.@test pieces.initial_guess isa OCDummyInit + Test.@test pieces.display == false + Test.@test pieces.disc_kwargs == NamedTuple() + Test.@test pieces.modeler_options == (backend=:manual,) + Test.@test haskey(pieces.solver_kwargs, :tol) + Test.@test pieces.solver_kwargs.tol == 1e-6 + + # Solve-level aliases should be accepted in description mode. + parsed_alias = OptimalControl._parse_top_level_kwargs_description(( + init=OCDummyInit([3.0, 4.0]), + display=false, + modeler_options=(backend=:manual,), + tol=2e-6, + )) + + pieces_alias = OptimalControl._split_kwargs_for_description( + (:collocation, :adnlp, :ipopt), parsed_alias + ) + + Test.@test pieces_alias.initial_guess isa OCDummyInit + Test.@test pieces_alias.display == false + Test.@test pieces_alias.disc_kwargs == NamedTuple() + Test.@test pieces_alias.modeler_options == (backend=:manual,) + Test.@test haskey(pieces_alias.solver_kwargs, :tol) + Test.@test pieces_alias.solver_kwargs.tol == 2e-6 + + # Conflicting aliases for initial_guess should raise. + Test.@test_throws OptimalControl.IncorrectArgument begin + OptimalControl._parse_top_level_kwargs_description(( + initial_guess=OCDummyInit([1.0, 2.0]), i=OCDummyInit([3.0, 4.0]) + )) + end + + Test.@testset "description-mode solve/tool disambiguation" verbose = VERBOSE showtiming = SHOWTIMING begin + init = OCDummyInit([1.0, 2.0]) + + # 1) Alias i tagged :solve -> used as initial_guess, not kept in other_kwargs + parsed_solve = OptimalControl._parse_top_level_kwargs_description(( + i=(init, :solve), tol=1e-6 + )) + + Test.@test parsed_solve.initial_guess isa OCDummyInit + Test.@test parsed_solve.initial_guess === init + Test.@test !haskey(parsed_solve.other_kwargs, :i) + Test.@test haskey(parsed_solve.other_kwargs, :tol) + Test.@test parsed_solve.other_kwargs.tol == 1e-6 + + # 2) Alias i tagged :solver -> ignored by solve, left for the tools + parsed_solver = OptimalControl._parse_top_level_kwargs_description(( + i=(init, :solver), tol=2e-6 + )) + + # initial_guess stays at its default, alias i is kept in other_kwargs + Test.@test parsed_solver.initial_guess === OptimalControl.__initial_guess() + Test.@test haskey(parsed_solver.other_kwargs, :i) + Test.@test parsed_solver.other_kwargs.i == (init, :solver) + Test.@test haskey(parsed_solver.other_kwargs, :tol) + Test.@test parsed_solver.other_kwargs.tol == 2e-6 + + # 3) display tagged :solve -> top-level display + parsed_display_solve = OptimalControl._parse_top_level_kwargs_description(( + display=(false, :solve), + )) + Test.@test parsed_display_solve.display == false + Test.@test !haskey(parsed_display_solve.other_kwargs, :display) + + # 4) display tagged :solver -> ignored by solve, left for the tools + parsed_display_solver = OptimalControl._parse_top_level_kwargs_description(( + display=(false, :solver), + )) + Test.@test parsed_display_solver.display == OptimalControl.__display() + Test.@test haskey(parsed_display_solver.other_kwargs, :display) + Test.@test parsed_display_solver.other_kwargs.display == (false, :solver) + end + end + + Test.@testset "explicit-mode solve kwarg aliases" verbose = VERBOSE showtiming = SHOWTIMING begin + prob = OCDummyOCP() + init = OCDummyInit([1.0, 2.0]) + + discretizer_calls = Ref(0) + model_calls = Ref(0) + solution_calls = Ref(0) + solver_calls = Ref(0) + + discretizer = OCFakeDiscretizer(discretizer_calls) + modeler = OCFakeModeler(model_calls, solution_calls) + solver = OCFakeSolverNLP(solver_calls) + + # Using the "init" alias for initial_guess. + sol_init = solve( + prob; + init=init, + discretizer=discretizer, + modeler=modeler, + solver=solver, + display=false, + ) + Test.@test sol_init isa OCDummySolution + + # Using the short "i" alias for initial_guess. + discretizer_calls[] = 0 + model_calls[] = 0 + solution_calls[] = 0 + solver_calls[] = 0 + + sol_i = solve( + prob; + i=init, + discretizer=discretizer, + modeler=modeler, + solver=solver, + display=false, + ) + Test.@test sol_i isa OCDummySolution + Test.@test discretizer_calls[] == 1 + Test.@test model_calls[] == 1 + Test.@test solver_calls[] == 1 + Test.@test solution_calls[] == 1 + + # Short aliases for components d/m/s in explicit mode. + discretizer_calls[] = 0 + model_calls[] = 0 + solution_calls[] = 0 + solver_calls[] = 0 + + sol_dms = solve( + prob; initial_guess=init, d=discretizer, m=modeler, s=solver, display=false + ) + Test.@test sol_dms isa OCDummySolution + Test.@test discretizer_calls[] == 1 + Test.@test model_calls[] == 1 + Test.@test solver_calls[] == 1 + Test.@test solution_calls[] == 1 + + # Conflicting aliases for initial_guess in explicit mode should raise. + Test.@test_throws OptimalControl.IncorrectArgument begin + solve( + prob; + initial_guess=init, + init=init, + discretizer=discretizer, + modeler=modeler, + solver=solver, + display=false, + ) + end + end + + Test.@testset "display helpers" verbose = VERBOSE showtiming = SHOWTIMING begin + method = (:collocation, :adnlp, :ipopt) + discretizer = OptimalControl.Collocation() + modeler = OptimalControl.ADNLPModeler() + solver = OptimalControl.IpoptSolver() + + buf = sprint() do io + OptimalControl._display_ocp_method( + io, method, discretizer, modeler, solver; display=true + ) + end + Test.@test occursin("ADNLPModels", buf) + Test.@test occursin("NLPModelsIpopt", buf) + end + + # ======================================================================== + # Unit test: solve(ocp, init, discretizer, modeler, solver) + # ======================================================================== + + Test.@testset "solve(ocp, init, discretizer, modeler, solver)" verbose = VERBOSE showtiming = SHOWTIMING begin + prob = OCDummyOCP() + init = OCDummyInit([1.0, 2.0]) + + discretizer_calls = Ref(0) + model_calls = Ref(0) + solution_calls = Ref(0) + solver_calls = Ref(0) + + discretizer = OCFakeDiscretizer(discretizer_calls) + modeler = OCFakeModeler(model_calls, solution_calls) + solver = OCFakeSolverNLP(solver_calls) + + sol = OptimalControl._solve(prob, init, discretizer, modeler, solver; display=false) + + Test.@test sol isa OCDummySolution + Test.@test discretizer_calls[] == 1 + Test.@test model_calls[] == 1 + Test.@test solver_calls[] == 1 + Test.@test solution_calls[] == 1 + end + + Test.@testset "explicit-mode kwarg validation" verbose = VERBOSE showtiming = SHOWTIMING begin + prob = OCDummyOCP() + init = OCDummyInit([1.0, 2.0]) + + discretizer_calls = Ref(0) + model_calls = Ref(0) + solution_calls = Ref(0) + solver_calls = Ref(0) + + discretizer = OCFakeDiscretizer(discretizer_calls) + modeler = OCFakeModeler(model_calls, solution_calls) + solver = OCFakeSolverNLP(solver_calls) + + # modeler_options is forbidden in explicit mode + Test.@test_throws OptimalControl.IncorrectArgument begin + solve( + prob; + initial_guess=init, + discretizer=discretizer, + modeler=modeler, + solver=solver, + display=false, + modeler_options=(backend=:manual,), + ) + end + + # Unknown kwargs are rejected in explicit mode + Test.@test_throws OptimalControl.IncorrectArgument begin + solve( + prob; + initial_guess=init, + discretizer=discretizer, + modeler=modeler, + solver=solver, + display=false, + unknown_kwarg=1, + ) + end + + # Mixing description with explicit components is rejected + Test.@test_throws OptimalControl.IncorrectArgument begin + solve( + prob, + :collocation; + initial_guess=init, + discretizer=discretizer, + display=false, + ) + end + end + + Test.@testset "solve(ocp; kwargs)" verbose = VERBOSE showtiming = SHOWTIMING begin + prob = OCDummyOCP() + init = OCDummyInit([1.0, 2.0]) + + discretizer_calls = Ref(0) + model_calls = Ref(0) + solution_calls = Ref(0) + solver_calls = Ref(0) + + discretizer = OCFakeDiscretizer(discretizer_calls) + modeler = OCFakeModeler(model_calls, solution_calls) + solver = OCFakeSolverNLP(solver_calls) + + sol = solve( + prob; + initial_guess=init, + discretizer=discretizer, + modeler=modeler, + solver=solver, + display=false, + ) + + Test.@test sol isa OCDummySolution + Test.@test discretizer_calls[] == 1 + Test.@test model_calls[] == 1 + Test.@test solver_calls[] == 1 + Test.@test solution_calls[] == 1 + end + + # ======================================================================== + # Integration tests: Beam OCP level with Ipopt and MadNLP + # ======================================================================== + + Test.@testset "Beam OCP level" verbose = VERBOSE showtiming = SHOWTIMING begin + ipopt_options = Dict( + :max_iter => 1000, + :tol => 1e-6, + :print_level => 0, + :mu_strategy => "adaptive", + :linear_solver => "Mumps", + :sb => "yes", + ) + + madnlp_options = Dict(:max_iter => 1000, :tol => 1e-6, :print_level => MadNLP.ERROR) + + beam_data = Beam() + ocp = beam_data.ocp + init = OptimalControl.initial_guess(ocp; beam_data.init...) + discretizer = OptimalControl.Collocation() + + modelers = [OptimalControl.ADNLPModeler(; backend=:manual), OptimalControl.ExaModeler()] + modelers_names = ["ADNLPModeler (manual)", "ExaModeler (CPU)"] + + # ------------------------------------------------------------------ + # OCP level: solve(ocp, init, discretizer, modeler, solver) + # ------------------------------------------------------------------ + + Test.@testset "OCP level (Ipopt)" verbose = VERBOSE showtiming = SHOWTIMING begin + for (modeler, modeler_name) in zip(modelers, modelers_names) + Test.@testset "$(modeler_name)" verbose = VERBOSE showtiming = SHOWTIMING begin + solver = OptimalControl.IpoptSolver(; ipopt_options...) + sol = OptimalControl._solve( + ocp, init, discretizer, modeler, solver; display=false + ) + Test.@test sol isa Solution + Test.@test successful(sol) + Test.@test isfinite(objective(sol)) + Test.@test objective(sol) ≈ beam_data.obj atol = 1e-2 + Test.@test iterations(sol) <= ipopt_options[:max_iter] + Test.@test constraints_violation(sol) <= 1e-6 + end + end + end + + Test.@testset "OCP level (MadNLP)" verbose = VERBOSE showtiming = SHOWTIMING begin + for (modeler, modeler_name) in zip(modelers, modelers_names) + Test.@testset "$(modeler_name)" verbose = VERBOSE showtiming = SHOWTIMING begin + solver = OptimalControl.MadNLPSolver(; madnlp_options...) + sol = OptimalControl._solve( + ocp, init, discretizer, modeler, solver; display=false + ) + Test.@test sol isa Solution + Test.@test successful(sol) + Test.@test isfinite(objective(sol)) + Test.@test objective(sol) ≈ beam_data.obj atol = 1e-2 + Test.@test iterations(sol) <= madnlp_options[:max_iter] + Test.@test constraints_violation(sol) <= 1e-6 + end + end + end + + # ------------------------------------------------------------------ + # OCP level with @init (Ipopt, ADNLPModeler) + # ------------------------------------------------------------------ + + Test.@testset "OCP level with @init (Ipopt, ADNLPModeler)" verbose = VERBOSE showtiming = SHOWTIMING begin + init_macro = OptimalControl.@init ocp begin + x := [0.05, 0.1] + u := 0.1 + end + modeler = OptimalControl.ADNLPModeler(; backend=:manual) + solver = OptimalControl.IpoptSolver(; ipopt_options...) + sol = OptimalControl._solve( + ocp, init_macro, discretizer, modeler, solver; display=false + ) + Test.@test sol isa Solution + Test.@test successful(sol) + Test.@test isfinite(objective(sol)) + end + + # ------------------------------------------------------------------ + # OCP level: keyword-based API solve(ocp; ...) + # ------------------------------------------------------------------ + + Test.@testset "OCP level keyword API (Ipopt, ADNLPModeler)" verbose = VERBOSE showtiming = SHOWTIMING begin + modeler = OptimalControl.ADNLPModeler(; backend=:manual) + solver = OptimalControl.IpoptSolver(; ipopt_options...) + sol = solve( + ocp; + initial_guess=init, + discretizer=discretizer, + modeler=modeler, + solver=solver, + display=false, + ) + Test.@test sol isa Solution + Test.@test successful(sol) + Test.@test isfinite(objective(sol)) + Test.@test iterations(sol) <= ipopt_options[:max_iter] + Test.@test constraints_violation(sol) <= 1e-6 + end + + # ------------------------------------------------------------------ + # OCP level: description-based API solve(ocp, description; ...) + # ------------------------------------------------------------------ + + Test.@testset "OCP level description API" verbose = VERBOSE showtiming = SHOWTIMING begin + desc_cases = [ + ((:collocation, :adnlp, :ipopt), ipopt_options), + ((:collocation, :adnlp, :madnlp), madnlp_options), + ((:collocation, :exa, :ipopt), ipopt_options), + ((:collocation, :exa, :madnlp), madnlp_options), + ] + + for (method_syms, options) in desc_cases + Test.@testset "description = $(method_syms)" verbose = VERBOSE showtiming = SHOWTIMING begin + sol = solve( + ocp, method_syms...; initial_guess=init, display=false, options... + ) + Test.@test sol isa Solution + Test.@test successful(sol) + Test.@test isfinite(objective(sol)) + + if :ipopt in method_syms + Test.@test iterations(sol) <= ipopt_options[:max_iter] + Test.@test constraints_violation(sol) <= 1e-6 + elseif :madnlp in method_syms + Test.@test iterations(sol) <= madnlp_options[:max_iter] + Test.@test constraints_violation(sol) <= 1e-6 + end + end + end + + # modeler_options is allowed in description mode and forwarded to the + # modeler constructor. + Test.@testset "description API with modeler_options" verbose = VERBOSE showtiming = SHOWTIMING begin + sol = solve( + ocp, + :collocation, + :adnlp, + :ipopt; + initial_guess=init, + modeler_options=(backend=:manual,), + display=false, + ipopt_options..., + ) + Test.@test sol isa Solution + Test.@test successful(sol) + end + + # Tagged options using the (value, tool) convention: discretizer options + # are explicitly routed to the discretizer, and Ipopt options to the solver. + Test.@testset "description API with explicit tool tags" verbose = VERBOSE showtiming = SHOWTIMING begin + sol = solve( + ocp, + :collocation, + :adnlp, + :ipopt; + initial_guess=init, + display=false, + # Discretizer options + grid=(get_option_value(discretizer, :grid), :discretizer), + scheme=(get_option_value(discretizer, :scheme), :discretizer), + # Ipopt solver options + max_iter=(ipopt_options[:max_iter], :solver), + tol=(ipopt_options[:tol], :solver), + print_level=(ipopt_options[:print_level], :solver), + mu_strategy=(ipopt_options[:mu_strategy], :solver), + linear_solver=(ipopt_options[:linear_solver], :solver), + sb=(ipopt_options[:sb], :solver), + ) + Test.@test sol isa Solution + Test.@test successful(sol) + Test.@test isfinite(objective(sol)) + Test.@test iterations(sol) <= ipopt_options[:max_iter] + Test.@test constraints_violation(sol) <= 1e-6 + end + end + end + + # ======================================================================== + # Integration tests: Goddard OCP level with Ipopt and MadNLP + # ======================================================================== + + Test.@testset "Goddard OCP level" verbose = VERBOSE showtiming = SHOWTIMING begin + ipopt_options = Dict( + :max_iter => 1000, + :tol => 1e-6, + :print_level => 0, + :mu_strategy => "adaptive", + :linear_solver => "Mumps", + :sb => "yes", + ) + + madnlp_options = Dict(:max_iter => 1000, :tol => 1e-6, :print_level => MadNLP.ERROR) + + gdata = Goddard() + ocp_g = gdata.ocp + init_g = OptimalControl.initial_guess(ocp_g; gdata.init...) + discretizer_g = OptimalControl.Collocation() + + modelers = [OptimalControl.ADNLPModeler(; backend=:manual), OptimalControl.ExaModeler()] + modelers_names = ["ADNLPModeler (manual)", "ExaModeler (CPU)"] + + # ------------------------------------------------------------------ + # OCP level: solve(ocp_g, init_g, discretizer_g, modeler, solver) + # ------------------------------------------------------------------ + + Test.@testset "OCP level (Ipopt)" verbose = VERBOSE showtiming = SHOWTIMING begin + for (modeler, modeler_name) in zip(modelers, modelers_names) + Test.@testset "$(modeler_name)" verbose = VERBOSE showtiming = SHOWTIMING begin + solver = OptimalControl.IpoptSolver(; ipopt_options...) + sol = OptimalControl._solve( + ocp_g, init_g, discretizer_g, modeler, solver; display=false + ) + Test.@test sol isa Solution + Test.@test successful(sol) + Test.@test isfinite(objective(sol)) + Test.@test objective(sol) ≈ gdata.obj atol = 1e-4 + Test.@test iterations(sol) <= ipopt_options[:max_iter] + Test.@test constraints_violation(sol) <= 1e-6 + end + end + end + + Test.@testset "OCP level (MadNLP)" verbose = VERBOSE showtiming = SHOWTIMING begin + for (modeler, modeler_name) in zip(modelers, modelers_names) + Test.@testset "$(modeler_name)" verbose = VERBOSE showtiming = SHOWTIMING begin + solver = OptimalControl.MadNLPSolver(; madnlp_options...) + sol = OptimalControl._solve( + ocp_g, init_g, discretizer_g, modeler, solver; display=false + ) + Test.@test sol isa Solution + Test.@test successful(sol) + Test.@test isfinite(objective(sol)) + Test.@test objective(sol) ≈ gdata.obj atol = 1e-4 + Test.@test iterations(sol) <= madnlp_options[:max_iter] + Test.@test constraints_violation(sol) <= 1e-6 + end + end + end + + # ------------------------------------------------------------------ + # OCP level keyword API (Ipopt, ADNLPModeler) + # ------------------------------------------------------------------ + + Test.@testset "OCP level keyword API (Ipopt, ADNLPModeler)" verbose = VERBOSE showtiming = SHOWTIMING begin + modeler = OptimalControl.ADNLPModeler(; backend=:manual) + solver = OptimalControl.IpoptSolver(; ipopt_options...) + sol = solve( + ocp_g; + initial_guess=init_g, + discretizer=discretizer_g, + modeler=modeler, + solver=solver, + display=false, + ) + Test.@test sol isa Solution + Test.@test successful(sol) + Test.@test isfinite(objective(sol)) + Test.@test iterations(sol) <= ipopt_options[:max_iter] + Test.@test constraints_violation(sol) <= 1e-6 + end + + # ------------------------------------------------------------------ + # OCP level description API (Ipopt and MadNLP) + # ------------------------------------------------------------------ + + Test.@testset "OCP level description API" verbose = VERBOSE showtiming = SHOWTIMING begin + desc_cases = [ + ((:collocation, :adnlp, :ipopt), ipopt_options), + ((:collocation, :adnlp, :madnlp), madnlp_options), + ((:collocation, :exa, :ipopt), ipopt_options), + ((:collocation, :exa, :madnlp), madnlp_options), + ] + + for (method_syms, options) in desc_cases + Test.@testset "description = $(method_syms)" verbose = VERBOSE showtiming = SHOWTIMING begin + sol = solve( + ocp_g, + method_syms...; + initial_guess=init_g, + display=false, + options..., + ) + Test.@test sol isa Solution + Test.@test successful(sol) + Test.@test isfinite(objective(sol)) + + if :ipopt in method_syms + Test.@test iterations(sol) <= ipopt_options[:max_iter] + Test.@test constraints_violation(sol) <= 1e-6 + elseif :madnlp in method_syms + Test.@test iterations(sol) <= madnlp_options[:max_iter] + Test.@test constraints_violation(sol) <= 1e-6 + end + end + end + end + end +end \ No newline at end of file