diff --git a/.github/workflows/Documenter.yml b/.github/workflows/Documenter.yml index 56d3abf2..1eb5ef50 100644 --- a/.github/workflows/Documenter.yml +++ b/.github/workflows/Documenter.yml @@ -21,7 +21,11 @@ jobs: version: '1.10' show-versioninfo: true - name: Install dependencies - run: julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()' + run: | + julia --color=yes --project -e 'using Pkg; Pkg.instantiate()' + julia --color=yes --project -e 'using Pkg; Pkg.precompile()' + julia --color=yes --project=docs/ -e 'using Pkg; Pkg.instantiate()' + julia --color=yes --project=docs/ -e 'using Pkg; Pkg.precompile()' - name: Build and deploy env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token diff --git a/.gitignore b/.gitignore index f6bdc028..353c5651 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,7 @@ deps/src/ # Build artifacts for creating documentation generated by the Documenter package docs/build/ docs/site/ -docs/Manifest.toml +docs/src/literated/ # File generated by Pkg, the package manager, based on a corresponding Project.toml # It records a fixed state of all packages used by the project. As such, it should not be @@ -31,3 +31,4 @@ docs/Manifest.toml *.swp *.svg *.gif +*.zip diff --git a/Manifest.toml b/Manifest.toml index a824d739..de7f1d1e 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,27 +2,45 @@ julia_version = "1.10.2" manifest_format = "2.0" -project_hash = "8b7f9f42e5e87056d8c4e8c3f7c0d180e1eaa34b" +project_hash = "b77431445966c6920fb04c6ab1b5a7dbdaa668aa" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] [deps.AbstractFFTs.extensions] AbstractFFTsChainRulesCoreExt = "ChainRulesCore" AbstractFFTsTestExt = "Test" - [deps.AbstractFFTs.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown", "Test"] +git-tree-sha1 = "c0d491ef0b135fd7d63cbc6404286bc633329425" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.36" + + [deps.Accessors.extensions] + AccessorsAxisKeysExt = "AxisKeys" + AccessorsIntervalSetsExt = "IntervalSets" + AccessorsStaticArraysExt = "StaticArrays" + AccessorsStructArraysExt = "StructArrays" + AccessorsUnitfulExt = "Unitful" + + [deps.Accessors.weakdeps] + AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + Requires = "ae029012-a4dd-5104-9daa-d747884805df" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "0fb305e0253fd4e833d486914367a2ee2c2e78d0" +git-tree-sha1 = "6a55b747d1812e699320963ffde36f1ebdda4099" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.0.1" +version = "4.0.4" weakdeps = ["StaticArrays"] [deps.Adapt.extensions] @@ -33,16 +51,18 @@ uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" version = "1.1.1" [[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "c5aeb516a84459e0318a02507d2261edad97eb75" +deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "44691067188f6bd1b2289552a23e4b7572f4528d" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.7.1" +version = "7.9.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceChainRulesExt = "ChainRules" ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" ArrayInterfaceTrackerExt = "Tracker" @@ -50,7 +70,9 @@ version = "7.7.1" BandedMatrices = "aae01518-5342-5314-be14-df237901396f" BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" @@ -65,9 +87,9 @@ version = "0.1.0" [[deps.BFloat16s]] deps = ["LinearAlgebra", "Printf", "Random", "Test"] -git-tree-sha1 = "dbf84058d0a8cbbadee18d25cf606934b22d7c66" +git-tree-sha1 = "2c7cc21e8678eff479978a0a2ef5ce2f51b63dff" uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" -version = "0.4.2" +version = "0.5.0" [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" @@ -105,15 +127,12 @@ deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_ git-tree-sha1 = "baa8ea7a1ea63316fa3feb454635215773c9c845" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" version = "5.2.0" +weakdeps = ["ChainRulesCore", "SpecialFunctions"] [deps.CUDA.extensions] ChainRulesCoreExt = "ChainRulesCore" SpecialFunctionsExt = "SpecialFunctions" - [deps.CUDA.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" @@ -132,6 +151,22 @@ git-tree-sha1 = "8e25c009d2bf16c2c31a70a6e9e8939f7325cc84" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" version = "0.11.1+0" +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.23.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "e25e43451edd449c3dcc899bd447983d7b76a59f" +uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +version = "0.1.0" + [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" @@ -156,6 +191,17 @@ git-tree-sha1 = "d7d7b58e149f19c322840a50d1bc20e8c23addb4" uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" version = "0.3.5" +[[deps.CommonSolve]] +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.4" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + [[deps.Compat]] deps = ["TOML", "UUIDs"] git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" @@ -171,17 +217,26 @@ deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" version = "1.1.0+0" +[[deps.CompositionsBase]] +git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" +uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" +version = "0.1.2" +weakdeps = ["InverseFunctions"] + + [deps.CompositionsBase.extensions] + CompositionsBaseInverseFunctionsExt = "InverseFunctions" + [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] -git-tree-sha1 = "9c4708e3ed2b799e6124b5673a712dda0b596a9b" +git-tree-sha1 = "6cbbd4d241d7e6579ab354737f4dd95ca43946e1" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.3.1" +version = "2.4.1" [[deps.ConstructionBase]] deps = ["LinearAlgebra"] -git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" +git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.4" +version = "1.5.5" [deps.ConstructionBase.extensions] ConstructionBaseIntervalSetsExt = "IntervalSets" @@ -220,16 +275,16 @@ uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" version = "0.7.13" [[deps.DataFrames]] -deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] -git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" +deps = ["Compat", "DataAPI", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SnoopPrecompile", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "aa51303df86f8626a962fccb878430cdb0a97eee" uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "1.6.1" +version = "1.5.0" [[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "1fb174f0d48fe7d142e1109a10636bc1d14f5ac2" +deps = ["InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "88d48e133e6d3dd68183309877eac74393daa7eb" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.17" +version = "0.17.20" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -240,6 +295,18 @@ version = "1.0.0" deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + [[deps.DiskArrays]] deps = ["LRUCache", "OffsetArrays"] git-tree-sha1 = "ef25c513cad08d7ebbed158c91768ae32f308336" @@ -251,15 +318,12 @@ deps = ["LinearAlgebra", "Statistics", "StatsAPI"] git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" version = "0.10.11" +weakdeps = ["ChainRulesCore", "SparseArrays"] [deps.Distances.extensions] DistancesChainRulesCoreExt = "ChainRulesCore" DistancesSparseArraysExt = "SparseArrays" - [deps.Distances.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - [[deps.Distributed]] deps = ["Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" @@ -305,9 +369,9 @@ version = "3.3.10+0" [[deps.FileIO]] deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "c5c28c245101bd59154f649e19b038d15901b5dc" +git-tree-sha1 = "82d8afa92ecf4b52d78d869f038ebfb881267322" uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.16.2" +version = "1.16.3" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" @@ -318,6 +382,16 @@ git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" version = "0.8.4" +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.36" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + [[deps.Future]] deps = ["Random"] uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" @@ -352,9 +426,9 @@ version = "1.3.1" [[deps.GnuTLS_jll]] deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl", "Nettle_jll", "P11Kit_jll", "Zlib_jll"] -git-tree-sha1 = "f3c0936dd685d57fa0b1eee7dbebf382b969ea63" +git-tree-sha1 = "383db7d3f900f4c1f47a8a04115b053c095e48d3" uuid = "0951126a-58fd-58f1-b5b3-b08c7c4a876d" -version = "3.8.3+0" +version = "3.8.4+0" [[deps.HDF5_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] @@ -364,9 +438,9 @@ version = "1.14.2+1" [[deps.HTTP]] deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "ac7b73d562b8f4287c3b67b4c66a5395a19c1ae8" +git-tree-sha1 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.2" +version = "1.10.5" [[deps.Hwloc_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -401,6 +475,16 @@ version = "2024.0.2+0" deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +[[deps.InverseFunctions]] +deps = ["Test"] +git-tree-sha1 = "896385798a8d49a255c398bd49162062e4a4c435" +uuid = "3587e190-3f89-42d0-90ee-14403ec27112" +version = "0.1.13" +weakdeps = ["Dates"] + + [deps.InverseFunctions.extensions] + DatesExt = "Dates" + [[deps.InvertedIndices]] git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" @@ -454,9 +538,9 @@ version = "0.2.1+0" [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "c7753cc3febe006708ce6798482004241f7d890b" +git-tree-sha1 = "ed7167240f40e62d97c1f5f7735dea6de3cc5c49" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.17" +version = "0.9.18" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -466,9 +550,9 @@ version = "0.9.17" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "ddab4d40513bce53c8e3157825e245224f74fae7" +git-tree-sha1 = "839c82932db86740ae729779e610f07a1640be9a" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "6.6.0" +version = "6.6.3" weakdeps = ["BFloat16s"] [deps.LLVM.extensions] @@ -657,9 +741,9 @@ version = "2023.1.10" [[deps.NCDatasets]] deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] -git-tree-sha1 = "98ca95cf41116a24e46dc9a06fa22b923e8411b7" +git-tree-sha1 = "d40d24d12f710c39d3a66be99c567ce0032f28a7" uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.14.2" +version = "0.14.3" [[deps.NVTX]] deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] @@ -673,6 +757,12 @@ git-tree-sha1 = "ce3269ed42816bf18d500c9f63418d4b0d9f5a3b" uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" version = "3.1.0+2" +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + [[deps.NetCDF_jll]] deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "OpenMPI_jll", "XML2_jll", "Zlib_jll", "Zstd_jll", "libzip_jll"] git-tree-sha1 = "a8af1798e4eb9ff768ce7fdefc0e957097793f15" @@ -691,9 +781,11 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "4672af7242405313743af45168bfce3d87b84b2c" +git-tree-sha1 = "82eddd14528a13419be8b75da9daa23fb2a14363" +repo-rev = "main" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.11" +version = "0.90.12" [deps.Oceananigans.extensions] OceananigansEnzymeExt = "Enzyme" @@ -728,15 +820,15 @@ version = "5.0.2+0" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "51901a49222b09e3743c65b8847687ae5fc78eb2" +git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.1" +version = "1.4.2" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "60e3045590bd104a16fefb12836c00c0ef8c7f8c" +git-tree-sha1 = "3da7367955dcc5c54c1ba4d402ccdc09a1a3e046" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.13+0" +version = "3.0.13+1" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -812,15 +904,15 @@ version = "1.4.3" [[deps.PrecompileTools]] deps = ["Preferences"] -git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.2.0" +version = "1.2.1" [[deps.Preferences]] deps = ["TOML"] -git-tree-sha1 = "9e8fed0505b0c15b4c1295fd59ea47b411c019cf" +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.2" +version = "1.4.3" [[deps.PrettyTables]] deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] @@ -887,6 +979,30 @@ git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "1.3.0" +[[deps.RootSolvers]] +deps = ["ForwardDiff"] +git-tree-sha1 = "a87fd671f7a298de98f2f3c5a9cd9890714eb9dd" +uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" +version = "0.4.2" + +[[deps.Roots]] +deps = ["Accessors", "ChainRulesCore", "CommonSolve", "Printf"] +git-tree-sha1 = "1ab580704784260ee5f45bffac810b152922747b" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "2.1.5" + + [deps.Roots.extensions] + RootsForwardDiffExt = "ForwardDiff" + RootsIntervalRootFindingExt = "IntervalRootFinding" + RootsSymPyExt = "SymPy" + RootsSymPyPythonCallExt = "SymPyPythonCall" + + [deps.Roots.weakdeps] + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" + SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" + SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" + [[deps.Rotations]] deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] git-tree-sha1 = "2a0a5d8569f481ff8840e3b7c84bbf188db6a3fe" @@ -926,6 +1042,12 @@ git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" version = "1.1.0" +[[deps.SnoopPrecompile]] +deps = ["Preferences"] +git-tree-sha1 = "e760a70afdcd461cf01a575947738d359234665c" +uuid = "66db9d55-30c0-4569-8b51-7e840670fc0c" +version = "1.0.3" + [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" @@ -945,13 +1067,11 @@ deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_j git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" uuid = "276daf66-3868-5448-9aa4-cd146d93841b" version = "2.3.1" +weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - [deps.SpecialFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - [[deps.Static]] deps = ["IfElse"] git-tree-sha1 = "d2fdac9ff3906e27f7a618d47b676941baa6c80c" @@ -974,15 +1094,12 @@ deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" uuid = "90137ffa-7385-5640-81b9-e52037218182" version = "1.9.3" +weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] StaticArraysChainRulesCoreExt = "ChainRulesCore" StaticArraysStatisticsExt = "Statistics" - [deps.StaticArrays.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - [[deps.StaticArraysCore]] git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" @@ -1054,6 +1171,20 @@ deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.1+1" +[[deps.SurfaceFluxes]] +deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] +git-tree-sha1 = "c2c43206af0d861e018f746286d1af036aa7bc3a" +repo-rev = "glw/generalize-parameters" +repo-url = "https://github.com/glwagner/SurfaceFluxes.jl.git" +uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +version = "0.9.2" + + [deps.SurfaceFluxes.extensions] + CreateParametersExt = "CLIMAParameters" + + [deps.SurfaceFluxes.weakdeps] + CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" + [[deps.TOML]] deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" @@ -1092,6 +1223,18 @@ version = "0.16.0" deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +[[deps.Thermodynamics]] +deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] +git-tree-sha1 = "deac04ad36638b10fde82470d5f128419f627e9a" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.12.6" + + [deps.Thermodynamics.extensions] + CreateParametersExt = "ClimaParams" + + [deps.Thermodynamics.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" + [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" @@ -1099,9 +1242,9 @@ uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" version = "0.5.23" [[deps.TranscodingStreams]] -git-tree-sha1 = "54194d92959d8ebaa8e26227dbe3cdefcdcd594f" +git-tree-sha1 = "71509f04d045ec714c4748c785a59045c3736349" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.3" +version = "0.10.7" weakdeps = ["Random", "Test"] [deps.TranscodingStreams.extensions] @@ -1142,15 +1285,15 @@ version = "1.3.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "07e470dabc5a6a4254ffebc29a1b3fc01464e105" +git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.12.5+0" +version = "2.12.6+0" [[deps.XZ_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "37195dcb94a5970397ad425b95a9a26d0befce3a" +git-tree-sha1 = "ac88fb95ae6447c8dda6a5503f3bafd496ae8632" uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" -version = "5.6.0+0" +version = "5.4.6+0" [[deps.Zlib_jll]] deps = ["Libdl"] @@ -1159,9 +1302,9 @@ version = "1.2.13+1" [[deps.Zstd_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "49ce682769cd5de6c72dcf1b94ed7790cd08974c" +git-tree-sha1 = "e678132f07ddb5bfa46857f0d7620fb9be675d3b" uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" -version = "1.5.5+0" +version = "1.5.6+0" [[deps.libaec_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] diff --git a/Project.toml b/Project.toml index fd259802..32e35584 100644 --- a/Project.toml +++ b/Project.toml @@ -5,9 +5,12 @@ authors = ["Climate Modeling Alliance and contributors"] version = "0.2.0" [deps] +Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" +ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" CubicSplines = "9c784101-8907-5a6d-9be6-98f00873c89b" DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" @@ -15,10 +18,14 @@ NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +SurfaceFluxes = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" [compat] CUDA = "4, 5" +ClimaSeaIce = "0.1" CubicSplines = "0.2" DataDeps = "0.7" Downloads = "1.6" @@ -26,7 +33,7 @@ JLD2 = "0.4" KernelAbstractions = "0.9" NCDatasets = "0.12, 0.13, 0.14" Oceananigans = "0.90.10" -SeawaterPolynomials = "0.3" +SeawaterPolynomials = "0.3.4" Statistics = "1.9" julia = "1.9" diff --git a/docs/Manifest.toml b/docs/Manifest.toml new file mode 100644 index 00000000..60dfad2c --- /dev/null +++ b/docs/Manifest.toml @@ -0,0 +1,2256 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.2" +manifest_format = "2.0" +project_hash = "2b1abab6f384a62f893ca939d86c6775549fc57e" + +[[deps.ANSIColoredPrinters]] +git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" +uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9" +version = "0.0.1" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractLattices]] +git-tree-sha1 = "222ee9e50b98f51b5d78feb93dd928880df35f06" +uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" +version = "0.3.0" + +[[deps.AbstractTrees]] +git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.5" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "6a55b747d1812e699320963ffde36f1ebdda4099" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.0.4" +weakdeps = ["StaticArrays"] + + [deps.Adapt.extensions] + AdaptStaticArraysExt = "StaticArrays" + +[[deps.Animations]] +deps = ["Colors"] +git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" +uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" +version = "0.4.1" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "44691067188f6bd1b2289552a23e4b7572f4528d" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.9.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "0.1.0" + +[[deps.Automa]] +deps = ["PrecompileTools", "TranscodingStreams"] +git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" +uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" +version = "1.0.3" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.1.0" + +[[deps.AxisArrays]] +deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] +git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.4.7" + +[[deps.BFloat16s]] +deps = ["LinearAlgebra", "Printf", "Random", "Test"] +git-tree-sha1 = "2c7cc21e8678eff479978a0a2ef5ce2f51b63dff" +uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" +version = "0.5.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BitFlags]] +git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.8" + +[[deps.Blosc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "19b98ee7e3db3b4eff74c5c9c72bf32144e24f10" +uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" +version = "1.21.5+0" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+1" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CFTime]] +deps = ["Dates", "Printf"] +git-tree-sha1 = "5afb5c5ba2688ca43a9ad2e5a91cbb93921ccfa1" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.1.3" + +[[deps.CRC32c]] +uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" + +[[deps.CRlibm]] +deps = ["CRlibm_jll"] +git-tree-sha1 = "32abd86e3c2025db5172aa182b982debed519834" +uuid = "96374032-68de-5a5b-8d9e-752f78720389" +version = "1.0.1" + +[[deps.CRlibm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" +uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" +version = "1.0.1+0" + +[[deps.CUDA]] +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics"] +git-tree-sha1 = "baa8ea7a1ea63316fa3feb454635215773c9c845" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.2.0" +weakdeps = ["ChainRulesCore", "SpecialFunctions"] + + [deps.CUDA.extensions] + ChainRulesCoreExt = "ChainRulesCore" + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.CUDA_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.7.0+1" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "2cb12f6b2209f40a4b8967697689a47c50485490" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.2.3" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "8e25c009d2bf16c2c31a70a6e9e8939f7325cc84" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.11.1+0" + +[[deps.Cairo]] +deps = ["Cairo_jll", "Colors", "Glib_jll", "Graphics", "Libdl", "Pango_jll"] +git-tree-sha1 = "d0b3f8b4ad16cb0a2988c6788646a5e6a17b6b1b" +uuid = "159f3aea-2a34-519c-b102-8c37f9878175" +version = "1.0.5" + +[[deps.CairoMakie]] +deps = ["Base64", "Cairo", "Colors", "FFTW", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools", "SHA"] +git-tree-sha1 = "5e21a254d82c64b1a4ed9dbdc7e87c5d9cf4a686" +uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" +version = "0.10.12" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "a4c43f59baa34011e303e76f5c8c91bf58415aaf" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.0+1" + +[[deps.Calculus]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.5.1" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.23.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.4" + +[[deps.ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.24.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.4" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.10" + +[[deps.Combinatorics]] +git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.2" + +[[deps.CommonDataModel]] +deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] +git-tree-sha1 = "d7d7b58e149f19c322840a50d1bc20e8c23addb4" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.3.5" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.14.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.0+0" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "6cbbd4d241d7e6579ab354737f4dd95ca43946e1" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.4.1" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.5" +weakdeps = ["IntervalSets", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.CubedSphere]] +deps = ["Elliptic", "FFTW", "Printf", "ProgressBars", "SpecialFunctions", "TaylorSeries", "Test"] +git-tree-sha1 = "10134667d7d3569b191a65801514271b8a93b292" +uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" +version = "0.2.5" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataDeps]] +deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] +git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" +uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +version = "0.7.13" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.6.1" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "0f4b5d62a88d8f59003e43c25a8a90de9eb76317" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.18" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DelaunayTriangulation]] +deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] +git-tree-sha1 = "d4e9dc4c6106b8d44e40cd4faf8261a678552c7c" +uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" +version = "0.8.12" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DiskArrays]] +deps = ["LRUCache", "OffsetArrays"] +git-tree-sha1 = "ef25c513cad08d7ebbed158c91768ae32f308336" +uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" +version = "0.3.23" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.11" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.Distributions]] +deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "7c302d7a5fec5214eb8a5a4c466dcf7a51fcf169" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.107" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.3" + +[[deps.Documenter]] +deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"] +git-tree-sha1 = "4a40af50e8b24333b9ec6892546d9ca5724228eb" +uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +version = "1.3.0" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.DualNumbers]] +deps = ["Calculus", "NaNMath", "SpecialFunctions"] +git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" +uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" +version = "0.6.8" + +[[deps.EarCut_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" +uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" +version = "2.2.4+0" + +[[deps.Elliptic]] +git-tree-sha1 = "71c79e77221ab3a29918aaf6db4f217b89138608" +uuid = "b305315f-e792-5b7a-8f41-49f472929428" +version = "1.0.1" + +[[deps.EnumX]] +git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.4" + +[[deps.ErrorfreeArithmetic]] +git-tree-sha1 = "d6863c556f1142a061532e79f611aa46be201686" +uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" +version = "0.5.2" + +[[deps.ExactPredicates]] +deps = ["IntervalArithmetic", "Random", "StaticArraysCore", "Test"] +git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" +uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" +version = "2.2.5" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.10" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.5.0+0" + +[[deps.ExprTools]] +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" +uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" +version = "0.1.10" + +[[deps.Extents]] +git-tree-sha1 = "2140cd04483da90b2da7f99b2add0750504fc39c" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.2" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "ab3f7e1819dba9434a3a5126510c8fda3a4e7000" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "6.1.1+0" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "4820348781ae578893311153d69049a93d05f39d" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.8.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.10+0" + +[[deps.FastRounding]] +deps = ["ErrorfreeArithmetic", "LinearAlgebra"] +git-tree-sha1 = "6344aa18f654196be82e62816935225b3b9abe44" +uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" +version = "0.3.1" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "82d8afa92ecf4b52d78d869f038ebfb881267322" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.16.3" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "bfe82a708416cf00b73a3198db0859c82f741558" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.10.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "bc0c5092d6caaea112d3c8e3b238d61563c58d5f" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.23.0" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.4" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] +git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.93+0" + +[[deps.Formatting]] +deps = ["Logging", "Printf"] +git-tree-sha1 = "fb409abab2caf118986fc597ba84b50cbaf00b87" +uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" +version = "0.4.3" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.36" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FreeType]] +deps = ["CEnum", "FreeType2_jll"] +git-tree-sha1 = "907369da0f8e80728ab49c1c7e09327bf0d6d999" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "4.1.1" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.1+0" + +[[deps.FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] +git-tree-sha1 = "055626e1a35f6771fe99060e835b72ca61a52621" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.10.1" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.10+0" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GMP_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "781609d7-10c4-51f6-84f2-b8444358ff6d" +version = "6.2.1+6" + +[[deps.GPUArrays]] +deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] +git-tree-sha1 = "47e4686ec18a9620850bad110b79966132f14283" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "10.0.2" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.6" + +[[deps.GPUCompiler]] +deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] +git-tree-sha1 = "a846f297ce9d09ccba02ead0cae70690e072a119" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "0.25.0" + +[[deps.GeoInterface]] +deps = ["Extents"] +git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" +uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" +version = "1.3.3" + +[[deps.GeometryBasics]] +deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "5694b56ccf9d15addedc35e9a4ba9c317721b788" +uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +version = "0.4.10" + +[[deps.Gettext_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" +uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" +version = "0.21.0+0" + +[[deps.Git]] +deps = ["Git_jll"] +git-tree-sha1 = "04eff47b1354d702c3a85e8ab23d539bb7d5957e" +uuid = "d7ba0133-e1db-5d97-8f8c-041e4b3a1eb2" +version = "1.3.1" + +[[deps.Git_jll]] +deps = ["Artifacts", "Expat_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "Libiconv_jll", "OpenSSL_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "d18fb8a1f3609361ebda9bf029b60fd0f120c809" +uuid = "f8c6e375-362e-5223-8a59-34ff63f689eb" +version = "2.44.0+2" + +[[deps.Glib_jll]] +deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "359a1ba2e320790ddbe4ee8b4d54a305c0ea2aff" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.80.0+0" + +[[deps.Glob]] +git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" +uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" +version = "1.3.1" + +[[deps.GnuTLS_jll]] +deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl", "Nettle_jll", "P11Kit_jll", "Zlib_jll"] +git-tree-sha1 = "383db7d3f900f4c1f47a8a04115b053c095e48d3" +uuid = "0951126a-58fd-58f1-b5b3-b08c7c4a876d" +version = "3.8.4+0" + +[[deps.Graphics]] +deps = ["Colors", "LinearAlgebra", "NaNMath"] +git-tree-sha1 = "d61890399bc535850c4bf08e4e0d3a7ad0f21cbd" +uuid = "a2bd30eb-e257-5431-a919-1863eab51364" +version = "1.1.2" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.14+0" + +[[deps.GridLayoutBase]] +deps = ["GeometryBasics", "InteractiveUtils", "Observables"] +git-tree-sha1 = "f57a64794b336d4990d90f80b147474b869b1bc4" +uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" +version = "0.9.2" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HDF5_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] +git-tree-sha1 = "38c8874692d48d5440d5752d6c74b0c6b0b60739" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "1.14.2+1" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.5" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] +git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "2.8.1+1" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.10.0+0" + +[[deps.HypergeometricFunctions]] +deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.23" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "8b72179abc660bfab5e28472e019392b97d0985c" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.4" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[deps.ImageAxes]] +deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] +git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.6.11" + +[[deps.ImageBase]] +deps = ["ImageCore", "Reexport"] +git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" +uuid = "c817782e-172a-44cc-b673-b171935fbb9e" +version = "0.1.7" + +[[deps.ImageCore]] +deps = ["ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] +git-tree-sha1 = "b2a7eaa169c13f5bcae8131a83bc30eff8f71be0" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.10.2" + +[[deps.ImageIO]] +deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] +git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" +uuid = "82e4d734-157c-48bb-816b-45c225c6df19" +version = "0.6.7" + +[[deps.ImageMetadata]] +deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] +git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" +uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" +version = "0.9.9" + +[[deps.Imath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" +uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" +version = "3.1.7+0" + +[[deps.IncompleteLU]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "6c676e79f98abb6d33fa28122cad099f1e464afe" +uuid = "40713840-3770-5561-ab4c-a76e7d0d7895" +version = "0.2.1" + +[[deps.IndirectArrays]] +git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "1.0.0" + +[[deps.Inflate]] +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.4" + +[[deps.InlineStrings]] +deps = ["Parsers"] +git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.0" + +[[deps.IntegerMathUtils]] +git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.2" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2024.0.2+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.Interpolations]] +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.15.1" + + [deps.Interpolations.extensions] + InterpolationsUnitfulExt = "Unitful" + + [deps.Interpolations.weakdeps] + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.IntervalArithmetic]] +deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "Random", "RecipesBase", "RoundingEmulator", "SetRounding", "StaticArrays"] +git-tree-sha1 = "5ab7744289be503d76a944784bac3f2df7b809af" +uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +version = "0.20.9" + +[[deps.IntervalSets]] +git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.10" +weakdeps = ["Random", "RecipesBase", "Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsRandomExt = "Random" + IntervalSetsRecipesBaseExt = "RecipesBase" + IntervalSetsStatisticsExt = "Statistics" + +[[deps.InvertedIndices]] +git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.0" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.Isoband]] +deps = ["isoband_jll"] +git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" +uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" +version = "0.1.1" + +[[deps.IterTools]] +git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.10.0" + +[[deps.IterativeSolvers]] +deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] +git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" +uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" +version = "0.9.4" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLD2]] +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] +git-tree-sha1 = "5ea6acdd53a51d897672edb694e3cc2912f3f8a7" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.4.46" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.5.0" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JSON3]] +deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] +git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" +uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +version = "1.14.0" + + [deps.JSON3.extensions] + JSON3ArrowExt = ["ArrowTypes"] + + [deps.JSON3.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + +[[deps.JpegTurbo]] +deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] +git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" +uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" +version = "0.1.5" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3336abae9a713d2210bb57ab484b1e065edd7d23" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.0.2+0" + +[[deps.JuliaNVTXCallbacks_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" +uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" +version = "0.2.1+0" + +[[deps.KernelAbstractions]] +deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] +git-tree-sha1 = "ed7167240f40e62d97c1f5f7735dea6de3cc5c49" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.18" + + [deps.KernelAbstractions.extensions] + EnzymeExt = "EnzymeCore" + + [deps.KernelAbstractions.weakdeps] + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + +[[deps.KernelDensity]] +deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] +git-tree-sha1 = "fee018a29b60733876eb557804b5b109dd3dd8a7" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.8" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.1+0" + +[[deps.LLVM]] +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] +git-tree-sha1 = "839c82932db86740ae729779e610f07a1640be9a" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "6.6.3" +weakdeps = ["BFloat16s"] + + [deps.LLVM.extensions] + BFloat16sExt = "BFloat16s" + +[[deps.LLVMExtra_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "88b916503aac4fb7f701bb625cd84ca5dd1677bc" +uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" +version = "0.0.29+0" + +[[deps.LLVMLoopInfo]] +git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" +uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" +version = "1.0.0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "15.0.7+0" + +[[deps.LRUCache]] +git-tree-sha1 = "b3cc6698599b10e652832c2f23db3cab99d51b59" +uuid = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" +version = "1.6.1" +weakdeps = ["Serialization"] + + [deps.LRUCache.extensions] + SerializationExt = ["Serialization"] + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.1+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LazilyInitializedFields]] +git-tree-sha1 = "8f7f3cabab0fd1800699663533b6d5cb3fc0e612" +uuid = "0e77f7df-68c5-4e49-93ce-4cd80f5598bf" +version = "1.2.2" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LazyModules]] +git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" +uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" +version = "0.3.1" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.4.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.2.2+1" + +[[deps.Libgcrypt_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] +git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.7+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.42.0+0" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.17.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.39.3+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "0a04a1318df1bf510beb2562cf90fb0c386f58c4" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.39.3+1" + +[[deps.LightXML]] +deps = ["Libdl", "XML2_jll"] +git-tree-sha1 = "3a994404d3f6709610701c7dabfc03fed87a81f8" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.9.1" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.2.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.LinearAlgebraX]] +deps = ["LinearAlgebra", "Mods", "Primes", "SimplePolynomials"] +git-tree-sha1 = "d76cec8007ec123c2b681269d40f94b053473fcf" +uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" +version = "0.2.7" + +[[deps.Literate]] +deps = ["Base64", "IOCapture", "JSON", "REPL"] +git-tree-sha1 = "bad26f1ccd99c553886ec0725e99a509589dcd11" +uuid = "98b081ad-f1c9-55d3-8b20-4c87d4299306" +version = "2.16.1" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.27" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.0.3" + +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.9.4+0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2024.0.0+0" + +[[deps.MPI]] +deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] +git-tree-sha1 = "b4d8707e42b693720b54f0b3434abee6dd4d947a" +uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" +version = "0.20.16" + + [deps.MPI.extensions] + AMDGPUExt = "AMDGPU" + CUDAExt = "CUDA" + + [deps.MPI.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "656036b9ed6f942d35e536e249600bc31d0f9df8" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.2.0+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.10" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "77c3bd69fdb024d75af38713e883d0f249ce19c2" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.3.2+0" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.Makie]] +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] +git-tree-sha1 = "35fa3c150cd96fd77417a23965b7037b90d6ffc9" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.19.12" + +[[deps.MakieCore]] +deps = ["Observables", "REPL"] +git-tree-sha1 = "9b11acd07f21c4d035bd4156e789532e8ee2cc70" +uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" +version = "0.6.9" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MarkdownAST]] +deps = ["AbstractTrees", "Markdown"] +git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" +uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" +version = "0.1.2" + +[[deps.MathTeXEngine]] +deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] +git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" +uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" +version = "0.5.7" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.MicrosoftMPI_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f12a29c4400ba812841c6ace3f4efbb6dbb3ba01" +uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" +version = "10.1.4+2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.1.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.Mods]] +git-tree-sha1 = "924f962b524a71eef7a21dae1e6853817f9b658f" +uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" +version = "2.2.4" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.Multisets]] +git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" +uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" +version = "0.4.4" + +[[deps.NCDatasets]] +deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] +git-tree-sha1 = "d40d24d12f710c39d3a66be99c567ce0032f28a7" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.14.3" + +[[deps.NLSolversBase]] +deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.8.3" + +[[deps.NVTX]] +deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] +git-tree-sha1 = "53046f0483375e3ed78e49190f1154fa0a4083a1" +uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" +version = "0.3.4" + +[[deps.NVTX_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ce3269ed42816bf18d500c9f63418d4b0d9f5a3b" +uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" +version = "3.1.0+2" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + +[[deps.NetCDF_jll]] +deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "OpenMPI_jll", "XML2_jll", "Zlib_jll", "Zstd_jll", "libzip_jll"] +git-tree-sha1 = "a8af1798e4eb9ff768ce7fdefc0e957097793f15" +uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" +version = "400.902.209+0" + +[[deps.Netpbm]] +deps = ["FileIO", "ImageCore", "ImageMetadata"] +git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" +uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" +version = "1.1.1" + +[[deps.Nettle_jll]] +deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "eca63e3847dad608cfa6a3329b95ef674c7160b4" +uuid = "4c82536e-c426-54e4-b420-14f461c4ed8b" +version = "3.7.2+0" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.Observables]] +git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.5" + +[[deps.Oceananigans]] +deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] +git-tree-sha1 = "4672af7242405313743af45168bfce3d87b84b2c" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.90.11" + + [deps.Oceananigans.extensions] + OceananigansEnzymeExt = "Enzyme" + + [deps.Oceananigans.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.OffsetArrays]] +git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.13.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.5+1" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.23+4" + +[[deps.OpenEXR]] +deps = ["Colors", "FileIO", "OpenEXR_jll"] +git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" +uuid = "52e1d378-f018-4a11-a4be-720524705ac7" +version = "0.3.2" + +[[deps.OpenEXR_jll]] +deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" +uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" +version = "3.1.4+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.1+2" + +[[deps.OpenMPI_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "PMIx_jll", "TOML", "Zlib_jll", "libevent_jll", "prrte_jll"] +git-tree-sha1 = "f46caf663e069027a06942d00dced37f1eb3d8ad" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.2+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.4.2" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3da7367955dcc5c54c1ba4d402ccdc09a1a3e046" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.13+1" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.5+0" + +[[deps.Optim]] +deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] +git-tree-sha1 = "d9b79c4eed437421ac4285148fcadf42e0700e89" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "1.9.4" + + [deps.Optim.extensions] + OptimMOIExt = "MathOptInterface" + + [deps.Optim.weakdeps] + MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.3.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.3" + +[[deps.P11Kit_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "2cd396108e178f3ae8dedbd8e938a18726ab2fbf" +uuid = "c2071276-7c44-58a7-b746-946036e04d0a" +version = "0.24.1+0" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.42.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.31" + +[[deps.PMIx_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] +git-tree-sha1 = "8b3b19351fa24791f94d7ae85faf845ca1362541" +uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" +version = "4.2.7+0" + +[[deps.PNGFiles]] +deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] +git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" +uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" +version = "0.4.3" + +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.2" +weakdeps = ["Requires", "TOML"] + +[[deps.Packing]] +deps = ["GeometryBasics"] +git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.5.0" + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "526f5a03792669e4187e584e8ec9d534248ca765" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.52.1+0" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.PencilArrays]] +deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] +git-tree-sha1 = "6510e851700a851944f7ffa5cd990cced4802ad2" +uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" +version = "0.19.3" + + [deps.PencilArrays.extensions] + PencilArraysDiffEqExt = ["DiffEqBase"] + PencilArraysHDF5Ext = ["HDF5"] + + [deps.PencilArrays.weakdeps] + DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" + HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" + +[[deps.PencilFFTs]] +deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "MPI", "PencilArrays", "Reexport", "TimerOutputs"] +git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" +uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" +version = "0.15.1" + +[[deps.Permutations]] +deps = ["Combinatorics", "LinearAlgebra", "Random"] +git-tree-sha1 = "eb3f9df2457819bf0a9019bd93cc451697a0751e" +uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" +version = "0.4.20" + +[[deps.PikaParser]] +deps = ["DocStringExtensions"] +git-tree-sha1 = "d6ff87de27ff3082131f31a714d25ab6d0a88abf" +uuid = "3bbf5609-3e7b-44cd-8549-7c69f321e792" +version = "0.6.1" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.42.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.10.0" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] +git-tree-sha1 = "7b1a9df27f072ac4c9c7cbe5efb198489258d1f5" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.1" + +[[deps.PolygonOps]] +git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" +uuid = "647866c9-e3ac-4575-94e7-e3d426903924" +version = "0.1.2" + +[[deps.Polynomials]] +deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] +git-tree-sha1 = "a9c7a523d5ed375be3983db190f6a5874ae9286d" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "4.0.6" + + [deps.Polynomials.extensions] + PolynomialsChainRulesCoreExt = "ChainRulesCore" + PolynomialsFFTWExt = "FFTW" + PolynomialsMakieCoreExt = "MakieCore" + PolynomialsMutableArithmeticsExt = "MutableArithmetics" + + [deps.Polynomials.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" + MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" + MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" + +[[deps.PooledArrays]] +deps = ["DataAPI", "Future"] +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "1.4.3" + +[[deps.PositiveFactorizations]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.4" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.3.1" + +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "cb420f77dc474d23ee47ca8d14c90810cafe69e7" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.6" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.ProgressBars]] +deps = ["Printf"] +git-tree-sha1 = "b437cdb0385ed38312d91d9c00c20f3798b30256" +uuid = "49802e3a-d2f1-5c88-81d8-b72133a6f568" +version = "1.5.1" + +[[deps.ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "763a8ceb07833dd51bb9e3bbca372de32c0605ad" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.10.0" + +[[deps.QOI]] +deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] +git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" +uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" +version = "1.0.0" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.9.4" + +[[deps.Quaternions]] +deps = ["LinearAlgebra", "Random", "RealDot"] +git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" +uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" +version = "0.7.6" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Random123]] +deps = ["Random", "RandomNumbers"] +git-tree-sha1 = "4743b43e5a9c4a2ede372de7061eed81795b12e7" +uuid = "74087812-796a-5b5d-8853-05524746bad3" +version = "1.7.0" + +[[deps.RandomNumbers]] +deps = ["Random", "Requires"] +git-tree-sha1 = "043da614cc7e95c703498a491e2c21f58a2b8111" +uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" +version = "1.5.3" + +[[deps.RangeArrays]] +git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.2" + +[[deps.Ratios]] +deps = ["Requires"] +git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.4.5" +weakdeps = ["FixedPointNumbers"] + + [deps.Ratios.extensions] + RatiosFixedPointNumbersExt = "FixedPointNumbers" + +[[deps.RealDot]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" +uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" +version = "0.1.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RegistryInstances]] +deps = ["LazilyInitializedFields", "Pkg", "TOML", "Tar"] +git-tree-sha1 = "ffd19052caf598b8653b99404058fce14828be51" +uuid = "2792f1a3-b283-48e8-9a74-f99dce5104f3" +version = "0.1.0" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.RingLists]] +deps = ["Random"] +git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" +uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" +version = "0.2.8" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.7.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.4.0+0" + +[[deps.Rotations]] +deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] +git-tree-sha1 = "2a0a5d8569f481ff8840e3b7c84bbf188db6a3fe" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.7.0" +weakdeps = ["RecipesBase"] + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" + +[[deps.RoundingEmulator]] +git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" +uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" +version = "0.2.1" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.1" + +[[deps.SeawaterPolynomials]] +git-tree-sha1 = "6d85acd6de472f8e6da81c61c7c5b6280a55e0bc" +uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +version = "0.3.4" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.1" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.SetRounding]] +git-tree-sha1 = "d7a25e439d07a17b7cdf97eecee504c50fedf5f6" +uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" +version = "0.2.1" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.1" + +[[deps.ShaderAbstractions]] +deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "79123bc60c5507f035e6d1d9e563bb2971954ec8" +uuid = "65257c39-d410-5151-9873-9b3e5be5013e" +version = "0.4.1" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.1.0" + +[[deps.SimpleGraphs]] +deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] +git-tree-sha1 = "f65caa24a622f985cc341de81d3f9744435d0d0f" +uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" +version = "0.8.6" + +[[deps.SimplePartitions]] +deps = ["AbstractLattices", "DataStructures", "Permutations"] +git-tree-sha1 = "e182b9e5afb194142d4668536345a365ea19363a" +uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" +version = "0.3.2" + +[[deps.SimplePolynomials]] +deps = ["Mods", "Multisets", "Polynomials", "Primes"] +git-tree-sha1 = "7063828369cafa93f3187b3d0159f05582011405" +uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" +version = "0.2.17" + +[[deps.SimpleRandom]] +deps = ["Distributions", "LinearAlgebra", "Random"] +git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" +uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" +version = "0.3.1" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sixel]] +deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] +git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" +uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" +version = "0.1.3" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.3.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StableHashTraits]] +deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] +git-tree-sha1 = "10dc702932fe05a0e09b8e5955f00794ea1e8b12" +uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" +version = "1.1.8" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.1" + +[[deps.Static]] +deps = ["IfElse"] +git-tree-sha1 = "d2fdac9ff3906e27f7a618d47b676941baa6c80c" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "0.8.10" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] +git-tree-sha1 = "5d66818a39bb04bf328e92bc933ec5b4ee88e436" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.5.0" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.3" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.2" + +[[deps.StaticPermutations]] +git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" +uuid = "15972242-4b8f-49a0-b8a1-9ac0e7a1a45d" +version = "0.3.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "5cf7606d6cef84b543b483848d4ae08ad9832b21" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.3" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "cef0472124fab0695b58ca35a77c6fb942fdab8a" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.3.1" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Strided]] +deps = ["LinearAlgebra", "StridedViews", "TupleTools"] +git-tree-sha1 = "40c69be0e1b72ee2f42923b7d1ff13e0b04e675c" +uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" +version = "2.0.4" + +[[deps.StridedViews]] +deps = ["LinearAlgebra", "PackageExtensionCompat"] +git-tree-sha1 = "5b765c4e401693ab08981989f74a36a010aa1d8e" +uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" +version = "0.2.2" +weakdeps = ["CUDA"] + + [deps.StridedViews.extensions] + StridedViewsCUDAExt = "CUDA" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.3.4" + +[[deps.StructArrays]] +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.6.18" +weakdeps = ["Adapt", "GPUArraysCore", "SparseArrays", "StaticArrays"] + + [deps.StructArrays.extensions] + StructArraysAdaptExt = "Adapt" + StructArraysGPUArraysCoreExt = "GPUArraysCore" + StructArraysSparseArraysExt = "SparseArrays" + StructArraysStaticArraysExt = "StaticArrays" + +[[deps.StructTypes]] +deps = ["Dates", "UUIDs"] +git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" +uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" +version = "1.10.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TaylorSeries]] +deps = ["LinearAlgebra", "Markdown", "Requires", "SparseArrays"] +git-tree-sha1 = "1c7170668366821b0c4c4fe03ee78f8d6cf36e2c" +uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" +version = "0.16.0" +weakdeps = ["IntervalArithmetic"] + + [deps.TaylorSeries.extensions] + TaylorSeriesIAExt = "IntervalArithmetic" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.TiffImages]] +deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] +git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" +uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" +version = "0.6.8" + +[[deps.TimerOutputs]] +deps = ["ExprTools", "Printf"] +git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" +uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" +version = "0.5.23" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "71509f04d045ec714c4748c785a59045c3736349" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.10.7" +weakdeps = ["Random", "Test"] + + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] + +[[deps.TriplotBase]] +git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" +uuid = "981d1d27-644d-49a2-9326-4793e63143c3" +version = "0.1.0" + +[[deps.TupleTools]] +git-tree-sha1 = "41d61b1c545b06279871ef1a4b5fcb2cac2191cd" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.5.0" + +[[deps.URIs]] +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.5.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.UnsafeAtomics]] +git-tree-sha1 = "6331ac3440856ea1988316b46045303bef658278" +uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" +version = "0.2.1" + +[[deps.UnsafeAtomicsLLVM]] +deps = ["LLVM", "UnsafeAtomics"] +git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" +uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" +version = "0.1.3" + +[[deps.VersionParsing]] +git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.3.0" + +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "1.0.0" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.12.6+0" + +[[deps.XSLT_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" +uuid = "aed1982a-8fda-507f-9586-7b0439959a61" +version = "1.1.34+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ac88fb95ae6447c8dda6a5503f3bafd496ae8632" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.4.6+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.6+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.11+0" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.4+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.4+4" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.10+4" + +[[deps.Xorg_libpthread_stubs_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" +uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" +version = "0.1.1+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] +git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.15.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.5.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+1" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e678132f07ddb5bfa46857f0d7620fb9be675d3b" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.6+0" + +[[deps.isoband_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" +uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" +version = "0.2.3+0" + +[[deps.libaec_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "46bf7be2917b59b761247be3f317ddf75e50e997" +uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" +version = "1.1.2+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.4.0+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] +git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.15.1+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.8.0+1" + +[[deps.libevent_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "OpenSSL_jll"] +git-tree-sha1 = "f04ec6d9a186115fb38f858f05c0c4e1b7fc9dcb" +uuid = "1080aeaf-3a6a-583e-a51c-c537b09f60ec" +version = "2.1.13+1" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.2+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d7015d2e18a5fd9a4f47de711837e980519781a4" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.43+1" + +[[deps.libsixel_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] +git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" +uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" +version = "1.10.3+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] +git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.7+1" + +[[deps.libzip_jll]] +deps = ["Artifacts", "Bzip2_jll", "GnuTLS_jll", "JLLWrappers", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "3282b7d16ae7ac3e57ec2f3fa8fafb564d8f9f7f" +uuid = "337d8026-41b4-5cde-a456-74a10e5b31d1" +version = "1.10.1+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" + +[[deps.prrte_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "PMIx_jll", "libevent_jll"] +git-tree-sha1 = "5adb2d7a18a30280feb66cad6f1a1dfdca2dc7b0" +uuid = "eb928a42-fffd-568d-ab9c-3f5d54fc65b9" +version = "3.0.2+0" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "2021.5.5+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "3.5.0+0" diff --git a/docs/Project.toml b/docs/Project.toml index 369e2aeb..d7cbe6e6 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -9,4 +9,4 @@ Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" CairoMakie = "0.10.12" DataDeps = "0.7" Documenter = "1" -Oceananigans = "0.90.10" \ No newline at end of file +Oceananigans = "0.90.10" diff --git a/docs/make.jl b/docs/make.jl index 81bb2d65..9724e318 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,3 +1,5 @@ +pushfirst!(LOAD_PATH, joinpath(@__DIR__, "..")) # add ClimaOcean to environment stack + using Documenter, Literate, diff --git a/examples/compute_mixed_layer_depth.jl b/examples/compute_mixed_layer_depth.jl deleted file mode 100644 index 07defabf..00000000 --- a/examples/compute_mixed_layer_depth.jl +++ /dev/null @@ -1,27 +0,0 @@ -using ClimaOcean.NearGlobalSimulations: one_degree_near_global_simulation -using ClimaOcean.Diagnostics -using Oceananigans -using Oceananigans - -using GLMakie - -# Build the simulation -simulation = one_degree_near_global_simulation(CPU()) -model = simulation.model - -h = MixedLayerDepthField(model) -compute!(h) -x, y, z = nodes(model.tracers.T) - -fig = Figure(resolution=(1800, 1200)) -ax = Axis(fig[1, 1], xlabel="Longitude", ylabel="Latitude") -hm = heatmap!(ax, x, y, interior(h, :, :, 1), colorrange=(-1, 100)) - -Colorbar(fig[1, 2], hm; - vertical = true, - tellheight = false, - flipaxis = true, - label = "Mixed layer depth (m)") - -display(fig) - diff --git a/examples/generate_atmos_dataset.jl b/examples/generate_atmos_dataset.jl new file mode 100644 index 00000000..b4e395bd --- /dev/null +++ b/examples/generate_atmos_dataset.jl @@ -0,0 +1,18 @@ +using ClimaOcean +using Oceananigans +using JLD2 + +time_indices = 1:1 + +qt = ClimaOcean.JRA55.jra55_field_time_series(:specific_humidity; time_indices) +Tt = ClimaOcean.JRA55.jra55_field_time_series(:temperature; time_indices) +pt = ClimaOcean.JRA55.jra55_field_time_series(:sea_level_pressure; time_indices) + +Nx, Ny, Nz = size(qt[1]) + +q = Array(interior(qt[1], 1:4:Nx, 1:4:Ny, 1)) +T = Array(interior(Tt[1], 1:4:Nx, 1:4:Ny, 1)) +p = Array(interior(pt[1], 1:4:Nx, 1:4:Ny, 1)) + +@save "atmospheric_state.jld2" q T p + diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index 78d83b01..0468499a 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -20,7 +20,7 @@ h = regrid_bathymetry(grid, height_above_water=1, minimum_depth=5) land = interior(h) .> 0 interior(h)[land] .= NaN -fig = Figure(resolution=(2400, 1200)) +fig = Figure(size=(2400, 1200)) ax = Axis(fig[1, 1]) heatmap!(ax, λ, φ, interior(h, :, :, 1), nan_color=:white, colorrange=(-5000, 0)) @@ -56,11 +56,10 @@ interior(h_smooth)[land_smooth] .= NaN land_rough = interior(h_rough) .> 0 interior(h_rough)[land_rough] .= NaN -fig = Figure(resolution=(2400, 800)) +fig = Figure(size=(2400, 1200)) ax = Axis(fig[1, 1]) heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white) #, colorrange=(-5000, 0)) ax = Axis(fig[1, 2]) heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white) #, colorrange=(-5000, 0)) display(fig) - diff --git a/examples/inspect_JRA55_data.jl b/examples/inspect_JRA55_data.jl index f4f031ea..1c1f0ccb 100644 --- a/examples/inspect_JRA55_data.jl +++ b/examples/inspect_JRA55_data.jl @@ -32,7 +32,7 @@ n = Observable(1) Qswn = @lift interior(Qswt[$n], :, :, 1) rhn = @lift interior(rht[$n], :, :, 1) -fig = Figure(resolution=(1400, 700)) +fig = Figure(size=(1400, 700)) axsw = Axis3(fig[1, 1], aspect=(1, 1, 1)) axrh = Axis3(fig[1, 2], aspect=(1, 1, 1)) diff --git a/examples/inspect_ecco2_data.jl b/examples/inspect_ecco2_data.jl index def71eab..4c61392b 100644 --- a/examples/inspect_ecco2_data.jl +++ b/examples/inspect_ecco2_data.jl @@ -35,7 +35,7 @@ Tp[Tp .< -10] .= NaN # We're ready to plot. We'll make an animation # that depicts how the ECCO2 data changes with depth. -fig = Figure(resolution=(1200, 1400)) +fig = Figure(size=(1200, 1400)) axT = Axis(fig[1, 1]) axS = Axis(fig[2, 1]) diff --git a/examples/quarter_degree_near_global_simulation.jl b/examples/quarter_degree_near_global_simulation.jl deleted file mode 100644 index b687792a..00000000 --- a/examples/quarter_degree_near_global_simulation.jl +++ /dev/null @@ -1,96 +0,0 @@ -using ClimaOcean.NearGlobalSimulations: quarter_degree_near_global_simulation - -using Oceananigans -using Oceananigans.Units -using Oceananigans.Utils: WallTimeInterval -using Oceananigans.BuoyancyModels: buoyancy -using Oceananigans.Models.HydrostaticFreeSurfaceModels: VerticalVorticityField -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: - MixingLength, TurbulentKineticEnergyEquation, CATKEVerticalDiffusivity - -using ParameterEstimocean.Parameters: closure_with_parameters -using JLD2 - -##### -##### Boundary layer turbulence closure options -##### - -# "Ri-based" --- uses calibrated defaults in Oceananigans -ri_based = RiBasedVerticalDiffusivity() - -# Choose closure -boundary_layer_turbulence_closure = ri_based - -@show boundary_layer_turbulence_closure - -##### -##### Build the simulation -##### - -start_time = 0days -stop_time = start_time + 10years - -simulation = quarter_degree_near_global_simulation(; start_time, stop_time, boundary_layer_turbulence_closure) - -# Define output -slices_save_interval = 1day -fields_save_interval = 30days -Nx, Ny, Nz = size(simulation.model.grid) - -dir = "/storage2/simone/quarter-degree-data/" -closure_name = typeof(boundary_layer_turbulence_closure).name.wrapper -output_prefix = "near_global_$(Nx)_$(Ny)_$(Nz)_$closure_name" - -simulation.output_writers[:checkpointer] = Checkpointer(simulation.model; dir, - prefix = output_prefix * "_checkpointer", - schedule = WallTimeInterval(10minutes), - cleanup = true, - overwrite_existing = true) - -model = simulation.model - -simulation.output_writers[:fields] = JLD2OutputWriter(model, merge(model.velocities, model.tracers); dir, - schedule = TimeInterval(slices_save_interval), - filename = output_prefix * "_fields", - with_halos = true, - overwrite_existing = true) - -slice_indices = [(:, :, Nz), (:, :, Nz-10)] -output_names = [:surface, :near_surface] -for n = 1:2 - indices = slice_indices[n] - - outputs = Dict() - - for name in keys(model.tracers) - c = model.tracers[name] - outputs[name] = Field(c; indices) - end - - outputs[:u] = Field(model.velocities.u; indices) - outputs[:v] = Field(model.velocities.v; indices) - outputs[:w] = Field(model.velocities.w; indices) - outputs[:η] = model.free_surface.η - outputs[:ζ] = VerticalVorticityField(model.grid, model.velocities; indices) - - name = output_names[n] - simulation.output_writers[name] = JLD2OutputWriter(model, outputs; dir, - schedule = TimeInterval(slices_save_interval), - filename = output_prefix * "_fields_$name", - with_halos = true, - overwrite_existing = true) -end - -@info "Running a simulation with Δt = $(prettytime(simulation.Δt))" - -spinup = 11days -simulation.Δt = 1minute -simulation.stop_time = time(simulation) + spinup -run!(simulation) - -simulation.stop_time = start_time + 2.2years - spinup -simulation.Δt = 10minutes -run!(simulation) - -@info "Simulation took $(prettytime(simulation.run_wall_time))." - diff --git a/examples/quarter_degree_omip_run.jl b/examples/quarter_degree_omip_run.jl deleted file mode 100644 index 8a5afb84..00000000 --- a/examples/quarter_degree_omip_run.jl +++ /dev/null @@ -1,36 +0,0 @@ -using GLMakie -using Oceananigans -using ClimaOcean.Bathymetry: regrid_bathymetry -using ClimaOcean.VerticalGrids: stretched_vertical_faces, PowerLawStretching - -##### -##### Quarter degree near-global grid -##### - -arch = CPU() - -z_faces = stretched_vertical_faces(surface_layer_Δz = 8, - surface_layer_height = 128, - stretching = PowerLawStretching(1.02), - minimum_depth = 6000) - -grid = LatitudeLongitudeGrid(arch; - size = (4 * 360, 4 * 160, 1), - latitude = (-80, 80), - longitude = (-180, 180), - z = z_faces, - halo = (4, 4, 4)) - -h = regrid_bathymetry(grid, height_above_water=1, minimum_depth=5) - -λ, φ, z = nodes(h) - -land = interior(h) .> 0 -interior(h)[land] .= NaN - -fig = Figure(resolution=(2400, 1200)) -ax = Axis(fig[1, 1], xlabel="Longitude", ylabel="Latitude") -heatmap!(ax, λ, φ, interior(h, :, :, 1), nan_color=:white, colorrange=(-5000, 0)) - -display(fig) - diff --git a/examples/surface_flux_computation.jl b/examples/surface_flux_computation.jl new file mode 100644 index 00000000..9b786df6 --- /dev/null +++ b/examples/surface_flux_computation.jl @@ -0,0 +1,101 @@ + using SurfaceFluxes + using Thermodynamics + using StaticArrays + using ClimaOcean + + import CLIMAParameters + + using Thermodynamics: q_vap_saturation_from_density, partial_pressure_vapor + using SurfaceFluxes.Parameters: SurfaceFluxesParameters + using ClimaOcean.OceanSeaIceModels: + default_universal_function_parameters, + default_surface_flux_parameters + + const CP = CLIMAParameters + + function extrapolate_surface_density(params, atmos_state, surface_temperature) + Tₛ = surface_temperature + Tₐ = air_temperature(params, atmos_state) + Rmₐ = gas_constant_air(params, atmos_state) + ρₐ = air_density(params, atmos_state) + κ = cv_m(params, atmos_state) / Rmₐ + return ρₐ * (Tₛ / Tₐ)^κ +end + +function surface_saturation_specific_humidity(params, surface_temperature, atmos_state) + Tₛ = surface_temperature + ρₛ = atmos_state.ρ #extrapolate_surface_density(thermo_params, atmos_state, Tₛ) + + @show p★ = saturation_vapor_pressure(params, Tₛ, Liquid()) + + q = PhasePartition(thermo_params, atmos_thermo_state) + @show q + + @show pᵥ = partial_pressure_vapor(params, atmos_state.p, q) + @show p★ₐ = saturation_vapor_pressure(params, atmos_state.T, Liquid()) + @show q★ₐ = q_vap_saturation_from_density(params, atmos_state.T, atmos_state.ρ, p★ₐ) + @show pᵥ / p★ₐ + + q★ = q_vap_saturation_from_density(params, Tₛ, ρₛ, p★) + @show q★ + @show q + + return q★ +end + +FT = Float64 +thermo_params = Thermodynamics.Parameters.HierarchicalThermodynamicsParameters(FT) +businger_params = default_universal_function_parameters(FT) +surface_flux_parameters = default_surface_flux_parameters(thermo_params) + +#= +include(joinpath(pkgdir(SurfaceFluxes), "parameters", "create_parameters.jl")) +toml_dict = CP.create_toml_dict(FT; dict_type = "alias") +uf_type = SurfaceFluxes.UniversalFunctions.BusingerType() +param_set = create_parameters(toml_dict, uf_type) +thermo_params = SurfaceFluxes.Parameters.thermodynamics_params(param_set) +=# + +h = 2.0 # height at which measurements are made, in m +surface_velocity = SVector(0.0, 0.0) +atmos_velocity = SVector(4.0, 0.0) + +atmos_pressure = 101350.0 +atmos_temperature = 298.15 +atmos_specific_humidity = 0.03 + +atmos_thermo_state = Thermodynamics.PhaseEquil_pTq(thermo_params, + atmos_pressure, + atmos_temperature, + atmos_specific_humidity) + + +surface_temperature = Tₛ = 297.15 + +q₀ = 0.98 +c₁ = 640380 +c₂ = 5107.4 +qLY = q₀ * c₁ * exp(-c₂ / Tₛ) + +q★ = surface_saturation_specific_humidity(thermo_params, surface_temperature, atmos_thermo_state) +surface_thermo_state = Thermodynamics.PhaseEquil_pTq(thermo_params, + atmos_pressure, + surface_temperature, + q★) + + +# State at z=0, eg the "surface" +surface_dynamic_state = SurfaceFluxes.StateValues(0.0, surface_velocity, surface_thermo_state) + +# State at z=h, eg the "atmosphere" +atmos_dynamic_state = SurfaceFluxes.StateValues(h, atmos_velocity, atmos_thermo_state) + +momentum_roughness_length = 0.01 +buoyancy_roughness_length = 0.001 + +values = SurfaceFluxes.ValuesOnly(atmos_dynamic_state, + surface_dynamic_state, + momentum_roughness_length, + buoyancy_roughness_length) + +conditions = SurfaceFluxes.surface_conditions(surface_flux_parameters, values) diff --git a/examples/distributed_perfect_one_degree_model_calibration.jl b/experiments/one_degree_simulations/distributed_perfect_one_degree_model_calibration.jl similarity index 100% rename from examples/distributed_perfect_one_degree_model_calibration.jl rename to experiments/one_degree_simulations/distributed_perfect_one_degree_model_calibration.jl diff --git a/examples/gm_one_degree_model_calibration.jl b/experiments/one_degree_simulations/gm_one_degree_model_calibration.jl similarity index 100% rename from examples/gm_one_degree_model_calibration.jl rename to experiments/one_degree_simulations/gm_one_degree_model_calibration.jl diff --git a/examples/inspect_one_degree_near_global_simulation.jl b/experiments/one_degree_simulations/inspect_one_degree_near_global_simulation.jl similarity index 99% rename from examples/inspect_one_degree_near_global_simulation.jl rename to experiments/one_degree_simulations/inspect_one_degree_near_global_simulation.jl index 4fc09c47..13654f4e 100644 --- a/examples/inspect_one_degree_near_global_simulation.jl +++ b/experiments/one_degree_simulations/inspect_one_degree_near_global_simulation.jl @@ -33,7 +33,7 @@ grid = Tt.grid Nx, Ny, Nz = size(grid) Nt = length(times) -fig = Figure(resolution=(2400, 1800)) +fig = Figure(size=(2400, 1800)) ax_T = Axis(fig[2, 2], xlabel="Longitude", ylabel="Latitude") ax_S = Axis(fig[3, 2], xlabel="Longitude", ylabel="Latitude") diff --git a/examples/one_degree_near_global_simulation.jl b/experiments/one_degree_simulations/one_degree_near_global_simulation.jl similarity index 100% rename from examples/one_degree_near_global_simulation.jl rename to experiments/one_degree_simulations/one_degree_near_global_simulation.jl diff --git a/examples/perfect_one_degree_model_calibration.jl b/experiments/one_degree_simulations/perfect_one_degree_model_calibration.jl similarity index 100% rename from examples/perfect_one_degree_model_calibration.jl rename to experiments/one_degree_simulations/perfect_one_degree_model_calibration.jl diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml new file mode 100644 index 00000000..230b6f71 --- /dev/null +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -0,0 +1,2359 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.2" +manifest_format = "2.0" +project_hash = "d8dbe9035fba3af9077b6e3c6495e511c55cd6e3" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractLattices]] +git-tree-sha1 = "222ee9e50b98f51b5d78feb93dd928880df35f06" +uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" +version = "0.3.0" + +[[deps.AbstractTrees]] +git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.5" + +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown", "Test"] +git-tree-sha1 = "c0d491ef0b135fd7d63cbc6404286bc633329425" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.36" + + [deps.Accessors.extensions] + AccessorsAxisKeysExt = "AxisKeys" + AccessorsIntervalSetsExt = "IntervalSets" + AccessorsStaticArraysExt = "StaticArrays" + AccessorsStructArraysExt = "StructArrays" + AccessorsUnitfulExt = "Unitful" + + [deps.Accessors.weakdeps] + AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + Requires = "ae029012-a4dd-5104-9daa-d747884805df" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "6a55b747d1812e699320963ffde36f1ebdda4099" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.0.4" +weakdeps = ["StaticArrays"] + + [deps.Adapt.extensions] + AdaptStaticArraysExt = "StaticArrays" + +[[deps.Animations]] +deps = ["Colors"] +git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" +uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" +version = "0.4.1" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "44691067188f6bd1b2289552a23e4b7572f4528d" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.9.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "0.1.0" + +[[deps.Automa]] +deps = ["PrecompileTools", "TranscodingStreams"] +git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" +uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" +version = "1.0.3" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.1.0" + +[[deps.AxisArrays]] +deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] +git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.4.7" + +[[deps.BFloat16s]] +deps = ["LinearAlgebra", "Printf", "Random", "Test"] +git-tree-sha1 = "2c7cc21e8678eff479978a0a2ef5ce2f51b63dff" +uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" +version = "0.5.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BitFlags]] +git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.8" + +[[deps.Blosc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "19b98ee7e3db3b4eff74c5c9c72bf32144e24f10" +uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" +version = "1.21.5+0" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+1" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CFTime]] +deps = ["Dates", "Printf"] +git-tree-sha1 = "5afb5c5ba2688ca43a9ad2e5a91cbb93921ccfa1" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.1.3" + +[[deps.CRC32c]] +uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" + +[[deps.CRlibm]] +deps = ["CRlibm_jll"] +git-tree-sha1 = "32abd86e3c2025db5172aa182b982debed519834" +uuid = "96374032-68de-5a5b-8d9e-752f78720389" +version = "1.0.1" + +[[deps.CRlibm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" +uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" +version = "1.0.1+0" + +[[deps.CUDA]] +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics"] +git-tree-sha1 = "baa8ea7a1ea63316fa3feb454635215773c9c845" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.2.0" +weakdeps = ["ChainRulesCore", "SpecialFunctions"] + + [deps.CUDA.extensions] + ChainRulesCoreExt = "ChainRulesCore" + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.CUDA_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.7.0+1" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "2cb12f6b2209f40a4b8967697689a47c50485490" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.2.3" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "8e25c009d2bf16c2c31a70a6e9e8939f7325cc84" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.11.1+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "a4c43f59baa34011e303e76f5c8c91bf58415aaf" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.0+1" + +[[deps.Calculus]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.5.1" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.23.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.ClimaOcean]] +deps = ["Adapt", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] +git-tree-sha1 = "2cd02219dd1feb66fa43bab0f3d80a9c04a2af4e" +repo-rev = "glw-ss/ice-ocean-model" +repo-url = "../.." +uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" +version = "0.2.0" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "6afd99a2cb2495792aaed92dc895ba78a3b82870" +repo-rev = "main" +repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" +uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +version = "0.1.0" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.4" + +[[deps.ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.24.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.4" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.10" + +[[deps.Combinatorics]] +git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.2" + +[[deps.CommonDataModel]] +deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] +git-tree-sha1 = "d7d7b58e149f19c322840a50d1bc20e8c23addb4" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.3.5" + +[[deps.CommonSolve]] +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.4" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.14.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.0+0" + +[[deps.CompositionsBase]] +git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" +uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" +version = "0.1.2" +weakdeps = ["InverseFunctions"] + + [deps.CompositionsBase.extensions] + CompositionsBaseInverseFunctionsExt = "InverseFunctions" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "6cbbd4d241d7e6579ab354737f4dd95ca43946e1" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.4.1" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.5" +weakdeps = ["IntervalSets", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.CubedSphere]] +deps = ["Elliptic", "FFTW", "Printf", "ProgressBars", "SpecialFunctions", "TaylorSeries", "Test"] +git-tree-sha1 = "10134667d7d3569b191a65801514271b8a93b292" +uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" +version = "0.2.5" + +[[deps.CubicSplines]] +deps = ["Random", "Test"] +git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" +uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" +version = "0.2.1" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataDeps]] +deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] +git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" +uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +version = "0.7.13" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.6.1" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "0f4b5d62a88d8f59003e43c25a8a90de9eb76317" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.18" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DelaunayTriangulation]] +deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] +git-tree-sha1 = "d4e9dc4c6106b8d44e40cd4faf8261a678552c7c" +uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" +version = "0.8.12" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DiskArrays]] +deps = ["LRUCache", "OffsetArrays"] +git-tree-sha1 = "ef25c513cad08d7ebbed158c91768ae32f308336" +uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" +version = "0.3.23" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.11" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.Distributions]] +deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "7c302d7a5fec5214eb8a5a4c466dcf7a51fcf169" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.107" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.3" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.DualNumbers]] +deps = ["Calculus", "NaNMath", "SpecialFunctions"] +git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" +uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" +version = "0.6.8" + +[[deps.EarCut_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" +uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" +version = "2.2.4+0" + +[[deps.Elliptic]] +git-tree-sha1 = "71c79e77221ab3a29918aaf6db4f217b89138608" +uuid = "b305315f-e792-5b7a-8f41-49f472929428" +version = "1.0.1" + +[[deps.EnumX]] +git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.4" + +[[deps.ErrorfreeArithmetic]] +git-tree-sha1 = "d6863c556f1142a061532e79f611aa46be201686" +uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" +version = "0.5.2" + +[[deps.ExactPredicates]] +deps = ["IntervalArithmetic", "Random", "StaticArraysCore", "Test"] +git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" +uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" +version = "2.2.5" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.10" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.5.0+0" + +[[deps.ExprTools]] +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" +uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" +version = "0.1.10" + +[[deps.Extents]] +git-tree-sha1 = "2140cd04483da90b2da7f99b2add0750504fc39c" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.2" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "ab3f7e1819dba9434a3a5126510c8fda3a4e7000" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "6.1.1+0" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "4820348781ae578893311153d69049a93d05f39d" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.8.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.10+0" + +[[deps.FastRounding]] +deps = ["ErrorfreeArithmetic", "LinearAlgebra"] +git-tree-sha1 = "6344aa18f654196be82e62816935225b3b9abe44" +uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" +version = "0.3.1" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "82d8afa92ecf4b52d78d869f038ebfb881267322" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.16.3" + +[[deps.FilePaths]] +deps = ["FilePathsBase", "MacroTools", "Reexport", "Requires"] +git-tree-sha1 = "919d9412dbf53a2e6fe74af62a73ceed0bce0629" +uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" +version = "0.8.3" + +[[deps.FilePathsBase]] +deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"] +git-tree-sha1 = "9f00e42f8d99fdde64d40c8ea5d14269a2e2c1aa" +uuid = "48062228-2e41-5def-b9a4-89aafe57970f" +version = "0.9.21" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "bfe82a708416cf00b73a3198db0859c82f741558" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.10.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "bc0c5092d6caaea112d3c8e3b238d61563c58d5f" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.23.0" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.4" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] +git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.93+0" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.36" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FreeType]] +deps = ["CEnum", "FreeType2_jll"] +git-tree-sha1 = "907369da0f8e80728ab49c1c7e09327bf0d6d999" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "4.1.1" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.1+0" + +[[deps.FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] +git-tree-sha1 = "055626e1a35f6771fe99060e835b72ca61a52621" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.10.1" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.10+0" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GLFW]] +deps = ["GLFW_jll"] +git-tree-sha1 = "35dbc482f0967d8dceaa7ce007d16f9064072166" +uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +version = "3.4.1" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] +git-tree-sha1 = "ff38ba61beff76b8f4acad8ab0c97ef73bb670cb" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.3.9+0" + +[[deps.GLMakie]] +deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] +git-tree-sha1 = "b99a999cdcc7467769c7ea8cdc0978a5f059aa7b" +uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +version = "0.9.10" + +[[deps.GMP_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "781609d7-10c4-51f6-84f2-b8444358ff6d" +version = "6.2.1+6" + +[[deps.GPUArrays]] +deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] +git-tree-sha1 = "47e4686ec18a9620850bad110b79966132f14283" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "10.0.2" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.6" + +[[deps.GPUCompiler]] +deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] +git-tree-sha1 = "a846f297ce9d09ccba02ead0cae70690e072a119" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "0.25.0" + +[[deps.GeoInterface]] +deps = ["Extents"] +git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" +uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" +version = "1.3.3" + +[[deps.GeometryBasics]] +deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "5694b56ccf9d15addedc35e9a4ba9c317721b788" +uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +version = "0.4.10" + +[[deps.Gettext_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" +uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" +version = "0.21.0+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "359a1ba2e320790ddbe4ee8b4d54a305c0ea2aff" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.80.0+0" + +[[deps.Glob]] +git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" +uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" +version = "1.3.1" + +[[deps.GnuTLS_jll]] +deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl", "Nettle_jll", "P11Kit_jll", "Zlib_jll"] +git-tree-sha1 = "383db7d3f900f4c1f47a8a04115b053c095e48d3" +uuid = "0951126a-58fd-58f1-b5b3-b08c7c4a876d" +version = "3.8.4+0" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.14+0" + +[[deps.GridLayoutBase]] +deps = ["GeometryBasics", "InteractiveUtils", "Observables"] +git-tree-sha1 = "6f93a83ca11346771a93bbde2bdad2f65b61498f" +uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" +version = "0.10.2" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HDF5_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] +git-tree-sha1 = "38c8874692d48d5440d5752d6c74b0c6b0b60739" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "1.14.2+1" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.5" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] +git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "2.8.1+1" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.10.0+0" + +[[deps.HypergeometricFunctions]] +deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.23" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[deps.ImageAxes]] +deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] +git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.6.11" + +[[deps.ImageBase]] +deps = ["ImageCore", "Reexport"] +git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" +uuid = "c817782e-172a-44cc-b673-b171935fbb9e" +version = "0.1.7" + +[[deps.ImageCore]] +deps = ["ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] +git-tree-sha1 = "b2a7eaa169c13f5bcae8131a83bc30eff8f71be0" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.10.2" + +[[deps.ImageIO]] +deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] +git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" +uuid = "82e4d734-157c-48bb-816b-45c225c6df19" +version = "0.6.7" + +[[deps.ImageMetadata]] +deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] +git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" +uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" +version = "0.9.9" + +[[deps.Imath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" +uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" +version = "3.1.7+0" + +[[deps.IncompleteLU]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "6c676e79f98abb6d33fa28122cad099f1e464afe" +uuid = "40713840-3770-5561-ab4c-a76e7d0d7895" +version = "0.2.1" + +[[deps.IndirectArrays]] +git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "1.0.0" + +[[deps.Inflate]] +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.4" + +[[deps.InlineStrings]] +deps = ["Parsers"] +git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.0" + +[[deps.IntegerMathUtils]] +git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.2" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2024.0.2+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.Interpolations]] +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.15.1" + + [deps.Interpolations.extensions] + InterpolationsUnitfulExt = "Unitful" + + [deps.Interpolations.weakdeps] + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.IntervalArithmetic]] +deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "Random", "RecipesBase", "RoundingEmulator", "SetRounding", "StaticArrays"] +git-tree-sha1 = "5ab7744289be503d76a944784bac3f2df7b809af" +uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +version = "0.20.9" + +[[deps.IntervalSets]] +git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.10" +weakdeps = ["Random", "RecipesBase", "Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsRandomExt = "Random" + IntervalSetsRecipesBaseExt = "RecipesBase" + IntervalSetsStatisticsExt = "Statistics" + +[[deps.InverseFunctions]] +deps = ["Test"] +git-tree-sha1 = "896385798a8d49a255c398bd49162062e4a4c435" +uuid = "3587e190-3f89-42d0-90ee-14403ec27112" +version = "0.1.13" +weakdeps = ["Dates"] + + [deps.InverseFunctions.extensions] + DatesExt = "Dates" + +[[deps.InvertedIndices]] +git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.0" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.Isoband]] +deps = ["isoband_jll"] +git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" +uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" +version = "0.1.1" + +[[deps.IterTools]] +git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.10.0" + +[[deps.IterativeSolvers]] +deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] +git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" +uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" +version = "0.9.4" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLD2]] +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] +git-tree-sha1 = "5ea6acdd53a51d897672edb694e3cc2912f3f8a7" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.4.46" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.5.0" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JSON3]] +deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] +git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" +uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +version = "1.14.0" + + [deps.JSON3.extensions] + JSON3ArrowExt = ["ArrowTypes"] + + [deps.JSON3.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + +[[deps.JpegTurbo]] +deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] +git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" +uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" +version = "0.1.5" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3336abae9a713d2210bb57ab484b1e065edd7d23" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.0.2+0" + +[[deps.JuliaNVTXCallbacks_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" +uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" +version = "0.2.1+0" + +[[deps.KernelAbstractions]] +deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] +git-tree-sha1 = "ed7167240f40e62d97c1f5f7735dea6de3cc5c49" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.18" + + [deps.KernelAbstractions.extensions] + EnzymeExt = "EnzymeCore" + + [deps.KernelAbstractions.weakdeps] + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + +[[deps.KernelDensity]] +deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] +git-tree-sha1 = "fee018a29b60733876eb557804b5b109dd3dd8a7" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.8" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.1+0" + +[[deps.LLVM]] +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] +git-tree-sha1 = "839c82932db86740ae729779e610f07a1640be9a" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "6.6.3" +weakdeps = ["BFloat16s"] + + [deps.LLVM.extensions] + BFloat16sExt = "BFloat16s" + +[[deps.LLVMExtra_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "88b916503aac4fb7f701bb625cd84ca5dd1677bc" +uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" +version = "0.0.29+0" + +[[deps.LLVMLoopInfo]] +git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" +uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" +version = "1.0.0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "15.0.7+0" + +[[deps.LRUCache]] +git-tree-sha1 = "b3cc6698599b10e652832c2f23db3cab99d51b59" +uuid = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" +version = "1.6.1" +weakdeps = ["Serialization"] + + [deps.LRUCache.extensions] + SerializationExt = ["Serialization"] + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.1+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LazyModules]] +git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" +uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" +version = "0.3.1" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.4.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.2.2+1" + +[[deps.Libgcrypt_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] +git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "6f73d1dd803986947b2c750138528a999a6c7733" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.6.0+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.42.0+0" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.17.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.39.3+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "0a04a1318df1bf510beb2562cf90fb0c386f58c4" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.39.3+1" + +[[deps.LightXML]] +deps = ["Libdl", "XML2_jll"] +git-tree-sha1 = "3a994404d3f6709610701c7dabfc03fed87a81f8" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.9.1" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.2.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.LinearAlgebraX]] +deps = ["LinearAlgebra", "Mods", "Primes", "SimplePolynomials"] +git-tree-sha1 = "d76cec8007ec123c2b681269d40f94b053473fcf" +uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" +version = "0.2.7" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.27" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.0.3" + +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.9.4+0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2024.0.0+0" + +[[deps.MPI]] +deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] +git-tree-sha1 = "b4d8707e42b693720b54f0b3434abee6dd4d947a" +uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" +version = "0.20.16" + + [deps.MPI.extensions] + AMDGPUExt = "AMDGPU" + CUDAExt = "CUDA" + + [deps.MPI.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "656036b9ed6f942d35e536e249600bc31d0f9df8" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.2.0+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.10" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "77c3bd69fdb024d75af38713e883d0f249ce19c2" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.3.2+0" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.Makie]] +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] +git-tree-sha1 = "46ca613be7a1358fb93529726ea2fc28050d3ae0" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.20.9" + +[[deps.MakieCore]] +deps = ["Observables", "REPL"] +git-tree-sha1 = "248b7a4be0f92b497f7a331aed02c1e9a878f46b" +uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" +version = "0.7.3" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MathTeXEngine]] +deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] +git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" +uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" +version = "0.5.7" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryBasics", "Printf"] +git-tree-sha1 = "8c26ab950860dfca6767f2bbd90fdf1e8ddc678b" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.4.11" + +[[deps.MicrosoftMPI_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f12a29c4400ba812841c6ace3f4efbb6dbb3ba01" +uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" +version = "10.1.4+2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.1.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.ModernGL]] +deps = ["Libdl"] +git-tree-sha1 = "b76ea40b5c0f45790ae09492712dd326208c28b2" +uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +version = "1.1.7" + +[[deps.Mods]] +git-tree-sha1 = "924f962b524a71eef7a21dae1e6853817f9b658f" +uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" +version = "2.2.4" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.Multisets]] +git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" +uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" +version = "0.4.4" + +[[deps.NCDatasets]] +deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] +git-tree-sha1 = "d40d24d12f710c39d3a66be99c567ce0032f28a7" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.14.3" + +[[deps.NLSolversBase]] +deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.8.3" + +[[deps.NVTX]] +deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] +git-tree-sha1 = "53046f0483375e3ed78e49190f1154fa0a4083a1" +uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" +version = "0.3.4" + +[[deps.NVTX_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ce3269ed42816bf18d500c9f63418d4b0d9f5a3b" +uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" +version = "3.1.0+2" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + +[[deps.NetCDF_jll]] +deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "OpenMPI_jll", "XML2_jll", "Zlib_jll", "Zstd_jll", "libzip_jll"] +git-tree-sha1 = "a8af1798e4eb9ff768ce7fdefc0e957097793f15" +uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" +version = "400.902.209+0" + +[[deps.Netpbm]] +deps = ["FileIO", "ImageCore", "ImageMetadata"] +git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" +uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" +version = "1.1.1" + +[[deps.Nettle_jll]] +deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "eca63e3847dad608cfa6a3329b95ef674c7160b4" +uuid = "4c82536e-c426-54e4-b420-14f461c4ed8b" +version = "3.7.2+0" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.Observables]] +git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.5" + +[[deps.Oceananigans]] +deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] +git-tree-sha1 = "4672af7242405313743af45168bfce3d87b84b2c" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.90.11" + + [deps.Oceananigans.extensions] + OceananigansEnzymeExt = "Enzyme" + + [deps.Oceananigans.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.OffsetArrays]] +git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.13.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.5+1" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.23+4" + +[[deps.OpenEXR]] +deps = ["Colors", "FileIO", "OpenEXR_jll"] +git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" +uuid = "52e1d378-f018-4a11-a4be-720524705ac7" +version = "0.3.2" + +[[deps.OpenEXR_jll]] +deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" +uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" +version = "3.1.4+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.1+2" + +[[deps.OpenMPI_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "PMIx_jll", "TOML", "Zlib_jll", "libevent_jll", "prrte_jll"] +git-tree-sha1 = "f46caf663e069027a06942d00dced37f1eb3d8ad" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.2+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.4.2" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3da7367955dcc5c54c1ba4d402ccdc09a1a3e046" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.13+1" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.5+0" + +[[deps.Optim]] +deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] +git-tree-sha1 = "d9b79c4eed437421ac4285148fcadf42e0700e89" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "1.9.4" + + [deps.Optim.extensions] + OptimMOIExt = "MathOptInterface" + + [deps.Optim.weakdeps] + MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.3.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.3" + +[[deps.P11Kit_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "2cd396108e178f3ae8dedbd8e938a18726ab2fbf" +uuid = "c2071276-7c44-58a7-b746-946036e04d0a" +version = "0.24.1+0" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.42.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.31" + +[[deps.PMIx_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] +git-tree-sha1 = "8b3b19351fa24791f94d7ae85faf845ca1362541" +uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" +version = "4.2.7+0" + +[[deps.PNGFiles]] +deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] +git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" +uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" +version = "0.4.3" + +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.2" +weakdeps = ["Requires", "TOML"] + +[[deps.Packing]] +deps = ["GeometryBasics"] +git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.5.0" + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.PencilArrays]] +deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] +git-tree-sha1 = "6510e851700a851944f7ffa5cd990cced4802ad2" +uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" +version = "0.19.3" + + [deps.PencilArrays.extensions] + PencilArraysDiffEqExt = ["DiffEqBase"] + PencilArraysHDF5Ext = ["HDF5"] + + [deps.PencilArrays.weakdeps] + DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" + HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" + +[[deps.PencilFFTs]] +deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "MPI", "PencilArrays", "Reexport", "TimerOutputs"] +git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" +uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" +version = "0.15.1" + +[[deps.Permutations]] +deps = ["Combinatorics", "LinearAlgebra", "Random"] +git-tree-sha1 = "eb3f9df2457819bf0a9019bd93cc451697a0751e" +uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" +version = "0.4.20" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.42.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.10.0" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] +git-tree-sha1 = "7b1a9df27f072ac4c9c7cbe5efb198489258d1f5" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.1" + +[[deps.PolygonOps]] +git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" +uuid = "647866c9-e3ac-4575-94e7-e3d426903924" +version = "0.1.2" + +[[deps.Polynomials]] +deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] +git-tree-sha1 = "a9c7a523d5ed375be3983db190f6a5874ae9286d" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "4.0.6" + + [deps.Polynomials.extensions] + PolynomialsChainRulesCoreExt = "ChainRulesCore" + PolynomialsFFTWExt = "FFTW" + PolynomialsMakieCoreExt = "MakieCore" + PolynomialsMutableArithmeticsExt = "MutableArithmetics" + + [deps.Polynomials.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" + MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" + MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" + +[[deps.PooledArrays]] +deps = ["DataAPI", "Future"] +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "1.4.3" + +[[deps.PositiveFactorizations]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.4" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.3.1" + +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "cb420f77dc474d23ee47ca8d14c90810cafe69e7" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.6" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.ProgressBars]] +deps = ["Printf"] +git-tree-sha1 = "b437cdb0385ed38312d91d9c00c20f3798b30256" +uuid = "49802e3a-d2f1-5c88-81d8-b72133a6f568" +version = "1.5.1" + +[[deps.ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "763a8ceb07833dd51bb9e3bbca372de32c0605ad" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.10.0" + +[[deps.QOI]] +deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] +git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" +uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" +version = "1.0.0" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.9.4" + +[[deps.Quaternions]] +deps = ["LinearAlgebra", "Random", "RealDot"] +git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" +uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" +version = "0.7.6" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Random123]] +deps = ["Random", "RandomNumbers"] +git-tree-sha1 = "4743b43e5a9c4a2ede372de7061eed81795b12e7" +uuid = "74087812-796a-5b5d-8853-05524746bad3" +version = "1.7.0" + +[[deps.RandomNumbers]] +deps = ["Random", "Requires"] +git-tree-sha1 = "043da614cc7e95c703498a491e2c21f58a2b8111" +uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" +version = "1.5.3" + +[[deps.RangeArrays]] +git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.2" + +[[deps.Ratios]] +deps = ["Requires"] +git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.4.5" +weakdeps = ["FixedPointNumbers"] + + [deps.Ratios.extensions] + RatiosFixedPointNumbersExt = "FixedPointNumbers" + +[[deps.RealDot]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" +uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" +version = "0.1.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.RingLists]] +deps = ["Random"] +git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" +uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" +version = "0.2.8" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.7.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.4.0+0" + +[[deps.RootSolvers]] +deps = ["ForwardDiff"] +git-tree-sha1 = "a87fd671f7a298de98f2f3c5a9cd9890714eb9dd" +uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" +version = "0.4.2" + +[[deps.Roots]] +deps = ["Accessors", "ChainRulesCore", "CommonSolve", "Printf"] +git-tree-sha1 = "1ab580704784260ee5f45bffac810b152922747b" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "2.1.5" + + [deps.Roots.extensions] + RootsForwardDiffExt = "ForwardDiff" + RootsIntervalRootFindingExt = "IntervalRootFinding" + RootsSymPyExt = "SymPy" + RootsSymPyPythonCallExt = "SymPyPythonCall" + + [deps.Roots.weakdeps] + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" + SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" + SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" + +[[deps.Rotations]] +deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] +git-tree-sha1 = "2a0a5d8569f481ff8840e3b7c84bbf188db6a3fe" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.7.0" +weakdeps = ["RecipesBase"] + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" + +[[deps.RoundingEmulator]] +git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" +uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" +version = "0.2.1" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.1" + +[[deps.SeawaterPolynomials]] +git-tree-sha1 = "6d85acd6de472f8e6da81c61c7c5b6280a55e0bc" +uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +version = "0.3.4" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.1" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.SetRounding]] +git-tree-sha1 = "d7a25e439d07a17b7cdf97eecee504c50fedf5f6" +uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" +version = "0.2.1" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.1" + +[[deps.ShaderAbstractions]] +deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "79123bc60c5507f035e6d1d9e563bb2971954ec8" +uuid = "65257c39-d410-5151-9873-9b3e5be5013e" +version = "0.4.1" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.1.0" + +[[deps.SimpleGraphs]] +deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] +git-tree-sha1 = "f65caa24a622f985cc341de81d3f9744435d0d0f" +uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" +version = "0.8.6" + +[[deps.SimplePartitions]] +deps = ["AbstractLattices", "DataStructures", "Permutations"] +git-tree-sha1 = "e182b9e5afb194142d4668536345a365ea19363a" +uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" +version = "0.3.2" + +[[deps.SimplePolynomials]] +deps = ["Mods", "Multisets", "Polynomials", "Primes"] +git-tree-sha1 = "7063828369cafa93f3187b3d0159f05582011405" +uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" +version = "0.2.17" + +[[deps.SimpleRandom]] +deps = ["Distributions", "LinearAlgebra", "Random"] +git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" +uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" +version = "0.3.1" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sixel]] +deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] +git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" +uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" +version = "0.1.3" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.3.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.1" + +[[deps.Static]] +deps = ["IfElse"] +git-tree-sha1 = "d2fdac9ff3906e27f7a618d47b676941baa6c80c" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "0.8.10" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] +git-tree-sha1 = "5d66818a39bb04bf328e92bc933ec5b4ee88e436" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.5.0" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.3" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.2" + +[[deps.StaticPermutations]] +git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" +uuid = "15972242-4b8f-49a0-b8a1-9ac0e7a1a45d" +version = "0.3.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "5cf7606d6cef84b543b483848d4ae08ad9832b21" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.3" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "cef0472124fab0695b58ca35a77c6fb942fdab8a" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.3.1" +weakdeps = ["ChainRulesCore", "InverseFunctions"] + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + +[[deps.Strided]] +deps = ["LinearAlgebra", "StridedViews", "TupleTools"] +git-tree-sha1 = "40c69be0e1b72ee2f42923b7d1ff13e0b04e675c" +uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" +version = "2.0.4" + +[[deps.StridedViews]] +deps = ["LinearAlgebra", "PackageExtensionCompat"] +git-tree-sha1 = "5b765c4e401693ab08981989f74a36a010aa1d8e" +uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" +version = "0.2.2" +weakdeps = ["CUDA"] + + [deps.StridedViews.extensions] + StridedViewsCUDAExt = "CUDA" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.3.4" + +[[deps.StructArrays]] +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.6.18" +weakdeps = ["Adapt", "GPUArraysCore", "SparseArrays", "StaticArrays"] + + [deps.StructArrays.extensions] + StructArraysAdaptExt = "Adapt" + StructArraysGPUArraysCoreExt = "GPUArraysCore" + StructArraysSparseArraysExt = "SparseArrays" + StructArraysStaticArraysExt = "StaticArrays" + +[[deps.StructTypes]] +deps = ["Dates", "UUIDs"] +git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" +uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" +version = "1.10.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.SurfaceFluxes]] +deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] +git-tree-sha1 = "c2c43206af0d861e018f746286d1af036aa7bc3a" +repo-rev = "glw/generalize-parameters" +repo-url = "https://github.com/glwagner/SurfaceFluxes.jl.git" +uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +version = "0.9.2" + + [deps.SurfaceFluxes.extensions] + CreateParametersExt = "CLIMAParameters" + + [deps.SurfaceFluxes.weakdeps] + CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TaylorSeries]] +deps = ["LinearAlgebra", "Markdown", "Requires", "SparseArrays"] +git-tree-sha1 = "1c7170668366821b0c4c4fe03ee78f8d6cf36e2c" +uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" +version = "0.16.0" +weakdeps = ["IntervalArithmetic"] + + [deps.TaylorSeries.extensions] + TaylorSeriesIAExt = "IntervalArithmetic" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.Thermodynamics]] +deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] +git-tree-sha1 = "deac04ad36638b10fde82470d5f128419f627e9a" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.12.6" + + [deps.Thermodynamics.extensions] + CreateParametersExt = "ClimaParams" + + [deps.Thermodynamics.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" + +[[deps.TiffImages]] +deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] +git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" +uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" +version = "0.6.8" + +[[deps.TimerOutputs]] +deps = ["ExprTools", "Printf"] +git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" +uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" +version = "0.5.23" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "71509f04d045ec714c4748c785a59045c3736349" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.10.7" +weakdeps = ["Random", "Test"] + + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] + +[[deps.TriplotBase]] +git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" +uuid = "981d1d27-644d-49a2-9326-4793e63143c3" +version = "0.1.0" + +[[deps.TupleTools]] +git-tree-sha1 = "41d61b1c545b06279871ef1a4b5fcb2cac2191cd" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.5.0" + +[[deps.URIs]] +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.5.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.UnsafeAtomics]] +git-tree-sha1 = "6331ac3440856ea1988316b46045303bef658278" +uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" +version = "0.2.1" + +[[deps.UnsafeAtomicsLLVM]] +deps = ["LLVM", "UnsafeAtomics"] +git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" +uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" +version = "0.1.3" + +[[deps.VersionParsing]] +git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.3.0" + +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "1.0.0" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.12.6+0" + +[[deps.XSLT_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" +uuid = "aed1982a-8fda-507f-9586-7b0439959a61" +version = "1.1.34+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ac88fb95ae6447c8dda6a5503f3bafd496ae8632" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.4.6+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.6+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.11+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.0+4" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.4+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.4+4" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "5.0.3+4" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.7.10+4" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"] +git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.4+4" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.2+4" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.10+4" + +[[deps.Xorg_libpthread_stubs_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" +uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" +version = "0.1.1+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] +git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.15.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.5.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+1" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e678132f07ddb5bfa46857f0d7620fb9be675d3b" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.6+0" + +[[deps.isoband_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" +uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" +version = "0.2.3+0" + +[[deps.libaec_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "46bf7be2917b59b761247be3f317ddf75e50e997" +uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" +version = "1.1.2+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.4.0+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] +git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.15.1+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.8.0+1" + +[[deps.libevent_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "OpenSSL_jll"] +git-tree-sha1 = "f04ec6d9a186115fb38f858f05c0c4e1b7fc9dcb" +uuid = "1080aeaf-3a6a-583e-a51c-c537b09f60ec" +version = "2.1.13+1" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.2+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d7015d2e18a5fd9a4f47de711837e980519781a4" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.43+1" + +[[deps.libsixel_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] +git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" +uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" +version = "1.10.3+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] +git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.7+1" + +[[deps.libzip_jll]] +deps = ["Artifacts", "Bzip2_jll", "GnuTLS_jll", "JLLWrappers", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "3282b7d16ae7ac3e57ec2f3fa8fafb564d8f9f7f" +uuid = "337d8026-41b4-5cde-a456-74a10e5b31d1" +version = "1.10.1+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" + +[[deps.prrte_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "PMIx_jll", "libevent_jll"] +git-tree-sha1 = "5adb2d7a18a30280feb66cad6f1a1dfdca2dc7b0" +uuid = "eb928a42-fffd-568d-ab9c-3f5d54fc65b9" +version = "3.0.2+0" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "2021.5.5+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "3.5.0+0" diff --git a/experiments/prototype_omip_simulation/Project.toml b/experiments/prototype_omip_simulation/Project.toml new file mode 100644 index 00000000..7744d52a --- /dev/null +++ b/experiments/prototype_omip_simulation/Project.toml @@ -0,0 +1,19 @@ +[deps] +CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" +ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" +ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" +Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" + +[compat] +GLMakie = "0.9" +Oceananigans = "0.90.10" +SeawaterPolynomials = "0.3.4" +Thermodynamics = "0.12.6" diff --git a/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl b/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl new file mode 100644 index 00000000..23585c82 --- /dev/null +++ b/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl @@ -0,0 +1,147 @@ +using Oceananigans +using Oceananigans.Architectures: arch_array +using Oceananigans.Units +using Oceananigans.BuoyancyModels: buoyancy_frequency +using Oceananigans.Units: Time + +using ClimaOcean +using ClimaOcean.OceanSeaIceModels: Radiation +using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere +using ClimaOcean.DataWrangling.ECCO2: ecco2_field + +# using GLMakie +using Printf +using Dates + +start_time = time_ns() + +include("omip_components.jl") + +arch = CPU() +epoch = Date(1992, 1, 1) +date = Date(1992, 10, 1) +start_seconds = Second(date - epoch).value +Te = ecco2_field(:temperature, date) +Se = ecco2_field(:salinity, date) +# ℋe = ecco2_field(:sea_ice_thickness, date) + +land = interior(Te) .< -10 +interior(Te)[land] .= NaN +interior(Se)[land] .= NaN + +elapsed = time_ns() - start_time +@info "Initial condition built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +##### +##### Construct the grid +##### + +latitude = (-80, -20) +longitude = (0, 360) + +i₁ = 4 * first(longitude) + 1 +i₂ = 1440 - 4 * (360 - last(longitude)) +Nx = i₂ - i₁ + 1 + +j₁ = 4 * (90 + first(latitude)) + 1 +j₂ = 720 - 4 * (90 - last(latitude)) +Ny = j₂ - j₁ + 1 + +zc = znodes(Te) +zf = znodes(Te.grid, Face()) +Δz = first(zspacings(Te.grid, Center())) + +Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) +Sᵢ = interior(Se, i₁:i₂, j₁:j₂, :) +# ℋᵢ = interior(ℋe, i₁:i₂, j₁:j₂, :) + +# Construct bottom_height depth by analyzing T +Nx, Ny, Nz = size(Tᵢ) +bottom_height = ones(Nx, Ny) .* (zf[1] - Δz) + +for i = 1:Nx, j = 1:Ny + @inbounds for k = Nz:-1:1 + if isnan(Tᵢ[i, j, k]) + bottom_height[i, j] = zf[k+1] + break + end + end +end + +Tᵢ = arch_array(arch, Tᵢ) +Sᵢ = arch_array(arch, Sᵢ) +# ℋᵢ = arch_array(arch, ℋᵢ) + +if longitude[2] - longitude[1] == 360 + TX = Periodic +else + TX = Bounded +end + +grid = LatitudeLongitudeGrid(arch; latitude, longitude, + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = zf, + topology = (Periodic, Bounded, Bounded)) + +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + +#= +ocean = omip_ocean_component(grid) +sea_ice = omip_sea_ice_component(ocean.model) + +coupled_model = OceanSeaIceModel(ocean, sea_ice) +stop_time = 4 * 360days +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=stop_time) + +set!(sea_ice.model, h=ℋᵢ) +#set!(ocean.model, T=Tᵢ, S=Sᵢ, e=1e-6) +set!(ocean.model, T=Tᵢ, S=Sᵢ) + +wall_clock = Ref(time_ns()) + +function progress(sim) + msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) + + elapsed = 1e-9 * (time_ns() - wall_clock[]) + msg *= string(", wall time: ", prettytime(elapsed)) + wall_clock[] = time_ns() + + u, v, w = sim.model.ocean.model.velocities + msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + + T = sim.model.ocean.model.tracers.T + S = sim.model.ocean.model.tracers.S + + msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", maximum(T), minimum(T)) + msg *= @sprintf(", extrema(S): (%.2f, %.2f) g kg⁻¹", minimum(S), maximum(S)) + + # e = sim.model.ocean.model.tracers.e + # msg *= @sprintf(", extrema(e): (%.2f, %.2f) m² s⁻²", minimum(e), maximum(e)) + + @info msg +end + +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +N² = buoyancy_frequency(ocean.model) +κᶜ = ocean.model.diffusivity_fields.κᶜ +auxiliary_fields = (; N², κᶜ) +fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) + +filename = "free_decay_heat_only_cold_ice_surface" + +coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, fields; + filename = filename * "_fields", + indices = (:, :, Nz), + schedule = TimeInterval(10days), + overwrite_existing = true) + +coupled_simulation.output_writers[:seaice] = JLD2OutputWriter(sea_ice.model, (; h = sea_ice.model.ice_thickness); + filename = filename * "_sea_ice_thickness", + schedule = TimeInterval(10days), + overwrite_existing = true) + +run!(coupled_simulation) +=# diff --git a/experiments/prototype_omip_simulation/omip_components.jl b/experiments/prototype_omip_simulation/omip_components.jl new file mode 100644 index 00000000..9f354bcb --- /dev/null +++ b/experiments/prototype_omip_simulation/omip_components.jl @@ -0,0 +1,205 @@ + using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: + CATKEVerticalDiffusivity, + MixingLength, + TurbulentKineticEnergyEquation + +using Oceananigans.Architectures: architecture +using Oceananigans.Grids: halo_size, topology, φnodes, λnodes, znode +using Oceananigans.Fields: ConstantField, ZeroField, interpolate! +using Oceananigans.Utils: launch! + +using ClimaSeaIce +using ClimaSeaIce.HeatBoundaryConditions: IceWaterThermalEquilibrium + +using KernelAbstractions: @kernel, @index + +using SeawaterPolynomials.TEOS10: TEOS10EquationOfState + +function regional_omip_grid(arch, ecco_2_temperature_field; + latitude, + longitude = (0, 360), + z = znodes(ecco_2_temperature_field.grid, Face()), + resolution = 1/4, # degree + halo = (7, 7, 7)) + + start_time = time_ns() + + Te = ecco_2_temperature_field + launch!(architecture(Te), Te.grid, :xyz, nan_land!, Te) + + ΔΛ = last(longitude) - first(longitude) + ΔΦ = last(latitude) - first(latitude) + Nx = Int(ΔΛ / resolution) + Ny = Int(ΔΦ / resolution) + + Nz = length(z) - 1 + grid = LatitudeLongitudeGrid(arch; latitude, longitude, halo, + size = (Nx, Ny, Nz), + z = z) + + Tᵢ = CenterField(grid) + interpolate!(Tᵢ, Te) + + bottom_height = Field{Center, Center, Nothing}(grid) + set!(bottom_height, -Inf) + + # Construct bottom_height depth by analyzing T + launch!(arch, grid, :xy, infer_bottom_height!, bottom_height, Tᵢ, grid) + + grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + + elapsed = 1e-9 * (time_ns() - start_time) + @info string("Grid for regional omip simulation generated in ", prettytime(elapsed), ".") + @show grid + + return grid, Tᵢ +end + +function omip_ocean_component(grid; + closure = :default, + passive_tracers = tuple()) + + start_time = time_ns() + + top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(grid) + top_salt_flux = Fˢ = Field{Center, Center, Nothing}(grid) + top_zonal_momentum_flux = τˣ = Field{Face, Center, Nothing}(grid) + top_meridional_momentum_flux = τʸ = Field{Center, Face, Nothing}(grid) + + ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(τˣ)), + v = FieldBoundaryConditions(top=FluxBoundaryCondition(τʸ)), + T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), + S = FieldBoundaryConditions(top=FluxBoundaryCondition(Fˢ))) + + # Model construction + teos10 = TEOS10EquationOfState() + buoyancy = SeawaterBuoyancy(equation_of_state=teos10) + + Nx, Ny, Nz = size(grid) + + if Nx == Ny == 1 + tracer_advection = nothing + momentum_advection = nothing + else + tracer_advection = WENO() + momentum_advection = VectorInvariant(vorticity_scheme = WENO(), + divergence_scheme = WENO(), + vertical_scheme = WENO()) + end + + tracers = tuple(:T, :S, passive_tracers...) + + if closure == :default + + turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) + mixing_length = MixingLength(Cᵇ=0.01) + + closure = CATKEVerticalDiffusivity(; mixing_length, + turbulent_kinetic_energy_equation, + maximum_tracer_diffusivity = 1e-1, + maximum_tke_diffusivity = 1e-1, + maximum_viscosity = 1e-1, + negative_turbulent_kinetic_energy_damping_time_scale = 30, + minimum_turbulent_kinetic_energy = 1e-6, + minimum_convective_buoyancy_flux = 1e-11) + + tracers = tuple(:e, tracers...) + end + + ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, tracers, + tracer_advection, momentum_advection, + free_surface = SplitExplicitFreeSurface(cfl=0.7; grid), + boundary_conditions = ocean_boundary_conditions, + coriolis = HydrostaticSphericalCoriolis()) + + ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) + + elapsed = time_ns() - start_time + msg = string("Finished building ocean component (" * prettytime(elapsed * 1e-9), ").") + @info msg + + return ocean +end + +function omip_sea_ice_component(ocean_model) + start_time = time_ns() + + ocean_grid = ocean_model.grid + Nx, Ny, Nz = size(ocean_grid) + Hx, Hy, Hz = halo_size(ocean_grid) + TX, TY, TZ = topology(ocean_grid) + + λ = λnodes(ocean_grid, Face()) + φ = φnodes(ocean_grid, Face()) + longitude = (λ[1], λ[end]) + latitude = (φ[1], φ[end]) + + sea_ice_grid = LatitudeLongitudeGrid(arch; longitude, latitude, + size = (Nx, Ny), + halo = (Hx, Hy), + topology = (TX, TY, Flat)) + + if ocean_grid isa ImmersedBoundaryGrid + h = ocean_grid.immersed_boundary.bottom_height + land = interior(h) .>= 0 + sea_ice_grid = ImmersedBoundaryGrid(sea_ice_grid, GridFittedBoundary(land)) + end + + sea_ice_ocean_heat_flux = Field{Center, Center, Nothing}(ocean_grid) + + Nz = size(ocean_grid, 3) + So = ocean_model.tracers.S + ocean_surface_salinity = view(So, :, :, Nz) + bottom_bc = IceWaterThermalEquilibrium(ocean_surface_salinity) + + u, v, w = ocean_model.velocities + ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), + v = view(v, :, :, Nz), #interior(v, :, :, Nz), + w = ZeroField()) + + sea_ice_model = SlabSeaIceModel(sea_ice_grid; + velocities = ocean_surface_velocities, + advection = WENO(), + ice_consolidation_thickness = 0.05, + ice_salinity = 4, + internal_heat_flux = ConductiveFlux(conductivity=2), + top_heat_flux = ConstantField(0), # W m⁻² + top_heat_boundary_condition = PrescribedTemperature(-10), + bottom_heat_boundary_condition = bottom_bc, + bottom_heat_flux = sea_ice_ocean_heat_flux) + + sea_ice = Simulation(sea_ice_model, Δt=5minutes, verbose=false) + + elapsed = time_ns() - start_time + msg = string("Finished building sea ice component (" * prettytime(elapsed * 1e-9), ").") + @info msg + + return sea_ice +end + +const c = Center() +const f = Face() + +@kernel function infer_bottom_height!(bottom_height, T, grid) + i, j = @index(Global, NTuple) + + Nz = size(grid, 3) + + @inbounds for k = Nz:-1:1 + if isnan(T[i, j, k]) + bottom_height[i, j] = znode(i, j, k+1, grid, c, c, f) + break + end + end +end + +@kernel function nan_land!(T) + i, j, k = @index(Global, NTuple) + + @inbounds begin + Tᵢ = T[i, j, k] + land = Tᵢ < -10 + T[i, j, k] = ifelse(land, NaN, Tᵢ) + end +end + diff --git a/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl b/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl new file mode 100644 index 00000000..9238a70f --- /dev/null +++ b/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl @@ -0,0 +1,40 @@ +using GLMakie +using Oceananigans +using JLD2 + +sea_ice_filename = "freely_decaying_regional_simulation_heat_only_sea_ice_thickness.jld2" +fields_filename = "freely_decaying_regional_simulation_heat_only_fields.jld2" + +ht = FieldTimeSeries(sea_ice_filename, "h") +Tt = FieldTimeSeries(fields_filename, "T") +times = ht.times +Nt = length(times) + +for n = 1:Nt + Tn = interior(Tt[n]) + hn = interior(ht[n]) + land = Tn .== 0 + Tn[land] .= NaN + hn[land] .= NaN +end + +fig = Figure(resolution=(1200, 600)) +axT = Axis(fig[1, 1], xlabel="Longitude", ylabel="Latitude") +axh = Axis(fig[2, 1], xlabel="Longitude", ylabel="Latitude") + +n = Observable(1) +Tn = @lift interior(Tt[$n], :, :, 1) +hn = @lift interior(ht[$n], :, :, 1) + +λ, φ, z = nodes(Tt) + +hmT = heatmap!(axT, λ, φ, Tn, nan_color=:lightyellow, colormap=:thermal, colorrange=(-2, 22)) +hmh = heatmap!(axh, λ, φ, hn, nan_color=:lightyellow, colormap=:grays, colorrange=(0, 1)) + +Colorbar(fig[1, 2], hmT, label="Temperature (ᵒC)") +Colorbar(fig[2, 2], hmh, label="Sea ice thickness (m)") + +record(fig, "free_decay_southern_ocean.mp4", 1:Nt, framerate=12) do nn + @info "Plotting frame $nn of $Nt..." + n[] = nn +end diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl new file mode 100644 index 00000000..bf9bce40 --- /dev/null +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -0,0 +1,174 @@ +using Oceananigans +using Oceananigans.Architectures: arch_array +using Oceananigans.Units +using Oceananigans.BuoyancyModels: buoyancy_frequency +using Oceananigans.Units: Time + +using ClimaOcean +using ClimaOcean.OceanSeaIceModels: Radiation, FreezingLimitedOceanTemperature +using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere, JRA55NetCDFBackend +using ClimaOcean.DataWrangling.ECCO2: ecco2_field + +using ClimaSeaIce: LinearLiquidus + +# using GLMakie +using Printf +using Dates + +start_time = time_ns() + +include("omip_components.jl") + +arch = CPU() + +##### +##### Construct initial conditions + grid +##### + +epoch = Date(1992, 1, 1) +date = Date(1992, 1, 2) +start_seconds = Second(date - epoch).value +Te = ecco2_field(:temperature, date, architecture=arch) + +latitude = (-75, -70) +grid, Tᵢ = regional_omip_grid(arch, Te; latitude) + +backend = JRA55NetCDFBackend(8) # InMemory(8) +atmosphere = JRA55_prescribed_atmosphere(arch, 1:56; backend) +radiation = Radiation() + +#closure = RiBasedVerticalDiffusivity(maximum_diffusivity=1e2, maximum_viscosity=1e2) +#closure = RiBasedVerticalDiffusivity() +closure = :default +ocean = omip_ocean_component(grid; closure) +@show size(Tᵢ) ocean.model.grid +set!(ocean.model, T=Tᵢ) #, S=Sᵢ) + +Se = ecco2_field(:salinity, date, architecture=arch) +interpolate!(ocean.model.tracers.S, Se) + +if :e ∈ keys(ocean.model.tracers) + set!(ocean.model, e=1e-6) +end + +sea_ice = FreezingLimitedOceanTemperature(LinearLiquidus(eltype(grid))) + +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +coupled_model.clock.time = start_seconds +stop_time = start_seconds + 30days +coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_time=stop_time) + +elapsed = 1e-9 * (time_ns() - start_time) +@info string("Coupled simulation built ", prettytime(elapsed), ".") +start_time = time_ns() + +wall_clock = Ref(time_ns()) + +# Hm... + +function clip_diffusivity(coupled_simulation) + ocean_model = coupled_simulation.model.ocean.model + κᶜ = parent(ocean_model.diffusivity_fields.κᶜ) + κᵘ = parent(ocean_model.diffusivity_fields.κᵘ) + @. κᶜ = min(κᶜ, 100) + @. κᵘ = min(κᵘ, 100) + return nothing +end + +coupled_simulation.callbacks[:clip] = Callback(clip_diffusivity) + +##### +##### Progress +##### + +Jᵘ = coupled_model.fluxes.total.ocean.momentum.u +Jᵛ = coupled_model.fluxes.total.ocean.momentum.v +Jᵀ = coupled_model.fluxes.total.ocean.tracers.T +Jˢ = coupled_model.fluxes.total.ocean.tracers.S +Fv = coupled_model.fluxes.turbulent.fields.water_vapor +Qc = coupled_model.fluxes.turbulent.fields.sensible_heat +Qv = coupled_model.fluxes.turbulent.fields.latent_heat +ρₒ = coupled_model.fluxes.ocean_reference_density +cₚ = coupled_model.fluxes.ocean_heat_capacity + +import Oceananigans.Fields: reduced_dimensions +reduced_dimensions(::Oceananigans.AbstractOperations.BinaryOperation) = tuple(3) + +ΣQ = ρₒ * cₚ * Jᵀ +τˣ = ρₒ * Jᵘ +τʸ = ρₒ * Jᵛ +N² = buoyancy_frequency(ocean.model) +κᶜ = ocean.model.diffusivity_fields.κᶜ + +function progress(sim) + msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) + + elapsed = 1e-9 * (time_ns() - wall_clock[]) + msg *= string(", wall time: ", prettytime(elapsed)) + wall_clock[] = time_ns() + + u, v, w = sim.model.ocean.model.velocities + msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + + T = sim.model.ocean.model.tracers.T + S = sim.model.ocean.model.tracers.S + + msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) + msg *= @sprintf(", extrema(S): (%.2f, %.2f) g kg⁻¹", minimum(S), maximum(S)) + msg *= @sprintf(", max|τ|: (%.2e, %.2e) N m⁻²", maximum(τˣ), maximum(τʸ)) + msg *= @sprintf(", max|Qv|: %.2e W m⁻²", maximum(Qv)) + msg *= @sprintf(", max|Qc|: %.2e W m⁻²", maximum(Qc)) + msg *= @sprintf(", extrema(ΣQ): (%.2e, %.2e) W m⁻²", minimum(ΣQ), maximum(ΣQ)) + msg *= @sprintf(", extrema(Fv): (%.2e, %.2e) kg s⁻¹ m⁻²", minimum(Fv), maximum(Fv)) + msg *= @sprintf(", extrema(κᶜ): (%.2e, %.2e) m² s⁻¹", minimum(κᶜ), maximum(κᶜ)) + + #e = sim.model.ocean.model.tracers.e + #msg *= @sprintf(", extrema(e): (%.2f, %.2f) m² s⁻²", minimum(e), maximum(e)) + + @info msg +end + +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +run!(coupled_simulation) + +#= +# Build flux outputs +Jᵘ = coupled_model.fluxes.total.ocean.momentum.u +Jᵛ = coupled_model.fluxes.total.ocean.momentum.v +Jᵀ = coupled_model.fluxes.total.ocean.tracers.T +Jˢ = coupled_model.fluxes.total.ocean.tracers.S +Fv = coupled_model.fluxes.turbulent.fields.freshwater +Qc = coupled_model.fluxes.turbulent.fields.sensible_heat +Qv = coupled_model.fluxes.turbulent.fields.latent_heat +ρₒ = coupled_model.fluxes.ocean_reference_density +cₚ = coupled_model.fluxes.ocean_heat_capacity + +ΣQ = ρₒ * cₚ * Jᵀ +τˣ = ρₒ * Jᵘ +τʸ = ρₒ * Jᵛ +N² = buoyancy_frequency(ocean.model) +κᶜ = ocean.model.diffusivity_fields.κᶜ + +fluxes = (; τˣ, τʸ, Fv, Jˢ, ΣQ, Qc, Qv) + +auxiliary_fields = (; N², κᶜ) +fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) + +# Slice fields at the surface +outputs = merge(fields, fluxes) + +filename = "regional_omip_simulation" + +coupled_simulation.output_writers[:fluxes] = JLD2OutputWriter(ocean.model, fluxes; + filename = filename * "_fluxes", + schedule = TimeInterval(1days), + overwrite_existing = true) + +coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, fields; + filename = filename * "_fields", + indices = (:, :, Nz), + schedule = TimeInterval(1days), + overwrite_existing = true) + +=# diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl new file mode 100644 index 00000000..093b9415 --- /dev/null +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -0,0 +1,342 @@ +using Oceananigans +using Oceananigans.Units +using Oceananigans.BuoyancyModels: buoyancy_frequency +using Oceananigans.Units: Time + +using ClimaOcean +using ClimaOcean.DataWrangling.ECCO2: ecco2_column + +using GLMakie +using Printf +using Dates + +include("omip_components.jl") + +locations = ( + eastern_mediterranean = (λ = 30, φ = 32), + ocean_station_papa = (λ = 215, φ = 50), + north_atlantic = (λ = 325, φ = 50), + drake_passage = (λ = 300, φ = -60), + weddell_sea = (λ = 325, φ = -70), + tasman_southern_ocean = (λ = 145, φ = -55), +) + +location = :ocean_station_papa + +start_time = time_ns() + +epoch = Date(1992, 1, 1) +date = Date(1992, 10, 1) +start_seconds = Second(date - epoch).value +Tᵢ = ecco2_field(:temperature, date) +Sᵢ = ecco2_field(:salinity, date) + +elapsed = time_ns() - start_time +@info "Initial condition built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +##### +##### Construct the grid +##### + +Nz = 80 +H = 400 +arch = CPU() +λ★, φ★ = locations[location] +i★, j★, longitude, latitude = ecco2_column(λ★, φ★) + +grid = LatitudeLongitudeGrid(arch; longitude, latitude, + size = (1, 1, Nz), + z = (-H, 0), + topology = (Periodic, Periodic, Bounded)) + +ocean = omip_ocean_component(grid) + +backend = JRA55NetCDFBackend(8 * 60) +atmosphere = JRA55_prescribed_atmosphere(:; longitude, latitude, backend) + +ocean.model.clock.time = start_seconds +ocean.model.clock.iteration = 0 +interpolate!(ocean.model.tracers.T, Tᵢ) +interpolate!(ocean.model.tracers.S, Sᵢ) +set!(ocean.model, e=1e-6) + +ua = atmosphere.velocities.u +va = atmosphere.velocities.v +Ta = atmosphere.tracers.T +qa = atmosphere.tracers.q +times = ua.times + +fig = Figure(size=(1200, 1800)) +axu = Axis(fig[1, 1]) +axT = Axis(fig[2, 1]) +axq = Axis(fig[3, 1]) + +lines!(axu, times ./ days, interior(ua, 1, 1, 1, :)) +lines!(axu, times ./ days, interior(va, 1, 1, 1, :)) +lines!(axT, times ./ days, interior(Ta, 1, 1, 1, :)) +lines!(axq, times ./ days, interior(qa, 1, 1, 1, :)) + +display(fig) + +sea_ice = nothing +radiation = Radiation() +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 30days) + +elapsed = time_ns() - start_time +@info "Coupled simulation built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +wall_clock = Ref(time_ns()) + +function progress(sim) + msg = string("(", location, ")") + msg *= string(", iter: ", iteration(sim), ", time: ", prettytime(sim)) + + elapsed = 1e-9 * (time_ns() - wall_clock[]) + msg *= string(", wall time: ", prettytime(elapsed)) + wall_clock[] = time_ns() + + u, v, w = sim.model.ocean.model.velocities + msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + + T = sim.model.ocean.model.tracers.T + S = sim.model.ocean.model.tracers.S + e = sim.model.ocean.model.tracers.e + + τˣ = first(sim.model.fluxes.total.ocean.momentum.τˣ) + τʸ = first(sim.model.fluxes.total.ocean.momentum.τʸ) + u★ = sqrt(sqrt(τˣ^2 + τʸ^2)) + Q = first(sim.model.fluxes.total.ocean.heat) + + Nz = size(T, 3) + msg *= @sprintf(", u★: %.2f m s⁻¹", u★) + msg *= @sprintf(", Q: %.2f W m⁻²", Q) + msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) + msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) + msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) + msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) + + @info msg +end + +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) + +# Build flux outputs +Ju = coupled_model.fluxes.total.ocean.momentum.u +Jv = coupled_model.fluxes.total.ocean.momentum.v +JT = coupled_model.fluxes.total.ocean.tracers.T +Js = coupled_model.fluxes.total.ocean.tracers.S +E = coupled_model.fluxes.turbulent.fields.water_vapor +Qc = coupled_model.fluxes.turbulent.fields.sensible_heat +Qv = coupled_model.fluxes.turbulent.fields.latent_heat +ρₒ = coupled_model.fluxes.ocean_reference_density +cₚ = coupled_model.fluxes.ocean_heat_capacity + +Q = ρₒ * cₚ * Jᵀ +τx = ρₒ * Jᵘ +τy = ρₒ * Jᵛ +N² = buoyancy_frequency(ocean.model) +κc = ocean.model.diffusivity_fields.κᶜ + +fluxes = (; τx, τy, E, Js, Q, Qc, Qc) + +auxiliary_fields = (; N², κc) +fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) + +# Slice fields at the surface +outputs = merge(fields, fluxes) + +output_attributes = Dict{String, Any}( + "κc" => Dict("long_name" => "Tracer diffusivity", "units" => "m^2 / s"), + "Q" => Dict("long_name" => "Net heat flux", "units" => "W / m^2", "convention" => "positive upwards"), + "Qv" => Dict("long_name" => "Latent heat flux", "units" => "W / m^2", "convention" => "positive upwards"), + "Qc" => Dict("long_name" => "Sensible heat flux", "units" => "W / m^2", "convention" => "positive upwards"), + "Js" => Dict("long_name" => "Salt flux", "units" => "g kg⁻¹ m s⁻¹", "convention" => "positive upwards"), + "E" => Dict("long_name" => "Freshwater evaporation flux", "units" => "m s⁻¹", "convention" => "positive upwards"), + "e" => Dict("long_name" => "Turbulent kinetic energy", "units" => "m^2 / s^2"), + "τx" => Dict("long_name" => "Zonal momentum flux", "units" => "m^2 / s^2"), + "τx" => Dict("long_name" => "Meridional momentum flux", "units" => "m^2 / s^2"), +) + +filename = "single_column_omip_$location" + +coupled_simulation.output_writers[:jld2] = JLD2OutputWriter(ocean.model, outputs; filename, + schedule = TimeInterval(3hours), + overwrite_existing = true) + +#= +coupled_simulation.output_writers[:nc] = NetCDFOutputWriter(ocean.model, outputs; filename, + schedule = AveragedTimeInterval(1days), + output_attributes, + overwrite_existing = true) +=# + +run!(coupled_simulation) + +#= +filename *= ".jld2" + +ut = FieldTimeSeries(filename, "u") +vt = FieldTimeSeries(filename, "v") +Tt = FieldTimeSeries(filename, "T") +St = FieldTimeSeries(filename, "S") +et = FieldTimeSeries(filename, "e") +N²t = FieldTimeSeries(filename, "N²") +κt = FieldTimeSeries(filename, "κᶜ") + +Qt = FieldTimeSeries(filename, "Q") +Qset = FieldTimeSeries(filename, "Qse") +Qlat = FieldTimeSeries(filename, "Qla") +Jˢt = FieldTimeSeries(filename, "Jˢ") +Et = FieldTimeSeries(filename, "E") +τˣt = FieldTimeSeries(filename, "τˣ") +τʸt = FieldTimeSeries(filename, "τʸ") + +Nz = size(Tt, 3) +times = Qt.times + +ua = atmosphere.velocities.u +va = atmosphere.velocities.v +Ta = atmosphere.tracers.T +qa = atmosphere.tracers.q +Qlw = atmosphere.downwelling_radiation.longwave +Qsw = atmosphere.downwelling_radiation.shortwave +Pr = atmosphere.freshwater_flux.rain +Ps = atmosphere.freshwater_flux.snow + +Nt = length(times) +uat = zeros(Nt) +vat = zeros(Nt) +Tat = zeros(Nt) +qat = zeros(Nt) +Qswt = zeros(Nt) +Qlwt = zeros(Nt) +Pt = zeros(Nt) + +for n = 1:Nt + t = times[n] + uat[n] = ua[1, 1, 1, Time(t)] + vat[n] = va[1, 1, 1, Time(t)] + Tat[n] = Ta[1, 1, 1, Time(t)] + qat[n] = qa[1, 1, 1, Time(t)] + Qswt[n] = Qsw[1, 1, 1, Time(t)] + Qlwt[n] = Qlw[1, 1, 1, Time(t)] + Pt[n] = Pr[1, 1, 1, Time(t)] + Ps[1, 1, 1, Time(t)] +end + +set_theme!(Theme(linewidth=3)) + +fig = Figure(size=(2400, 1800)) + +axτ = Axis(fig[1, 1:2], xlabel="Days since Oct 1 1992", ylabel="Wind stress (N m⁻²)") +axu = Axis(fig[2, 1:2], xlabel="Days since Oct 1 1992", ylabel="Velocities (m s⁻¹)") +axQ = Axis(fig[1, 3:4], xlabel="Days since Oct 1 1992", ylabel="Heat flux (W m⁻²)") +axT = Axis(fig[2, 3:4], xlabel="Days since Oct 1 1992", ylabel="Surface temperature (ᵒC)") +axF = Axis(fig[1, 5:6], xlabel="Days since Oct 1 1992", ylabel="Freshwater volume flux (m s⁻¹)") +axS = Axis(fig[2, 5:6], xlabel="Days since Oct 1 1992", ylabel="Surface salinity (g kg⁻¹)") + +axuz = Axis(fig[3, 1], xlabel="Velocities (m s⁻¹)", ylabel="z (m)") +axTz = Axis(fig[3, 2], xlabel="Temperature (ᵒC)", ylabel="z (m)") +axSz = Axis(fig[3, 3], xlabel="Salinity (g kg⁻¹)", ylabel="z (m)") +axNz = Axis(fig[3, 4], xlabel="Buoyancy frequency (s⁻²)", ylabel="z (m)") +axκz = Axis(fig[3, 5], xlabel="Eddy diffusivity (m² s⁻¹)", ylabel="z (m)", xscale=log10) +axez = Axis(fig[3, 6], xlabel="Turbulent kinetic energy (m² s⁻²)", ylabel="z (m)", xscale=log10) + +title = @sprintf("Single column simulation at %.2f, %.2f", φ★, λ★) +Label(fig[0, 1:6], title) + +slider = Slider(fig[4, 1:6], range=1:Nt, startvalue=1) +n = slider.value + +times = (times .- times[1]) ./days +tn = @lift times[$n] + +colors = Makie.wong_colors() + +#lines!(axu, times, uat, color=colors[1]) +#lines!(axu, times, vat, color=colors[2]) + +ρₒ = coupled_model.fluxes.ocean_reference_density +Jᵘt = interior(τˣt, 1, 1, 1, :) ./ ρₒ +Jᵛt = interior(τʸt, 1, 1, 1, :) ./ ρₒ +u★ = @. (Jᵘt^2 + Jᵛt^2)^(1/4) + +lines!(axu, times, interior(ut, 1, 1, Nz, :), color=colors[1], label="Zonal") +lines!(axu, times, interior(vt, 1, 1, Nz, :), color=colors[2], label="Meridional") +lines!(axu, times, u★, color=colors[3], label="Ocean-side u★") +vlines!(axu, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axu) + +lines!(axτ, times, interior(τˣt, 1, 1, 1, :), label="Zonal") +lines!(axτ, times, interior(τʸt, 1, 1, 1, :), label="Meridional") +vlines!(axτ, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axτ) + +lines!(axT, times, Tat .- 273.15, color=colors[1], linewidth=2, linestyle=:dash, label="Atmosphere temperature") +lines!(axT, times, interior(Tt, 1, 1, Nz, :), color=colors[2], linewidth=4, label="Ocean surface temperature") +vlines!(axT, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axT) + +lines!(axQ, times, interior(Qt, 1, 1, 1, :), color=colors[1], label="Total", linewidth=6) +lines!(axQ, times, interior(Qset, 1, 1, 1, :), color=colors[2], label="Sensible", linewidth=2) +lines!(axQ, times, interior(Qlat, 1, 1, 1, :), color=colors[3], label="Latent", linewidth=2) +lines!(axQ, times, - Qswt, color=colors[4], label="Shortwave", linewidth=2) +lines!(axQ, times, - Qlwt, color=colors[5], label="Longwave", linewidth=2) +vlines!(axQ, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axQ) + +#lines!(axF, times, interior(Jˢt, 1, 1, 1, :), label="Net freshwater flux") +lines!(axF, times, Pt, label="Prescribed freshwater flux") +lines!(axF, times, - interior(Et, 1, 1, 1, :), label="Evaporation") +vlines!(axF, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axF) + +lines!(axS, times, interior(St, 1, 1, Nz, :)) +vlines!(axS, tn, linewidth=4, color=(:black, 0.5)) + +zc = znodes(Tt) +zf = znodes(κt) +un = @lift interior(ut[$n], 1, 1, :) +vn = @lift interior(vt[$n], 1, 1, :) +Tn = @lift interior(Tt[$n], 1, 1, :) +Sn = @lift interior(St[$n], 1, 1, :) +κn = @lift interior(κt[$n], 1, 1, :) +en = @lift max.(1e-6, interior(et[$n], 1, 1, :)) +N²n = @lift interior(N²t[$n], 1, 1, :) + +scatterlines!(axuz, un, zc, label="u") +scatterlines!(axuz, vn, zc, label="v") +scatterlines!(axTz, Tn, zc) +scatterlines!(axSz, Sn, zc) +scatterlines!(axez, en, zc) +scatterlines!(axNz, N²n, zf) +scatterlines!(axκz, κn, zf) + +axislegend(axuz) + +Tmax = maximum(interior(Tt)) +Tmin = minimum(interior(Tt)) +xlims!(axTz, Tmin - 0.1, Tmax + 0.1) + +Nmax = maximum(interior(N²t)) +Nmin = minimum(interior(N²t)) +xlims!(axNz, Nmin / 2, Nmin * 1.1) + +emax = maximum(interior(et)) +xlims!(axez, 8e-7, emax * 1.1) +xlims!(axκz, 1e-7, 10) + +Smax = maximum(interior(St)) +Smin = minimum(interior(St)) +xlims!(axSz, Smin - 0.2, Smax + 0.2) + +display(fig) + +record(fig, "$(location)_single_column_simulation.mp4", 1:Nt, framerate=24) do nn + @info "Drawing frame $nn of $Nt..." + n[] = nn +# end +end +=# diff --git a/sandbox/one_degree_75S_75N.jl b/sandbox/one_degree_75S_75N.jl deleted file mode 100755 index 9d811165..00000000 --- a/sandbox/one_degree_75S_75N.jl +++ /dev/null @@ -1,333 +0,0 @@ -using ClimaOcean - -using Oceananigans -using Oceananigans.Units - -using Oceananigans.Operators: Δzᵃᵃᶜ -using Oceananigans.Architectures: on_architecture -using Oceananigans.Coriolis: HydrostaticSphericalCoriolis -using Oceananigans.Coriolis: WetCellEnstrophyConservingScheme -using Oceananigans.TurbulenceClosures: RiBasedVerticalDiffusivity, FluxTapering - -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: - CATKEVerticalDiffusivity, MixingLength - -using Statistics -using JLD2 -using Printf -using SeawaterPolynomials.TEOS10: TEOS10EquationOfState -using CUDA: @allowscalar - -# 1 degree resolution -Nx = 360 -Ny = 150 -Nz = 48 - -arch = GPU() -reference_density = 1029.0 -reference_heat_capacity = 3991.0 -reference_salinity = 34.0 - -output_prefix = "./near_global_lat_lon_$(Nx)_$(Ny)_$(Nz)_fine" -pickup = false -save_interval = 5days - -##### -##### Load surface boundary conditions and inital conditions -##### from ECCO version 4: -##### https://ecco.jpl.nasa.gov/drive/files -##### -##### Bathymetry is interpolated from ETOPO1: -##### https://www.ngdc.noaa.gov/mgg/global/ -##### - -bathymetry_file = jldopen("bathymetry_360_150_75S_75N.jld2") -bathymetry = bathymetry_file["bathymetry"] -close(bathymetry_file) - -@info "Reading initial conditions..."; start=time_ns() -initial_conditions_file = jldopen("initial_conditions_360_150_48_75S_75N.jld2") -T_init = initial_conditions_file["T"] -S_init = initial_conditions_file["S"] -close(initial_conditions_file) -@info "... read initial conditions (" * prettytime(1e-9 * (time_ns() - start)) * ")" - -# Files contain 12 arrays of monthly-averaged data from 1992 -@info "Reading boundary conditions..."; start=time_ns() -boundary_conditions_file = jldopen("surface_boundary_conditions_360_150_75S_75N.jld2") -τˣ = - boundary_conditions_file["τˣ"] ./ reference_density -τʸ = - boundary_conditions_file["τʸ"] ./ reference_density -T★ = + boundary_conditions_file["Tₛ"] -S★ = + boundary_conditions_file["Sₛ"] -Q★ = - boundary_conditions_file["Qᶠ"] ./ reference_density ./ reference_heat_capacity -F★ = - boundary_conditions_file["Sᶠ"] ./ reference_density .* reference_salinity -close(boundary_conditions_file) -@info "... read boundary conditions (" * prettytime(1e-9 * (time_ns() - start)) * ")" - -# Convert boundary conditions arrays to GPU -τˣ = on_architecture(arch, τˣ) -τʸ = on_architecture(arch, τʸ) -target_sea_surface_temperature = T★ = on_architecture(arch, T★) -target_sea_surface_salinity = S★ = on_architecture(arch, S★) -surface_temperature_flux = Q★ = on_architecture(arch, Q★) -surface_salt_flux = F★ = on_architecture(arch, F★) - -# Stretched faces from ECCO Version 4 (49 levels in the vertical) -z_faces = ClimaOcean.VerticalGrids.z_49_levels_10_to_400_meter_spacing - -# A spherical domain -underlying_grid = LatitudeLongitudeGrid(arch, - size = (Nx, Ny, Nz), - longitude = (-180, 180), - latitude = (-75, 75), - halo = (5, 5, 5), - z = z_faces) - -grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bathymetry)) - -@info "Created $grid" - -##### -##### Physics and model setup -##### - -const surface_νz = 1e-2 -const background_νz = 1e-4 -const background_κz = 1e-5 - -@inline νz(x, y, z, t) = ifelse(z > -49, surface_νz, background_νz) - -horizontal_viscosity = HorizontalScalarDiffusivity(ν=5e4) -vertical_mixing = RiBasedVerticalDiffusivity() -vertical_viscosity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), - ν=νz, κ=background_κz) - -κ_skew = 900.0 # [m² s⁻¹] skew diffusivity -κ_symmetric = 900.0 # [m² s⁻¹] symmetric diffusivity - -gent_mcwilliams_diffusivity = IsopycnalSkewSymmetricDiffusivity(; κ_skew, κ_symmetric, - slope_limiter = FluxTapering(1e-2)) - -#closures = gent_mcwilliams_diffusivity - -closures = ( - vertical_viscosity, - horizontal_viscosity, - vertical_mixing, - gent_mcwilliams_diffusivity, -) - -##### -##### Boundary conditions / time-dependent fluxes -##### - -const Nyears = 2.0 -const Nmonths = 12 -const thirty_days = 30days - -@inline current_time_index(time, tot_months) = mod(unsafe_trunc(Int32, time / thirty_days), tot_months) + 1 -@inline next_time_index(time, tot_months) = mod(unsafe_trunc(Int32, time / thirty_days) + 1, tot_months) + 1 -@inline cyclic_interpolate(u₁::Number, u₂, time) = u₁ + mod(time / thirty_days, 1) * (u₂ - u₁) - -Δz_top = @allowscalar Δzᵃᵃᶜ(1, 1, grid.Nz, grid.underlying_grid) -Δz_bottom = @allowscalar Δzᵃᵃᶜ(1, 1, 1, grid.underlying_grid) - -@inline function surface_wind_stress(i, j, grid, clock, fields, τ) - time = clock.time - n₁ = current_time_index(time, Nmonths) - n₂ = next_time_index(time, Nmonths) - - @inbounds begin - τ₁ = τ[i, j, n₁] - τ₂ = τ[i, j, n₂] - end - - return cyclic_interpolate(τ₁, τ₂, time) -end - -Δz_top = @allowscalar grid.Δzᵃᵃᶜ[Nz] - -using Oceananigans.Operators: ℑxyᶠᶜᵃ, ℑxyᶜᶠᵃ - -# Linear bottom drag: -μ = 0.003 # Non dimensional - -@inline speedᶠᶜᶜ(i, j, k, grid, fields) = @inbounds sqrt(fields.u[i, j, k]^2 + ℑxyᶠᶜᵃ(i, j, k, grid, fields.v)^2) -@inline speedᶜᶠᶜ(i, j, k, grid, fields) = @inbounds sqrt(fields.v[i, j, k]^2 + ℑxyᶜᶠᵃ(i, j, k, grid, fields.u)^2) - -@inline u_bottom_drag(i, j, grid, clock, fields, μ) = @inbounds - μ * fields.u[i, j, 1] * speedᶠᶜᶜ(i, j, 1, grid, fields) -@inline v_bottom_drag(i, j, grid, clock, fields, μ) = @inbounds - μ * fields.v[i, j, 1] * speedᶜᶠᶜ(i, j, 1, grid, fields) - -@inline u_immersed_bottom_drag(i, j, k, grid, clock, fields, μ) = @inbounds - μ * fields.u[i, j, k] * speedᶠᶜᶜ(i, j, k, grid, fields) -@inline v_immersed_bottom_drag(i, j, k, grid, clock, fields, μ) = @inbounds - μ * fields.v[i, j, k] * speedᶜᶠᶜ(i, j, k, grid, fields) - -drag_u = FluxBoundaryCondition(u_immersed_bottom_drag, discrete_form=true, parameters = μ) -drag_v = FluxBoundaryCondition(v_immersed_bottom_drag, discrete_form=true, parameters = μ) - -no_slip_bc = ValueBoundaryCondition(0) - -u_immersed_bc = ImmersedBoundaryCondition(bottom = drag_u, - west = no_slip_bc, - east = no_slip_bc, - south = no_slip_bc, - north = no_slip_bc) - -v_immersed_bc = ImmersedBoundaryCondition(bottom = drag_v, - west = no_slip_bc, - east = no_slip_bc, - south = no_slip_bc, - north = no_slip_bc) - -u_bottom_drag_bc = FluxBoundaryCondition(u_bottom_drag, discrete_form = true, parameters = μ) -v_bottom_drag_bc = FluxBoundaryCondition(v_bottom_drag, discrete_form = true, parameters = μ) - -u_wind_stress_bc = FluxBoundaryCondition(surface_wind_stress, discrete_form = true, parameters = τˣ); -v_wind_stress_bc = FluxBoundaryCondition(surface_wind_stress, discrete_form = true, parameters = τʸ); - -@inline function surface_temperature_relaxation(i, j, grid, clock, fields, p) - time = clock.time - - n₁ = current_time_index(time, Nmonths) - n₂ = next_time_index(time, Nmonths) - - @inbounds begin - T★₁ = p.T★[i, j, n₁] - T★₂ = p.T★[i, j, n₂] - Q★₁ = p.Q★[i, j, n₁] - Q★₂ = p.Q★[i, j, n₂] - T_surface = fields.T[i, j, grid.Nz] - end - - T★ = cyclic_interpolate(T★₁, T★₂, time) - Q★ = cyclic_interpolate(Q★₁, Q★₂, time) - - return Q★ + p.λ * (T_surface - T★) -end - -@inline function surface_salinity_relaxation(i, j, grid, clock, fields, p) - time = clock.time - - n₁ = current_time_index(time, Nmonths) - n₂ = next_time_index(time, Nmonths) - - @inbounds begin - S★₁ = p.S★[i, j, n₁] - S★₂ = p.S★[i, j, n₂] - F★₁ = p.F★[i, j, n₁] - F★₂ = p.F★[i, j, n₂] - S_surface = fields.S[i, j, grid.Nz] - end - - S★ = cyclic_interpolate(S★₁, S★₂, time) - F★ = cyclic_interpolate(F★₁, F★₂, time) - - return - F★ + p.λ * (S_surface - S★) -end - -T_relaxation_parameters = (λ = Δz_top/30days, - T★ = target_sea_surface_temperature, - Q★ = surface_temperature_flux) - -S_relaxation_parameters = (λ = Δz_top/90days, - S★ = target_sea_surface_salinity, - F★ = surface_salt_flux) - -T_surface_relaxation_bc = FluxBoundaryCondition(surface_temperature_relaxation, - discrete_form = true, - parameters = T_relaxation_parameters) - -S_surface_relaxation_bc = FluxBoundaryCondition(surface_salinity_relaxation, - discrete_form = true, - parameters = S_relaxation_parameters) - -u_bcs = FieldBoundaryConditions(top = u_wind_stress_bc, - bottom = u_bottom_drag_bc, - immersed = u_immersed_bc) - -v_bcs = FieldBoundaryConditions(top = v_wind_stress_bc, - bottom = v_bottom_drag_bc, - immersed = v_immersed_bc) - -T_bcs = FieldBoundaryConditions(top = T_surface_relaxation_bc) -S_bcs = FieldBoundaryConditions(top = S_surface_relaxation_bc) - -equation_of_state = TEOS10EquationOfState(; reference_density) -#equation_of_state = LinearEquationOfState() -buoyancy = SeawaterBuoyancy(; equation_of_state) -coriolis = HydrostaticSphericalCoriolis(scheme = WetCellEnstrophyConservingScheme()) -free_surface = ImplicitFreeSurface() - -@info "Building a model..."; start=time_ns() - -model = HydrostaticFreeSurfaceModel(; grid, free_surface, buoyancy, coriolis, - momentum_advection = VectorInvariant(), - tracer_advection = WENO(underlying_grid), - closure = closures, - boundary_conditions = (u=u_bcs, v=v_bcs, T=T_bcs, S=S_bcs), - tracers = (:T, :S)) -@info "... built $model." -@info "Model building time: " * prettytime(1e-9 * (time_ns() - start)) - -##### -##### Initial condition: -##### - -set!(model, T=T_init, S=S_init) - -# Because JMC's forcing starts at Jan 15 -model.clock.time = 345days - -##### -##### Simulation setup -##### - -Δt = 20minutes -simulation = Simulation(model; Δt, stop_iteration=100) #stop_time=Nyears * years) - -start_time = [time_ns()] - -function progress(sim) - wall_time = (time_ns() - start_time[1]) * 1e-9 - - u = sim.model.velocities.u - w = sim.model.velocities.w - - intw = Array(interior(w)) - max_w = findmax(intw) - - mw = max_w[1] - iw = max_w[2] - - @info @sprintf("Time: % 12s, iteration: %d, max(|u|): %.2e ms⁻¹, wmax: %.2e , loc: (%d, %d, %d), wall time: %s", - prettytime(sim.model.clock.time), - sim.model.clock.iteration, maximum(abs, u), mw, iw[1], iw[2], iw[3], - prettytime(wall_time)) - - start_time[1] = time_ns() - - return nothing -end - -simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -u, v, w = model.velocities -T = model.tracers.T -S = model.tracers.S - -simulation.output_writers[:surface_fields] = - JLD2OutputWriter(model, (; u, v, w, T, S), - schedule = TimeInterval(save_interval), - filename = output_prefix * "_snapshots", - with_halos = true, - overwrite_existing = true) - -# Let's goo! -@info "Running a simulation with Δt = $(prettytime(simulation.Δt))" - -run!(simulation; pickup) - -@info """ - Simulation took $(prettytime(simulation.run_wall_time)) - Free surface: $(typeof(model.free_surface).name.wrapper) - Time step: $(prettytime(Δt)) -""" diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 2009223e..37114adc 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -1,11 +1,18 @@ module ClimaOcean -export regrid_bathymetry -export stretched_vertical_faces -export PowerLawStretching, LinearStretching -export jra55_field_time_series -export ecco2_field, ECCO2Metadata -export initialize! +export + OceanSeaIceModel, + FreezingLimitedOceanTemperature, + Radiation, + JRA55_prescribed_atmosphere, + JRA55NetCDFBackend, + ecco2_field, + regrid_bathymetry, + stretched_vertical_faces, + PowerLawStretching, LinearStretching, + jra55_field_time_series, + ecco2_field, ECCO2Metadata, + initialize! using Oceananigans using Oceananigans.Operators: ℑxyᶠᶜᵃ, ℑxyᶜᶠᵃ @@ -21,6 +28,7 @@ using DataDeps @inline u_immersed_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.u[i, j, k] * spᶠᶜᶜ(i, j, k, grid, Φ) @inline v_immersed_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * spᶜᶠᶜ(i, j, k, grid, Φ) +include("OceanSeaIceModels/OceanSeaIceModels.jl") include("VerticalGrids.jl") include("InitialConditions/InitialConditions.jl") include("DataWrangling/DataWrangling.jl") @@ -32,5 +40,8 @@ using .Bathymetry using .DataWrangling: JRA55 using .DataWrangling: ECCO2 using .InitialConditions +using .DataWrangling: JRA55, ECCO2 +using .OceanSeaIceModels: OceanSeaIceModel, Radiation end # module + diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index fb2a5b4a..706c7dcf 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -52,45 +52,6 @@ end ##### FieldTimeSeries utilities ##### -# TODO: move this to Oceananigans - -@kernel function _interpolate_field_time_series!(target_fts, target_grid, target_location, - source_fts, source_grid, source_location) - - # 4D index, cool! - i, j, k, n = @index(Global, NTuple) - - source_field = view(source_fts, :, :, :, n) - target_node = node(i, j, k, target_grid, target_location...) - - @inbounds target_fts[i, j, k, n] = interpolate(target_node, source_field, source_location, source_grid) -end - -function interpolate_field_time_series!(target_fts, source_fts) - @assert target_fts.times == source_fts.times - times = target_fts.times - Nt = length(times) - - target_grid = target_fts.grid - source_grid = source_fts.grid - - @assert architecture(target_grid) == architecture(source_grid) - arch = architecture(target_grid) - - # Make locations - source_location = Tuple(L() for L in location(source_fts)) - target_location = Tuple(L() for L in location(target_fts)) - - launch!(arch, target_grid, size(target_fts), - _interpolate_field_time_series!, - target_fts.data, target_grid, target_location, - source_fts.data, source_grid, source_location) - - fill_halo_regions!(target_fts) - - return nothing -end - function save_field_time_series!(fts; path, name, overwrite_existing=false) overwrite_existing && rm(path; force=true) times = fts.times diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 28bfd255..e4ac88b7 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -28,16 +28,99 @@ ECCO2Metadata(name::Symbol) = ECCO2Metadata(name, 1992, 1, 2) filename(data::ECCO2Metadata) = "ecco2_" * string(data.name) * "_$(data.year)$(data.month)$(data.day).nc" +const ECCO2_Nx = 1440 +const ECCO2_Ny = 720 +const ECCO2_Nz = 50 + +# Vertical coordinate +const ECCO2_z = [ + -6128.75, + -5683.75, + -5250.25, + -4839.75, + -4452.25, + -4087.75, + -3746.25, + -3427.75, + -3132.25, + -2859.75, + -2610.25, + -2383.74, + -2180.13, + -1999.09, + -1839.64, + -1699.66, + -1575.64, + -1463.12, + -1357.68, + -1255.87, + -1155.72, + -1056.53, + -958.45, + -862.10, + -768.43, + -678.57, + -593.72, + -515.09, + -443.70, + -380.30, + -325.30, + -278.70, + -240.09, + -208.72, + -183.57, + -163.43, + -147.11, + -133.45, + -121.51, + -110.59, + -100.20, + -90.06, + -80.01, + -70.0, + -60.0, + -50.0, + -40.0, + -30.0, + -20.0, + -10.0, + 0.0, +] + +ecco2_file_names = Dict( + :temperature => "THETA.1440x720x50.19920102.nc", + :salinity => "SALT.1440x720x50.19920102.nc", + :sea_ice_thickness => "SIheff.1440x720.19920102.nc", + :sea_ice_area_fraction => "SIarea.1440x720.19920102.nc", + :u_velocity => "UVEL.1440x720.19920102.nc", + :v_velocity => "VVEL.1440x720.19920102.nc", +) + +variable_is_three_dimensional = Dict( + :temperature => true, + :salinity => true, + :u_velocity => true, + :v_velocity => true, + :sea_ice_thickness => false, + :sea_ice_area_fraction => false, +) + ecco2_short_names = Dict( - :temperature => "THETA", - :salinity => "SALT", - :effective_ice_thickness => "SIheff" + :temperature => "THETA", + :salinity => "SALT", + :u_velocity => "UVEL", + :v_velocity => "VVEL", + :sea_ice_thickness => "SIheff", + :sea_ice_area_fraction => "SIarea" ) ecco2_location = Dict( - :temperature => (Center, Center, Center), - :salinity => (Center, Center, Center), - :effective_ice_thickness => (Center, Center, Nothing) + :temperature => (Center, Center, Center), + :salinity => (Center, Center, Center), + :sea_ice_thickness => (Center, Center, Nothing), + :sea_ice_area_fraction => (Center, Center, Nothing), + :u_velocity => (Face, Center, Center), + :v_velocity => (Center, Face, Center), ) ecco2_depth_names = Dict( @@ -45,31 +128,39 @@ ecco2_depth_names = Dict( :salinity => "DEPTH_T", ) -variable_is_three_dimensional = Dict( - :temperature => true, - :salinity => true, - :effective_ice_thickness => false, +ecco2_urls = Dict( + :temperature => "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs", + :salinity => "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw", + :sea_ice_thickness => "https://www.dropbox.com/scl/fi/x0v9gjrfebwsef4tv1dvn/SIheff.1440x720.19920102.nc?rlkey=2uel3jtzbsplr28ejcnx3u6am", + :sea_ice_area_fraction => "https://www.dropbox.com/scl/fi/q14moq3201zicppu8ff8h/SIarea.1440x720.19920102.nc?rlkey=pt7pt80gr7r6mmjm9e0u4f5n1", + :u_velocity => "https://www.dropbox.com/scl/fi/myur9kpanc5mprrf5ge32/UVEL.1440x720x50.19920102.nc?rlkey=7a5dpvfgoc87yr6q5ktrqwndu", + :v_velocity => "https://www.dropbox.com/scl/fi/buic35gssyeyfqohenkeo/VVEL.1440x720x50.19920102.nc?rlkey=fau48w4t5ruop4s6gm8t7z0a0", ) -ecco2_file_names = Dict( - :temperature => "ecco2_temperature_19920102.nc", - :salinity => "ecco2_salinity_19920102.nc", - :effective_ice_thickness => "ecco2_effective_ice_thickness_19920102.nc", + +shortnames = Dict( + :temperature => "THETA", + :salinity => "SALT", + :sea_ice_thickness => "SIheff", + :sea_ice_area_fraction => "SIarea", + :u_velocity => "UVEL", + :v_velocity => "VVEL", ) -# Downloaded from https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N +surface_variable(variable_name) = variable_name == :sea_ice_thickness -ecco2_urls = Dict( - :temperature => "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/" * - "THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs&dl=0", +""" + construct_vertical_interfaces(ds, depth_name) - :salinity => "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/" * - "SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw&dl=0", +Constructs vertical interfaces for a given dataset `ds` and depth variable `depth_name`. - :effective_ice_thickness => "https://www.dropbox.com/scl/fi/x0v9gjrfebwsef4tv1dvn/" * - "SIheff.1440x720.19920102.nc?rlkey=2uel3jtzbsplr28ejcnx3u6am&dl=0" -) +# Arguments +- `ds`: The dataset containing the depth variable. +- `depth_name`: The name of the depth variable in the dataset. +# Returns +- `zf`: An array of interface depths. +""" function construct_vertical_interfaces(ds, depth_name) # Construct vertical coordinate depth = ds[depth_name][:] @@ -280,5 +371,23 @@ function set!(field::Field, ecco2_metadata::ECCO2Metadata; filename="./inpainted return field end +function ecco2_column(λ★, φ★) + Δ = 1/4 # resolution in degrees + φ₁ = -90 + Δ/2 + φ₂ = +90 - Δ/2 + λ₁ = 0 + Δ/2 + λ₂ = 360 - Δ/2 + φe = φ₁:Δ:φ₂ + λe = λ₁:Δ:λ₂ + + i★ = searchsortedfirst(λe, λ★) + j★ = searchsortedfirst(φe, φ★) + + longitude = (λe[i★] - Δ/2, λe[i★] + Δ/2) + latitude = (φe[j★] - Δ/2, φe[j★] + Δ/2) + + return i★, j★, longitude, latitude +end + end # module diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 785a5766..b83637be 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -2,68 +2,102 @@ module JRA55 using Oceananigans using Oceananigans.Units + +using Oceananigans.Architectures: arch_array +using Oceananigans.DistributedComputations +using Oceananigans.DistributedComputations: child_architecture using Oceananigans.BoundaryConditions: fill_halo_regions! +using Oceananigans.Grids: λnodes, φnodes, on_architecture +using Oceananigans.Fields: interpolate! +using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices + +using ClimaOcean.OceanSeaIceModels: + PrescribedAtmosphere, + TwoStreamDownwellingRadiation + +using CUDA: @allowscalar + using NCDatasets +using JLD2 +using Dates + +import Oceananigans.Fields: set! +import Oceananigans.OutputReaders: new_backend, update_field_time_series! using Downloads: download # A list of all variables provided in the JRA55 dataset: -jra55_short_names = (:freshwater_river_flux, - :freshwater_rain_flux, - :freshwater_snow_flux, - :freshwater_iceberg_flux, - :specific_humidity, - :sea_level_pressure, - :relative_humidity, - :downwelling_longwave_radiation, - :downwelling_shortwave_radiation, - :atmospheric_temperature, - :atmospheric_eastward_velocity, - :atmospheric_northward_velocity) - -file_names = Dict( - :freshwater_river_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers - :freshwater_rain_flux => "RYF.prra.1990_1991.nc", # Freshwater flux from rainfall - :freshwater_snow_flux => "RYF.prsn.1990_1991.nc", # Freshwater flux from snowfall - :freshwater_iceberg_flux => "RYF.licalvf.1990_1991.nc", # Freshwater flux from calving icebergs +JRA55_variable_names = (:river_freshwater_flux, + :rain_freshwater_flux, + :snow_freshwater_flux, + :iceberg_freshwater_flux, + :specific_humidity, + :sea_level_pressure, + :relative_humidity, + :downwelling_longwave_radiation, + :downwelling_shortwave_radiation, + :temperature, + :eastward_velocity, + :northward_velocity) + +filenames = Dict( + :river_freshwater_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers + :rain_freshwater_flux => "RYF.prra.1990_1991.nc", # Freshwater flux from rainfall + :snow_freshwater_flux => "RYF.prsn.1990_1991.nc", # Freshwater flux from snowfall + :iceberg_freshwater_flux => "RYF.licalvf.1990_1991.nc", # Freshwater flux from calving icebergs :specific_humidity => "RYF.huss.1990_1991.nc", # Surface specific humidity :sea_level_pressure => "RYF.psl.1990_1991.nc", # Sea level pressure :relative_humidity => "RYF.rhuss.1990_1991.nc", # Surface relative humidity :downwelling_longwave_radiation => "RYF.rlds.1990_1991.nc", # Downwelling longwave radiation :downwelling_shortwave_radiation => "RYF.rsds.1990_1991.nc", # Downwelling shortwave radiation - :atmospheric_temperature => "RYF.tas.1990_1991.nc", # Near-surface air temperature - :atmospheric_eastward_velocity => "RYF.uas.1990_1991.nc", # Eastward near-surface wind - :atmospheric_northward_velocity => "RYF.vas.1990_1991.nc", # Northward near-surface wind + :temperature => "RYF.tas.1990_1991.nc", # Near-surface air temperature + :eastward_velocity => "RYF.uas.1990_1991.nc", # Eastward near-surface wind + :northward_velocity => "RYF.vas.1990_1991.nc", # Northward near-surface wind ) -short_names = Dict( - :freshwater_river_flux => "friver", # Freshwater fluxes from rivers - :freshwater_rain_flux => "prra", # Freshwater flux from rainfall - :freshwater_snow_flux => "prsn", # Freshwater flux from snowfall - :freshwater_iceberg_flux => "licalvf", # Freshwater flux from calving icebergs +jra55_short_names = Dict( + :river_freshwater_flux => "friver", # Freshwater fluxes from rivers + :rain_freshwater_flux => "prra", # Freshwater flux from rainfall + :snow_freshwater_flux => "prsn", # Freshwater flux from snowfall + :iceberg_freshwater_flux => "licalvf", # Freshwater flux from calving icebergs :specific_humidity => "huss", # Surface specific humidity :sea_level_pressure => "psl", # Sea level pressure :relative_humidity => "rhuss", # Surface relative humidity :downwelling_longwave_radiation => "rlds", # Downwelling longwave radiation :downwelling_shortwave_radiation => "rsds", # Downwelling shortwave radiation - :atmospheric_temperature => "tas", # Near-surface air temperature - :atmospheric_eastward_velocity => "uas", # Eastward near-surface wind - :atmospheric_northward_velocity => "vas", # Northward near-surface wind + :temperature => "tas", # Near-surface air temperature + :eastward_velocity => "uas", # Eastward near-surface wind + :northward_velocity => "vas", # Northward near-surface wind +) + +field_time_series_short_names = Dict( + :river_freshwater_flux => "Fri", # Freshwater fluxes from rivers + :rain_freshwater_flux => "Fra", # Freshwater flux from rainfall + :snow_freshwater_flux => "Fsn", # Freshwater flux from snowfall + :iceberg_freshwater_flux => "Fic", # Freshwater flux from calving icebergs + :specific_humidity => "qa", # Surface specific humidity + :sea_level_pressure => "pa", # Sea level pressure + :relative_humidity => "rh", # Surface relative humidity + :downwelling_longwave_radiation => "Ql", # Downwelling longwave radiation + :downwelling_shortwave_radiation => "Qs", # Downwelling shortwave radiation + :temperature => "Ta", # Near-surface air temperature + :eastward_velocity => "ua", # Eastward near-surface wind + :northward_velocity => "va", # Northward near-surface wind ) urls = Dict( :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", - :freshwater_river_flux => "https://www.dropbox.com/scl/fi/21ggl4p74k4zvbf04nb67/" * + :river_freshwater_flux => "https://www.dropbox.com/scl/fi/21ggl4p74k4zvbf04nb67/" * "RYF.friver.1990_1991.nc?rlkey=ny2qcjkk1cfijmwyqxsfm68fz&dl=0", - :freshwater_rain_flux => "https://www.dropbox.com/scl/fi/5icl1gbd7f5hvyn656kjq/" * + :rain_freshwater_flux => "https://www.dropbox.com/scl/fi/5icl1gbd7f5hvyn656kjq/" * "RYF.prra.1990_1991.nc?rlkey=iifyjm4ppwyd8ztcek4dtx0k8&dl=0", - :freshwater_snow_flux => "https://www.dropbox.com/scl/fi/1r4ajjzb3643z93ads4x4/" * + :snow_freshwater_flux => "https://www.dropbox.com/scl/fi/1r4ajjzb3643z93ads4x4/" * "RYF.prsn.1990_1991.nc?rlkey=auyqpwn060cvy4w01a2yskfah&dl=0", - :freshwater_iceberg_flux => "https://www.dropbox.com/scl/fi/44nc5y27ohvif7lkvpyv0/" * + :iceberg_freshwater_flux => "https://www.dropbox.com/scl/fi/44nc5y27ohvif7lkvpyv0/" * "RYF.licalvf.1990_1991.nc?rlkey=w7rqu48y2baw1efmgrnmym0jk&dl=0", :specific_humidity => "https://www.dropbox.com/scl/fi/66z6ymfr4ghkynizydc29/" * @@ -81,23 +115,151 @@ urls = Dict( :downwelling_shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", - :atmospheric_temperature => "https://www.dropbox.com/scl/fi/fpl0npwi476w635g6lke9/" * - "RYF.tas.1990_1991.nc?rlkey=0skb9pe6lgbfbiaoybe7m945s&dl=0", + :temperature => "https://www.dropbox.com/scl/fi/fpl0npwi476w635g6lke9/" * + "RYF.tas.1990_1991.nc?rlkey=0skb9pe6lgbfbiaoybe7m945s&dl=0", - :atmospheric_eastward_velocity => "https://www.dropbox.com/scl/fi/86wetpqla2x97isp8092g/" * - "RYF.uas.1990_1991.nc?rlkey=rcaf18sh1yz0v9g4hjm1249j0&dl=0", + :eastward_velocity => "https://www.dropbox.com/scl/fi/86wetpqla2x97isp8092g/" * + "RYF.uas.1990_1991.nc?rlkey=rcaf18sh1yz0v9g4hjm1249j0&dl=0", - :atmospheric_northward_velocity => "https://www.dropbox.com/scl/fi/d38sflo9ddljstd5jwgml/" * - "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", + :northward_velocity => "https://www.dropbox.com/scl/fi/d38sflo9ddljstd5jwgml/" * + "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", ) +compute_bounding_nodes(::Nothing, ::Nothing, LH, hnodes) = nothing +compute_bounding_nodes(bounds, ::Nothing, LH, hnodes) = bounds + +# TODO: remove the allowscalar +function compute_bounding_nodes(::Nothing, grid, LH, hnodes) + hg = hnodes(grid, LH()) + h₁ = @allowscalar minimum(hg) + h₂ = @allowscalar maximum(hg) + return h₁, h₂ +end + +function compute_bounding_indices(::Nothing, hc) + Nh = length(hc) + return 1, Nh +end + +function compute_bounding_indices(bounds, hc) + h₁, h₂ = bounds + Nh = length(hc) + + # The following should work. If ᵒ are the extrema of nodes we want to + # interpolate to, and the following is a sketch of the JRA55 native grid, + # + # 1 2 3 4 5 + # | | | | | | + # | x ᵒ | x | x | x ᵒ | x | + # | | | | | | + # 1 2 3 4 5 6 + # + # then for example, we should find that (iᵢ, i₂) = (1, 5). + # So we want to reduce the first index by one, and limit them + # both by the available data. There could be some mismatch due + # to the use of different coordinate systems (ie whether λ ∈ (0, 360) + # which we may also need to handle separately. + i₁ = searchsortedfirst(hc, h₁) + i₂ = searchsortedfirst(hc, h₂) + i₁ = max(1, i₁ - 1) + i₂ = min(Nh, i₂) + + return i₁, i₂ +end + +infer_longitudinal_topology(::Nothing) = Periodic + +function infer_longitudinal_topology(λbounds) + λ₁, λ₂ = λbounds + TX = λ₂ - λ₁ ≈ 360 ? Periodic : Bounded + return TX +end + +function compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) + λbounds = compute_bounding_nodes(longitude, grid, LX, λnodes) + φbounds = compute_bounding_nodes(latitude, grid, LY, φnodes) + + i₁, i₂ = compute_bounding_indices(λbounds, λc) + j₁, j₂ = compute_bounding_indices(φbounds, φc) + TX = infer_longitudinal_topology(λbounds) + + return i₁, i₂, j₁, j₂, TX +end + +# Convert dates to range until Oceananigans supports dates natively +function jra55_times(native_times, start_time=DateTimeNoLeap(1900, 01, 01)) + Nt = length(native_times) + Δt = native_times[2] - native_times[1] # assume all times are equispaced + Δt = Second(Δt).value + + start_time = native_times[1] - start_time + start_time = Second(start_time).value + + stop_time = start_time + Δt * (Nt - 1) + times = start_time:Δt:stop_time + + return times +end + +struct JRA55NetCDFBackend <: AbstractInMemoryBackend{Int} + start :: Int + length :: Int +end + +""" + JRA55NetCDFBackend(length) + +Represents a JRA55 FieldTimeSeries backed by JRA55 native .nc files. """ - jra55_field_time_series(variable_name; +JRA55NetCDFBackend(length) = JRA55NetCDFBackend(1, length) + +Base.length(backend::JRA55NetCDFBackend) = backend.length +Base.summary(backend::JRA55NetCDFBackend) = string("JRA55NetCDFBackend(", backend.start, ", ", backend.length, ")") + +const JRA55NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend} + +function set!(fts::JRA55NetCDFFTS, path::String=fts.path, name::String=fts.name) + + ds = Dataset(path) + + # Note that each file should have the variables + # - ds["time"]: time coordinate + # - ds["lon"]: longitude at the location of the variable + # - ds["lat"]: latitude at the location of the variable + # - ds["lon_bnds"]: bounding longitudes between which variables are averaged + # - ds["lat_bnds"]: bounding latitudes between which variables are averaged + # - ds[shortname]: the variable data + + # Nodes at the variable location + λc = ds["lon"][:] + φc = ds["lat"][:] + LX, LY, LZ = location(fts) + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) + + ti = time_indices(fts) + ti = collect(ti) + data = ds[name][i₁:i₂, j₁:j₂, ti] + close(ds) + + copyto!(interior(fts, :, :, 1, :), data) + fill_halo_regions!(fts) + + return nothing +end + +new_backend(::JRA55NetCDFBackend, start, length) = JRA55NetCDFBackend(start, length) + +""" + JRA55_field_time_series(variable_name; architecture = CPU(), - time_indices = :, - url = urls[name], - filename = file_names[variable_name], - short_name = short_names[variable_name]) + location = nothing, + url = nothing, + filename = nothing, + shortname = nothing, + backend = InMemory(), + preprocess_chunk_size = 10, + preprocess_architecture = CPU(), + time_indices = nothing) Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, which describes one of the variables in the "repeat year forcing" dataset derived @@ -107,21 +269,21 @@ For more information about the derivation of the repeat year forcing dataset, se "Stewart et al., JRA55-do-based repeat year forcing datasets for driving ocean–sea-ice models", Ocean Modelling, 2020, https://doi.org/10.1016/j.ocemod.2019.101557. -The `variable_name`s (and their `short_name`s used in NetCDF files) +The `variable_name`s (and their `shortname`s used in NetCDF files) available from the JRA55-do are: - - `:freshwater_river_flux` ("friver") - - `:freshwater_rain_flux` ("prra") - - `:freshwater_snow_flux` ("prsn") - - `:freshwater_iceberg_flux` ("licalvf") + - `:river_freshwater_flux` ("friver") + - `:rain_freshwater_flux` ("prra") + - `:snow_freshwater_flux` ("prsn") + - `:iceberg_freshwater_flux` ("licalvf") - `:specific_humidity` ("huss") - `:sea_level_pressure` ("psl") - `:relative_humidity` ("rhuss") - `:downwelling_longwave_radiation` ("rlds") - `:downwelling_shortwave_radiation` ("rsds") - - `:atmospheric_temperature` ("ras") - - `:atmospheric_eastward_velocity` ("uas") - - `:atmospheric_northward_velocity` ("vas") + - `:temperature` ("ras") + - `:eastward_velocity` ("uas") + - `:northward_velocity` ("vas") Keyword arguments ================= @@ -140,83 +302,352 @@ Keyword arguments - `filename`: The name of the downloaded file. Default: `ClimaOcean.JRA55.filenames[variable_name]`. - - `short_name`: The "short name" of `variable_name` inside its NetCDF file. - Default: `ClimaOcean.JRA55.short_names[variable_name]`. + - `shortname`: The "short name" of `variable_name` inside its NetCDF file. + Default: `ClimaOcean.JRA55.jra55_short_names[variable_name]`. + + - `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. + If it does not exist it will be generated. + + - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is + loaded (not recommended). """ -function jra55_field_time_series(variable_name; +function JRA55_field_time_series(variable_name; architecture = CPU(), - time_indices = :, - url = urls[variable_name], - filename = file_names[variable_name], - short_name = short_names[variable_name]) + grid = nothing, + location = nothing, + url = nothing, + filename = nothing, + shortname = nothing, + latitude = nothing, + longitude = nothing, + backend = InMemory(), + time_indexing = Cyclical(), + preprocess_chunk_size = 10, + preprocess_architecture = CPU(), + time_indices = nothing) + + # OnDisk backends do not support time interpolation! + # Disallow OnDisk for JRA55 dataset loading + if backend isa OnDisk + msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") + throw(ArgumentError(msg)) + end + + if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) + variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) + variables_msg = prod(variable_strs) + msg = string("The variable :$variable_name is not provided by the JRA55-do dataset!", '\n', + "The variables provided by the JRA55-do dataset are:", '\n', + variables_msg) + + throw(ArgumentError(msg)) + end + + if !isnothing(filename) && !isfile(filename) && isnothing(url) + throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ + If intended, please provide both the filename and url that should be used \n \ + to download the new file.")) + end + + isnothing(shortname) && (shortname = jra55_short_names[variable_name]) + isnothing(filename) && (filename = filenames[variable_name]) + isnothing(url) && (url = urls[variable_name]) + + # Record some important user decisions + totally_in_memory = backend isa TotallyInMemory + on_native_grid = isnothing(grid) + !on_native_grid && backend isa JRA55NetCDFBackend && error("Can't use custom grid with JRA55NetCDFBackend.") + + jld2_filename = string("JRA55_repeat_year_", variable_name, ".jld2") + fts_name = field_time_series_short_names[variable_name] + + # Note, we don't re-use existing jld2 files. isfile(filename) || download(url, filename) + isfile(jld2_filename) && rm(jld2_filename) + + # Determine default time indices + if totally_in_memory + # In this case, the whole time series is in memory. + # Either the time series is short, or we are doing a limited-area + # simulation, like in a single column. So, we conservatively + # set a default `time_indices = 1:2`. + isnothing(time_indices) && (time_indices = 1:2) + time_indices_in_memory = time_indices + native_fts_architecture = architecture + else + # In this case, part or all of the time series will be stored in a file. + # Note: if the user has provided a grid, we will have to preprocess the + # .nc JRA55 data into a .jld2 file. In this case, `time_indices` refers + # to the time_indices that we will preprocess; + # by default we choose all of them. The architecture is only the + # architecture used for preprocessing, which typically will be CPU() + # even if we would like the final FieldTimeSeries on the GPU. + isnothing(time_indices) && (time_indices = :) + + if backend isa JRA55NetCDFBackend + time_indices_in_memory = 1:length(backend) + native_fts_architecture = architecture + else # then `time_indices_in_memory` refers to preprocessing + maximum_index = min(preprocess_chunk_size, length(time_indices)) + time_indices_in_memory = 1:maximum_index + native_fts_architecture = preprocess_architecture + end + end + + # Set a default location. + if isnothing(location) + LX = LY = Center + else + LX, LY = location + end ds = Dataset(filename) # Note that each file should have the variables - # ds["time"]: time coordinate - # ds["lon"]: longitude at the location of the variable - # ds["lat"]: latitude at the location of the variable - # ds["lon_bnds"]: bounding longitudes between which variables are averaged - # ds["lat_bnds"]: bounding latitudes between which variables are averaged - # ds[short_name]: the variable data + # - ds["time"]: time coordinate + # - ds["lon"]: longitude at the location of the variable + # - ds["lat"]: latitude at the location of the variable + # - ds["lon_bnds"]: bounding longitudes between which variables are averaged + # - ds["lat_bnds"]: bounding latitudes between which variables are averaged + # - ds[shortname]: the variable data - # Extract variable data - data = ds[short_name][:, :, time_indices] + # Nodes at the variable location + λc = ds["lon"][:] + φc = ds["lat"][:] - # Make the JRA55 grid - λ = ds["lon_bnds"][1, :] - φ = ds["lat_bnds"][1, :] - times = ds["time"][time_indices] - - close(ds) + # Interfaces for the "native" JRA55 grid + λn = ds["lon_bnds"][1, :] + φn = ds["lat_bnds"][1, :] # The .nc coordinates lon_bnds and lat_bnds do not include # the last interface, so we push them here. - push!(φ, 90) - push!(λ, λ[1] + 360) - - Nx = length(λ) - 1 - Ny = length(φ) - 1 - - grid = LatitudeLongitudeGrid(architecture, - size = (Nx, Ny); - longitude = λ, - latitude = φ, - topology = (Periodic, Bounded, Flat)) - - # Hack together the `times` for the JRA55 dataset we are currently using. - # We might want to use the acutal dates instead though. - # So the following code maybe should change. - Δt = 3hours # just what it is - Nt = length(times) - start_time = 0 # Note: the forcing start at Jan 1 of the repeat year. - stop_time = Δt * (Nt - 1) - times = start_time:Δt:stop_time + push!(φn, 90) + push!(λn, λn[1] + 360) + + # TODO: support loading just part of the JRA55 data. + # Probably with arguments that take latitude, longitude bounds. + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) + + native_times = ds["time"][time_indices] + data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + λr = λn[i₁:i₂+1] + φr = φn[j₁:j₂+1] + Nrx, Nry, Nt = size(data) + close(ds) - boundary_conditions = FieldBoundaryConditions(grid, (Center, Center, Nothing)) - fts = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions) + JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture, Float32; + halo = (3, 3), + size = (Nrx, Nry), + longitude = λr, + latitude = φr, + topology = (TX, Bounded, Flat)) + + boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) + times = jra55_times(native_times) + + if backend isa JRA55NetCDFBackend + fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + backend, + time_indexing, + boundary_conditions, + path = filename, + name = shortname) + + # Fill the data in a GPU-friendly manner + copyto!(interior(fts, :, :, 1, :), data) + fill_halo_regions!(fts) - # Fill the data - interior(fts, :, :, 1, :) .= data[:, :, :] + return fts + else + # Make times into an array for later preprocessing + if !totally_in_memory + times = collect(times) + end - # Fill halo regions so we can interpolate to finer grids - Nt = length(times) - chunk_size = 100 - if Nt <= chunk_size # one chunk will do - fill_halo_regions!(fts) - else # need multiple chunks - start = 1 - while start < Nt - stop = min(Nt, start + chunk_size - 1) - fts_chunk = Tuple(fts[n] for n = start:stop) - fill_halo_regions!(fts_chunk) - start += chunk_size + native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + time_indexing, + boundary_conditions) + + # Fill the data in a GPU-friendly manner + copyto!(interior(native_fts, :, :, 1, :), data) + fill_halo_regions!(native_fts) + + if on_native_grid && totally_in_memory + return native_fts + + elseif totally_in_memory # but not on the native grid! + boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) + fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; time_indexing, boundary_conditions) + interpolate!(fts, native_fts) + return fts + end + end + + @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." + + preprocessing_grid = on_native_grid ? JRA55_native_grid : grid + + # Re-open the dataset! + ds = Dataset(filename) + all_datetimes = ds["time"][time_indices] + all_Nt = length(all_datetimes) + + all_times = jra55_times(all_datetimes) + + on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, all_times; + boundary_conditions, + backend = OnDisk(), + path = jld2_filename, + name = fts_name) + + # Save data to disk, one field at a time + start_clock = time_ns() + n = 1 # on disk + m = 0 # in memory + + times_in_memory = all_times[time_indices_in_memory] + + fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, times_in_memory; + boundary_conditions, + backend = InMemory(), + path = jld2_filename, + name = fts_name) + + # Re-compute data + new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + + if !on_native_grid + copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) + fill_halo_regions!(native_fts) + interpolate!(fts, native_fts) + else + copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) + end + + while n <= all_Nt + print(" ... processing time index $n of $all_Nt \r") + + if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory + m += 1 + else # load new data + # Update time_indices + time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size + n₁ = first(time_indices_in_memory) + + # Clip time_indices if they extend past the end of the dataset + if last(time_indices_in_memory) > all_Nt + time_indices_in_memory = UnitRange(n₁, all_Nt) + end + + # Re-compute times + new_times = jra55_times(all_times[time_indices_in_memory], all_times[n₁]) + native_fts.times = new_times + + # Re-compute data + new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + fts.times = new_times + + if !on_native_grid + copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) + fill_halo_regions!(native_fts) + interpolate!(fts, native_fts) + else + copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) + end + + m = 1 # reset end + + @show fts[m] + + set!(on_disk_fts, fts[m], n, fts.times[m]) + + n += 1 + end + + elapsed = 1e-9 * (time_ns() - start_clock) + elapsed_str = prettytime(elapsed) + @info " ... done ($elapsed_str)" * repeat(" ", 20) + + close(ds) + + user_fts = FieldTimeSeries(jld2_filename, fts_name; architecture, backend, time_indexing) + fill_halo_regions!(user_fts) + + return user_fts +end + +const AA = Oceananigans.Architectures.AbstractArchitecture + +JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = + JRA55_prescribed_atmosphere(CPU(), time_indices; kw...) + +JRA55_prescribed_atmosphere(arch::Distributed, time_indices=Colon(); kw...) = + JRA55_prescribed_atmosphere(child_architecture(arch), time_indices; kw...) + +# TODO: allow the user to pass dates +function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); + backend = nothing, + time_indexing = Cyclical(), + reference_height = 2, # meters + other_kw...) + + if isnothing(backend) # apply a default + Ni = try + length(time_indices) + catch + Inf + end + + # Manufacture a default for the number of fields to keep InMemory + Nf = min(24, Ni) + backend = JRA55NetCDFBackend(Nf) end - return fts + kw = (; time_indices, time_indexing, backend, architecture) + kw = merge(kw, other_kw) + + ua = JRA55_field_time_series(:eastward_velocity; kw...) + va = JRA55_field_time_series(:northward_velocity; kw...) + Ta = JRA55_field_time_series(:temperature; kw...) + qa = JRA55_field_time_series(:specific_humidity; kw...) + ra = JRA55_field_time_series(:relative_humidity; kw...) + pa = JRA55_field_time_series(:sea_level_pressure; kw...) + Fra = JRA55_field_time_series(:rain_freshwater_flux; kw...) + Fsn = JRA55_field_time_series(:snow_freshwater_flux; kw...) + Fri = JRA55_field_time_series(:river_freshwater_flux; kw...) + Fic = JRA55_field_time_series(:iceberg_freshwater_flux; kw...) + Ql = JRA55_field_time_series(:downwelling_longwave_radiation; kw...) + Qs = JRA55_field_time_series(:downwelling_shortwave_radiation; kw...) + + times = ua.times + + velocities = (u = ua, + v = va) + + tracers = (T = Ta, + q = qa, + r = ra) + + freshwater_flux = (rain = Fra, + snow = Fsn, + rivers = Fri, + icebergs = Fic) + + pressure = pa + + downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qs, longwave=Ql) + + atmosphere = PrescribedAtmosphere(times, eltype(ua); + velocities, + freshwater_flux, + tracers, + downwelling_radiation, + reference_height, + pressure) + + return atmosphere end end # module diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl new file mode 100644 index 00000000..8a423205 --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -0,0 +1,68 @@ +module CrossRealmFluxes + +using Oceananigans + +export Radiation, + OceanSeaIceSurfaceFluxes + +using ..OceanSeaIceModels: SKOFTS, default_gravitational_acceleration + +import ..OceanSeaIceModels: surface_velocities, + surface_tracers + +##### +##### Utilities +##### + +@inline stateindex(a::Number, i, j, k, time) = a +@inline stateindex(a::SKOFTS, i, j, k, time) = @inbounds a[i, j, k, time] +@inline stateindex(a::AbstractArray, i, j, k, time) = @inbounds a[i, j, k] +@inline Δϕt²(i, j, k, grid, ϕ1, ϕ2, time) = (stateindex(ϕ1, i, j, k, time) - stateindex(ϕ2, i, j, k, time))^2 + +@inline function stateindex(a::Tuple, i, j, k, time) + N = length(a) + ntuple(Val(N)) do n + stateindex(a[n], i, j, k, time) + end +end + +@inline function stateindex(a::NamedTuple, i, j, k, time) + vals = stateindex(values(a), i, j, k, time) + names = keys(a) + return NamedTuple{names}(vals) +end + +function surface_flux(f::Field) + top_bc = f.boundary_conditions.top + if top_bc isa BoundaryCondition{<:Oceananigans.BoundaryConditions.Flux} + return top_bc.condition + else + return nothing + end +end + +function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) + grid = ocean.model.grid + Nz = size(grid, 3) + u = view(ocean.model.velocities.u.data, :, :, Nz) + v = view(ocean.model.velocities.v.data, :, :, Nz) + w = view(ocean.model.velocities.w.data, :, :, Nz+1) + return (; u, v, w) +end + +function surface_tracers(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) + grid = ocean.model.grid + Nz = size(grid, 3) + tracers = ocean.model.tracers + names = keys(tracers) + sfc_tracers = NamedTuple(name => view(tracers[name].data, :, :, Nz) for name in names) + return sfc_tracers +end + +include("radiation.jl") +include("similarity_theory_turbulent_fluxes.jl") +include("ocean_sea_ice_surface_fluxes.jl") +include("sea_ice_ocean_fluxes.jl") +# include("atmosphere_sea_ice_fluxes.jl") + +end # module diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_sea_ice_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_sea_ice_fluxes.jl new file mode 100644 index 00000000..5035e0f4 --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_sea_ice_fluxes.jl @@ -0,0 +1,6 @@ +using ClimaSeaIce: SlabSeaIceModel + +sea_ice_thickness(sea_ice::Simulation{<:SlabSeaIceModel}) = sea_ice.model.ice_thickness +sea_ice_thickness(::Nothing) = nothing + +# Nothing yet... diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl new file mode 100644 index 00000000..a71484e5 --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -0,0 +1,477 @@ +using StaticArrays +using Thermodynamics +using SurfaceFluxes + +using ..OceanSeaIceModels: reference_density, + heat_capacity, + sea_ice_concentration, + downwelling_radiation, + freshwater_flux + +using ClimaSeaIce: SlabSeaIceModel + +using Oceananigans: HydrostaticFreeSurfaceModel, architecture +using Oceananigans.Grids: inactive_node, node +using Oceananigans.BoundaryConditions: fill_halo_regions! +using Oceananigans.Fields: ConstantField, interpolate +using Oceananigans.Utils: launch!, Time + +# using Oceananigans.OutputReaders: extract_field_time_series, update_field_time_series! + +using Oceananigans.Operators: ℑxᶜᵃᵃ, ℑyᵃᶜᵃ, ℑxᶠᵃᵃ, ℑyᵃᶠᵃ + +using KernelAbstractions: @kernel, @index + +##### +##### Container for organizing information related to fluxes +##### + +struct OceanSeaIceSurfaceFluxes{T, P, C, R, PI, PC, FT, UN} + turbulent :: T + prescribed :: P + total :: C + radiation :: R + previous_ice_thickness :: PI + previous_ice_concentration :: PC + # The ocean is Boussinesq, so these are _only_ coupled properties: + ocean_reference_density :: FT + ocean_heat_capacity :: FT + freshwater_density :: FT + ocean_temperature_units :: UN +end + +# Possible units for temperature and salinity +struct DegreesCelsius end +struct DegreesKelvin end + +const celsius_to_kelvin = 273.15 +@inline convert_to_kelvin(::DegreesCelsius, T::FT) where FT = T + convert(FT, celsius_to_kelvin) +@inline convert_to_kelvin(::DegreesKelvin, T) = T + +Base.summary(crf::OceanSeaIceSurfaceFluxes) = "OceanSeaIceSurfaceFluxes" +Base.show(io::IO, crf::OceanSeaIceSurfaceFluxes) = print(io, summary(crf)) + +const SlabSeaIceSimulation = Simulation{<:SlabSeaIceModel} + +function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; + atmosphere = nothing, + radiation = nothing, + freshwater_density = 1000, + ocean_temperature_units = DegreesCelsius(), + ocean_reference_density = reference_density(ocean), + ocean_heat_capacity = heat_capacity(ocean)) + + grid = ocean.model.grid + FT = eltype(grid) + + ocean_reference_density = convert(FT, ocean_reference_density) + ocean_heat_capacity = convert(FT, ocean_heat_capacity) + freshwater_density = convert(FT, freshwater_density) + + if !isnothing(atmosphere) + # It's the "thermodynamics gravitational acceleration" + # (as opposed to the one used for the free surface) + gravitational_acceleration = ocean.model.buoyancy.model.gravitational_acceleration + similarity_theory = SimilarityTheoryTurbulentFluxes(grid; gravitational_acceleration) + else + similarity_theory = nothing + end + + prescribed_fluxes = nothing + + if sea_ice isa SlabSeaIceSimulation + previous_ice_thickness = deepcopy(sea_ice.model.ice_thickness) + previous_ice_concentration = deepcopy(sea_ice.model.ice_concentration) + else + previous_ice_thickness = nothing + previous_ice_concentration = nothing + end + + ocean_grid = ocean.model.grid + ρₒ = ocean_reference_density + Jᵘ = surface_flux(ocean.model.velocities.u) + Jᵛ = surface_flux(ocean.model.velocities.v) + Jᵘᶜᶜᶜ = Field{Center, Center, Nothing}(ocean_grid) + Jᵛᶜᶜᶜ = Field{Center, Center, Nothing}(ocean_grid) + + ocean_momentum_fluxes = (u = Jᵘ, # fluxes used in the model + v = Jᵛ, # + τˣ = ρₒ * Jᵘ, # momentum fluxes multiplied by reference density + τʸ = ρₒ * Jᵛ, # + uᶜᶜᶜ = Jᵘᶜᶜᶜ, # fluxes computed by bulk formula at cell centers + vᶜᶜᶜ = Jᵛᶜᶜᶜ) + + tracers = ocean.model.tracers + ocean_tracer_fluxes = NamedTuple(name => surface_flux(tracers[name]) for name in keys(tracers)) + + cₚ = ocean_heat_capacity + ocean_heat_flux = ρₒ * cₚ * ocean_tracer_fluxes.T + + total_ocean_fluxes = (momentum = ocean_momentum_fluxes, + tracers = ocean_tracer_fluxes, + heat = ocean_heat_flux) + + total_fluxes = (; ocean=total_ocean_fluxes) + + return OceanSeaIceSurfaceFluxes(similarity_theory, + prescribed_fluxes, + total_fluxes, + radiation, + previous_ice_thickness, + previous_ice_concentration, + ocean_reference_density, + ocean_heat_capacity, + freshwater_density, + ocean_temperature_units) +end + +##### +##### Surface flux computation +##### + +const c = Center() +const f = Face() + +function compute_atmosphere_ocean_fluxes!(coupled_model) + ocean = coupled_model.ocean + sea_ice = coupled_model.sea_ice + atmosphere = coupled_model.atmosphere + atmosphere_grid = atmosphere.grid + + # Basic model properties + grid = ocean.model.grid + arch = architecture(grid) + clock = coupled_model.clock + + # Ocean, atmosphere, and sea ice state + ocean_velocities = surface_velocities(ocean) + ocean_tracers = surface_tracers(ocean) + ice_concentration = sea_ice_concentration(sea_ice) + + # Fluxes, and flux contributors + centered_velocity_fluxes = (u = coupled_model.fluxes.total.ocean.momentum.uᶜᶜᶜ, + v = coupled_model.fluxes.total.ocean.momentum.vᶜᶜᶜ) + + staggered_velocity_fluxes = (u = coupled_model.fluxes.total.ocean.momentum.u, + v = coupled_model.fluxes.total.ocean.momentum.v) + + net_tracer_fluxes = coupled_model.fluxes.total.ocean.tracers + similarity_theory = coupled_model.fluxes.turbulent + prescribed_fluxes = coupled_model.fluxes.prescribed + radiation_properties = coupled_model.fluxes.radiation + + ocean_state = merge(ocean_velocities, ocean_tracers) + + atmosphere_velocities = map(u -> u.data, atmosphere.velocities) + atmosphere_tracers = map(c -> c.data, atmosphere.tracers) + atmosphere_pressure = atmosphere.pressure.data + + atmosphere_state = merge(atmosphere_velocities, atmosphere_tracers, (; p=atmosphere_pressure)) + freshwater_flux = map(ϕ -> ϕ.data, atmosphere.freshwater_flux) + + u = atmosphere.velocities.u # for example + atmosphere_times = u.times + atmosphere_backend = u.backend + atmosphere_time_indexing = u.time_indexing + + Qs = atmosphere.downwelling_radiation.shortwave + Ql = atmosphere.downwelling_radiation.longwave + downwelling_radiation = (shortwave=Qs.data, longwave=Ql.data) + + launch!(arch, grid, :xy, compute_atmosphere_ocean_similarity_theory_fluxes!, + similarity_theory.fields, + grid, + clock, + ocean_state, + coupled_model.fluxes.ocean_temperature_units, + atmosphere_state, + atmosphere_grid, + atmosphere_times, + atmosphere_backend, + atmosphere_time_indexing, + atmosphere.reference_height, # height at which the state is known + atmosphere.thermodynamics_parameters, + similarity_theory.roughness_lengths) + + launch!(arch, grid, :xy, assemble_atmosphere_ocean_fluxes!, + centered_velocity_fluxes, + net_tracer_fluxes, + grid, + clock, + ocean_state.T, + ocean_state.S, + coupled_model.fluxes.ocean_temperature_units, + similarity_theory.fields, + downwelling_radiation, + freshwater_flux, + atmosphere_grid, + atmosphere_times, + atmosphere_backend, + atmosphere_time_indexing, + radiation_properties, + coupled_model.fluxes.ocean_reference_density, + coupled_model.fluxes.ocean_heat_capacity, + coupled_model.fluxes.freshwater_density) + + # Note: I think this can be avoided if we modify the preceding kernel + # to compute from 0:Nx+1, ie in halo regions + fill_halo_regions!(centered_velocity_fluxes) + + launch!(arch, grid, :xy, reconstruct_momentum_fluxes!, + grid, staggered_velocity_fluxes, centered_velocity_fluxes) + + return nothing +end + +const c = Center() +const f = Face() + +@kernel function compute_atmosphere_ocean_similarity_theory_fluxes!(similarity_theory_fields, + grid, + clock, + ocean_state, + ocean_temperature_units, + atmos_state, + atmos_grid, + atmos_times, + atmos_backend, + atmos_time_indexing, + atmosphere_reference_height, + atmos_thermodynamics_parameters, + roughness_lengths) + + i, j = @index(Global, NTuple) + kᴺ = size(grid, 3) + + time = Time(clock.time) + + # Extract state variables at cell centers + @inbounds begin + # Ocean state + uₒ = ℑxᶜᵃᵃ(i, j, 1, grid, ocean_state.u) + vₒ = ℑyᵃᶜᵃ(i, j, 1, grid, ocean_state.v) + Tₒ = ocean_state.T[i, j, 1] + Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) + Sₒ = ocean_state.S[i, j, 1] + end + + @inbounds begin + # Atmos state, which is _assumed_ to exist at location = (c, c, nothing) + # The third index "k" should not matter but we put the correct index to get + # a surface node anyways. + X = node(i, j, kᴺ + 1, grid, c, c, f) + atmos_args = (atmos_grid, atmos_times, atmos_backend, atmos_time_indexing) + + uₐ = interp_atmos_time_series(atmos_state.u, X, time, atmos_args...) + vₐ = interp_atmos_time_series(atmos_state.v, X, time, atmos_args...) + + Tₐ = interp_atmos_time_series(atmos_state.T, X, time, atmos_args...) + pₐ = interp_atmos_time_series(atmos_state.p, X, time, atmos_args...) + qₐ = interp_atmos_time_series(atmos_state.q, X, time, atmos_args...) + end + + # Build thermodynamic and dynamic states in the atmosphere and surface. + # Notation: + # ⋅ 𝒬 ≡ thermodynamic state vector + # ⋅ 𝒰 ≡ "dynamic" state vector (thermodynamics + reference height + velocity) + ℂₐ = atmos_thermodynamics_parameters + 𝒬ₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₐ, qₐ) + + hₐ = atmosphere_reference_height # elevation of atmos variables relative to surface + Uₐ = SVector(uₐ, vₐ) + 𝒰ₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(hₐ, Uₐ, 𝒬ₐ) + + # Build surface state with saturated specific humidity + surface_type = AtmosphericThermodynamics.Liquid() + qₒ = seawater_saturation_specific_humidity(ℂₐ, Tₒ, Sₒ, 𝒬ₐ, + 0.98, #similarity_theory.water_mole_fraction, + ClasiusClapyeronSaturation(), #similarity_theory.water_vapor_saturation, + surface_type) + + # Thermodynamic and dynamic surface state + 𝒬₀ = thermodynamic_surface_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₒ, qₒ) + + h₀ = zero(grid) # surface height + Uₒ = SVector(uₒ, vₒ) + 𝒰₀ = dynamic_ocean_state = SurfaceFluxes.StateValues(h₀, Uₒ, 𝒬₀) + + Qv = similarity_theory_fields.latent_heat + Qc = similarity_theory_fields.sensible_heat + Fv = similarity_theory_fields.water_vapor + τx = similarity_theory_fields.x_momentum + τy = similarity_theory_fields.y_momentum + + @inbounds begin + Qcᵢ = Qc[i, j, 1] + Fvᵢ = Fv[i, j, 1] + τxᵢ = τx[i, j, 1] + τyᵢ = τy[i, j, 1] + end + + # Compute initial guess based on previous fluxes + ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) + cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity + + u★ = sqrt(sqrt(τxᵢ^2 + τyᵢ^2)) + θ★ = - Qcᵢ / (ρₐ * cₚ * u★) + q★ = - Fvᵢ / (ρₐ * u★) + Σ★ = SimilarityScales(u★, θ★, q★) + + g = default_gravitational_acceleration + ϰ = 0.4 + turbulent_fluxes = compute_similarity_theory_fluxes(roughness_lengths, + dynamic_ocean_state, + dynamic_atmos_state, + ℂₐ, g, ϰ, Σ★) + + kᴺ = size(grid, 3) # index of the top ocean cell + + inactive = inactive_node(i, j, kᴺ, grid, c, c, c) + + @inbounds begin + # +0: cooling, -0: heating + Qv[i, j, 1] = ifelse(inactive, 0, turbulent_fluxes.latent_heat) + Qc[i, j, 1] = ifelse(inactive, 0, turbulent_fluxes.sensible_heat) + Fv[i, j, 1] = ifelse(inactive, 0, turbulent_fluxes.water_vapor) + τx[i, j, 1] = ifelse(inactive, 0, turbulent_fluxes.x_momentum) + τy[i, j, 1] = ifelse(inactive, 0, turbulent_fluxes.y_momentum) + end +end + +@kernel function assemble_atmosphere_ocean_fluxes!(centered_velocity_fluxes, + net_tracer_fluxes, + grid, + clock, + ocean_temperature, + ocean_salinity, + ocean_temperature_units, + similarity_theory_fields, + downwelling_radiation, + prescribed_freshwater_flux, + atmos_grid, + atmos_times, + atmos_backend, + atmos_time_indexing, + radiation_properties, + ocean_reference_density, + ocean_heat_capacity, + freshwater_density) + + i, j = @index(Global, NTuple) + kᴺ = size(grid, 3) + time = Time(clock.time) + + @inbounds begin + Tₒ = ocean_temperature[i, j, 1] + Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) + Sₒ = ocean_salinity[i, j, 1] + + X = node(i, j, kᴺ + 1, grid, c, c, f) + atmos_args = (atmos_grid, atmos_times, atmos_backend, atmos_time_indexing) + + Qs = interp_atmos_time_series(downwelling_radiation.shortwave, X, time, atmos_args...) + Qℓ = interp_atmos_time_series(downwelling_radiation.longwave, X, time, atmos_args...) + + # Accumulate mass fluxes of freshwater due to rain, snow, rivers, + # icebergs, and whatever else. + Mp = interp_atmos_time_series(prescribed_freshwater_flux, X, time, atmos_args...) + + Qc = similarity_theory_fields.sensible_heat[i, j, 1] # sensible or "conductive" heat flux + Qv = similarity_theory_fields.latent_heat[i, j, 1] # latent heat flux + Mv = similarity_theory_fields.water_vapor[i, j, 1] # mass flux of water vapor + τx = similarity_theory_fields.x_momentum[i, j, 1] # zonal momentum flux + τy = similarity_theory_fields.y_momentum[i, j, 1] # meridional momentum flux + end + + # Compute heat fluxes, bulk flux first + Qd = net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation_properties) + Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, Tₒ) + ΣQ = Qd + Qu + Qc + Qv + + # Convert from a mass flux to a volume flux (aka velocity) + # by dividing by the density of freshwater. + # Also switch the sign, for some reason we are given freshwater flux as positive down. + ρᶠ = freshwater_density + ΣF = - Mp / ρᶠ + + # Add the contribution from the turbulent water vapor flux + Fv = Mv / ρᶠ + ΣF += Fv + + # Compute fluxes for u, v, T, S from momentum, heat, and freshwater fluxes + Jᵘ = centered_velocity_fluxes.u + Jᵛ = centered_velocity_fluxes.v + Jᵀ = net_tracer_fluxes.T + Jˢ = net_tracer_fluxes.S + + ρₒ = ocean_reference_density + cₒ = ocean_heat_capacity + + atmos_ocean_Jᵘ = τx / ρₒ + atmos_ocean_Jᵛ = τy / ρₒ + atmos_ocean_Jᵀ = ΣQ / (ρₒ * cₒ) + atmos_ocean_Jˢ = - Sₒ * ΣF + + # Mask fluxes over land for convenience + inactive = inactive_node(i, j, kᴺ, grid, c, c, c) + + @inbounds begin + Jᵘ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵘ) + Jᵛ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵛ) + Jᵀ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵀ) + Jˢ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jˢ) + end +end + +@kernel function reconstruct_momentum_fluxes!(grid, J, Jᶜᶜᶜ) + i, j = @index(Global, NTuple) + + @inbounds begin + J.u[i, j, 1] = ℑxᶠᵃᵃ(i, j, 1, grid, Jᶜᶜᶜ.u) + J.v[i, j, 1] = ℑyᵃᶠᵃ(i, j, 1, grid, Jᶜᶜᶜ.v) + end +end + +@inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation) + α = stateindex(radiation.reflection.ocean, i, j, 1, time) + return @inbounds - (1 - α) * Qs - Qℓ +end + +@inline function net_upwelling_radiation(i, j, grid, time, radiation, Tₒ) + σ = radiation.stefan_boltzmann_constant + ϵ = stateindex(radiation.emission.ocean, i, j, 1, time) + + # Note: positive implies _upward_ heat flux, and therefore cooling. + return ϵ * σ * Tₒ^4 +end + +##### +##### Utility for interpolating tuples of fields +##### + +# Note: assumes loc = (c, c, nothing) (and the third location should +# not matter.) +@inline interp_atmos_time_series(J, X, time, grid, args...) = + interpolate(X, time, J, (c, c, nothing), grid, args...) + +@inline interp_atmos_time_series(ΣJ::NamedTuple, args...) = + interp_atmos_time_series(values(ΣJ), args...) + +@inline interp_atmos_time_series(ΣJ::Tuple{<:Any}, args...) = + interp_atmos_time_series(ΣJ[1], args...) + + interp_atmos_time_series(ΣJ[2], args...) + +@inline interp_atmos_time_series(ΣJ::Tuple{<:Any, <:Any}, args...) = + interp_atmos_time_series(ΣJ[1], args...) + + interp_atmos_time_series(ΣJ[2], args...) + +@inline interp_atmos_time_series(ΣJ::Tuple{<:Any, <:Any, <:Any}, args...) = + interp_atmos_time_series(ΣJ[1], args...) + + interp_atmos_time_series(ΣJ[2], args...) + + interp_atmos_time_series(ΣJ[3], args...) + +@inline interp_atmos_time_series(ΣJ::Tuple{<:Any, <:Any, <:Any, <:Any}, args...) = + interp_atmos_time_series(ΣJ[1], args...) + + interp_atmos_time_series(ΣJ[2], args...) + + interp_atmos_time_series(ΣJ[3], args...) + + interp_atmos_time_series(ΣJ[4], args...) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl new file mode 100644 index 00000000..f9ca57be --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl @@ -0,0 +1,34 @@ +struct Radiation{FT, E, R} + emission :: E + reflection :: R + stefan_boltzmann_constant :: FT +end + +function Radiation(FT=Float64; + ocean_emissivity = 0.97, + sea_ice_emissivity = 1.0, + ocean_albedo = 0.3, + sea_ice_albedo = 0.7, + stefan_boltzmann_constant = 5.67e-8) + + ocean_emissivity isa Number && (ocean_emissivity = convert(FT, ocean_emissivity)) + sea_ice_emissivity isa Number && (sea_ice_emissivity = convert(FT, sea_ice_emissivity)) + ocean_albedo isa Number && (ocean_albedo = convert(FT, ocean_albedo)) + sea_ice_albedo isa Number && (sea_ice_albedo = convert(FT, sea_ice_albedo)) + + emission = SurfaceProperties(ocean_emissivity, sea_ice_emissivity) + reflection = SurfaceProperties(ocean_albedo, sea_ice_albedo) + + return Radiation(emission, + reflection, + convert(FT, stefan_boltzmann_constant)) +end + +Base.summary(r::Radiation) = "Radiation" +Base.show(io::IO, r::Radiation) = print(io, summary(osf)) + +struct SurfaceProperties{O, I} + ocean :: O + sea_ice :: I +end + diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl new file mode 100644 index 00000000..93ddea05 --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl @@ -0,0 +1,164 @@ +using Oceananigans.Operators: Δzᶜᶜᶜ + +function compute_sea_ice_ocean_fluxes!(coupled_model) + #compute_sea_ice_ocean_salinity_flux!(coupled_model) + sea_ice_ocean_latent_heat_flux!(coupled_model) + return nothing +end + +function compute_sea_ice_ocean_salinity_flux!(coupled_model) + # Compute salinity increment due to changes in ice thickness + + sea_ice = coupled_model.sea_ice + ocean = coupled_model.ocean + grid = ocean.model.grid + arch = architecture(grid) + Qˢ = ocean.model.tracers.S.boundary_conditions.top.condition + Sₒ = ocean.model.tracers.S + Sᵢ = sea_ice.model.ice_salinity + Δt = ocean.Δt + hⁿ = sea_ice.model.ice_thickness + h⁻ = coupled_model.fluxes.previous_ice_thickness + + launch!(arch, grid, :xy, _compute_sea_ice_ocean_salinity_flux!, + Qˢ, grid, hⁿ, h⁻, Sᵢ, Sₒ, Δt) + + return nothing +end + +@kernel function _compute_sea_ice_ocean_salinity_flux!(sea_ice_ocean_salinity_flux, + grid, + ice_thickness, + previous_ice_thickness, + ice_salinity, + ocean_salinity, + Δt) + i, j = @index(Global, NTuple) + + Nz = size(grid, 3) + + hⁿ = ice_thickness + h⁻ = previous_ice_thickness + Qˢ = sea_ice_ocean_salinity_flux + Sᵢ = ice_salinity + Sₒ = ocean_salinity + + @inbounds begin + # Change in thickness + Δh = hⁿ[i, j, 1] - h⁻[i, j, 1] + + # Update surface salinity flux. + # Note: the Δt below is the ocean time-step, eg. + # ΔS = ⋯ - ∮ Qˢ dt ≈ ⋯ - Δtₒ * Qˢ + Qˢ[i, j, 1] = Δh / Δt * (Sᵢ[i, j, 1] - Sₒ[i, j, Nz]) + + # Update previous ice thickness + h⁻[i, j, 1] = hⁿ[i, j, 1] + end +end + +function sea_ice_ocean_latent_heat_flux!(coupled_model) + ocean = coupled_model.ocean + sea_ice = coupled_model.sea_ice + ρₒ = coupled_model.fluxes.ocean_reference_density + cₒ = coupled_model.fluxes.ocean_heat_capacity + Qₒ = sea_ice.model.external_heat_fluxes.bottom + Tₒ = ocean.model.tracers.T + Sₒ = ocean.model.tracers.S + Δt = ocean.Δt + hᵢ = sea_ice.model.ice_thickness + + liquidus = sea_ice.model.phase_transitions.liquidus + grid = ocean.model.grid + arch = architecture(grid) + + # What about the latent heat removed from the ocean when ice forms? + # Is it immediately removed from the ocean? Or is it stored in the ice? + launch!(arch, grid, :xy, _compute_sea_ice_ocean_latent_heat_flux!, + Qₒ, grid, hᵢ, Tₒ, Sₒ, liquidus, ρₒ, cₒ, Δt) + + return nothing +end + +#= +function adjust_ice_covered_ocean_temperature!(coupled_model) + sea_ice_ocean_latent_heat_flux!(coupled_model) + sea_ice = coupled_model.sea_ice + Qₒ = sea_ice.model.external_heat_fluxes.bottom + parent(Qₒ) .= 0 + return nothing +end +=# + +@kernel function _compute_sea_ice_ocean_latent_heat_flux!(latent_heat_flux, + grid, + ice_thickness, + ocean_temperature, + ocean_salinity, + liquidus, + ρₒ, cₒ, Δt) + + i, j = @index(Global, NTuple) + + Nz = size(grid, 3) + Qₒ = latent_heat_flux + hᵢ = ice_thickness + Tₒ = ocean_temperature + Sₒ = ocean_salinity + + δQ = zero(grid) + icy_cell = @inbounds hᵢ[i, j, 1] > 0 # make ice bath approximation then + + for k = Nz:-1:1 + @inbounds begin + # Various quantities + Δz = Δzᶜᶜᶜ(i, j, k, grid) + Tᴺ = Tₒ[i, j, k] + Sᴺ = Sₒ[i, j, k] + end + + # Melting / freezing temperature at the surface of the ocean + Tₘ = melting_temperature(liquidus, Sᴺ) + + # Conditions for non-zero ice-ocean flux: + # - the ocean is below the freezing temperature, causing formation of ice. + freezing = Tᴺ < Tₘ + + # - We are at the surface and the cell is covered by ice. + icy_surface_cell = (k == Nz) & icy_cell + + # When there is a non-zero ice-ocean flux, we will instantaneously adjust the + # temperature of the grid cells accordingly. + adjust_temperature = freezing | icy_surface_cell + + # Compute change in ocean heat energy. + # + # - When Tᴺ < Tₘ, we heat the ocean back to melting temperature by extracting heat from the ice, + # assuming that the heat flux (which is carried by nascent ice crystals called frazil ice) floats + # instantaneously to the surface. + # + # - When Tᴺ > Tₘ and we are in a surface cell covered by ice, we assume equilibrium + # and cool the ocean by injecting excess heat into the ice. + # + δEₒ = adjust_temperature * ρₒ * cₒ * (Tₘ - Tᴺ) + + # Perform temperature adjustment + @inline Tₒ[i, j, k] = ifelse(adjust_temperature, Tₘ, Tᴺ) + + # Compute the heat flux from ocean into ice. + # + # A positive value δQ > 0 implies that the ocean is cooled; ie heat + # is fluxing upwards, into the ice. This occurs when applying the + # ice bath equilibrium condition to cool down a warm ocean (δEₒ < 0). + # + # A negative value δQ < 0 implies that heat is fluxed from the ice into + # the ocean, cooling the ice and heating the ocean (δEₒ > 0). This occurs when + # frazil ice is formed within the ocean. + + δQ -= δEₒ * Δz / Δt + end + + # Store ice-ocean flux + @inbounds Qₒ[i, j, 1] = δQ +end + diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl new file mode 100644 index 00000000..224ef4d4 --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -0,0 +1,528 @@ +using Oceananigans.Utils: prettysummary +using Oceananigans.Grids: AbstractGrid + +using Adapt +using Thermodynamics: Liquid +using SurfaceFluxes.Parameters: SurfaceFluxesParameters, AbstractSurfaceFluxesParameters +using SurfaceFluxes.UniversalFunctions: BusingerParams, BusingerType + +using Printf +using Thermodynamics: PhasePartition +using KernelAbstractions.Extras.LoopInfo: @unroll + +using ..PrescribedAtmospheres: PrescribedAtmosphereThermodynamicsParameters + +import Thermodynamics as AtmosphericThermodynamics +import Thermodynamics.Parameters: molmass_ratio + +import SurfaceFluxes.Parameters: + thermodynamics_params, + uf_params, + von_karman_const, + universal_func_type, + grav + + +##### +##### Bulk turbulent fluxes based on similarity theory +##### + +struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP, S, W, R, F} <: AbstractSurfaceFluxesParameters + gravitational_acceleration :: FT + von_karman_constant :: FT + bulk_velocity_scale :: ΔU + similarity_functions :: UF + thermodynamics_parameters :: TP + water_vapor_saturation :: S + water_mole_fraction :: W + roughness_lengths :: R + fields :: F +end + +const STTF = SimilarityTheoryTurbulentFluxes +@inline thermodynamics_params(fluxes::STTF) = fluxes.thermodynamics_parameters +@inline uf_params(fluxes::STTF) = fluxes.similarity_functions +@inline von_karman_const(fluxes::STTF) = fluxes.von_karman_constant +@inline grav(fluxes::STTF) = fluxes.gravitational_acceleration +@inline molmass_ratio(fluxes::STTF) = molmass_ratio(fluxes.thermodynamics_parameters) + +@inline universal_func_type(fluxes::STTF{<:Any, <:Any, <:BusingerParams}) = BusingerType() + +Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt(to, fluxes.gravitational_acceleration), + adapt(to, fluxes.von_karman_constant), + nothing, # adapt(to, fluxes.bulk_velocity_scale), + adapt(to, fluxes.similarity_functions), + adapt(to, fluxes.thermodynamics_parameters), + nothing, #adapt(to, fluxes.water_vapor_saturation), + nothing, #adapt(to, fluxes.water_mole_fraction), + adapt(to, fluxes.roughness_lengths), + adapt(to, fluxes.fields)) + +Base.summary(::SimilarityTheoryTurbulentFluxes{FT}) where FT = "SimilarityTheoryTurbulentFluxes{$FT}" + +struct ClasiusClapyeronSaturation end + +@inline function water_saturation_specific_humidity(::ClasiusClapyeronSaturation, ℂₐ, ρₛ, Tₛ) + p★ = AtmosphericThermodynamics.saturation_vapor_pressure(ℂₐ, Tₛ, Liquid()) + q★ = AtmosphericThermodynamics.q_vap_saturation_from_density(ℂₐ, Tₛ, ρₛ, p★) + return q★ +end + +struct LargeYeagerSaturation{FT} + c₁ :: FT + c₂ :: FT +end + +function LargeYeagerSaturation(FT=Float64; c₁ = 640380, c₂ = 5107.4) + return LargeYeagerSaturation(convert(FT, c₁), convert(FT, c₂)) +end + +const LYS = LargeYeagerSaturation +@inline water_saturation_specific_humidity(lys::LYS, ℂₐ, ρₛ, Tₛ) = lys.c₁ * exp(-lys.c₂ / Tₛ) / ρₛ + +function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) + print(io, summary(fluxes), '\n', + "├── gravitational_acceleration: ", prettysummary(fluxes.gravitational_acceleration), '\n', + "├── von_karman_constant: ", prettysummary(fluxes.von_karman_constant), '\n', + "├── bulk_velocity_scale: ", summary(fluxes.bulk_velocity_scale), '\n', + "├── similarity_function: ", summary(fluxes.similarity_function), '\n', + "├── water_mole_fraction: ", summary(fluxes.water_mole_fraction), '\n', + "├── water_vapor_saturation: ", summary(fluxes.water_vapor_saturation), '\n', + "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) +end + +const PATP = PrescribedAtmosphereThermodynamicsParameters + +function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; + gravitational_acceleration = default_gravitational_acceleration, + bulk_velocity_scale = nothing, + von_karman_constant = convert(FT, 0.4), + similarity_functions = businger_similarity_functions(FT), + thermodynamics_parameters = PATP(FT), + water_vapor_saturation = ClasiusClapyeronSaturation(), + water_mole_fraction = convert(FT, 0.98), + roughness_lengths = default_roughness_lengths(FT), + fields = nothing) + + return SimilarityTheoryTurbulentFluxes(convert(FT, gravitational_acceleration), + convert(FT, von_karman_constant), + bulk_velocity_scale, + similarity_functions, + thermodynamics_parameters, + water_vapor_saturation, + water_mole_fraction, + roughness_lengths, + fields) +end + +function SimilarityTheoryTurbulentFluxes(grid::AbstractGrid; kw...) + water_vapor = Field{Center, Center, Nothing}(grid) + latent_heat = Field{Center, Center, Nothing}(grid) + sensible_heat = Field{Center, Center, Nothing}(grid) + x_momentum = Field{Center, Center, Nothing}(grid) + y_momentum = Field{Center, Center, Nothing}(grid) + + fields = (; latent_heat, sensible_heat, water_vapor, x_momentum, y_momentum) + + return SimilarityTheoryTurbulentFluxes(eltype(grid); kw..., fields) +end + +# See SurfaceFluxes.jl for other parameter set options. +default_businger_parameters(FT=Float64) = BusingerParams{FT}(Pr_0 = convert(FT, 0.74), + a_m = convert(FT, 4.7), + a_h = convert(FT, 4.7), + ζ_a = convert(FT, 2.5), + γ = convert(FT, 4.42)) + +@inline function seawater_saturation_specific_humidity(atmosphere_thermodynamics_parameters, + surface_temperature, + surface_salinity, + atmos_state, + water_mole_fraction, + water_vapor_saturation, + ::Liquid) + + ℂₐ = atmosphere_thermodynamics_parameters + FT = eltype(ℂₐ) + Tₛ = surface_temperature + Sₛ = surface_salinity + ρₛ = atmos_state.ρ # surface density -- should we extrapolate to obtain this? + ρₛ = convert(FT, ρₛ) + + q★_H₂O = water_saturation_specific_humidity(water_vapor_saturation, ℂₐ, ρₛ, Tₛ) + x_H₂O = compute_water_mole_fraction(water_mole_fraction, Sₛ) + + # Return saturation specific humidity for salty seawater + return q★_H₂O * x_H₂O +end + +struct SalinityConstituent{FT} + molar_mass :: FT + mass_fraction :: FT +end + +struct WaterMoleFraction{FT, C} + water_molar_mass :: FT + salinity_constituents :: C +end + +function WaterMoleFraction(FT=Float64) + water_molar_mass = convert(FT, 18.02) + + # TODO: find reference for these + salinity_constituents = ( + chloride = SalinityConstituent{FT}(35.45, 0.56), + sodium = SalinityConstituent{FT}(22.99, 0.31), + sulfate = SalinityConstituent{FT}(96.06, 0.08), + magnesium = SalinityConstituent{FT}(24.31, 0.05), + ) + + return SeawaterComposition(water_molar_mass, salinity_constituents) +end + +@inline compute_water_mole_fraction(x_H₂O::Number, S) = x_H₂O + +@inline function compute_water_mole_fraction(wmf::WaterMoleFraction, S) + # TODO: express the concept of "ocean_salinity_units"? + s = S / 1000 # convert g/kg to concentration + + # Molecular weights + μ_H₂O = wmf.water_molar_mass + + # Salinity constituents: Cl, Na, SO₄, Mg + μ_Cl = wmf.salinity_constituents.chloride.molar_mass + μ_Na = wmf.salinity_constituents.sodium.molar_mass + μ_SO₄ = wmf.salinity_constituents.sulfate.molar_mass + μ_Mg = wmf.salinity_constituents.magnesium.molar_mass + + # Salinity constituent fractions + ϵ_Cl = wmf.salinity_constituents.chloride.mass_fraction + ϵ_Na = wmf.salinity_constituents.sodium.mass_fraction + ϵ_SO₄ = wmf.salinity_constituents.sulfate.mass_fraction + ϵ_Mg = wmf.salinity_constituents.magnesium.mass_fraction + + α = μ_H₂O * (ϵ_Cl/μ_Cl + ϵ_Na/μ_Na + ϵ_SO₄/μ_SO₄ + ϵ_Mg/μ_Mg) + + return (1 - s) / (1 - s + α * s) +end + + +@inline update_turbulent_flux_fields!(::Nothing, args...) = nothing + +@inline function update_turbulent_flux_fields!(fields, i, j, grid, fluxes) + return nothing +end + +@inline compute_similarity_theory_fluxes(turbulent_fluxes, atmos_state, surface_state) = + compute_similarity_theory_fluxes(turbulent_fluxes.roughness_lengths, turbulent_fluxes, atmos_state, surface_state) + +##### +##### Struct that represents a 3-tuple of momentum, heat, and water vapor +##### + +struct SimilarityScales{U, T, Q} + momentum :: U + temperature :: T + water_vapor :: Q +end + +# Convenience default with water_vapor component = nothing +SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature, nothing) + +##### +##### Interface into SurfaceFluxes.jl +##### + +# This is the case that SurfaceFluxes.jl can do +const NothingVaporRoughnessLength = SimilarityScales{<:Number, <:Number, Nothing} + +@inline function compute_similarity_theory_fluxes(roughness_lengths::NothingVaporRoughnessLength, + surface_state, + atmos_state, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant) + + # turbulent_fluxes, + # atmos_state, + # surface_state) + + FT = Float64 + similarity_functions = BusingerParams{FT}(Pr_0 = convert(FT, 0.74), + a_m = convert(FT, 4.7), + a_h = convert(FT, 4.7), + ζ_a = convert(FT, 2.5), + γ = convert(FT, 4.42)) + + turbulent_fluxes = SimilarityTheoryTurbulentFluxes(gravitational_acceleration, + von_karman_constant, + nothing, + similarity_functions, + thermodynamics_parameters, + nothing, + nothing, + nothing, + nothing) + + # Constant roughness lengths + ℓu = roughness_lengths.momentum + ℓθ = roughness_lengths.temperature + + # Solve for the surface fluxes with initial roughness length guess + Uᵍ = zero(ℓu) # gustiness + β = one(ℓu) # surface "resistance" + values = SurfaceFluxes.ValuesOnly(atmos_state, surface_state, ℓu, ℓθ, Uᵍ, β) + conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) + + fluxes = (; + sensible_heat = conditions.shf, + latent_heat = conditions.lhf, + water_vapor = conditions.evaporation, + x_momentum = conditions.ρτxz, + y_momentum = conditions.ρτyz, + ) + + return fluxes +end + +##### +##### Fixed-point iteration for roughness length +##### + +const ConstantRoughnessLength = SimilarityScales{<:Number, <:Number, <:Number} + +struct SimilarityFunction{FT, C} + a :: FT + b :: FT + c :: C +end + +@inline function (ψ::SimilarityFunction)(Ri) + a = ψ.a + b = ψ.b + c = ψ.c + + Ri⁻ = min(zero(Ri), Ri) + ϕ⁻¹ = (1 - b * Ri⁻)^c + ψ_unstable = log((1 + ϕ⁻¹)^2 * (1 + ϕ⁻¹^2) / 8) - (4 * atan(ϕ⁻¹) + π) / 2 + + ψ_stable = - a * Ri + + return ifelse(Ri < 0, ψ_unstable, ψ_stable) +end + +struct OneQuarter end +struct OneHalf end + +import Base: ^ +@inline ^(x, ::OneQuarter) = sqrt(sqrt(x)) +@inline ^(x, ::OneHalf) = sqrt(x) + +function businger_similarity_functions(FT=Float64) + au = convert(FT, 4.7) + bu = convert(FT, 15) + cu = OneQuarter() + ψu = SimilarityFunction(au, bu, cu) + + ah = convert(FT, 6.35) + bh = convert(FT, 9) + ch = OneHalf() + ψh = SimilarityFunction(ah, bh, ch) + + ψq = ψh + + return SimilarityScales(ψu, ψh, ψq) +end + +@inline function bulk_factor(ψ, h, ℓ, Ri) + L★ = h / Ri + χ⁻¹ = log(h / ℓ) - ψ(Ri) + ψ(ℓ / L★) + return 1 / χ⁻¹ +end + +@inline function buoyancy_scale(θ★, q★, 𝒬, ℂ, g) + 𝒯₀ = AtmosphericThermodynamics.virtual_temperature(ℂ, 𝒬) + θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬) + q₀ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬) + + ε = AtmosphericThermodynamics.Parameters.molmass_ratio(ℂ) + δ = ε - 1 + + b★ = g / 𝒯₀ * (θ★ * (1 + δ * q₀) + δ * θ₀ * q★) + + return b★ +end + + +@inline function state_differences(ℂ, 𝒰₁, 𝒰₀) + z₁ = 𝒰₁.z + z₀ = 𝒰₀.z + Δh = z₁ - z₀ + + U₁ = 𝒰₁.u + U₀ = 𝒰₀.u + + @inbounds begin + Δu = U₁[1] - U₀[1] + Δv = U₁[2] - U₀[2] + end + + # Thermodynamic state + 𝒬₁ = 𝒰₁.ts + 𝒬₀ = 𝒰₀.ts + + θ₁ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬₁) + θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬₀) + Δθ = θ₁ - θ₀ + + q₁ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬₁) + q₀ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬₀) + Δq = q₁ - q₀ + + return Δh, Δu, Δv, Δθ, Δq +end + +@inline function compute_similarity_theory_fluxes(roughness_lengths, + surface_state, + atmos_state, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant, + Σ₀ = SimilarityScales(1e-3, 1e-3, 1e-3)) + + # Prescribed difference between two states + ℂₐ = thermodynamics_parameters + Δh, Δu, Δv, Δθ, Δq = state_differences(ℂₐ, atmos_state, surface_state) + differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) + + # Solve for the characteristic scales u★, θ★, q★, and thus for fluxes. + Σ★ = Σ₀ + + @unroll for iter = 1:10 + Σ★ = refine_characteristic_scales(Σ★, + roughness_lengths, + surface_state, + differences, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant) + end + + u★ = Σ★.momentum + θ★ = Σ★.temperature + q★ = Σ★.water_vapor + + # u★² ≡ sqrt(τx² + τy²) + τx = - u★^2 * Δu / sqrt(Δu^2 + Δv^2) + τy = - u★^2 * Δv / sqrt(Δu^2 + Δv^2) + + 𝒬ₐ = atmos_state.ts + ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) + cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity + ℰv = AtmosphericThermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) + + fluxes = (; + water_vapor = - ρₐ * u★ * q★, + sensible_heat = - ρₐ * cₚ * u★ * θ★, + latent_heat = - ρₐ * u★ * q★ * ℰv, + x_momentum = + ρₐ * τx, + y_momentum = + ρₐ * τy, + ) + + return fluxes +end + +@inline compute_roughness_length(ℓ::Number, Σ★) = ℓ +@inline compute_roughness_length(ℓ, Σ★) = ℓ(Σ★) + +@inline function refine_characteristic_scales(estimated_characteristic_scales, + roughness_lengths, + surface_state, + differences, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant) + + # "initial" scales because we will recompute them + u★ = estimated_characteristic_scales.momentum + θ★ = estimated_characteristic_scales.temperature + q★ = estimated_characteristic_scales.water_vapor + Σ★ = estimated_characteristic_scales + + # Extract roughness lengths + ℓu = roughness_lengths.momentum + ℓθ = roughness_lengths.temperature + ℓq = roughness_lengths.water_vapor + + ℓu₀ = compute_roughness_length(ℓu, Σ★) + ℓθ₀ = compute_roughness_length(ℓθ, Σ★) + ℓq₀ = compute_roughness_length(ℓq, Σ★) + + # Compute flux Richardson number + h = differences.h + ϰ = von_karman_constant + + ℂ = thermodynamics_parameters + g = gravitational_acceleration + 𝒬ₒ = surface_state.ts # thermodyanmic state + b★ = buoyancy_scale(θ★, q★, 𝒬ₒ, ℂ, g) + Riₕ = - ϰ * h * b★ / u★^2 + Riₕ = ifelse(isnan(Riₕ), zero(Riₕ), Riₕ) + + # Compute similarity functions + ψu = SimilarityFunction(4.7, 15.0, OneQuarter()) + ψc = SimilarityFunction(6.35, 9.0, OneHalf()) + + χu = bulk_factor(ψu, h, ℓu₀, Riₕ) + χθ = bulk_factor(ψc, h, ℓθ₀, Riₕ) + χq = bulk_factor(ψc, h, ℓq₀, Riₕ) + + Δu = differences.u + Δv = differences.v + Δθ = differences.θ + Δq = differences.q + + u★ = ϰ * χu * sqrt(Δu^2 + Δv^2) + θ★ = ϰ * χθ * Δθ + q★ = ϰ * χq * Δq + + return SimilarityScales(u★, θ★, q★) +end + +struct GravityWaveRoughnessLength{FT} + gravitational_acceleration :: FT + air_kinematic_viscosity :: FT + gravity_wave_parameter :: FT + laminar_parameter :: FT +end + +function GravityWaveRoughnessLength(FT=Float64; + gravitational_acceleration = default_gravitational_acceleration, + air_kinematic_viscosity = 1.5e-5, + gravity_wave_parameter = 0.011, + laminar_parameter = 0.11) + + return GravityWaveRoughnessLength(convert(FT, gravitational_acceleration), + convert(FT, air_kinematic_viscosity), + convert(FT, gravity_wave_parameter), + convert(FT, laminar_parameter)) +end + +@inline function compute_roughness_length(ℓ::GravityWaveRoughnessLength, Σ★) + u★ = Σ★.momentum + g = ℓ.gravitational_acceleration + ν = ℓ.air_kinematic_viscosity + α = ℓ.gravity_wave_parameter + β = ℓ.laminar_parameter + + return α * u★^2 / g + β * ν / u★ +end + +function default_roughness_lengths(FT=Float64) + momentum = 1e-4 #GravityWaveRoughnessLength(FT) + temperature = convert(FT, 1e-4) + water_vapor = convert(FT, 1e-4) + return SimilarityScales(momentum, temperature, water_vapor) +end + + diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl new file mode 100644 index 00000000..90629718 --- /dev/null +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -0,0 +1,107 @@ +module OceanSeaIceModels + +using Oceananigans +using SeawaterPolynomials + +using Oceananigans.Operators + +using Oceananigans.Utils: launch!, Time +using Oceananigans.Architectures: architecture +using Oceananigans.BoundaryConditions: fill_halo_regions!, BoundaryCondition +using Oceananigans.Grids: architecture +using Oceananigans.TimeSteppers: tick! +using Oceananigans.Models: AbstractModel +using Oceananigans.OutputReaders: FieldTimeSeries, GPUAdaptedFieldTimeSeries + +using ClimaSeaIce: melting_temperature + +using KernelAbstractions: @kernel, @index +using KernelAbstractions.Extras.LoopInfo: @unroll + +const SomeKindOfFieldTimeSeries = Union{FieldTimeSeries, + GPUAdaptedFieldTimeSeries} + +const SKOFTS = SomeKindOfFieldTimeSeries + +function surface_velocities end +function surface_tracers end +function downwelling_radiation end +function freshwater_flux end +function reference_density end +function heat_capacity end + +sea_ice_thickness(::Nothing) = nothing +sea_ice_concentration(::Nothing) = nothing + +const default_gravitational_acceleration = 9.80665 +const default_freshwater_density = 1000 + +##### +##### Some implementation +##### + +include("PrescribedAtmospheres.jl") + +using .PrescribedAtmospheres: + PrescribedAtmosphere, + TwoStreamDownwellingRadiation + +include("CrossRealmFluxes/CrossRealmFluxes.jl") + +using .CrossRealmFluxes + +include("ocean_sea_ice_model.jl") +include("ocean_only_model.jl") +include("time_step_ocean_sea_ice_model.jl") + +import .CrossRealmFluxes: + compute_atmosphere_ocean_fluxes!, + compute_sea_ice_ocean_fluxes! + +# "No atmosphere" implementation +const NoAtmosphereModel = OceanSeaIceModel{<:Any, Nothing} +const NoSeaIceModel = OceanSeaIceModel{Nothing} + +compute_atmosphere_ocean_fluxes!(coupled_model::NoAtmosphereModel) = nothing +compute_sea_ice_ocean_fluxes!(coupled_model::NoSeaIceModel) = nothing + +##### +##### A fairly dumb, but nevertheless effective "sea ice model" +##### + +struct FreezingLimitedOceanTemperature{L} + liquidus :: L +end + +const FreezingLimitedCoupledModel = OceanSeaIceModel{<:FreezingLimitedOceanTemperature} + +sea_ice_concentration(::FreezingLimitedOceanTemperature) = nothing + +function compute_sea_ice_ocean_fluxes!(cm::FreezingLimitedCoupledModel) + ocean = cm.ocean + liquidus = cm.sea_ice.liquidus + grid = ocean.model.grid + arch = architecture(grid) + Sₒ = ocean.model.tracers.S + Tₒ = ocean.model.tracers.T + + launch!(arch, grid, :xyz, above_freezing_ocean_temperature!, Tₒ, Sₒ, liquidus) + + return nothing +end + +@kernel function above_freezing_ocean_temperature!(Tₒ, Sₒ, liquidus) + + i, j, k = @index(Global, NTuple) + + @inbounds begin + Sᵢ = Sₒ[i, j, k] + Tᵢ = Tₒ[i, j, k] + end + + Tₘ = melting_temperature(liquidus, Sᵢ) + @inbounds Tₒ[i, j, k] = ifelse(Tᵢ < Tₘ, Tₘ, Tᵢ) +end + +end # module + diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl new file mode 100644 index 00000000..10925962 --- /dev/null +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -0,0 +1,369 @@ +module PrescribedAtmospheres + +using Oceananigans.Utils: prettysummary +using Oceananigans.OutputReaders: update_field_time_series!, extract_field_time_series + +using Adapt +using Thermodynamics.Parameters: AbstractThermodynamicsParameters + +import Oceananigans.Models: update_model_field_time_series! + +import Thermodynamics.Parameters: + gas_constant, # + molmass_dryair, # Molar mass of dry air (without moisture) + molmass_water, # Molar mass of gaseous water vapor + molmass_ratio, # Ratio of the molar masses of dry air to water vapor + R_v, # Specific gas constant for water vapor + R_d, # Specific gas constant for dry air + kappa_d, # Ideal gas adiabatic exponent for dry air + T_0, # Enthalpy reference temperature + LH_v0, # Vaporization enthalpy at the reference temperature + LH_s0, # Sublimation enthalpy at the reference temperature + LH_f0, # Fusionn enthalpy at the reference temperature + cp_d, # Heat capacity of dry air at constant pressure + cp_v, # Isobaric specific heat capacity of gaseous water vapor + cp_l, # Isobaric specific heat capacity of liquid water + cp_i, # Isobaric specific heat capacity of water ice + cv_v, # Heat capacity of dry air at constant volume + cv_l, # Isobaric specific heat capacity of liquid water + cv_i, # Isobaric specific heat capacity of liquid water + e_int_v0, # what? someting about reference internal energy of water vapor + T_freeze, # Freezing temperature of _pure_ water + T_triple, # Triple point temperature of _pure_ water + press_triple, # Triple point pressure of pure water + T_icenuc, # Lower temperature limit for the presence of liquid condensate + # (below which homogeneous ice nucleation occurs) + pow_icenuc # "Power parameter" that controls liquid/ice condensate partitioning + # during partial ice nucleation + +import ..OceanSeaIceModels: + surface_velocities, + surface_tracers, + downwelling_radiation, + freshwater_flux + +##### +##### Atmospheric thermodynamics parameters +##### + +struct ConstitutiveParameters{FT} <: AbstractThermodynamicsParameters{FT} + gas_constant :: FT + dry_air_molar_mass :: FT + water_molar_mass :: FT +end + +function Base.summary(p::ConstitutiveParameters{FT}) where FT + return string("ConstitutiveParameters{$FT}(", + "R=", prettysummary(p.gas_constant), + ", Mᵈ=", prettysummary(p.dry_air_molar_mass), + ", Mᵛ=", prettysummary(p.water_molar_mass), ")") +end + +Base.show(io::IO, p::ConstitutiveParameters) = print(io, summary(p)) + +""" + ConstitutiveParameters(FT; gas_constant = 8.3144598, + dry_air_molar_mass = 0.02897, + water_molar_mass = 0.018015) + +Construct a set of parameters that define the density of moist air, + +```math +ρ = p / Rᵐ(q) T, +``` + +where ``p`` is pressure, ``T`` is temperature, ``q`` defines the partition +of total mass into vapor, liqiud, and ice mass fractions, and +``Rᵐ`` is the effective specific gas constant for the mixture, + +```math +Rᵐ(q) = +``` + +where + +For more information see [reference docs]. +""" +function ConstitutiveParameters(FT = Float64; + gas_constant = 8.3144598, + dry_air_molar_mass = 0.02897, + water_molar_mass = 0.018015) + + return ConstitutiveParameters{FT}(convert(FT, gas_constant), + convert(FT, dry_air_molar_mass), + convert(FT, water_molar_mass)) +end + +const CP = ConstitutiveParameters + +@inline gas_constant(p::CP) = p.gas_constant +@inline molmass_dryair(p::CP) = p.dry_air_molar_mass +@inline molmass_water(p::CP) = p.water_molar_mass +@inline molmass_ratio(p::CP) = molmass_dryair(p) / molmass_water(p) +@inline R_v(p::CP) = gas_constant(p) / molmass_water(p) +@inline R_d(p::CP) = gas_constant(p) / molmass_dryair(p) + +struct HeatCapacityParameters{FT} <: AbstractThermodynamicsParameters{FT} + dry_air_adiabatic_exponent :: FT + water_vapor_heat_capacity :: FT + liquid_water_heat_capacity :: FT + water_ice_heat_capacity :: FT +end + +function Base.summary(p::HeatCapacityParameters{FT}) where FT + return string("HeatCapacityParameters{$FT}(", + "κᵈ=", prettysummary(p.dry_air_adiabatic_exponent), + ", cᵖᵛ=", prettysummary(p.water_vapor_heat_capacity), + ", cᵖˡ=", prettysummary(p.liquid_water_heat_capacity), + ", cᵖⁱ=", prettysummary(p.water_ice_heat_capacity)) +end + +Base.show(io::IO, p::HeatCapacityParameters) = print(io, summary(p)) + +""" + HeatCapacityParameters(FT = Float64, + dry_air_adiabatic_exponent = 2/7, + water_vapor_heat_capacity = 1859, + liquid_water_heat_capacity = 4181, + water_ice_heat_capacity = 2100) + +Isobaric heat capacities. +""" +function HeatCapacityParameters(FT = Float64; + dry_air_adiabatic_exponent = 2/7, + water_vapor_heat_capacity = 1859, + liquid_water_heat_capacity = 4181, + water_ice_heat_capacity = 2100) + + return HeatCapacityParameters{FT}(convert(FT, dry_air_adiabatic_exponent), + convert(FT, water_vapor_heat_capacity), + convert(FT, liquid_water_heat_capacity), + convert(FT, water_ice_heat_capacity)) +end + +const HCP = HeatCapacityParameters +@inline cp_v(p::HCP) = p.water_vapor_heat_capacity +@inline cp_l(p::HCP) = p.liquid_water_heat_capacity +@inline cp_i(p::HCP) = p.water_ice_heat_capacity +@inline cv_l(p::HCP) = cp_l(p) +@inline cv_i(p::HCP) = cp_i(p) +@inline kappa_d(p::HCP) = p.dry_air_adiabatic_exponent + +struct PhaseTransitionParameters{FT} <: AbstractThermodynamicsParameters{FT} + reference_vaporization_enthalpy :: FT + reference_sublimation_enthalpy :: FT + reference_temperature :: FT + triple_point_temperature :: FT + triple_point_pressure :: FT + water_freezing_temperature :: FT + total_ice_nucleation_temperature :: FT +end + +function Base.summary(p::PhaseTransitionParameters{FT}) where FT + return string("PhaseTransitionParameters{$FT}(", + "ℒᵛ⁰=", prettysummary(p.reference_vaporization_enthalpy), + ", ℒˢ⁰=", prettysummary(p.reference_sublimation_enthalpy), + ", T⁰=", prettysummary(p.reference_temperature), + ", Tᵗʳ=", prettysummary(p.triple_point_temperature), + ", pᵗʳ=", prettysummary(p.triple_point_pressure), + ", Tᶠ=", prettysummary(p.water_freezing_temperature), + ", Tⁱⁿ=", prettysummary(p.total_ice_nucleation_temperature), ')') +end + +Base.show(io::IO, p::PhaseTransitionParameters) = print(io, summary(p)) + +function PhaseTransitionParameters(FT = Float64; + reference_vaporization_enthalpy = 2500800, + reference_sublimation_enthalpy = 2834400, + reference_temperature = 273.16, + triple_point_temperature = 273.16, + triple_point_pressure = 611.657, + water_freezing_temperature = 273.15, + total_ice_nucleation_temperature = 233) + + return PhaseTransitionParameters{FT}(convert(FT, reference_vaporization_enthalpy), + convert(FT, reference_sublimation_enthalpy), + convert(FT, reference_temperature), + convert(FT, triple_point_temperature), + convert(FT, triple_point_pressure), + convert(FT, water_freezing_temperature), + convert(FT, total_ice_nucleation_temperature)) +end + +const PTP = PhaseTransitionParameters +@inline LH_v0(p::PTP) = p.reference_vaporization_enthalpy +@inline LH_s0(p::PTP) = p.reference_sublimation_enthalpy +@inline LH_f0(p::PTP) = LH_s0(p) - LH_v0(p) +@inline T_freeze(p::PTP) = p.water_freezing_temperature +@inline T_triple(p::PTP) = p.triple_point_temperature +@inline T_icenuc(p::PTP) = p.total_ice_nucleation_temperature +@inline pow_icenuc(p::PTP) = convert(eltype(p), 1) # we shouldn't have the need to set this +@inline press_triple(p::PTP) = p.triple_point_pressure +@inline T_0(p::PTP) = p.reference_temperature + +struct PrescribedAtmosphereThermodynamicsParameters{FT} <: AbstractThermodynamicsParameters{FT} + constitutive :: ConstitutiveParameters{FT} + heat_capacity :: HeatCapacityParameters{FT} + phase_transitions :: PhaseTransitionParameters{FT} +end + +const PATP{FT} = PrescribedAtmosphereThermodynamicsParameters{FT} where FT + +Base.summary(::PATP{FT}) where FT = "PrescribedAtmosphereThermodynamicsParameters{$FT}" + +function Base.show(io::IO, p::PrescribedAtmosphereThermodynamicsParameters) + FT = eltype(p) + + cp = p.constitutive + hc = p.heat_capacity + pt = p.phase_transitions + + return print(io, summary(p), ':', '\n', + "├── ConstitutiveParameters{$FT}:", '\n', + "│ ├── gas_constant (R): ", prettysummary(cp.gas_constant), '\n', + "│ ├── dry_air_molar_mass (Mᵈ): ", prettysummary(cp.dry_air_molar_mass), '\n', + "│ └── water_molar_mass (Mᵛ): ", prettysummary(cp.water_molar_mass), '\n', + "├── HeatCapacityParameters{$FT}:", '\n', + "│ ├── dry_air_adiabatic_exponent (κᵈ): ", prettysummary(hc.dry_air_adiabatic_exponent), '\n', + "│ ├── water_vapor_heat_capacity (cᵖᵛ): ", prettysummary(hc.water_vapor_heat_capacity), '\n', + "│ ├── liquid_water_heat_capacity (cᵖˡ): ", prettysummary(hc.liquid_water_heat_capacity), '\n', + "│ └── water_ice_heat_capacity (cᵖⁱ): ", prettysummary(hc.water_ice_heat_capacity), '\n', + "└── PhaseTransitionParameters{$FT}", '\n', + " ├── reference_vaporization_enthalpy (ℒᵛ⁰): ", prettysummary(pt.reference_vaporization_enthalpy), '\n', + " ├── reference_sublimation_enthalpy (ℒˢ⁰): ", prettysummary(pt.reference_sublimation_enthalpy), '\n', + " ├── reference_temperature (T⁰): ", prettysummary(pt.reference_temperature), '\n', + " ├── triple_point_temperature (Tᵗʳ): ", prettysummary(pt.triple_point_temperature), '\n', + " ├── triple_point_pressure (pᵗʳ): ", prettysummary(pt.triple_point_pressure), '\n', + " ├── water_freezing_temperature (Tᶠ): ", prettysummary(pt.water_freezing_temperature), '\n', + " └── total_ice_nucleation_temperature (Tⁱ): ", prettysummary(pt.total_ice_nucleation_temperature)) +end + +function PrescribedAtmosphereThermodynamicsParameters(FT = Float64; + constitutive = ConstitutiveParameters(FT), + phase_transitions = PhaseTransitionParameters(FT), + heat_capacity = HeatCapacityParameters(FT)) + + return PrescribedAtmosphereThermodynamicsParameters(constitutive, heat_capacity, phase_transitions) +end + +const PATP = PrescribedAtmosphereThermodynamicsParameters + +@inline R_d(p::PATP) = R_d(p.constitutive) +@inline R_v(p::PATP) = R_v(p.constitutive) +@inline gas_constant(p::PATP) = gas_constant(p.constitutive) +@inline molmass_dryair(p::PATP) = molmass_dryair(p.constitutive) +@inline molmass_water(p::PATP) = molmass_water(p.constitutive) +@inline molmass_ratio(p::PATP) = molmass_ratio(p.constitutive) +@inline LH_v0(p::PATP) = LH_v0(p.phase_transitions) +@inline LH_s0(p::PATP) = LH_s0(p.phase_transitions) +@inline LH_f0(p::PATP) = LH_f0(p.phase_transitions) +@inline T_freeze(p::PATP) = T_freeze(p.phase_transitions) +@inline T_triple(p::PATP) = T_triple(p.phase_transitions) +@inline T_icenuc(p::PATP) = T_icenuc(p.phase_transitions) +@inline pow_icenuc(p::PATP) = pow_icenuc(p.phase_transitions) +@inline press_triple(p::PATP) = press_triple(p.phase_transitions) +@inline T_0(p::PATP) = T_0(p.phase_transitions) + +@inline e_int_v0(p::PATP) = LH_v0(p) - R_v(p) * T_0(p) + +@inline cp_v(p::PATP) = cp_v(p.heat_capacity) +@inline cp_l(p::PATP) = cp_l(p.heat_capacity) +@inline cp_i(p::PATP) = cp_i(p.heat_capacity) + +@inline cv_l(p::PATP) = cv_l(p.heat_capacity) +@inline cv_i(p::PATP) = cv_i(p.heat_capacity) + +@inline kappa_d(p::PATP) = kappa_d(p.heat_capacity) +@inline cp_d(p::PATP) = R_d(p) / kappa_d(p) +@inline cv_d(p::PATP) = cp_d(p) - R_d(p) +@inline cv_v(p::PATP) = cp_v(p) - R_v(p) + +##### +##### Prescribed atmosphere (as opposed to dynamically evolving / prognostic) +##### + +struct PrescribedAtmosphere{G, U, P, C, F, R, TP, TI, FT} + grid :: G + velocities :: U + pressure :: P + tracers :: C + freshwater_flux :: F + downwelling_radiation :: R + thermodynamics_parameters :: TP + times :: TI + reference_height :: FT +end + +Base.summary(::PrescribedAtmosphere) = "PrescribedAtmosphere" +Base.show(io::IO, pa::PrescribedAtmosphere) = print(io, summary(pa)) + +""" + PrescribedAtmosphere(times; + reference_height, + velocities = nothing, + pressure = nothing, + freshwater_flux = nothing, + downwelling_radiation = nothing, + tracers = nothing) + +Return a representation of a prescribed time-evolving atmospheric +state with data given at `times`. +""" +function PrescribedAtmosphere(times, FT=Float64; + reference_height, + velocities = nothing, + pressure = nothing, + freshwater_flux = nothing, + downwelling_radiation = nothing, + thermodynamics_parameters = PrescribedAtmosphereThermodynamicsParameters(FT), + grid = nothing, + tracers = nothing) + + if isnothing(grid) # try to find it + u = first(velocities) + grid = u.grid + end + + return PrescribedAtmosphere(grid, + velocities, + pressure, + tracers, + freshwater_flux, + downwelling_radiation, + thermodynamics_parameters, + times, + convert(FT, reference_height)) +end + +update_model_field_time_series!(::Nothing, time) = nothing + +function update_model_field_time_series!(atmos::PrescribedAtmosphere, time) + ftses = extract_field_time_series(atmos) + for fts in ftses + update_field_time_series!(fts, time) + end + + return nothing +end + +struct TwoStreamDownwellingRadiation{SW, LW} + shortwave :: SW + longwave :: LW +end + +""" + TwoStreamDownwellingRadiation(shortwave=nothing, longwave=nothing) + +Return a two-stream model for downwelling radiation that +passes through he atmosphere and arrives at the surface of ocean +or sea ice. +""" +TwoStreamDownwellingRadiation(; shortwave=nothing, longwave=nothing) = + TwoStreamDownwellingRadiation(shortwave, longwave) + +Adapt.adapt_structure(to, tsdr::TwoStreamDownwellingRadiation) = + TwoStreamDownwellingRadiation(adapt(to, tsdr.shortwave), + adapt(to, tsdr.longwave)) + +end # module + diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl new file mode 100644 index 00000000..2d7b1bdc --- /dev/null +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -0,0 +1,54 @@ +const OceanOnlyModel = OceanSeaIceModel{Nothing} + +OceanOnlyModel(ocean; kw...) = OceanSeaIceModel(nothing, ocean; kw...) + +##### +##### No ice-ocean fluxes in this model!! +##### + +#= +compute_ice_ocean_salinity_flux!(::OceanOnlyModel) = nothing +ice_ocean_latent_heat!(::OceanOnlyModel) = nothing + +##### +##### Air-sea fluxes +##### + +function time_step!(coupled_model::OceanOnlyModel, Δt; callbacks=nothing) + time_step!(ocean) + tick!(coupled_model.clock, Δt) + return nothing +end + +function update_state!(coupled_model::OceanOnlyModel; callbacks=nothing) + compute_air_sea_flux!(coupled_model) + return nothing +end + +function compute_air_sea_fluxes!(coupled_model::OceanOnlyModel) + ocean = coupled_model.ocean + forcing = coupled_model.atmospheric_forcing + + (; T, S) = ocean.model.tracers + (; u, v) = ocean.model.velocities + + grid = ocean.model.grid + clock = ocean.model.clock + fields = prognostic_fields(ocean.model) + + Qˢ = T.boundary_conditions.top.condition + Fˢ = S.boundary_conditions.top.condition + τˣ = u.boundary_conditions.top.condition + τʸ = v.boundary_conditions.top.condition + + ε = coupled_model.ocean_emissivity + ρₒ = coupled_model.ocean_reference_density + cₒ = coupled_model.ocean_heat_capacity + I₀ = coupled_model.solar_insolation + + launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, Iₒ, + grid, clock, fields, forcing, nothing) + + return nothing +end +=# diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl new file mode 100644 index 00000000..8a0cb264 --- /dev/null +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -0,0 +1,89 @@ +using Oceananigans +using Oceananigans.Models: update_model_field_time_series! +using Oceananigans.TimeSteppers: Clock +using Oceananigans.BuoyancyModels: SeawaterBuoyancy + +using SeawaterPolynomials: TEOS10EquationOfState + +# Simulations interface +import Oceananigans: fields, prognostic_fields +import Oceananigans.Fields: set! +import Oceananigans.Models: timestepper, NaNChecker, default_nan_checker +import Oceananigans.OutputWriters: default_included_properties +import Oceananigans.Simulations: reset!, initialize!, iteration +import Oceananigans.TimeSteppers: time_step!, update_state!, time +import Oceananigans.Utils: prettytime +import Oceananigans.Models: timestepper, NaNChecker, default_nan_checker + +struct OceanSeaIceModel{I, A, O, F, C, G} <: AbstractModel{Nothing} + clock :: C + grid :: G # TODO: make it so Oceananigans.Simulation does not require this + atmosphere :: A + sea_ice :: I + ocean :: O + fluxes :: F +end + +const OSIM = OceanSeaIceModel + +Base.summary(::OSIM) = "OceanSeaIceModel" +Base.show(io::IO, cm::OSIM) = print(io, summary(cm)) +prettytime(model::OSIM) = prettytime(model.clock.time) +iteration(model::OSIM) = model.clock.iteration +timestepper(::OSIM) = nothing +reset!(::OSIM) = nothing +initialize!(::OSIM) = nothing +default_included_properties(::OSIM) = tuple() +prognostic_fields(cm::OSIM) = nothing +fields(::OSIM) = NamedTuple() +default_clock(TT) = Oceananigans.TimeSteppers.Clock{TT}(0, 0, 1) + +reference_density(unsupported) = + throw(ArgumentError("Cannot extract reference density from $(typeof(unsupported))")) + +heat_capacity(unsupported) = + throw(ArgumentError("Cannot deduce the heat capacity from $(typeof(unsupported))")) + +reference_density(ocean::Simulation) = reference_density(ocean.model.buoyancy.model) +reference_density(buoyancy_model::SeawaterBuoyancy) = reference_density(buoyancy_model.equation_of_state) +reference_density(eos::TEOS10EquationOfState) = eos.reference_density + +heat_capacity(ocean::Simulation) = heat_capacity(ocean.model.buoyancy.model) +heat_capacity(buoyancy_model::SeawaterBuoyancy) = heat_capacity(buoyancy_model.equation_of_state) + +function heat_capacity(eos::TEOS10EquationOfState{FT}) where FT + cₚ⁰ = SeawaterPolynomials.TEOS10.teos10_reference_heat_capacity + return convert(FT, cₚ⁰) +end + +function OceanSeaIceModel(ocean, sea_ice=nothing; + atmosphere = nothing, + radiation = nothing, + ocean_reference_density = reference_density(ocean), + ocean_heat_capacity = heat_capacity(ocean), + clock = deepcopy(ocean.model.clock)) + + # Contains information about flux contributions: bulk formula, prescribed fluxes, etc. + fluxes = OceanSeaIceSurfaceFluxes(ocean, sea_ice; atmosphere, radiation) + + ocean_sea_ice_model = OceanSeaIceModel(clock, + ocean.model.grid, + atmosphere, + sea_ice, + ocean, + fluxes) + + update_state!(ocean_sea_ice_model) + + return ocean_sea_ice_model +end + +time(coupled_model::OceanSeaIceModel) = coupled_model.clock.time + +# Check for NaNs in the first prognostic field (generalizes to prescribed velocitries). +function default_nan_checker(model::OceanSeaIceModel) + u_ocean = model.ocean.model.velocities.u + nan_checker = NaNChecker((; u_ocean)) + return nan_checker +end + diff --git a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl new file mode 100644 index 00000000..0f8941e6 --- /dev/null +++ b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl @@ -0,0 +1,55 @@ +using .CrossRealmFluxes: compute_atmosphere_ocean_fluxes!, compute_sea_ice_ocean_fluxes! + +using ClimaSeaIce: SlabSeaIceModel + +const SlabSeaIceSimulation = Simulation{<:SlabSeaIceModel} + +function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_tendencies=true) + ocean = coupled_model.ocean + sea_ice = coupled_model.sea_ice + + # Be paranoid and update state at iteration 0 + coupled_model.clock.iteration == 0 && update_state!(coupled_model, callbacks) + + # Eventually, split out into OceanOnlyModel + if sea_ice isa SlabSeaIceSimulation + h = sea_ice.model.ice_thickness + fill_halo_regions!(h) + + # Initialization + if coupled_model.clock.iteration == 0 + @info "Initializing coupled model ice thickness..." + h⁻ = coupled_model.fluxes.previous_ice_thickness + hⁿ = coupled_model.sea_ice.model.ice_thickness + parent(h⁻) .= parent(hⁿ) + end + + sea_ice.Δt = Δt + time_step!(sea_ice) + end + + ocean.Δt = Δt + + # TODO after ice time-step: + # - Adjust ocean heat flux if the ice completely melts? + + time_step!(ocean) + + # TODO: + # - Store fractional ice-free / ice-covered _time_ for more + # accurate flux computation? + tick!(coupled_model.clock, Δt) + update_state!(coupled_model, callbacks; compute_tendencies) + + return nothing +end + +function update_state!(coupled_model::OceanSeaIceModel, callbacks=[]; compute_tendencies=false) + time = Time(coupled_model.clock.time) + update_model_field_time_series!(coupled_model.atmosphere, time) + compute_atmosphere_ocean_fluxes!(coupled_model) + compute_sea_ice_ocean_fluxes!(coupled_model) + #compute_atmosphere_sea_ice_fluxes!(coupled_model) + return nothing +end + diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl new file mode 100644 index 00000000..5e995a45 --- /dev/null +++ b/src/OceanSimulations/OceanSimulations.jl @@ -0,0 +1,81 @@ +module OceanSimulations + +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: + CATKEVerticalDiffusivity, + MixingLength, + TurbulentKineticEnergyEquation + +using SeawaterPolynomials.TEOS10: TEOS10EquationOfState + +using Oceananigans.BuoyancyModels: g_Earth +using Oceananigans.Coriolis: Ω_Earth + +# Some defualts +default_free_surface(grid) = SplitExplicitFreeSurface(cfl=0.7; grid) + +function default_ocean_closure() + mixing_length = MixingLength(Cᵇ=0.01) + turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) + return CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) +end + +# TODO: Specify the grid to a grid on the sphere; otherwise we can provide a different +# function that requires latitude and longitude etc for computing coriolis=FPlane... +function ocean_simulation(grid; + closure = default_ocean_closure(), + free_surface = default_free_surface(grid), + reference_density = 1020, + rotation_rate = Ω_Earth, + gravitational_acceleration = g_Earth) + + # Set up boundary conditions using Field + top_zonal_momentum_flux = Jᵘ = Field{Face, Center, Nothing}(grid) + top_meridional_momentum_flux = Jᵛ = Field{Center, Face, Nothing}(grid) + top_ocean_heat_flux = Jᵀ = Field{Center, Center, Nothing}(grid) + top_salt_flux = Jˢ = Field{Center, Center, Nothing}(grid) + + ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵘ)), + v = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵛ)), + T = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵀ)), + S = FieldBoundaryConditions(top=FluxBoundaryCondition(Jˢ))) + + # Use the TEOS10 equation of state + teos10 = TEOS10EquationOfState(; reference_density) + buoyancy = SeawaterBuoyancy(; gravitational_acceleration, equation_of_state=teos10) + + # Minor simplifications for single column grids + Nx, Ny, Nz = size(grid) + if Nx == Ny == 1 # single column grid + tracer_advection = nothing + momentum_advection = nothing + else + # TODO: better advection scheme + tracer_advection = WENO() + momentum_advection = VectorInvariant(vorticity_scheme = WENO(), + divergence_scheme = WENO(), + vertical_scheme = WENO()) + end + + tracers = (:T, :S) + if closure isa CATKEVerticalDiffusivity + tracers = tuple(tracers..., :e) + end + + coriolis = HydrostaticSphericalCoriolis(; rotation_rate) + + ocean_model = HydrostaticFreeSurfaceModel(; grid, + buoyancy, + closure, + tracer_advection, + momentum_advection, + tracers, + free_surface, + coriolis, + boundary_conditions = ocean_boundary_conditions) + + ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) + + return ocean +end + +end # module diff --git a/src/quarter_degree_global_simulation.jl b/src/quarter_degree_global_simulation.jl new file mode 100644 index 00000000..05caa21c --- /dev/null +++ b/src/quarter_degree_global_simulation.jl @@ -0,0 +1,213 @@ +using Oceananigans.TurbulenceClosures: HorizontalDivergenceFormulation +using Oceananigans.Advection: VelocityStencil + +""" + quarter_degree_near_global_simulation(architecture = GPU(); kwargs...) + +Return an `Oceananigans.Simulation` of Earth's ocean at 1/4 degree lateral resolution. +""" +function quarter_degree_near_global_simulation(architecture = GPU(); + size = (1440, 600, 48), + boundary_layer_turbulence_closure = RiBasedVerticalDiffusivity(), + background_vertical_diffusivity = 1e-5, + background_vertical_viscosity = 1e-4, + horizontal_viscosity = geometric_viscosity(HorizontalDivergenceFormulation(), 5days), + surface_temperature_relaxation_time_scale = 7days, + surface_salinity_relaxation_time_scale = 7days, + bottom_drag_coefficient = 3e-3, + reference_density = 1029.0, + reference_heat_capacity = 3991.0, + reference_salinity = 34.0, + time_step = 6minutes, + stop_iteration = Inf, + start_time = 345days, + stop_time = Inf, + equation_of_state = TEOS10EquationOfState(; reference_density), + tracers = [:T, :S], + initial_conditions = datadep"near_global_quarter_degree/initial_conditions.jld2", + bathymetry_path = datadep"near_global_quarter_degree/bathymetry-1440x600.jld2", + temp_surface_boundary_conditions_path = datadep"near_global_quarter_degree/temp-1440x600-latitude-75.jld2", + salt_surface_boundary_conditions_path = datadep"near_global_quarter_degree/salt-1440x600-latitude-75.jld2", + u_stress_surface_boundary_conditions_path = datadep"near_global_quarter_degree/tau_x-1440x600-latitude-75.jld2", + v_stress_surface_boundary_conditions_path = datadep"near_global_quarter_degree/tau_y-1440x600-latitude-75.jld2", +) + + bathymetry_file = jldopen(bathymetry_path) + bathymetry = bathymetry_file["bathymetry"] + close(bathymetry_file) + + @info "Reading initial conditions..."; start=time_ns() + initial_conditions_file = jldopen(initial_conditions) + T_init = initial_conditions_file["T"] + S_init = initial_conditions_file["S"] + close(initial_conditions_file) + @info "... read initial conditions (" * prettytime(1e-9 * (time_ns() - start)) * ")" + + # Files contain 12 arrays of monthly-averaged data from 1992 + @info "Reading boundary conditions..."; start=time_ns() + # Files contain 1 year (1992) of 12 monthly averages + τˣ = - jldopen(u_stress_surface_boundary_conditions_path)["field"] ./ reference_density + τʸ = - jldopen(v_stress_surface_boundary_conditions_path)["field"] ./ reference_density + T★ = jldopen(temp_surface_boundary_conditions_path)["field"] + S★ = jldopen(salt_surface_boundary_conditions_path)["field"] + F★ = zeros(Base.size(S★)...) + Q★ = zeros(Base.size(T★)...) + # close(u_stress_surface_boundary_conditions_path) + # close(v_stress_surface_boundary_conditions_path) + # close(temp_surface_boundary_conditions_path) + # close(salt_surface_boundary_conditions_path) + @info "... read boundary conditions (" * prettytime(1e-9 * (time_ns() - start)) * ")" + + # Convert boundary conditions arrays to GPU + τˣ = arch_array(architecture, τˣ) + τʸ = arch_array(architecture, τʸ) + target_sea_surface_temperature = T★ = arch_array(architecture, T★) + target_sea_surface_salinity = S★ = arch_array(architecture, S★) + surface_temperature_flux = Q★ = arch_array(architecture, Q★) + surface_salt_flux = F★ = arch_array(architecture, F★) + + # Stretched faces from ECCO Version 4 (49 levels in the vertical) + z_faces = VerticalGrids.z_49_levels_10_to_400_meter_spacing + + # A spherical domain + underlying_grid = LatitudeLongitudeGrid(architecture; size, + longitude = (-180, 180), + latitude = (-75, 75), + halo = (5, 5, 5), + z = z_faces) + + grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bathymetry)) + + @info "Created $grid" + + ##### + ##### Physics and model setup + ##### + + vitd = VerticallyImplicitTimeDiscretization() + + vertical_viscosity = VerticalScalarDiffusivity(vitd, ν=background_vertical_viscosity, κ=background_vertical_diffusivity) + + closures = Any[horizontal_viscosity, boundary_layer_turbulence_closure, vertical_viscosity] + + boundary_layer_turbulence_closure isa CATKEVerticalDiffusivity && + push!(tracers, :e) + + # TODO: do this internally in model constructor + closures = tuple(closures...) + + ##### + ##### Boundary conditions / time-dependent fluxes + ##### + + drag_u = FluxBoundaryCondition(u_immersed_bottom_drag, discrete_form=true, parameters = bottom_drag_coefficient) + drag_v = FluxBoundaryCondition(v_immersed_bottom_drag, discrete_form=true, parameters = bottom_drag_coefficient) + + no_slip_bc = ValueBoundaryCondition(0) + + u_immersed_bc = ImmersedBoundaryCondition(bottom = drag_u, + west = no_slip_bc, + east = no_slip_bc, + south = no_slip_bc, + north = no_slip_bc) + + v_immersed_bc = ImmersedBoundaryCondition(bottom = drag_v, + west = no_slip_bc, + east = no_slip_bc, + south = no_slip_bc, + north = no_slip_bc) + + u_bottom_drag_bc = FluxBoundaryCondition(u_bottom_drag, discrete_form = true, parameters = bottom_drag_coefficient) + v_bottom_drag_bc = FluxBoundaryCondition(v_bottom_drag, discrete_form = true, parameters = bottom_drag_coefficient) + + Nmonths = 12 # number of months in the forcing file + u_wind_stress_parameters = (; τ=τˣ, Nmonths) + v_wind_stress_parameters = (; τ=τʸ, Nmonths) + u_wind_stress_bc = FluxBoundaryCondition(surface_wind_stress, discrete_form=true, parameters=u_wind_stress_parameters) + v_wind_stress_bc = FluxBoundaryCondition(surface_wind_stress, discrete_form=true, parameters=v_wind_stress_parameters) + + Δz_top = @allowscalar Δzᵃᵃᶜ(1, 1, grid.Nz, grid.underlying_grid) + + T_relaxation_parameters = (; λ = Δz_top / surface_temperature_relaxation_time_scale, + Nmonths, + T★ = target_sea_surface_temperature, + Q★ = surface_temperature_flux) + + S_relaxation_parameters = (; λ = Δz_top / surface_salinity_relaxation_time_scale, + Nmonths, + S★ = target_sea_surface_salinity, + F★ = surface_salt_flux) + + T_surface_relaxation_bc = FluxBoundaryCondition(surface_temperature_relaxation, + discrete_form = true, + parameters = T_relaxation_parameters) + + S_surface_relaxation_bc = FluxBoundaryCondition(surface_salinity_relaxation, + discrete_form = true, + parameters = S_relaxation_parameters) + + u_bcs = FieldBoundaryConditions(top = u_wind_stress_bc, + bottom = u_bottom_drag_bc, + immersed = u_immersed_bc) + + v_bcs = FieldBoundaryConditions(top = v_wind_stress_bc, + bottom = v_bottom_drag_bc, + immersed = v_immersed_bc) + + T_bcs = FieldBoundaryConditions(top = T_surface_relaxation_bc) + S_bcs = FieldBoundaryConditions(top = S_surface_relaxation_bc) + + buoyancy = SeawaterBuoyancy(; equation_of_state) + coriolis = HydrostaticSphericalCoriolis(scheme = WetCellEnstrophyConservingScheme()) + free_surface = ImplicitFreeSurface() + + model = HydrostaticFreeSurfaceModel(; grid, free_surface, coriolis, buoyancy, tracers, + momentum_advection = WENO(vector_invariant = VelocityStencil()), + closure = closures, + boundary_conditions = (u=u_bcs, v=v_bcs, T=T_bcs, S=S_bcs), + tracer_advection = WENO(underlying_grid)) + + @info "... built $model." + @info "Model building time: " * prettytime(1e-9 * (time_ns() - start)) + + ##### + ##### Initial condition: + ##### + + set!(model, T=T_init, S=S_init) + + # Because MITgcm forcing starts at Jan 15 (?) + model.clock.time = start_time + + simulation = Simulation(model; Δt=time_step, stop_iteration, stop_time) + + start_time = [time_ns()] + + function progress(sim) + wall_time = (time_ns() - start_time[1]) * 1e-9 + + u = sim.model.velocities.u + w = sim.model.velocities.w + + intw = Array(interior(w)) + max_w = findmax(intw) + + mw = max_w[1] + iw = max_w[2] + + msg1 = @sprintf("Time: % 12s, iteration: %d, ", prettytime(sim), iteration(sim)) + msg2 = @sprintf("max(|u|): %.2e ms⁻¹, wmax: %.2e, loc: (%d, %d, %d), ", + maximum(abs, u), mw, iw[1], iw[2], iw[3]) + msg3 = @sprintf("wall time: %s", prettytime(wall_time)) + + @info msg1 * msg2 * msg3 + + start_time[1] = time_ns() + + return nothing + end + + simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) + + return simulation +end diff --git a/test/runtests_setup.jl b/test/runtests_setup.jl index 993f89a3..83e3f1d9 100644 --- a/test/runtests_setup.jl +++ b/test/runtests_setup.jl @@ -4,5 +4,6 @@ using CUDA using Test using Oceananigans.Architectures: architecture +using Oceananigans.OutputReaders: interpolate! test_architectures = [CPU()] diff --git a/test/test_downloading.jl b/test/test_downloading.jl index 128efcb3..7bc53331 100644 --- a/test/test_downloading.jl +++ b/test/test_downloading.jl @@ -2,7 +2,7 @@ include("runtests_setup.jl") @testset "Availability of JRA55 data" begin @info "Testing that we can download all the JRA55 data..." - for name in ClimaOcean.DataWrangling.JRA55.jra55_short_names - fts = ClimaOcean.JRA55.jra55_field_time_series(name; time_indices=1:1) + for name in ClimaOcean.DataWrangling.JRA55.JRA55_variable_names + fts = ClimaOcean.JRA55.JRA55_field_time_series(name; time_indices=2:3) end end diff --git a/test/test_ecco2.jl b/test/test_ecco2.jl index 278dc2bf..abbebec2 100644 --- a/test/test_ecco2.jl +++ b/test/test_ecco2.jl @@ -24,8 +24,8 @@ using Oceananigans.Grids: topology @test Ny == 720 @test Nz == 50 - ice_thickness_filename = ECCO2.ecco2_file_names[:effective_ice_thickness] - ecco2_ice_thickness = ECCO2.ecco2_field(:effective_ice_thickness; architecture=arch) + ice_thickness_filename = ECCO2.ecco2_file_names[:sea_ice_thickness] + ecco2_ice_thickness = ECCO2.ecco2_field(:sea_ice_thickness; architecture=arch) @test isfile(ice_thickness_filename) rm(ice_thickness_filename) diff --git a/test/test_jra55.jl b/test/test_jra55.jl index 6e686e4f..d13b3d4f 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -3,32 +3,53 @@ include("runtests_setup.jl") @testset "JRA55 and data wrangling utilities" begin for arch in test_architectures A = typeof(arch) - @info "Testing jra55_field_time_series on $A..." + @info "Testing JRA55_field_time_series on $A..." test_name = :downwelling_shortwave_radiation test_filename = "RYF.rsds.1990_1991.nc" + test_jld2_filename = "JRA55_repeat_year_downwelling_shortwave_radiation.jld2" time_indices = 1:3 # This should download a file called "RYF.rsds.1990_1991.nc" - jra55_fts = ClimaOcean.JRA55.jra55_field_time_series(test_name; architecture=arch, time_indices) + jra55_fts = ClimaOcean.JRA55.JRA55_field_time_series(test_name; architecture=arch, time_indices) @test isfile(test_filename) - rm(test_filename) - @test jra55_fts isa FieldTimeSeries @test jra55_fts.grid isa LatitudeLongitudeGrid - + Nx, Ny, Nz, Nt = size(jra55_fts) @test Nx == 640 @test Ny == 320 @test Nz == 1 @test Nt == length(time_indices) + CUDA.@allowscalar begin + @test jra55_fts[1, 1, 1, 1] == 430.98105f0 + @test jra55_fts[641, 1, 1, 1] == 430.98105f0 + end + # Test that halo regions were filled to respect boundary conditions CUDA.@allowscalar begin @test view(jra55_fts.data, 1, :, 1, :) == view(jra55_fts.data, Nx+1, :, 1, :) end + @info "Testing preprocessing JRA55 data on $A..." + rm(test_jld2_filename, force=true) + + @info "Testing loading preprocessed JRA55 data on $A..." + in_memory_jra55_fts = ClimaOcean.JRA55.JRA55_field_time_series(test_name; + time_indices, + architecture = arch, + backend = InMemory(2)) + + @test in_memory_jra55_fts isa FieldTimeSeries + + @test interior(in_memory_jra55_fts[1]) == interior(jra55_fts[1]) + + # Clean up + rm(test_filename) + rm(in_memory_jra55_fts.path) + @info "Testing interpolate_field_time_series! on $A..." # Make target grid and field resolution = 1 # degree, eg 1/4 @@ -50,16 +71,15 @@ include("runtests_setup.jl") times = jra55_fts.times boundary_conditions = jra55_fts.boundary_conditions target_fts = FieldTimeSeries{Center, Center, Nothing}(target_grid, times; boundary_conditions) - - ClimaOcean.DataWrangling.interpolate_field_time_series!(target_fts, jra55_fts) + interpolate!(target_fts, jra55_fts) # Random regression test CUDA.@allowscalar begin - @test target_fts[1, 1, 1, 1] == 222.24310434509874 + @test target_fts[1, 1, 1, 1] == 222.243136478611 # Only include this if we are filling halo regions within # interpolate_field_time_series - @test target_fts[Nx + 1, 1, 1, 1] == 222.24310434509874 + @test target_fts[Nx + 1, 1, 1, 1] == 222.243136478611 end @test target_fts.times == jra55_fts.times @@ -74,6 +94,7 @@ include("runtests_setup.jl") # Test that we can load the data back Qswt = FieldTimeSeries(filepath, "Qsw") + @show size(Qswt.data), size(target_fts) @test parent(Qswt) == parent(target_fts) @test Qswt.times == target_fts.times rm(filepath)