diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl index e97f6fad0..0eadfad3e 100644 --- a/examples/generate_surface_fluxes.jl +++ b/examples/generate_surface_fluxes.jl @@ -67,8 +67,8 @@ set!(ocean.model; T=T_metadata, S=S_metadata) coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation=Radiation()) -# Now that the surface fluxes are computed, we can extract and visualize them. -# The turbulent fluxes are stored in `coupled_model.fluxes.turbulent`. +# # Now that the surface fluxes are computed, we can extract and visualize them. +# # The turbulent fluxes are stored in `coupled_modelinterfaces.atmosphere_ocean_interface.fluxes`. fluxes = coupled_model.interfaces.atmosphere_ocean_interface.fluxes λ, φ, z = nodes(fluxes.sensible_heat) @@ -91,4 +91,4 @@ ax = Axis(fig[3, 1], title = "Water vapor flux (kg m⁻² s⁻¹)", xlabel = "Lo heatmap!(ax, λ, φ, interior(fluxes.water_vapor, :, :, 1); colormap = :bwr) save("fluxes.png", fig) -# ![](fluxes.png) +![](fluxes.png) diff --git a/examples/one_degree_simulation.jl b/examples/one_degree_simulation.jl index 977c659ab..154031437 100644 --- a/examples/one_degree_simulation.jl +++ b/examples/one_degree_simulation.jl @@ -60,7 +60,6 @@ FS = ECCORestoring(salinity, grid; mask, rate=restoring_rate) forcing = (T=FT, S=FS) # ### Closures -# # We include a Gent-McWilliam isopycnal diffusivity as a parameterization for the mesoscale # eddy fluxes. For vertical mixing at the upper-ocean boundary layer we include the CATKE # parameterization. We also include some explicit horizontal diffusivity. @@ -75,7 +74,6 @@ vertical_mixing = ClimaOcean.OceanSimulations.default_ocean_closure() closure = (eddy_closure, vertical_mixing) # ### Ocean simulation -# # Now we bring everything together to construct the ocean simulation. # We use a split-explicit timestepping with 30 substeps for the barotropic # mode. @@ -102,7 +100,6 @@ set!(ocean.model, T=ECCOMetadata(:temperature; dates=first(dates)), # ### Atmospheric forcing # We force the simulation with an JRA55-do atmospheric reanalysis. - radiation = Radiation(arch) atmosphere = JRA55PrescribedAtmosphere(arch; backend=JRA55NetCDFBackend(20)) @@ -149,7 +146,6 @@ function progress(sim) end # And add it as a callback to the simulation. - add_callback!(simulation, progress, IterationInterval(10)) # ### Output @@ -164,6 +160,9 @@ ocean.output_writers[:surface] = JLD2OutputWriter(ocean.model, outputs; schedule = TimeInterval(5days), filename = "global_surface_fields", indices = (:, :, grid.Nz), + with_halos = true, + overwrite_existing = true, + array_type = Array{Float32}) overwrite_existing = true) # ### Ready to run @@ -183,7 +182,6 @@ run!(simulation) # ### A pretty movie # # We load the saved output and make a pretty movie of the simulation. First we plot a snapshot: - using CairoMakie u = FieldTimeSeries("global_surface_fields.jld2", "u"; backend = OnDisk()) @@ -197,7 +195,6 @@ Nt = length(times) n = Observable(Nt) # We create a land mask and use it to fill land points with `NaN`s. - land = interior(T.grid.immersed_boundary.bottom_height) .≥ 0 Tn = @lift begin @@ -213,7 +210,6 @@ en = @lift begin end # We compute the surface speed. - un = Field{Face, Center, Nothing}(u.grid) vn = Field{Center, Face, Nothing}(v.grid) s = Field(sqrt(un^2 + vn^2)) @@ -229,7 +225,6 @@ end # Finally, we plot a snapshot of the surface speed, temperature, and the turbulent # eddy kinetic energy from the CATKE vertical mixing parameterization. - fig = Figure(size = (800, 1200)) axs = Axis(fig[1, 1], xlabel="Longitude (deg)", ylabel="Latitude (deg)") diff --git a/experiments/coupled_simulation/ocean_sea_ice_coupled_simulation.jl b/experiments/coupled_simulation/ocean_sea_ice_coupled_simulation.jl new file mode 100644 index 000000000..1349d1103 --- /dev/null +++ b/experiments/coupled_simulation/ocean_sea_ice_coupled_simulation.jl @@ -0,0 +1,159 @@ +using ClimaOcean +using Oceananigans +using Oceananigans.Units +using Oceananigans.Grids +using OrthogonalSphericalShellGrids +using CFTime +using Dates +using Printf + +using Oceananigans.Utils: launch! +using ClimaOcean.DataWrangling: NearestNeighborInpainting +using ClimaSeaIce.SeaIceThermodynamics: melting_temperature +using Oceananigans.Grids: architecture +using KernelAbstractions: @kernel, @index + + +arch = CPU() + +depth = 1000meters +Nz = 10 +h = 3 + +r_faces = ClimaOcean.exponential_z_faces(; Nz, h, depth) +z_faces = MutableVerticalDiscretization(r_faces) + +Nx = 256 # longitudinal direction -> 250 points is about 1.5ᵒ resolution +Ny = 128 # meridional direction -> same thing, 48 points is about 1.5ᵒ resolution +Nz = length(r_faces) - 1 +grid = TripolarGrid(arch, Float64; size=(Nx, Ny, Nz), z=z_faces) +sea_ice_grid = TripolarGrid(arch, Float64; size=(Nx, Ny, 1), z = (-10, 0)) + +# ## Adding a bathymetry to the grid +url = "https://www.dropbox.com/scl/fi/zy1cu64ybn93l67rjgiq0/Downsampled_ETOPO_2022.nc?rlkey=5upqvoxrnljj205amqf663vcw&st=ou8b32tt&dl=0" +filename = isfile("Downsampled_ETOPO_2022.nc") ? "Downsampled_ETOPO_2022.nc" : download(url, "Downsampled_ETOPO_2022.nc") +bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, filename, dir="./") + +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) +sea_ice_grid = ImmersedBoundaryGrid(sea_ice_grid, GridFittedBottom(bottom_height)) + +##### +##### Ocean model +##### + +momentum_advection = WENOVectorInvariant(order=3) +tracer_advection = Centered() + +free_surface = SplitExplicitFreeSurface(grid; substeps=30) + +using Oceananigans.TurbulenceClosures: IsopycnalSkewSymmetricDiffusivity, + DiffusiveFormulation + +using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity + +eddy_closure = IsopycnalSkewSymmetricDiffusivity(κ_skew=1e3, κ_symmetric=1e3, skew_flux_formulation=DiffusiveFormulation()) +vertical_mixing = ClimaOcean.OceanSimulations.default_ocean_closure() + +closure = (eddy_closure, vertical_mixing) + +ocean = ocean_simulation(grid; + momentum_advection, + tracer_advection, + closure, + free_surface) + +##### +##### Sea-ice model +##### + +# Define the model! +# TODO: Fix the melting temperature to -1.96 degrees Celsius +# Verify that the minimum temperature is -1.96 degrees Celsius +sea_ice = sea_ice_simulation(sea_ice_grid; dynamics=nothing, advection=nothing) + +##### +##### Initialize Ocean and Sea ice models +##### + +temperature = ECCOMetadata(:temperature; dir="./") +salinity = ECCOMetadata(:salinity; dir="./") + +ice_thickness = ECCOMetadata(:sea_ice_thickness; dir="./") +ice_concentration = ECCOMetadata(:sea_ice_concentration; dir="./") + +atmosphere = JRA55PrescribedAtmosphere(arch, backend=JRA55NetCDFBackend(20)) +radiation = Radiation(ocean_albedo = LatitudeDependentAlbedo(), sea_ice_albedo=0.6) + +set!(ocean.model, T=temperature, S=salinity) +set!(sea_ice.model.ice_thickness, ice_thickness, inpainting=NearestNeighborInpainting(1)) +set!(sea_ice.model.ice_concentration, ice_concentration, inpainting=NearestNeighborInpainting(1)) + +adjust_ocean_temperature!(ocean, sea_ice) +earth_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +earth = Simulation(earth_model; Δt=30minutes, stop_iteration=10, stop_time=30days) + +u, v, _ = ocean.model.velocities +T = ocean.model.tracers.T +S = ocean.model.tracers.S +s = sqrt(u^2 + v^2) + +h = sea_ice.model.ice_thickness +ℵ = sea_ice.model.ice_concentration +η = ocean.model.free_surface.η + +earth.output_writers[:surface_tracers] = JLD2OutputWriter(ocean.model, (; T, S, s), + schedule = TimeInterval(12hours), + indices = (:, :, grid.Nz), + overwrite_existing = true, + filename = "surface_fields.jld2") + + +earth.output_writers[:sea_ice_variables] = JLD2OutputWriter(sea_ice.model, (; h, ℵ), + schedule = TimeInterval(12hours), + overwrite_existing = true, + filename = "sea_ice_fields.jld2") + + +earth.output_writers[:free_surface] = JLD2OutputWriter(ocean.model, (; η), + schedule = TimeInterval(12hours), + overwrite_existing = true, + filename = "free_surface.jld2") + +Q = earth.model.interfaces.net_fluxes.ocean_surface.T +τx = earth.model.interfaces.net_fluxes.ocean_surface.u +τy = earth.model.interfaces.net_fluxes.ocean_surface.v +PE = earth.model.interfaces.net_fluxes.ocean_surface.S + +earth.output_writers[:fluxes] = JLD2OutputWriter(ocean.model, (; Q, τx, τy, PE), + schedule = TimeInterval(12hours), + overwrite_existing = true, + filename = "surface_fluxes.jld2") + +# Also, we add a callback to print a message about how the simulation is going + +wall_time = [time_ns()] + +function progress(earth) + clock = earth.model.clock + + maxu = maximum(abs, u) + maxv = maximum(abs, v) + maxT = maximum(T) + minS = minimum(S) + + @info @sprintf("Iteration: %d, time: %s, wall_time: %s, max(|u|, |v|): %.2e %.2e max(T): %.2e, min(S): %.2e\n", + clock.iteration, prettytime(clock.time), prettytime(1e-9 * (time_ns() - wall_time[1])), maxu, maxv, maxT, minS) + + wall_time[1] = time_ns() +end + +add_callback!(earth, progress, IterationInterval(10)) + + +run!(earth) + +# ## Visualizing the results +# +# We can visualize the results using CairoMakie. We record a video of surface variables and fluxes. +# To load the data we can use Oceananigans' `FieldTimeSeries` object. \ No newline at end of file diff --git a/experiments/mesoscale_resolving_omip/Manifest.toml b/experiments/mesoscale_resolving_omip/Manifest.toml deleted file mode 100644 index 3d4f43c0d..000000000 --- a/experiments/mesoscale_resolving_omip/Manifest.toml +++ /dev/null @@ -1,1568 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.10.4" -manifest_format = "2.0" -project_hash = "1cab777b23bf99dac075dcd3cc1d9faf7933f586" - -[[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.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.ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.1" - -[[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "ed2ec3c9b483842ae59cd273834e5b46206d6dda" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.11.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceCUDSSExt = "CUDSS" - 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" - CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" - 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.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 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" -uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.9" - -[[deps.BitTwiddlingConvenienceFunctions]] -deps = ["Static"] -git-tree-sha1 = "0c5f81f47bbbcf4aea7b2959135713459170798b" -uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" -version = "0.1.5" - -[[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.CPUSummary]] -deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] -git-tree-sha1 = "585a387a490f1c4bd88be67eea15b93da5e85db7" -uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" -version = "0.2.5" - -[[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 = "6e945e876652f2003e6ca74e19a3c45017d3e9f6" -uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.4.2" - - [deps.CUDA.extensions] - ChainRulesCoreExt = "ChainRulesCore" - EnzymeCoreExt = "EnzymeCore" - SpecialFunctionsExt = "SpecialFunctions" - - [deps.CUDA.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - -[[deps.CUDA_Driver_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "c48f9da18efd43b6b7adb7ee1f93fe5f2926c339" -uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.9.0+0" - -[[deps.CUDA_Runtime_Discovery]] -deps = ["Libdl"] -git-tree-sha1 = "f3b237289a5a77c759b2dd5d4c2ff641d67c4030" -uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "0.3.4" - -[[deps.CUDA_Runtime_jll]] -deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "bcba305388e16aa5c879e896726db9e71b4942c6" -uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.14.0+1" - -[[deps.ChainRulesCore]] -deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "71acdbf594aab5bbb2cec89b208c41b4c411e49f" -uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.24.0" -weakdeps = ["SparseArrays"] - - [deps.ChainRulesCore.extensions] - ChainRulesCoreSparseArraysExt = "SparseArrays" - -[[deps.ClimaOcean]] -deps = ["Adapt", "CFTime", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "ImageMorphology", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "Scratch", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] -path = ".." -uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" -version = "0.2.0" - -[[deps.ClimaSeaIce]] -deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "be4f97676cd18dc1566637e03c189b04c3fb4c59" -repo-rev = "main" -repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" -uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -version = "0.1.0" - -[[deps.CloseOpenIntervals]] -deps = ["Static", "StaticArrayInterface"] -git-tree-sha1 = "70232f82ffaab9dc52585e0dd043b5e0c6b714f1" -uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" -version = "0.1.12" - -[[deps.CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.4" - -[[deps.ColorTypes]] -deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.11.5" - -[[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 = "362a287c3aa50601b0bc359053d5c2468f0e7ce0" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.12.11" - -[[deps.CommonDataModel]] -deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] -git-tree-sha1 = "d6fb5bf939a2753c74984b11434ea25d6c397a58" -uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.3.6" - -[[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 = "b1c55339b7c6c350ee89f2c1604299660525b248" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.15.0" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.1+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" - - [deps.ConstructionBase.extensions] - ConstructionBaseIntervalSetsExt = "IntervalSets" - ConstructionBaseStaticArraysExt = "StaticArrays" - - [deps.ConstructionBase.weakdeps] - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.CpuId]] -deps = ["Markdown"] -git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" -uuid = "adafc99b-e345-5852-983c-f28acb93d879" -version = "0.3.1" - -[[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 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.20" - -[[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.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.DocStringExtensions]] -deps = ["LibGit2"] -git-tree-sha1 = "b19534d1895d702889b219c382a6e18010797f0b" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.8.6" - -[[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 = "5461b2a67beb9089980e2f8f25145186b6d34f91" -uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.4.1" - -[[deps.DocumenterTools]] -deps = ["Base64", "DocStringExtensions", "LibGit2"] -git-tree-sha1 = "58db9d1c626de92318ee35cbaf466739f4b5a09a" -uuid = "35a29f4d-8980-5a13-9543-d66fff28ecb8" -version = "0.1.2" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.0" - -[[deps.Elliptic]] -git-tree-sha1 = "71c79e77221ab3a29918aaf6db4f217b89138608" -uuid = "b305315f-e792-5b7a-8f41-49f472929428" -version = "1.0.1" - -[[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 = "1c6317308b9dc757616f0b5cb379db10494443a7" -uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.6.2+0" - -[[deps.ExprTools]] -git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" -uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" -version = "0.1.10" - -[[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.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.FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.5" - -[[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" - -[[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 = "c154546e322a9c73364e8a60430b0f79b812d320" -uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "10.2.0" - -[[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 = "518ebd058c9895de468a8c255797b0c53fdb44dd" -uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "0.26.5" - -[[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.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.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 = "d1d712be3164d61d1fb98e7ce9bcbc6cc06b45ed" -uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.8" - -[[deps.HostCPUFeatures]] -deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] -git-tree-sha1 = "eb8fed28f4994600e29beef49744639d985a04b2" -uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" -version = "0.1.16" - -[[deps.Hwloc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" -uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.10.0+0" - -[[deps.IOCapture]] -deps = ["Logging", "Random"] -git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" -uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" -version = "0.2.5" - -[[deps.IfElse]] -git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" -uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" -version = "0.1.1" - -[[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.ImageMorphology]] -deps = ["DataStructures", "ImageCore", "LinearAlgebra", "LoopVectorization", "OffsetArrays", "Requires", "TiledIteration"] -git-tree-sha1 = "6f0a801136cb9c229aebea0df296cdcd471dbcd1" -uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" -version = "0.4.5" - -[[deps.IncompleteLU]] -deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "6c676e79f98abb6d33fa28122cad099f1e464afe" -uuid = "40713840-3770-5561-ab4c-a76e7d0d7895" -version = "0.2.1" - -[[deps.InlineStrings]] -deps = ["Parsers"] -git-tree-sha1 = "86356004f30f8e737eff143d57d41bd580e437aa" -uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.1" - - [deps.InlineStrings.extensions] - ArrowTypesExt = "ArrowTypes" - - [deps.InlineStrings.weakdeps] - ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" - -[[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "be50fe8df3acbffa0274a744f1a99d29c45a57f4" -uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.1.0+0" - -[[deps.InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[deps.InverseFunctions]] -deps = ["Test"] -git-tree-sha1 = "e7cbed5032c4c397a6ac23d1493f3289e01231c4" -uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.14" -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.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", "Reexport", "Requires", "TranscodingStreams", "UUIDs", "Unicode"] -git-tree-sha1 = "bdbe8222d2f5703ad6a7019277d149ec6d78c301" -uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.48" - -[[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 = "95220473901735a0f4df9d1ca5b171b568b2daa3" -uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" -version = "1.13.2" - -[[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 = "b8fcefe4418e4a7a2c3aaac883fecddd8efbe286" -uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.21" - - [deps.KernelAbstractions.extensions] - EnzymeExt = "EnzymeCore" - - [deps.KernelAbstractions.weakdeps] - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - -[[deps.LLVM]] -deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "389aea28d882a40b5e1747069af71bdbd47a1cae" -uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "7.2.1" -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.LaTeXStrings]] -git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" -uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -version = "1.3.1" - -[[deps.LayoutPointers]] -deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "62edfee3211981241b57ff1cedf4d74d79519277" -uuid = "10f19ff3-798f-405d-979b-55457f8fc047" -version = "0.1.15" - -[[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.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.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" -uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.17.0+0" - -[[deps.LinearAlgebra]] -deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[deps.LogExpFunctions]] -deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "a2d09619db4e765091ee5c6ffe8872849de0feea" -uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.28" - - [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.LoopVectorization]] -deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] -git-tree-sha1 = "8f6786d8b2b3248d79db3ad359ce95382d5a6df8" -uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.170" -weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] - - [deps.LoopVectorization.extensions] - ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] - SpecialFunctionsExt = "SpecialFunctions" - -[[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", "oneTBB_jll"] -git-tree-sha1 = "80b2833b56d466b3858d565adcd16a4a05f2089b" -uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2024.1.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 = "4099bb6809ac109bfc17d521dad33763bcf026b7" -uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.2.1+1" - -[[deps.MPIPreferences]] -deps = ["Libdl", "Preferences"] -git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" -uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.11" - -[[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "8c35d5420193841b2f367e658540e8d9e0601ed0" -uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.4.0+0" - -[[deps.MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.13" - -[[deps.ManualMemory]] -git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" -uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" -version = "0.1.8" - -[[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.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 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "1.2.0" - -[[deps.Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[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.NCDatasets]] -deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] -git-tree-sha1 = "a640912695952b074672edb5f9aaee2f7f9fd59a" -uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.14.4" - -[[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.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.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 = "f5005c8637ebbc10dbbec3b3732cca11d39249ce" -repo-rev = "main" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" -uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.91.4" - - [deps.Oceananigans.extensions] - OceananigansEnzymeExt = "Enzyme" - - [deps.Oceananigans.weakdeps] - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - -[[deps.OffsetArrays]] -git-tree-sha1 = "e64b4f5ea6b7389f6f046d13d4896a8f9c1ba71e" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.14.0" -weakdeps = ["Adapt"] - - [deps.OffsetArrays.extensions] - OffsetArraysAdaptExt = "Adapt" - -[[deps.OpenBLAS_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] -uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.23+4" - -[[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", "TOML", "Zlib_jll"] -git-tree-sha1 = "a9de2f1fc98b92f8856c640bf4aec1ac9b2a0d86" -uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.3+0" - -[[deps.OpenSSL]] -deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "38cb508d080d21dc1128f7fb04f20387ed4c0af4" -uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.3" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "a028ee3cb5641cccc4c24e90c36b0a4f7707bdf5" -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.14+0" - -[[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.OrderedCollections]] -git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.6.3" - -[[deps.OrthogonalSphericalShellGrids]] -deps = ["Adapt", "CUDA", "Documenter", "DocumenterTools", "JLD2", "KernelAbstractions", "MPI", "Oceananigans", "OffsetArrays"] -git-tree-sha1 = "f9614694b607bd2168aef61a819f98a43b9b81c5" -repo-rev = "main" -repo-url = "https://github.com/CliMA/OrthogonalSphericalShellGrids.jl" -uuid = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" -version = "0.1.2" - -[[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.PackageExtensionCompat]] -git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" -uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" -version = "1.0.2" -weakdeps = ["Requires", "TOML"] - -[[deps.PaddedViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.5.12" - -[[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 = "fa85ac32172d96cfdb91dbc53e8e57007e5a2b5a" -uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" -version = "0.19.5" - - [deps.PencilArrays.extensions] - PencilArraysAMDGPUExt = ["AMDGPU"] - PencilArraysDiffEqExt = ["DiffEqBase"] - PencilArraysHDF5Ext = ["HDF5"] - - [deps.PencilArrays.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - 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.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.PolyesterWeave]] -deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] -git-tree-sha1 = "240d7170f5ffdb285f9427b92333c3463bf65bf6" -uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" -version = "0.2.1" - -[[deps.PooledArrays]] -deps = ["DataAPI", "Future"] -git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" -uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" -version = "1.4.3" - -[[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 = "66b20dd35966a748321d3b2537c4584cf40387c7" -uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.3.2" - -[[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.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.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.Requires]] -deps = ["UUIDs"] -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 = "5680a9276685d392c87407df00d57c9924d9f11e" -uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.7.1" -weakdeps = ["RecipesBase"] - - [deps.Rotations.extensions] - RotationsRecipesBaseExt = "RecipesBase" - -[[deps.SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[deps.SIMDTypes]] -git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" -uuid = "94e857df-77ce-4151-89e5-788b33177be4" -version = "0.1.0" - -[[deps.SLEEFPirates]] -deps = ["IfElse", "Static", "VectorizationBase"] -git-tree-sha1 = "3aac6d68c5e57449f5b9b865c9ba50ac2970c4cf" -uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" -version = "0.6.42" - -[[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 = "90b4f68892337554d31cdcdbe19e48989f26c7e6" -uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.3" - -[[deps.Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[deps.SimpleBufferStream]] -git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" -uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" -version = "1.1.0" - -[[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 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.4.0" -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 = "6e00379a24597be4ae1ee6b2d882e15392040132" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.5" -weakdeps = ["ChainRulesCore", "Statistics"] - - [deps.StaticArrays.extensions] - StaticArraysChainRulesCoreExt = "ChainRulesCore" - StaticArraysStatisticsExt = "Statistics" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.3" - -[[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.Strided]] -deps = ["LinearAlgebra", "StridedViews", "TupleTools"] -git-tree-sha1 = "bd9bd1c70cfc115cc3a30213fc725125a6b43652" -uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" -version = "2.1.0" - -[[deps.StridedViews]] -deps = ["LinearAlgebra", "PackageExtensionCompat"] -git-tree-sha1 = "2917996ce0fa6b8a3a85240a5e9ff930e2aeaa43" -uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" -version = "0.3.1" -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 = "89c701c87f378ce95e7ddbcd69b8f1106ba8b968" -uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.11.0" - - [deps.SurfaceFluxes.extensions] - CreateParametersExt = "ClimaParams" - - [deps.SurfaceFluxes.weakdeps] - ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" - -[[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" - - [deps.TaylorSeries.extensions] - TaylorSeriesIAExt = "IntervalArithmetic" - - [deps.TaylorSeries.weakdeps] - IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" - -[[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.ThreadingUtilities]] -deps = ["ManualMemory"] -git-tree-sha1 = "eda08f7e9818eb53661b3deb74e3159460dfbc27" -uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" -version = "0.5.2" - -[[deps.TiledIteration]] -deps = ["OffsetArrays", "StaticArrayInterface"] -git-tree-sha1 = "1176cc31e867217b06928e2f140c90bd1bc88283" -uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" -version = "0.5.0" - -[[deps.TimerOutputs]] -deps = ["ExprTools", "Printf"] -git-tree-sha1 = "5a13ae8a41237cff5ecf34f73eb1b8f42fff6531" -uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" -version = "0.5.24" - -[[deps.TranscodingStreams]] -git-tree-sha1 = "d73336d81cafdc277ff45558bb7eaa2b04a8e472" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.10" -weakdeps = ["Random", "Test"] - - [deps.TranscodingStreams.extensions] - TestExt = ["Test", "Random"] - -[[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.UnsafeAtomics]] -git-tree-sha1 = "6331ac3440856ea1988316b46045303bef658278" -uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" -version = "0.2.1" - -[[deps.UnsafeAtomicsLLVM]] -deps = ["LLVM", "UnsafeAtomics"] -git-tree-sha1 = "d9f5962fecd5ccece07db1ff006fb0b5271bdfdd" -uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" -version = "0.1.4" - -[[deps.VectorizationBase]] -deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "e863582a41c5731f51fd050563ae91eb33cf09be" -uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" -version = "0.21.68" - -[[deps.VersionParsing]] -git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" -uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" -version = "1.3.0" - -[[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "52ff2af32e591541550bd753c0da8b9bc92bb9d9" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.12.7+0" - -[[deps.XZ_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "ac88fb95ae6447c8dda6a5503f3bafd496ae8632" -uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" -version = "5.4.6+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.libaec_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "46bf7be2917b59b761247be3f317ddf75e50e997" -uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" -version = "1.1.2+0" - -[[deps.libblastrampoline_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.8.0+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.oneTBB_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "7d0ea0f4895ef2f5cb83645fa689e52cb55cf493" -uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" -version = "2021.12.0+0" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" diff --git a/experiments/mesoscale_resolving_omip/Project.toml b/experiments/mesoscale_resolving_omip/Project.toml deleted file mode 100644 index e8e6b41fc..000000000 --- a/experiments/mesoscale_resolving_omip/Project.toml +++ /dev/null @@ -1,13 +0,0 @@ -[deps] -Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -CFTime = "179af706-886a-5703-950a-314cd64e0468" -ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" -ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" -JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" -KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -OrthogonalSphericalShellGrids = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" -SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" -SurfaceFluxes = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" diff --git a/experiments/mesoscale_resolving_omip/lat_lon_near_global_simulation.jl b/experiments/mesoscale_resolving_omip/lat_lon_near_global_simulation.jl deleted file mode 100644 index 125b7631e..000000000 --- a/experiments/mesoscale_resolving_omip/lat_lon_near_global_simulation.jl +++ /dev/null @@ -1,169 +0,0 @@ -using Oceananigans -using Oceananigans.Units - -using ClimaOcean -using ClimaOcean.ECCO: ECCO_restoring_forcing, ECCO4Monthly, ECCO2Daily, ECCOMetadata - -using OrthogonalSphericalShellGrids -using Printf - -using CFTime -using Dates - -##### -##### Global ocean simulation -##### - -Nx = 4 * 360 -Ny = 4 * 160 -Nz = 60 -arch = GPU() -z_faces = exponential_z_faces(depth=5000; Nz) -prefix = "near_global_omip_Nz$(Nz)_" - -#arch = Distributed(GPU(), partition = Partition(2)) - -grid = LatitudeLongitudeGrid(arch; - size = (Nx, Ny, Nz), - halo = (5, 5, 5), - longitude = (0, 360), - latitude = (-80, 80), - z = z_faces) - -@info "Put together a grid:" -@info grid - -bottom_height = retrieve_bathymetry(grid; - minimum_depth = 10, - interpolation_passes = 10, - major_basins = 1) - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) - -##### -##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic -##### - -@inline function restoring_mask(λ, φ, z, t=0) - ϵN = (φ - 75) / 5 - ϵN = clamp(ϵN, zero(ϵN), one(ϵN)) - ϵS = - (φ + 75) / 5 - ϵS = clamp(ϵS, zero(ϵS), one(ϵS)) - return ϵN + ϵS -end - -restoring_mask_field = CenterField(grid) -set!(restoring_mask_field, restoring_mask) - -@inline sponge_layer(λ, φ, z, t, c, ω) = - restoring_mask(λ, φ, z, t) * ω * c -Fu = Forcing(sponge_layer, field_dependencies=:u, parameters=1/1days) -Fv = Forcing(sponge_layer, field_dependencies=:v, parameters=1/1days) - -dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(2003, 12, 1) - -temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) -salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) - -FT = ECCO_restoring_forcing(temperature; mask=restoring_mask_field, grid, architecture=arch, timescale=1days) -FS = ECCO_restoring_forcing(salinity; mask=restoring_mask_field, grid, architecture=arch, timescale=1days) -forcing = (; T=FT, S=FS, u=Fu, v=Fv) - -# New advection scheme -tracer_advection = WENO(order=5) -momentum_advection = WENOVectorInvariant(vorticity_order=5) - -ocean = ocean_simulation(grid; forcing, tracer_advection, momentum_advection) - -fluxes = (u = ocean.model.velocities.u.boundary_conditions.top.condition, - v = ocean.model.velocities.v.boundary_conditions.top.condition, - T = ocean.model.tracers.T.boundary_conditions.top.condition, - S = ocean.model.tracers.S.boundary_conditions.top.condition) - -ocean.output_writers[:fluxes] = JLD2OutputWriter(ocean.model, fluxes, - schedule = TimeInterval(1days), - with_halos = true, - overwrite_existing = true, - array_type = Array{Float32}, - filename = prefix * "surface_fluxes") - -ocean.output_writers[:surface] = JLD2OutputWriter(ocean.model, merge(ocean.model.tracers, ocean.model.velocities), - schedule = TimeInterval(1days), - with_halos = true, - overwrite_existing = true, - array_type = Array{Float32}, - filename = prefix * "surface", - indices = (:, :, grid.Nz)) - -ocean.output_writers[:snapshots] = JLD2OutputWriter(ocean.model, merge(ocean.model.tracers, ocean.model.velocities), - schedule = TimeInterval(10days), - with_halos = true, - overwrite_existing = true, - array_type = Array{Float32}, - filename = prefix * "snapshots") - -ocean.output_writers[:checkpoint] = Checkpointer(ocean.model, - schedule = TimeInterval(60days), - overwrite_existing = true, - prefix = prefix * "checkpoint") - -@info "Built an ocean simulation with the model:" -@info ocean.model -@info "\ninside the simulation:" -@info ocean - -##### -##### The atmosphere -##### - -backend = JRA55NetCDFBackend(4) -atmosphere = JRA55PrescribedAtmosphere(arch; backend) -radiation = Radiation(arch, ocean_albedo=LatitudeDependentAlbedo()) -coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) - -@info "Set up coupled model:" -@info coupled_model - -coupled_simulation = Simulation(coupled_model; Δt=30.0, stop_time=25days) - -# Spin up -set!(ocean.model, - T = ECCOMetadata(:temperature, dates[1], ECCO2Daily()), - S = ECCOMetadata(:salinity, dates[1], ECCO2Daily())) - -wall_time = Ref(time_ns()) - -function progress(sim) - ocean = sim.model.ocean - u, v, w = ocean.model.velocities - T, S = ocean.model.tracers - - Tmax = maximum(interior(T)) - Tmin = minimum(interior(T)) - umax = maximum(abs, interior(u)), maximum(abs, interior(v)), maximum(abs, interior(w)) - step_time = 1e-9 * (time_ns() - wall_time[]) - - msg = @sprintf("Time: %s, iter: %d, Δt: %s", - prettytime(sim), iteration(sim), prettytime(sim.Δt)) - - msg *= @sprintf("max(u): (%.2e, %.2e, %.2e) m s⁻¹, extrema(T): %.2fᵒC, %.2fᵒC, wall time: %s", - umax..., Tmax, Tmin, prettytime(step_time)) - - wall_time[] = time_ns() -end - -add_callback!(coupled_simulation, progress, IterationInterval(10)) - -@info "Running the coupled simulation:" -@info coupled_simulation - -run!(coupled_simulation) - -# Run for real -coupled_simulation.Δt = 5minutes - -# Let's reset the maximum number of iterations -coupled_simulation.stop_time = 7200days -coupled_simulation.stop_iteration = Inf - -run!(coupled_simulation) - diff --git a/experiments/mesoscale_resolving_omip/prototype_omip_simulation.jl b/experiments/mesoscale_resolving_omip/prototype_omip_simulation.jl deleted file mode 100644 index b57e24a20..000000000 --- a/experiments/mesoscale_resolving_omip/prototype_omip_simulation.jl +++ /dev/null @@ -1,210 +0,0 @@ -using Printf -using Oceananigans -using Oceananigans.Units -using ClimaOcean -using OrthogonalSphericalShellGrids -using Oceananigans -using Oceananigans: architecture -using Oceananigans.Grids: on_architecture -using Oceananigans.Coriolis: ActiveCellEnstrophyConserving -using Oceananigans.Units -using ClimaOcean -using ClimaOcean.OceanSimulations -using ClimaOcean.OceanSeaIceModels -using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation, SimilarityTheoryFluxes -using ClimaOcean.VerticalGrids: exponential_z_faces -using ClimaOcean.JRA55 -using ClimaOcean.ECCO -using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55PrescribedAtmosphere -using ClimaOcean.ECCO: ECCO_restoring_forcing, ECCO4Monthly, ECCO2Daily, ECCOMetadata -using ClimaOcean.Bathymetry -using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: LatitudeDependentAlbedo - -import ClimaOcean: stateindex - -using CFTime -using Dates - -include("tripolar_specific_methods.jl") - -##### -##### Global Ocean at 1/6th of a degree -##### - -bathymetry_file = nothing # "bathymetry_tmp.jld2" - -# 60 vertical levels -z_faces = exponential_z_faces(Nz=60, depth=6000) - -Nx = 2160 -Ny = 1080 -Nz = length(z_faces) - 1 - -arch = GPU() #Distributed(GPU(), partition = Partition(2)) - -grid = TripolarGrid(arch; - size = (Nx, Ny, Nz), - halo = (7, 7, 7), - z = z_faces, - north_poles_latitude = 55, - first_pole_longitude = 75) - -bottom_height = retrieve_bathymetry(grid, bathymetry_file; - minimum_depth = 10, - dir = "./", - interpolation_passes = 20, - connected_regions_allowed = 0) - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) - -##### -##### The Ocean component -##### - -free_surface = SplitExplicitFreeSurface(grid; cfl = 0.75, fixed_Δt = 600) - -##### -##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic -##### - -# Build a mask that goes from 0 to 1 as a cubic function of φ between -# 70 degrees and 90 degrees and zero derivatives at 70 and 90. -x₁ = 70 -x₂ = 90 -y₁ = 0 -y₂ = 1 - -A⁺ = [ x₁^3 x₁^2 x₁ 1 - x₂^3 x₂^2 x₂ 1 - 3*x₁^2 2*x₁ 1 0 - 3*x₂^2 2*x₂ 1 0] - -b⁺ = [y₁, y₂, 0, 0] -c⁺ = A⁺ \ b⁺ - -# Coefficients for the cubic mask -const c₁⁺ = c⁺[1] -const c₂⁺ = c⁺[2] -const c₃⁺ = c⁺[3] -const c₄⁺ = c⁺[4] - -const c₁⁻ = - c⁺[1] -const c₂⁻ = c⁺[2] -const c₃⁻ = - c⁺[3] -const c₄⁻ = c⁺[4] - -@inline mask_f(λ, φ, z) = ifelse(φ >= 70, c₁⁺ * φ^3 + c₂⁺ * φ^2 + c₃⁺ * φ + c₄⁺, - ifelse(φ <= -70, c₁⁻ * φ^3 + c₂⁻ * φ^2 + c₃⁻ * φ + c₄⁻, zero(eltype(φ)))) - -mask = CenterField(grid) -set!(mask, mask_f) - -dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(2003, 12, 1) - -temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) -salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) - -FT = ECCO_restoring_forcing(temperature; mask, grid, architecture = arch, timescale = 30days) -FS = ECCO_restoring_forcing(salinity; mask, grid, architecture = arch, timescale = 30days) - -forcing = (; T = FT, S = FS) - -ocean = ocean_simulation(grid; free_surface, forcing) -model = ocean.model - -initial_date = dates[1] - -##### -##### The atmosphere -##### - -backend = JRA55NetCDFBackend(4) -atmosphere = JRA55PrescribedAtmosphere(arch; backend) -radiation = Radiation(arch) -coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) - -wall_time = [time_ns()] - -function progress(sim) - u, v, w = sim.model.velocities - T, S = sim.model.tracers - - Tmax = maximum(interior(T)) - Tmin = minimum(interior(T)) - umax = maximum(interior(u)), maximum(interior(v)), maximum(interior(w)) - step_time = 1e-9 * (time_ns() - wall_time[1]) - - @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", - prettytime(sim.model.clock.time), - sim.model.clock.iteration, - prettytime(sim.Δt), - umax..., Tmax, Tmin, prettytime(step_time)) - - wall_time[1] = time_ns() -end - -ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -fluxes = (u = model.velocities.u.boundary_conditions.top.condition, - v = model.velocities.v.boundary_conditions.top.condition, - T = model.tracers.T.boundary_conditions.top.condition, - S = model.tracers.S.boundary_conditions.top.condition) - -ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes, - schedule = TimeInterval(0.5days), - overwrite_existing = false, - array_type = Array{Float32}, - filename = "surface_fluxes") - -ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), - schedule = TimeInterval(0.5days), - overwrite_existing = false, - array_type = Array{Float32}, - filename = "surface", - indices = (:, :, grid.Nz)) - -ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), - schedule = TimeInterval(10days), - overwrite_existing = false, - array_type = Array{Float32}, - filename = "snapshots") - -ocean.output_writers[:checkpoint] = Checkpointer(model, - schedule = TimeInterval(60days), - overwrite_existing = true, - prefix = "checkpoint") - -restart = nothing - -coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) -ocean.Δt = 10 - -if isnothing(restart) - - # Set simulation from ECCO2 fields - set!(ocean.model, - T = ECCOMetadata(:temperature, initial_date, ECCO2Daily()), - S = ECCOMetadata(:salinity, initial_date, ECCO2Daily())) - - # Simulation warm up! - wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 1.5minutes, max_change = 1.1) - ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) - - stop_time = 25days - - run!(coupled_simulation) -else - # Set the ocean from the restart file - set!(ocean.model, restart) -end - -wizard = TimeStepWizard(; cfl = 0.3, max_Δt = 600, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) - -# Let's reset the maximum number of iterations -coupled_model.ocean.stop_time = 7200days -coupled_simulation.stop_time = 7200days -coupled_model.ocean.stop_iteration = Inf -coupled_simulation.stop_iteration = Inf - -run!(coupled_simulation) diff --git a/experiments/mesoscale_resolving_omip/tripolar_specific_methods.jl b/experiments/mesoscale_resolving_omip/tripolar_specific_methods.jl deleted file mode 100644 index 0e3e342de..000000000 --- a/experiments/mesoscale_resolving_omip/tripolar_specific_methods.jl +++ /dev/null @@ -1,75 +0,0 @@ -using ClimaOcean -import ClimaOcean.InitialConditions: interpolate! - -using Oceananigans -using Oceananigans.Operators -using Oceananigans.BoundaryConditions -using Oceananigans.Fields: OneField -using Oceananigans.Grids: peripheral_node -using Oceananigans.Utils: launch! -using Oceananigans.Fields: instantiated_location, interior, CenterField -using Oceananigans.Architectures: architecture, device, GPU, child_architecture - -# Implementation of 3-dimensional regridding -# TODO: move all the following to Oceananigans! - -using Oceananigans.Fields: regrid!, interpolate! -using Oceananigans.Grids: cpu_face_constructor_x, - cpu_face_constructor_y, - cpu_face_constructor_z, - topology, - λnode, φnode - -using OrthogonalSphericalShellGrids: TRG -import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: extrinsic_vector, intrinsic_vector - -@inline hack_cosd(φ) = cos(π * φ / 180) -@inline hack_sind(φ) = sin(π * φ / 180) - -# TODO: when https://github.com/CliMA/Oceananigans.jl/pull/3631 is merged, -# these functions will be transferred to OrthogonalSphericalShellGrids - -# Here we assume that the tripolar grid is locally orthogonal -@inline function extrinsic_vector(i, j, k, grid::TRG, uₒ, vₒ) - - φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) - φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) - Δyᶜᶜᵃ = Δyᶜᶜᶜ(i, j, 1, grid) - - ũ = deg2rad(φᶜᶠᵃ₊ - φᶜᶠᵃ₋) / Δyᶜᶜᵃ - - φᶠᶜᵃ₊ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) - φᶠᶜᵃ₋ = φnode(i, j, 1, grid, Face(), Center(), Center()) - Δxᶜᶜᵃ = Δxᶜᶜᶜ(i, j, 1, grid) - - ṽ = - deg2rad(φᶠᶜᵃ₊ - φᶠᶜᵃ₋) / Δxᶜᶜᵃ - - 𝒰 = sqrt(ũ^2 + ṽ^2) - - d₁ = ũ / 𝒰 - d₂ = ṽ / 𝒰 - - return uₒ * d₁ - vₒ * d₂, uₒ * d₂ + vₒ * d₁ -end - -@inline function intrinsic_vector(i, j, k, grid::TRG, uₒ, vₒ) - - φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) - φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) - Δyᶜᶜᵃ = Δyᶜᶜᶜ(i, j, 1, grid) - - ũ = deg2rad(φᶜᶠᵃ₊ - φᶜᶠᵃ₋) / Δyᶜᶜᵃ - - φᶠᶜᵃ₊ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) - φᶠᶜᵃ₋ = φnode(i, j, 1, grid, Face(), Center(), Center()) - Δxᶜᶜᵃ = Δxᶜᶜᶜ(i, j, 1, grid) - - ṽ = - deg2rad(φᶠᶜᵃ₊ - φᶠᶜᵃ₋) / Δxᶜᶜᵃ - - 𝒰 = sqrt(ũ^2 + ṽ^2) - - d₁ = ũ / 𝒰 - d₂ = ṽ / 𝒰 - - return uₒ * d₁ + vₒ * d₂, uₒ * d₂ - vₒ * d₁ -end diff --git a/experiments/three_degree_simulation/analyze_quarter_degree_simulation.jl b/experiments/three_degree_simulation/analyze_quarter_degree_simulation.jl deleted file mode 100644 index 97d824474..000000000 --- a/experiments/three_degree_simulation/analyze_quarter_degree_simulation.jl +++ /dev/null @@ -1,33 +0,0 @@ -using Oceananigans -using ClimaOcean -using GLMakie - -filename = "three_degree_simulation_surface.jld2" - -# ht = FieldTimeSeries(filename, "h") -ℵt = FieldTimeSeries(filename, "ℵ") -Tt = FieldTimeSeries(filename, "T") - -fig = Figure(size=(1200, 1200)) - -#axh = Axis(fig[1, 1]) -axℵ = Axis(fig[1, 1]) -axT = Axis(fig[2, 1]) - -Nt = length(Tt) -n = Observable(1) -#ℵn = @lift interior(ℵt[$n], :, :, 1) -ℵn = @lift ℵt[$n] -Tn = @lift interior(Tt[$n], :, :, 1) - -#heatmap!(axh, hn) -heatmap!(axℵ, ℵn) -heatmap!(axT, Tn) - -display(fig) - -record(fig, "quarter_degree_acc.mp4", 1:Nt, framerate=12) do nn - @info "Drawing frame $nn of $Nt..." - n[] = nn -end - diff --git a/experiments/three_degree_simulation/coupled_global_simulation.jl b/experiments/three_degree_simulation/coupled_global_simulation.jl deleted file mode 100644 index 33d414b52..000000000 --- a/experiments/three_degree_simulation/coupled_global_simulation.jl +++ /dev/null @@ -1,208 +0,0 @@ -using ClimaOcean -using ClimaOcean.ECCO: ECCO4Monthly -using ClimaSeaIce -using OrthogonalSphericalShellGrids -using Oceananigans -using Oceananigans.Units -using CFTime -using Dates -using Printf -using Statistics -using Oceananigans.TimeSteppers: update_state! - -arch = GPU() - -#Nx = 2160 -#Ny = 1080 -#Nz = 60 - -Nx = 360 * 1 -Ny = 180 * 1 - -Nz = 40 -z_faces = exponential_z_faces(; Nz, depth=5000, h=30) -prefix = "deep_half_degree_simulation_io" - -#Nz = 10 -#z_faces = (-3000, 0) -#prefix = "shallow_fourth_degree_simulation" - -underlying_grid = TripolarGrid(arch; size=(Nx, Ny, Nz), halo=(7, 7, 7), z=z_faces) -bottom_height = regrid_bathymetry(underlying_grid) -grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bottom_height)) - -catke = ClimaOcean.OceanSimulations.default_ocean_closure() - -dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 12, 1) -temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) -salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) - -ocean = ocean_simulation(grid; - closure = catke, - tracers = (:T, :S, :e), - momentum_advection = WENOVectorInvariant(vorticity_order=5), - tracer_advection = WENO(order=5)) - -radiation = Radiation(arch) -atmosphere = JRA55PrescribedAtmosphere(arch; backend=JRA55NetCDFBackend(20)) - -##### -##### Sea ice model stuff -##### - -sea_ice_grid = underlying_grid -land_mask = interior(bottom_height) .>= 0 -sea_ice_grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBoundary(land_mask)) -top_sea_ice_temperature = Field{Center, Center, Nothing}(sea_ice_grid) -top_heat_boundary_condition = PrescribedTemperature(top_sea_ice_temperature) -ice_thermodynamics = SlabSeaIceThermodynamics(sea_ice_grid; top_heat_boundary_condition) - -top_sea_ice_heat_flux = Field{Center, Center, Nothing}(sea_ice_grid) -bottom_sea_ice_heat_flux = Field{Center, Center, Nothing}(sea_ice_grid) - -sea_ice_model = SeaIceModel(sea_ice_grid; - top_heat_flux = top_sea_ice_heat_flux, - bottom_heat_flux = bottom_sea_ice_heat_flux, - ice_thermodynamics) - -sea_ice = Simulation(sea_ice_model, Δt=10minutes) -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -simulation = Simulation(coupled_model; Δt=10minutes, stop_time=4*360days) - -start_date = first(dates) -thickness_meta = ECCOMetadata(:sea_ice_thickness; dates=start_date) -concentration_meta = ECCOMetadata(:sea_ice_concentration; dates=start_date) -set!(sea_ice.model.ice_thickness, thickness_meta) -set!(sea_ice.model.ice_concentration, concentration_meta) - -set!(ocean.model, T=ECCOMetadata(:temperature; dates=start_date), - S=ECCOMetadata(:salinity; dates=start_date), u=0, v=0) - -wall_time = Ref(time_ns()) - -function progress(sim) - sea_ice = sim.model.sea_ice - h = sea_ice.model.ice_thickness - Tai = coupled_model.interfaces.atmosphere_sea_ice_interface.temperature - hmax = maximum(interior(h)) - Taimin = minimum(interior(Tai)) - - ocean = sim.model.ocean - u, v, w = ocean.model.velocities - T = ocean.model.tracers.T - Tmax = maximum(interior(T)) - Tmin = minimum(interior(T)) - umax = (maximum(abs, interior(u)), maximum(abs, interior(v)), maximum(abs, interior(w))) - step_time = 1e-9 * (time_ns() - wall_time[]) - - Fv_ao = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.water_vapor - Qv_ao = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.latent_heat - Qc_ao = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.sensible_heat - τx_ao = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.x_momentum - τy_ao = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.y_momentum - - Fv_ai = coupled_model.interfaces.atmosphere_sea_ice_interface.fluxes.water_vapor - Qv_ai = coupled_model.interfaces.atmosphere_sea_ice_interface.fluxes.latent_heat - Qc_ai = coupled_model.interfaces.atmosphere_sea_ice_interface.fluxes.sensible_heat - τx_ai = coupled_model.interfaces.atmosphere_sea_ice_interface.fluxes.x_momentum - τy_ai = coupled_model.interfaces.atmosphere_sea_ice_interface.fluxes.y_momentum - - msg = @sprintf("Time: %s, n: %d, Δt: %s, \ - max(h): %.1f, \ - min(Ti): %.2f ᵒC, \ - max|u|: (%.2e, %.2e, %.2e) m s⁻¹, \ - extrema(To): (%.1f, %.1f) ᵒC, \ - wall time: %s \n", - prettytime(sim), iteration(sim), prettytime(sim.Δt), - hmax, - Taimin,# Taiavg, - umax..., - Tmin, Tmax, - prettytime(step_time)) - - max_Fv_ai = maximum(Fv_ai) - max_Qv_ai = maximum(Qv_ai) - max_Qc_ai = maximum(Qc_ai) - max_τx_ai = maximum(τx_ai) - max_τy_ai = maximum(τy_ai) - - min_Fv_ai = minimum(Fv_ai) - min_Qv_ai = minimum(Qv_ai) - min_Qc_ai = minimum(Qc_ai) - min_τx_ai = minimum(τx_ai) - min_τy_ai = minimum(τy_ai) - - max_Fv_ao = maximum(Fv_ao) - max_Qv_ao = maximum(Qv_ao) - max_Qc_ao = maximum(Qc_ao) - max_τx_ao = maximum(τx_ao) - max_τy_ao = maximum(τy_ao) - - min_Fv_ao = minimum(Fv_ao) - min_Qv_ao = minimum(Qv_ao) - min_Qc_ao = minimum(Qc_ao) - min_τx_ao = minimum(τx_ao) - min_τy_ao = minimum(τy_ao) - - msg *= @sprintf(" ao: extrema(Qv): (% 6d, % 6d), ao: extrema(Qc): (% 6d, % 6d), ao: extrema(Fv): (% 6d, % 6d), ao: extrema(τx): (% 6d, % 6d), ao: extrema(τy): (% 6d, % 6d) \n", - min_Qv_ao, max_Qv_ao, - min_Qc_ao, max_Qc_ao, - 1e6 * min_Fv_ao, 1e6 * max_Fv_ao, - 1e3 * min_τx_ao, 1e3 * max_τx_ao, - 1e3 * min_τy_ao, 1e3 * max_τy_ao) - - msg *= @sprintf(" ai: extrema(Qv): (% 6d, % 6d), ai: extrema(Qc): (% 6d, % 6d), ai: extrema(Fv): (% 6d, % 6d)", - min_Qv_ai, max_Qv_ai, - min_Qc_ai, max_Qc_ai, - 1e6 * min_Fv_ai, 1e6 * max_Fv_ai) - - @info msg - - wall_time[] = time_ns() - - return nothing -end - -add_callback!(simulation, progress, IterationInterval(100)) - -Qv = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.latent_heat -Qc = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.sensible_heat -τx = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.x_momentum -τy = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.y_momentum -Fv = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.water_vapor - -fluxes = (; Qv, Qc, τx, τy, Fv) - -Nz = size(grid, 3) -u, v, w = ocean.model.velocities -s_op = @at (Center, Center, Center) sqrt(u^2 + v^2) -s = Field(s_op, indices=(:, :, Nz)) -ocean_outputs = merge(ocean.model.velocities, ocean.model.tracers, (; s)) - -ocean_outputs = NamedTuple(name => view(ocean_outputs[name], :, :, Nz) for name in keys(ocean_outputs)) -h = sea_ice_model.ice_thickness -ℵ = sea_ice_model.ice_concentration -Ti = top_sea_ice_temperature -sea_ice_outputs = (; h, ℵ, Ti) - -surface_outputs = merge(ocean_outputs, sea_ice_outputs, fluxes) - -surface_ow = JLD2OutputWriter(ocean.model, surface_outputs, - filename = prefix * "_surface.jld2", - schedule = TimeInterval(5days), - overwrite_existing = true) - -simulation.output_writers[:jld2] = surface_ow - -fields_outputs = merge(ocean.model.velocities, ocean.model.tracers) -fields_outputs = merge(fields_outputs, (; h, ℵ)) - -fields_ow = JLD2OutputWriter(ocean.model, fields_outputs, - filename = prefix * "_fields.jld2", - schedule = TimeInterval(30days), - overwrite_existing = true) - -simulation.output_writers[:fields] = fields_ow - -run!(simulation) - diff --git a/experiments/three_degree_simulation/three_degree_simulation.jl b/experiments/three_degree_simulation/three_degree_simulation.jl deleted file mode 100644 index aaadb3693..000000000 --- a/experiments/three_degree_simulation/three_degree_simulation.jl +++ /dev/null @@ -1,219 +0,0 @@ -using ClimaOcean -using ClimaOcean.ECCO: ECCO4Monthly -using ClimaSeaIce -using OrthogonalSphericalShellGrids -using Oceananigans -using Oceananigans.Units -using CFTime -using Dates -using Printf -using Statistics -using Oceananigans.TimeSteppers: update_state! - -arch = CPU() - -#= -Nx = 360 * 4 -Ny = 60 * 4 -Nz = 60 -=# - -Nx = 120 -Ny = 60 -Nz = 30 -z_faces = exponential_z_faces(; Nz, depth=5000, h=30) - -latitude = (-80, -20) -longitude = (0, 360) - -underlying_grid = LatitudeLongitudeGrid(arch; size=(Nx, Ny, Nz), halo=(7, 7, 7), latitude, longitude, z=z_faces) -bottom_height = regrid_bathymetry(underlying_grid) -grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bottom_height)) - -gm = Oceananigans.TurbulenceClosures.IsopycnalSkewSymmetricDiffusivity(κ_skew=2000, κ_symmetric=2000) -catke = ClimaOcean.OceanSimulations.default_ocean_closure() -viscous_closure = Oceananigans.TurbulenceClosures.HorizontalScalarDiffusivity(ν=2000) - -dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 12, 1) -temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) -salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) - -restoring_rate = 1/2days -mask = LinearlyTaperedPolarMask(northern=(-25, -20)) -FT = ECCORestoring(temperature, grid; mask, rate=restoring_rate) -FS = ECCORestoring(salinity, grid; mask, rate=restoring_rate) - -ocean = ocean_simulation(grid; - #momentum_advection = VectorInvariant(), - #tracer_advection = Centered(order=2), - #closure = (gm, catke, viscous_closure), - closure = catke, - # forcing = (T=FT, S=FT), - tracers = (:T, :S, :e)) - -start_date = first(dates) -#set!(ocean.model, T=ECCOMetadata(:temperature; dates=start_date), -# S=ECCOMetadata(:salinity; dates=start_date)) - -radiation = Radiation(arch) -atmosphere = JRA55PrescribedAtmosphere(arch; backend=JRA55NetCDFBackend(20)) -# ocean.model.clock.time = 180days - -##### -##### Sea ice model stuff -##### - -sea_ice_grid = LatitudeLongitudeGrid(arch; size=(Nx, Ny), latitude, longitude, topology=(Periodic, Bounded, Flat)) -land_mask = interior(bottom_height) .>= 0 -sea_ice_grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBoundary(land_mask)) -top_sea_ice_temperature = Field{Center, Center, Nothing}(sea_ice_grid) -top_heat_boundary_condition = PrescribedTemperature(top_sea_ice_temperature) -ice_thermodynamics = SlabSeaIceThermodynamics(sea_ice_grid; top_heat_boundary_condition) - -top_sea_ice_heat_flux = Field{Center, Center, Nothing}(sea_ice_grid) -bottom_sea_ice_heat_flux = Field{Center, Center, Nothing}(sea_ice_grid) - -sea_ice_model = SeaIceModel(sea_ice_grid; - top_heat_flux = top_sea_ice_heat_flux, - bottom_heat_flux = bottom_sea_ice_heat_flux, - ice_thermodynamics) - -sea_ice = Simulation(sea_ice_model, Δt=10minutes) - -thickness_meta = ECCOMetadata(:sea_ice_thickness; dates=start_date) -concentration_meta = ECCOMetadata(:sea_ice_concentration; dates=start_date) -set!(sea_ice.model.ice_thickness, thickness_meta) -set!(sea_ice.model.ice_concentration, concentration_meta) - -set!(ocean.model, T=ECCOMetadata(:temperature; dates=start_date), - S=ECCOMetadata(:salinity; dates=start_date), u=0, v=0) - -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -simulation = Simulation(coupled_model; Δt=10minutes, stop_time=3days) - -ℵ = sea_ice.model.ice_concentration -heatmap(ℵ) - -#h = sea_ice.model.ice_thickness -#heatmap(h) - - -#= - -wall_time = Ref(time_ns()) - -function progress(sim) - sea_ice = sim.model.sea_ice - h = sea_ice.model.ice_thickness - Tai = coupled_model.interfaces.atmosphere_sea_ice_interface.temperature - hmax = maximum(interior(h)) - #Taiavg = mean(interior(Tai)) - Taimin = minimum(interior(Tai)) - - ocean = sim.model.ocean - u, v, w = ocean.model.velocities - T = ocean.model.tracers.T - Tmax = maximum(interior(T)) - Tmin = minimum(interior(T)) - umax = (maximum(abs, interior(u)), maximum(abs, interior(v)), maximum(abs, interior(w))) - step_time = 1e-9 * (time_ns() - wall_time[]) - - Fv_ao = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.water_vapor - Qv_ao = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.latent_heat - Qc_ao = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.sensible_heat - τx_ao = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.x_momentum - τy_ao = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.y_momentum - - Fv_ai = coupled_model.interfaces.atmosphere_sea_ice_interface.fluxes.water_vapor - Qv_ai = coupled_model.interfaces.atmosphere_sea_ice_interface.fluxes.latent_heat - Qc_ai = coupled_model.interfaces.atmosphere_sea_ice_interface.fluxes.sensible_heat - τx_ai = coupled_model.interfaces.atmosphere_sea_ice_interface.fluxes.x_momentum - τy_ai = coupled_model.interfaces.atmosphere_sea_ice_interface.fluxes.y_momentum - - msg = @sprintf("Time: %s, n: %d, Δt: %s, \ - max(h): %.1f, \ - min(Ti): %.2f ᵒC, \ - max|u|: (%.2e, %.2e, %.2e) m s⁻¹, \ - extrema(To): (%.1f, %.1f) ᵒC, \ - wall time: %s \n", - prettytime(sim), iteration(sim), prettytime(sim.Δt), - hmax, - Taimin,# Taiavg, - umax..., - Tmin, Tmax, - prettytime(step_time)) - - max_Fv_ai = maximum(Fv_ai) - max_Qv_ai = maximum(Qv_ai) - max_Qc_ai = maximum(Qc_ai) - max_τx_ai = maximum(τx_ai) - max_τy_ai = maximum(τy_ai) - - min_Fv_ai = minimum(Fv_ai) - min_Qv_ai = minimum(Qv_ai) - min_Qc_ai = minimum(Qc_ai) - min_τx_ai = minimum(τx_ai) - min_τy_ai = minimum(τy_ai) - - max_Fv_ao = maximum(Fv_ao) - max_Qv_ao = maximum(Qv_ao) - max_Qc_ao = maximum(Qc_ao) - max_τx_ao = maximum(τx_ao) - max_τy_ao = maximum(τy_ao) - - min_Fv_ao = minimum(Fv_ao) - min_Qv_ao = minimum(Qv_ao) - min_Qc_ao = minimum(Qc_ao) - min_τx_ao = minimum(τx_ao) - min_τy_ao = minimum(τy_ao) - - msg *= @sprintf(" ao: extrema(Qv): (% 6d, % 6d), ao: extrema(Qc): (% 6d, % 6d), ao: extrema(Fv): (% 6d, % 6d), ao: extrema(τx): (% 6d, % 6d), ao: extrema(τy): (% 6d, % 6d) \n", - min_Qv_ao, max_Qv_ao, - min_Qc_ao, max_Qc_ao, - 1e6 * min_Fv_ao, 1e6 * max_Fv_ao, - 1e3 * min_τx_ao, 1e3 * max_τx_ao, - 1e3 * min_τy_ao, 1e3 * max_τy_ao) - - msg *= @sprintf(" ai: extrema(Qv): (% 6d, % 6d), ai: extrema(Qc): (% 6d, % 6d), ai: extrema(Fv): (% 6d, % 6d)", - min_Qv_ai, max_Qv_ai, - min_Qc_ai, max_Qc_ai, - 1e6 * min_Fv_ai, 1e6 * max_Fv_ai) - - @info msg - - wall_time[] = time_ns() - - return nothing -end - -add_callback!(simulation, progress, IterationInterval(100)) - -Ql = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.latent_heat -Qs = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.sensible_heat -τx = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.x_momentum -τy = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.y_momentum -Fv = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.water_vapor -fluxes = (; Ql, Qs, τx, τy, Fv) -ocean_outputs = merge(ocean.model.velocities, ocean.model.tracers) - -Nz = size(grid, 3) -ocean_outputs = NamedTuple(name => view(ocean_outputs[name], :, :, Nz) - for name in keys(ocean_outputs)) - -h = sea_ice_model.ice_thickness -ℵ = sea_ice_model.ice_concentration -Ti = top_sea_ice_temperature -sea_ice_outputs = (; h, ℵ, Ti) - -outputs = merge(ocean_outputs, sea_ice_outputs, fluxes) - -ow = JLD2OutputWriter(ocean.model, outputs, - filename = "three_degree_simulation_surface.jld2", - indices = (:, :, size(grid, 3)), - schedule = TimeInterval(1days), - overwrite_existing = true) - -simulation.output_writers[:jld2] = ow - -#run!(simulation) -=# diff --git a/src/DataWrangling/ECCO/ECCO.jl b/src/DataWrangling/ECCO/ECCO.jl index 35942eebb..25f813f56 100644 --- a/src/DataWrangling/ECCO/ECCO.jl +++ b/src/DataWrangling/ECCO/ECCO.jl @@ -122,6 +122,19 @@ function empty_ECCO_field(metadata::ECCOMetadata; return Field{loc...}(grid) end +# Only temperature and salinity need a thorough inpainting because of stability, +# other variables can do with only a couple of passes. Sea ice variables +# cannot be inpainted because zeros in the data are physical, not missing values. +function default_inpainting(metadata::ECCOMetadata) + if metadata.name in [:temperature, :salinity] + return NearestNeighborInpainting(Inf) + elseif metadata.name in [:sea_ice_fraction, :sea_ice_thickness] + return nothing + else + return NearestNeighborInpainting(5) + end +end + """ ECCO_field(metadata::ECCOMetadata; architecture = CPU(), @@ -138,7 +151,7 @@ within the specified `mask`. `mask` is set to `ECCO_mask` for non-nothing """ function ECCO_field(metadata::ECCOMetadata; architecture = CPU(), - inpainting = NearestNeighborInpainting(Inf), + inpainting = default_inpainting(metadata), mask = nothing, horizontal_halo = (7, 7), cache_inpainted_data = true) diff --git a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl index 0eecef754..344366625 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl @@ -4,7 +4,7 @@ using Oceananigans.Operators: ℑxᶠᵃᵃ, ℑyᵃᶠᵃ using ClimaOcean.OceanSeaIceModels: sea_ice_concentration @inline computed_sea_ice_ocean_fluxes(interface) = interface.fluxes -@inline computed_sea_ice_ocean_fluxes(::Nothing) = nothing +@inline computed_sea_ice_ocean_fluxes(::Nothing) = (heat = ZeroField(), salt = ZeroField()) function compute_net_ocean_fluxes!(coupled_model) ocean = coupled_model.ocean @@ -58,7 +58,7 @@ function compute_net_ocean_fluxes!(coupled_model) return nothing end -@inline τᶜᶜᶜ(i, j, k, grid, ρₒ⁻¹, ℵ, ρτᶜᶜᶜ) = @inbounds ρₒ⁻¹ * (1 - ℵ[i, j, 1]) +@inline τᶜᶜᶜ(i, j, k, grid, ρₒ⁻¹, ℵ, ρτᶜᶜᶜ) = @inbounds ρₒ⁻¹ * (1 - ℵ[i, j, k]) * ρτᶜᶜᶜ[i, j, k] @kernel function _assemble_net_ocean_fluxes!(net_ocean_fluxes, grid, @@ -74,71 +74,11 @@ end ocean_properties) i, j = @index(Global, NTuple) - - assemble_net_atmosphere_ocean_fluxes!(i, j, grid, - net_ocean_fluxes, - clock, - atmos_ocean_fluxes, - ocean_salinity, - ocean_surface_temperature, - downwelling_radiation, - freshwater_flux, - atmos_ocean_properties, - ocean_properties) - - add_sea_ice_ocean_fluxes!(i, j, grid, - net_ocean_fluxes, - sea_ice_ocean_fluxes, - sea_ice_concentration, - ocean_salinity, - ocean_surface_temperature) -end - -@inline add_sea_ice_ocean_fluxes!(i, j, grid, net_ocean_fluxes, ::Nothing, args...) = nothing - -@inline function add_sea_ice_ocean_fluxes!(i, j, grid, - net_ocean_fluxes, - sea_ice_ocean_fluxes, - sea_ice_concentration, args...) - - # Compute fluxes for u, v, T, S from momentum, heat, and freshwater fluxes - τx = net_ocean_fluxes.u - τy = net_ocean_fluxes.v - Jᵀ = net_ocean_fluxes.T - Jˢ = net_ocean_fluxes.S - - ρₒ⁻¹ = 1 / ocean_properties.reference_density - cₒ = ocean_properties.heat_capacity - - @inbounds begin - ℵ = sea_ice_concentration[i, j, 1] - Qio = sea_ice_ocean_fluxes.heat[i, j, 1] - Jˢio = sea_ice_ocean_fluxes.salt[i, j, 1] - end - - Jᵀio = Qio * ρₒ⁻¹ / cₒ - - @inbounds begin - τx[i, j, 1] *= 1 - ℑxᶠᵃᵃ(i, j, 1, grid, ℵ) - τy[i, j, 1] *= 1 - ℑyᵃᶠᵃ(i, j, 1, grid, ℵ) - Jᵀ[i, j, 1] = (1 - ℵ) * Jᵀ[i, j, 1] + Jᵀio - Jˢ[i, j, 1] = (1 - ℵ) * Jˢ[i, j, 1] + Jˢio - end -end - -@inline function assemble_net_atmosphere_ocean_fluxes!(i, j, grid, - net_ocean_fluxes, - clock, - atmos_ocean_fluxes, - ocean_salinity, - ocean_surface_temperature, - downwelling_radiation, - freshwater_flux, - atmos_ocean_properties, - ocean_properties) kᴺ = size(grid, 3) time = Time(clock.time) - + ρτx = atmos_ocean_fluxes.x_momentum # zonal momentum flux + ρτy = atmos_ocean_fluxes.y_momentum # meridional momentum flux + @inbounds begin Sₒ = ocean_salinity[i, j, kᴺ] Tₛ = ocean_surface_temperature[i, j, 1] @@ -150,8 +90,6 @@ end Qc = atmos_ocean_fluxes.sensible_heat[i, j, 1] # sensible or "conductive" heat flux Qv = atmos_ocean_fluxes.latent_heat[i, j, 1] # latent heat flux Mv = atmos_ocean_fluxes.water_vapor[i, j, 1] # mass flux of water vapor - ρτx = atmos_ocean_fluxes.x_momentum[i, j, 1] # zonal momentum flux - ρτy = atmos_ocean_fluxes.y_momentum[i, j, 1] # meridional momentum flux end # Compute radiation fluxes @@ -179,20 +117,28 @@ end τy = net_ocean_fluxes.v Jᵀ = net_ocean_fluxes.T Jˢ = net_ocean_fluxes.S - + ℵ = sea_ice_concentration ρₒ⁻¹ = 1 / ocean_properties.reference_density cₒ = ocean_properties.heat_capacity - τxao = ℑxᶠᵃᵃ(i, j, 1, grid, ρτx) * ρₒ⁻¹ - τyao = ℑyᵃᶠᵃ(i, j, 1, grid, ρτy) * ρₒ⁻¹ + τxao = ℑxᶠᵃᵃ(i, j, 1, grid, τᶜᶜᶜ, ρₒ⁻¹, ℵ, ρτx) + τyao = ℑyᵃᶠᵃ(i, j, 1, grid, τᶜᶜᶜ, ρₒ⁻¹, ℵ, ρτy) Jᵀao = ΣQao * ρₒ⁻¹ / cₒ Jˢao = - Sₒ * ΣFao + ρₒ⁻¹ = 1 / ocean_properties.reference_density + cₒ = ocean_properties.heat_capacity + @inbounds begin + ℵᵢ = ℵ[i, j, 1] + Qio = sea_ice_ocean_fluxes.heat[i, j, 1] + Jˢio = sea_ice_ocean_fluxes.salt[i, j, 1] + Jᵀio = Qio * ρₒ⁻¹ / cₒ + τx[i, j, 1] = τxao τy[i, j, 1] = τyao - Jᵀ[i, j, 1] = Jᵀao - Jˢ[i, j, 1] = Jˢao + Jᵀ[i, j, 1] = (1 - ℵᵢ) * Jᵀao + Jᵀio + Jˢ[i, j, 1] = (1 - ℵᵢ) * Jˢao + Jˢio end end diff --git a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl index d4a9f35f4..d9645926c 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl @@ -133,7 +133,7 @@ end Sₛ = zero(FT) # what should we use for interface salinity? initial_interface_state = InterfaceState(u★, u★, u★, uᵢ, vᵢ, Tₛ, Sₛ, convert(FT, qₛ)) land = inactive_node(i, j, kᴺ, grid, Center(), Center(), Center()) - ice_free = hᵢ == 0 + ice_free = ℵᵢ == 0 if (land | ice_free) interface_state = InterfaceState(zero(FT), zero(FT), zero(FT), uᵢ, vᵢ, Tᵢ, Sₛ, zero(FT)) @@ -186,12 +186,12 @@ end @inbounds begin # +0: cooling, -0: heating - Qv[i, j, 1] = _Qv = - ρₐ * u★ * q★ * ℰs - Qc[i, j, 1] = _Qc = - ρₐ * cₚ * u★ * θ★ + Qv[i, j, 1] = _Qv = - ρₐ * u★ * q★ * ℰs + Qc[i, j, 1] = _Qc = - ρₐ * cₚ * u★ * θ★ ΣQ[i, j, 1] = Qu + Qd + _Qv + _Qc - Fv[i, j, 1] = - ρₐ * u★ * q★ - ρτx[i, j, 1] = + ρₐ * τx - ρτy[i, j, 1] = + ρₐ * τy + Fv[i, j, 1] = - ρₐ * u★ * q★ + ρτx[i, j, 1] = + ρₐ * τx + ρτy[i, j, 1] = + ρₐ * τy Ts[i, j, 1] = convert_from_kelvin(sea_ice_properties.temperature_units, Ψₛ.T) end end diff --git a/src/OceanSeaIceModels/InterfaceComputations/coefficient_based_turbulent_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/coefficient_based_turbulent_fluxes.jl index caaf56207..031c2aa30 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/coefficient_based_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/coefficient_based_turbulent_fluxes.jl @@ -20,7 +20,7 @@ function CoefficientBasedFluxes(FT = Oceananigans.defaults.FloatType; bulk_velocity = RelativeVelocity(), solver_stop_criteria = nothing, solver_tolerance = 1e-8, - solver_maxiter = 10) + solver_maxiter = 20) if isnothing(solver_stop_criteria) solver_tolerance = convert(FT, solver_tolerance) diff --git a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl index 76c3bb953..6f8d6c49a 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl @@ -171,7 +171,6 @@ function ComponentInterfaces(atmosphere, ocean, sea_ice=nothing; radiation = Radiation(), freshwater_density = 1000, atmosphere_ocean_flux_formulation = SimilarityTheoryFluxes(), - #atmosphere_sea_ice_flux_formulation = atmosphere_sea_ice_stability_functions(), atmosphere_sea_ice_flux_formulation = CoefficientBasedFluxes(drag_coefficient=2e-3, heat_transfer_coefficient=1e-4, vapor_flux_coefficient=1e-4), @@ -187,7 +186,7 @@ function ComponentInterfaces(atmosphere, ocean, sea_ice=nothing; ocean_grid = ocean.model.grid FT = eltype(ocean_grid) - + ocean_reference_density = convert(FT, ocean_reference_density) ocean_heat_capacity = convert(FT, ocean_heat_capacity) sea_ice_reference_density = convert(FT, sea_ice_reference_density) diff --git a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl index 0b927c27a..20105ed81 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl @@ -133,23 +133,18 @@ where ``Jᵀ`` are the fluxes at the top of the interface (turbulent + radiative Note that all fluxes positive upwards. """ -struct SkinTemperature{I} +struct SkinTemperature{I, FT} internal_flux :: I + max_ΔT :: FT end +SkinTemperature(internal_flux; max_ΔT=5) = SkinTemperature(internal_flux, max_ΔT) + struct DiffusiveFlux{Z, K} δ :: Z # Boundary layer thickness, as a first guess we will use half the grid spacing κ :: K # diffusivity in m² s⁻¹ end -# A default constructor for SkinTemperature -function SkinTemperature(FT::DataType=Float64; κ=1e-2, δ=1.0) - internal_flux = DiffusiveFlux(FT; κ, δ) - return SkinTemperature(internal_flux) -end - -DiffusiveFlux(FT; κ = 1e-2, δ = 1.0) = DiffusiveFlux(convert(FT, δ), convert(FT, κ)) - # The flux balance is solved by computing # # κ @@ -161,7 +156,7 @@ DiffusiveFlux(FT; κ = 1e-2, δ = 1.0) = DiffusiveFlux(convert(FT, δ), convert( # We have indicated that Jᵃ may depend on the surface temperature from the previous # iterate. We thus find that # -# Tₛⁿ⁺¹ = Tᵢ + δ * Jᵃ(Tₛⁿ) / κ +# Tₛⁿ⁺¹ = Tᵢ - δ * Jᵃ(Tₛⁿ) / κ # # Note that we could also use the fact that Jᵃ(T) = σ * ϵ * T^4 + ⋯ # to expand Jᵃ around Tⁿ⁺¹, @@ -184,16 +179,18 @@ DiffusiveFlux(FT; κ = 1e-2, δ = 1.0) = DiffusiveFlux(convert(FT, δ), convert( # Tₛⁿ⁺¹ = = (Tᵢ - δ / κ * (Jᵃ - 4 α Tₛⁿ⁴)) / (1 + 4 δ σ ϵ Tₛⁿ³ / ρ c κ) # # corresponding to a linearization of the outgoing longwave radiation term. -@inline function flux_balance_temperature(F::DiffusiveFlux, Qₐ, Ψₛ, ℙₛ, Ψᵢ, ℙᵢ) +@inline function flux_balance_temperature(st::SkinTemperature{<:DiffusiveFlux}, Qₐ, Ψₛ, ℙₛ, Ψᵢ, ℙᵢ) + F = st.internal_flux ρ = ℙᵢ.reference_density c = ℙᵢ.heat_capacity Jᵀ = Qₐ / (ρ * c) - return Ψᵢ.T + Jᵀ * F.δ / F.κ + return Ψᵢ.T - Jᵀ * F.δ / F.κ end # Q + k / h * (Tˢ - Tᵢ) = 0 # ⟹ Tₛ = Tᵢ - Q * h / k -@inline function flux_balance_temperature(F::ClimaSeaIce.ConductiveFlux, Qₐ, Ψₛ, ℙₛ, Ψᵢ, ℙᵢ) +@inline function flux_balance_temperature(st::SkinTemperature{<:ClimaSeaIce.ConductiveFlux}, Qₐ, Ψₛ, ℙₛ, Ψᵢ, ℙᵢ) + F = st.internal_flux k = F.conductivity h = Ψᵢ.h @@ -209,22 +206,21 @@ end Tₛ = (Tᵢ - h / k * (Qₐ + 4α * Tₛ⁻^4)) / (1 + 4α * h * Tₛ⁻^3 / k) =# - Tₛ = Tᵢ - Qₐ * h / k + T★ = Tᵢ - Qₐ * h / k # Under heating fluxes, cap surface temperature by melting temperature Tₘ = ℙᵢ.liquidus.freshwater_melting_temperature Tₘ = convert_to_kelvin(ℙᵢ.temperature_units, Tₘ) # Fix a NaN - Tₛ = ifelse(isnan(Tₛ), Tₛ⁻, Tₛ) - - # Don't let it go below some minimum number? - FT = typeof(Tₛ⁻) - min_Tₛ = convert(FT, 230) - Tₛ = max(min_Tₛ, Tₛ) - Tₛ = min(Tₛ, Tₘ) + T★ = ifelse(isnan(T★), Tₛ⁻, T★) - Tₛ⁺ = (Tₛ + 9Tₛ⁻) / 10 + # To prevent instabilities in the fixed point iteration + # solver we cap the maximum temperature difference with `max_ΔT` + ΔT★ = T★ - Tₛ⁻ + max_ΔT = convert(typeof(T★), st.max_ΔT) + abs_ΔT = min(max_ΔT, abs(ΔT★)) + Tₛ⁺ = Tₛ⁻ + abs_ΔT * sign(ΔT★) return Tₛ⁺ end @@ -268,7 +264,7 @@ end # Net heat flux Qa = Qr + Qc + Qv - Tₛ = flux_balance_temperature(st.internal_flux, Qa, + Tₛ = flux_balance_temperature(st, Qa, interface_state, interface_properties, interior_state, diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index cfa040e75..3ea4d3f17 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -13,6 +13,7 @@ using Oceananigans.Utils: launch!, Time using Oceananigans.Architectures: architecture using Oceananigans.BoundaryConditions: fill_halo_regions!, BoundaryCondition using Oceananigans.Grids: architecture +using Oceananigans.Fields: ZeroField using Oceananigans.TimeSteppers: tick! using Oceananigans.Models: AbstractModel using Oceananigans.OutputReaders: FieldTimeSeries, GPUAdaptedFieldTimeSeries @@ -35,10 +36,10 @@ const default_freshwater_density = 1000 const SeaIceSimulation = Simulation{<:SeaIceModel} -sea_ice_thickness(::Nothing) = nothing +sea_ice_thickness(::Nothing) = ZeroField() sea_ice_thickness(sea_ice::SeaIceSimulation) = sea_ice.model.ice_thickness -sea_ice_concentration(::Nothing) = nothing +sea_ice_concentration(::Nothing) = ZeroField() sea_ice_concentration(sea_ice::SeaIceSimulation) = sea_ice.model.ice_concentration ##### diff --git a/src/OceanSeaIceModels/freezing_limited_ocean_temperature.jl b/src/OceanSeaIceModels/freezing_limited_ocean_temperature.jl index 26cd0d178..538c6853f 100644 --- a/src/OceanSeaIceModels/freezing_limited_ocean_temperature.jl +++ b/src/OceanSeaIceModels/freezing_limited_ocean_temperature.jl @@ -1,9 +1,5 @@ using ClimaSeaIce.SeaIceThermodynamics: LinearLiquidus -import ClimaOcean.OceanSeaIceModels.InterfaceComputations: add_sea_ice_ocean_fluxes!, - computed_sea_ice_ocean_fluxes, - sea_ice_ocean_interface - ##### ##### A workaround when you don't have a sea ice model ##### @@ -13,22 +9,21 @@ struct FreezingLimitedOceanTemperature{L} end """ - FreezingLimitedOceanTemperature(FT=Float64) + FreezingLimitedOceanTemperature(FT=Float64; liquidus=LinearLiquidus(FT)) -The minimal possible sea ice representation, providing an "Insulating layer" on -the surface and clipping the temperature below to the freezing point. Not really -a "model"' per se, however, it is the most simple way to make sure that temperature -does not dip below freezing. All fluxes are shut down when the surface is below -the `T < Tₘ` except for heating to allow temperature to increase. +The minimal possible sea ice representation, clipping the temperature below to the freezing point. +Not really a "model"' per se, however, it is the most simple way to make sure that temperature +does not dip below freezing. The melting temperature is a function of salinity and is controlled by the `liquidus`. """ -FreezingLimitedOceanTemperature(FT::DataType=Oceananigans.defaults.FloatType) = - FreezingLimitedOceanTemperature(LinearLiquidus(FT)) +FreezingLimitedOceanTemperature(FT::DataType=Oceananigans.defaults.FloatType; liquidus=LinearLiquidus(FT)) = + FreezingLimitedOceanTemperature(liquidus) const FreezingLimitedCoupledModel = OceanSeaIceModel{<:FreezingLimitedOceanTemperature} -sea_ice_concentration(::FreezingLimitedOceanTemperature) = nothing +# Extend interface methods to work with a `FreezingLimitedOceanTemperature` +sea_ice_concentration(::FreezingLimitedOceanTemperature) = ZeroField() sea_ice_thickness(::FreezingLimitedOceanTemperature) = nothing # does not matter @@ -43,12 +38,12 @@ function compute_sea_ice_ocean_fluxes!(cm::FreezingLimitedCoupledModel) Sₒ = ocean.model.tracers.S Tₒ = ocean.model.tracers.T - launch!(arch, grid, :xyz, above_freezing_ocean_temperature!, Tₒ, Sₒ, liquidus) - + launch!(arch, grid, :xyz, _above_freezing_ocean_temperature!, Tₒ, Sₒ, liquidus) + return nothing end -@kernel function above_freezing_ocean_temperature!(Tₒ, Sₒ, liquidus) +@kernel function _above_freezing_ocean_temperature!(Tₒ, Sₒ, liquidus) i, j, k = @index(Global, NTuple) @@ -59,77 +54,4 @@ end Tₘ = melting_temperature(liquidus, Sᵢ) @inbounds Tₒ[i, j, k] = ifelse(Tᵢ < Tₘ, Tₘ, Tᵢ) -end - -@kernel function _adjust_fluxes_over_sea_ice!(net_fluxes, - grid, - liquidus, - ocean_temperature, - ocean_salinity) - - i, j = @index(Global, NTuple) - kᴺ = size(grid, 3) - - @inbounds begin - Tₒ = ocean_temperature[i, j, kᴺ] - Sₒ = ocean_salinity[i, j, kᴺ] - - Tₘ = melting_temperature(liquidus, Sₒ) - - τx = net_fluxes.u - τy = net_fluxes.v - Jᵀ = net_fluxes.T - Jˢ = net_fluxes.S - - sea_ice = Tₒ < Tₘ - cooling_sea_ice = sea_ice & (Jᵀ[i, j, 1] > 0) - - @show i, j, cooling_sea_ice, sea_ice - # Don't allow the ocean to cool below the minimum temperature! (make sure it heats up though!) - Jᵀ[i, j, 1] = ifelse(cooling_sea_ice, zero(grid), Jᵀ[i, j, 1]) - - # If we are in a "sea ice" region we remove all fluxes - Jˢ[i, j, 1] = ifelse(sea_ice, zero(grid), Jˢ[i, j, 1]) - τx[i, j, 1] = ifelse(sea_ice, zero(grid), τx[i, j, 1]) - τy[i, j, 1] = ifelse(sea_ice, zero(grid), τy[i, j, 1]) - end -end - -# Extend interface methods to work with a `FreezingLimitedOceanTemperature` - -sea_ice_ocean_interface(sea_ice::FreezingLimitedOceanTemperature, args...) = sea_ice - -@inline computed_sea_ice_ocean_fluxes(interface::FreezingLimitedOceanTemperature) = interface - -@inline function add_sea_ice_ocean_fluxes!(i, j, grid, - net_ocean_fluxes, - sea_ice_ocean_fluxes::FreezingLimitedOceanTemperature, - sea_ice_concentration, - ocean_salinity, - ocean_surface_temperature) - - kᴺ = size(grid, 3) - - @inbounds begin - Tₒ = ocean_surface_temperature[i, j, kᴺ] - Sₒ = ocean_salinity[i, j, kᴺ] - - Tₘ = melting_temperature(sea_ice_ocean_fluxes.liquidus, Sₒ) - - τx = net_ocean_fluxes.u - τy = net_ocean_fluxes.v - Jᵀ = net_ocean_fluxes.T - Jˢ = net_ocean_fluxes.S - - sea_ice = Tₒ < Tₘ - cooling_sea_ice = sea_ice & (Jᵀ[i, j, 1] > 0) - - # Don't allow the ocean to cool below the minimum temperature! (make sure it heats up though!) - Jᵀ[i, j, 1] = ifelse(cooling_sea_ice, zero(grid), Jᵀ[i, j, 1]) - - # If we are in a "sea ice" region we remove all fluxes - Jˢ[i, j, 1] = ifelse(sea_ice, zero(grid), Jˢ[i, j, 1]) - τx[i, j, 1] = ifelse(sea_ice, zero(grid), τx[i, j, 1]) - τy[i, j, 1] = ifelse(sea_ice, zero(grid), τy[i, j, 1]) - end -end +end \ No newline at end of file diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index be0461da5..5bda5b2da 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -1,6 +1,8 @@ using Oceananigans using Oceananigans.TimeSteppers: Clock using Oceananigans: SeawaterBuoyancy +using ClimaSeaIce.SeaIceThermodynamics: melting_temperature +using KernelAbstractions: @kernel, @index using SeawaterPolynomials: TEOS10EquationOfState @@ -86,7 +88,7 @@ function heat_capacity(::TEOS10EquationOfState{FT}) where FT return convert(FT, cₚ⁰) end -function OceanSeaIceModel(ocean, sea_ice=FreezingLimitedOceanTemperature(); +function OceanSeaIceModel(ocean, sea_ice=FreezingLimitedOceanTemperature(eltype(ocean.model)); atmosphere = nothing, radiation = nothing, clock = deepcopy(ocean.model.clock), @@ -134,6 +136,9 @@ function OceanSeaIceModel(ocean, sea_ice=FreezingLimitedOceanTemperature(); ocean, interfaces) + # Make sure the initial temperature of the ocean + # is not below freezing and above melting near the surface + adjust_freezing_ocean_temperature!(ocean, sea_ice) update_state!(ocean_sea_ice_model) return ocean_sea_ice_model @@ -147,3 +152,35 @@ function default_nan_checker(model::OceanSeaIceModel) nan_checker = NaNChecker((; u_ocean)) return nan_checker end + +@kernel function _adjust_freezing_ocean_temperature!(T, grid, S, ℵ, liquidus) + i, j = @index(Global, NTuple) + Nz = size(grid, 3) + + @inbounds begin + for k in 1:Nz-1 + Tm = melting_temperature(liquidus, S[i, j, k]) + T[i, j, k] = max(T[i, j, k], Tm) + end + + ℵi = ℵ[i, j, 1] + Tm = melting_temperature(liquidus, S[i, j, Nz]) + T[i, j, Nz] = ifelse(ℵi > 0, Tm, T[i, j, Nz]) + end +end + +# Fallback +adjust_freezing_ocean_temperature!(ocean, sea_ice) = nothing + +function adjust_freezing_ocean_temperature!(ocean, sea_ice::SeaIceSimulation) + T = ocean.model.tracers.T + S = ocean.model.tracers.S + ℵ = sea_ice.model.ice_concentration + liquidus = sea_ice.model.ice_thermodynamics.phase_transitions.liquidus + + grid = ocean.model.grid + arch = architecture(grid) + launch!(arch, grid, :xy, _adjust_freezing_ocean_temperature!, T, grid, S, ℵ, liquidus) + + return nothing +end \ No newline at end of file diff --git a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl index 5f40a1695..bf04b2d22 100644 --- a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl @@ -32,7 +32,8 @@ function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_ end sea_ice.Δt = Δt - thermodynamic_sea_ice_time_step!(coupled_model) + # thermodynamic_sea_ice_time_step!(coupled_model) + time_step!(sea_ice) end # TODO after ice time-step: @@ -74,7 +75,7 @@ function thermodynamic_sea_ice_time_step!(coupled_model) sea_ice = coupled_model.sea_ice model = sea_ice.model Δt = sea_ice.Δt - grid = coupled_model.ocean.model.grid + grid = coupled_model.sea_ice.model.grid arch = architecture(grid) clock = model.clock thermodynamics = model.ice_thermodynamics diff --git a/src/OceanSimulations.jl b/src/OceanSimulations.jl index 8a24814e3..7691a3ca8 100644 --- a/src/OceanSimulations.jl +++ b/src/OceanSimulations.jl @@ -249,3 +249,4 @@ hasclosure(closure, ClosureType) = closure isa ClosureType hasclosure(closure_tuple::Tuple, ClosureType) = any(hasclosure(c, ClosureType) for c in closure_tuple) end # module + diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index c4daccd48..7859d28a1 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -25,7 +25,9 @@ function sea_ice_simulation(grid; advection = nothing, # for the moment tracers = (), ice_heat_capacity = 2100, # J kg⁻¹ K⁻¹ + ice_consolidation_thickness = 0.05, # m ice_density = 900, # kg m⁻³ + dynamics = nothing, phase_transitions = PhaseTransitions(; ice_heat_capacity, ice_density), conductivity = 2, # kg m s⁻³ K⁻¹ internal_heat_flux = ConductiveFlux(; conductivity)) @@ -45,19 +47,18 @@ function sea_ice_simulation(grid; bottom_heat_flux = Field{Center, Center, Nothing}(grid) top_heat_flux = Field{Center, Center, Nothing}(grid) - top_momentum_stress = (u = Field{Face, Center, Nothing}(grid), - v = Field{Center, Face, Nothing}(grid)) - - velocities = deepcopy(top_momentum_stress) + # top_momentum_stress = (u = Field{Face, Center, Nothing}(grid), + # v = Field{Center, Face, Nothing}(grid)) # Build the sea ice model sea_ice_model = SeaIceModel(grid; ice_salinity, advection, tracers, - velocities, - top_momentum_stress, + ice_consolidation_thickness, + # top_momentum_stress, ice_thermodynamics, + dynamics, bottom_heat_flux, top_heat_flux) diff --git a/test/test_simulations.jl b/test/test_simulations.jl index 79b3599fe..96868eb5c 100644 --- a/test/test_simulations.jl +++ b/test/test_simulations.jl @@ -2,16 +2,21 @@ include("runtests_setup.jl") using CUDA using OrthogonalSphericalShellGrids +using ClimaOcean.OceanSeaIceModels: adjust_freezing_ocean_temperature! +using ClimaSeaIce.SeaIceThermodynamics: melting_temperature @testset "GPU time stepping test" begin for arch in test_architectures + + ##### + ##### Ocean and prescribed atmosphere + ##### + grid = TripolarGrid(arch; size = (50, 50, 10), halo = (7, 7, 7), - z = (-6000, 0), - first_pole_longitude = 75, - north_poles_latitude = 55) + z = (-6000, 0)) bottom_height = retrieve_bathymetry(grid; minimum_depth = 10, @@ -34,5 +39,37 @@ using OrthogonalSphericalShellGrids time_step!(coupled_model, 1) true end + + ##### + ##### Coupled ocean-sea ice and prescribed atmosphere + ##### + + sea_ice_grid = TripolarGrid(arch; size=(50, 50, 1), z = (-10, 0)) + sea_ice_grid = ImmersedBoundaryGrid(sea_ice_grid, GridFittedBottom(bottom_height)) + + sea_ice = sea_ice_simulation(sea_ice_grid) + liquidus = sea_ice.model.ice_thermodynamics.phase_transitions.liquidus + + # Set the ocean temperature and salinity + set!(ocean.model, T=temperature_metadata[1], S=salinity_metadata[1]) + + adjust_freezing_ocean_temperature!(ocean, sea_ice) + + # Test that ocean temperatures are above freezing + T = on_architecture(CPU(), ocean.model.T) + S = on_architecture(CPU(), ocean.model.S) + + @inline pointwise_melting_T(i, j, k, grid, liquidus, S) = @inbounds melting_temperature(liquidus, S[i, j, k]) + + Tm = KernelFunctionOperation{Center, Center, Center}(pointwise_melting_T, grid, S) + + @test all(T .> Tm) + + # Fluxes are computed when the model is constructed, so we just test that this works. + # And that we can time step with sea ice + @test begin + coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + true + end end end diff --git a/test/test_surface_fluxes.jl b/test/test_surface_fluxes.jl index 01ee51c54..c946f8b13 100644 --- a/test/test_surface_fluxes.jl +++ b/test/test_surface_fluxes.jl @@ -8,7 +8,8 @@ using ClimaOcean.OceanSeaIceModels.InterfaceComputations: saturation_specific_humidity, surface_flux, SkinTemperature, - BulkTemperature + BulkTemperature, + DiffusiveFlux using Thermodynamics using CUDA @@ -69,13 +70,13 @@ end radiation = Radiation(ocean_emissivity=0, ocean_albedo=1) # turbulent fluxes that force a specific humidity at the ocean's surface - for Tmode in (BulkTemperature, SkinTemperature) - @info " Testing zero fluxes with $(Tmode)..." + for atmosphere_ocean_interface_temperature in (BulkTemperature(), SkinTemperature(DiffusiveFlux(1, 1e-2))) + @info " Testing zero fluxes with $(atmosphere_ocean_interface_temperature)..." interfaces = ComponentInterfaces(atmosphere, ocean; radiation, atmosphere_ocean_interface_specific_humidity, - atmosphere_ocean_interface_temperature=Tmode()) + atmosphere_ocean_interface_temperature) g = ocean.model.buoyancy.formulation.gravitational_acceleration @@ -192,14 +193,6 @@ end coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) - # Make sure that temperature fluxes are zero when the temperature - # is below the minimum but not zero when it is above - Jᵀ = surface_flux(ocean.model.tracers.T) - - @test Jᵀ[1, 2, 1] != 0.0 # below freezing and cooling, no flux - @test Jᵀ[2, 1, 1] != 0.0 # below freezing and cooling, no flux - @test Jᵀ[2, 2, 1] == 0.0 # above freezing and cooling - # Test that the temperature has snapped up to freezing @test minimum(ocean.model.tracers.T) == 0 end