From e33b8d8d6be801020e9ec84cb496582a5ae10738 Mon Sep 17 00:00:00 2001 From: Bart Date: Tue, 30 Jun 2026 16:19:37 +0200 Subject: [PATCH] Remove ControlPlots backend; migrate plotting to Makie + MakieControlPlots - Delete the ControlPlots extension, examples_cp/, and the PythonCall/ Matplotlib setup (bin/install_controlplots, CI matplotlib/PyCall steps). - Collapse the plot-backend dispatch (PlotBackend/MakieBackend/ ControlPlotsBackend/set_plot_backend\!); plotting works once a Makie backend and MakieControlPlots are loaded. Drop the never-implemented plot_circulation_distribution. - VortexStepMethodMakieExt now triggers on ["Makie", "MakieControlPlots"] and renders plot_section_polars via MakieControlPlots; other plots stay native Makie. - Examples load GLMakie/CairoMakie + MakieControlPlots. - Add tests for plot_section_polars and plot_airfoils; regenerate the 1.11 and 1.12 default manifests; drop dead PyCall Aqua ignores. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/CI.yml | 10 - CHANGELOG.md | 17 + Manifest-v1.11.toml.default | 270 ++++--- Manifest-v1.12.toml.default | 458 ++++++----- Project.toml | 11 +- README.md | 19 +- bin/install | 42 +- bin/install_controlplots | 348 -------- bin/jetls_examples | 3 - bin/run_julia | 2 +- docs/Project.toml | 1 + docs/make.jl | 1 + docs/src/examples.md | 46 +- docs/src/functions.md | 3 +- docs/src/index.md | 6 - examples/Project.toml | 1 + examples/V3_neuralfoil.jl | 1 + examples/linearize_check.jl | 1 + examples/menu.jl | 3 +- examples/neuralfoil_polars.jl | 1 + examples/ram_air_kite.jl | 1 + examples/show_slices.jl | 1 + examples_cp/LocalPreferences.toml.default | 5 - examples_cp/Project.toml | 11 - examples_cp/menu_cp.jl | 75 -- ext/VortexStepMethodControlPlotsExt.jl | 943 ---------------------- ext/VortexStepMethodMakieExt.jl | 244 +----- src/VortexStepMethod.jl | 144 ++-- test/Aqua.jl | 3 +- test/LocalPreferences.toml.default | 2 - test/Project.toml | 6 +- test/plotting/test_backend_coexistence.jl | 42 - test/plotting/test_plotting.jl | 139 ++-- test/runtests.jl | 56 +- test/test_setup.sh | 2 +- 35 files changed, 626 insertions(+), 2292 deletions(-) delete mode 100755 bin/install_controlplots delete mode 100644 examples_cp/LocalPreferences.toml.default delete mode 100644 examples_cp/Project.toml delete mode 100644 examples_cp/menu_cp.jl delete mode 100644 ext/VortexStepMethodControlPlotsExt.jl delete mode 100644 test/LocalPreferences.toml.default delete mode 100644 test/plotting/test_backend_coexistence.jl diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 10ae5147..5d2491e7 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -56,12 +56,6 @@ jobs: ${{ runner.os }}-test- ${{ runner.os }}- - uses: julia-actions/julia-buildpkg@v1 - - name: Install matplotlib - if: runner.os == 'Linux' - run: sudo apt-get update && sudo apt-get install -y python3-matplotlib - - name: Build PyCall with system Python - if: runner.os == 'Linux' - run: julia -e 'ENV["PYTHON"]="python3"; using Pkg; Pkg.add("PyCall"); Pkg.build("PyCall")' - uses: julia-actions/julia-runtest@v1 env: BUILD_IS_PRODUCTION_BUILD: ${{ matrix.build_is_production_build }} @@ -89,10 +83,6 @@ jobs: version: ${{ matrix.julia_version }} - uses: julia-actions/cache@v2 - uses: julia-actions/julia-buildpkg@v1 - - name: Install matplotlib - run: sudo apt-get update && sudo apt-get install -y python3-matplotlib - - name: Build PyCall with system Python - run: julia -e 'ENV["PYTHON"]="python3"; using Pkg; Pkg.add("PyCall"); Pkg.build("PyCall")' - uses: julia-actions/julia-runtest@v1 env: BUILD_IS_PRODUCTION_BUILD: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 64e09d73..f344e5b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## Unreleased + +### Removed +- The `ControlPlots` plotting backend and its extension + `VortexStepMethodControlPlotsExt`, together with the `PythonCall`/Matplotlib + setup it required. Plotting is now Makie-only. +- The plot-backend dispatch machinery: `PlotBackend`, `MakieBackend`, + `ControlPlotsBackend`, and `set_plot_backend!`. Plotting functions work as + soon as a Makie backend and `MakieControlPlots` are loaded. +- `plot_circulation_distribution` (an exported stub that was never implemented). +- The `examples_cp/` directory and the `menu_cp()` ControlPlots example menu. + +### Changed +- The Makie extension now also loads when `MakieControlPlots` is present and uses + it for `plot_section_polars`. Examples load `GLMakie`/`CairoMakie` together + with `MakieControlPlots`. + ## VortexStepMethod v3.3.6 2026-06-13 ### Added diff --git a/Manifest-v1.11.toml.default b/Manifest-v1.11.toml.default index 43306bba..4c36e892 100644 --- a/Manifest-v1.11.toml.default +++ b/Manifest-v1.11.toml.default @@ -2,12 +2,12 @@ julia_version = "1.11.9" manifest_format = "2.0" -project_hash = "3afeaa867282214c3057ab37347a1bbb8af6fe92" +project_hash = "6d819b6b32f1312b2d31d1cba26887098fe3abd1" [[deps.ADTypes]] -git-tree-sha1 = "f7304359109c768cf32dc5fa2d371565bb63b68a" +git-tree-sha1 = "d9aaef7c63466eee4de23b4d9dad03629df54bea" uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" -version = "1.21.0" +version = "1.22.1" weakdeps = ["ChainRulesCore", "ConstructionBase", "EnzymeCore"] [deps.ADTypes.extensions] @@ -15,11 +15,17 @@ weakdeps = ["ChainRulesCore", "ConstructionBase", "EnzymeCore"] ADTypesConstructionBaseExt = "ConstructionBase" ADTypesEnzymeCoreExt = "EnzymeCore" +[[deps.AMD]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse_jll"] +git-tree-sha1 = "45a1272e3f809d36431e57ab22703c6896b8908f" +uuid = "14f7f29c-3bd6-536c-9a0b-7339e30b5a3e" +version = "0.5.3" + [[deps.Accessors]] deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] -git-tree-sha1 = "2eeb2c9bef11013efc6f8f97f32ee59b146b09fb" +git-tree-sha1 = "7063ad1083578215c7c4bf410368150abe8d5524" uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.44" +version = "0.1.45" [deps.Accessors.extensions] AxisKeysExt = "AxisKeys" @@ -40,10 +46,10 @@ version = "0.1.44" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" [[deps.Adapt]] -deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "0761717147821d696c9470a7a86364b2fbd22fd8" +deps = ["LinearAlgebra"] +git-tree-sha1 = "daa72978cd7a624246e894a4f4f067706d4e17e2" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.5.2" +version = "4.7.0" weakdeps = ["SparseArrays", "StaticArrays"] [deps.Adapt.extensions] @@ -56,9 +62,9 @@ version = "1.1.2" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "54f895554d05c83e3dd59f6a396671dae8999573" +git-tree-sha1 = "75757da5d9f771ef5909fc84f81d2f9d24127315" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.24.0" +version = "7.27.0" [deps.ArrayInterface.extensions] ArrayInterfaceAMDGPUExt = "AMDGPU" @@ -68,6 +74,7 @@ version = "7.24.0" ArrayInterfaceCUDSSExt = ["CUDSS", "CUDA"] ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceFillArraysExt = "FillArrays" ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" ArrayInterfaceMetalExt = "Metal" ArrayInterfaceReverseDiffExt = "ReverseDiff" @@ -83,6 +90,7 @@ version = "7.24.0" CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" @@ -106,9 +114,9 @@ version = "1.11.0" [[deps.BracketingNonlinearSolve]] deps = ["CommonSolve", "ConcreteStructs", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "7ad7171d693ae5552ac43862e7f6b61df4471c2b" +git-tree-sha1 = "6e7c9b6ab9aa711009a49252e45a122212c1d869" uuid = "70df07ce-3d50-431d-a3e7-ca6ddb60ac1e" -version = "1.12.1" +version = "1.12.2" weakdeps = ["ChainRulesCore", "ForwardDiff"] [deps.BracketingNonlinearSolve.extensions] @@ -144,9 +152,9 @@ uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.13.1" [[deps.CommonSolve]] -git-tree-sha1 = "78ea4ddbcf9c241827e7035c3a03e2e456711470" +git-tree-sha1 = "99ee296f88c12485402e37c2fd025f95ae097637" uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" -version = "0.2.6" +version = "0.2.9" [[deps.CommonSubexpressions]] deps = ["MacroTools"] @@ -179,9 +187,9 @@ weakdeps = ["InverseFunctions"] CompositionsBaseInverseFunctionsExt = "InverseFunctions" [[deps.ConcreteStructs]] -git-tree-sha1 = "f749037478283d372048690eb3b5f92a79432b34" +git-tree-sha1 = "1988532cb3b4525bb718b99ba07e433bbf0e600b" uuid = "2569d6c7-a4a2-43d3-a901-331e8e4be471" -version = "0.2.3" +version = "0.2.5" [[deps.ConstructionBase]] git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" @@ -223,15 +231,15 @@ version = "1.1.0" [[deps.DiffRules]] deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] -git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +git-tree-sha1 = "79a2aca180a85c690c58a020d47b426954b590f8" uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "1.15.1" +version = "1.16.0" [[deps.DifferentiationInterface]] deps = ["ADTypes", "LinearAlgebra"] -git-tree-sha1 = "7ae99144ea44715402c6c882bfef2adbeadbc4ce" +git-tree-sha1 = "2147a95a217cc8a78ec96ee03581adf129468e49" uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" -version = "0.7.16" +version = "0.7.18" [deps.DifferentiationInterface.extensions] DifferentiationInterfaceChainRulesCoreExt = "ChainRulesCore" @@ -241,8 +249,9 @@ version = "0.7.16" DifferentiationInterfaceFiniteDiffExt = "FiniteDiff" DifferentiationInterfaceFiniteDifferencesExt = "FiniteDifferences" DifferentiationInterfaceForwardDiffExt = ["ForwardDiff", "DiffResults"] - DifferentiationInterfaceGPUArraysCoreExt = "GPUArraysCore" + DifferentiationInterfaceGPUArraysCoreExt = ["GPUArraysCore", "Adapt"] DifferentiationInterfaceGTPSAExt = "GTPSA" + DifferentiationInterfaceHyperHessiansExt = "HyperHessians" DifferentiationInterfaceMooncakeExt = "Mooncake" DifferentiationInterfacePolyesterForwardDiffExt = ["PolyesterForwardDiff", "ForwardDiff", "DiffResults"] DifferentiationInterfaceReverseDiffExt = ["ReverseDiff", "DiffResults"] @@ -255,6 +264,7 @@ version = "0.7.16" DifferentiationInterfaceZygoteExt = ["Zygote", "ForwardDiff"] [deps.DifferentiationInterface.weakdeps] + Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" DiffResults = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" Diffractor = "9f5e2b26-1114-432f-b630-d3fe2085c51c" @@ -266,6 +276,7 @@ version = "0.7.16" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" GTPSA = "b27dd330-f138-47c5-815b-40db9dd9b6e8" + HyperHessians = "06b494a0-c8e0-40cc-ad32-d99506a00a6c" Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" @@ -298,9 +309,9 @@ uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" version = "1.0.7" [[deps.EnzymeCore]] -git-tree-sha1 = "24bbb6fc8fb87eb71c1f8d00184a60fc22c63903" +git-tree-sha1 = "c6ee69ee502060982d12dbaaf3d8fcb4e835a0d1" uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" -version = "0.8.19" +version = "0.8.20" weakdeps = ["Adapt", "ChainRulesCore"] [deps.EnzymeCore.extensions] @@ -317,15 +328,27 @@ git-tree-sha1 = "acebe244d53ee1b461970f8910c235b259e772ef" uuid = "9aa1b823-49e4-5ca5-8b0f-3971ec8bab6a" version = "0.3.2" +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "8e9c059d6857607253e837730dbf780b6b151acd" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.19.0" + + [deps.FileIO.extensions] + HTTPExt = "HTTP" + + [deps.FileIO.weakdeps] + HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3" + [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" version = "1.11.0" [[deps.FiniteDiff]] deps = ["ArrayInterface", "LinearAlgebra", "Setfield"] -git-tree-sha1 = "73e879af0e767bd6dfade7c5b09d7b05657a8284" +git-tree-sha1 = "2e5742cda07276e1834281ada4cc71b6bfc87586" uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.30.0" +version = "2.31.1" [deps.FiniteDiff.extensions] FiniteDiffBandedMatricesExt = "BandedMatrices" @@ -340,16 +363,16 @@ version = "2.30.0" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" [[deps.FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +deps = ["Random", "Statistics"] +git-tree-sha1 = "59af96b98217c6ef4ae0dfe065ac7c20831d1a84" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.5" +version = "0.8.6" [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "cddeab6487248a39dae1a960fff0ac17b2a28888" +git-tree-sha1 = "2c5d0b0e12088cde2cf84afb2784415b1ea3dfee" uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "1.3.3" +version = "1.4.1" weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] @@ -362,9 +385,9 @@ version = "1.1.3" [[deps.FunctionWrappersWrappers]] deps = ["FunctionWrappers", "PrecompileTools", "TruncatedStacktraces"] -git-tree-sha1 = "ce6762f8f0e7542534f01523ae051e625cbf0468" +git-tree-sha1 = "9760060160c6d7f642308eed67a40a1ffe3f028c" uuid = "77dc65aa-8811-40c2-897b-53d922fa7daf" -version = "1.5.0" +version = "1.9.3" [deps.FunctionWrappersWrappers.extensions] FunctionWrappersWrappersEnzymeExt = ["Enzyme", "EnzymeCore"] @@ -399,9 +422,9 @@ version = "1.11.0" [[deps.Interpolations]] deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] -git-tree-sha1 = "65d505fa4c0d7072990d659ef3fc086eb6da8208" +git-tree-sha1 = "48922d06068130f87e43edef52382e6a94305ae6" uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.16.2" +version = "0.16.3" [deps.Interpolations.extensions] InterpolationsForwardDiffExt = "ForwardDiff" @@ -436,15 +459,15 @@ version = "1.0.0" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +git-tree-sha1 = "7204148362dafe5fe6a273f855b8ccbe4df8173e" uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.7.1" +version = "1.8.0" [[deps.Krylov]] deps = ["LinearAlgebra", "Printf", "SparseArrays"] -git-tree-sha1 = "c4d19f51afc7ba2afbe32031b8f2d21b11c9e26e" +git-tree-sha1 = "fc2e5bc665dfa1be33fac60b5762d462bccfae7b" uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" -version = "0.10.6" +version = "0.10.8" [[deps.LaTeXStrings]] git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" @@ -493,9 +516,9 @@ version = "1.18.0+0" [[deps.LineSearch]] deps = ["ADTypes", "CommonSolve", "ConcreteStructs", "FastClosures", "LinearAlgebra", "MaybeInplace", "PrecompileTools", "SciMLBase", "SciMLJacobianOperators", "StaticArraysCore"] -git-tree-sha1 = "69da095e4c24ed3c4a168bb76dc9c620a6d7239c" +git-tree-sha1 = "a7553de02835e996f80bf895a291ab981ba1f796" uuid = "87fe0de2-c867-4266-b59a-2f0a94fc965b" -version = "0.1.7" +version = "0.1.10" [deps.LineSearch.extensions] LineSearchLineSearchesExt = "LineSearches" @@ -509,10 +532,10 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" version = "1.11.0" [[deps.LinearSolve]] -deps = ["ArrayInterface", "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 = "42b5cb44317e89ef75dd841c9c8eba9045bf9ff0" +deps = ["AMD", "ArrayInterface", "ConcreteStructs", "DocStringExtensions", "EnumX", "GPUArraysCore", "InteractiveUtils", "Krylov", "Libdl", "LinearAlgebra", "MKL_jll", "Markdown", "OpenBLAS_jll", "PrecompileTools", "Preferences", "PureKLU", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLLogging", "SciMLOperators", "Setfield", "SparseArrays", "SparseColumnPivotedQR", "StaticArraysCore"] +git-tree-sha1 = "ec49ed72f6024be2f9833fe630fbd72f6048f8ad" uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -version = "3.75.0" +version = "3.87.0" [deps.LinearSolve.extensions] LinearSolveAMDGPUExt = "AMDGPU" @@ -520,7 +543,7 @@ version = "3.75.0" LinearSolveBLISExt = ["blis_jll", "LAPACK_jll"] LinearSolveBandedMatricesExt = "BandedMatrices" LinearSolveBlockDiagonalsExt = "BlockDiagonals" - LinearSolveCUDAExt = "CUDA" + LinearSolveCUDAExt = ["cuSOLVER"] LinearSolveCUDSSExt = "CUDSS" LinearSolveCUSOLVERRFExt = ["CUSOLVERRF", "SparseArrays"] LinearSolveChainRulesCoreExt = "ChainRulesCore" @@ -531,27 +554,32 @@ version = "3.75.0" LinearSolveFastLapackInterfaceExt = "FastLapackInterface" LinearSolveForwardDiffExt = "ForwardDiff" LinearSolveGinkgoExt = ["Ginkgo", "SparseArrays"] + LinearSolveHSLExt = ["HSL", "SparseArrays"] LinearSolveHYPREExt = "HYPRE" LinearSolveIterativeSolversExt = "IterativeSolvers" LinearSolveKernelAbstractionsExt = "KernelAbstractions" LinearSolveKrylovKitExt = "KrylovKit" + LinearSolveMUMPSExt = ["MUMPS", "SparseArrays"] LinearSolveMetalExt = "Metal" LinearSolveMooncakeExt = "Mooncake" - LinearSolvePETScCSRExt = ["PETSc", "SparseArrays", "SparseMatricesCSR"] - LinearSolvePETScExt = ["PETSc", "SparseArrays"] + LinearSolvePETScExt = ["PETSc", "SparseArrays", "SparseMatricesCSR"] LinearSolvePETScMPIExt = ["PETSc", "PartitionedArrays", "SparseArrays", "SparseMatricesCSR"] LinearSolveParUExt = ["ParU_jll", "SparseArrays"] LinearSolvePardisoExt = ["Pardiso", "SparseArrays"] + LinearSolvePartitionedSolversExt = ["PartitionedArrays", "PartitionedSolvers"] + LinearSolvePureUMFPACKExt = ["PureUMFPACK", "SparseArrays"] LinearSolveRecursiveFactorizationExt = "RecursiveFactorization" + LinearSolveSTRUMPACKExt = ["SparseArrays", "STRUMPACK_jll"] LinearSolveSparseArraysExt = "SparseArrays" LinearSolveSparspakExt = ["SparseArrays", "Sparspak"] + LinearSolveSpecializingFactorizationsExt = "SpecializingFactorizations" + LinearSolveSuperLUDISTExt = ["SparseArrays", "SuperLUDIST"] [deps.LinearSolve.weakdeps] AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" AlgebraicMultigrid = "2169fc97-5a83-5252-b627-83903c6c433c" BandedMatrices = "aae01518-5342-5314-be14-df237901396f" BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" CUSOLVERRF = "a8cc9031-bad2-4722-94f5-40deabb4245c" ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" @@ -562,28 +590,35 @@ version = "3.75.0" FastLapackInterface = "29a986be-02c6-4525-aec4-84b980013641" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Ginkgo = "4c8bd3c9-ead9-4b5e-a625-08f1338ba0ec" + HSL = "34c5aeac-e683-54a6-a0e9-6e0fdc586c50" HYPRE = "b5ffcf37-a2bd-41ab-a3da-4bd9bc8ad771" IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" LAPACK_jll = "51474c39-65e3-53ba-86ba-03b1b862ec14" + MUMPS = "55d2b088-9f4e-11e9-26c0-150b02ea6a46" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" PETSc = "ace2c81b-2b5f-4b1e-a30d-d662738edfe0" ParU_jll = "9e0b026c-e8ce-559c-a2c4-6a3d5c955bc9" Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2" PartitionedArrays = "5a9dfac6-5c52-46f7-8278-5e2210713be9" + PartitionedSolvers = "11b65f7f-80ac-401b-9ef2-3db765482d62" + PureUMFPACK = "b7e1f0a2-3c4d-4e5f-9a0b-1c2d3e4f5a6b" RecursiveFactorization = "f2c3362d-daeb-58d1-803e-2bc74f2840b4" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + STRUMPACK_jll = "86fbd0b9-476f-557c-b766-62c724b42d8c" SparseMatricesCSR = "a0a7dd2c-ebf4-11e9-1f05-cf50bc540ca1" Sparspak = "e56a9233-b9d6-4f03-8d0f-1825330902ac" + SpecializingFactorizations = "fa08b7a1-13d3-4faf-875d-5cbc1520e3f3" + SuperLUDIST = "4cd002a6-0da4-410d-a012-232df062f478" blis_jll = "6136c539-28a5-5bf0-87cc-b183200dce32" + cuSOLVER = "887afef0-6a32-4de5-add4-7827692ba8fc" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +git-tree-sha1 = "bba2d9aa057d8f126415de240573e86a8f39d2a1" uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.29" +version = "1.0.1" [deps.LogExpFunctions.extensions] LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" @@ -623,9 +658,9 @@ version = "1.11.0" [[deps.MaybeInplace]] deps = ["ArrayInterface", "LinearAlgebra", "MacroTools"] -git-tree-sha1 = "54e2fdc38130c05b42be423e90da3bade29b74bd" +git-tree-sha1 = "bf287c2abdd365d73c9ee86b262c6d8af0d6e2a1" uuid = "bb5d69b7-63fc-4a16-80bd-7e42200c7bdb" -version = "0.1.4" +version = "0.1.5" weakdeps = ["SparseArrays"] [deps.MaybeInplace.extensions] @@ -649,21 +684,33 @@ version = "1.11.0" uuid = "14a3606d-f60d-562e-9121-12d972cd8159" version = "2023.12.12" +[[deps.MuladdMacro]] +deps = ["PrecompileTools"] +git-tree-sha1 = "e8dcbeef032ba2f9051a44ac22b4e54e3a1a0099" +uuid = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +version = "0.2.6" + +[[deps.NPZ]] +deps = ["FileIO", "ZipFile"] +git-tree-sha1 = "60a8e272fe0c5079363b28b0953831e2dd7b7e6f" +uuid = "15e1cf62-19b3-5cfa-8e77-841668bca605" +version = "0.4.3" + [[deps.NaNMath]] deps = ["OpenLibm_jll"] -git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +git-tree-sha1 = "dbd2e8cd2c1c27f0b584f6661b4309609c5a685e" uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "1.1.3" +version = "1.1.4" [[deps.NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" [[deps.NonlinearSolve]] -deps = ["ADTypes", "ArrayInterface", "BracketingNonlinearSolve", "CommonSolve", "ConcreteStructs", "DifferentiationInterface", "FastClosures", "FiniteDiff", "ForwardDiff", "LineSearch", "LinearAlgebra", "LinearSolve", "NonlinearSolveBase", "NonlinearSolveFirstOrder", "NonlinearSolveQuasiNewton", "NonlinearSolveSpectralMethods", "PrecompileTools", "Preferences", "Reexport", "SciMLBase", "SciMLLogging", "Setfield", "SimpleNonlinearSolve", "StaticArraysCore", "SymbolicIndexingInterface"] -git-tree-sha1 = "e88921859836899abe94d08ea0fd42137067280e" +deps = ["ADTypes", "ArrayInterface", "BracketingNonlinearSolve", "CommonSolve", "ConcreteStructs", "DifferentiationInterface", "FastClosures", "FiniteDiff", "ForwardDiff", "LineSearch", "LinearAlgebra", "LinearSolve", "NonlinearSolveBase", "NonlinearSolveFirstOrder", "NonlinearSolveQuasiNewton", "NonlinearSolveSpectralMethods", "PrecompileTools", "Preferences", "Reexport", "SciMLBase", "Setfield", "SimpleNonlinearSolve", "StaticArraysCore", "SymbolicIndexingInterface"] +git-tree-sha1 = "997abb773470b8c0bc6f85e3bfe86ff437983121" uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" -version = "4.17.1" +version = "4.20.1" [deps.NonlinearSolve.extensions] NonlinearSolveFastLevenbergMarquardtExt = "FastLevenbergMarquardt" @@ -694,9 +741,9 @@ version = "4.17.1" [[deps.NonlinearSolveBase]] deps = ["ADTypes", "Adapt", "ArrayInterface", "CommonSolve", "Compat", "ConcreteStructs", "DifferentiationInterface", "EnzymeCore", "FastClosures", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "LogExpFunctions", "Markdown", "MaybeInplace", "PreallocationTools", "PrecompileTools", "Preferences", "Printf", "RecursiveArrayTools", "SciMLBase", "SciMLJacobianOperators", "SciMLLogging", "SciMLOperators", "SciMLStructures", "Setfield", "StaticArraysCore", "SymbolicIndexingInterface", "TimerOutputs"] -git-tree-sha1 = "a19a5df29ef2b197499fc631fa1a59385ae15262" +git-tree-sha1 = "ed3b90b4c6265192f6dc5d7297d32a6766f74c2e" uuid = "be0214bd-f91f-a760-ac4e-3421ce2b2da0" -version = "2.25.0" +version = "2.31.3" [deps.NonlinearSolveBase.extensions] NonlinearSolveBaseBandedMatricesExt = "BandedMatrices" @@ -726,15 +773,15 @@ version = "2.25.0" [[deps.NonlinearSolveFirstOrder]] deps = ["ADTypes", "ArrayInterface", "CommonSolve", "ConcreteStructs", "FiniteDiff", "ForwardDiff", "LineSearch", "LinearAlgebra", "LinearSolve", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase", "SciMLJacobianOperators", "Setfield", "StaticArraysCore"] -git-tree-sha1 = "ce68820a4f421fb5bee7ec4dcf875aff33886bfb" +git-tree-sha1 = "2ec3c6ce945831db0ec689df143ea1190db75be9" uuid = "5959db7a-ea39-4486-b5fe-2dd0bf03d60d" -version = "2.1.1" +version = "2.1.2" [[deps.NonlinearSolveQuasiNewton]] deps = ["ArrayInterface", "CommonSolve", "ConcreteStructs", "LinearAlgebra", "LinearSolve", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase", "SciMLOperators", "StaticArraysCore"] -git-tree-sha1 = "538432ca1aea8bf63db02929bf870501f8a7c64c" +git-tree-sha1 = "06f9454f0dc432502c465d87dbc20fc64e2192ea" uuid = "9a2c21bd-3a47-402d-9113-8faf9a0ee114" -version = "1.13.1" +version = "1.13.2" weakdeps = ["ForwardDiff"] [deps.NonlinearSolveQuasiNewton.extensions] @@ -742,9 +789,9 @@ weakdeps = ["ForwardDiff"] [[deps.NonlinearSolveSpectralMethods]] deps = ["CommonSolve", "ConcreteStructs", "LineSearch", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "a3781e12becdf0ce5520bd97ec617e879bf4e9f2" +git-tree-sha1 = "ba7d164f81482d09a03ea7e8c59ef313618e661e" uuid = "26075421-4e9a-44e1-8bd1-420ed7ad02b2" -version = "1.7.1" +version = "1.7.2" weakdeps = ["ForwardDiff"] [deps.NonlinearSolveSpectralMethods.extensions] @@ -776,9 +823,9 @@ uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" version = "0.5.6+0" [[deps.OrderedCollections]] -git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +git-tree-sha1 = "94ba93778373a53bfd5a0caaf7d809c445292ff4" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.8.1" +version = "1.8.2" [[deps.Parameters]] deps = ["OrderedCollections", "UnPack"] @@ -799,9 +846,9 @@ version = "1.11.0" [[deps.PreallocationTools]] deps = ["Adapt", "ArrayInterface", "PrecompileTools"] -git-tree-sha1 = "e16b73bf892c55d16d53c9c0dbd0fb31cb7e25da" +git-tree-sha1 = "0c319df479a33799d3b7566fbf14498e4e38a6f3" uuid = "d236fae5-4411-538c-8e31-a6e3d9e00b46" -version = "1.2.0" +version = "1.2.1" [deps.PreallocationTools.extensions] PreallocationToolsForwardDiffExt = "ForwardDiff" @@ -830,6 +877,16 @@ deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" version = "1.11.0" +[[deps.PureKLU]] +deps = ["LinearAlgebra", "MuladdMacro", "PrecompileTools", "SparseArrays"] +git-tree-sha1 = "7ff9a12af707ff8b8fc54e5e10b732af1019f6f4" +uuid = "0c0d3e7f-3a8b-4f7e-b6f1-9a4d2e7c1f01" +version = "1.1.0" +weakdeps = ["ForwardDiff"] + + [deps.PureKLU.extensions] + PureKLUForwardDiffExt = "ForwardDiff" + [[deps.Random]] deps = ["SHA"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" @@ -853,9 +910,9 @@ version = "1.3.4" [[deps.RecursiveArrayTools]] deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "LinearAlgebra", "PrecompileTools", "RecipesBase", "StaticArraysCore", "SymbolicIndexingInterface"] -git-tree-sha1 = "79a5a1a5b6294c54602d18a59026ec0b07471054" +git-tree-sha1 = "a0aa35f847b21c7884371ec60913632cc1b68495" uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "4.2.0" +version = "4.3.2" [deps.RecursiveArrayTools.extensions] RecursiveArrayToolsCUDAExt = "CUDA" @@ -904,9 +961,9 @@ version = "1.3.1" [[deps.RuntimeGeneratedFunctions]] deps = ["ExprTools", "SHA", "Serialization"] -git-tree-sha1 = "cfcdc949c4660544ab0fdeed169561cb22f835f4" +git-tree-sha1 = "bd9d6c153d0c8a120b504bfb2f3be42308cc857a" uuid = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47" -version = "0.5.18" +version = "0.5.21" [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" @@ -914,9 +971,9 @@ version = "0.7.0" [[deps.SciMLBase]] deps = ["ADTypes", "Accessors", "Adapt", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PreallocationTools", "PrecompileTools", "Preferences", "Printf", "Random", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLLogging", "SciMLOperators", "SciMLPublic", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface"] -git-tree-sha1 = "4fdad3606c60fbbd52424737c31ec4141672c809" +git-tree-sha1 = "f3e7cd82d057fdeacf9c12292ea72481c05a57c2" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "3.3.0" +version = "3.30.0" [deps.SciMLBase.extensions] SciMLBaseChainRulesCoreExt = "ChainRulesCore" @@ -933,6 +990,7 @@ version = "3.3.0" SciMLBasePythonCallExt = "PythonCall" SciMLBaseRCallExt = "RCall" SciMLBaseReverseDiffExt = "ReverseDiff" + SciMLBaseStaticArraysExt = "StaticArrays" SciMLBaseTrackerExt = "Tracker" SciMLBaseZygoteExt = ["Zygote", "ChainRulesCore"] @@ -952,20 +1010,21 @@ version = "3.3.0" PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" RCall = "6f49c342-dc21-5d91-9882-a32aef131414" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.SciMLJacobianOperators]] deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "ConstructionBase", "DifferentiationInterface", "FastClosures", "LinearAlgebra", "SciMLBase", "SciMLOperators"] -git-tree-sha1 = "7156a5b51cba1bea33a82a036939ead4131f92bc" +git-tree-sha1 = "fcdbc0214fd43dcb9201bddda77bc4cb2ddf5da7" uuid = "19f34311-ddf3-4b8b-af20-060888a46c0e" -version = "0.1.13" +version = "0.1.14" [[deps.SciMLLogging]] deps = ["Logging", "LoggingExtras", "Preferences"] -git-tree-sha1 = "0161be062570af4042cf6f69e3d5d0b0555b6927" +git-tree-sha1 = "032fad418d14f5b9bad9db7f97db23514886dabc" uuid = "a6db7da4-7206-11f0-1eab-35f2a5dbe1d1" -version = "1.9.1" +version = "2.0.1" [deps.SciMLLogging.extensions] SciMLLoggingTracyExt = "Tracy" @@ -974,26 +1033,31 @@ version = "1.9.1" Tracy = "e689c965-62c8-4b79-b2c5-8359227902fd" [[deps.SciMLOperators]] -deps = ["Accessors", "ArrayInterface", "DocStringExtensions", "LinearAlgebra"] -git-tree-sha1 = "234869cf9fee9258a95464b7a7065cc7be84db00" +deps = ["Accessors", "Adapt", "ArrayInterface", "DocStringExtensions", "LinearAlgebra"] +git-tree-sha1 = "e6d0a9836575d20218770fc38784e5f669c58b1b" uuid = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" -version = "1.16.0" -weakdeps = ["SparseArrays", "StaticArraysCore"] +version = "1.22.1" [deps.SciMLOperators.extensions] + SciMLOperatorsLoopVectorizationExt = "LoopVectorization" SciMLOperatorsSparseArraysExt = "SparseArrays" SciMLOperatorsStaticArraysCoreExt = "StaticArraysCore" + [deps.SciMLOperators.weakdeps] + LoopVectorization = "bdcacae8-1622-11e9-2a5c-532679323890" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + [[deps.SciMLPublic]] -git-tree-sha1 = "0ba076dbdce87ba230fff48ca9bca62e1f345c9b" +git-tree-sha1 = "2b1b64add566435a768abdb3b053cac17d19ff3c" uuid = "431bcebd-1456-4ced-9d72-93c2757fff0b" -version = "1.0.1" +version = "1.2.1" [[deps.SciMLStructures]] deps = ["ArrayInterface", "PrecompileTools"] -git-tree-sha1 = "607f6867d0b0553e98fc7f725c9f9f13b4d01a32" +git-tree-sha1 = "1419128e9816e2876f7c4e93a519683b6d1d211e" uuid = "53ae85a6-f571-4167-b2af-e1d143709226" -version = "1.10.0" +version = "1.10.1" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" @@ -1012,9 +1076,9 @@ version = "1.11.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 = "d688de789b7e643326caf9a1051376dadbcd8873" +git-tree-sha1 = "72413286ef77ccacac383c5578641b99100eabd9" uuid = "727e6d20-b764-4bd8-a329-72de5adea6c7" -version = "2.11.1" +version = "2.12.1" [deps.SimpleNonlinearSolve.extensions] SimpleNonlinearSolveChainRulesCoreExt = "ChainRulesCore" @@ -1035,11 +1099,21 @@ deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" version = "1.11.0" +[[deps.SparseColumnPivotedQR]] +deps = ["LinearAlgebra", "PrecompileTools", "SparseArrays"] +git-tree-sha1 = "e408da3a280ab9033531cad1ebccbb54c81ea9c3" +uuid = "a57abbd0-fea5-4d57-96be-5e525945e8e4" +version = "2.1.2" +weakdeps = ["AMD"] + + [deps.SparseColumnPivotedQR.extensions] + SparseColumnPivotedQRAMDExt = "AMD" + [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "2700b235561b0335d5bef7097a111dc513b8655e" +git-tree-sha1 = "6547cbdd8ce32efba0d21c5a40fa96d1a3548f9f" uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.7.2" +version = "2.8.0" weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] @@ -1089,9 +1163,9 @@ version = "7.7.0+0" [[deps.SymbolicIndexingInterface]] deps = ["Accessors", "ArrayInterface", "RuntimeGeneratedFunctions", "StaticArraysCore"] -git-tree-sha1 = "94c58884e013efff548002e8dc2fdd1cb74dfce5" +git-tree-sha1 = "d4751bc16b120dc617719f7901a3b4e69c85b7bf" uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5" -version = "0.3.46" +version = "0.3.49" [deps.SymbolicIndexingInterface.extensions] SymbolicIndexingInterfacePrettyTablesExt = "PrettyTables" @@ -1165,6 +1239,12 @@ git-tree-sha1 = "a1c0c7585346251353cddede21f180b96388c403" uuid = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" version = "0.4.16" +[[deps.ZipFile]] +deps = ["Libdl", "Printf", "Zlib_jll"] +git-tree-sha1 = "f492b7fe1698e623024e873244f10d89c95c340a" +uuid = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea" +version = "0.10.1" + [[deps.Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" @@ -1182,9 +1262,9 @@ version = "1.59.0+0" [[deps.oneTBB_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "1350188a69a6e46f799d3945beef36435ed7262f" +git-tree-sha1 = "da8c1f6eee04831f14edcfa5dae611d309807e57" uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" -version = "2022.0.0+1" +version = "2022.3.0+0" [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] diff --git a/Manifest-v1.12.toml.default b/Manifest-v1.12.toml.default index 3d686d1c..b23b4e03 100644 --- a/Manifest-v1.12.toml.default +++ b/Manifest-v1.12.toml.default @@ -1,13 +1,13 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.12.6" +julia_version = "1.12.5" manifest_format = "2.0" -project_hash = "356626525ca9bb0f9ff17fd7cd0e99e15eac7f01" +project_hash = "30adb65bf2e48d1c0cd0a19da51c375ecdec07ec" [[deps.ADTypes]] -git-tree-sha1 = "bbc22a9a08a0ef6460041086d8a7b27940ed4ffd" +git-tree-sha1 = "d9aaef7c63466eee4de23b4d9dad03629df54bea" uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" -version = "1.22.0" +version = "1.22.1" weakdeps = ["ChainRulesCore", "ConstructionBase", "EnzymeCore"] [deps.ADTypes.extensions] @@ -15,6 +15,12 @@ weakdeps = ["ChainRulesCore", "ConstructionBase", "EnzymeCore"] ADTypesConstructionBaseExt = "ConstructionBase" ADTypesEnzymeCoreExt = "EnzymeCore" +[[deps.AMD]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse_jll"] +git-tree-sha1 = "45a1272e3f809d36431e57ab22703c6896b8908f" +uuid = "14f7f29c-3bd6-536c-9a0b-7339e30b5a3e" +version = "0.5.3" + [[deps.ANSIColoredPrinters]] git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9" @@ -38,9 +44,9 @@ version = "0.4.5" [[deps.Accessors]] deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] -git-tree-sha1 = "2eeb2c9bef11013efc6f8f97f32ee59b146b09fb" +git-tree-sha1 = "7063ad1083578215c7c4bf410368150abe8d5524" uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.44" +version = "0.1.45" [deps.Accessors.extensions] AxisKeysExt = "AxisKeys" @@ -62,9 +68,9 @@ version = "0.1.44" [[deps.Adapt]] deps = ["LinearAlgebra"] -git-tree-sha1 = "28e1637322d4019ed2577cbec9268fab9b7da117" +git-tree-sha1 = "daa72978cd7a624246e894a4f4f067706d4e17e2" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.6.0" +version = "4.7.0" weakdeps = ["SparseArrays", "StaticArrays"] [deps.Adapt.extensions] @@ -90,9 +96,9 @@ version = "0.4.2" [[deps.Aqua]] deps = ["Compat", "Pkg", "Test"] -git-tree-sha1 = "d57fd255a8932b6509baf43284c416fc44d0b903" +git-tree-sha1 = "4537cc8ed3fba5d88b844a18f7e9bb93f07d2742" uuid = "4c88cf16-eb10-579e-8560-4a9242c79595" -version = "0.8.14" +version = "0.8.16" [[deps.ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" @@ -100,9 +106,9 @@ version = "1.1.2" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "3d0cabd25fab32390e3bcb82cd67e700aebd9816" +git-tree-sha1 = "75757da5d9f771ef5909fc84f81d2f9d24127315" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.25.0" +version = "7.27.0" [deps.ArrayInterface.extensions] ArrayInterfaceAMDGPUExt = "AMDGPU" @@ -112,6 +118,7 @@ version = "7.25.0" ArrayInterfaceCUDSSExt = ["CUDSS", "CUDA"] ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceFillArraysExt = "FillArrays" ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" ArrayInterfaceMetalExt = "Metal" ArrayInterfaceReverseDiffExt = "ReverseDiff" @@ -127,6 +134,7 @@ version = "7.25.0" CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" @@ -139,10 +147,10 @@ uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" version = "1.11.0" [[deps.Automa]] -deps = ["PrecompileTools", "SIMD", "TranscodingStreams"] -git-tree-sha1 = "a8f503e8e1a5f583fbef15a8440c8c7e32185df2" +deps = ["PrecompileTools", "TranscodingStreams"] +git-tree-sha1 = "94eab0b3ccdcac361188cc661daf69d4433c1818" uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" -version = "1.1.0" +version = "1.2.0" [[deps.AxisAlgorithms]] deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] @@ -161,9 +169,9 @@ uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" version = "1.11.0" [[deps.BaseDirs]] -git-tree-sha1 = "bca794632b8a9bbe159d56bf9e31c422671b35e0" +git-tree-sha1 = "8c290a1b223deaeea9aea44b235d24546da8eb98" uuid = "18cc8868-cbac-4acf-b575-c8ff214dc66f" -version = "1.3.2" +version = "1.4.0" [[deps.BenchmarkTools]] deps = ["Compat", "JSON", "Logging", "PrecompileTools", "Printf", "Profile", "Statistics", "UUIDs"] @@ -172,15 +180,15 @@ uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" version = "1.8.0" [[deps.BitFlags]] -git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +git-tree-sha1 = "bbe1079eecf9c9fbb52765193ad2bae27ae09bc8" uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.9" +version = "0.1.10" [[deps.BracketingNonlinearSolve]] deps = ["CommonSolve", "ConcreteStructs", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "7ad7171d693ae5552ac43862e7f6b61df4471c2b" +git-tree-sha1 = "6e7c9b6ab9aa711009a49252e45a122212c1d869" uuid = "70df07ce-3d50-431d-a3e7-ca6ddb60ac1e" -version = "1.12.1" +version = "1.12.2" weakdeps = ["ChainRulesCore", "ForwardDiff"] [deps.BracketingNonlinearSolve.extensions] @@ -228,9 +236,9 @@ version = "1.1.1" [[deps.CairoMakie]] deps = ["CRC32c", "Cairo", "Cairo_jll", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"] -git-tree-sha1 = "fa072933899aae6dc61dde934febed8254e66c6a" +git-tree-sha1 = "80b2770813b42f80235ea57f4333de8ff3e1c342" uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -version = "0.15.9" +version = "0.15.12" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] @@ -248,6 +256,23 @@ weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] ChainRulesCoreSparseArraysExt = "SparseArrays" +[[deps.ChunkCodecCore]] +git-tree-sha1 = "1a3ad7e16a321667698a19e77362b35a1e94c544" +uuid = "0b6fb165-00bc-4d37-ab8b-79f91016dbe1" +version = "1.0.1" + +[[deps.ChunkCodecLibZlib]] +deps = ["ChunkCodecCore", "Zlib_jll"] +git-tree-sha1 = "cee8104904c53d39eb94fd06cbe60cb5acde7177" +uuid = "4c0bbee4-addc-4d73-81a0-b6caacae83c8" +version = "1.0.0" + +[[deps.ChunkCodecLibZstd]] +deps = ["ChunkCodecCore", "Zstd_jll"] +git-tree-sha1 = "34d9873079e4cb3d0c62926a225136824677073f" +uuid = "55437552-ac27-4d47-9aa3-63184e8fd398" +version = "1.0.0" + [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" @@ -299,13 +324,9 @@ uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.13.1" [[deps.CommonSolve]] -git-tree-sha1 = "dd91a10d8b8ae06e15706158eaf1a3e87e97b5f5" +git-tree-sha1 = "99ee296f88c12485402e37c2fd025f95ae097637" uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" -version = "0.2.7" -weakdeps = ["EnzymeCore"] - - [deps.CommonSolve.extensions] - CommonSolveEnzymeCoreExt = "EnzymeCore" +version = "0.2.9" [[deps.CommonSubexpressions]] deps = ["MacroTools"] @@ -339,14 +360,14 @@ weakdeps = ["InverseFunctions"] [[deps.ComputePipeline]] deps = ["Observables", "Preferences"] -git-tree-sha1 = "3b4be73db165146d8a88e47924f464e55ab053cd" +git-tree-sha1 = "7bc84b769c1d384315e7b5c4ac03a6c303e6cf35" uuid = "95dc2771-c249-4cd0-9c9f-1f3b4330693c" -version = "0.1.7" +version = "0.1.8" [[deps.ConcreteStructs]] -git-tree-sha1 = "ed1da4eac5ba9b3f6d061c90f3ca6ba190dd6595" +git-tree-sha1 = "1988532cb3b4525bb718b99ba07e433bbf0e600b" uuid = "2569d6c7-a4a2-43d3-a901-331e8e4be471" -version = "0.2.4" +version = "0.2.5" [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] @@ -354,12 +375,6 @@ git-tree-sha1 = "21d088c496ea22914fe80906eb5bce65755e5ec8" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" version = "2.5.1" -[[deps.CondaPkg]] -deps = ["JSON", "Markdown", "MicroMamba", "Pidfile", "Pkg", "Preferences", "Scratch", "TOML", "pixi_jll"] -git-tree-sha1 = "2b1afb8ae65a0758795b00adafb37f97e67ef0e9" -uuid = "992eb4ea-22a4-4c89-a5bb-47a3300528ab" -version = "0.2.36" - [[deps.ConstructionBase]] git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" @@ -376,18 +391,6 @@ git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" version = "0.6.3" -[[deps.ControlPlots]] -deps = ["JLD2", "LaTeXStrings", "Pkg", "Printf", "PythonPlot", "StaticArraysCore"] -git-tree-sha1 = "6cbab46fef00616339eb4c3e10faeb11b408a9cc" -uuid = "23c2ee80-7a9e-4350-b264-8e670f12517c" -version = "0.3.0" - - [deps.ControlPlots.extensions] - ControlPlotsExt = "ControlSystemsBase" - - [deps.ControlPlots.weakdeps] - ControlSystemsBase = "aaaaaaaa-a6ca-5380-bf3e-84a91bcd477e" - [[deps.CoreMath]] deps = ["CoreMath_jll"] git-tree-sha1 = "8c0480f92b1b1796239156a1b9b1bfb1b39499b4" @@ -418,9 +421,9 @@ version = "1.8.2" [[deps.DataStructures]] deps = ["OrderedCollections"] -git-tree-sha1 = "e86f4a2805f7f19bec5129bc9150c38208e5dc23" +git-tree-sha1 = "6fb53a69613a0b2b68a0d12671717d307ab8b24e" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.19.4" +version = "0.19.5" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -527,19 +530,21 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" version = "1.11.0" [[deps.Distributions]] -deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "e421c1938fafab0165b04dc1a9dbe2a26272952c" +deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "Roots", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "cd3c5ac74cd3923c8945c6a81518c46abd0e73a3" uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.125" +version = "0.25.129" [deps.Distributions.extensions] DistributionsChainRulesCoreExt = "ChainRulesCore" DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsSparseConnectivityTracerExt = "SparseConnectivityTracer" DistributionsTestExt = "Test" [deps.Distributions.weakdeps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.DocStringExtensions]] @@ -608,16 +613,11 @@ git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" version = "0.1.10" -[[deps.Extents]] -git-tree-sha1 = "b309b36a9e02fe7be71270dd8c0fd873625332b4" -uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" -version = "0.1.6" - [[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", "libva_jll", "libvorbis_jll", "x264_jll", "x265_jll"] -git-tree-sha1 = "cac41ca6b2d399adfc95e51240566f8a60a80806" +git-tree-sha1 = "7a58e45171b63ed4782f2d36fdee8713a469e6e0" uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "8.1.0+0" +version = "8.1.2+0" [[deps.FFTA]] deps = ["AbstractFFTs", "DocStringExtensions", "LinearAlgebra", "MuladdMacro", "Primes", "Random", "Reexport"] @@ -686,9 +686,9 @@ weakdeps = ["PDMats", "SparseArrays", "StaticArrays", "Statistics"] [[deps.FiniteDiff]] deps = ["ArrayInterface", "LinearAlgebra", "Setfield"] -git-tree-sha1 = "f7017a4f337f8df189fcce98e32b67a1298a2115" +git-tree-sha1 = "2e5742cda07276e1834281ada4cc71b6bfc87586" uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.31.0" +version = "2.31.1" [deps.FiniteDiff.extensions] FiniteDiffBandedMatricesExt = "BandedMatrices" @@ -703,10 +703,10 @@ version = "2.31.0" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" [[deps.FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +deps = ["Random", "Statistics"] +git-tree-sha1 = "59af96b98217c6ef4ae0dfe065ac7c20831d1a84" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.5" +version = "0.8.6" [[deps.Fontconfig_jll]] deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] @@ -721,9 +721,9 @@ version = "1.3.7" [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "cddeab6487248a39dae1a960fff0ac17b2a28888" +git-tree-sha1 = "2c5d0b0e12088cde2cf84afb2784415b1ea3dfee" uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "1.3.3" +version = "1.4.1" weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] @@ -760,9 +760,9 @@ version = "1.1.3" [[deps.FunctionWrappersWrappers]] deps = ["FunctionWrappers", "PrecompileTools", "TruncatedStacktraces"] -git-tree-sha1 = "b28fca87e487d18ba462317e4a95d7253ae51929" +git-tree-sha1 = "9760060160c6d7f642308eed67a40a1ffe3f028c" uuid = "77dc65aa-8811-40c2-897b-53d922fa7daf" -version = "1.9.1" +version = "1.9.3" [deps.FunctionWrappersWrappers.extensions] FunctionWrappersWrappersEnzymeExt = ["Enzyme", "EnzymeCore"] @@ -792,9 +792,9 @@ version = "3.4.1+1" [[deps.GLMakie]] deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] -git-tree-sha1 = "1e0d427d2c73eb5a7564394df2c9fec8b85e7805" +git-tree-sha1 = "4ab403982698430670bd5302bfe0bd303f9518b8" uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.13.9" +version = "0.13.12" [[deps.GPUArraysCore]] deps = ["Adapt"] @@ -803,16 +803,20 @@ uuid = "46192b85-c4d5-4398-a991-12ede77f4527" version = "0.2.0" [[deps.GeometryBasics]] -deps = ["EarCut_jll", "Extents", "IterTools", "LinearAlgebra", "PrecompileTools", "Random", "StaticArrays"] -git-tree-sha1 = "1f5a80f4ed9f5a4aada88fc2db456e637676414b" +deps = ["EarCut_jll", "LinearAlgebra", "PrecompileTools", "Random", "StaticArrays"] +git-tree-sha1 = "364685f5ffde25deb1bbcfd5bb278a5c6b7a9b37" uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" -version = "0.5.10" +version = "0.5.11" [deps.GeometryBasics.extensions] + ExtentsExt = "Extents" GeometryBasicsGeoInterfaceExt = "GeoInterface" + IntervalSetsExt = "IntervalSets" [deps.GeometryBasics.weakdeps] + Extents = "411431e0-e8b7-467b-b5e0-f676ba4f2910" GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" [[deps.GettextRuntime_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll"] @@ -858,9 +862,9 @@ version = "1.1.3" [[deps.Graphite2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "8a6dbda1fd736d60cc477d99f2e7a042acfa46e8" +git-tree-sha1 = "69ffb934a5c5b7e086a0b4fee3427db2556fba6e" uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" -version = "1.3.15+0" +version = "1.3.16+0" [[deps.GridLayoutBase]] deps = ["GeometryBasics", "InteractiveUtils", "Observables"] @@ -868,11 +872,6 @@ git-tree-sha1 = "93d5c27c8de51687a2c70ec0716e6e76f298416f" uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" version = "0.11.2" -[[deps.Grisu]] -git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" -uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" -version = "1.0.2" - [[deps.HTTP]] deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] git-tree-sha1 = "51059d23c8bb67911a2e6fd5130229113735fc7e" @@ -979,9 +978,9 @@ version = "1.11.0" [[deps.Interpolations]] deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] -git-tree-sha1 = "65d505fa4c0d7072990d659ef3fc086eb6da8208" +git-tree-sha1 = "48922d06068130f87e43edef52382e6a94305ae6" uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.16.2" +version = "0.16.3" weakdeps = ["ForwardDiff", "Unitful"] [deps.Interpolations.extensions] @@ -1062,10 +1061,10 @@ uuid = "82899510-4779-5014-852e-03e436cf321d" version = "1.0.0" [[deps.JLD2]] -deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues", "TranscodingStreams"] -git-tree-sha1 = "d97791feefda45729613fafeccc4fbef3f539151" +deps = ["ChunkCodecLibZlib", "ChunkCodecLibZstd", "FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues"] +git-tree-sha1 = "941f87a0ae1b14d1ac2fa57245425b23a9d7a516" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.5.15" +version = "0.6.4" weakdeps = ["UnPack"] [deps.JLD2.extensions] @@ -1079,9 +1078,9 @@ version = "1.8.0" [[deps.JSON]] deps = ["Dates", "Logging", "Parsers", "PrecompileTools", "StructUtils", "UUIDs", "Unicode"] -git-tree-sha1 = "f76f7560267b840e492180f9899b472f30b88450" +git-tree-sha1 = "c89d196f5ffb64bfbf80985b699ea913b0d2c211" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "1.6.0" +version = "1.6.1" [deps.JSON.extensions] JSONArrowExt = ["ArrowTypes"] @@ -1114,9 +1113,9 @@ version = "0.6.12" [[deps.Krylov]] deps = ["LinearAlgebra", "Printf", "SparseArrays"] -git-tree-sha1 = "c4d19f51afc7ba2afbe32031b8f2d21b11c9e26e" +git-tree-sha1 = "fc2e5bc665dfa1be33fac60b5762d462bccfae7b" uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" -version = "0.10.6" +version = "0.10.8" [[deps.LAME_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1223,9 +1222,9 @@ version = "2.42.0+0" [[deps.LineSearch]] deps = ["ADTypes", "CommonSolve", "ConcreteStructs", "FastClosures", "LinearAlgebra", "MaybeInplace", "PrecompileTools", "SciMLBase", "SciMLJacobianOperators", "StaticArraysCore"] -git-tree-sha1 = "fd58a77c92e7c8f1db25c9839127d52943a49349" +git-tree-sha1 = "a7553de02835e996f80bf895a291ab981ba1f796" uuid = "87fe0de2-c867-4266-b59a-2f0a94fc965b" -version = "0.1.9" +version = "0.1.10" [deps.LineSearch.extensions] LineSearchLineSearchesExt = "LineSearches" @@ -1239,10 +1238,10 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" version = "1.12.0" [[deps.LinearSolve]] -deps = ["ArrayInterface", "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 = "ce45dd7e3a54842037b52c290915a01aeecce026" +deps = ["AMD", "ArrayInterface", "ConcreteStructs", "DocStringExtensions", "EnumX", "GPUArraysCore", "InteractiveUtils", "Krylov", "Libdl", "LinearAlgebra", "MKL_jll", "Markdown", "OpenBLAS_jll", "PrecompileTools", "Preferences", "PureKLU", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLLogging", "SciMLOperators", "Setfield", "SparseArrays", "SparseColumnPivotedQR", "StaticArraysCore"] +git-tree-sha1 = "ec49ed72f6024be2f9833fe630fbd72f6048f8ad" uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -version = "3.82.0" +version = "3.87.0" [deps.LinearSolve.extensions] LinearSolveAMDGPUExt = "AMDGPU" @@ -1261,20 +1260,26 @@ version = "3.82.0" LinearSolveFastLapackInterfaceExt = "FastLapackInterface" LinearSolveForwardDiffExt = "ForwardDiff" LinearSolveGinkgoExt = ["Ginkgo", "SparseArrays"] + LinearSolveHSLExt = ["HSL", "SparseArrays"] LinearSolveHYPREExt = "HYPRE" LinearSolveIterativeSolversExt = "IterativeSolvers" LinearSolveKernelAbstractionsExt = "KernelAbstractions" LinearSolveKrylovKitExt = "KrylovKit" + LinearSolveMUMPSExt = ["MUMPS", "SparseArrays"] LinearSolveMetalExt = "Metal" LinearSolveMooncakeExt = "Mooncake" LinearSolvePETScExt = ["PETSc", "SparseArrays", "SparseMatricesCSR"] LinearSolvePETScMPIExt = ["PETSc", "PartitionedArrays", "SparseArrays", "SparseMatricesCSR"] LinearSolveParUExt = ["ParU_jll", "SparseArrays"] LinearSolvePardisoExt = ["Pardiso", "SparseArrays"] + LinearSolvePartitionedSolversExt = ["PartitionedArrays", "PartitionedSolvers"] + LinearSolvePureUMFPACKExt = ["PureUMFPACK", "SparseArrays"] LinearSolveRecursiveFactorizationExt = "RecursiveFactorization" LinearSolveSTRUMPACKExt = ["SparseArrays", "STRUMPACK_jll"] LinearSolveSparseArraysExt = "SparseArrays" LinearSolveSparspakExt = ["SparseArrays", "Sparspak"] + LinearSolveSpecializingFactorizationsExt = "SpecializingFactorizations" + LinearSolveSuperLUDISTExt = ["SparseArrays", "SuperLUDIST"] [deps.LinearSolve.weakdeps] AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" @@ -1291,22 +1296,27 @@ version = "3.82.0" FastLapackInterface = "29a986be-02c6-4525-aec4-84b980013641" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Ginkgo = "4c8bd3c9-ead9-4b5e-a625-08f1338ba0ec" + HSL = "34c5aeac-e683-54a6-a0e9-6e0fdc586c50" HYPRE = "b5ffcf37-a2bd-41ab-a3da-4bd9bc8ad771" IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" LAPACK_jll = "51474c39-65e3-53ba-86ba-03b1b862ec14" + MUMPS = "55d2b088-9f4e-11e9-26c0-150b02ea6a46" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" PETSc = "ace2c81b-2b5f-4b1e-a30d-d662738edfe0" ParU_jll = "9e0b026c-e8ce-559c-a2c4-6a3d5c955bc9" Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2" PartitionedArrays = "5a9dfac6-5c52-46f7-8278-5e2210713be9" + PartitionedSolvers = "11b65f7f-80ac-401b-9ef2-3db765482d62" + PureUMFPACK = "b7e1f0a2-3c4d-4e5f-9a0b-1c2d3e4f5a6b" RecursiveFactorization = "f2c3362d-daeb-58d1-803e-2bc74f2840b4" STRUMPACK_jll = "86fbd0b9-476f-557c-b766-62c724b42d8c" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" SparseMatricesCSR = "a0a7dd2c-ebf4-11e9-1f05-cf50bc540ca1" Sparspak = "e56a9233-b9d6-4f03-8d0f-1825330902ac" + SpecializingFactorizations = "fa08b7a1-13d3-4faf-875d-5cbc1520e3f3" + SuperLUDIST = "4cd002a6-0da4-410d-a012-232df062f478" blis_jll = "6136c539-28a5-5bf0-87cc-b183200dce32" cuSOLVER = "887afef0-6a32-4de5-add4-7827692ba8fc" @@ -1318,9 +1328,9 @@ version = "1.5.0" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +git-tree-sha1 = "bba2d9aa057d8f126415de240573e86a8f39d2a1" uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.29" +version = "1.0.1" [deps.LogExpFunctions.extensions] LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" @@ -1359,10 +1369,10 @@ uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.5.16" [[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "ComputePipeline", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageBase", "ImageIO", "InteractiveUtils", "Interpolations", "IntervalSets", "InverseFunctions", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "PNGFiles", "Packing", "Pkg", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] -git-tree-sha1 = "68af66ec16af8b152309310251ecb4fbfe39869f" +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "ComputePipeline", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageBase", "ImageIO", "InteractiveUtils", "Interpolations", "IntervalSets", "InverseFunctions", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "PNGFiles", "Packing", "Pkg", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] +git-tree-sha1 = "efe001e1ee81b8eee0fe7da5a4328fcbbfd6b3aa" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.24.9" +version = "0.24.12" [deps.Makie.extensions] MakieDynamicQuantitiesExt = "DynamicQuantities" @@ -1370,6 +1380,18 @@ version = "0.24.9" [deps.Makie.weakdeps] DynamicQuantities = "06fc5a27-2a28-4c7c-a15d-362465fb6821" +[[deps.MakieControlPlots]] +deps = ["CairoMakie", "GLMakie", "GridLayoutBase", "JLD2", "LaTeXStrings", "Makie", "PrecompileTools", "Printf", "StaticArraysCore"] +git-tree-sha1 = "4d56ef86cbdd81c443021ec63d80900a1c96f87a" +uuid = "6d616b69-6563-4f6e-8472-6f6c706c6f74" +version = "0.1.5" + + [deps.MakieControlPlots.extensions] + MakieControlPlotsControlSystemsBaseExt = "ControlSystemsBase" + + [deps.MakieControlPlots.weakdeps] + ControlSystemsBase = "aaaaaaaa-a6ca-5380-bf3e-84a91bcd477e" + [[deps.MappedArrays]] git-tree-sha1 = "0ee4497a4e80dbd29c058fcee6493f5219556f40" uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" @@ -1394,9 +1416,9 @@ version = "0.6.9" [[deps.MaybeInplace]] deps = ["ArrayInterface", "LinearAlgebra", "MacroTools"] -git-tree-sha1 = "54e2fdc38130c05b42be423e90da3bade29b74bd" +git-tree-sha1 = "bf287c2abdd365d73c9ee86b262c6d8af0d6e2a1" uuid = "bb5d69b7-63fc-4a16-80bd-7e42200c7bdb" -version = "0.1.4" +version = "0.1.5" weakdeps = ["SparseArrays"] [deps.MaybeInplace.extensions] @@ -1425,12 +1447,6 @@ git-tree-sha1 = "c009236e222df68e554c7ce5c720e4a33cc0c23f" uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" version = "0.5.3" -[[deps.MicroMamba]] -deps = ["Pkg", "Scratch", "micromamba_jll"] -git-tree-sha1 = "535656ce55266bfed0575cd051acc4f36dc869a0" -uuid = "0b3b1443-0f03-428d-bdfb-f27f9c1191ea" -version = "0.1.15" - [[deps.Missings]] deps = ["DataAPI"] git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" @@ -1458,15 +1474,22 @@ uuid = "14a3606d-f60d-562e-9121-12d972cd8159" version = "2025.11.4" [[deps.MuladdMacro]] -git-tree-sha1 = "cac9cc5499c25554cba55cd3c30543cff5ca4fab" +deps = ["PrecompileTools"] +git-tree-sha1 = "e8dcbeef032ba2f9051a44ac22b4e54e3a1a0099" uuid = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" -version = "0.2.4" +version = "0.2.6" + +[[deps.NPZ]] +deps = ["FileIO", "ZipFile"] +git-tree-sha1 = "60a8e272fe0c5079363b28b0953831e2dd7b7e6f" +uuid = "15e1cf62-19b3-5cfa-8e77-841668bca605" +version = "0.4.3" [[deps.NaNMath]] deps = ["OpenLibm_jll"] -git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +git-tree-sha1 = "dbd2e8cd2c1c27f0b584f6661b4309609c5a685e" uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "1.1.3" +version = "1.1.4" [[deps.Netpbm]] deps = ["FileIO", "ImageCore", "ImageMetadata"] @@ -1480,9 +1503,9 @@ 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", "Setfield", "SimpleNonlinearSolve", "StaticArraysCore", "SymbolicIndexingInterface"] -git-tree-sha1 = "a6c5719bbb42985c72f4cacbfa49e86bab850d66" +git-tree-sha1 = "997abb773470b8c0bc6f85e3bfe86ff437983121" uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" -version = "4.19.1" +version = "4.20.1" [deps.NonlinearSolve.extensions] NonlinearSolveFastLevenbergMarquardtExt = "FastLevenbergMarquardt" @@ -1513,9 +1536,9 @@ version = "4.19.1" [[deps.NonlinearSolveBase]] deps = ["ADTypes", "Adapt", "ArrayInterface", "CommonSolve", "Compat", "ConcreteStructs", "DifferentiationInterface", "EnzymeCore", "FastClosures", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "LogExpFunctions", "Markdown", "MaybeInplace", "PreallocationTools", "PrecompileTools", "Preferences", "Printf", "RecursiveArrayTools", "SciMLBase", "SciMLJacobianOperators", "SciMLLogging", "SciMLOperators", "SciMLStructures", "Setfield", "StaticArraysCore", "SymbolicIndexingInterface", "TimerOutputs"] -git-tree-sha1 = "e518a141677e451667e1527312b18d65d261342e" +git-tree-sha1 = "ed3b90b4c6265192f6dc5d7297d32a6766f74c2e" uuid = "be0214bd-f91f-a760-ac4e-3421ce2b2da0" -version = "2.29.0" +version = "2.31.3" [deps.NonlinearSolveBase.extensions] NonlinearSolveBaseBandedMatricesExt = "BandedMatrices" @@ -1545,15 +1568,15 @@ version = "2.29.0" [[deps.NonlinearSolveFirstOrder]] deps = ["ADTypes", "ArrayInterface", "CommonSolve", "ConcreteStructs", "FiniteDiff", "ForwardDiff", "LineSearch", "LinearAlgebra", "LinearSolve", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase", "SciMLJacobianOperators", "Setfield", "StaticArraysCore"] -git-tree-sha1 = "ce68820a4f421fb5bee7ec4dcf875aff33886bfb" +git-tree-sha1 = "2ec3c6ce945831db0ec689df143ea1190db75be9" uuid = "5959db7a-ea39-4486-b5fe-2dd0bf03d60d" -version = "2.1.1" +version = "2.1.2" [[deps.NonlinearSolveQuasiNewton]] deps = ["ArrayInterface", "CommonSolve", "ConcreteStructs", "LinearAlgebra", "LinearSolve", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase", "SciMLOperators", "StaticArraysCore"] -git-tree-sha1 = "538432ca1aea8bf63db02929bf870501f8a7c64c" +git-tree-sha1 = "06f9454f0dc432502c465d87dbc20fc64e2192ea" uuid = "9a2c21bd-3a47-402d-9113-8faf9a0ee114" -version = "1.13.1" +version = "1.13.2" weakdeps = ["ForwardDiff"] [deps.NonlinearSolveQuasiNewton.extensions] @@ -1561,9 +1584,9 @@ weakdeps = ["ForwardDiff"] [[deps.NonlinearSolveSpectralMethods]] deps = ["CommonSolve", "ConcreteStructs", "LineSearch", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "a3781e12becdf0ce5520bd97ec617e879bf4e9f2" +git-tree-sha1 = "ba7d164f81482d09a03ea7e8c59ef313618e661e" uuid = "26075421-4e9a-44e1-8bd1-420ed7ad02b2" -version = "1.7.1" +version = "1.7.2" weakdeps = ["ForwardDiff"] [deps.NonlinearSolveSpectralMethods.extensions] @@ -1608,9 +1631,9 @@ version = "0.3.3" [[deps.OpenEXR_jll]] deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "9ac7c730c53b3b5d9a73fb900ac4b4fc263774db" +git-tree-sha1 = "0d621a4beb5e48d195f907c3c5b0bea285d9ff9d" uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" -version = "3.4.9+0" +version = "3.4.13+0" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] @@ -1647,9 +1670,9 @@ uuid = "91d4177d-7536-5919-b921-800302f37372" version = "1.6.1+0" [[deps.OrderedCollections]] -git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +git-tree-sha1 = "94ba93778373a53bfd5a0caaf7d809c445292ff4" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.8.1" +version = "1.8.2" [[deps.PCRE2_jll]] deps = ["Artifacts", "Libdl"] @@ -1658,9 +1681,9 @@ version = "10.44.0+1" [[deps.PDMats]] deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "e4cff168707d441cd6bf3ff7e4832bdf34278e4a" +git-tree-sha1 = "26766d4b5f1a410c218a19b85a672c6edb693c65" uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.37" +version = "0.11.40" weakdeps = ["StatsBase"] [deps.PDMats.extensions] @@ -1698,15 +1721,9 @@ version = "0.12.3" [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "5d5e0a78e971354b1c7bff0655d11fdc1b0e12c8" +git-tree-sha1 = "32a4e09c5f29402573d673901778a0e03b0807b9" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.8.4" - -[[deps.Pidfile]] -deps = ["FileWatching", "Test"] -git-tree-sha1 = "2d8aaf8ee10df53d0dfb9b8ee44ae7c04ced2b03" -uuid = "fa939f87-e72e-5be4-a000-7fc836dbe307" -version = "1.3.0" +version = "2.8.6" [[deps.Pixman_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] @@ -1748,9 +1765,9 @@ version = "1.4.3" [[deps.PreallocationTools]] deps = ["Adapt", "ArrayInterface", "PrecompileTools"] -git-tree-sha1 = "e16b73bf892c55d16d53c9c0dbd0fb31cb7e25da" +git-tree-sha1 = "0c319df479a33799d3b7566fbf14498e4e38a6f3" uuid = "d236fae5-4411-538c-8e31-a6e3d9e00b46" -version = "1.2.0" +version = "1.2.1" [deps.PreallocationTools.extensions] PreallocationToolsForwardDiffExt = "ForwardDiff" @@ -1813,25 +1830,15 @@ git-tree-sha1 = "4fbbafbc6251b883f4d2705356f3641f3652a7fe" uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" version = "1.4.0" -[[deps.PythonCall]] -deps = ["CondaPkg", "Dates", "Libdl", "MacroTools", "Markdown", "Preferences", "Serialization", "Tables", "UnsafePointers"] -git-tree-sha1 = "84e5ad9f90856963f4b17cfe12872598e731082c" -uuid = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" -version = "0.9.34" - - [deps.PythonCall.extensions] - CategoricalArraysExt = "CategoricalArrays" - PyCallExt = "PyCall" - - [deps.PythonCall.weakdeps] - CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597" - PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" +[[deps.PureKLU]] +deps = ["LinearAlgebra", "MuladdMacro", "PrecompileTools", "SparseArrays"] +git-tree-sha1 = "7ff9a12af707ff8b8fc54e5e10b732af1019f6f4" +uuid = "0c0d3e7f-3a8b-4f7e-b6f1-9a4d2e7c1f01" +version = "1.1.0" +weakdeps = ["ForwardDiff"] -[[deps.PythonPlot]] -deps = ["Colors", "CondaPkg", "LaTeXStrings", "PythonCall", "Sockets", "Test", "VersionParsing"] -git-tree-sha1 = "409884283434a04092ddf1d9594c22bc097d5d9a" -uuid = "274fc56d-3b97-40fa-a1cd-1b4a50311bf9" -version = "1.0.6" + [deps.PureKLU.extensions] + PureKLUForwardDiffExt = "ForwardDiff" [[deps.QOI]] deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] @@ -1884,9 +1891,9 @@ version = "1.3.4" [[deps.RecursiveArrayTools]] deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "LinearAlgebra", "PrecompileTools", "RecipesBase", "StaticArraysCore", "SymbolicIndexingInterface"] -git-tree-sha1 = "57b6fb3932fc8d1fc911f840d2c9de5fe3ba5008" +git-tree-sha1 = "a0aa35f847b21c7884371ec60913632cc1b68495" uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "4.3.0" +version = "4.3.2" [deps.RecursiveArrayTools.extensions] RecursiveArrayToolsCUDAExt = "CUDA" @@ -1957,6 +1964,28 @@ git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" version = "0.5.1+0" +[[deps.Roots]] +deps = ["Accessors", "CommonSolve", "Printf"] +git-tree-sha1 = "91cfb1cb4f6e27557cc2df798a31eff6089a41eb" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "3.0.0" + + [deps.Roots.extensions] + RootsChainRulesCoreExt = "ChainRulesCore" + RootsForwardDiffExt = "ForwardDiff" + RootsIntervalRootFindingExt = "IntervalRootFinding" + RootsSymPyExt = "SymPy" + RootsSymPyPythonCallExt = "SymPyPythonCall" + RootsUnitfulExt = "Unitful" + + [deps.Roots.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" + SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" + SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + [[deps.RoundingEmulator]] git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" @@ -1964,9 +1993,9 @@ version = "0.2.1" [[deps.RuntimeGeneratedFunctions]] deps = ["ExprTools", "SHA", "Serialization"] -git-tree-sha1 = "28154d426e557495aa75097861b18c11f2541ded" +git-tree-sha1 = "bd9d6c153d0c8a120b504bfb2f3be42308cc857a" uuid = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47" -version = "0.5.19" +version = "0.5.21" [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" @@ -1980,9 +2009,9 @@ version = "3.7.2" [[deps.SciMLBase]] deps = ["ADTypes", "Accessors", "Adapt", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PreallocationTools", "PrecompileTools", "Preferences", "Printf", "Random", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLLogging", "SciMLOperators", "SciMLPublic", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface"] -git-tree-sha1 = "8e680fb9e8b3fb7eb66bf4ead84a646ee4e9ef8b" +git-tree-sha1 = "f3e7cd82d057fdeacf9c12292ea72481c05a57c2" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "3.16.0" +version = "3.30.0" [deps.SciMLBase.extensions] SciMLBaseChainRulesCoreExt = "ChainRulesCore" @@ -2025,15 +2054,15 @@ version = "3.16.0" [[deps.SciMLJacobianOperators]] deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "ConstructionBase", "DifferentiationInterface", "FastClosures", "LinearAlgebra", "SciMLBase", "SciMLOperators"] -git-tree-sha1 = "7156a5b51cba1bea33a82a036939ead4131f92bc" +git-tree-sha1 = "fcdbc0214fd43dcb9201bddda77bc4cb2ddf5da7" uuid = "19f34311-ddf3-4b8b-af20-060888a46c0e" -version = "0.1.13" +version = "0.1.14" [[deps.SciMLLogging]] deps = ["Logging", "LoggingExtras", "Preferences"] -git-tree-sha1 = "3f98a53703f925cbd5aac5da4924f82ca34d09ab" +git-tree-sha1 = "032fad418d14f5b9bad9db7f97db23514886dabc" uuid = "a6db7da4-7206-11f0-1eab-35f2a5dbe1d1" -version = "2.0.0" +version = "2.0.1" [deps.SciMLLogging.extensions] SciMLLoggingTracyExt = "Tracy" @@ -2043,9 +2072,9 @@ version = "2.0.0" [[deps.SciMLOperators]] deps = ["Accessors", "Adapt", "ArrayInterface", "DocStringExtensions", "LinearAlgebra"] -git-tree-sha1 = "3b204078e8574b9de19cac90e0c87c811a87deac" +git-tree-sha1 = "e6d0a9836575d20218770fc38784e5f669c58b1b" uuid = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" -version = "1.22.0" +version = "1.22.1" [deps.SciMLOperators.extensions] SciMLOperatorsLoopVectorizationExt = "LoopVectorization" @@ -2058,15 +2087,15 @@ version = "1.22.0" StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" [[deps.SciMLPublic]] -git-tree-sha1 = "0ba076dbdce87ba230fff48ca9bca62e1f345c9b" +git-tree-sha1 = "2b1b64add566435a768abdb3b053cac17d19ff3c" uuid = "431bcebd-1456-4ced-9d72-93c2757fff0b" -version = "1.0.1" +version = "1.2.1" [[deps.SciMLStructures]] deps = ["ArrayInterface", "PrecompileTools"] -git-tree-sha1 = "607f6867d0b0553e98fc7f725c9f9f13b4d01a32" +git-tree-sha1 = "1419128e9816e2876f7c4e93a519683b6d1d211e" uuid = "53ae85a6-f571-4167-b2af-e1d143709226" -version = "1.10.0" +version = "1.10.1" [[deps.ScopedValues]] deps = ["HashArrayMappedTries", "Logging"] @@ -2107,12 +2136,6 @@ deps = ["Distributed", "Mmap", "Random", "Serialization"] uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" version = "1.11.0" -[[deps.Showoff]] -deps = ["Dates", "Grisu"] -git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" -uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" -version = "1.0.3" - [[deps.SignedDistanceFields]] deps = ["Statistics"] git-tree-sha1 = "3949ad92e1c9d2ff0cd4a1317d5ecbba682f4b92" @@ -2126,9 +2149,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 = "d688de789b7e643326caf9a1051376dadbcd8873" +git-tree-sha1 = "72413286ef77ccacac383c5578641b99100eabd9" uuid = "727e6d20-b764-4bd8-a329-72de5adea6c7" -version = "2.11.1" +version = "2.12.1" [deps.SimpleNonlinearSolve.extensions] SimpleNonlinearSolveChainRulesCoreExt = "ChainRulesCore" @@ -2158,15 +2181,25 @@ version = "1.11.0" [[deps.SortingAlgorithms]] deps = ["DataStructures"] -git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" +git-tree-sha1 = "13cd91cc9be159e3f4d95b857fa2aa383b53772a" uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.2" +version = "1.2.3" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" version = "1.12.0" +[[deps.SparseColumnPivotedQR]] +deps = ["LinearAlgebra", "PrecompileTools", "SparseArrays"] +git-tree-sha1 = "e408da3a280ab9033531cad1ebccbb54c81ea9c3" +uuid = "a57abbd0-fea5-4d57-96be-5e525945e8e4" +version = "2.1.2" +weakdeps = ["AMD"] + + [deps.SparseColumnPivotedQR.extensions] + SparseColumnPivotedQRAMDExt = "AMD" + [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] git-tree-sha1 = "6547cbdd8ce32efba0d21c5a40fa96d1a3548f9f" @@ -2223,15 +2256,15 @@ version = "1.8.0" [[deps.StatsBase]] deps = ["AliasTables", "DataAPI", "DataStructures", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "c6f18e5a52a176a383f6f6c635e0f81feed1d6d4" +git-tree-sha1 = "e4d7a1a0edc20af42689ea6f4f3587a2175d50ee" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.34.11" +version = "0.34.12" [[deps.StatsFuns]] deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] -git-tree-sha1 = "91f091a8716a6bb38417a6e6f274602a19aaa685" +git-tree-sha1 = "770240df9a3b8888065046948f7a09b4e0f997d5" uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "1.5.2" +version = "2.2.0" weakdeps = ["ChainRulesCore", "InverseFunctions"] [deps.StatsFuns.extensions] @@ -2307,9 +2340,9 @@ version = "7.8.3+2" [[deps.SymbolicIndexingInterface]] deps = ["Accessors", "ArrayInterface", "RuntimeGeneratedFunctions", "StaticArraysCore"] -git-tree-sha1 = "64b15330b9e3c91a86bcac92f369c58e382981c6" +git-tree-sha1 = "d4751bc16b120dc617719f7901a3b4e69c85b7bf" uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5" -version = "0.3.48" +version = "0.3.49" weakdeps = ["PrettyTables"] [deps.SymbolicIndexingInterface.extensions] @@ -2328,9 +2361,9 @@ version = "1.0.1" [[deps.Tables]] deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "f2c1efbc8f3a609aadf318094f8fc5204bdaf344" +git-tree-sha1 = "0f38a06c83f0007bbab3cf911262841c9a0f07e0" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.12.1" +version = "1.13.0" [[deps.Tar]] deps = ["ArgTools", "SHA"] @@ -2436,26 +2469,15 @@ version = "1.28.0" NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" -[[deps.UnsafePointers]] -git-tree-sha1 = "c81331b3b2e60a982be57c046ec91f599ede674a" -uuid = "e17b2a0c-0bdf-430a-bd0c-3a23cae4ff39" -version = "1.0.0" - -[[deps.VersionParsing]] -git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" -uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" -version = "1.3.0" - [[deps.VortexStepMethod]] -deps = ["Colors", "DefaultApplication", "DelimitedFiles", "DifferentiationInterface", "FiniteDiff", "ForwardDiff", "Interpolations", "LaTeXStrings", "LinearAlgebra", "Logging", "Measures", "NonlinearSolve", "Parameters", "Pkg", "PreallocationTools", "PrecompileTools", "RecursiveArrayTools", "SciMLBase", "Serialization", "StaticArrays", "Statistics", "StructMapping", "Timers", "Xfoil", "YAML"] +deps = ["Colors", "DefaultApplication", "DelimitedFiles", "DifferentiationInterface", "FiniteDiff", "ForwardDiff", "Interpolations", "LaTeXStrings", "LinearAlgebra", "Logging", "Measures", "NPZ", "NonlinearSolve", "Parameters", "Pkg", "PreallocationTools", "PrecompileTools", "Printf", "RecursiveArrayTools", "SciMLBase", "Serialization", "StaticArrays", "Statistics", "StructMapping", "Timers", "Xfoil", "YAML"] path = "." uuid = "ed3cd733-9f0f-46a9-93e0-89b8d4998dd9" -version = "3.3.4" -weakdeps = ["ControlPlots", "Makie", "PythonCall"] +version = "3.3.6" +weakdeps = ["Makie", "MakieControlPlots"] [deps.VortexStepMethod.extensions] - VortexStepMethodControlPlotsExt = ["ControlPlots", "PythonCall"] - VortexStepMethodMakieExt = "Makie" + VortexStepMethodMakieExt = ["Makie", "MakieControlPlots"] [[deps.Wayland_jll]] deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll"] @@ -2600,6 +2622,12 @@ git-tree-sha1 = "a1c0c7585346251353cddede21f180b96388c403" uuid = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" version = "0.4.16" +[[deps.ZipFile]] +deps = ["Libdl", "Printf", "Zlib_jll"] +git-tree-sha1 = "f492b7fe1698e623024e873244f10d89c95c340a" +uuid = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea" +version = "0.10.1" + [[deps.Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" @@ -2682,12 +2710,6 @@ git-tree-sha1 = "4e4282c4d846e11dce56d74fa8040130b7a95cb3" uuid = "c5f90fcd-3b7e-5836-afba-fc50a0988cb2" version = "1.6.0+0" -[[deps.micromamba_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "717df6f6892af4ee13279a73aa58474e58a88667" -uuid = "f8abcde7-e9b7-5caa-b8af-a437887ae8e4" -version = "2.3.1+0" - [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" @@ -2704,12 +2726,6 @@ deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" version = "17.7.0+0" -[[deps.pixi_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "3667b0931a7fe50f0a5554c61af00e5640019e21" -uuid = "4d7b5844-a134-5dcd-ac86-c8f19cd51bed" -version = "0.63.2+0" - [[deps.x264_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "14cc7083fc6dff3cc44f2bc435ee96d06ed79aa7" diff --git a/Project.toml b/Project.toml index ef66215d..6d188d41 100644 --- a/Project.toml +++ b/Project.toml @@ -4,7 +4,7 @@ authors = ["1-Bart-1 ", "Oriol Cayon and contributors"] version = "3.3.6" [workspace] -projects = ["examples", "examples_cp", "docs", "test"] +projects = ["examples", "docs", "test"] [deps] Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" @@ -36,17 +36,14 @@ Xfoil = "19641d66-a62d-11e8-2441-8f57a969a9c4" YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" [weakdeps] -ControlPlots = "23c2ee80-7a9e-4350-b264-8e670f12517c" Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" +MakieControlPlots = "6d616b69-6563-4f6e-8472-6f6c706c6f74" [extensions] -VortexStepMethodControlPlotsExt = ["ControlPlots", "PythonCall"] -VortexStepMethodMakieExt = "Makie" +VortexStepMethodMakieExt = ["Makie", "MakieControlPlots"] [compat] Colors = "0.13" -ControlPlots = "0.2.5, 0.3" DefaultApplication = "1" DelimitedFiles = "1" DifferentiationInterface = "0.7.4" @@ -57,6 +54,7 @@ LaTeXStrings = "1" LinearAlgebra = "1" Logging = "1" Makie = "0.24.6" +MakieControlPlots = "0.1.5" Measures = "0.3" NonlinearSolve = "4.8.0" NPZ = "0.4" @@ -64,7 +62,6 @@ Parameters = "0.12" Pkg = "1" Printf = "1" PreallocationTools = "1.1.2" -PythonCall = "0.9" PrecompileTools = "1.2.1" RecursiveArrayTools = "3, 4" SciMLBase = "2, 3" diff --git a/README.md b/README.md index b05c0972..619bd078 100644 --- a/README.md +++ b/README.md @@ -19,15 +19,8 @@ Example output is shown in the figure below, where the aerodynamic predictions o ![Example output](docs/v3_example_output.png) ## Installation -Install [Julia 1.10](https://ufechner7.github.io/2024/08/09/installing-julia-with-juliaup.html) or later, -if you haven't already. On Linux, make sure that Python3 and Matplotlib are installed: -``` -sudo apt install python3-matplotlib -``` -Furthermore, the package `ControlPlots` must be installed globally: -``` -julia -e 'using Pkg; Pkg.add("ControlPlots")' -``` +Install [Julia 1.10](https://ufechner7.github.io/2024/08/09/installing-julia-with-juliaup.html) or later, +if you haven't already. Before installing this software it is suggested to create a new project, for example like this: @@ -62,10 +55,6 @@ julia> using VortexStepMethod julia> VortexStepMethod.install_examples() julia> include("examples/menu.jl") ``` -or, for using the ControlPlots library (faster time-to-first-plot): -``` -include("examples_cp/menu_cp.jl") -``` ## Running the examples as developer If you have git installed, check out this repo because it makes it easier to understand the code: @@ -88,10 +77,6 @@ Then you can display a menu with the available examples using the GLMakie librar ```julia menu() ``` -or using the ControlPlots library (faster time-to-first-plot): -```julia -menu_cp() -``` To browse the code, it is suggested to use [VSCode](https://code.visualstudio.com/) with the Julia plugin. diff --git a/bin/install b/bin/install index cd48e024..c7f69397 100755 --- a/bin/install +++ b/bin/install @@ -187,7 +187,7 @@ if ! instantiate_main_with_fallback "." "main"; then exit 1 fi -SUBPROJECTS=("examples" "examples_cp" "test" "docs" "scripts") +SUBPROJECTS=("examples" "test" "docs" "scripts") echo echo "Instantiating sub-projects..." @@ -226,46 +226,10 @@ else exit 1 fi -# Bootstrap LocalPreferences.toml for subprojects that need PythonCall. -# Only copies the .default if no LocalPreferences.toml exists yet (e.g. fresh -# clone). A subsequent run of bin/install_controlplots will add or update the -# machine-specific settings on top. -echo -echo "Bootstrapping LocalPreferences.toml for subprojects..." -for _lp_dir in examples_cp test; do - _lp_file="${_lp_dir}/LocalPreferences.toml" - _lp_default="${_lp_dir}/LocalPreferences.toml.default" - if [[ ! -f "$_lp_file" && -f "$_lp_default" ]]; then - cp "$_lp_default" "$_lp_file" - echo " Created ${_lp_file} from default (CondaPkg disabled)." - fi -done - $_julia_cmd --project=. -e 'using Pkg; Pkg.precompile(); Pkg.activate("examples"); Pkg.precompile(); -Pkg.activate("examples_cp"); Pkg.precompile(); Pkg.activate("test"); Pkg.precompile(); +Pkg.activate("test"); Pkg.precompile(); @info "Precompilation complete."' -$_julia_cmd --project=examples -e 'using GLMakie, VortexStepMethod; @info "GLMakie extension ready."' -_cp_lp="examples_cp/LocalPreferences.toml" -# Skip ControlPlots verification only when Python is genuinely not yet configured -# (Null backend with no exe= set). After install_controlplots --system the file -# still has backend="Null" but also has exe=..., so we proceed with verification. -if grep -q 'backend = "Null"' "$_cp_lp" 2>/dev/null && ! grep -q 'exe = ' "$_cp_lp" 2>/dev/null; then - echo "Skipping ControlPlots extension verification (Python not yet configured)." - echo "Run ./bin/install_controlplots to set up Python and verify ControlPlots." -else - # On Linux, prepend Julia's lib/julia so its bundled libcrypto.so.3 takes - # priority over an older system OpenSSL (e.g. Ubuntu 22.04 ships 3.0 while - # Julia 1.12 bundles 3.3+). - _julia_lib=$($_julia_cmd -e 'print(joinpath(Sys.BINDIR, "..", "lib", "julia"))' 2>/dev/null || true) - if [[ "$(uname -s)" == "Linux" && -n "$_julia_lib" && -d "$_julia_lib" ]]; then - LD_LIBRARY_PATH="${_julia_lib}${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" \ - $_julia_cmd -t1 --project=examples_cp \ - -e 'using ControlPlots, VortexStepMethod; @info "ControlPlots extension ready."' - else - $_julia_cmd -t1 --project=examples_cp \ - -e 'using ControlPlots, VortexStepMethod; @info "ControlPlots extension ready."' - fi -fi +$_julia_cmd --project=examples -e 'using GLMakie, MakieControlPlots, VortexStepMethod; @info "Makie plotting extension ready."' $_julia_cmd --project=. -e 'using Pkg; Pkg.test(test_args=["settings/test_settings.jl"]); @info "Minimal test smoke check complete."' diff --git a/bin/install_controlplots b/bin/install_controlplots deleted file mode 100755 index 59a8abfd..00000000 --- a/bin/install_controlplots +++ /dev/null @@ -1,348 +0,0 @@ -#!/bin/bash -eu -# SPDX-FileCopyrightText: 2025 Uwe Fechner -# SPDX-License-Identifier: MIT -# -# Install and configure matplotlib for ControlPlots.jl (via PythonCall). -# -# Two backends are supported: -# 1) System Python – uses the matplotlib package installed by Ubuntu/Debian (apt). -# Fastest option; shares the system Python install. -# 2) CondaPkg – installs matplotlib into a pixi-managed Conda environment. -# Self-contained; does not require root / sudo. -# -# Both options configure the Qt (qtagg) backend for interactive plot windows. - -print_usage() { - echo "Usage:" - echo " ./bin/install_controlplots [--system | --conda] [-y | --yes] [-h | --help]" - echo "" - echo "Options:" - echo " --system Use the system Python and matplotlib (Ubuntu/Debian apt)" - echo " --conda Use CondaPkg (pixi) to install matplotlib" - echo " -y, --yes Non-interactive; accept defaults" - echo " -h, --help Show this help message" -} - -_backend="" # "system" or "conda" -_yes=false - -while [[ $# -gt 0 ]]; do - case $1 in - -h|--help) - print_usage - exit 0 - ;; - --system) - _backend="system" - shift - ;; - --conda) - _backend="conda" - shift - ;; - -y|--yes) - _yes=true - shift - ;; - *) - echo "Unknown option: $1" - print_usage - exit 1 - ;; - esac -done - -# Always run from the repository root (resolve from this script location). -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" -cd "${REPO_ROOT}" - -CONTROLPLOTS_PROJECT="examples_cp" -TEST_PROJECT="test" - -# ── Interactive backend selection ───────────────────────────────────────────── - -if [[ -z "$_backend" ]]; then - echo "Which matplotlib backend do you want to use for ControlPlots?" - echo "" - echo " 1) System Python (uses Ubuntu/Debian python3-matplotlib via apt)" - echo " - Requires sudo" - echo " - Shares the system-wide Python installation" - echo "" - echo " 2) CondaPkg (installs matplotlib into a pixi-managed Conda environment)" - echo " - No sudo required" - echo " - Self-contained; downloads ~200 MB on first use" - echo "" - if [[ "$_yes" == true ]]; then - _choice="2" - echo "Using default: 2 (CondaPkg)" - else - read -rp "Enter 1 or 2 [default: 2]: " _choice - fi - case "${_choice:-2}" in - 1) _backend="system" ;; - 2) _backend="conda" ;; - *) - echo "Invalid choice. Please enter 1 or 2." - exit 1 - ;; - esac -fi - -echo "" -echo "Selected backend: $_backend" -echo "" - -# ── Helper: install matplotlib via CondaPkg ─────────────────────────────────── - -_install_matplotlib_condapkg() { - echo "Installing matplotlib and pyqt into CondaPkg (pixi) environment..." - julia --project="${CONTROLPLOTS_PROJECT}" -e ' -using Pkg -# Ensure CondaPkg is available -if Base.find_package("CondaPkg") === nothing - Pkg.add("CondaPkg") -end -using CondaPkg -CondaPkg.add("matplotlib") -CondaPkg.add("pyqt") -CondaPkg.resolve() -println("matplotlib and pyqt installed in CondaPkg environment.") -' -} - -_verify_controlplots() { - echo "Verifying ControlPlots can be loaded..." - local _julia_prefix="" - if [[ "$(uname -s)" == "Linux" ]]; then - # Julia 1.12+ ships libssl.so.3 compiled against OpenSSL 3.3+, which may - # not match the system libcrypto.so.3 (e.g. Ubuntu 22.04 ships 3.0). - # Prepend Julia's own lib/julia directory so its bundled libcrypto.so.3 - # is found before the system one. We keep any existing LD_LIBRARY_PATH - # entries so other libraries set by callers are not lost. - _julia_lib=$(julia -e 'print(joinpath(Sys.BINDIR, "..", "lib", "julia"))' 2>/dev/null || true) - if [[ -n "$_julia_lib" && -d "$_julia_lib" ]]; then - _julia_prefix="env LD_LIBRARY_PATH=${_julia_lib}${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" - fi - fi - if $_julia_prefix julia --project="${CONTROLPLOTS_PROJECT}" -e ' -using ControlPlots -println("ControlPlots loaded successfully.") -'; then - echo "" - echo "✓ ControlPlots is working." - else - echo "" - echo "Warning: ControlPlots could not be loaded. Check the error output above." - echo "You may need to run this script again with the other backend option." - exit 1 - fi -} - -# ── Helper: write MPLBACKEND=qtagg to LocalPreferences.toml ────────────────── - -_set_mplbackend_qtagg() { - local _prefs_file="${CONTROLPLOTS_PROJECT}/LocalPreferences.toml" - # Remove any existing [ENV] section managed by this script. - if [[ -f "$_prefs_file" ]]; then - _tmp=$(mktemp) - awk ' - /^\[ENV\]/ { in_env=1; next } - in_env && /^\[/ { in_env=0 } - !in_env { print } - ' "$_prefs_file" > "$_tmp" - mv "$_tmp" "$_prefs_file" - fi - { - echo "" - echo "[ENV]" - echo "MPLBACKEND = \"qtagg\"" - } >> "$_prefs_file" - echo "Set MPLBACKEND=qtagg in $_prefs_file." -} - -# ── System Python backend ───────────────────────────────────────────────────── - -if [[ "$_backend" == "system" ]]; then - # Detect package manager and install python3-matplotlib if missing. - if [[ "$(uname -s)" == "Linux" ]]; then - if grep -qiE "ubuntu|debian" /etc/os-release 2>/dev/null; then - if ! dpkg -s python3-matplotlib &>/dev/null 2>&1 || ! dpkg -s python3-pyqt5 &>/dev/null 2>&1; then - echo "Installing python3-matplotlib and python3-pyqt5 via apt..." - sudo apt install -y python3-matplotlib python3-pyqt5 - else - echo "python3-matplotlib and python3-pyqt5 are already installed." - fi - elif grep -qi "fedora" /etc/os-release 2>/dev/null; then - if ! rpm -q python3-matplotlib &>/dev/null 2>&1 || ! rpm -q python3-pyqt5 &>/dev/null 2>&1; then - echo "Installing python3-matplotlib and python3-qt5 via dnf..." - sudo dnf install -y python3-matplotlib python3-pyqt5 - else - echo "python3-matplotlib and python3-pyqt5 are already installed." - fi - else - echo "Warning: Could not detect Ubuntu/Debian or Fedora." - echo "Please ensure python3-matplotlib is installed manually before continuing." - if [[ "$_yes" == false ]]; then - read -rp "Continue anyway? (y/n) [default: y]: " _cont - case "${_cont:-y}" in - n|N) echo "Aborted."; exit 1 ;; - esac - fi - fi - elif [[ "$(uname -s)" =~ ^(MINGW|MSYS|CYGWIN) ]]; then - # Windows (Git Bash): use pip to install matplotlib and PyQt5. - _pip="" - for _pip_candidate in pip3 pip; do - if command -v "$_pip_candidate" &>/dev/null; then - _pip="$_pip_candidate" - break - fi - done - if [[ -n "$_pip" ]]; then - if ! "$_pip" show matplotlib &>/dev/null 2>&1 || ! "$_pip" show PyQt5 &>/dev/null 2>&1; then - echo "Installing matplotlib and PyQt5 via pip..." - "$_pip" install --user matplotlib PyQt5 - else - echo "matplotlib and PyQt5 are already installed." - fi - else - echo "Warning: pip not found. Please install matplotlib and PyQt5 manually:" - echo " pip install matplotlib PyQt5" - if [[ "$_yes" == false ]]; then - read -rp "Continue anyway? (y/n) [default: y]: " _cont - case "${_cont:-y}" in - n|N) echo "Aborted."; exit 1 ;; - esac - fi - fi - else - echo "Warning: System Python backend is intended for Ubuntu/Debian/Fedora Linux or Windows." - echo "On this OS ($(uname -s)) you may need to install matplotlib manually." - if [[ "$_yes" == false ]]; then - read -rp "Continue anyway? (y/n) [default: y]: " _cont - case "${_cont:-y}" in - n|N) echo "Aborted."; exit 1 ;; - esac - fi - fi - - # Locate the system python3 executable. - _syspython="" - if [[ "$(uname -s)" =~ ^(MINGW|MSYS|CYGWIN) ]]; then - # On Windows (Git Bash) 'python3' may not exist; also try 'python'. - for _candidate in python3 python; do - if command -v "$_candidate" &>/dev/null; then - _syspython=$(command -v "$_candidate") - # Verify it runs (guards against the Windows Store stub). - if "$_syspython" --version &>/dev/null 2>&1; then - break - fi - _syspython="" - fi - done - else - for _candidate in python3 /usr/bin/python3; do - if command -v "$_candidate" &>/dev/null; then - _syspython=$(command -v "$_candidate") - break - fi - done - fi - if [[ -z "$_syspython" ]]; then - echo "Error: python3 not found on PATH. Please install python3." - exit 1 - fi - echo "Found system Python: $_syspython" - - # Remove the CondaPkg-managed environment so that PythonCall won't keep - # using a stale conda Python when switching to system Python. - if [[ -d "${CONTROLPLOTS_PROJECT}/.CondaPkg" ]]; then - echo "Removing ${CONTROLPLOTS_PROJECT}/.CondaPkg (switching from CondaPkg to system Python)..." - rm -rf "${CONTROLPLOTS_PROJECT}/.CondaPkg" - fi - if [[ -d "${TEST_PROJECT}/.CondaPkg" ]]; then - echo "Removing ${TEST_PROJECT}/.CondaPkg (switching from CondaPkg to system Python)..." - rm -rf "${TEST_PROJECT}/.CondaPkg" - fi - # Unset JULIA_PYTHONCALL_EXE so the LocalPreferences.toml exe setting takes - # effect. - unset JULIA_PYTHONCALL_EXE - # Prevent CondaPkg from re-installing a Conda env in the current process. - export JULIA_CONDAPKG_BACKEND="Null" - export JULIA_PYTHONCALL_EXE="$_syspython" - - # Helper: update a LocalPreferences.toml file with the system Python settings. - _write_system_python_prefs() { - local _pf="$1" - if [[ -f "$_pf" ]]; then - _tmp=$(mktemp) - awk ' - /^\[PythonCall\]/ { in_sec=1; next } - /^\[PyCall\]/ { in_sec=1; next } - /^\[CondaPkg\]/ { in_sec=1; next } - in_sec && /^\[/ { in_sec=0 } - !in_sec { print } - ' "$_pf" > "$_tmp" - mv "$_tmp" "$_pf" - fi - { - echo "" - echo "[PythonCall]" - echo "exe = \"$_syspython\"" - echo "" - echo "[CondaPkg]" - echo "backend = \"Null\"" - } >> "$_pf" - echo "Written to $_pf." - } - - echo "" - echo "Saving python_exe=$_syspython to LocalPreferences.toml files..." - # Write to the root project plus the subprojects that load PythonCall. - _write_system_python_prefs "LocalPreferences.toml" - _write_system_python_prefs "${CONTROLPLOTS_PROJECT}/LocalPreferences.toml" - _write_system_python_prefs "${TEST_PROJECT}/LocalPreferences.toml" - - _set_mplbackend_qtagg - _verify_controlplots - - echo "" - echo "Done. ControlPlots will use the system Python (PythonCall) matplotlib with the Qt (qtagg) backend." - -# ── CondaPkg backend ────────────────────────────────────────────────────────── - -elif [[ "$_backend" == "conda" ]]; then - # Remove [PythonCall] exe, [CondaPkg] backend override, and legacy [PyCall] - # so PythonCall falls back to the CondaPkg-managed Python. - # Must be done in both the root and examples_cp LocalPreferences.toml. - _remove_python_prefs() { - local _pf="$1" - [[ -f "$_pf" ]] || return 0 - _tmp=$(mktemp) - awk ' - /^\[PythonCall\]/ { in_sec=1; next } - /^\[PyCall\]/ { in_sec=1; next } - /^\[CondaPkg\]/ { in_sec=1; next } - in_sec && /^\[/ { in_sec=0 } - !in_sec { print } - ' "$_pf" > "$_tmp" - if ! diff -q "$_pf" "$_tmp" &>/dev/null; then - mv "$_tmp" "$_pf" - echo "Removed [PythonCall]/[CondaPkg] sections from $_pf (switching to CondaPkg)." - else - rm -f "$_tmp" - fi - } - _remove_python_prefs "LocalPreferences.toml" - _remove_python_prefs "${CONTROLPLOTS_PROJECT}/LocalPreferences.toml" - _remove_python_prefs "${TEST_PROJECT}/LocalPreferences.toml" - - _install_matplotlib_condapkg - - _set_mplbackend_qtagg - _verify_controlplots - - echo "" - echo "Done. ControlPlots will use the CondaPkg-managed matplotlib with the Qt (qtagg) backend." -fi diff --git a/bin/jetls_examples b/bin/jetls_examples index 2bcc466d..13a98e75 100755 --- a/bin/jetls_examples +++ b/bin/jetls_examples @@ -9,9 +9,6 @@ fi echo -e "\033[1mInstalling dependencies...\033[0m" julia --project=examples -e 'using Pkg; Pkg.instantiate()' -julia --project=examples_cp -e 'using Pkg; Pkg.instantiate()' echo -e "\033[1mChecking examples with jetls...\033[0m" jetls check --root=. examples/*.jl -echo -e "\033[1mChecking examples_cp with jetls...\033[0m" -jetls -t 1,0 -- check --root=. examples_cp/*.jl echo diff --git a/bin/run_julia b/bin/run_julia index 8408a0c7..3c14cce7 100755 --- a/bin/run_julia +++ b/bin/run_julia @@ -9,7 +9,7 @@ export JULIA_PKG_SERVER_REGISTRY_PREFERENCE=eager # If any local project preferences file disables CondaPkg, forward that as an # env var so that Julia reads it at runtime even when activating a subproject # interactively (where @load_preference may have a stale baked-in value). -for _lp in LocalPreferences.toml examples_cp/LocalPreferences.toml test/LocalPreferences.toml; do +for _lp in LocalPreferences.toml test/LocalPreferences.toml; do if grep -q 'backend = "Null"' "$_lp" 2>/dev/null; then export JULIA_CONDAPKG_BACKEND=Null break diff --git a/docs/Project.toml b/docs/Project.toml index 2039ea48..d7d84381 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -2,6 +2,7 @@ Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" LiveServer = "16fef848-5104-11e9-1b77-fb7a48bbb589" Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +MakieControlPlots = "6d616b69-6563-4f6e-8472-6f6c706c6f74" VortexStepMethod = "ed3cd733-9f0f-46a9-93e0-89b8d4998dd9" [sources] diff --git a/docs/make.jl b/docs/make.jl index c173b484..5d8221a1 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,4 +1,5 @@ using Makie +using MakieControlPlots using VortexStepMethod using Documenter diff --git a/docs/src/examples.md b/docs/src/examples.md index 36555701..5c7cf7ea 100644 --- a/docs/src/examples.md +++ b/docs/src/examples.md @@ -132,12 +132,6 @@ more examples by typing: julia> include("examples/menu.jl") ``` -or, you prefer to use the ControlPlots library: - -```julia -julia> include("examples_cp/menu_cp.jl") -``` - You should see the following menu: ```text @@ -161,7 +155,13 @@ Press `` to run the selected example. ## Plotting Backends -The examples in this package support three plotting backends. Here is a comparison to help you choose: +The examples use two Makie backends — `GLMakie` (interactive) and `CairoMakie` +(headless / vector output). For a +[ControlPlots](https://github.com/aenarete/ControlPlots.jl)-style plotting API on +top of Makie, the examples also load +[`MakieControlPlots`](https://github.com/OpenSourceAWE/MakieControlPlots.jl), +which provides `plot`, `plotx`, and `plotxy` helpers. Here is a comparison to +help you choose a backend: ### GLMakie **Advantages:** @@ -172,7 +172,6 @@ The examples in this package support three plotting backends. Here is a comparis **Disadvantages:** - Requires a display server (does not work in headless/server environments without a virtual framebuffer). - Heavier dependency: needs OpenGL drivers and a GPU. -- Longer initial load time compared to ControlPlots ### CairoMakie **Advantages:** @@ -183,29 +182,14 @@ The examples in this package support three plotting backends. Here is a comparis - Plots are static — no interactive zoom or pan. - Slower for very large or complex scenes because rendering is done in software. - 3D support is limited compared to GLMakie. -- Longer initial load time compared to ControlPlots -### ControlPlots (based on PyPlot / Matplotlib) -**Advantages:** -- Simple API, easy to learn for students -- In addition, the Matplotlib API for users coming from Python/Matplotlib is supported. -- Works in headless environments; can save to PNG, SVG, PDF, etc. -- Very lightweight Julia-side dependency (delegates work to Python). - -**Disadvantages:** -- Requires a working Python installation with Matplotlib (via `PyCall`). -- Might crash when multithreading is enabled. Start Julia with `-t 1,0` to avoid problems. -- No native Makie ecosystem integration (e.g. cannot use `Makie.Observable` for live updates). -- Interactivity is limited and depends on the Matplotlib backend in use. -- Extra setup complexity when Python or Matplotlib are not already installed. - -| Feature | GLMakie | CairoMakie | ControlPlots | -|---|---|---|---| -| Interactive (zoom/pan) | yes | no | yes | -| Headless / server | no* | yes | yes | -| Vector output (PDF/SVG) | no | yes | yes | -| GPU required | yes | no | no | -| 3D support | full | limited | limited | -| Load time | slow | medium | fast | +| Feature | GLMakie | CairoMakie | +|---|---|---| +| Interactive (zoom/pan) | yes | no | +| Headless / server | no* | yes | +| Vector output (PDF/SVG) | no | yes | +| GPU required | yes | no | +| 3D support | full | limited | +| Load time | slow | medium | \* GLMakie can run headless with a virtual framebuffer (e.g. `Xvfb`), but this requires additional setup. \ No newline at end of file diff --git a/docs/src/functions.md b/docs/src/functions.md index c051085a..58c97115 100644 --- a/docs/src/functions.md +++ b/docs/src/functions.md @@ -26,13 +26,14 @@ calculate_results ``` ## Main Plotting Functions -The plotting functions are implemented as [package extensions](https://pkgdocs.julialang.org/v1.11/creating-packages/#Conditional-loading-of-code-in-packages-(Extensions)). They are available when `GLMakie` (or `ControlPlots`) is loaded before `VortexStepMethod`. The examples use `GLMakie`. +The plotting functions are implemented as [package extensions](https://pkgdocs.julialang.org/v1.11/creating-packages/#Conditional-loading-of-code-in-packages-(Extensions)). They are available when a Makie backend (`GLMakie` or `CairoMakie`) and `MakieControlPlots` are loaded before `VortexStepMethod`. The examples use `GLMakie`. ```@docs plot_geometry plot_distribution plot_polars plot_polar_data plot_combined_analysis +plot_airfoil_slices plot_airfoils plot_section_polars ``` diff --git a/docs/src/index.md b/docs/src/index.md index 8ef6e3d4..b5f0aa55 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -82,12 +82,6 @@ Then you can display a menu with the available examples using the GLMakie librar menu() ``` -or using the ControlPlots library (faster time-to-first-plot): - -```julia -menu_cp() -``` - To browse the code, it is suggested to use [VSCode](https://code.visualstudio.com/) with the Julia plugin. diff --git a/examples/Project.toml b/examples/Project.toml index 2241d9e7..d5c71d51 100644 --- a/examples/Project.toml +++ b/examples/Project.toml @@ -8,6 +8,7 @@ DifferentiationInterface = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +MakieControlPlots = "6d616b69-6563-4f6e-8472-6f6c706c6f74" REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" VortexStepMethod = "ed3cd733-9f0f-46a9-93e0-89b8d4998dd9" diff --git a/examples/V3_neuralfoil.jl b/examples/V3_neuralfoil.jl index 60c43597..c7342206 100644 --- a/examples/V3_neuralfoil.jl +++ b/examples/V3_neuralfoil.jl @@ -3,6 +3,7 @@ if Base.active_project() \!= joinpath(@__DIR__, "Project.toml") Pkg.activate(@__DIR__) end using GLMakie +using MakieControlPlots using VortexStepMethod using LinearAlgebra diff --git a/examples/linearize_check.jl b/examples/linearize_check.jl index 57023755..d398a020 100644 --- a/examples/linearize_check.jl +++ b/examples/linearize_check.jl @@ -4,6 +4,7 @@ if Base.active_project() != joinpath(@__DIR__, "Project.toml") end using GLMakie +using MakieControlPlots using DifferentiationInterface using LinearAlgebra using VortexStepMethod diff --git a/examples/menu.jl b/examples/menu.jl index 38a986c6..9714dbed 100644 --- a/examples/menu.jl +++ b/examples/menu.jl @@ -3,11 +3,10 @@ Pkg.activate(@__DIR__) using GLMakie using CairoMakie +using MakieControlPlots using VortexStepMethod using REPL.TerminalMenus -set_plot_backend!(MakieBackend()) - url = "https://opensourceawe.github.io/VortexStepMethod.jl/dev" example_files = [ diff --git a/examples/neuralfoil_polars.jl b/examples/neuralfoil_polars.jl index b6dbb0d9..8163560e 100644 --- a/examples/neuralfoil_polars.jl +++ b/examples/neuralfoil_polars.jl @@ -3,6 +3,7 @@ if Base.active_project() \!= joinpath(@__DIR__, "Project.toml") Pkg.activate(@__DIR__) end using GLMakie +using MakieControlPlots using VortexStepMethod # Configuration diff --git a/examples/ram_air_kite.jl b/examples/ram_air_kite.jl index 3e54ad8d..5ffa7d9b 100644 --- a/examples/ram_air_kite.jl +++ b/examples/ram_air_kite.jl @@ -3,6 +3,7 @@ if Base.active_project() \!= joinpath(@__DIR__, "Project.toml") Pkg.activate(@__DIR__) end using GLMakie +using MakieControlPlots using VortexStepMethod using LinearAlgebra diff --git a/examples/show_slices.jl b/examples/show_slices.jl index 10f91752..8c1cefe3 100644 --- a/examples/show_slices.jl +++ b/examples/show_slices.jl @@ -3,6 +3,7 @@ if Base.active_project() \!= joinpath(@__DIR__, "Project.toml") Pkg.activate(@__DIR__) end using GLMakie +using MakieControlPlots using VortexStepMethod # Change this to the OBJ file you want to slice diff --git a/examples_cp/LocalPreferences.toml.default b/examples_cp/LocalPreferences.toml.default deleted file mode 100644 index 99b6cf42..00000000 --- a/examples_cp/LocalPreferences.toml.default +++ /dev/null @@ -1,5 +0,0 @@ -[CondaPkg] -backend = "Null" - -[ENV] -MPLBACKEND = "qtagg" diff --git a/examples_cp/Project.toml b/examples_cp/Project.toml deleted file mode 100644 index c1d68765..00000000 --- a/examples_cp/Project.toml +++ /dev/null @@ -1,11 +0,0 @@ -[deps] -CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" -ControlPlots = "23c2ee80-7a9e-4350-b264-8e670f12517c" -DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab" -LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" -VortexStepMethod = "ed3cd733-9f0f-46a9-93e0-89b8d4998dd9" - -[sources] -VortexStepMethod = {path = ".."} diff --git a/examples_cp/menu_cp.jl b/examples_cp/menu_cp.jl deleted file mode 100644 index 401d845a..00000000 --- a/examples_cp/menu_cp.jl +++ /dev/null @@ -1,75 +0,0 @@ -using Pkg -if !("ControlPlots" ∈ keys(Pkg.project().dependencies)) - Pkg.activate(@__DIR__) -end - -using ControlPlots -using VortexStepMethod -using REPL.TerminalMenus - -set_plot_backend!(ControlPlotsBackend()) - -url = "https://opensourceawe.github.io/VortexStepMethod.jl/dev" - -examples_dir = joinpath(@__DIR__, "..", "examples") - -example_files = [ - "V3_kite.jl", - "billowing.jl", - "pyramid_model.jl", - "rectangular_wing.jl", - "ram_air_kite.jl", - "stall_model.jl", - "bench.jl", - "cleanup.jl", -] - -function run_all() - failed_examples = String[] - for f in example_files - f == "cleanup.jl" && continue - println("\n" * "="^60) - println("Running: $f") - println("="^60) - try - include(joinpath(examples_dir, f)) - catch e - @error "Failed: $f" exception=(e, catch_backtrace()) - push!(failed_examples, f) - end - end - if isempty(failed_examples) - println("\nAll examples completed.") - else - failed_list = join(failed_examples, ", ") - throw(ErrorException("run_all failed for $(length(failed_examples)) example(s): $failed_list")) - end -end - -function example_menu() - options = [ - [("$(splitext(f)[1]) = include(\"../examples/$f\")") - for f in example_files]; - "help_me = VortexStepMethod.help(\"$url\")"; - "quit" - ] - active = true - while active - menu = RadioMenu(options, pagesize=8) - choice = request( - "\nChoose function to execute or `q` to quit: ", - menu) - if choice != -1 && choice != length(options) - eval(Meta.parse(options[choice])) - else - println("Left menu. Press to quit Julia!") - active = false - end - end -end - -if "--run-all" in ARGS - run_all() -else - example_menu() -end diff --git a/ext/VortexStepMethodControlPlotsExt.jl b/ext/VortexStepMethodControlPlotsExt.jl deleted file mode 100644 index dba0be96..00000000 --- a/ext/VortexStepMethodControlPlotsExt.jl +++ /dev/null @@ -1,943 +0,0 @@ -module VortexStepMethodControlPlotsExt -using ControlPlots, LaTeXStrings, VortexStepMethod, LinearAlgebra, Statistics, DelimitedFiles -using PythonCall: pyconvert -import ControlPlots: plt -import VortexStepMethod: calculate_filaments_for_plotting - -export plot_wing, plot_circulation_distribution, plot_geometry, plot_distribution, - plot_polars, save_plot, show_plot, plot_polar_data, plot_combined_analysis - -# Set this extension as the active plotting backend when loaded (only if not already set) -function __init__() - isnothing(VortexStepMethod._PLOT_BACKEND[]) && - (VortexStepMethod._PLOT_BACKEND[] = VortexStepMethod.ControlPlotsBackend()) -end - -""" - set_plot_style(titel_size=16; use_tex=false) - -Set the default style for plots using LaTeX. -`` -# Arguments: -- `titel_size`: size of the plot title in points (default: 16) -- `ùse_tex`: if the external `pdflatex` command shall be used -""" -function set_plot_style(titel_size=16; use_tex=false) - rcParams = plt.matplotlib."rcParams" - rcParams["text.usetex"] = use_tex - rcParams["font.family"] = "serif" - if use_tex - rcParams["font.serif"] = ["Computer Modern Roman"] - end - rcParams["axes.titlesize"] = titel_size - rcParams["axes.labelsize"] = 12 - rcParams["axes.linewidth"] = 1 - rcParams["lines.linewidth"] = 1 - rcParams["lines.markersize"] = 6 - rcParams["xtick.labelsize"] = 10 - rcParams["ytick.labelsize"] = 10 - rcParams["legend.fontsize"] = 10 - rcParams["figure.titlesize"] = 16 - if use_tex - rcParams["pgf.texsystem"] = "pdflatex" # Use pdflatex - end - rcParams["pgf.rcfonts"] = false - rcParams["figure.figsize"] = (10, 6) # Default figure size -end - - -""" - save_plot(fig, save_path, title; data_type=".pdf") - -Save a plot to a file. - -# Arguments -- `fig`: Plots figure object -- `save_path`: Path to save the plot -- `title`: Title of the plot - -# Keyword arguments -- `data_type`: File extension (default: ".pdf") -""" -function VortexStepMethod.save_plot(fig, save_path, title; data_type=".pdf") - isnothing(save_path) && throw(ArgumentError("save_path should be provided")) - - !isdir(save_path) && mkpath(save_path) - sanitized_title = replace(replace(String(title), ' ' => '_'), '%' => "pct") - full_path = joinpath(save_path, sanitized_title * data_type) - - @debug "Attempting to save figure to: $full_path" - @debug "Current working directory: $(pwd())" - - try - hasproperty(fig, :savefig) || throw(ArgumentError( - "Figure object of type $(typeof(fig)) does not support savefig()." - )) - getproperty(fig, :savefig)(full_path) - @debug "Figure saved as $data_type" - - if isfile(full_path) - @debug "File successfully saved to $full_path" - @debug "File size: $(filesize(full_path)) bytes" - else - @info "File does not exist after save attempt: $full_path" - end - catch e - @error "Error saving figure: $e" - @error "Error type: $(typeof(e))" - rethrow(e) - end -end - -""" - show_plot(fig::plt.Figure; dpi=130) - -Display a plot at specified DPI. - -# Arguments -- `fig`: Plots figure object - -# Keyword arguments -- `dpi`: Dots per inch for the figure (default: 130) -""" -function VortexStepMethod.show_plot(fig; dpi=130) - isnothing(fig) && throw(MethodError(VortexStepMethod.show_plot, (fig,))) - fig.set_dpi(dpi) - plt.display(fig) -end - -""" - plot_line_segment!(ax, segment, color, label; width=3) - -Plot a line segment in 3D with arrow. - -# Arguments -- `ax`: Plot axis -- `segment`: Array of two points defining the segment -- `color`: Color of the segment -- `label`: Label for the legend - -# Keyword Arguments -- `width`: Line width (default: 3) -""" -function plot_line_segment!(ax, segment, color, label; width=3) - ax.plot( - [segment[1][1], segment[2][1]], - [segment[1][2], segment[2][2]], - [segment[1][3], segment[2][3]], - color=color, label=label, linewidth=width - ) - - dir = segment[2] - segment[1] - ax.quiver( - [segment[1][1]], [segment[1][2]], [segment[1][3]], - [dir[1]], [dir[2]], [dir[3]], - color=color - ) -end - -""" - set_axes_equal!(ax; zoom=1.8) - -Set 3D plot axes to equal scale. - -# Arguments -- ax: 3D plot axis - -# Keyword arguments -zoom: zoom factor (default: 1.8) -""" -function set_axes_equal!(ax; zoom=1.8) - x_lims = pyconvert(Vector{Float64}, ax.get_xlim3d()) ./ zoom - y_lims = pyconvert(Vector{Float64}, ax.get_ylim3d()) ./ zoom - z_lims = pyconvert(Vector{Float64}, ax.get_zlim3d()) ./ zoom - - x_range = abs(x_lims[2] - x_lims[1]) - y_range = abs(y_lims[2] - y_lims[1]) - z_range = abs(z_lims[2] - z_lims[1]) - - max_range = max(x_range, y_range, z_range) - - x_mid = mean(x_lims) - y_mid = mean(y_lims) - z_mid = mean(z_lims) - - ax.set_xlim3d((x_mid - max_range / 2, x_mid + max_range / 2)) - ax.set_ylim3d((y_mid - max_range / 2, y_mid + max_range / 2)) - ax.set_zlim3d((z_mid - max_range / 2, z_mid + max_range / 2)) -end - -""" - create_geometry_plot(body_aero::BodyAerodynamics, title, view_elevation, view_azimuth; - zoom=1.8, use_tex=false) - -Create a 3D plot of wing geometry including panels and filaments. - -# Arguments -- body_aero: struct of type BodyAerodynamics -- title: plot title -- view_elevation: initial view elevation angle [°] -- view_azimuth: initial view azimuth angle [°] - -# Keyword arguments -- zoom: zoom factor (default: 1.8) -""" -function create_geometry_plot(body_aero::BodyAerodynamics, title, view_elevation, view_azimuth; - zoom=1.8, use_tex=false) - set_plot_style(28; use_tex) - - panels = body_aero.panels - isempty(panels) && throw(ArgumentError("Cannot plot geometry: body_aero.panels is empty.")) - - va = if body_aero.has_distributed_va - body_aero._va - else - isa(body_aero.va, Tuple) ? body_aero.va[1] : body_aero.va - end - - # Extract geometric data - control_points = [panel.control_point for panel in panels] - aero_centers = [panel.aero_center for panel in panels] - - # Create plot - fig = plt.figure(figsize=(14, 14)) - ax = fig.add_subplot(111, projection="3d") - ax.set_title(title) - - # Plot panels - legend_used = Dict{String,Bool}() - for (i, panel) in enumerate(panels) - # Plot panel edges and surfaces - corners = Matrix{Float64}(panel.corner_points) - x_corners = corners[1, :] - y_corners = corners[2, :] - z_corners = corners[3, :] - - push!(x_corners, x_corners[1]) - push!(y_corners, y_corners[1]) - push!(z_corners, z_corners[1]) - - ax.plot(x_corners, - y_corners, - z_corners, - color="grey", - linewidth=1, - label=i == 1 ? "Panel Edges" : "") - - # Plot control points and aerodynamic centers - ax.scatter([control_points[i][1]], [control_points[i][2]], [control_points[i][3]], - color="green", label=i == 1 ? "Control Points" : "") - ax.scatter([aero_centers[i][1]], [aero_centers[i][2]], [aero_centers[i][3]], - color="blue", label=i == 1 ? "Aerodynamic Centers" : "") - - # Plot filaments - filaments = calculate_filaments_for_plotting(panel) - legends = ["Bound Vortex", "side1", "side2", "wake_1", "wake_2"] - - for (filament, legend) in zip(filaments, legends) - x1, x2, color = filament - @debug "Legend: $legend" - show_legend = !get(legend_used, legend, false) - plot_line_segment!(ax, [x1, x2], color, show_legend ? legend : "") - legend_used[legend] = true - end - end - - # Plot velocity vector - max_chord = maximum(panel.chord for panel in panels) - va_mag = norm(va) - va_vector_begin = -2 * max_chord * va / va_mag - va_vector_end = va_vector_begin + 1.5 * va / va_mag - plot_line_segment!(ax, [va_vector_begin, va_vector_end], "lightblue", "va") - - # Add legends for the first occurrence of each label - # by_label = Dict(zip(labels, handles)) - # ax.legend(values(by_label), keys(by_label), bbox_to_anchor=(0, 0, 1.1, 1)) - - # Set labels and make axes equal - ax.set_xlabel("x") - ax.set_ylabel("y") - ax.set_zlabel("z") - set_axes_equal!(ax; zoom) - - # Set the initial view - ax.view_init(elev=view_elevation, azim=view_azimuth) - - # Ensure the figure is fully rendered - # fig.canvas.draw() - plt.tight_layout(rect=(0, 0, 1, 0.97)) - - return fig -end - -""" - plot_geometry(body_aero::BodyAerodynamics, title, ::ControlPlotsBackend; - data_type=".pdf", save_path=nothing, - is_save=false, is_show=false, - view_elevation=15, view_azimuth=-120, use_tex=false) - -ControlPlots backend implementation of [`plot_geometry`](@ref). - -# Arguments: -- `body_aero`: the [BodyAerodynamics](@ref) to plot -- `title`: plot title - -# Keyword arguments: -- `data_type``: string with the file type postfix (default: ".pdf") -- `save_path`: path for saving the graphic (default: `nothing`) -- `is_save`: boolean value, indicates if the graphic shall be saved (default: `false`) -- `is_show`: boolean value, indicates if the graphic shall be displayed (default: `false`) -- `view_elevation`: initial view elevation angle in degrees (default: 15) -- `view_azimuth`: initial view azimuth angle in degrees (default: -120) -- `use_tex`: if the external `pdflatex` command shall be used (default: false) - -""" -function VortexStepMethod.plot_geometry(body_aero::BodyAerodynamics, title, - ::VortexStepMethod.ControlPlotsBackend; - data_type=".pdf", - save_path=nothing, - is_save=false, - is_show=false, - view_elevation=15, - view_azimuth=-120, - use_tex=false) - - if is_save - plt.ioff() - # Angled view - fig = create_geometry_plot(body_aero, "$(title)_angled_view", 15, -120; use_tex) - save_plot(fig, save_path, "$(title)_angled_view", data_type=data_type) - - # Top view - fig = create_geometry_plot(body_aero, "$(title)_top_view", 90, 0; use_tex) - save_plot(fig, save_path, "$(title)_top_view", data_type=data_type) - - # Front view - fig = create_geometry_plot(body_aero, "$(title)_front_view", 0, 0; use_tex) - save_plot(fig, save_path, "$(title)_front_view", data_type=data_type) - - # Side view - fig = create_geometry_plot(body_aero, "$(title)_side_view", 0, -90; use_tex) - save_plot(fig, save_path, "$(title)_side_view", data_type=data_type) - end - - if is_show - plt.ion() - fig = create_geometry_plot(body_aero, title, view_elevation, view_azimuth; use_tex) - plt.display(fig) - else - fig = create_geometry_plot(body_aero, title, view_elevation, view_azimuth; use_tex) - end - fig -end - -""" - plot_distribution(y_coordinates_list, results_list, label_list, ::ControlPlotsBackend; - title="spanwise_distribution", data_type=".pdf", - save_path=nothing, is_save=false, is_show=true, use_tex=false) - -ControlPlots backend implementation of [`plot_distribution`](@ref). - -# Arguments -- `y_coordinates_list`: List of spanwise coordinates -- `results_list`: List of result dictionaries -- `label_list`: List of labels for different results - -# Keyword arguments -- `title`: Plot title (default: "spanwise_distribution") -- `data_type`: File extension for saving (default: ".pdf") -- `save_path`: Path to save plots (default: nothing) -- `is_save`: Whether to save plots (default: false) -- `is_show`: Whether to display plots (default: true) -- `use_tex`: if the external `pdflatex` command shall be used -""" -function VortexStepMethod.plot_distribution(y_coordinates_list, results_list, label_list, - ::VortexStepMethod.ControlPlotsBackend; - title="spanwise_distribution", - data_type=".pdf", - save_path=nothing, - is_save=false, - is_show=true, - use_tex=false) - - length(results_list) == length(label_list) || throw(ArgumentError( - "Number of results ($(length(results_list))) must match number of labels ($(length(label_list)))" - )) - - # Set the plot style - set_plot_style(; use_tex) - - # Initializing plot - fig, axs = plt.subplots(3, 3, figsize=(16, 10)) - fig.suptitle(title, fontsize=16) - - # CL plot - for (y_coordinates_i, result_i, label_i) in zip(y_coordinates_list, results_list, label_list) - value = "$(round(result_i["cl"], digits=2))" - if label_i == "LLT" - label = label_i * L" $~C_\mathrm{L}$: " * value - else - label = label_i * L" $C_\mathrm{L}$: " * value - end - axs[0, 0].plot( - y_coordinates_i, - result_i["cl_distribution"], - label=label - ) - end - axs[0, 0].set_title(L"$C_\mathrm{L}$ Distribution", size=16) - axs[0, 0].set_xlabel(L"Spanwise Position $y/b$") - axs[0, 0].set_ylabel(L"Lift Coefficient $C_\mathrm{L}$") - axs[0, 0].legend() - - # CD plot - for (y_coordinates_i, result_i, label_i) in zip(y_coordinates_list, results_list, label_list) - value = "$(round(result_i["cl"], digits=2))" - if label_i == "LLT" - label = label_i * L" $~C_\mathrm{D}$: " * value - else - label = label_i * L" $C_\mathrm{D}$: " * value - end - axs[0, 1].plot( - y_coordinates_i, - result_i["cd_distribution"], - label=label - ) - end - axs[0, 1].set_title(L"$C_\mathrm{D}$ Distribution", size=16) - axs[0, 1].set_xlabel(L"Spanwise Position $y/b$") - axs[0, 1].set_ylabel(L"Drag Coefficient $C_\mathrm{D}$") - axs[0, 1].legend() - - # Gamma Distribution - for (y_coordinates_i, result_i, label_i) in zip(y_coordinates_list, results_list, label_list) - axs[0, 2].plot( - y_coordinates_i, - result_i["gamma_distribution"], - label=label_i - ) - end - axs[0, 2].set_title(L"\Gamma~Distribution", size=16) - axs[0, 2].set_xlabel(L"Spanwise Position $y/b$") - axs[0, 2].set_ylabel(L"Circulation~\Gamma") - axs[0, 2].legend() - - # Geometric Alpha - for (y_coordinates_i, result_i, label_i) in zip(y_coordinates_list, results_list, label_list) - axs[1, 0].plot( - y_coordinates_i, - result_i["alpha_geometric"], - label=label_i - ) - end - axs[1, 0].set_title(L"$\alpha$ Geometric", size=16) - axs[1, 0].set_xlabel(L"Spanwise Position $y/b$") - axs[1, 0].set_ylabel(L"Angle of Attack $\alpha$ (deg)") - axs[1, 0].legend() - - # Calculated/ Corrected Alpha - for (y_coordinates_i, result_i, label_i) in zip(y_coordinates_list, results_list, label_list) - axs[1, 1].plot( - y_coordinates_i, - result_i["alpha_at_ac"], - label=label_i - ) - end - axs[1, 1].set_title(L"$\alpha$ result (corrected to aerodynamic center)", size=16) - axs[1, 1].set_xlabel(L"Spanwise Position $y/b$") - axs[1, 1].set_ylabel(L"Angle of Attack $\alpha$ (deg)") - axs[1, 1].legend() - - # Uncorrected Alpha plot - for (y_coordinates_i, result_i, label_i) in zip(y_coordinates_list, results_list, label_list) - axs[1, 2].plot( - y_coordinates_i, - result_i["alpha_uncorrected"], - label=label_i - ) - end - axs[1, 2].set_title(L"$\alpha$ Uncorrected (if VSM, at the control point)", size=16) - axs[1, 2].set_xlabel(L"Spanwise Position $y/b$") - axs[1, 2].set_ylabel(L"Angle of Attack $\alpha$ (deg)") - axs[1, 2].legend() - - # Force Components - for (idx, component) in enumerate(["x", "y", "z"]) - axs[2, idx-1].set_title("Force in $component direction", size=16) - axs[2, idx-1].set_xlabel(L"Spanwise Position $y/b$") - axs[2, idx-1].set_ylabel(raw"$F_\mathrm" * "{$component}" * raw"$") - for (y_coords, results, label) in zip(y_coordinates_list, results_list, label_list) - # Extract force components for the current direction (idx) - forces = results["F_distribution"][idx, :] - # Verify dimensions match - if length(y_coords) != length(forces) - @warn "Dimension mismatch in force plotting" length(y_coords) length(forces) component - continue # Skip this component instead of throwing error - end - space = "" - if label == "LLT" - space = "~" - end - axs[2, idx-1].plot( - y_coords, - forces, - label="$label" * space * raw"$~\Sigma~F_\mathrm" * "{$component}:~" * - raw"$" * "$(round(results["F$component"], digits=2)) N" - ) - axs[2, idx-1].legend() - end - end - - fig.tight_layout() - - # Save and show plot - if is_save - save_plot(fig, save_path, title, data_type=data_type) - end - - if is_show - show_plot(fig) - end - - return fig -end - -""" - generate_polar_data(solver, body_aero::BodyAerodynamics, angle_range; - angle_type="angle_of_attack", angle_of_attack=0.0, - side_slip=0.0, v_a=10.0, use_latex=false) - -Generate polar data for aerodynamic analysis over a range of angles. - -# Arguments -- `solver`: Aerodynamic solver object -- `body_aero`: Wing aerodynamics struct -- `angle_range`: Range of angles to analyze - -# Keyword arguments -- `angle_type`: Type of angle variation ("angle_of_attack" or "side_slip") -- `angle_of_attack`: Initial angle of attack [°] -- `side_slip`: Initial side slip angle [°] -- `v_a`: Norm of apparent wind speed [m/s] - -# Returns -- Tuple of polar data array and Reynolds number -""" - -""" - plot_polars(solver_list, body_aero_list, label_list, ::ControlPlotsBackend; - literature_path_list=String[], - angle_range=range(0, 20, 2), angle_type="angle_of_attack", - angle_of_attack=0.0, side_slip=0.0, v_a=10.0, - title="polar", data_type=".pdf", save_path=nothing, - is_save=true, is_show=true, use_tex=false) - -ControlPlots backend implementation of [`plot_polars`](@ref). - -# Arguments -- `solver_list`: List of aerodynamic solvers -- `body_aero_list`: List of wing aerodynamics objects -- `label_list`: List of labels for each configuration - -# Keyword arguments -- `literature_path_list`: Optional paths to literature data files -- `angle_range`: Range of angles to analyze in degrees -- `angle_type`: "`angle_of_attack`" or "`side_slip`"; (default: `angle_of_attack`) -- `angle_of_attack:` AoA to be used for plotting the polars (default: 0.0) [°] -- `side_slip`: side slip angle (default: 0.0) [°] -- `v_a`: norm of apparent wind speed (default: 10.0) [m/s] -- title: plot title -- `data_type`: File extension for saving (default: ".pdf") -- `save_path`: Path to save plots (default: nothing) -- `is_save`: Whether to save plots (default: true) -- `is_show`: Whether to display plots (default: true) -- `use_tex`: if the external `pdflatex` command shall be used (default: false) -- `cl_over_cd`: Plot CL/CD vs angle instead of CL vs CD (default: true) -""" -function VortexStepMethod.plot_polars( - solver_list, - body_aero_list, - label_list, - ::VortexStepMethod.ControlPlotsBackend; - literature_path_list=String[], - angle_range=range(0, 20, 2), - angle_type="angle_of_attack", - angle_of_attack=0.0, - side_slip=0.0, - v_a=10.0, - title="polar", - data_type=".pdf", - save_path=nothing, - is_save=true, - is_show=true, - use_tex=false, - cl_over_cd=true, - show_moments=false, -) - # Validate inputs - total_cases = length(body_aero_list) + length(literature_path_list) - if total_cases != length(label_list) || length(solver_list) != length(body_aero_list) - throw(ArgumentError("Mismatch in number of solvers ($(length(solver_list))), " * - "cases ($total_cases), and labels ($(length(label_list)))")) - end - main_title = replace(title, " " => "_") - set_plot_style(; use_tex) - - # Generate polar data - polar_data_list = [] - cm_data_list = [] - for (i, (solver, body_aero)) in enumerate(zip(solver_list, body_aero_list)) - result = VortexStepMethod.generate_polar_data( - solver, body_aero, angle_range; - angle_type, - angle_of_attack, - side_slip, - v_a - ) - push!(polar_data_list, result.polar_data) - push!(cm_data_list, (cmx=result.cmx, cmy=result.cmy, - cmz=result.cmz)) - # Update label with Reynolds number - label_list[i] = "$(label_list[i]) Re = $(round(Int64, result.rey*1e-5))e5" - end - # Load literature data if provided - if !isempty(literature_path_list) - for path in literature_path_list - raw_data = readdlm(path, ',') - lit = VortexStepMethod.extract_literature_polar_data( - raw_data, path; angle_type) - push!(polar_data_list, lit.polar_data) - push!(cm_data_list, (cmx=lit.cmx, cmy=lit.cmy, - cmz=lit.cmz)) - end - end - - # Number of computational results (excluding literature) - n_solvers = length(solver_list) - - # Helper: format label and line style - function format_label(label, i, n_solvers) - if i < n_solvers - linestyle, marker, markersize = "-", "*", 7 - else - linestyle, marker, markersize = "-", ".", 5 - end - if use_tex - if contains(label, "LLT") - label = replace(label, "e5" => raw"\cdot10^5") - label = replace(label, " " => raw"~") - label = replace(label, - "LLT" => raw"\mathrm{LLT}{~\,}") - label = raw"$" * label * raw"$" - else - label = replace(label, "e5" => raw"\cdot10^5") - label = replace(label, " " => "~") - label = replace(label, - "VSM" => raw"\mathrm{VSM}") - label = raw"$" * label * raw"$" - end - end - return label, linestyle, marker, markersize - end - - if show_moments - # 2x3 layout: CL, CD, CS, CMx, CMy, CMz - fig, axs = plt.subplots(2, 3, figsize=(21, 14)) - coeff_specs = [ - (1, raw"$C_\mathrm{L}$", 2, nothing), - (2, raw"$C_\mathrm{D}$", 3, nothing), - (3, raw"$C_\mathrm{S}$", 4, nothing), - (4, raw"$C_\mathrm{Mx}$", nothing, :cmx), - (5, raw"$C_\mathrm{My}$", nothing, :cmy), - (6, raw"$C_\mathrm{Mz}$", nothing, :cmz), - ] - for (ax_idx, ylabel, pd_col, cm_field) in coeff_specs - row = (ax_idx - 1) ÷ 3 - col = (ax_idx - 1) % 3 - ax = axs[row, col] - for (i, (polar_data, cm, label)) in enumerate( - zip(polar_data_list, cm_data_list, - label_list)) - label, ls, mk, ms = format_label( - label, i, n_solvers) - if pd_col !== nothing - y_data = polar_data[pd_col] - else - y_data = Float64.(getfield(cm, cm_field)) - all(isnan, y_data) && continue - end - ax.plot(polar_data[1], y_data; - label=label, linestyle=ls, - marker=mk, markersize=ms) - end - ax.set_title( - ylabel * " vs $angle_type [°]") - ax.set_xlabel("$angle_type [°]") - ax.set_ylabel(ylabel) - ax.legend() - end - else - # 2x2 layout: CL, CD, CS, CL/CD or CL-vs-CD - fig, axs = plt.subplots(2, 2, figsize=(14, 14)) - coeff_specs = [ - ((0, 0), raw"$C_\mathrm{L}$", 2), - ((0, 1), raw"$C_\mathrm{D}$", 3), - ((1, 0), raw"$C_\mathrm{S}$", 4), - ] - for (pos, ylabel, pd_col) in coeff_specs - ax = axs[pos...] - for (i, (polar_data, label)) in enumerate( - zip(polar_data_list, label_list)) - label, ls, mk, ms = format_label( - label, i, n_solvers) - ax.plot(polar_data[1], polar_data[pd_col]; - label=label, linestyle=ls, - marker=mk, markersize=ms) - if maximum(polar_data[2]) > 10 - ax.set_ylim([-0.5, 2]) - end - end - ax.set_title( - ylabel * " vs $angle_type [°]") - ax.set_xlabel("$angle_type [°]") - ax.set_ylabel(ylabel) - ax.legend() - end - # Fourth panel: CL/CD or CL-vs-CD - ax4 = axs[1, 1] - for (i, (polar_data, label)) in enumerate( - zip(polar_data_list, label_list)) - label, ls, mk, ms = format_label( - label, i, n_solvers) - if cl_over_cd - cl_cd = polar_data[2] ./ polar_data[3] - ax4.plot(polar_data[1], cl_cd; - label=label, linestyle=ls, - marker=mk, markersize=ms) - else - ax4.plot(polar_data[3], polar_data[2]; - label=label, linestyle=ls, - marker=mk, markersize=ms) - end - end - if cl_over_cd - ax4.set_title( - raw"$C_\mathrm{L}/C_\mathrm{D}$" * - " vs $angle_type [°]") - ax4.set_xlabel("$angle_type [°]") - ax4.set_ylabel( - raw"$C_\mathrm{L}/C_\mathrm{D}$") - else - ax4.set_title( - raw"$C_\mathrm{L}$" * " vs " * - raw"$C_\mathrm{D}$") - ax4.set_xlabel(raw"$C_\mathrm{D}$") - ax4.set_ylabel(raw"$C_\mathrm{L}$") - end - ax4.legend() - end - - fig.tight_layout(h_pad=3.5, rect=(0.01, 0.01, 0.99, 0.99)) - - # Save and show plot - if is_save && !isnothing(save_path) - save_plot(fig, save_path, main_title; data_type) - end - - if is_show - show_plot(fig) - end - - return fig -end - -""" - plot_polar_data(body_aero::BodyAerodynamics, ::ControlPlotsBackend; - alphas=collect(deg2rad.(-5:0.3:25)), - delta_tes=collect(deg2rad.(-5:0.3:25))) - -ControlPlots backend implementation of [`plot_polar_data`](@ref). Plots Cl, Cd, Cm as 3D surfaces -against angle of attack and trailing edge deflection angle. - -# Arguments -- `body_aero`: Wing aerodynamics struct - -# Keyword arguments -- `alphas`: Range of angle of attack values in radians (default: `deg2rad.(-5:0.3:25)`) -- `delta_tes`: Range of trailing edge angles in radians (default: `deg2rad.(-5:0.3:25)`) -- `is_show`: Whether to display plots (default: true) -- `use_tex`: if the external `pdflatex` command shall be used -""" -function VortexStepMethod.plot_polar_data(body_aero::BodyAerodynamics, - ::VortexStepMethod.ControlPlotsBackend; - alphas=collect(deg2rad.(-5:0.3:25)), - delta_tes = collect(deg2rad.(-5:0.3:25)), - is_show = true, - use_tex = false - ) - if body_aero.panels[1].aero_model == POLAR_MATRICES - set_plot_style(; use_tex) - - # Create figure with subplots - fig = plt.figure(figsize=(15, 6)) - - # Get interpolation functions and labels - interp_data = [ - (body_aero.panels[1].cl_interp, L"$C_l$"), - (body_aero.panels[1].cd_interp, L"$C_d$"), - (body_aero.panels[1].cm_interp, L"$C_m$") - ] - - # Create each subplot - for (idx, (interp, label)) in enumerate(interp_data) - ax = fig.add_subplot(1, 3, idx, projection="3d") - - # Create interpolation matrix - interp_matrix = zeros(length(delta_tes), length(alphas)) - interp_matrix .= [interp(alpha, delta_te) - for delta_te in delta_tes, alpha in alphas] - X = collect(delta_tes) .+ zeros(length(alphas))' - Y = collect(alphas)' .+ zeros(length(delta_tes)) - - # Plot surface - ax.plot_wireframe(X, Y, interp_matrix, - edgecolor="blue", - lw=0.5, - rstride=5, - cstride=5, - alpha=0.6) - - # Set labels and title - ax.set_xlabel(L"$\delta$ [rad]") - ax.set_ylabel(L"$\alpha$ [rad]") - ax.set_zlabel(label) - ax.set_title(label * L" vs $\alpha$ and $\delta$") - ax.grid(true) - end - - # Adjust layout and display - plt.tight_layout(rect=(0.01, 0.01, 0.99, 0.99)) - if is_show - show_plot(fig) - end - return fig - else - throw(ArgumentError("Plotting polar data for $(body_aero.panels[1].aero_model) is not implemented.")) - end -end - -""" - plot_combined_analysis(solver, body_aero, results, ::ControlPlotsBackend; kwargs...) - -ControlPlots backend implementation of [`plot_combined_analysis`](@ref). -Calls `plot_geometry`, `plot_distribution`, and `plot_polars` sequentially. - -# Arguments -- `solver`: Solver or array of solvers -- `body_aero`: BodyAerodynamics object or array -- `results`: Results dict or array of results dicts - -See individual functions for detailed parameter descriptions. -""" -function VortexStepMethod.plot_combined_analysis( - solver, - body_aero, - results, - backend::VortexStepMethod.ControlPlotsBackend; - solver_label="VSM", - labels=nothing, - angle_range=range(0, 20, length=20), - angle_type="angle_of_attack", - angle_of_attack=0.0, - side_slip=0.0, - v_a=10.0, - title="Combined Analysis", - data_type=".pdf", - save_path=nothing, - is_save=false, - is_show=true, - view_elevation=15, - view_azimuth=-120, - use_tex=false, - literature_path_list=String[], - cl_over_cd=true, - angle_of_attack_for_spanwise_distribution=5.0, -) - # Normalize inputs to arrays for consistent handling - solvers = solver isa Vector ? solver : [solver] - body_aeros = body_aero isa Vector ? body_aero : [body_aero] - results_list = results isa Vector ? results : [results] - n_solvers = length(solvers) - n_literature = length(literature_path_list) - - # Label normalization (matches Makie version) - label_source = isnothing(labels) ? solver_label : labels - labels_in = label_source isa AbstractVector ? - string.(label_source) : [string(label_source)] - solver_labels = length(labels_in) == 1 ? - fill(labels_in[1], n_solvers) : - labels_in[1:n_solvers] - - # Compute spanwise results at specified AoA - results_spanwise = copy(results_list) - if !isnothing(angle_of_attack_for_spanwise_distribution) - α_span = deg2rad( - angle_of_attack_for_spanwise_distribution) - β_span = deg2rad(side_slip) - for (i, (s, ba)) in enumerate( - zip(solvers, body_aeros)) - va_old = copy(getfield(ba, :_va)) - omega_old = copy(ba.omega) - set_va!(ba, [cos(α_span) * cos(β_span), - sin(β_span), sin(α_span)] * v_a) - results_spanwise[i] = solve(s, ba, - s.sol.gamma_distribution) - set_va!(ba, va_old, omega_old) - end - end - - # Extract y-coordinates for distribution plot - y_coords_list = [ - [p.aero_center[2] for p in ba.panels] - for ba in body_aeros] - - # Plot geometry (first body_aero only) - plot_geometry( - body_aeros[1], - title, - backend; - data_type, save_path, is_save, is_show, - view_elevation, view_azimuth, use_tex - ) - - # Plot spanwise distributions - plot_distribution( - y_coords_list, - results_spanwise, - solver_labels, - backend; - title=title * " - Distributions", - data_type, save_path, is_save, is_show, use_tex - ) - - # Plot polars (include literature labels) - polar_labels = if n_literature > 0 && - length(labels_in) == n_solvers + n_literature - labels_in - else - solver_labels - end - plot_polars( - solvers, - body_aeros, - polar_labels, - backend; - literature_path_list, angle_range, angle_type, - angle_of_attack, side_slip, v_a, - title=title * " - Polars", - data_type, save_path, is_save, is_show, - use_tex, cl_over_cd - ) -end - -end \ No newline at end of file diff --git a/ext/VortexStepMethodMakieExt.jl b/ext/VortexStepMethodMakieExt.jl index 19d90399..f9452c8b 100644 --- a/ext/VortexStepMethodMakieExt.jl +++ b/ext/VortexStepMethodMakieExt.jl @@ -1,17 +1,8 @@ module VortexStepMethodMakieExt using Makie, VortexStepMethod, LinearAlgebra, Statistics, DelimitedFiles +import MakieControlPlots import VortexStepMethod: calculate_filaments_for_plotting -export plot_geometry, plot_distribution, plot_polars, save_plot, show_plot, - plot_polar_data, plot_combined_analysis, plot_airfoil_slices, plot_airfoils, - plot_section_polars - -# Set this extension as the active plotting backend when loaded (only if not already set) -function __init__() - isnothing(VortexStepMethod._PLOT_BACKEND[]) && - (VortexStepMethod._PLOT_BACKEND[] = VortexStepMethod.MakieBackend()) -end - # Global storage for panel mesh observables (for dynamic plotting) const PANEL_MESH_OBSERVABLES = Ref{Union{Nothing,Dict}}(nothing) @@ -465,29 +456,7 @@ function create_geometry_plot_makie(body_aero::BodyAerodynamics, title, return fig end -""" - plot_geometry(body_aero::BodyAerodynamics, title, ::MakieBackend; - data_type=nothing, save_path=nothing, - is_save=false, is_show=false, - view_elevation=15, view_azimuth=-120, use_tex=false) - -Makie backend implementation of [`plot_geometry`](@ref). - -# Arguments: -- `body_aero`: the BodyAerodynamics to plot -- `title`: plot title - -# Keyword arguments: -- `data_type`: File extension (default: `nothing`; delegated to `save_plot` backend-aware default) -- `save_path`: Path for saving (default: nothing) -- `is_save`: Whether to save (default: false) -- `is_show`: Whether to display (default: false) -- `view_elevation`: View elevation angle in degrees (default: 15) -- `view_azimuth`: View azimuth angle in degrees (default: -120) -- `use_tex`: Ignored for Makie (default: false) -""" -function VortexStepMethod.plot_geometry(body_aero::BodyAerodynamics, title, - ::VortexStepMethod.MakieBackend; +function VortexStepMethod.plot_geometry(body_aero::BodyAerodynamics, title; data_type=nothing, save_path=nothing, is_save=false, @@ -523,28 +492,7 @@ function VortexStepMethod.plot_geometry(body_aero::BodyAerodynamics, title, return fig end -""" - plot_distribution(y_coordinates_list, results_list, label_list, ::MakieBackend; - title="spanwise_distribution", data_type=nothing, - save_path=nothing, is_save=false, is_show=true, use_tex=false) - -Makie backend implementation of [`plot_distribution`](@ref). - -# Arguments -- `y_coordinates_list`: List of spanwise coordinates -- `results_list`: List of result dictionaries -- `label_list`: List of labels for different results - -# Keyword arguments -- `title`: Plot title (default: "spanwise_distribution") -- `data_type`: File extension (default: `nothing`; delegated to `save_plot` backend-aware default) -- `save_path`: Path to save plots (default: nothing) -- `is_save`: Whether to save (default: false) -- `is_show`: Whether to display (default: true) -- `use_tex`: Ignored for Makie (default: false) -""" -function VortexStepMethod.plot_distribution(y_coordinates_list, results_list, label_list, - ::VortexStepMethod.MakieBackend; +function VortexStepMethod.plot_distribution(y_coordinates_list, results_list, label_list; title="spanwise_distribution", data_type=nothing, save_path=nothing, @@ -654,63 +602,10 @@ function VortexStepMethod.plot_distribution(y_coordinates_list, results_list, la return fig end -""" - generate_polar_data(solver, body_aero::BodyAerodynamics, angle_range; - angle_type="angle_of_attack", angle_of_attack=0.0, - side_slip=0.0, v_a=10.0) - -Generate polar data for aerodynamic analysis over a range of angles. - -# Arguments -- `solver`: Aerodynamic solver object -- `body_aero`: Wing aerodynamics struct -- `angle_range`: Range of angles to analyze - -# Keyword arguments -- `angle_type`: Type of angle variation ("angle_of_attack" or "side_slip") -- `angle_of_attack`: Initial angle of attack [°] -- `side_slip`: Initial side slip angle [°] -- `v_a`: Norm of apparent wind speed [m/s] - -# Returns -- Tuple of polar data array and Reynolds number -""" - -""" - plot_polars(solver_list, body_aero_list, label_list, ::MakieBackend; - literature_path_list=String[], - angle_range=range(0, 20, 2), angle_type="angle_of_attack", - angle_of_attack=0.0, side_slip=0.0, v_a=10.0, - title="polar", data_type=nothing, save_path=nothing, - is_save=true, is_show=true, use_tex=false) - -Makie backend implementation of [`plot_polars`](@ref). - -# Arguments -- `solver_list`: List of aerodynamic solvers -- `body_aero_list`: List of wing aerodynamics objects -- `label_list`: List of labels for each configuration - -# Keyword arguments -- `literature_path_list`: Optional paths to literature data files -- `angle_range`: Range of angles in degrees -- `angle_type`: "angle_of_attack" or "side_slip" (default: angle_of_attack) -- `angle_of_attack`: AoA [°] (default: 0.0) -- `side_slip`: Side slip angle [°] (default: 0.0) -- `v_a`: Wind speed [m/s] (default: 10.0) -- `title`: Plot title -- `data_type`: File extension (default: `nothing`; delegated to `save_plot` backend-aware default) -- `save_path`: Path to save (default: nothing) -- `is_save`: Whether to save (default: true) -- `is_show`: Whether to display (default: true) -- `use_tex`: Ignored for Makie (default: false) -- `cl_over_cd`: Plot CL/CD vs angle instead of CL vs CD (default: true) -""" function VortexStepMethod.plot_polars( solver_list, body_aero_list, - label_list, - ::VortexStepMethod.MakieBackend; + label_list; literature_path_list=String[], angle_range=range(0, 20, 2), angle_type="angle_of_attack", @@ -875,25 +770,7 @@ function VortexStepMethod.plot_polars( return fig end -""" - plot_polar_data(body_aero::BodyAerodynamics, ::MakieBackend; - alphas=collect(deg2rad.(-5:0.3:25)), - delta_tes=collect(deg2rad.(-5:0.3:25)), - is_show=true, use_tex=false) - -Makie backend implementation of [`plot_polar_data`](@ref). - -# Arguments -- `body_aero`: Wing aerodynamics struct - -# Keyword arguments -- `alphas`: Range of AoA values in radians (default: `deg2rad.(-5:0.3:25)`) -- `delta_tes`: Range of trailing edge angles in radians (default: `deg2rad.(-5:0.3:25)`) -- `is_show`: Whether to display (default: true) -- `use_tex`: Ignored for Makie (default: false) -""" -function VortexStepMethod.plot_polar_data(body_aero::BodyAerodynamics, - ::VortexStepMethod.MakieBackend; +function VortexStepMethod.plot_polar_data(body_aero::BodyAerodynamics; alphas=collect(deg2rad.(-5:0.3:25)), delta_tes=collect(deg2rad.(-5:0.3:25)), is_show=true, @@ -939,52 +816,10 @@ function VortexStepMethod.plot_polar_data(body_aero::BodyAerodynamics, end end -""" - plot_combined_analysis(solver, body_aero, results, ::MakieBackend; - solver_label="VSM", - angle_range=range(0,20,length=20), - angle_type="angle_of_attack", - angle_of_attack=0.0, side_slip=0.0, v_a=10.0, - title="Combined Analysis", - view_elevation=15, view_azimuth=-120, - is_show=true, use_tex=false, - literature_path_list=String[], - data_type=".png", save_path=nothing, is_save=false) - -Makie backend implementation of [`plot_combined_analysis`](@ref). - -# Arguments -- `solver`: Aerodynamic solver -- `body_aero`: BodyAerodynamics object -- `results`: Solution dictionary from solve() - -# Keyword arguments -- `labels`: Optional label string or label vector. If a vector with length - `length(solver)+length(literature_path_list)` is provided, the tail is used - for literature labels; otherwise literature labels default to file basenames. -- `solver_label`: Backward-compatible alias for `labels`. -- `angle_range`: Range of angles for polars (default: range(0,20,length=20)) -- `angle_type`: "angle_of_attack" or "side_slip" (default: "angle_of_attack") -- `angle_of_attack`: AoA in degrees (default: 0.0) -- `side_slip`: Side slip in degrees (default: 0.0) -- `v_a`: Wind speed in m/s (default: 10.0) -- `title`: Overall figure title (default: "Combined Analysis") -- `view_elevation`: Geometry view elevation in degrees (default: 15) -- `view_azimuth`: Geometry view azimuth in degrees (default: -120) -- `is_show`: Display figure (default: true) -- `use_tex`: Ignored for Makie (default: false) -- `literature_path_list`: Paths to literature CSV files (default: String[]) -- `data_type`: File extension (default: ".png", also supports ".jpeg") -- `save_path`: Directory path to save files (default: nothing) -- `is_save`: Save plots to files (default: false) -- `cl_over_cd`: Plot CL/CD vs angle instead of CL vs CD (default: true) -- `angle_of_attack_for_spanwise_distribution`: AoA for spanwise plots (default: 5.0) -""" function VortexStepMethod.plot_combined_analysis( solver, body_aero, - results, - ::VortexStepMethod.MakieBackend; + results; solver_label="VSM", labels=nothing, angle_range=range(0, 20, length=20), @@ -1312,24 +1147,6 @@ end # Airfoil Slice and Kulfan Fit Visualization # ============================================================================ -""" - plot_airfoil_slices(obj_path::String; n_slices=5, is_show=true, - save_path=nothing, data_type=".png") - -Plot airfoil cross-sections extracted from OBJ mesh with Kulfan CST fits overlaid. - -# Arguments -- `obj_path`: Path to OBJ file - -# Keyword Arguments -- `n_slices`: Number of spanwise slices (default 5) -- `is_show`: Display figure (default true) -- `save_path`: Directory to save figure (default nothing) -- `data_type`: Image format (default ".png") - -# Returns -- Makie Figure object -""" function VortexStepMethod.plot_airfoil_slices(obj_path::String; n_slices::Int=5, is_show::Bool=true, save_path=nothing, @@ -1475,14 +1292,7 @@ function plot_airfoil_fit(x::Vector, y::Vector; title::String="Airfoil Fit", return fig, params end -""" - plot_airfoils(geometry_file, ::MakieBackend; n_cols=3, is_show=true, - is_save=false, save_path=nothing, data_type=".png") - -Makie backend implementation of [`plot_airfoils`](@ref). -""" -function VortexStepMethod.plot_airfoils(geometry_file::String, - ::VortexStepMethod.MakieBackend; +function VortexStepMethod.plot_airfoils(geometry_file::String; n_cols::Int=3, is_show::Bool=true, is_save::Bool=false, save_path=nothing, data_type::String=".png") @@ -1510,15 +1320,8 @@ function VortexStepMethod.plot_airfoils(geometry_file::String, return fig end -""" - plot_section_polars(body_aero, coefficient, ::MakieBackend; is_show=true, - is_save=false, save_path=nothing, data_type=".png") - -Makie backend implementation of [`plot_section_polars`](@ref). -""" function VortexStepMethod.plot_section_polars(body_aero::BodyAerodynamics, - coefficient::Symbol, ::VortexStepMethod.MakieBackend; - is_show::Bool=true, is_save::Bool=false, + coefficient::Symbol=:cl; is_show::Bool=true, is_save::Bool=false, save_path=nothing, data_type::String=".png") coefficient in (:cl, :cd, :cm) || @@ -1526,27 +1329,36 @@ function VortexStepMethod.plot_section_polars(body_aero::BodyAerodynamics, idx = coefficient === :cl ? 2 : coefficient === :cd ? 3 : 4 label = uppercasefirst(string(coefficient)) - fig = Figure(size=(900, 600)) - ax = Axis(fig[1, 1]; title="$label per section", xlabel="α [deg]", ylabel=label) - - n_sections = 0 + alphas_deg = nothing + series = Vector{Float64}[] + labels = String[] for wing in body_aero.wings for (s, section) in enumerate(wing.unrefined_sections) section.aero_model == POLAR_VECTORS || continue aero = section.aero_data aero === nothing && continue - lines!(ax, rad2deg.(aero[1]), aero[idx]; label="section $s") - n_sections += 1 + section_alphas = rad2deg.(aero[1]) + if isnothing(alphas_deg) + alphas_deg = collect(section_alphas) + elseif length(section_alphas) != length(alphas_deg) + @warn "section $s has a different α grid; plotting against the first section's α" + end + push!(series, Float64.(aero[idx])) + push!(labels, "section $s") end end - n_sections == 0 && error("No POLAR_VECTORS sections found in body") - n_sections <= 12 && axislegend(ax; position=:rt, framevisible=false) + isempty(series) && error("No POLAR_VECTORS sections found in body") + + plt = MakieControlPlots.plot(alphas_deg, series; + xlabel="α [deg]", ylabel=label, title="$label per section", + labels=labels, disp=(is_show || is_save)) if is_save && !isnothing(save_path) - VortexStepMethod.save_plot(fig, save_path, "section_polars_$coefficient"; data_type) + isdir(save_path) || mkpath(save_path) + MakieControlPlots.savefig( + joinpath(save_path, "section_polars_$(coefficient)$(data_type)")) end - is_show && display(fig) - return fig + return plt end end diff --git a/src/VortexStepMethod.jl b/src/VortexStepMethod.jl index 866b1c8f..ab94759d 100644 --- a/src/VortexStepMethod.jl +++ b/src/VortexStepMethod.jl @@ -52,86 +52,38 @@ export slice_obj_wing, slice_obj_at_positions export generate_neuralfoil_polars, generate_polar_from_coordinates, generate_polar_from_dat export obj_to_yaml -export plot_airfoil_slices, plot_airfoils, plot_circulation_distribution, - plot_combined_analysis, plot_distribution, plot_geometry, plot_polar_data, - plot_polars, plot_section_polars, save_plot, show_plot +export plot_airfoil_slices, plot_airfoils, plot_combined_analysis, + plot_distribution, plot_geometry, plot_polar_data, plot_polars, + plot_section_polars, save_plot, show_plot -# Backend dispatch types for multi-backend support (Makie and ControlPlots can coexist) -abstract type PlotBackend end -struct MakieBackend <: PlotBackend end -struct ControlPlotsBackend <: PlotBackend end -export PlotBackend, MakieBackend, ControlPlotsBackend - -const _PLOT_BACKEND = Ref{Union{Nothing, PlotBackend}}(nothing) - -""" - set_plot_backend!(backend::PlotBackend) - -Select the active plotting backend when both Makie and ControlPlots are loaded. - -# Example -```julia -set_plot_backend!(MakieBackend()) -set_plot_backend!(ControlPlotsBackend()) -``` -""" -function set_plot_backend!(backend::PlotBackend) - _PLOT_BACKEND[] = backend -end -export set_plot_backend! - -# Generic stubs — extended by MakieExt and ControlPlotsExt with a PlotBackend argument. -# The no-backend-argument wrappers below route through the active backend. -function plot_geometry end -function plot_distribution end -function plot_circulation_distribution end -function plot_polars end -function save_plot end -function show_plot end -function plot_polar_data end -function plot_combined_analysis end -function plot_airfoil_slices end -function plot_airfoils end -function plot_section_polars end - -function _active_backend() - b = _PLOT_BACKEND[] - isnothing(b) && error( - "No plotting backend loaded. Load Makie or ControlPlots first, " * - "or call set_plot_backend!(MakieBackend()) / set_plot_backend!(ControlPlotsBackend()) " * - "when both are loaded." - ) - b -end +# Plotting functions live in the `VortexStepMethodMakieExt` extension, loaded +# once a Makie backend (`GLMakie` or `CairoMakie`) and `MakieControlPlots` are +# available. The declarations below carry the public docstrings; the extension +# provides the implementations. """ plot_geometry(body_aero::BodyAerodynamics, title; kwargs...) Plot wing geometry from different viewpoints and optionally save/show plots. -Routes to the active plotting backend (Makie or ControlPlots). # Arguments - `body_aero`: the [`BodyAerodynamics`](@ref) to plot - `title`: plot title # Keyword arguments -- `data_type`: file extension for saving (default depends on backend) +- `data_type`: file extension for saving (default: `.pdf` for CairoMakie, `.png` otherwise) - `save_path`: path for saving the graphic (default: `nothing`) - `is_save`: whether to save the graphic (default: `false`) - `is_show`: whether to display the graphic (default: `false`) - `view_elevation`: initial view elevation angle in degrees (default: `15`) - `view_azimuth`: initial view azimuth angle in degrees (default: `-120`) -- `use_tex`: use external `pdflatex` for rendering (default: `false`; ignored by Makie) """ -function plot_geometry(body_aero, title; kwargs...) - plot_geometry(body_aero, title, _active_backend(); kwargs...) -end +function plot_geometry end """ plot_distribution(y_coordinates_list, results_list, label_list; kwargs...) Plot spanwise distributions of aerodynamic properties. -Routes to the active plotting backend (Makie or ControlPlots). # Arguments - `y_coordinates_list`: list of spanwise coordinate arrays @@ -140,21 +92,17 @@ Routes to the active plotting backend (Makie or ControlPlots). # Keyword arguments - `title`: plot title (default: `"spanwise_distribution"`) -- `data_type`: file extension for saving (default depends on backend) +- `data_type`: file extension for saving (default: `.pdf` for CairoMakie, `.png` otherwise) - `save_path`: path to save plots (default: `nothing`) - `is_save`: whether to save (default: `false`) - `is_show`: whether to display (default: `true`) -- `use_tex`: use external `pdflatex` for rendering (default: `false`; ignored by Makie) """ -function plot_distribution(y_coordinates_list, results_list, label_list; kwargs...) - plot_distribution(y_coordinates_list, results_list, label_list, _active_backend(); kwargs...) -end +function plot_distribution end """ plot_polars(solver_list, body_aero_list, label_list; kwargs...) Plot polar data comparing different solvers and configurations. -Routes to the active plotting backend (Makie or ControlPlots). # Arguments - `solver_list`: list of aerodynamic solvers @@ -169,22 +117,18 @@ Routes to the active plotting backend (Makie or ControlPlots). - `side_slip`: side slip angle (default: `0.0`) [°] - `v_a`: apparent wind speed magnitude (default: `10.0`) [m/s] - `title`: plot title (default: `"polar"`) -- `data_type`: file extension for saving (default depends on backend) +- `data_type`: file extension for saving (default: `.pdf` for CairoMakie, `.png` otherwise) - `save_path`: path to save plots (default: `nothing`) - `is_save`: whether to save (default: `true`) - `is_show`: whether to display (default: `true`) -- `use_tex`: use external `pdflatex` for rendering (default: `false`; ignored by Makie) - `cl_over_cd`: plot CL/CD vs angle instead of CL vs CD (default: `true`) """ -function plot_polars(solver_list, body_aero_list, label_list; kwargs...) - plot_polars(solver_list, body_aero_list, label_list, _active_backend(); kwargs...) -end +function plot_polars end """ plot_polar_data(body_aero::BodyAerodynamics; kwargs...) Plot polar data (Cl, Cd, Cm) as 3-D surfaces against angle of attack and trailing edge deflection. -Routes to the active plotting backend (Makie or ControlPlots). # Arguments - `body_aero`: the [`BodyAerodynamics`](@ref) to plot (must use `POLAR_MATRICES` aero model) @@ -193,17 +137,14 @@ Routes to the active plotting backend (Makie or ControlPlots). - `alphas`: AoA values in radians (default: `deg2rad.(-5:0.3:25)`) - `delta_tes`: trailing edge deflection angles in radians (default: `deg2rad.(-5:0.3:25)`) - `is_show`: whether to display (default: `true`) -- `use_tex`: use external `pdflatex` for rendering (default: `false`; ignored by Makie) """ -function plot_polar_data(body_aero; kwargs...) - plot_polar_data(body_aero, _active_backend(); kwargs...) -end +function plot_polar_data end """ plot_combined_analysis(solver, body_aero, results; kwargs...) Create a combined analysis by calling `plot_geometry`, `plot_distribution`, and `plot_polars` -in sequence. Routes to the active plotting backend (Makie or ControlPlots). +in sequence. # Arguments - `solver`: solver or vector of solvers @@ -222,45 +163,35 @@ in sequence. Routes to the active plotting backend (Makie or ControlPlots). - `view_elevation`: geometry view elevation in degrees (default: `15`) - `view_azimuth`: geometry view azimuth in degrees (default: `-120`) - `is_show`: whether to display (default: `true`) -- `use_tex`: use external `pdflatex` for rendering (default: `false`; ignored by Makie) - `literature_path_list`: paths to literature CSV files (default: `String[]`) -- `data_type`: file extension for saving (default depends on backend) +- `data_type`: file extension for saving (default: `".png"`) - `save_path`: directory to save files (default: `nothing`) - `is_save`: whether to save (default: `false`) - `cl_over_cd`: plot CL/CD vs angle (default: `true`) """ -function plot_combined_analysis(solver, body_aero, results; kwargs...) - plot_combined_analysis(solver, body_aero, results, _active_backend(); kwargs...) -end +function plot_combined_analysis end """ - plot_airfoils(geometry_file::String; kwargs...) + plot_airfoil_slices(obj_path::String; kwargs...) -Plot every airfoil of a YAML wing geometry in a grid of subfigures. The airfoil -shapes are read from the `.dat` files referenced by the geometry's -`wing_airfoils` (a loaded [`BodyAerodynamics`](@ref) does not retain airfoil -coordinates, so the YAML is the source). Routes to the active plotting backend. +Plot airfoil cross-sections extracted from an OBJ mesh with Kulfan CST fits overlaid. # Arguments -- `geometry_file`: path to a YAML geometry file (e.g. written by [`obj_to_yaml`](@ref)) +- `obj_path`: path to an OBJ file # Keyword arguments -- `n_cols`: number of subfigure columns (default: `3`) +- `n_slices`: number of spanwise slices (default: `5`) - `is_show`: whether to display (default: `true`) -- `is_save`: whether to save (default: `false`) - `save_path`: directory to save the figure (default: `nothing`) -- `data_type`: file extension for saving (default: `".png"`) +- `data_type`: image format (default: `".png"`) """ -function plot_airfoils(geometry_file::String; kwargs...) - plot_airfoils(geometry_file, _active_backend(); kwargs...) -end +function plot_airfoil_slices end """ plot_section_polars(body_aero::BodyAerodynamics, coefficient=:cl; kwargs...) Plot one polar coefficient (`:cl`, `:cd`, or `:cm`) against angle of attack for -every section of a wing using stored `POLAR_VECTORS` data. Routes to the active -plotting backend. +every section of a wing using stored `POLAR_VECTORS` data. # Arguments - `body_aero`: the [`BodyAerodynamics`](@ref) to plot @@ -272,9 +203,30 @@ plotting backend. - `save_path`: directory to save the figure (default: `nothing`) - `data_type`: file extension for saving (default: `".png"`) """ -function plot_section_polars(body_aero, coefficient::Symbol=:cl; kwargs...) - plot_section_polars(body_aero, coefficient, _active_backend(); kwargs...) -end +function plot_section_polars end + +function save_plot end +function show_plot end + +""" + plot_airfoils(geometry_file::String; kwargs...) + +Plot every airfoil of a YAML wing geometry in a grid of subfigures. The airfoil +shapes are read from the `.dat` files referenced by the geometry's +`wing_airfoils` (a loaded [`BodyAerodynamics`](@ref) does not retain airfoil +coordinates, so the YAML is the source). + +# Arguments +- `geometry_file`: path to a YAML geometry file (e.g. written by [`obj_to_yaml`](@ref)) + +# Keyword arguments +- `n_cols`: number of subfigure columns (default: `3`) +- `is_show`: whether to display (default: `true`) +- `is_save`: whether to save (default: `false`) +- `save_path`: directory to save the figure (default: `nothing`) +- `data_type`: file extension for saving (default: `".png"`) +""" +function plot_airfoils end """ const MVec3 = MVector{3, Float64} diff --git a/test/Aqua.jl b/test/Aqua.jl index 4ed9be3c..2c2f3755 100644 --- a/test/Aqua.jl +++ b/test/Aqua.jl @@ -2,8 +2,7 @@ using Aqua, VortexStepMethod, Test @testset "Aqua.jl" begin Aqua.test_all( VortexStepMethod; - stale_deps=(ignore=[:Xfoil, :Timers, :PyCall],), - deps_compat=(ignore=[:PyCall],), + stale_deps=(ignore=[:Xfoil, :Timers],), persistent_tasks=false ) end diff --git a/test/LocalPreferences.toml.default b/test/LocalPreferences.toml.default deleted file mode 100644 index a2ee2658..00000000 --- a/test/LocalPreferences.toml.default +++ /dev/null @@ -1,2 +0,0 @@ -[CondaPkg] -backend = "Null" diff --git a/test/Project.toml b/test/Project.toml index e81a7223..5e1ffca3 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -3,7 +3,6 @@ Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -ControlPlots = "23c2ee80-7a9e-4350-b264-8e670f12517c" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab" DifferentiationInterface = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" @@ -12,8 +11,8 @@ ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" +MakieControlPlots = "6d616b69-6563-4f6e-8472-6f6c706c6f74" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" @@ -30,13 +29,12 @@ Aqua = "0.8" BenchmarkTools = "1" CSV = "0.10" CairoMakie = "0" -ControlPlots = "0.2.5, 0.3" DataFrames = "1.7" Documenter = "1.8" Interpolations = "0.15, 0.16" LinearAlgebra = "1" Logging = "1" -PythonCall = "0.9" +MakieControlPlots = "0.1.5" Random = "1.10.0" Serialization = "1" StaticArrays = "1" diff --git a/test/plotting/test_backend_coexistence.jl b/test/plotting/test_backend_coexistence.jl deleted file mode 100644 index dc149872..00000000 --- a/test/plotting/test_backend_coexistence.jl +++ /dev/null @@ -1,42 +0,0 @@ -# Regression test for https://github.com/OpenSourceAWE/VortexStepMethod.jl/issues/236 -# Verifies that loading both Makie and ControlPlots in the same process: -# (1) does not cause method-redefinition / precompile errors, and -# (2) set_plot_backend! correctly switches which backend the no-backend wrappers route to. - -using CairoMakie -using ControlPlots - -@testset "Backend coexistence (Makie + ControlPlots)" begin - backend_before = VortexStepMethod._PLOT_BACKEND[] - try - # (1) Both extensions must be loaded without errors when both packages are in scope. - # If either `using` above threw a method-redefinition error we would never reach here. - makie_ext = Base.get_extension(VortexStepMethod, :VortexStepMethodMakieExt) - cp_ext = Base.get_extension(VortexStepMethod, :VortexStepMethodControlPlotsExt) - @test makie_ext !== nothing - - # The ControlPlots extension depends on PythonCall/matplotlib, which can - # fail to load (e.g. segfault during precompilation) on some platforms - # such as macOS-aarch64. Skip the ControlPlots-specific checks when the - # extension is unavailable rather than failing the whole suite. - if cp_ext === nothing - @test_skip "VortexStepMethodControlPlotsExt unavailable (ControlPlots failed to load)" - return - end - @test cp_ext !== nothing - - # (2) set_plot_backend! correctly switches the active backend. - set_plot_backend!(ControlPlotsBackend()) - @test VortexStepMethod._PLOT_BACKEND[] isa VortexStepMethod.ControlPlotsBackend - - set_plot_backend!(MakieBackend()) - @test VortexStepMethod._PLOT_BACKEND[] isa VortexStepMethod.MakieBackend - - # Round-trip: switch back to ControlPlots. - set_plot_backend!(ControlPlotsBackend()) - @test VortexStepMethod._PLOT_BACKEND[] isa VortexStepMethod.ControlPlotsBackend - finally - # Restore whatever backend was active before this testset ran. - VortexStepMethod._PLOT_BACKEND[] = backend_before - end -end diff --git a/test/plotting/test_plotting.jl b/test/plotting/test_plotting.jl index b779fe15..17ab85bd 100644 --- a/test/plotting/test_plotting.jl +++ b/test/plotting/test_plotting.jl @@ -13,21 +13,16 @@ module FakeMakieReturnsOtherModule import Base current_backend() = Base end -backend = if "plot-controlplots" in ARGS - using ControlPlots - import ControlPlots: plt - using PythonCall: pyconvert - "ControlPlots" -else - using CairoMakie - "Makie" -end +using CairoMakie +using MakieControlPlots +# MakieControlPlots activates GLMakie on load; force CairoMakie so headless +# figure saving uses the software backend. +CairoMakie.activate!() using VortexStepMethod using Test -const makie_ext = backend == "Makie" ? - Base.get_extension(VortexStepMethod, :VortexStepMethodMakieExt) : nothing +const makie_ext = Base.get_extension(VortexStepMethod, :VortexStepMethodMakieExt) # Resolve repo data directory for ram air kite assets _ram_data_dir = joinpath(dirname(dirname(@__DIR__)), @@ -88,7 +83,7 @@ function create_body_aero() body_aero end -@testset "Plotting ($backend)" begin +@testset "Plotting (Makie)" begin save_dir = tempdir() body_aero = create_body_aero() @@ -99,21 +94,11 @@ end save_path=save_dir, is_save=true, is_show=false) - if backend == "Makie" - @test fig isa Figure - else - @test fig !== nothing - end + @test fig isa Figure - if backend == "Makie" - @test hasmethod(VortexStepMethod.show_plot, Tuple{Figure}) - @test_throws MethodError VortexStepMethod.show_plot(nothing) - @test_nowarn VortexStepMethod.show_plot(fig) - else - FigType = plt.Figure - @test hasmethod(VortexStepMethod.show_plot, Tuple{FigType}) - @test_throws MethodError VortexStepMethod.show_plot(nothing) - end + @test hasmethod(VortexStepMethod.show_plot, Tuple{Figure}) + @test_throws MethodError VortexStepMethod.show_plot(nothing) + @test_nowarn VortexStepMethod.show_plot(fig) @test isfile(joinpath(save_dir, "Rectangular_wing_geometry_angled_view.png")) @@ -151,11 +136,7 @@ end title="Spanwise Distributions", is_show=false ) - if backend == "Makie" - @test fig isa Figure - else - @test fig !== nothing - end + @test fig isa Figure # Plot polar curves v_a = 20.0 @@ -173,11 +154,7 @@ end is_save=true, is_show=false ) - if backend == "Makie" - @test fig isa Figure - else - @test fig !== nothing - end + @test fig isa Figure @test isfile(joinpath(save_dir, "Rectangular_Wing_Polars.png")) safe_rm(joinpath(save_dir, "Rectangular_Wing_Polars.png")) @@ -194,11 +171,7 @@ end is_show=false, cl_over_cd=false ) - if backend == "Makie" - @test fig isa Figure - else - @test fig !== nothing - end + @test fig isa Figure # Plot combined analysis with cl_over_cd fig = plot_combined_analysis( @@ -212,11 +185,7 @@ end is_show=false, cl_over_cd=true ) - if backend == "Makie" - @test fig isa Figure - else - @test fig !== nothing - end + @test fig isa Figure # Plot combined analysis with cl_over_cd=false fig = plot_combined_analysis( @@ -230,30 +199,18 @@ end is_show=false, cl_over_cd=false ) - if backend == "Makie" - @test fig isa Figure - else - @test fig !== nothing - end + @test fig isa Figure # Test polar data plotting body_aero = BodyAerodynamics([ram_wing]) fig = plot_polar_data(body_aero; is_show=false) - if backend == "Makie" - @test fig isa Figure - else - @test fig !== nothing - end + @test fig isa Figure fig_rect = plot_polar_data(body_aero; alphas=collect(deg2rad.(-5:1.0:15)), delta_tes=collect(deg2rad.(-3:1.0:5)), is_show=false) - if backend == "Makie" - @test fig_rect isa Figure - else - @test fig_rect !== nothing - end + @test fig_rect isa Figure # Tests for both backends body_aero_empty = create_body_aero() @@ -302,25 +259,7 @@ end safe_rm(literature_csv) end - # CP-specific tests (DPI, matplotlib internals) - if backend == "ControlPlots" - # `get_dpi()` returns a Python float; convert to a Julia Float64 so the - # comparisons below evaluate to a Julia `Bool` rather than a `Py` object. - get_dpi(fig) = pyconvert(Float64, fig.get_dpi()) - - fig_dpi = plt.figure() - default_dpi = get_dpi(fig_dpi) - @test default_dpi != 173 - - show_plot(fig_dpi; dpi=173) - @test get_dpi(fig_dpi) == 173 - - show_plot(fig_dpi) - @test get_dpi(fig_dpi) == 130 - plt.close(fig_dpi) - end - - # Unit tests for shared extract_literature_polar_data (both backends) + # Unit tests for shared extract_literature_polar_data using DelimitedFiles # Tuple parsing branch (e.g. readdlm(...; header=true) shape) @@ -458,8 +397,7 @@ end safe_rm(no_cm_path) # Tests for save_plot function - if backend == "Makie" - @testset "_active_backend_prefers_vector_output" begin + @testset "_active_backend_prefers_vector_output" begin @test makie_ext !== nothing active_backend_prefers_vector_output = @@ -538,6 +476,43 @@ end # Test 8: save_plot raises error when save_path is nothing @test_throws ArgumentError VortexStepMethod.save_plot(fig, nothing, "test_title", data_type=".png") +end + +@testset "plot_section_polars and plot_airfoils" begin + # Build a wing with POLAR_VECTORS sections for plot_section_polars + alpha = deg2rad.(collect(-5.0:1.0:15.0)) + cl = 0.1 .* rad2deg.(alpha) + cd = fill(0.02, length(alpha)) + cm = fill(-0.05, length(alpha)) + aero_data = (alpha, cl, cd, cm) + sec_wing = Wing(4, spanwise_distribution=LINEAR) + add_section!(sec_wing, [0.0, 1.0, 0.0], [1.0, 1.0, 0.0], POLAR_VECTORS, aero_data) + add_section!(sec_wing, [0.0, -1.0, 0.0], [1.0, -1.0, 0.0], POLAR_VECTORS, aero_data) + refine!(sec_wing) + sec_body = BodyAerodynamics([sec_wing]) + + plt = plot_section_polars(sec_body, :cl; is_show=false) + @test plt !== nothing + @test_throws ArgumentError plot_section_polars(sec_body, :bad; is_show=false) + + body_inviscid = create_body_aero() + @test_throws Exception plot_section_polars(body_inviscid; is_show=false) + + # plot_airfoils from a YAML referencing a .dat file + foil = joinpath(tempdir(), "ram_air_kite_foil.dat") + cp(joinpath(_ram_data_dir, "ram_air_kite_foil.dat"), foil; force=true) + yaml_path = joinpath(tempdir(), "airfoils_test.yaml") + open(yaml_path, "w") do io + write(io, """ + wing_airfoils: + headers: [airfoil_id, info_dict] + data: + - [1, {dat_file: "$foil"}] + - [2, {dat_file: "$foil"}] + """) end + fig_af = plot_airfoils(yaml_path; is_show=false) + @test fig_af isa Figure + safe_rm(yaml_path) end nothing diff --git a/test/runtests.jl b/test/runtests.jl index 027b4af7..b1740adf 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,13 +4,10 @@ using Test, VortexStepMethod cd(@__DIR__) # ensure we're in test/ no matter how tests are launched include("test_data_utils.jl") -# Filter special args from pattern matching -const test_patterns = filter(a -> a != "plot-controlplots", ARGS) +const test_patterns = ARGS println("Running tests...") -if "plot-controlplots" in ARGS - println("Running plotting tests with ControlPlots backend") -elseif !isempty(test_patterns) +if !isempty(test_patterns) println("Filtering tests matching: ", test_patterns) end @@ -34,34 +31,29 @@ const build_is_production_build = let v = get(ENV, build_is_production_build_env end::Bool function include_selected_tests() - if "plot-controlplots" in ARGS - include("plotting/test_plotting.jl") - else - if build_is_production_build && should_run_test("bench") - include("bench.jl") - end - should_run_test("body_aerodynamics/test_body_aerodynamics.jl") && include("body_aerodynamics/test_body_aerodynamics.jl") - should_run_test("body_aerodynamics/test_results.jl") && include("body_aerodynamics/test_results.jl") - should_run_test("test_refinement_validation.jl") && include("test_refinement_validation.jl") - should_run_test("filament/test_bound_filament.jl") && include("filament/test_bound_filament.jl") - should_run_test("filament/test_semi_infinite_filament.jl") && include("filament/test_semi_infinite_filament.jl") - should_run_test("panel/test_panel.jl") && include("panel/test_panel.jl") - should_run_test("plotting/test_plotting.jl") && include("plotting/test_plotting.jl") - should_run_test("plotting/test_backend_coexistence.jl") && include("plotting/test_backend_coexistence.jl") - should_run_test("polars/test_polars.jl") && include("polars/test_polars.jl") - should_run_test("ram_geometry/test_kite_geometry.jl") && include("ram_geometry/test_kite_geometry.jl") - should_run_test("neuralfoil/test_neuralfoil.jl") && include("neuralfoil/test_neuralfoil.jl") - should_run_test("settings/test_settings.jl") && include("settings/test_settings.jl") - should_run_test("solver/test_solver.jl") && include("solver/test_solver.jl") - should_run_test("solver/test_forwarddiff.jl") && include("solver/test_forwarddiff.jl") - should_run_test("solver/test_unrefined_dist.jl") && include("solver/test_unrefined_dist.jl") - should_run_test("VortexStepMethod/test_VortexStepMethod.jl") && include("VortexStepMethod/test_VortexStepMethod.jl") - should_run_test("wake/test_wake.jl") && include("wake/test_wake.jl") - should_run_test("wing_geometry/test_wing_geometry.jl") && include("wing_geometry/test_wing_geometry.jl") - should_run_test("wing_geometry/test_billowing.jl") && include("wing_geometry/test_billowing.jl") - should_run_test("yaml_geometry/test_yaml_geometry.jl") && include("yaml_geometry/test_yaml_geometry.jl") - should_run_test("Aqua.jl") && include("Aqua.jl") + if build_is_production_build && should_run_test("bench") + include("bench.jl") end + should_run_test("body_aerodynamics/test_body_aerodynamics.jl") && include("body_aerodynamics/test_body_aerodynamics.jl") + should_run_test("body_aerodynamics/test_results.jl") && include("body_aerodynamics/test_results.jl") + should_run_test("test_refinement_validation.jl") && include("test_refinement_validation.jl") + should_run_test("filament/test_bound_filament.jl") && include("filament/test_bound_filament.jl") + should_run_test("filament/test_semi_infinite_filament.jl") && include("filament/test_semi_infinite_filament.jl") + should_run_test("panel/test_panel.jl") && include("panel/test_panel.jl") + should_run_test("plotting/test_plotting.jl") && include("plotting/test_plotting.jl") + should_run_test("polars/test_polars.jl") && include("polars/test_polars.jl") + should_run_test("ram_geometry/test_kite_geometry.jl") && include("ram_geometry/test_kite_geometry.jl") + should_run_test("neuralfoil/test_neuralfoil.jl") && include("neuralfoil/test_neuralfoil.jl") + should_run_test("settings/test_settings.jl") && include("settings/test_settings.jl") + should_run_test("solver/test_solver.jl") && include("solver/test_solver.jl") + should_run_test("solver/test_forwarddiff.jl") && include("solver/test_forwarddiff.jl") + should_run_test("solver/test_unrefined_dist.jl") && include("solver/test_unrefined_dist.jl") + should_run_test("VortexStepMethod/test_VortexStepMethod.jl") && include("VortexStepMethod/test_VortexStepMethod.jl") + should_run_test("wake/test_wake.jl") && include("wake/test_wake.jl") + should_run_test("wing_geometry/test_wing_geometry.jl") && include("wing_geometry/test_wing_geometry.jl") + should_run_test("wing_geometry/test_billowing.jl") && include("wing_geometry/test_billowing.jl") + should_run_test("yaml_geometry/test_yaml_geometry.jl") && include("yaml_geometry/test_yaml_geometry.jl") + should_run_test("Aqua.jl") && include("Aqua.jl") end @testset verbose = true "Testing VortexStepMethod..." begin diff --git a/test/test_setup.sh b/test/test_setup.sh index be620253..57e4f274 100755 --- a/test/test_setup.sh +++ b/test/test_setup.sh @@ -58,7 +58,7 @@ fi for f in bench.jl rectangular_wing.jl V3_kite.jl \ pyramid_model.jl ram_air_kite.jl stall_model.jl; do if ! grep -q "using GLMakie" "examples/$f" && \ - ! grep -q "using ControlPlots" "examples/$f"; then + ! grep -q "using MakieControlPlots" "examples/$f"; then pass "$f is backend-agnostic" else fail "$f is backend-agnostic"